Refactoring, database structure changed

This commit is contained in:
2025-03-03 00:56:32 +01:00
Unverified
parent d3805ef3db
commit c603c41c0b
913 changed files with 21764 additions and 32775 deletions

206
WatchIt.WebAPI/Program.cs Normal file
View File

@@ -0,0 +1,206 @@
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Text;
using System.Text.Json;
using Delta;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.HttpLogging;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using WatchIt.Database;
using WatchIt.DTO;
using WatchIt.DTO.Converters;
using WatchIt.WebAPI.BusinessLogic.Accounts;
using WatchIt.WebAPI.BusinessLogic.Authentication;
using WatchIt.WebAPI.BusinessLogic.Genders;
using WatchIt.WebAPI.BusinessLogic.Genres;
using WatchIt.WebAPI.BusinessLogic.Media;
using WatchIt.WebAPI.BusinessLogic.People;
using WatchIt.WebAPI.BusinessLogic.Photos;
using WatchIt.WebAPI.BusinessLogic.Roles;
using WatchIt.WebAPI.Constants;
using WatchIt.WebAPI.Repositories.Accounts;
using WatchIt.WebAPI.Repositories.Genders;
using WatchIt.WebAPI.Repositories.Genres;
using WatchIt.WebAPI.Repositories.Media;
using WatchIt.WebAPI.Repositories.People;
using WatchIt.WebAPI.Repositories.Photos;
using WatchIt.WebAPI.Repositories.Roles;
using WatchIt.WebAPI.Services.Tokens;
using WatchIt.WebAPI.Services.User;
namespace WatchIt.WebAPI;
public static class Program
{
#region PUBLIC METHODS
public static void Main(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.SetupAuthentication();
builder.SetupDatabases();
builder.Services.AddRepositories();
builder.Services.AddHttpContextAccessor();
builder.Services.AddServices();
builder.Services.AddBusinessLogic();
builder.Services.AddWorkers();
builder.Services.AddFluentValidation();
builder.Services.AddControllers()
.AddJsonOptions(x =>
{
x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower;
x.JsonSerializerOptions.Converters.Add(new ColorJsonConverter());
});
builder.Services.AddOpenApi();
builder.Services.AddHttpLogging(o => { o.LoggingFields |= HttpLoggingFields.RequestQuery; });
WebApplication app = builder.Build();
app.UseHttpLogging();
app.UseDelta<DatabaseContext>();
app.InitializeDatabase();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
#endregion
#region PRIVATE METHODS
private static void AddRepositories(this IServiceCollection services)
{
services.AddTransient<IGendersRepository, GendersRepository>();
services.AddTransient<IGenresRepository, GenresRepository>();
services.AddTransient<IAccountsRepository, AccountsRepository>();
services.AddTransient<IMediaRepository, MediaRepository>();
services.AddTransient<IPeopleRepository, PeopleRepository>();
services.AddTransient<IPhotosRepository, PhotosRepository>();
services.AddTransient<IRolesRepository, RolesRepository>();
}
private static void AddServices(this IServiceCollection services)
{
services.AddTransient<ITokensService, TokensService>();
services.AddTransient<IUserService, UserService>();
}
private static void AddBusinessLogic(this IServiceCollection services)
{
services.AddTransient<IGendersBusinessLogic, GendersBusinessLogic>();
services.AddTransient<IGenresBusinessLogic, GenresBusinessLogic>();
services.AddTransient<IAuthenticationBusinessLogic, AuthenticationBusinessLogic>();
services.AddTransient<IAccountsBusinessLogic, AccountsBusinessLogic>();
services.AddTransient<IMediaBusinessLogic, MediaBusinessLogic>();
services.AddTransient<IPeopleBusinessLogic, PeopleBusinessLogic>();
services.AddTransient<IPhotosBusinessLogic, PhotosBusinessLogic>();
services.AddTransient<IRolesBusinessLogic, RolesBusinessLogic>();
}
private static void AddWorkers(this IServiceCollection services)
{
}
private static void AddFluentValidation(this IServiceCollection services)
{
services.AddValidatorsFromAssembly(Assembly.GetAssembly(typeof(CustomValidators)));
services.AddFluentValidationAutoValidation();
}
private static WebApplicationBuilder SetupAuthentication(this WebApplicationBuilder builder)
{
string issuer = builder.Configuration.GetValue<string>("Authentication:JWT:Issuer")!;
string audience = builder.Configuration.GetValue<string>("Authentication:JWT:Audience")!;
string key = builder.Configuration.GetValue<string>("Authentication:JWT:Key")!;
byte[] encodedKey = Encoding.UTF8.GetBytes(key);
JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = issuer,
ValidAudience = audience,
IssuerSigningKey = new SymmetricSecurityKey(encodedKey),
ClockSkew = TimeSpan.FromMinutes(1),
};
x.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Append("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
builder.Services
.AddAuthorization(options =>
{
options.AddPolicy(Policies.Admin, policy => policy.RequireAuthenticatedUser()
.RequireClaim(AdditionalClaimNames.Admin, bool.TrueString));
});
return builder;
}
private static WebApplicationBuilder SetupDatabases(this WebApplicationBuilder builder)
{
builder.Services
.AddDbContext<DatabaseContext>(x => x.UseNpgsql(builder.Configuration
.GetConnectionString("Database")),
ServiceLifetime.Transient);
return builder;
}
private static void InitializeDatabase(this WebApplication app)
{
using (IServiceScope scope = app.Services.CreateScope())
{
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
while (!database.Database.CanConnect())
{
app.Logger.LogInformation("Waiting for database...");
Thread.Sleep(1000);
}
database.Database.Migrate();
}
}
#endregion
}