Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b7b86b655 | |||
| 387bff34e2 | |||
| aff6a89b73 | |||
| 335557eb7c | |||
| f0405cfbe3 |
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>WebDoorCreator - Egalware</i>
|
||||
<h4>Version: 0.9.2305.2612</h4>
|
||||
<h4>Version: 0.9.2305.2619</h4>
|
||||
<br /> Release note:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.9.2305.2612
|
||||
0.9.2305.2619
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>0.9.2305.2612</version>
|
||||
<version>0.9.2305.2619</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/WDC/stable/WDC.UI.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/WDC/stable/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace WebDoorCreator.Core
|
||||
public const string rKeyOrderStatus = $"{redisBaseAddr}:Cache:OrderStatus";
|
||||
public const string rKeyRoles = $"{redisBaseAddr}:Cache:Roles";
|
||||
public const string rKeyUsers = $"{redisBaseAddr}:Cache:Users";
|
||||
public const string rKeyUsersAll = $"{redisBaseAddr}:Cache:UsersAll";
|
||||
public const string rKeyUsersDataId = $"{redisBaseAddr}:Cache:UsersData:Id";
|
||||
public const string rKeyUsersDataSearch = $"{redisBaseAddr}:Cache:UsersData:Search";
|
||||
public const string rKeyUsersView = $"{redisBaseAddr}:Cache:UsersView";
|
||||
public const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma";
|
||||
public const string rKeyLanguage = $"{redisBaseAddr}:Cache:Languages";
|
||||
|
||||
@@ -84,20 +84,6 @@ namespace WebDoorCreator.Data.Services
|
||||
await Task.Delay(1);
|
||||
return dbResult;
|
||||
}
|
||||
/// <summary>
|
||||
/// Update company
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> UserAddMod(AspNetUsers currRec)
|
||||
{
|
||||
var dbResult = await dbController.UserAddMod(currRec);
|
||||
// elimino cache redis...
|
||||
RedisValue pattern = new RedisValue($"{Constants.rKeyCompany}");
|
||||
bool answ = await ExecFlushRedisPattern(pattern);
|
||||
await Task.Delay(1);
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Company list filtered by company id
|
||||
@@ -2067,6 +2053,21 @@ namespace WebDoorCreator.Data.Services
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update company
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> UserAddMod(AspNetUsers currRec)
|
||||
{
|
||||
var dbResult = await dbController.UserAddMod(currRec);
|
||||
// elimino cache redis...
|
||||
RedisValue pattern = new RedisValue($"{Constants.rKeyCompany}");
|
||||
bool answ = await ExecFlushRedisPattern(pattern);
|
||||
await Task.Delay(1);
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Users roles list
|
||||
/// </summary>
|
||||
@@ -2279,12 +2280,6 @@ namespace WebDoorCreator.Data.Services
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected Random rnd = new Random();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected WebDoorCreator.Data.DDF.Converter currDdfConv { get; set; } = null!;
|
||||
@@ -2294,11 +2289,8 @@ namespace WebDoorCreator.Data.Services
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration _configuration = null!;
|
||||
|
||||
private static JsonSerializerSettings? JSSettings;
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly IEmailSender _emailSender;
|
||||
|
||||
/// <summary>
|
||||
@@ -2321,6 +2313,8 @@ namespace WebDoorCreator.Data.Services
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private Random rnd = new Random();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WebDoorCreator.Data.User
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe generalizzaizone identity (user + roles + claims) x gestione semplificata in editing
|
||||
/// </summary>
|
||||
public class UserData
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public List<System.Security.Claims.Claim> Claims { get; set; } = new List<System.Security.Claims.Claim>();
|
||||
|
||||
public IdentityUser Identity { get; set; } = null!;
|
||||
|
||||
public List<string> Roles { get; set; } = new List<string>();
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,11 @@
|
||||
<!--Hiding to non-SuperAdmin users the option to manage the application -->
|
||||
<AuthorizeView Roles="SuperAdmin" Context="MenuHide">
|
||||
<Authorized>
|
||||
<div class="nav-item px-3 d-flex flex-warp align-items-center">
|
||||
<NavLink class="nav-link" href="UserAdmin">
|
||||
<span class="bi bi-people pe-2" aria-hidden="true"></span> User management
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3 d-flex flex-warp align-items-center">
|
||||
<NavLink class="nav-link" href="SuperAdmin">
|
||||
<span class="oi oi-list-rich" aria-hidden="true"></span> General management
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace WebDoorCreator.UI.Components.Gen
|
||||
reportVocLemmas();
|
||||
}
|
||||
}
|
||||
[Inject]
|
||||
public NavigationManager NavManager { get; set; } = default!;
|
||||
|
||||
public List<string>? userClaimsList
|
||||
{
|
||||
@@ -229,51 +231,57 @@ namespace WebDoorCreator.UI.Components.Gen
|
||||
// reset preliminare
|
||||
listRecord = new List<string>();
|
||||
listCompanies = new List<CompanyModel>();
|
||||
if (!string.IsNullOrEmpty(userId) && string.IsNullOrEmpty(userRole))
|
||||
if (!NavManager.Uri.Contains("UserAdmin"))
|
||||
{
|
||||
var user = await _userManager.FindByNameAsync(userId);
|
||||
var roleList = await _userManager.GetRolesAsync(user);
|
||||
if (roleList != null)
|
||||
if (!string.IsNullOrEmpty(userId) && string.IsNullOrEmpty(userRole))
|
||||
{
|
||||
var role = roleList.FirstOrDefault();
|
||||
if (role != null)
|
||||
{
|
||||
userRole = role;
|
||||
}
|
||||
}
|
||||
var claimsList = await _userManager.GetClaimsAsync(user);
|
||||
// FARE!!! rivedere con await WDCUsrServ.UserDataGetById(userId);
|
||||
|
||||
if (claimsList != null)
|
||||
{
|
||||
if (userRole == "SuperAdmin")
|
||||
|
||||
var user = await _userManager.FindByNameAsync(userId);
|
||||
var roleList = await _userManager.GetRolesAsync(user);
|
||||
if (roleList != null)
|
||||
{
|
||||
listCompanies = await WDCService.CompanyGetByKey(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (claimsList.Count > 1)
|
||||
var role = roleList.FirstOrDefault();
|
||||
if (role != null)
|
||||
{
|
||||
foreach (var item in claimsList)
|
||||
{
|
||||
listRecord.Add(item.Value);
|
||||
var rawList = await WDCService.CompanyGetByKey(int.Parse(item.Value));
|
||||
CompanyModel firstComp = rawList.FirstOrDefault() ?? new CompanyModel();
|
||||
listCompanies.Add(firstComp);
|
||||
}
|
||||
}
|
||||
else if (claimsList.Count == 1)
|
||||
{
|
||||
var currClaim = claimsList.FirstOrDefault();
|
||||
if (currClaim != null)
|
||||
{
|
||||
listRecord.Add(currClaim.Value);
|
||||
listCompanies = await WDCService.CompanyGetByKey(int.Parse(currClaim.Value));
|
||||
}
|
||||
compToShow = listCompanies?.FirstOrDefault()!;
|
||||
userRole = role;
|
||||
}
|
||||
}
|
||||
fixSelCompany();
|
||||
userClaimsList = listRecord;
|
||||
var claimsList = await _userManager.GetClaimsAsync(user);
|
||||
|
||||
if (claimsList != null)
|
||||
{
|
||||
if (userRole == "SuperAdmin")
|
||||
{
|
||||
listCompanies = await WDCService.CompanyGetByKey(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (claimsList.Count > 1)
|
||||
{
|
||||
foreach (var item in claimsList)
|
||||
{
|
||||
listRecord.Add(item.Value);
|
||||
var rawList = await WDCService.CompanyGetByKey(int.Parse(item.Value));
|
||||
CompanyModel firstComp = rawList.FirstOrDefault() ?? new CompanyModel();
|
||||
listCompanies.Add(firstComp);
|
||||
}
|
||||
}
|
||||
else if (claimsList.Count == 1)
|
||||
{
|
||||
var currClaim = claimsList.FirstOrDefault();
|
||||
if (currClaim != null)
|
||||
{
|
||||
listRecord.Add(currClaim.Value);
|
||||
listCompanies = await WDCService.CompanyGetByKey(int.Parse(currClaim.Value));
|
||||
}
|
||||
compToShow = listCompanies?.FirstOrDefault()!;
|
||||
}
|
||||
}
|
||||
fixSelCompany();
|
||||
userClaimsList = listRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
namespace WebDoorCreator.UI.Data
|
||||
{
|
||||
public class MessageService
|
||||
{
|
||||
#region Public Events
|
||||
|
||||
public event Action EA_HideSearch = null!;
|
||||
|
||||
public event Action EA_SearchUpdated = null!;
|
||||
|
||||
public event Action EA_ShowSearch = null!;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string SearchVal
|
||||
{
|
||||
get => _searchVal;
|
||||
set
|
||||
{
|
||||
if (_searchVal != value)
|
||||
{
|
||||
_searchVal = value;
|
||||
|
||||
if (EA_SearchUpdated != null)
|
||||
{
|
||||
EA_SearchUpdated?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowSearch
|
||||
{
|
||||
get => _showSearch;
|
||||
set
|
||||
{
|
||||
if (_showSearch != value)
|
||||
{
|
||||
_showSearch = value;
|
||||
if (_showSearch)
|
||||
{
|
||||
if (EA_ShowSearch != null)
|
||||
{
|
||||
EA_ShowSearch?.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EA_HideSearch != null)
|
||||
{
|
||||
EA_HideSearch?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private bool _showSearch;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string _searchVal { get; set; } = "";
|
||||
|
||||
#endregion Private Properties
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,61 @@
|
||||
namespace WebDoorCreator.UI.Data
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using WebDoorCreator.Core;
|
||||
using WebDoorCreator.Data.User;
|
||||
|
||||
namespace WebDoorCreator.UI.Data
|
||||
{
|
||||
public class WDCUserService
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public WDCUserService(IConnectionMultiplexer redisConnMult, UserManager<IdentityUser> userManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
// Conf cache
|
||||
redisConn = redisConnMult;
|
||||
redisDb = this.redisConn.GetDatabase();
|
||||
|
||||
// json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
|
||||
JSSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
||||
};
|
||||
// chiudo log
|
||||
Log.Info("Avviata classe WDCUserService");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Events
|
||||
|
||||
public event Action EA_UserId = null!;
|
||||
|
||||
public event Action EA_UserClaims = null!;
|
||||
|
||||
public event Action EA_UserRole = null!;
|
||||
|
||||
public event Action EA_UserCurrCompany = null!;
|
||||
|
||||
public event Action EA_CurrLanguage = null!;
|
||||
|
||||
public event Action EA_UserClaims = null!;
|
||||
|
||||
public event Action EA_UserCurrCompany = null!;
|
||||
|
||||
public event Action EA_UserId = null!;
|
||||
|
||||
public event Action EA_UserRole = null!;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public Dictionary<string, string> UserPref { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public string userId
|
||||
public string? currLanguage
|
||||
{
|
||||
get => _userId;
|
||||
get => _currLanguage;
|
||||
set
|
||||
{
|
||||
if (_userId != value)
|
||||
if (_currLanguage != value)
|
||||
{
|
||||
_userId = value;
|
||||
reportUserId();
|
||||
_currLanguage = value;
|
||||
reportCurrentLanguage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +73,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
public int userCurrComp
|
||||
{
|
||||
get => _userCurrComp;
|
||||
set
|
||||
{
|
||||
if (_userCurrComp != value)
|
||||
{
|
||||
_userCurrComp = value;
|
||||
reportUserCurrCompany();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string userId
|
||||
{
|
||||
get => _userId;
|
||||
set
|
||||
{
|
||||
if (_userId != value)
|
||||
{
|
||||
_userId = value;
|
||||
reportUserId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, string> UserPref { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public string userRole
|
||||
{
|
||||
get => _userRole;
|
||||
@@ -60,39 +114,205 @@
|
||||
}
|
||||
}
|
||||
|
||||
public int userCurrComp
|
||||
{
|
||||
get => _userCurrComp;
|
||||
set
|
||||
{
|
||||
if (_userCurrComp != value)
|
||||
{
|
||||
_userCurrComp = value;
|
||||
reportUserCurrCompany();
|
||||
}
|
||||
}
|
||||
}
|
||||
public string? currLanguage
|
||||
{
|
||||
get => _currLanguage;
|
||||
set
|
||||
{
|
||||
if (_currLanguage != value)
|
||||
{
|
||||
_currLanguage = value;
|
||||
reportCurrentLanguage();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (TUTTI) da REDIS o DB
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<IdentityUser>> UserDataGetAll()
|
||||
{
|
||||
string source = "DB";
|
||||
List<IdentityUser> dataResult = new List<IdentityUser>();
|
||||
// cerco da cache
|
||||
string currKey = $"{Constants.rKeyUsersAll}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<IdentityUser>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dataResult = new List<IdentityUser>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dataResult = await _userManager.Users.ToListAsync();
|
||||
rawData = JsonConvert.SerializeObject(dataResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dataResult == null)
|
||||
{
|
||||
dataResult = new List<IdentityUser>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"UserDataGetAll | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dataResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (singolo x UserId)
|
||||
/// </summary>
|
||||
/// <param name="UserId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UserData> UserDataGetById(string UserId)
|
||||
{
|
||||
string source = "DB";
|
||||
UserData dataResult = new UserData();
|
||||
// cerco da cache
|
||||
string currKey = $"{Constants.rKeyUsersDataId}:{UserId}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<UserData>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dataResult = new UserData();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collezione dati raw
|
||||
var userRaw = await _userManager.FindByIdAsync(UserId);
|
||||
if (userRaw != null)
|
||||
{
|
||||
var userIdent = new IdentityUser
|
||||
{
|
||||
Id = userRaw.Id,
|
||||
UserName = userRaw.UserName,
|
||||
Email = userRaw.Email,
|
||||
PhoneNumber = userRaw.PhoneNumber,
|
||||
PasswordHash = "*****",
|
||||
EmailConfirmed = userRaw.EmailConfirmed
|
||||
};
|
||||
// cerco ruoli & claims
|
||||
var UserRoles = await _userManager.GetRolesAsync(userIdent);
|
||||
var UserClaims = await _userManager.GetClaimsAsync(userIdent);
|
||||
// compongo output
|
||||
dataResult = new UserData()
|
||||
{
|
||||
Identity = userIdent,
|
||||
Roles = UserRoles.ToList(),
|
||||
Claims = UserClaims.ToList()
|
||||
};
|
||||
|
||||
rawData = JsonConvert.SerializeObject(dataResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, FastCache);
|
||||
}
|
||||
}
|
||||
if (dataResult == null)
|
||||
{
|
||||
dataResult = new UserData();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"UserDataGetById | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dataResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (filtrati da UserId)
|
||||
/// </summary>
|
||||
/// <param name="searchVal"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<UserData>> UserDataGetFilt(string searchVal)
|
||||
{
|
||||
string source = "DB";
|
||||
List<UserData> dataResult = new List<UserData>();
|
||||
// cerco da cache
|
||||
string currKey = $"{Constants.rKeyUsersDataSearch}:{searchVal}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<UserData>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dataResult = new List<UserData>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collezione dati raw
|
||||
List<IdentityUser> RawList = new List<IdentityUser>();
|
||||
//List<UserData> UsersList = new List<UserData>();
|
||||
var allData = await UserDataGetAll();
|
||||
if (!string.IsNullOrEmpty(searchVal))
|
||||
{
|
||||
RawList = allData.Where(x => x.NormalizedEmail.Contains(searchVal.ToUpper()) || x.NormalizedUserName.Contains(searchVal.ToUpper())).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
RawList = allData;
|
||||
}
|
||||
var user = RawList.Select(x => new IdentityUser
|
||||
{
|
||||
Id = x.Id,
|
||||
UserName = x.UserName,
|
||||
Email = x.Email,
|
||||
PhoneNumber = x.PhoneNumber,
|
||||
PasswordHash = "*****",
|
||||
EmailConfirmed = x.EmailConfirmed
|
||||
}).ToList();
|
||||
|
||||
foreach (var item in user)
|
||||
{
|
||||
var UserRoles = await _userManager.GetRolesAsync(item);
|
||||
var UserClaims = await _userManager.GetClaimsAsync(item);
|
||||
|
||||
var newItem = new UserData()
|
||||
{
|
||||
Identity = item,
|
||||
Roles = UserRoles.ToList(),
|
||||
Claims = UserClaims.ToList()
|
||||
};
|
||||
dataResult.Add(newItem);
|
||||
}
|
||||
rawData = JsonConvert.SerializeObject(dataResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, FastCache);
|
||||
}
|
||||
if (dataResult == null)
|
||||
{
|
||||
dataResult = new List<UserData>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"UserDataGetFilt | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dataResult;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void reportUserId()
|
||||
protected void reportCurrentLanguage()
|
||||
{
|
||||
if (EA_UserId != null)
|
||||
if (EA_CurrLanguage != null)
|
||||
{
|
||||
EA_UserId?.Invoke();
|
||||
EA_CurrLanguage?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +324,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
protected void reportUserCurrCompany()
|
||||
{
|
||||
if (EA_UserCurrCompany != null)
|
||||
{
|
||||
EA_UserCurrCompany?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected void reportUserId()
|
||||
{
|
||||
if (EA_UserId != null)
|
||||
{
|
||||
EA_UserId?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected void reportUserRole()
|
||||
{
|
||||
if (EA_UserRole != null)
|
||||
@@ -112,30 +348,115 @@
|
||||
}
|
||||
}
|
||||
|
||||
protected void reportUserCurrCompany()
|
||||
{
|
||||
if (EA_UserCurrCompany != null)
|
||||
{
|
||||
EA_UserCurrCompany?.Invoke();
|
||||
}
|
||||
}
|
||||
protected void reportCurrentLanguage()
|
||||
{
|
||||
if (EA_CurrLanguage != null)
|
||||
{
|
||||
EA_CurrLanguage?.Invoke();
|
||||
}
|
||||
}
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static JsonSerializerSettings? JSSettings;
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private readonly UserManager<IdentityUser> _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache lunga IN SECONDI
|
||||
/// </summary>
|
||||
private int cacheTtlLong = 60 * 5;
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache breve IN SECONDI
|
||||
/// </summary>
|
||||
private int cacheTtlShort = 60 * 1;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
private IConnectionMultiplexer redisConn;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private Random rnd = new Random();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string _userId { get; set; } = "";
|
||||
private List<string>? _userClaims { get; set; } = null;
|
||||
private string _userRole { get; set; } = "";
|
||||
private int _userCurrComp { get; set; } //= -1;
|
||||
private string? _currLanguage { get; set; } = null;
|
||||
|
||||
private List<string>? _userClaims { get; set; } = null;
|
||||
|
||||
private int _userCurrComp { get; set; }
|
||||
|
||||
private string _userId { get; set; } = "";
|
||||
|
||||
private string _userRole { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache breve (1 min circa + perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan FastCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan LongCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache molto breve (10 sec circa + perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan UltraFastCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlShort / 6 * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan UltraLongCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue flush memoria redis dato pattern
|
||||
/// </summary>
|
||||
/// <param name="pattern"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
|
||||
{
|
||||
bool answ = false;
|
||||
var listEndpoints = redisConn.GetEndPoints();
|
||||
foreach (var endPoint in listEndpoints)
|
||||
{
|
||||
//var server = redisConnAdmin.GetServer(listEndpoints[0]);
|
||||
var server = redisConn.GetServer(endPoint);
|
||||
if (server != null)
|
||||
{
|
||||
var keyList = server.Keys(redisDb.Database, pattern);
|
||||
foreach (var item in keyList)
|
||||
{
|
||||
await redisDb.KeyDeleteAsync(item);
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
//= -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
@page "/UserAdmin"
|
||||
|
||||
@if (ShowPopup)
|
||||
{
|
||||
<div class="modal" tabindex="-1" style="display:block" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Edit User</h3>
|
||||
<!-- Button to close the popup -->
|
||||
<button type="button" class="close" @onclick="ClosePopup">
|
||||
<span aria-hidden="true">X</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Edit form for the current user -->
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
@if (objUser.Id != "")
|
||||
{
|
||||
<p>@objUser.Id</p>
|
||||
}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="far fa-envelope"></i></span>
|
||||
</div>
|
||||
<input class="form-control" type="text" placeholder="Email" @bind="objUser.Email" />
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input class="form-control2" type="checkbox" title="Email Confirmed" @bind="objUser.EmailConfirmed" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-key"></i></span>
|
||||
</div>
|
||||
<input class="form-control" type="password" placeholder="Password" @bind="objUser.PasswordHash" />
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-user-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control" @bind="@CurrentUserRole">
|
||||
@foreach (var option in RolesList)
|
||||
{
|
||||
<option value="@option">
|
||||
@option
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control" @bind="@CurrentUserClaimType">
|
||||
@foreach (var option in ClaimsList)
|
||||
{
|
||||
<option value="@option">
|
||||
@option
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<select class="form-control" @bind="@CurrentUserClaimVal">
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var option in ClaimValList)
|
||||
{
|
||||
<option value="@option.Key">
|
||||
@option.Value
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<span style="color:red">@strError</span>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-block btn-success" @onclick="SaveUser" title="Save"><i class="fas fa-check"></i> Save</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-block btn-primary" @onclick="ClosePopup"><i class="far fa-window-close"></i> Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<!-- Only show Id if not a new user -->
|
||||
@if (objUser.Id != "")
|
||||
{
|
||||
<QrCodeDisplay rawCode="@qrCodeVal"></QrCodeDisplay>
|
||||
}
|
||||
<CopyToClipboard Text="@qrCodeVal"></CopyToClipboard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-4 col-lg-6 col-xl-8 text-truncate">
|
||||
<h3>User Administration</h3>
|
||||
</div>
|
||||
<div class="col-4 col-lg-3 col-xl-2 text-right">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-user-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control" @bind="@FiltUserRole">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var option in RolesList)
|
||||
{
|
||||
<option value="@option">
|
||||
@option
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-lg-3 col-xl-2 text-right">
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
@if (@context.User.IsInRole("SuperAdmin"))
|
||||
{
|
||||
<button class="btn btn-success btn-block" @onclick="AddNewUser">Add User</button>
|
||||
}
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body px-1">
|
||||
<table class="table table-sm table-striped table-responsive-md">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Id</th>
|
||||
<th>User / Email</th>
|
||||
<th>Ruolo</th>
|
||||
<th>Permessi</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in UsersList)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@if (!ShowPopup)
|
||||
{
|
||||
<button class="btn btn-sm btn-primary" @onclick="(() => EditUser(user.Identity))" title="Edit">
|
||||
<i class="fas fa-pen"></i>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled" title="Edit">
|
||||
<i class="fas fa-pen"></i>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
<td>@user.Identity.Id.Substring(0, 8)...</td>
|
||||
<td>
|
||||
@if (user.Identity.EmailConfirmed)
|
||||
{
|
||||
<span class="badge badge-pill badge-success" title="Email validata"><span class="oi oi-check" aria-hidden="true"></span></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="badge badge-pill badge-danger" title="Email NON ancora validata!"><span class="oi oi-check" aria-hidden="true"></span></span>
|
||||
}
|
||||
@user.Identity.Email
|
||||
</td>
|
||||
<td>
|
||||
@ShowRoles(user.Roles)
|
||||
</td>
|
||||
<td>
|
||||
@ShowClaims(user.Claims)
|
||||
</td>
|
||||
<td>
|
||||
@if (!ShowPopup)
|
||||
{
|
||||
<button class="btn btn-sm btn-danger" @onclick="(() => DeleteUser(user.Identity))" title="Delete">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled" title="Delete">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer p-1">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,719 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.JSInterop;
|
||||
using WebDoorCreator.Data.DbModels;
|
||||
using WebDoorCreator.Data.Services;
|
||||
using WebDoorCreator.Data.User;
|
||||
using WebDoorCreator.UI.Data;
|
||||
|
||||
namespace WebDoorCreator.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin")]
|
||||
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 Properties
|
||||
|
||||
public string searchVal
|
||||
{
|
||||
get
|
||||
{
|
||||
return AppMService.SearchVal;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public List<string> ConvertClaim(List<System.Security.Claims.Claim> ClaimList)
|
||||
{
|
||||
List<string> answ = new List<string>();
|
||||
|
||||
var pUpd = Task.Run(async () =>
|
||||
{
|
||||
await refreshLists();
|
||||
});
|
||||
pUpd.Wait();
|
||||
|
||||
// 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;
|
||||
|
||||
#if false
|
||||
case "SupplierId":
|
||||
if (suppList != null)
|
||||
{
|
||||
var plantRec = suppList
|
||||
.Where(x => x.SupplierId.ToString() == splitClaim[1].Trim())
|
||||
.FirstOrDefault();
|
||||
if (plantRec != null)
|
||||
{
|
||||
answ.Add($"{splitClaim[0]}: {plantRec.SupplierDesc}");
|
||||
}
|
||||
else
|
||||
{
|
||||
answ.Add($"{claim}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "TransporterId":
|
||||
if (transpList != null)
|
||||
{
|
||||
var plantRec = transpList
|
||||
.Where(x => x.TransporterId.ToString() == splitClaim[1].Trim())
|
||||
.FirstOrDefault();
|
||||
if (plantRec != null)
|
||||
{
|
||||
answ.Add($"{splitClaim[0]}: {plantRec.TransporterDesc}");
|
||||
}
|
||||
else
|
||||
{
|
||||
answ.Add($"{claim}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case "None":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AppMService.EA_SearchUpdated -= OnSeachUpdated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera elenco utenti
|
||||
/// </summary>
|
||||
public async Task GetUsers()
|
||||
{
|
||||
// clear any error messages
|
||||
strError = "";
|
||||
UsersAll = await WDCUsrServ.UserDataGetFilt(searchVal);
|
||||
// filtro visualizzazione x tipo SE richeisto
|
||||
if (FiltUserRole != "0")
|
||||
{
|
||||
UsersAll = UsersAll.Where(x => x.Roles.Contains(FiltUserRole)).ToList();
|
||||
}
|
||||
UsersList = UsersAll
|
||||
.Skip(numRecord * (currPage - 1)).Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async void OnSeachUpdated()
|
||||
{
|
||||
await GetUsers();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public string ShowClaims(List<System.Security.Claims.Claim> ClaimList)
|
||||
{
|
||||
//string answ = string.Join(",", ClaimList);
|
||||
string answ = string.Join(",", ConvertClaim(ClaimList));
|
||||
return answ;
|
||||
}
|
||||
|
||||
public string ShowRoles(List<string> RoleList)
|
||||
{
|
||||
string answ = string.Join(",", RoleList);
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected RoleManager<IdentityRole> _RoleManager { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected UserManager<IdentityUser> _UserManager { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; } = null!;
|
||||
|
||||
protected List<CompanyModel>? CompanyList { get; set; } = null;
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
protected int totalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int answ = 0;
|
||||
if (UsersAll != null)
|
||||
{
|
||||
answ = UsersAll.Count;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
[Inject]
|
||||
protected WebDoorCreatorService WDCService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected WDCUserService WDCUsrServ { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#if false
|
||||
protected List<GWMS.Data.DatabaseModels.SupplierModel>? suppList { get; set; } = null;
|
||||
protected List<GWMS.Data.DatabaseModels.TransporterModel>? transpList { get; set; } = null;
|
||||
#endif
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void ForceReload(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
}
|
||||
|
||||
protected void ForceReloadPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
AppMService.ShowSearch = true;
|
||||
AppMService.EA_SearchUpdated += OnSeachUpdated;
|
||||
// lettura dati
|
||||
await GetUsers();
|
||||
#if false
|
||||
await CheckSuperAdmin();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Elenco CLAIMS da mostrare durante editing
|
||||
/// </summary>
|
||||
private List<string> ClaimsList = new List<string>() { STD_CLAIM, "CompanyId", "SupplierId", "TransporterId" };
|
||||
|
||||
private Dictionary<string, string> ClaimValList = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// User corrente
|
||||
/// </summary>
|
||||
private IdentityUser objUser = new IdentityUser();
|
||||
|
||||
private string qrCodeVal = "";
|
||||
|
||||
/// <summary>
|
||||
/// Collezione utenti
|
||||
/// </summary>
|
||||
private List<IdentityUser> RawList = new List<IdentityUser>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ROLES da mostrare in dropdown durante editing (1 solo? usare DB?!?)
|
||||
/// </summary>
|
||||
private List<string> RolesList = new List<string>() { "Undef", "User", "CompUser", "CompAdmin", "Admin", "SuperAdmin" };
|
||||
|
||||
// To enable showing the Popup
|
||||
private bool ShowPopup = false;
|
||||
|
||||
// To hold any possible errors
|
||||
private string strError = "";
|
||||
|
||||
/// <summary>
|
||||
/// Collezione utenti (totale)
|
||||
/// </summary>
|
||||
private List<UserData> UsersAll = new List<UserData>();
|
||||
|
||||
/// <summary>
|
||||
/// Collezione utenti
|
||||
/// </summary>
|
||||
private List<UserData> UsersList = new List<UserData>();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string _CurrClaimType { get; set; } = "None";
|
||||
|
||||
private int _currPage { get; set; } = 1;
|
||||
|
||||
private string _filtUserRole { get; set; } = "0";
|
||||
|
||||
private int _numRecord { get; set; } = 10;
|
||||
|
||||
[CascadingParameter]
|
||||
private Task<AuthenticationState> authenticationStateTask { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IConfiguration Configuration { get; set; } = null!;
|
||||
|
||||
private System.Security.Claims.Claim CurrentUserClaim
|
||||
{
|
||||
get => new System.Security.Claims.Claim(CurrentUserClaimType, CurrentUserClaimVal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Claim di default (Tipo)
|
||||
/// </summary>
|
||||
private string CurrentUserClaimType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrClaimType;
|
||||
}
|
||||
set
|
||||
{
|
||||
_CurrClaimType = value;
|
||||
var pUpd = Task.Run(async () => await refreshClaimVal(value));
|
||||
pUpd.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Claim di default (valore)
|
||||
/// </summary>
|
||||
private string CurrentUserClaimVal { get; set; } = "0";
|
||||
|
||||
/// <summary>
|
||||
/// Ruolo di default (User!!!)
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gestione filtraggio dati
|
||||
/// </summary>
|
||||
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 Id to blank so we know it is a new record
|
||||
objUser.Id = "";
|
||||
// Open the Popup
|
||||
ShowPopup = true;
|
||||
}
|
||||
|
||||
private async Task CheckSuperAdmin()
|
||||
{
|
||||
// se non ci fosse --> creo samuele come superadmin
|
||||
string superUser = "samuele@steamware.net";
|
||||
string superPwd = "viaDante16!";
|
||||
var user = await _UserManager.FindByEmailAsync(superUser);
|
||||
if (user == null)
|
||||
{
|
||||
// Insert new user
|
||||
var NewUser =
|
||||
new IdentityUser
|
||||
{
|
||||
UserName = superUser,
|
||||
Email = superUser,
|
||||
EmailConfirmed = true
|
||||
};
|
||||
var CreateResult = await _UserManager.CreateAsync(NewUser, superPwd);
|
||||
if (CreateResult.Succeeded)
|
||||
{
|
||||
user = await _UserManager.FindByEmailAsync(superUser);
|
||||
}
|
||||
}
|
||||
|
||||
// verifico ruoli...
|
||||
if (user != null)
|
||||
{
|
||||
// Gestione salvataggio ruoli... SE VARIATO...
|
||||
var UserRoles = await _UserManager.GetRolesAsync(user);
|
||||
if (UserRoles != null && UserRoles.Count > 0)
|
||||
{
|
||||
var oldRole = UserRoles.Where(x => x == ADMIN_ROLE).FirstOrDefault();
|
||||
if (oldRole == null)
|
||||
{
|
||||
// aggiungo a ruolo admin
|
||||
await _UserManager.AddToRoleAsync(user, ADMIN_ROLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ClosePopup()
|
||||
{
|
||||
// Close the Popup
|
||||
ShowPopup = false;
|
||||
// Refresh Users
|
||||
await GetUsers();
|
||||
}
|
||||
|
||||
private async Task DeleteUser(IdentityUser _IdentityUser)
|
||||
{
|
||||
// Close the Popup
|
||||
ShowPopup = false;
|
||||
|
||||
if (!await JSRuntime.InvokeAsync<bool>("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);
|
||||
}
|
||||
// Refresh Users
|
||||
await GetUsers();
|
||||
}
|
||||
|
||||
private void EditUser(IdentityUser _IdentityUser)
|
||||
{
|
||||
// selezione come current user
|
||||
objUser = _IdentityUser;
|
||||
var pUpd = Task.Run(async () =>
|
||||
{
|
||||
var user = await WDCUsrServ.UserDataGetById(objUser.Id);
|
||||
|
||||
#if false
|
||||
// Get the user
|
||||
var user = await _UserManager.FindByIdAsync(objUser.Id);
|
||||
#endif
|
||||
if (user != null)
|
||||
{
|
||||
// salvo role
|
||||
if (user.Roles != null)
|
||||
{
|
||||
CurrentUserRole = user.Roles.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentUserRole = UNDEF_ROLE;
|
||||
}
|
||||
// salvo claim
|
||||
if (user.Claims != null && user.Claims.Count > 0)
|
||||
{
|
||||
var CurrentUserClaim = user.Claims.FirstOrDefault();
|
||||
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
|
||||
ShowPopup = true;
|
||||
}
|
||||
|
||||
private async Task refreshClaimVal(string newType)
|
||||
{
|
||||
// init vuoto
|
||||
ClaimValList = new Dictionary<string, string>();
|
||||
// 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;
|
||||
|
||||
#if false
|
||||
case "SupplierId":
|
||||
// elenco plant --> to dictionary!
|
||||
var suppList = await WDCService.SuppliersGetAll();
|
||||
if (suppList != null)
|
||||
{
|
||||
ClaimValList = suppList
|
||||
.ToDictionary(x => $"{x.SupplierId}", x => x.SupplierDesc);
|
||||
}
|
||||
break;
|
||||
|
||||
case "TransporterId":
|
||||
// elenco plant --> to dictionary!
|
||||
var transpList = await WDCService.TransportersGetAll();
|
||||
if (transpList != null)
|
||||
{
|
||||
ClaimValList = transpList
|
||||
.ToDictionary(x => $"{x.TransporterId}", x => x.TransporterDesc);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case "None":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task refreshLists()
|
||||
{
|
||||
// effettuo refresh valori cache Company/...
|
||||
if (CompanyList == null)
|
||||
{
|
||||
CompanyList = await WDCService.CompanyGetByKey(0);
|
||||
}
|
||||
#if false
|
||||
if (suppList == null)
|
||||
{
|
||||
suppList = await WDCService.SuppliersGetAll();
|
||||
}
|
||||
if (transpList == null)
|
||||
{
|
||||
transpList = await WDCService.TransportersGetAll();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
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.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 (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.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)
|
||||
{
|
||||
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 Users
|
||||
await GetUsers();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
strError = ex.GetBaseException().Message;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ builder.Services.AddScoped<WDCUserService>();
|
||||
builder.Services.AddSingleton<WDCRefreshService>();
|
||||
builder.Services.AddSingleton<WDCVocabularyService>();
|
||||
builder.Services.AddSingleton<QueueDataService>();
|
||||
builder.Services.AddScoped<MessageService>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>0.9.2305.2612</Version>
|
||||
<Version>0.9.2305.2619</Version>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>aspnet-WebDoorCreator.UI-dfe95fed-1398-4144-bd43-8b3a765d6608</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user