erp-platform/api/src/Kurs.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs
Sedat ÖZTÜRK 32a19578cb First Commit
2025-05-06 11:04:37 +03:00

387 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Hangfire;
using Hangfire.PostgreSql;
using Kurs.Languages;
using Kurs.MailQueue;
using Kurs.Notifications.Application;
using Kurs.Platform.BlobStoring;
using Kurs.Platform.EntityFrameworkCore;
using Kurs.Platform.Extensions;
using Kurs.Platform.Identity;
using Kurs.Settings;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using OpenIddict.Server.AspNetCore;
using OpenIddict.Validation.AspNetCore;
using Volo.Abp;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundWorkers.Hangfire;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Caching;
using Volo.Abp.Hangfire;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Swashbuckle;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using static Kurs.Platform.PlatformConsts;
namespace Kurs.Platform;
[DependsOn(
typeof(PlatformHttpApiModule),
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(PlatformApplicationModule),
typeof(PlatformEntityFrameworkCoreModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpAccountWebOpenIddictModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule),
typeof(AbpBackgroundWorkersHangfireModule)
)]
public class PlatformHttpApiHostModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddServer(server =>
{
server.SetAccessTokenLifetime(TimeSpan.FromMinutes(60));
server.SetRefreshTokenLifetime(TimeSpan.FromMinutes(90));
});
builder.AddValidation(options =>
{
options.AddAudiences(PlatformConsts.AppName);
options.UseLocalServer();
options.UseAspNetCore();
});
});
PreConfigure<IdentityBuilder>(builder =>
{
builder.AddClaimsPrincipalFactory<PlatformUserClaimsPrincipalFactory>();
builder.AddSignInManager<PlatformSignInManager>();
});
context.Services.Replace(
ServiceDescriptor.Transient<AbpUserClaimsPrincipalFactory, PlatformUserClaimsPrincipalFactory>());
context.Services.AddTransient<IPlatformSignInManager, PlatformSignInManager>();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
ConfigureAuthentication(context);
ConfigureBundles();
ConfigureUrls(configuration);
ConfigureConventionalControllers();
//Localization'ı veritabanından kullandıgımız icin bir json resource kullanmıyoruz
//Dolayısıyla şimdilik ihtiyacımız yok ama ileride başka bir sebepten kullanabiliriz diye silmedik
//ConfigureVirtualFileSystem(context);
ConfigureCors(context, configuration);
ConfigureSwaggerServices(context, configuration);
ConfigureIdentity(configuration);
ConfigureCache();
ConfigureHangfire(context, configuration);
ConfigureBlobStoring(configuration);
Configure<AbpExceptionHttpStatusCodeOptions>(options =>
{
options.Map(AppErrorCodes.NoAuth, System.Net.HttpStatusCode.Unauthorized);
});
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
Configure<AbpApplicationConfigurationOptions>(options =>
{
options.Contributors.AddIfNotContains(new PlatformApplicationConfigurationContributor());
});
}
private void ConfigureAuthentication(ServiceConfigurationContext context)
{
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
BasicThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
}
private void ConfigureUrls(IConfiguration configuration)
{
Configure<AppUrlOptions>(options =>
{
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty<string>());
options.Applications[PlatformConsts.React].RootUrl = configuration["App:ClientUrl"];
options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.EmailConfirmation] = "account/confirm";
options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.PasswordReset] = "account/reset-password";
options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.UserDetail] = "account/{0}";
//options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
//options.Applications["MVC"].Urls[PlatformConsts.Urls.EmailConfirmation] = "Account/Confirm";
//options.Applications["MVC"].Urls[PlatformConsts.Urls.TwoFactor] = "Account/TwoFactor";
//options.Applications["MVC"].Urls[PlatformConsts.Urls.Login] = "Account/Login";
//options.Applications["MVC"].Urls[PlatformConsts.Urls.UserDetail] = "Identity/Users/Detail";
});
}
private void ConfigureConventionalControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(PlatformApplicationModule).Assembly, opts =>
{
opts.TypePredicate = t => t.Namespace == "Kurs.Platform.ListForms.Administration";
opts.RootPath = "admin";
});
options.ConventionalControllers.Create(typeof(PlatformApplicationModule).Assembly, opts =>
{
opts.TypePredicate = t => t.Namespace != "Kurs.Platform.ListForms.Administration";
opts.RootPath = "app";
});
options.ConventionalControllers.Create(typeof(LanguagesApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(SettingsApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(KursMailQueueModule).Assembly);
options.ConventionalControllers.Create(typeof(NotificationApplicationModule).Assembly);
options.ChangeControllerModelApiExplorerGroupName = false;
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(PlatformUpdateProfileDto));
});
}
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<PlatformDomainSharedModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Kurs.Platform.Domain.Shared"));
options.FileSets.ReplaceEmbeddedByPhysical<PlatformDomainModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Kurs.Platform.Domain"));
options.FileSets.ReplaceEmbeddedByPhysical<PlatformApplicationContractsModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Kurs.Platform.Application.Contracts"));
options.FileSets.ReplaceEmbeddedByPhysical<PlatformApplicationModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Kurs.Platform.Application"));
options.FileSets.ReplaceEmbeddedByPhysical<KursMailQueueModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Kurs.MailQueue"));
});
}
}
private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(configuration["App:CorsOrigins"]?
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray() ?? Array.Empty<string>())
.WithAbpExposedHeaders()
.WithExposedHeaders(["X-Correlation-Id"])
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
private void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
new Dictionary<string, string>
{
{"Platform", "Platform API"}
},
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Platform API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
});
}
private void ConfigureIdentity(IConfiguration configuration)
{
//Veritabanından yonetildigi icin bunlar kapatildi
//Configure<IdentityOptions>(options =>
//{
// options.SignIn.RequireConfirmedEmail = true;
// options.SignIn.RequireConfirmedAccount = true;
// options.SignIn.RequireConfirmedPhoneNumber = false;
// options.User.RequireUniqueEmail = true;
// options.Lockout.AllowedForNewUsers = true;
// options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
// options.Lockout.MaxFailedAccessAttempts = 5;
// options.Password.RequiredLength = 6;
// options.Password.RequiredUniqueChars = 0;
// options.Password.RequireNonAlphanumeric = false;
// options.Password.RequireLowercase = false;
// options.Password.RequireUppercase = false;
// options.Password.RequireDigit = false;
//});
Configure<PlatformIdentityOptions>(configuration.GetSection(PlatformConsts.AbpIdentity.GroupName));
}
private void ConfigureCache()
{
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = PlatformConsts.AppName;
});
Configure<RedisCacheOptions>(options =>
{
});
}
private void ConfigureHangfire(ServiceConfigurationContext context, IConfiguration configuration)
{
Configure<AbpHangfireOptions>(options =>
{
options.ServerOptions = new BackgroundJobServerOptions()
{
Queues = ["default", "platform"]
};
});
context.Services.AddHangfire(config =>
{
config.UsePostgreSqlStorage(c =>
c.UseNpgsqlConnection(configuration.GetConnectionString("Default"))); //PGSQL
// config.UseSqlServerStorage(configuration.GetConnectionString("Default"));
});
}
private void ConfigureBlobStoring(IConfiguration configuration)
{
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.Configure<AvatarBlobContainer>(container =>
{
container.UseFileSystem(fileSystem =>
{
fileSystem.BasePath = configuration["App:CdnPath"];
});
});
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
// Auth hataları MVC tarafından /Error sayfasına yönlendirilmesin diye bu kaldırıldı
// if (!env.IsDevelopment())
// {
// app.UseErrorPage();
// }
app.UseCorrelationId();
app.MapAbpStaticAssets();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAbpOpenIddictValidation();
app.UseMiddleware<CaptchaMiddleware>();
if (PlatformConsts.IsMultiTenant)
{
app.UseMultiTenancy();
}
app.UseUnitOfWork();
app.UseDynamicClaims();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Platform API");
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
c.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
c.OAuthScopes("Platform");
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
if (env.IsDevelopment())
{
app.UseHangfireDashboard();
}
else
{
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = [new AbpHangfireAuthorizationFilter()]
});
}
app.UseConfiguredEndpoints();
}
}