using FoodsharingSiegen.Contracts; using FoodsharingSiegen.Contracts.Entity; using FoodsharingSiegen.Contracts.Enums; using FoodsharingSiegen.Contracts.Helper; using FoodsharingSiegen.Server.Data; using FoodsharingSiegen.Server.Service; using FoodsharingSiegen.Shared.Helper; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.EntityFrameworkCore; namespace FoodsharingSiegen.Server.Auth { /// /// The auth service class (a. beging, 04.04.2022) /// public class AuthService { #region Public Properties /// /// Gets or sets the value of the user (ab) /// public User? User => _user; #endregion #region Private Properties /// /// Gets the value of the context (ab) /// private FsContext Context { get; } #endregion #region Private Fields /// /// The authentication state provider /// private readonly AuthenticationStateProvider _authenticationStateProvider; /// /// The local storage service /// private readonly LocalStorageService _localStorageService; /// /// The user /// private User? _user; #endregion #region Setup/Teardown /// /// Initializes a new instance of the class /// /// The context /// The local storage service /// The authentication state provider public AuthService( FsContext context, LocalStorageService localStorageService, AuthenticationStateProvider authenticationStateProvider) { Context = context; _localStorageService = localStorageService; _authenticationStateProvider = authenticationStateProvider; } #endregion #region Public Method Initialize /// /// Initializes this instance (a. beging, 11.04.2022) /// public async Task Initialize() { if (_user != null) return; var token = await _localStorageService.GetItem(StorageKeys.TokenKey); if (AuthHelper.ValidateToken(token, out var user) && user != null) _user = user; } #endregion #region Public Method Login /// /// Logins the mail address (a. beging, 04.04.2022) /// /// The mail address /// The password /// A task containing the operation result public async Task Login(string mailAddress, string password) { #region Ensure Admin var existingTroogS = await Context.Users!.AnyAsync(x => x.Mail == "fs@beging.de"); if (!existingTroogS) { var troogs = new User { Name = "Andre", Mail = "fs@beging.de", GroupsList = [UserGroup.Ambassador], Type = UserType.Admin, Created = DateTime.UtcNow, EncryptedPassword = "qSIxTZo7J8M=" }; await Context.Users!.AddAsync(troogs); await Context.SaveChangesAsync(); } #endregion Ensure Admin var encryptedPassword = Cryptor.Encrypt(password); _user = await Context.Users!.FirstOrDefaultAsync(x => x.Mail.ToLower() == mailAddress.ToLower() && x.EncryptedPassword == encryptedPassword); if (_user != null) { var serializedToken = AuthHelper.CreateToken(_user); await _localStorageService.SetItem(StorageKeys.TokenKey, serializedToken); if (_user.ForceLogout) { _user.ForceLogout = false; await Context.SaveChangesAsync(); } Context.Entry(_user).State = EntityState.Detached; return new OperationResult(); } return new OperationResult(new Exception("Benutzername oder Passwort falsch")); } #endregion #region Public Method Logout /// /// Logouts this instance (a. beging, 04.04.2022) /// /// A task containing the operation result public async Task Logout() { try { await _localStorageService.RemoveItem(StorageKeys.TokenKey); _user = null; ((TokenAuthStateProvider) _authenticationStateProvider).MarkUserAsLoggedOut(); return new OperationResult(); } catch (Exception e) { return new OperationResult(e); } } #endregion #region Public Method RefreshState /// /// Refreshes the state (a. beging, 21.05.2022) /// public async Task RefreshState() { if (_user == null) return; _user = await Context.Users?.FirstOrDefaultAsync(x => x.Id == _user.Id)!; if (_user != null) { var serializedToken = AuthHelper.CreateToken(_user); await _localStorageService.SetItem(StorageKeys.TokenKey, serializedToken); } } #endregion } }