using Microsoft.AspNetCore.Identity; namespace zero.Identity; public class AuthenticationService : IAuthenticationService { protected IZeroContext Context { get; set; } protected SignInManager SignInManager { get; private set; } protected IZeroStore Store { get; set; } public AuthenticationService(IZeroContext context, SignInManager signInManager, IZeroStore store) { Context = context; SignInManager = signInManager; Store = store; } /// public bool IsLoggedIn() { //ClaimsPrincipal principal = HttpContextAccessor.HttpContext.User; //bool isAuthenticated = principal.Identity.IsAuthenticated; //bool isZeroUser = principal.HasClaim(Constants.Auth.Claims.IsZero, PermissionsValue.True); //bool isSignedIn = SignInManager.IsSignedIn(principal); //return isAuthenticated && isZeroUser && isSignedIn; return SignInManager.IsSignedIn(Context.BackofficeUser); } /// public bool IsSuper() { return Context.BackofficeUser.HasClaim(Constants.Auth.Claims.IsSuper, PermissionsValue.True); } /// public bool IsAdmin() { return Context.BackofficeUser.HasClaim(Constants.Auth.Claims.Role, "administrator"); // TODO use constant (in setup as well) } /// public async Task GetUser() { return await SignInManager.UserManager.GetUserAsync(Context.BackofficeUser); } /// public async Task Login(string email, string password, bool isPersistent) { EntityResult result = new(); ZeroUser user = await SignInManager.UserManager.FindByNameAsync(email); if (user == null) { result.AddError("@login.errors.wrongcredentials"); // TODO we don't need translations here, but return an enum, so the app itself can translate the error return result; } // TODO probably move this logic into a custom SignInManager which overrides CanSignInAsync() // see https://stackoverflow.com/a/35484758/670860 else if (!user.IsActive) { result.AddError("@login.errors.disabled"); return result; } SignInResult signInResult = await SignInManager.PasswordSignInAsync(user, password, isPersistent, true); if (!signInResult.Succeeded) { if (signInResult.IsLockedOut) { result.AddError("@login.errors.lockedout"); } else if (signInResult.IsNotAllowed) { result.AddError("@login.errors.notallowed"); } else if (signInResult.RequiresTwoFactor) { result.AddError("@login.errors.requirestwofactor"); } else { result.AddError("@login.errors.wrongcredentials"); } return result; } return EntityResult.Success(); } /// public async Task Logout() { await SignInManager.SignOutAsync(); } /// public string GetUserId() { return SignInManager.UserManager.GetUserId(Context.BackofficeUser); } } public interface IAuthenticationService { /// /// Get currently logged-in user /// Task GetUser(); /// /// Whether a user is currently logged-in /// bool IsLoggedIn(); /// /// Whether the current user is the super user who created the zero instance /// bool IsSuper(); /// /// Whether the current user belongs to the administrator role (will always return false if this role gets deleted) /// bool IsAdmin(); /// /// Logs a zero-user in and sets cookie /// Task Login(string email, string password, bool isPersistent); /// /// Logs out the current user /// Task Logout(); /// /// Get the ID of the currently logged in user /// string GetUserId(); }