using Kafka.Lib; using Kafka.Lib.Auth; using MassTransit; using Microsoft.AspNetCore.DataProtection; using Microsoft.OpenApi.Models; using OpenWarehouse.auth.api.Common; using OpenWarehouse.auth.api.Common.AuthTokenRepo; using OpenWarehouse.auth.api.Common.DefaultUserAndRole; using OpenWarehouse.auth.api.Common.RegisterTokenManager; using OpenWarehouse.auth.api.Common.ServiceManager; using OpenWarehouse.auth.api.Services; using OpenWarehouse.Common.Lib; var builder = WebApplication.CreateBuilder(args); var logger = builder.GetBuildLogger(); builder.Services.AddIdentity(options => { options.SignIn.RequireConfirmedAccount = false; options.User.RequireUniqueEmail = true; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.AllowedForNewUsers = false; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); var kafkaConfig = builder.Configuration.GetSection("Kafka").Get(); builder.AddAuthenticationService(); var connectionString = Environment.GetEnvironmentVariable("ConnectionString") ?? builder.Configuration.GetConnectionString("DefaultConnection"); if (string.IsNullOrEmpty(connectionString)) { logger.LogError("Connection string 'DefaultConnection' not found"); throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); } builder.Services.AddDbContext(options => options.UseNpgsql(connectionString)); builder.Services.AddDataProtection() .PersistKeysToDbContext(); builder.Host .UseMassTransit((hostContext, configurator) => { configurator.UsingInMemory(); configurator.AddRider(r => { var warehouseTopicName = $"events.OpenWarehouse.{kafkaConfig?.TopicRoot}"; try { r.AddProducer($"{warehouseTopicName}-warehouse-topicName-logout"); r.AddProducer(warehouseTopicName+".PermisionChange"); r.AddProducer(warehouseTopicName+".RegisterNewServic"); r.AddProducer(warehouseTopicName+".TokenValidation"); r.AddProducer(warehouseTopicName+".UserClaimChange"); r.AddProducer(warehouseTopicName+".UserChange"); } catch (Exception e) { logger.LogError("Error configuring Kafka producers: {Message}", e.Message); } r.UsingKafka((context, cfg) => { cfg.Host(kafkaConfig?.BootstrapServers); }); }); }).ConfigureServices(services => { services.AddMassTransitHostedService(); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = SecuritySchemeType.ApiKey, Scheme = "Bearer" }); options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty() } }); options.AddServer(new OpenApiServer { Url = "/auth/" }); }); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddControllers(options => { options.Filters.Add(new IgnoreAntiforgeryTokenAttribute()); }) .ConfigureApiBehaviorOptions(options => { options.SuppressConsumesConstraintForFormFileParameters = true; options.SuppressInferBindingSourcesForParameters = true; options.SuppressModelStateInvalidFilter = true; options.SuppressMapClientErrors = true; }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService(); context.Database.Migrate(); } } using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var seedService = services.GetRequiredService(); await seedService.SeedAsync(); } // Disable to connection in docker network // app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();