using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.JSInterop; using System.Security.Claims; using WebDoorCreator.Data.DbModels; using WebDoorCreator.Data.Services; using WebDoorCreator.Data.User; using WebDoorCreator.UI.Data; using NLog; namespace WebDoorCreator.UI.Pages { [Authorize(Roles = "SuperAdmin, DcaAdmin, CompAdmin")] public partial class UserAdmin : ComponentBase, IDisposable { #region Public Fields public const string ADMIN_ROLE = "SuperAdmin"; public const string STD_CLAIM = "None"; public const string STD_CLAIM_VAL = "0"; public const string UNDEF_ROLE = "Undef"; #endregion Public Fields #region Public Methods public List ConvertClaim(List ClaimList) { List answ = new List(); // ciclo sui claims foreach (var claim in ClaimList) { string claimStr = claim.ToString(); // verifico che in OGNI claim ci siaun valore ammissibile... if (claimStr.Contains(":")) { // splitto chiave/valore var splitClaim = claimStr.Split(':'); switch (splitClaim[0]) { case "CompanyId": if (CompanyList != null) { var compRec = CompanyList .Where(x => $"{x.CompanyId}" == splitClaim[1].Trim()) .FirstOrDefault(); if (compRec != null) { answ.Add($"{splitClaim[0]}: {compRec.CompanyName}"); } else { answ.Add($"{claim}"); } } break; case "None": default: break; } } } return answ; } public void Dispose() { } /// /// Recupera elenco utenti /// public async Task GetUsers() { // clear any error messages strError = ""; UsersAll = await UMService.UserDataGetFilt(searchVal); // filtro visualizzazione x RUOLO, SE richeisto if (FiltUserRole != "0") { UsersAll = UsersAll.Where(x => x.Roles.Contains(FiltUserRole)).ToList(); } // filtro visualizzazione x Company, SE richeisto if (FiltCompany != "0") { UsersAll = UsersAll .Where(x => x.Claims.Any(c => c.Type == "CompanyId" && c.Value == $"{FiltCompany}")) .ToList(); } UsersList = UsersAll .Skip(numRecord * (currPage - 1)).Take(numRecord) .ToList(); } public async void OnSeachUpdated() { await ReloadData(); StateHasChanged(); } public string ShowClaims(List ClaimList) { string answ = string.Join(",", ConvertClaim(ClaimList)); return answ; } public string ShowRoles(List RoleList) { string answ = string.Join(",", RoleList); return answ; } public async Task ToggleCodeDetails() { showCodeDetails = !showCodeDetails; await Task.Delay(1); } public string userCss(bool isInactive) { return isInactive ? "text-secondary text-decoration-line-through" : "text-dark"; } #endregion Public Methods #region Protected Properties [Inject] protected RoleManager _RoleManager { get; set; } = null!; [Inject] protected UserManager _UserManager { get; set; } = null!; [Inject] protected AuthenticationStateProvider AuthenticationStateProvider { get; set; } = null!; protected string btnShowDetails { get => showCodeDetails ? "Hide User Code" : "Show User Code"; } protected List CompanyList { get; set; } = new List(); protected IdentityUser currUser { get; set; } = new IdentityUser(); [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; protected string searchVal { get => _searchVal; set { if (value != _searchVal) { _searchVal = value; var pUpd = Task.Run(async () => { await ReloadData(); }); pUpd.Wait(); } } } protected bool showCodeDetails { get; set; } = false; protected int totalCount { get { int answ = 0; if (UsersAll != null) { answ = UsersAll.Count; } return answ; } } [Inject] protected UserManDataService UMService { get; set; } = null!; [Inject] protected WebDoorCreatorService WDCService { get; set; } = null!; [Inject] protected WDCUserService WDCUsrServ { get; set; } = null!; #endregion Protected Properties #region Protected Methods protected void ForceReload(int newNum) { numRecord = newNum; } protected void ForceReloadPage(int newNum) { currPage = newNum; } protected override async Task OnInitializedAsync() { searchVal = ""; CurrentUserClaimType = WDCUsrServ.userCurrComp.ToString(); // lettura dati await ReloadData(); } protected void resetSearch() { searchVal = ""; } #endregion Protected Methods #region Private Fields /// /// Elenco CLAIMS da mostrare durante editing /// private List ClaimsList = new List() { STD_CLAIM, "CompanyId" }; private Dictionary ClaimValList = new Dictionary(); /// /// User corrente /// private IdentityUser objUser = new IdentityUser(); private string qrCodeVal = ""; /// /// Elenco ROLES da mostrare in dropdown durante editing (1 solo? usare DB?!?) /// private List RolesList = new List() { "Undef", "User", "CompUser", "CompAdmin" }; // To enable showing the Popup private bool ShowPopup = false; // To hold any possible errors private string strError = ""; /// /// Collezione utenti (totale) /// private List UsersAll = new List(); /// /// Collezione utenti /// /// filtrati/mostrati private List UsersList = new List(); #endregion Private Fields #region Private Properties private string _CurrClaimType { get; set; } = "None"; private int _currPage { get; set; } = 1; private string _filtCompanyId { get; set; } = "0"; private string _filtUserRole { get; set; } = "0"; private int _numRecord { get; set; } = 10; private string _searchVal { get; set; } = ""; [CascadingParameter] private Task authenticationStateTask { get; set; } = null!; [Inject] private IConfiguration Configuration { get; set; } = null!; private Claim CurrentUserClaim { get => new Claim(CurrentUserClaimType, CurrentUserClaimVal); } /// /// Claim di default (Tipo) /// private string CurrentUserClaimType { get { return _CurrClaimType; } set { _CurrClaimType = value; var pUpd = Task.Run(async () => await refreshClaimVal(value)); pUpd.Wait(); } } /// /// Claim di default (valore) /// private string CurrentUserClaimVal { get; set; } = "0"; /// /// Ruolo di default (User!!!) /// private string CurrentUserRole { get; set; } = "User"; private int currPage { get => _currPage; set { if (_currPage != value) { _currPage = value; var pUpd = Task.Run(async () => await ReloadData()); pUpd.Wait(); } } } private string currUserRole { get => WDCUsrServ.userRole; } /// /// Gestione filtraggio COMPANY /// private string FiltCompany { get { return _filtCompanyId; } set { if (_filtCompanyId != value) { _filtCompanyId = value; var pUpd = Task.Run(async () => await ReloadData()); pUpd.Wait(); } } } /// /// Gestione filtraggio RUOLI utente /// private string FiltUserRole { get { return _filtUserRole; } set { if (_filtUserRole != value) { _filtUserRole = value; var pUpd = Task.Run(async () => await ReloadData()); pUpd.Wait(); } } } private bool isLoading { get; set; } = false; private int numRecord { get => _numRecord; set { if (_numRecord != value) { _numRecord = value; var pUpd = Task.Run(async () => await ReloadData()); pUpd.Wait(); } } } #endregion Private Properties #region Private Methods private void AddNewUser() { // Make new user objUser = new IdentityUser(); objUser.PasswordHash = "*****"; // set confermato objUser.EmailConfirmed = true; // Set Id to blank so we know it is a new record objUser.Id = ""; // hide dettaglio qrcode/clipboard... showCodeDetails = false; // Apro popup ShowPopup = true; } private async Task ClosePopup() { // Close the Popup ShowPopup = false; // Refresh page await ReloadData(); } private async Task DeleteUser(IdentityUser _IdentityUser) { // Close the Popup ShowPopup = false; if (!await JSRuntime.InvokeAsync("confirm", "Are sure you want to DELETE selected user??")) return; // Get the user var user = await _UserManager.FindByIdAsync(_IdentityUser.Id); if (user != null) { // Delete the user await _UserManager.DeleteAsync(user); // reset cache! await UMService.ResetUserDataCache(true); } // Refresh Users await ReloadData(); } private async Task DisableUser(IdentityUser _IdentityUser) { // Close the Popup ShowPopup = false; if (!await JSRuntime.InvokeAsync("confirm", "Are sure you want to disable selected user?")) return; // Get the user var user = await _UserManager.FindByIdAsync(_IdentityUser.Id); if (user != null) { user.LockoutEnabled = true; user.LockoutEnd = DateTime.Today.AddYears(100); // Update the user await _UserManager.UpdateAsync(user); // reset cache! await UMService.ResetUserDataCache(true); } // Refresh Users await ReloadData(); } private void EditUser(IdentityUser _IdentityUser) { // selezione come current user objUser = _IdentityUser; var pUpd = Task.Run(async () => { var user = await UMService.UserDataGetById(objUser.Id); if (user != null) { // salvo role if (user.Roles != null) { var fRole = user.Roles.FirstOrDefault(); CurrentUserRole = fRole != null ? fRole : UNDEF_ROLE; } else { CurrentUserRole = UNDEF_ROLE; } // salvo claim if (user.Claims != null && user.Claims.Count > 0) { var CurrentUserClaim = user.Claims.FirstOrDefault(); if (CurrentUserClaim != null) { CurrentUserClaimType = CurrentUserClaim.Type; CurrentUserClaimVal = CurrentUserClaim.Value; } } else { CurrentUserClaimType = STD_CLAIM; CurrentUserClaimVal = "0"; } string baseUrl = Configuration["BaseUrl"]; string baseAppPath = Configuration["BaseAppPath"]; string redirPage = Configuration["QrRedirPage"]; if (!string.IsNullOrEmpty(baseAppPath)) { if (baseUrl.EndsWith("/")) { baseUrl = baseUrl.Substring(0, baseUrl.Length - 1); } baseUrl = $"{baseUrl}{baseAppPath}"; } qrCodeVal = $"{baseUrl}Identity/Account/LogIn?uid={user.Identity.Id}&uem={user.Identity.Email}&pag={redirPage}"; } }); pUpd.Wait(); // Open the Popup showCodeDetails = false; ShowPopup = true; } private async Task EnableUser(IdentityUser _IdentityUser) { // Close the Popup ShowPopup = false; // Get the user var user = await _UserManager.FindByIdAsync(_IdentityUser.Id); if (user != null) { user.LockoutEnabled = false; user.LockoutEnd = DateTime.Today.AddYears(-10); // Update the user await _UserManager.UpdateAsync(user); // reset cache! await UMService.ResetUserDataCache(true); } // Refresh Users await ReloadData(); } private async Task refreshClaimVal(string newType) { // init vuoto ClaimValList = new Dictionary(); // aggiorno elenco ClaimValList switch (newType) { case "CompanyId": // elenco company (tutte, ID==0) --> to dictionary! var compList = await WDCService.CompanyGetByKey(0); if (compList != null) { ClaimValList = compList .ToDictionary(x => $"{x.CompanyId}", x => x.CompanyName); } break; case "None": default: break; } } private async Task refreshLists() { // effettuo refresh valori cache Company... if (CompanyList == null || CompanyList.Count == 0) { CompanyList = await WDCService.CompanyGetByKey(0); } // sistemo elenco ruoli dato livello utente... RolesList = new List() { "Undef", "User", "CompUser", "CompAdmin" }; if (currUserRole == "SuperAdmin") { RolesList.Add("DcaOrdMan"); RolesList.Add("DcaProj"); RolesList.Add("DcaAdmin"); RolesList.Add("SuperAdmin"); } else if (currUserRole == "DcaAdmin") { RolesList.Add("DcaOrdMan"); RolesList.Add("DcaProj"); RolesList.Add("DcaAdmin"); } else { FiltCompany = $"{WDCUsrServ.userCurrComp}"; CompanyList = await WDCService.CompanyGetByKey(WDCUsrServ.userCurrComp); } } private async Task ReloadData() { isLoading = true; await refreshLists(); await GetUsers(); isLoading = false; } private async Task SaveUser() { try { // Is this an existing user? if (objUser.Id != "") { // Get the user var user = await _UserManager.FindByIdAsync(objUser.Id); // Update Email + check email user.Email = objUser.Email; user.EmailConfirmed = objUser.EmailConfirmed; // Update the user await _UserManager.UpdateAsync(user); // Only update password if the current value is not the default value if (objUser.PasswordHash != "*****") { var resetToken = await _UserManager.GeneratePasswordResetTokenAsync(user); var passworduser = await _UserManager.ResetPasswordAsync( user, resetToken, objUser.PasswordHash); if (passworduser != null && !passworduser.Succeeded) { var errore = passworduser.Errors.FirstOrDefault(); if (errore != null) { strError = errore.Description; } else { strError = "Password error"; } // Keep the popup opened return; } } // Gestione salvataggio ruoli... SE VARIATO... var UserRoles = await _UserManager.GetRolesAsync(user); if (UserRoles != null && UserRoles.Count > 0) { var oldRole = UserRoles.FirstOrDefault(); if (!CurrentUserRole.Equals(oldRole)) { // recupero il ruolo attuale e lo rimuovo await _UserManager.RemoveFromRoleAsync(user, oldRole); } // aggiungo il nuovo ruolo await _UserManager.AddToRoleAsync(user, CurrentUserRole); } else { // aggiungo il nuovo ruolo await _UserManager.AddToRoleAsync(user, CurrentUserRole); } // gestione salvataggio Claims var UserClaims = await _UserManager.GetClaimsAsync(user); if (UserClaims != null && UserClaims.Count > 0) { var oldClaim = UserClaims.FirstOrDefault(); if (oldClaim != null && !oldClaim.Equals(CurrentUserClaim)) { // recupero il ruolo attuale e lo rimuovo await _UserManager.RemoveClaimAsync(user, oldClaim); } // aggiungo il nuovo ruolo await _UserManager.AddClaimAsync(user, CurrentUserClaim); } else { // aggiungo il nuovo ruolo await _UserManager.AddClaimAsync(user, CurrentUserClaim); } } else { // Insert new user var NewUser = new IdentityUser { UserName = objUser.Email, Email = objUser.Email }; var CreateResult = await _UserManager.CreateAsync(NewUser, objUser.PasswordHash); if (!CreateResult.Succeeded) { var currresErr = CreateResult.Errors.FirstOrDefault(); if (currresErr != null) { strError = currresErr.Description; } else { strError = "Create error"; } // Keep the popup opened return; } else { // aggiungo a ruolo undef await _UserManager.AddToRoleAsync(NewUser, UNDEF_ROLE); // aggiungo claim undef... await _UserManager.AddClaimAsync(NewUser, CurrentUserClaim); } } // Close the Popup ShowPopup = false; // reset cache! await UMService.ResetUserDataCache(true); // Refresh page await ReloadData(); } catch (Exception ex) { strError = ex.GetBaseException().Message; Log.Error($"{strError}{Environment.NewLine}"); } } private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Methods } }