208 lines
8.3 KiB
C#
208 lines
8.3 KiB
C#
using System.Security.Claims;
|
|
using System.Text.Json;
|
|
|
|
using MesaFabApproval.Shared.Models;
|
|
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
|
|
namespace MesaFabApproval.Client.Services;
|
|
|
|
public interface IUserService {
|
|
ClaimsPrincipal GetClaimsPrincipalFromUser(User user);
|
|
string GetLoginIdFromClaimsPrincipal(ClaimsPrincipal claimsPrincipal);
|
|
Task<User> GetUserFromClaimsPrincipal(ClaimsPrincipal claimsPrincipal);
|
|
Task<User> GetUserByUserId(int userId);
|
|
Task<User> GetUserByLoginId(string loginId);
|
|
Task<IEnumerable<User>> GetAllActiveUsers();
|
|
Task<IEnumerable<int>> GetApproverUserIdsBySubRoleCategoryItem(string item);
|
|
}
|
|
|
|
public class UserService : IUserService {
|
|
private readonly IMemoryCache _cache;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
|
|
public UserService(IMemoryCache cache, IHttpClientFactory httpClientFactory) {
|
|
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
|
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected");
|
|
}
|
|
|
|
public ClaimsPrincipal GetClaimsPrincipalFromUser(User user) {
|
|
if (user is null) throw new ArgumentNullException("user cannot be null");
|
|
|
|
List<Claim> claims = new() {
|
|
new Claim(nameof(user.LoginID), user.LoginID)
|
|
};
|
|
|
|
if (user.IsManager) claims.Add(new Claim(ClaimTypes.Role, "manager"));
|
|
if (user.IsAdmin) claims.Add(new Claim(ClaimTypes.Role, "admin"));
|
|
|
|
ClaimsIdentity identity = new ClaimsIdentity(claims, "MesaFabApprovalWasm");
|
|
|
|
return new ClaimsPrincipal(identity);
|
|
}
|
|
|
|
public async Task<User> GetUserByUserId(int userId) {
|
|
if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID");
|
|
|
|
User? user = _cache.Get<User>($"user{userId}");
|
|
|
|
if (user is null)
|
|
user = _cache.Get<IEnumerable<User>>("allActiveUsers")?.FirstOrDefault(u => u.UserID == userId);
|
|
|
|
if (user is null) {
|
|
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
|
|
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"user/userId?userId={userId}");
|
|
|
|
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
|
|
|
if (responseMessage.IsSuccessStatusCode) {
|
|
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
|
|
|
JsonSerializerOptions jsonSerializerOptions = new() {
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
user = JsonSerializer.Deserialize<User>(responseContent, jsonSerializerOptions) ??
|
|
throw new Exception("Unable to parse user from API response");
|
|
|
|
_cache.Set($"user{userId}", user, DateTimeOffset.Now.AddDays(1));
|
|
} else {
|
|
throw new Exception($"GetUserByUserId failed for user {userId}, because {responseMessage.ReasonPhrase}");
|
|
}
|
|
}
|
|
|
|
if (user is null) throw new Exception($"User for userId {userId} not found");
|
|
|
|
return user;
|
|
}
|
|
|
|
public async Task<User> GetUserByLoginId(string loginId) {
|
|
if (string.IsNullOrWhiteSpace(loginId))
|
|
throw new ArgumentNullException("loginId cannot be null or empty");
|
|
|
|
User? user = _cache.Get<User>($"user{loginId}");
|
|
|
|
if (user is null)
|
|
user = _cache.Get<IEnumerable<User>>("allActiveUsers")?.FirstOrDefault(u => u.LoginID == loginId);
|
|
|
|
if (user is null) {
|
|
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
|
|
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"user/loginId?loginId={loginId}");
|
|
|
|
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
|
|
|
if (responseMessage.IsSuccessStatusCode) {
|
|
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
|
|
|
JsonSerializerOptions jsonSerializerOptions = new() {
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
user = JsonSerializer.Deserialize<User>(responseContent, jsonSerializerOptions) ??
|
|
throw new Exception("Unable to parse user from API response");
|
|
|
|
_cache.Set($"user{loginId}", user, DateTimeOffset.Now.AddDays(1));
|
|
} else {
|
|
throw new Exception($"GetUserByLoginId failed for {loginId}, because {responseMessage.ReasonPhrase}");
|
|
}
|
|
}
|
|
|
|
if (user is null) throw new Exception($"User for loginId {loginId} not found");
|
|
|
|
return user;
|
|
}
|
|
|
|
public async Task<IEnumerable<User>> GetAllActiveUsers() {
|
|
IEnumerable<User>? activeUsers = _cache.Get<IEnumerable<User>>("allActiveUsers");
|
|
|
|
if (activeUsers is null) {
|
|
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
|
|
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"users/active");
|
|
|
|
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
|
|
|
if (responseMessage.IsSuccessStatusCode) {
|
|
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
|
|
|
JsonSerializerOptions jsonSerializerOptions = new() {
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
activeUsers = JsonSerializer.Deserialize<IEnumerable<User>>(responseContent, jsonSerializerOptions) ??
|
|
throw new Exception("Unable to parse user from API response");
|
|
|
|
_cache.Set("allActiveUsers", activeUsers, DateTimeOffset.Now.AddHours(1));
|
|
} else {
|
|
throw new Exception($"Cannot get all active users, because {responseMessage.ReasonPhrase}");
|
|
}
|
|
}
|
|
|
|
if (activeUsers is null)
|
|
activeUsers = new List<User>();
|
|
|
|
return activeUsers;
|
|
}
|
|
|
|
public string GetLoginIdFromClaimsPrincipal(ClaimsPrincipal principal) {
|
|
if (principal is null) throw new ArgumentNullException("Principal cannot be null");
|
|
|
|
Claim loginIdClaim = principal.FindFirst("LoginID") ??
|
|
throw new Exception("LoginID claim not found in principal");
|
|
|
|
string loginId = loginIdClaim.Value;
|
|
|
|
return loginId;
|
|
}
|
|
|
|
public async Task<User> GetUserFromClaimsPrincipal(ClaimsPrincipal claimsPrincipal) {
|
|
if (claimsPrincipal is null) throw new ArgumentNullException("ClaimsPrincipal cannot be null");
|
|
|
|
Claim loginIdClaim = claimsPrincipal.FindFirst("LoginID") ??
|
|
throw new Exception("LoginID claim not found in principal");
|
|
|
|
string loginId = loginIdClaim.Value ??
|
|
throw new Exception("LoginID claim value is null");
|
|
|
|
User user = await GetUserByLoginId(loginId) ??
|
|
throw new Exception($"User for loginId {loginId} not found");
|
|
|
|
return user;
|
|
}
|
|
|
|
public async Task<IEnumerable<int>> GetApproverUserIdsBySubRoleCategoryItem(string item) {
|
|
if (string.IsNullOrWhiteSpace(item)) throw new ArgumentException("SubRoleCategoryItem cannot be null or empty");
|
|
|
|
IEnumerable<int>? approverUserIds = _cache.Get<IEnumerable<int>>($"approvers{item}");
|
|
|
|
if (approverUserIds is null) {
|
|
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
|
|
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approver?subRoleCategoryItem={item}");
|
|
|
|
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
|
|
|
if (responseMessage.IsSuccessStatusCode) {
|
|
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
|
|
|
JsonSerializerOptions jsonSerializerOptions = new() {
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
approverUserIds = JsonSerializer.Deserialize<IEnumerable<int>>(responseContent, jsonSerializerOptions) ??
|
|
throw new Exception("Unable to parse user from API response");
|
|
|
|
_cache.Set($"approvers{item}", approverUserIds, DateTimeOffset.Now.AddDays(1));
|
|
} else {
|
|
throw new Exception($"Unable to get approvers for SubRoleCategoryItem {item}, because {responseMessage.ReasonPhrase}");
|
|
}
|
|
}
|
|
|
|
if (approverUserIds is null) throw new Exception($"Approvers for SubRoleCategoryItem {item} not found");
|
|
|
|
return approverUserIds;
|
|
}
|
|
}
|