using System.Text; using Hangfire; using Hangfire.MemoryStorage; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newsbot.Collector.Api; using Newsbot.Collector.Api.Authentication; using Newsbot.Collector.Api.Services; using Newsbot.Collector.Database; using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Domain.Models.Config.Sources; using Serilog; using Serilog.Events; using ILogger = Serilog.ILogger; var builder = WebApplication.CreateBuilder(args); // Define Logger builder.Host.UseSerilog(); // Build the config var config = GetConfiguration(); builder.Configuration.AddConfiguration(config); Log.Logger = GetLogger(config); Log.Information("Starting up"); // configure Entity Framework var dbconn = config.GetConnectionString("Database"); builder.Services.AddDbContext(o => o.UseNpgsql(dbconn ?? "")); builder.Services.AddIdentity() .AddRoles() .AddEntityFrameworkStores(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // Configure Identity builder.Services.AddScoped(); // Configure Hangfire builder.Services.AddHangfire(f => f.UseMemoryStorage()); builder.Services.AddHangfireServer(); GlobalConfiguration.Configuration.UseSerilogLogProvider(); // Add Health Checks builder.Services.AddHealthChecks() .AddNpgSql(config.GetValue(ConfigConnectionStringConst.Database) ?? ""); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.Configure(config.GetSection("ConnectionStrings")); 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 var jwtSettings = new JwtSettings(); config.Bind(nameof(jwtSettings), jwtSettings); builder.Services.AddSingleton(jwtSettings); builder.Services.AddAuthentication(x => { x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.Secret ?? "")), ValidateIssuer = false, ValidateAudience = false, RequireExpirationTime = false, ValidateLifetime = true }; }); builder.Services.AddSwaggerGen(cfg => { cfg.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme { Description = "The API key to access the API", Type = SecuritySchemeType.ApiKey, Name = "x-api-key", In = ParameterLocation.Header, Scheme = "ApiKeyScheme" }); cfg.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization Header using the bearer scheme", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey }); cfg.AddSecurityRequirement(new OpenApiSecurityRequirement { //{ // new OpenApiSecurityScheme // { // Reference = new OpenApiReference // { // Type = ReferenceType.SecurityScheme, // Id = "ApiKey" // }, // In = ParameterLocation.Header // }, // new List() //}, { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header }, new List() } }); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (config.GetValue("EnableSwagger")) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseHangfireDashboard(); BackgroundJobs.SetupRecurringJobs(config); //app.UseAuthorization(); app.UseAuthentication(); //app.UseMiddleware(); app.MapHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); app.MapControllers(); app.Run(); static IConfiguration GetConfiguration() { return new ConfigurationBuilder() .AddJsonFile("appsettings.json", true) .AddJsonFile("config/appsettings.json", true) .AddEnvironmentVariables() .Build(); } static ILogger GetLogger(IConfiguration configuration) { var otel = configuration.GetValue(ConfigConnectionStringConst.OpenTelemetry) ?? ""; if (otel == "") return Log.Logger = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Information() .CreateLogger(); return Log.Logger = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Information() .WriteTo.OpenTelemetry( otel, resourceAttributes: new Dictionary { { "Application", "newsbot-collector-api"}, { "service.name", "newsbot-collector-api" } }) .CreateLogger(); }