using System.Security.Claims; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using ScadaLink.Security; namespace ScadaLink.CentralUI.Auth; /// /// Minimal API endpoints for login/logout. These run outside Blazor Server (standard HTTP POST). /// On success, signs in via ASP.NET Core cookie authentication and redirects to dashboard. /// public static class AuthEndpoints { public static IEndpointRouteBuilder MapAuthEndpoints(this IEndpointRouteBuilder endpoints) { endpoints.MapPost("/auth/login", async (HttpContext context) => { var form = await context.Request.ReadFormAsync(); var username = form["username"].ToString(); var password = form["password"].ToString(); if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { context.Response.Redirect("/login?error=Username+and+password+are+required."); return; } var ldapAuth = context.RequestServices.GetRequiredService(); var jwtService = context.RequestServices.GetRequiredService(); var roleMapper = context.RequestServices.GetRequiredService(); var authResult = await ldapAuth.AuthenticateAsync(username, password); if (!authResult.Success) { var errorMsg = Uri.EscapeDataString(authResult.ErrorMessage ?? "Authentication failed."); context.Response.Redirect($"/login?error={errorMsg}"); return; } // Map LDAP groups to roles var roleMappingResult = await roleMapper.MapGroupsToRolesAsync(authResult.Groups ?? []); // Build claims from LDAP auth + role mapping var claims = new List { new(ClaimTypes.Name, authResult.Username ?? username), new(JwtTokenService.DisplayNameClaimType, authResult.DisplayName ?? username), new(JwtTokenService.UsernameClaimType, authResult.Username ?? username), }; foreach (var role in roleMappingResult.Roles) { claims.Add(new Claim(JwtTokenService.RoleClaimType, role)); } if (!roleMappingResult.IsSystemWideDeployment) { foreach (var siteId in roleMappingResult.PermittedSiteIds) { claims.Add(new Claim(JwtTokenService.SiteIdClaimType, siteId)); } } var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); await context.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(30) }); context.Response.Redirect("/"); }).DisableAntiforgery(); endpoints.MapPost("/auth/logout", async (HttpContext context) => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); context.Response.Redirect("/login"); }).DisableAntiforgery(); return endpoints; } }