diff --git a/Newsbot.Collector.Api/Program.cs b/Newsbot.Collector.Api/Program.cs index e82802f..843e449 100644 --- a/Newsbot.Collector.Api/Program.cs +++ b/Newsbot.Collector.Api/Program.cs @@ -10,6 +10,7 @@ using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newsbot.Collector.Api; using Newsbot.Collector.Api.Authentication; +using Newsbot.Collector.Api.Domain; using Newsbot.Collector.Api.Services; using Newsbot.Collector.Database; using Newsbot.Collector.Database.Repositories; @@ -39,10 +40,12 @@ Log.Information("Starting up"); var dbconn = config.GetConnectionString("Database"); builder.Services.AddDbContext(o => o.UseNpgsql(dbconn ?? "")); +// Configure how Identity will be managed builder.Services.AddIdentity() .AddRoles() .AddEntityFrameworkStores(); +// Allow the controllers to access all the table repositories based on the interface builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -60,7 +63,7 @@ builder.Services.AddHangfire(f => f.UseMemoryStorage()); builder.Services.AddHangfireServer(); GlobalConfiguration.Configuration.UseSerilogLogProvider(); -// Add Health Checks +// Build Health Checks builder.Services.AddHealthChecks() .AddNpgSql(config.GetValue(ConfigConnectionStringConst.Database) ?? ""); @@ -75,13 +78,13 @@ builder.Services.Configure(config.GetSection("ConnectionStrin builder.Services.Configure(config.GetSection(ConfigSectionsConst.ConnectionStrings)); builder.Services.Configure(config.GetSection(ConfigSectionsConst.Rss)); builder.Services.Configure(config.GetSection(ConfigSectionsConst.Youtube)); -//builder.Services.Configure< -// Configure JWT for auth +// Configure JWT for auth and load it into DI so we can use it in the controllers var jwtSettings = new JwtSettings(); config.Bind(nameof(jwtSettings), jwtSettings); builder.Services.AddSingleton(jwtSettings); +// Configure how the Token Validation will be handled var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, @@ -93,6 +96,7 @@ var tokenValidationParameters = new TokenValidationParameters }; builder.Services.AddSingleton(tokenValidationParameters); +// Build the Authentication that will be used builder.Services.AddAuthentication(x => { x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; @@ -104,9 +108,13 @@ builder.Services.AddAuthentication(x => x.TokenValidationParameters = tokenValidationParameters; }); +// Build the Authorization Policy that the users will conform to. +builder.Services.AddAuthorization(options => + options.AddPolicy(Authorization.AdministratorPolicy, b => b.RequireClaim( Authorization.AdministratorClaim, "true") )); + +// Configure swagger authentication builder.Services.AddSwaggerGen(cfg => { - cfg.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme { Description = "The API key to access the API", @@ -159,7 +167,9 @@ builder.Services.AddSwaggerGen(cfg => var app = builder.Build(); // Configure the HTTP request pipeline. -if (config.GetValue("EnableSwagger")) + +// Enable Swagger if requested based on config +if (config.GetValue(ConfigConst.EnableSwagger)) { app.UseSwagger(); app.UseSwaggerUI(); @@ -167,14 +177,17 @@ if (config.GetValue("EnableSwagger")) app.UseHttpsRedirection(); +// Enable Hangfire background jobs app.UseHangfireDashboard(); BackgroundJobs.SetupRecurringJobs(config); -//app.UseAuthorization(); +app.UseAuthorization(); app.UseAuthentication(); +// Add middleware //app.UseMiddleware(); +// Add HealthChecks app.MapHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true, @@ -182,6 +195,34 @@ app.MapHealthChecks("/health", new HealthCheckOptions }); app.MapControllers(); +// Run Database Migrations if requested +using var serviceScope = app.Services.CreateScope(); +if (config.GetValue(ConfigConst.RunDatabaseMigrationsOnStartup)) +{ + var dbContext = serviceScope.ServiceProvider.GetRequiredService(); + dbContext.Database.Migrate(); + +} +else +{ + Log.Warning("Database Migrations have been skipped. Make sure you run them on your own"); +} + +// Inject the roles +var roleManager = serviceScope.ServiceProvider.GetRequiredService>(); +if (!await roleManager.RoleExistsAsync("Administrators")) +{ + var adminRole = new IdentityRole("Administrators"); + await roleManager.CreateAsync(adminRole); +} + +if (!await roleManager.RoleExistsAsync("Users")) +{ + var userRole = new IdentityRole("Users"); + await roleManager.CreateAsync(userRole); +} + +// Start the application app.Run(); @@ -215,4 +256,4 @@ static ILogger GetLogger(IConfiguration configuration) { "service.name", "newsbot-collector-api" } }) .CreateLogger(); -} \ No newline at end of file +}