Init Git
This commit is contained in:
141
AMREZ.EOP.API/Program.cs
Normal file
141
AMREZ.EOP.API/Program.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using AMREZ.EOP.Abstractions.Applications.Tenancy;
|
||||
using AMREZ.EOP.API.Middleware;
|
||||
using AMREZ.EOP.Domain.Shared.Contracts;
|
||||
using AMREZ.EOP.Domain.Shared.Tenancy;
|
||||
using AMREZ.EOP.Infrastructures.Data;
|
||||
using AMREZ.EOP.Infrastructures.DependencyInjections;
|
||||
using AMREZ.EOP.Infrastructures.Options;
|
||||
using AMREZ.EOP.Infrastructures.Tenancy;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Npgsql;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.Configure<AuthOptions>(builder.Configuration.GetSection("Connections"));
|
||||
|
||||
builder.Services.AddInfrastructure();
|
||||
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Title = "AMREZ.EOP API",
|
||||
Version = "v1"
|
||||
});
|
||||
|
||||
// Cookie auth (ชื่อคุกกี้ eop.auth)
|
||||
c.AddSecurityDefinition("cookieAuth", new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
In = ParameterLocation.Cookie,
|
||||
Name = "eop.auth",
|
||||
Description = "Sign in via /api/authentication/login to receive cookie."
|
||||
});
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme{
|
||||
Reference = new OpenApiReference{ Type = ReferenceType.SecurityScheme, Id = "cookieAuth" }
|
||||
},
|
||||
Array.Empty<string>()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services
|
||||
.AddAuthentication(AuthPolicies.Scheme)
|
||||
.AddCookie(AuthPolicies.Scheme, o => { o.LoginPath="/api/authentication/login"; o.Cookie.Name="eop.auth"; o.SlidingExpiration=true; });
|
||||
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
builder.Services.AddSingleton(new StrictTenantGuardOptions
|
||||
{
|
||||
PlatformSlug = "public",
|
||||
HeaderName = "X-Tenant",
|
||||
ClaimName = "tenant"
|
||||
});
|
||||
builder.Services.AddTransient<StrictTenantGuardMiddleware>();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
await ApplyMigrationsAsync(app.Services);
|
||||
|
||||
app.MapOpenApi();
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(o =>
|
||||
{
|
||||
o.SwaggerEndpoint("/swagger/v1/swagger.json", "AMREZ.EOP API v1");
|
||||
o.RoutePrefix = "swagger";
|
||||
o.DisplayRequestDuration();
|
||||
});
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseMiddleware<StrictTenantGuardMiddleware>();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
|
||||
static async Task ApplyMigrationsAsync(IServiceProvider services)
|
||||
{
|
||||
using var scope = services.CreateScope();
|
||||
var sp = scope.ServiceProvider;
|
||||
|
||||
var opts = sp.GetRequiredService<Microsoft.Extensions.Options.IOptions<AuthOptions>>().Value;
|
||||
var factory = sp.GetRequiredService<ITenantDbContextFactory>();
|
||||
|
||||
if (!opts.UseSchemaPerTenant)
|
||||
{
|
||||
await using var db = factory.Create<AppDbContext>(new TenantContext { Id = "_shared_" });
|
||||
await db.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
var schemas = await GetAppSchemasAsync(opts.DefaultConnection);
|
||||
|
||||
foreach (var schema in schemas)
|
||||
{
|
||||
var t = new TenantContext { Id = schema, Schema = schema, Mode = TenantMode.Schema };
|
||||
await using var db = factory.Create<AppDbContext>(t);
|
||||
await db.Database.MigrateAsync();
|
||||
}
|
||||
}
|
||||
|
||||
static async Task<List<string>> GetAppSchemasAsync(string connectionString)
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
await using var conn = new NpgsqlConnection(connectionString);
|
||||
await conn.OpenAsync();
|
||||
|
||||
const string sql = @"
|
||||
SELECT nspname
|
||||
FROM pg_namespace
|
||||
WHERE nspname NOT LIKE 'pg_%'
|
||||
AND nspname <> 'information_schema'
|
||||
ORDER BY nspname;";
|
||||
|
||||
await using var cmd = new NpgsqlCommand(sql, conn);
|
||||
await using var rd = await cmd.ExecuteReaderAsync();
|
||||
while (await rd.ReadAsync())
|
||||
list.Add(rd.GetString(0));
|
||||
|
||||
if (list.Count == 0) list.Add("public");
|
||||
|
||||
return list;
|
||||
}
|
||||
Reference in New Issue
Block a user