using API.Authentication; using API.Authentication.Interfaces; using API.Hashing; using API.Hashing.Interfaces; using API.Services; using API.Services.Interfaces; using DAL.Contexts; using DAL.Models; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.EntityFrameworkCore; using Serilog; using System.Reflection; using ConfigurationManager = Microsoft.Extensions.Configuration.ConfigurationManager; using InvalidOperationException = System.InvalidOperationException; namespace API { internal static class Program { public static IServiceCollection AddLazyResolution(this IServiceCollection services) { return services.AddTransient( typeof(Lazy<>), typeof(LazilyResolved<>)); } private class LazilyResolved : Lazy { public LazilyResolved(IServiceProvider serviceProvider) : base(serviceProvider.GetRequiredService) { } } public static void Main(string[] args) { WebApplicationBuilder builder = WebApplication.CreateBuilder(args); ConfigurationManager configManager = builder.Configuration; builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); options.IncludeXmlComments(xmlPath, true); }); builder.Host.UseSerilog((context, configuration) => configuration.ReadFrom.Configuration(context.Configuration)); builder.Services.AddDbContext(options => { options.UseMySQL(builder.Configuration["connectionString"] ?? throw new InvalidOperationException("Connection String is null")); }); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(options => { ILogger logger = options.GetRequiredService>(); SASGContext context = options.GetRequiredService(); IUserAuthentication authentication = options.GetRequiredService(); PermissionService permissionService = options.GetRequiredService(); ulong defaultUserPermission = UInt64.Parse(builder.Configuration["defaultUserPermission"] ?? throw new InvalidOperationException("defaultUserPermission is null")); return new UserService(logger, context, authentication, permissionService, defaultUserPermission); }); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(options => { UserService userService = options.GetRequiredService(); IHashingFactory hashingFactory = options.GetRequiredService(); ILogger logger = options.GetRequiredService>(); HashingType hashingType; if (!Enum.TryParse(builder.Configuration["preferredHashingType"], out hashingType)) throw new InvalidOperationException($"preferredHashingType not one of {String.Join(", ", Enum.GetNames(typeof(HashingType)))}"); return new UserManager(userService, hashingFactory, logger, hashingType); }); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => { options.Events.OnRedirectToAccessDenied = context => { context.Response.StatusCode = 403; return Task.CompletedTask; }; }); // builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => // { // options.Cookie.SameSite = SameSiteMode.None; // options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // }); builder.Services.AddLazyResolution(); WebApplication app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict }); app.UseAuthorization(); app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }); app.UseHttpsRedirection(); app.MapControllers(); app.Run(); } } }