From 623d9d3e6dfc410be3febf2aa7f9c9ec87e7923d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 15 Jul 2024 12:04:28 +0200 Subject: [PATCH] Uldate filtraggio ruoli e nomi utente --- LiMan.DB/Controllers/DbController.cs | 14 +- LiMan.Transfer/Resources/ChangeLog.html | 2 +- LiMan.Transfer/Resources/VersNum.txt | 2 +- LiMan.Transfer/Resources/manifest.xml | 2 +- LiMan.UI/Components/UserMan.razor | 198 ++++++++++ LiMan.UI/Components/UserMan.razor.cs | 466 ++++++++++++++++++++++++ LiMan.UI/Data/LiManDataService.cs | 56 ++- LiMan.UI/LiMan.UI.csproj | 2 +- LiMan.UI/Pages/UserAdmin.razor | 4 + LiMan.UI/Pages/UserAdmin.razor.cs | 26 ++ LiMan.UI/Resources/ChangeLog.html | 2 +- LiMan.UI/Resources/VersNum.txt | 2 +- LiMan.UI/Resources/manifest.xml | 2 +- LiMan.UI/Shared/NavMenu.razor | 15 +- LiMan.UI/_Imports.razor | 1 + LiMan.UI/appsettings.json | 3 +- 16 files changed, 782 insertions(+), 15 deletions(-) create mode 100644 LiMan.UI/Components/UserMan.razor create mode 100644 LiMan.UI/Components/UserMan.razor.cs create mode 100644 LiMan.UI/Pages/UserAdmin.razor create mode 100644 LiMan.UI/Pages/UserAdmin.razor.cs diff --git a/LiMan.DB/Controllers/DbController.cs b/LiMan.DB/Controllers/DbController.cs index d302135..ddd27ad 100644 --- a/LiMan.DB/Controllers/DbController.cs +++ b/LiMan.DB/Controllers/DbController.cs @@ -385,12 +385,24 @@ namespace LiMan.DB.Controllers return answ; } + public List AuthUserAll() + { + List dbResult = new List(); + using (LMDbContext localDbCtx = new LMDbContext(_configuration)) + { + dbResult = localDbCtx + .DbSetUsers + .Include(c => c.Claims) + .ThenInclude(r => r.RoleNav) + .ToList(); + } + return dbResult; + } public List AuthUserGetFilt(string userName) { List dbResult = new List(); using (LMDbContext localDbCtx = new LMDbContext(_configuration)) { - DateTime oggi = DateTime.Today; dbResult = localDbCtx .DbSetUsers .Where(x => x.Username == userName) diff --git a/LiMan.Transfer/Resources/ChangeLog.html b/LiMan.Transfer/Resources/ChangeLog.html index be754f2..04a1350 100644 --- a/LiMan.Transfer/Resources/ChangeLog.html +++ b/LiMan.Transfer/Resources/ChangeLog.html @@ -1,6 +1,6 @@ License Manager -

Versione: 1.1.2407.1511

+

Versione: 1.1.2407.1512


Note di rilascio:
    diff --git a/LiMan.Transfer/Resources/VersNum.txt b/LiMan.Transfer/Resources/VersNum.txt index e3303b0..0dbc86e 100644 --- a/LiMan.Transfer/Resources/VersNum.txt +++ b/LiMan.Transfer/Resources/VersNum.txt @@ -1 +1 @@ -1.1.2407.1511 +1.1.2407.1512 diff --git a/LiMan.Transfer/Resources/manifest.xml b/LiMan.Transfer/Resources/manifest.xml index 4243068..dc8a591 100644 --- a/LiMan.Transfer/Resources/manifest.xml +++ b/LiMan.Transfer/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.1.2407.1511 + 1.1.2407.1512 https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.Transfer.zip https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html false diff --git a/LiMan.UI/Components/UserMan.razor b/LiMan.UI/Components/UserMan.razor new file mode 100644 index 0000000..4843d8f --- /dev/null +++ b/LiMan.UI/Components/UserMan.razor @@ -0,0 +1,198 @@ +@if (ShowPopup) +{ + +} +
    +
    +
    +
    +

    User Administration

    +
    +
    +
    + + + @* + + @if (@context.User.IsInRole("SuperAdmin")) + { + + } + + *@ +
    +
    +
    +
    +
    + + + + + + + + + + + + + + @foreach (var user in UsersList) + { + + + + + + + + + } + +
    AD UserCognomeNomeRuolo
    + @if (!ShowPopup) + { + + } + else + { + + } + @user.Username + @user.Cognome + + @user.Nome + + @ShowRoles(user.Claims.ToList()) + + @if (!ShowPopup) + { + + } + else + { + + } +
    +
    + +
    \ No newline at end of file diff --git a/LiMan.UI/Components/UserMan.razor.cs b/LiMan.UI/Components/UserMan.razor.cs new file mode 100644 index 0000000..892aa2c --- /dev/null +++ b/LiMan.UI/Components/UserMan.razor.cs @@ -0,0 +1,466 @@ +using LiMan.UI.Data; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Configuration; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using System; +using LiMan.DB.DBModels; + +namespace LiMan.UI.Components +{ + public partial class UserMan : IDisposable + { + #region Public Methods + + + public void Dispose() + { + AppMService.EA_SearchUpdated -= AppMService_EA_SearchUpdated; + } + + [Inject] + protected LiManDataService DataService { get; set; } = null!; + /// + /// Recupera elenco utenti + /// + public async Task GetUsers() + { + // clear any error messages + strError = ""; + + UsersAll = await DataService.AuthUserAll(); + + // filtro visualizzazione x tipo SE richeisto + if (FiltUserRole > 0) + { + UsersAll = UsersAll.Where(x => x.Claims.Any(c => c.RoleID == FiltUserRole)).ToList(); + } + // se c'è search,,, + if (!string.IsNullOrEmpty(currSearch)) + { + UsersAll = UsersAll + .Where(x => x.Cognome.Contains(currSearch, StringComparison.CurrentCultureIgnoreCase) + || x.Nome.Contains(currSearch, StringComparison.CurrentCultureIgnoreCase) + || x.Username.Contains(currSearch, StringComparison.CurrentCultureIgnoreCase)) + .ToList(); + } + + totalCount = UsersAll.Count; + + UsersList = UsersAll + .Skip(numRecord * (currPage - 1)).Take(numRecord) + .ToList(); + } + + + public string ShowRoles(List ClaimList) + { + string answ = ""; + foreach (var item in ClaimList) + { + answ += $"{item.RoleNav.Ruolo}, "; + } + if (answ.Length > 2) + { + answ = answ.Substring(0, answ.Length - 2); + } + return answ; + } + + #endregion Public Methods + + #region Protected Properties + + + [Inject] + protected MessageService AppMService { get; set; } = null!; + + protected int totalCount { get; set; } = 0; + + #endregion Protected Properties + + #region Protected Methods + + protected void DoSelect(AuthUserModel? selItem) + { +#if false + if (selItem != null) + { + ProjDbId = selItem.ProjDbId; + } + else + { + ProjDbId = 0; + } + E_ProjSel.InvokeAsync(selItem); +#endif + } + + protected override async Task OnInitializedAsync() + { + currSearch = ""; + string rawConf = Configuration["RuntimeOpt:MultiRoleEnab"]; + if (rawConf != null) + { + bool.TryParse(rawConf, out MultiRoleEnab); + } + AppMService.EA_SearchUpdated += AppMService_EA_SearchUpdated; + // lettura dati + await GetUsers(); + await refreshLists(); + } + + protected async Task SetNumRec(int newNum) + { + numRecord = newNum; + currPage = 1; + await InvokeAsync(ReloadData); + } + + protected async Task SetPage(int newNum) + { + currPage = newNum; + DoSelect(null); + await InvokeAsync(ReloadData); + } + + #endregion Protected Methods + + #region Private Fields + + private const string ADMIN_ROLE = "Admin"; + + private const string UNDEF_ROLE = "Undef"; + + + private string currSearch = ""; + + + /// + /// Abilitazione gestione ROLES multipli + /// + private bool MultiRoleEnab = true; + + /// + /// User corrente + /// + private IdentityUser objUser = new IdentityUser(); + + private string qrCodeVal = ""; + + /// + /// Elenco ROLES da mostrare in dropdown durante editing (usare DB?) + /// + private List RolesList = new List(); + + // 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 + /// + private List UsersList = new List(); + + #endregion Private Fields + + #region Private Properties + + private int _filtUserRole { get; set; } = 0; + + [Inject] + private IConfiguration Configuration { get; set; } = null!; + + + + + /// + /// Ruolo di default (User!!!) + /// + private string CurrentUserRole { get; set; } = "User"; + + private int currPage { get; set; } = 1; + + /// + /// Ruoli correnti utente + /// + private string[] CurrUserRoles { get; set; } = new string[] { "User" }; + + /// + /// Gestione filtraggio dati + /// + private int 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; set; } = 10; + + #endregion Private Properties + + #region Private Methods + + private void AddNewUser() + { + // Make new user + objUser = new IdentityUser(); + objUser.PasswordHash = "*****"; + // Set Id to blank so we know it is a new record + objUser.Id = ""; + // Open the Popup + ShowPopup = true; + } + + private async void AppMService_EA_SearchUpdated() + { + currSearch = AppMService.SearchVal; + await ReloadData(); + } + + private async Task ClosePopup() + { + // Close the Popup + ShowPopup = false; + // Refresh Users + await GetUsers(); + } + + private async Task DeleteUser(AuthUserModel _currRec) + { +#if false + // Close the Popup + ShowPopup = false; + + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare l'utente selezionato??")) + return; + + // Get the user + var user = await _UserManager.FindByIdAsync(_IdentityUser.Id); + if (user != null) + { + // Delete the user + await _UserManager.DeleteAsync(user); + } +#endif + // Refresh Users + await GetUsers(); + } + + private void EditUser(AuthUserModel _currRec) + { + // Open the Popup + ShowPopup = true; + } + + private async Task refreshLists() + { + RolesList = await DataService.AuthRolesGetAll(); + } + + private async Task ReloadData() + { + isLoading = true; + await GetUsers(); + isLoading = false; + } + + private async Task SaveUser() + { + try + { +#if false + // 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.Succeeded) + { + if (passworduser.Errors.FirstOrDefault() != null) + { + strError = + passworduser + .Errors + .FirstOrDefault() + .Description; + } + else + { + strError = "Password error"; + } + // Keep the popup opened + return; + } + } + // Gestione salvataggio ruoli... SE VARIATO... + var UserRoles = await _UserManager.GetRolesAsync(user); + if (!MultiRoleEnab) + { + 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); + } + } + else + { + // verifico ruoli costanti... + var listOk = UserRoles.Intersect(CurrUserRoles).ToList(); + var list2del = UserRoles.Except(listOk).ToList(); + var list2add = CurrUserRoles.Except(listOk).ToList(); + // elimino + foreach (var item in list2del) + { + await _UserManager.RemoveFromRoleAsync(user, item); + } + // aggiungo + foreach (var item in list2add) + { + await _UserManager.AddToRoleAsync(user, item); + } + } + + // gestione salvataggio Claims + var UserClaims = await _UserManager.GetClaimsAsync(user); + if (!MultiClaimEnab) + { + if (UserClaims != null && UserClaims.Count > 0) + { + var oldClaim = UserClaims.FirstOrDefault(); + if (!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 + { + // elimino i vecchi claims non presenti nel nuovo... + var listClaimsMod = CurrentUserClaims.Select(x => new Claim(x.Type, x.Value)).ToList(); + var listOk = UserClaims.Intersect(listClaimsMod).ToList(); + var list2del = UserClaims.Except(listOk).ToList(); + var list2add = listClaimsMod.Except(listOk).ToList(); + // elimino + foreach (var item in list2del) + { + await _UserManager.RemoveClaimAsync(user, item); + } + // aggiungo + foreach (var item in list2add) + { + await _UserManager.AddClaimAsync(user, item); + } + } + } + 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) + { + if (CreateResult + .Errors + .FirstOrDefault() != null) + { + strError = + CreateResult + .Errors + .FirstOrDefault() + .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; + // refresh cache... + await MTService.ResetUserDataCache(); +#endif + // Refresh Users + await GetUsers(); + } + catch (Exception ex) + { + strError = ex.GetBaseException().Message; + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/LiMan.UI/Data/LiManDataService.cs b/LiMan.UI/Data/LiManDataService.cs index 6d278d2..fc730c1 100644 --- a/LiMan.UI/Data/LiManDataService.cs +++ b/LiMan.UI/Data/LiManDataService.cs @@ -372,6 +372,60 @@ namespace LiMan.UI.Data return fatto; } + + /// + /// Recupera elenco Utenti (tutti) + /// + /// + public async Task> AuthUserAll() + { + string source = "DB"; + List? dbResult = new List(); + try + { + string currKey = $"{Const.rKeyConfig}:Auth:UsersList"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + string? rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + if (tempResult == null) + { + dbResult = new List(); + } + else + { + dbResult = tempResult; + } + } + else + { + dbResult = dbControllerNext.AuthUserAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); + // per evitare loopback uso deserialize... + var tempResult = JsonConvert.DeserializeObject>(rawData); + if (tempResult != null) + { + dbResult = tempResult; + } + } + if (dbResult == null) + { + dbResult = new List(); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"AuthUserAll | {source} in: {ts.TotalMilliseconds} ms"); + } + catch (Exception exc) + { + Log.Error($"Error during AuthUserAll:{Environment.NewLine}{exc}"); + } + return dbResult; + } /// /// Recupera elenco Utenti UserName (idealmente 1...) /// @@ -383,7 +437,7 @@ namespace LiMan.UI.Data List? dbResult = new List(); try { - string currKey = $"{Const.rKeyConfig}:Auth:Users:{userName}"; + string currKey = $"{Const.rKeyConfig}:Auth:User:{userName}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); diff --git a/LiMan.UI/LiMan.UI.csproj b/LiMan.UI/LiMan.UI.csproj index a6e2f3b..b6055a7 100644 --- a/LiMan.UI/LiMan.UI.csproj +++ b/LiMan.UI/LiMan.UI.csproj @@ -2,7 +2,7 @@ net6.0 - 1.1.2407.1511 + 1.1.2407.1512 LiMan.UI LiMan.UI diff --git a/LiMan.UI/Pages/UserAdmin.razor b/LiMan.UI/Pages/UserAdmin.razor new file mode 100644 index 0000000..4705189 --- /dev/null +++ b/LiMan.UI/Pages/UserAdmin.razor @@ -0,0 +1,4 @@ +@page "/UserAdmin" +@attribute [Authorize] + + \ No newline at end of file diff --git a/LiMan.UI/Pages/UserAdmin.razor.cs b/LiMan.UI/Pages/UserAdmin.razor.cs new file mode 100644 index 0000000..b05f9ff --- /dev/null +++ b/LiMan.UI/Pages/UserAdmin.razor.cs @@ -0,0 +1,26 @@ +using LiMan.UI.Data; +using Microsoft.AspNetCore.Components; + +namespace LiMan.UI.Pages +{ + public partial class UserAdmin + { + #region Protected Properties + + [Inject] + protected MessageService AppMService { get; set; } = null!; + + #endregion Protected Properties + + #region Protected Methods + + protected override void OnInitialized() + { + AppMService.ShowSearch = false; + AppMService.PageName = "Gestione Utenti"; + AppMService.PageIcon = "fas fa-users"; + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/LiMan.UI/Resources/ChangeLog.html b/LiMan.UI/Resources/ChangeLog.html index 1688811..80fdaac 100644 --- a/LiMan.UI/Resources/ChangeLog.html +++ b/LiMan.UI/Resources/ChangeLog.html @@ -1,6 +1,6 @@ License Manager -

    Versione: 1.1.2407.1511

    +

    Versione: 1.1.2407.1512


    Note di rilascio:
    • diff --git a/LiMan.UI/Resources/VersNum.txt b/LiMan.UI/Resources/VersNum.txt index e3303b0..0dbc86e 100644 --- a/LiMan.UI/Resources/VersNum.txt +++ b/LiMan.UI/Resources/VersNum.txt @@ -1 +1 @@ -1.1.2407.1511 +1.1.2407.1512 diff --git a/LiMan.UI/Resources/manifest.xml b/LiMan.UI/Resources/manifest.xml index d1a820c..f0ab127 100644 --- a/LiMan.UI/Resources/manifest.xml +++ b/LiMan.UI/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.1.2407.1511 + 1.1.2407.1512 https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html false diff --git a/LiMan.UI/Shared/NavMenu.razor b/LiMan.UI/Shared/NavMenu.razor index 83e856f..22bd6fa 100644 --- a/LiMan.UI/Shared/NavMenu.razor +++ b/LiMan.UI/Shared/NavMenu.razor @@ -14,6 +14,11 @@
    • + @if (UserHasClaim("SuperUser") || UserHasClaim("Admin")) { + } -