using System.Security.Claims; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace ZB.MOM.WW.ScadaBridge.Security.Auth; /// /// Auth handler used ONLY when is true. /// Registered under the cookie scheme name, it authenticates EVERY request as the configured /// dev user with all roles, system-wide — no credential check, no cookie. /// The minted principal mirrors a real login (it reuses ). /// Dev/test ONLY. /// public sealed class AutoLoginAuthenticationHandler : AuthenticationHandler, IAuthenticationSignInHandler { // Only _opts.User is consumed here. The DisableLogin flag is gated at registration time // (AddSecurity); if DisableLogin is false this handler is never registered, so it is // never reached and the flag itself is irrelevant inside the handler. private readonly AuthDisableLoginOptions _opts; private readonly TimeProvider _clock; /// Initializes the handler with the scheme plumbing, the disable-login options, and the clock. public AutoLoginAuthenticationHandler( IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, IOptions disableLoginOptions, TimeProvider clock) : base(options, logger, encoder) { _opts = disableLoginOptions.Value; _clock = clock; } /// No-op: auto-login writes no cookie, so an explicit sign-in has nothing to persist. public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties) => Task.CompletedTask; /// No-op: there is no auth cookie to clear; the next request re-authenticates via this handler. public Task SignOutAsync(AuthenticationProperties? properties) => Task.CompletedTask; /// protected override Task HandleAuthenticateAsync() { var user = string.IsNullOrWhiteSpace(_opts.User) ? "multi-role" : _opts.User; // All roles, system-wide (no site-scope claims). Reuse the canonical builder so the // principal is shape-identical to a real all-roles system-wide login. var mapping = new RoleMappingResult(Roles.All, [], IsSystemWideDeployment: true); var principal = SessionClaimBuilder.Build( username: user, displayName: user, groups: [], mapping: mapping, refreshTimestamp: _clock.GetUtcNow()); var ticket = new AuthenticationTicket(principal, Scheme.Name); return Task.FromResult(AuthenticateResult.Success(ticket)); } }