using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using System.Text; using Webshop.Application.Services.Public; using Webshop.Application.Services.Auth; using Webshop.Application.Services.Admin; using Webshop.Domain.Interfaces; using Webshop.Infrastructure.Data; using Webshop.Infrastructure.Repositories; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.Logging; var builder = WebApplication.CreateBuilder(args); // --- START: DIENSTE ZUM CONTAINER HINZUFÜGEN --- // 1. Datenbank-Kontext (DbContext) registrieren builder.Services.AddDbContext(options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")) ); // 2. ASP.NET Core Identity für Benutzerverwaltung registrieren builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); // 3. JWT-Authentifizierung konfigurieren var jwtSettings = builder.Configuration.GetSection("JwtSettings"); var secretKey = jwtSettings["Secret"] ?? throw new InvalidOperationException("JWT Secret not found in configuration."); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings["Issuer"], ValidAudience = jwtSettings["Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)) }; }); builder.Services.AddAuthorization(); // Aktiviert die Autorisierung // 4. Unsere eigenen Interfaces und Klassen registrieren (Dependency Injection) builder.Services.AddScoped(); // AUTH Services builder.Services.AddScoped(); // PUBLIC Services builder.Services.AddScoped(); // Ihr ProductService ist hier registriert // ADMIN Services builder.Services.AddScoped(); builder.Services.AddScoped(); // CUSTOMER Services (später Implementierungen hinzufügen) // builder.Services.AddScoped(); // 5. Controller und Swagger/OpenAPI hinzufügen builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // --- ENDE: DIENSTE ZUM CONTAINER HINZUFÜGEN --- var app = builder.Build(); // Optional: Automatisches Anwenden von Migrationen beim Start (nur für Entwicklung/Tests) using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; try { var context = services.GetRequiredService(); context.Database.Migrate(); // Wendet ausstehende Migrationen an } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred while migrating the database."); } } // --- START: HTTP REQUEST PIPELINE KONFIGURIEREN --- app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); // Swagger immer aktivieren (auch in Produktion für API-Dokumentation) // Für die Produktion wäre es sicherer, dies an `app.Environment.IsDevelopment()` zu binden // if (app.Environment.IsDevelopment()) // { app.UseSwagger(); app.UseSwaggerUI(); // } // app.UseHttpsRedirection(); // Auskommentiert für Docker HTTP-Entwicklung // WICHTIG: Die Reihenfolge ist entscheidend! app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); // --- ENDE: HTTP REQUEST PIPELINE KONFIGURIEREN --- app.Run(); // --- TEMPORÄRER INITIALER ADMIN- UND KUNDEN-SETUP (NUR FÜR ERSTE ENTWICKLUNG!) --- // Dieser Block erstellt Rollen und initiale Benutzer, falls sie noch nicht existieren. // Entfernen oder kommentiere dies aus, NACHDEM du deine ersten Benutzer erstellt hast! using (var scope = app.Services.CreateScope()) // Eigener Scope, da app.Run() blockierend ist { var serviceProvider = scope.ServiceProvider; var roleManager = serviceProvider.GetRequiredService>(); var userManager = serviceProvider.GetRequiredService>(); string[] roleNames = { "Admin", "Customer" }; foreach (var roleName in roleNames) { var roleExist = await roleManager.RoleExistsAsync(roleName); if (!roleExist) { await roleManager.CreateAsync(new IdentityRole(roleName)); } } // Erstelle einen initialen Admin-Benutzer var adminUser = await userManager.FindByEmailAsync("admin@yourwebshop.com"); // << ANPASSEN >> if (adminUser == null) { adminUser = new IdentityUser { UserName = "admin@yourwebshop.com", // << ANPASSEN >> Email = "admin@yourwebshop.com", // << ANPASSEN >> EmailConfirmed = true }; var createAdmin = await userManager.CreateAsync(adminUser, "SecureAdminPass123!"); // << ANPASSEN >> if (createAdmin.Succeeded) { await userManager.AddToRoleAsync(adminUser, "Admin"); Console.WriteLine("Admin user created."); } else { Console.WriteLine($"Error creating admin user: {string.Join(", ", createAdmin.Errors.Select(e => e.Description))}"); } } // Erstelle einen initialen Kunden-Benutzer var customerUser = await userManager.FindByEmailAsync("customer@yourwebshop.com"); // << ANPASSEN >> if (customerUser == null) { customerUser = new IdentityUser { UserName = "customer@yourwebshop.com", // << ANPASSEN >> Email = "customer@yourwebshop.com", // << ANPASSEN >> EmailConfirmed = true }; var createCustomer = await userManager.CreateAsync(customerUser, "SecureCustomerPass123!"); // << ANPASSEN >> if (createCustomer.Succeeded) { await userManager.AddToRoleAsync(customerUser, "Customer"); Console.WriteLine("Customer user created."); } else { Console.WriteLine($"Error creating customer user: {string.Join(", ", createCustomer.Errors.Select(e => e.Description))}"); } } } // --- ENDE DES TEMPORÄREN SETUP-BLOCKS ---