387 lines
15 KiB
C#
387 lines
15 KiB
C#
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();
|
||
}
|
||
}
|