Files
MilkyShots/Lactose/Program.cs
2025-09-04 02:40:29 +02:00

179 lines
6.3 KiB
C#

using Lactose.Authorization;
using Lactose.Configuration;
using Lactose.Context;
using Lactose.Jobs;
using Lactose.Models;
using Lactose.Repositories;
using Lactose.Services;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Npgsql;
using Pgvector.EntityFrameworkCore;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
//Adds configurations to the builder
builder.Configuration.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", true, true);
builder.Services.Configure<RouteOptions>(options => options.LowercaseUrls = true);
builder.Services.ConfigureOptions<SignKeyProvider>();
string? user = builder.Configuration["DatabaseCredentials:UserID"];
string? password = builder.Configuration["DatabaseCredentials:Password"];
string database = builder.Configuration["DatabaseCredentials:Database"] ?? "lactose";
string host = builder.Configuration["DatabaseAddress:Host"] ?? "localhost";
string port = builder.Configuration["DatabaseAddress:Port"] ?? "3306";
var strBuilder = new NpgsqlConnectionStringBuilder() {
Host = host,
Port = int.Parse(port),
Username = user,
Password = password,
Database = database
};
builder.Services.AddDbContext<LactoseDbContext>(
options => {
/*
options.UseMySql(dbConnString, new MariaDbServerVersion(new Version(11, 5, 2)))
#if DEBUG
.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
#endif
;*/
options.UseNpgsql(strBuilder.ConnectionString, o => o.UseVector())
#if DEBUG
.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
#endif
//.ConfigureWarnings(warnings => warnings.Ignore(RelationalEventId.PendingModelChangesWarning))
;
}
);
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
// Add services to initialize an empty the database
builder.Services.AddScoped<IDbInitializer, DbInitializer>();
// Add services to the container.
builder.Services.AddTransient<IPasswordHasher<User>, PasswordHasher<User>>();
builder.Services.AddTransient<ISettingsRepository, SettingsRepository>();
builder.Services.AddTransient<IFolderRepository, FolderRepository>();
builder.Services.AddTransient<IUserRepository,UserRepository>();
builder.Services.AddTransient<ITagRepository, TagRepository>();
builder.Services.AddTransient<IAssetRepository, AssetRepository>();
builder.Services.AddTransient<IAlbumRepository, AlbumRepository>();
builder.Services.AddTransient<IMediaRepository, MediaRepository>();
builder.Services.AddTransient<ITokenService, TokenService>();
builder.Services.AddTransient<LactoseAuthService>();
builder.Services.AddSingleton<JobManager>();
builder.Services.AddSingleton<JobScheduler>();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(
options => {
options.SwaggerDoc(
"v1",
new OpenApiInfo {
Title = "Lactose",
Version = "v1"
}
);
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
In = ParameterLocation.Header,
Description = "Enter the Bearer Authorization string as following: `Bearer <Generated-JWT-Token>`",
Name = "Authorization",
BearerFormat = "JWT",
Scheme = "bearer",
Type = SecuritySchemeType.ApiKey
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer",
},
},
[]
}
});
options.SupportNonNullableReferenceTypes();
options.DescribeAllParametersInCamelCase();
options.UseInlineDefinitionsForEnums();
}
);
SecurityKey securityKey = new SignKeyProvider(builder.Configuration).Get().GetSecurityKey();
builder.Services.AddTransient<IClaimsTransformation, RefreshTokenTransformation>();
var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireClaim(RefreshTokenTransformation.ClaimType)
.Build();
builder.Services.AddAuthorization(options =>
{
AuthorizationPolicy defaultPolicy =
new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireClaim(RefreshTokenTransformation.ClaimType,"true")
.Build();
});
builder.Services
.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = securityKey,
ValidateIssuer = false,
ValidateAudience = false
};
});
//Add the job manager service
builder.Services.AddHostedService<JobManager>(p => p.GetRequiredService<JobManager>());
builder.Services.AddHostedService<JobScheduler>(p => p.GetRequiredService<JobScheduler>());
WebApplication app = builder.Build();
using (var scope = app.Services.CreateScope()) {
var dbInitializer = scope.ServiceProvider.GetRequiredService<IDbInitializer>();
dbInitializer.Initialize();
}
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "AuthCore API V1");
});
}
app.UseAuthentication();
app.UseAuthorization();
//app.UseHttpsRedirection();
app.MapControllers();
app.Run();