MRB webassembly
This commit is contained in:
300
MesaFabApproval.Client/Services/ApprovalService.cs
Normal file
300
MesaFabApproval.Client/Services/ApprovalService.cs
Normal file
@ -0,0 +1,300 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IApprovalService {
|
||||
Task<int> GetRoleIdForRoleName(string roleName);
|
||||
Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId);
|
||||
Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId);
|
||||
Task CreateApproval(Approval approval);
|
||||
Task UpdateApproval(Approval approval);
|
||||
Task Approve(Approval approval);
|
||||
Task Deny(Approval approval);
|
||||
Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache);
|
||||
Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache);
|
||||
}
|
||||
|
||||
public class ApprovalService : IApprovalService {
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public ApprovalService(IMemoryCache cache, IHttpClientFactory httpClientFactory) {
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ??
|
||||
throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
}
|
||||
|
||||
public async Task CreateApproval(Approval approval) {
|
||||
if (approval is null) throw new ArgumentNullException("approval cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, "approval");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to create approval, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
await GetApprovalsForIssueId(approval.IssueID, true);
|
||||
await GetApprovalsForUserId(approval.UserID, true);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache) {
|
||||
if (issueId <= 0) throw new ArgumentException($"{issueId} is not a valid issue ID");
|
||||
|
||||
IEnumerable<Approval>? approvals = null;
|
||||
|
||||
if (!bypassCache)
|
||||
approvals = _cache.Get<IEnumerable<Approval>>($"approvals{issueId}");
|
||||
|
||||
if (approvals is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/issue?issueId={issueId}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
approvals = JsonSerializer.Deserialize<IEnumerable<Approval>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse approvals from API response");
|
||||
|
||||
_cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"Unable to get approvals, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Approval approval in approvals) {
|
||||
if (approval.ItemStatus < 0)
|
||||
approval.StatusMessage = "Denied";
|
||||
if (approval.ItemStatus == 0)
|
||||
approval.StatusMessage = "Assigned";
|
||||
if (approval.ItemStatus > 0)
|
||||
approval.StatusMessage = "Approved";
|
||||
}
|
||||
|
||||
return approvals;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache) {
|
||||
if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID");
|
||||
|
||||
IEnumerable<Approval>? approvals = null;
|
||||
|
||||
if (!bypassCache) approvals = _cache.Get<IEnumerable<Approval>>($"approvals{userId}");
|
||||
|
||||
if (approvals is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/user?userId={userId}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
approvals = JsonSerializer.Deserialize<IEnumerable<Approval>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse approvals from API response");
|
||||
|
||||
_cache.Set($"approvals{userId}", approvals, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"Unable to get approvals, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Approval approval in approvals) {
|
||||
if (approval.ItemStatus < 0)
|
||||
approval.StatusMessage = "Denied";
|
||||
if (approval.ItemStatus == 0)
|
||||
approval.StatusMessage = "Assigned";
|
||||
if (approval.ItemStatus > 0)
|
||||
approval.StatusMessage = "Approved";
|
||||
}
|
||||
|
||||
return approvals;
|
||||
}
|
||||
|
||||
public async Task UpdateApproval(Approval approval) {
|
||||
if (approval is null) throw new ArgumentNullException("approval cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to update approval, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
await GetApprovalsForIssueId(approval.IssueID, true);
|
||||
await GetApprovalsForUserId(approval.UserID, true);
|
||||
}
|
||||
|
||||
public async Task Approve(Approval approval) {
|
||||
if (approval is null) throw new ArgumentNullException("approval cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval/approve");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Approval failed, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
await GetApprovalsForIssueId(approval.IssueID, true);
|
||||
await GetApprovalsForUserId(approval.UserID, true);
|
||||
}
|
||||
|
||||
public async Task Deny(Approval approval) {
|
||||
if (approval is null) throw new ArgumentNullException("approval cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval/deny");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Denial failed, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> GetRoleIdForRoleName(string roleName) {
|
||||
if (string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("role name cannot be null or empty");
|
||||
|
||||
int roleId = _cache.Get<int>($"roleId{roleName}");
|
||||
|
||||
if (roleId <= 0) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/roleId?roleName={roleName}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
roleId = JsonSerializer.Deserialize<int>(responseContent, jsonSerializerOptions);
|
||||
|
||||
if (roleId <= 0)
|
||||
throw new Exception($"unable to find role ID for {roleName}");
|
||||
|
||||
_cache.Set($"roleId{roleName}", roleId, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"Unable to get role ID, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId) {
|
||||
if (string.IsNullOrWhiteSpace(subRoleName)) throw new ArgumentException("role name cannot be null or empty");
|
||||
if (roleId <= 0) throw new ArgumentException($"{roleId} is not a valid role ID");
|
||||
|
||||
IEnumerable<SubRole>? subRoles = _cache.Get<IEnumerable<SubRole>>($"subRoles{subRoleName}");
|
||||
|
||||
if (subRoles is null || subRoles.Count() <= 0) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/subRoles?subRoleName={subRoleName}&roleId={roleId}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
subRoles = JsonSerializer.Deserialize<IEnumerable<SubRole>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse sub roles from API response");
|
||||
|
||||
if (subRoles is not null && subRoles.Count() > 0) {
|
||||
_cache.Set($"subRoles{subRoleName}", subRoles, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"unable to find sub roles for {subRoleName}");
|
||||
}
|
||||
} else {
|
||||
throw new Exception($"Unable to get sub roles, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return subRoles;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId) {
|
||||
if (subRoleId <= 0) throw new ArgumentException($"{subRoleId} is not a valid sub role ID");
|
||||
|
||||
IEnumerable<User>? members = _cache.Get<IEnumerable<User>>($"approvalMembers{subRoleId}");
|
||||
|
||||
if (members is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/members?subRoleId={subRoleId}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
members = JsonSerializer.Deserialize<IEnumerable<User>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse users from API response");
|
||||
|
||||
if (members is null || members.Count() <= 0)
|
||||
throw new Exception($"unable to find group members for sub role {subRoleId}");
|
||||
|
||||
_cache.Set($"approvalMembers{subRoleId}", members, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"Unable to get group members, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
}
|
232
MesaFabApproval.Client/Services/AuthenticationService.cs
Normal file
232
MesaFabApproval.Client/Services/AuthenticationService.cs
Normal file
@ -0,0 +1,232 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IAuthenticationService {
|
||||
Task<ClaimsPrincipal> SendAuthenticationRequest(string loginId, string password);
|
||||
Task<ClaimsPrincipal> AttemptLocalUserAuth();
|
||||
Task<ClaimsPrincipal> FetchAuthState();
|
||||
Task ClearTokens();
|
||||
Task ClearCurrentUser();
|
||||
Task SetTokens(string jwt, string refreshToken);
|
||||
Task SetLoginId(string loginId);
|
||||
Task SetCurrentUser(User user);
|
||||
Task<User> GetCurrentUser();
|
||||
Task<AuthTokens> GetAuthTokens();
|
||||
Task<string> GetLoginId();
|
||||
ClaimsPrincipal GetClaimsPrincipalFromJwt(string jwt);
|
||||
}
|
||||
|
||||
public class AuthenticationService : IAuthenticationService {
|
||||
private readonly ILocalStorageService _localStorageService;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public AuthenticationService(ILocalStorageService localStorageService,
|
||||
IMemoryCache cache,
|
||||
IHttpClientFactory httpClientFactory) {
|
||||
_localStorageService = localStorageService ??
|
||||
throw new ArgumentNullException("ILocalStorageService not injected");
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
}
|
||||
|
||||
public async Task<ClaimsPrincipal> SendAuthenticationRequest(string loginId, string password) {
|
||||
if (string.IsNullOrWhiteSpace(loginId)) throw new ArgumentException("loginId cannot be null or empty");
|
||||
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("password cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
AuthAttempt authAttempt = new() {
|
||||
LoginID = loginId,
|
||||
Password = password
|
||||
};
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "auth/login");
|
||||
|
||||
request.Content = new StringContent(JsonSerializer.Serialize(authAttempt),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
|
||||
|
||||
if (httpResponseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await httpResponseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
LoginResult loginResult = JsonSerializer.Deserialize<LoginResult>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse login result from API response");
|
||||
|
||||
if (!loginResult.IsAuthenticated) throw new Exception($"User with Login ID {loginId} not authorized");
|
||||
|
||||
await SetLoginId(loginId);
|
||||
|
||||
await SetTokens(loginResult.AuthTokens.JwtToken, loginResult.AuthTokens.RefreshToken);
|
||||
|
||||
await SetCurrentUser(loginResult.User);
|
||||
|
||||
ClaimsPrincipal principal = GetClaimsPrincipalFromJwt(loginResult.AuthTokens.JwtToken);
|
||||
|
||||
return principal;
|
||||
} else {
|
||||
throw new Exception($"Login API request failed for {loginId}, because {httpResponseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ClaimsPrincipal> AttemptLocalUserAuth() {
|
||||
WindowsIdentity? user = WindowsIdentity.GetCurrent();
|
||||
|
||||
if (user is null)
|
||||
throw new Exception("no authenticated user found");
|
||||
|
||||
if (!user.IsAuthenticated)
|
||||
throw new Exception("you are not authenticated");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "auth/login/localWindows");
|
||||
|
||||
request.Content = new StringContent(JsonSerializer.Serialize(user),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
|
||||
|
||||
if (httpResponseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await httpResponseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
LoginResult loginResult = JsonSerializer.Deserialize<LoginResult>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse login result from API response");
|
||||
|
||||
if (!loginResult.IsAuthenticated) throw new Exception($"User with Login ID {user.Name} not authorized");
|
||||
|
||||
await SetLoginId(loginResult.User.LoginID);
|
||||
|
||||
await SetTokens(loginResult.AuthTokens.JwtToken, loginResult.AuthTokens.RefreshToken);
|
||||
|
||||
await SetCurrentUser(loginResult.User);
|
||||
|
||||
ClaimsPrincipal principal = GetClaimsPrincipalFromJwt(loginResult.AuthTokens.JwtToken);
|
||||
|
||||
return principal;
|
||||
} else {
|
||||
throw new Exception($"Login API request failed for {user.Name}, because {httpResponseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ClaimsPrincipal> FetchAuthState() {
|
||||
string? jwt = _cache.Get<string>("MesaFabApprovalJwt");
|
||||
|
||||
if (jwt is null) jwt = await _localStorageService.GetItem("MesaFabApprovalJwt");
|
||||
|
||||
if (jwt is null) throw new Exception("Unable to find JWT");
|
||||
|
||||
ClaimsPrincipal principal = GetClaimsPrincipalFromJwt(jwt);
|
||||
|
||||
return principal;
|
||||
}
|
||||
|
||||
public async Task ClearTokens() {
|
||||
_cache.Remove("MesaFabApprovalJwt");
|
||||
await _localStorageService.RemoveItem("MesaFabApprovalJwt");
|
||||
_cache.Remove("MesaFabApprovalRefreshToken");
|
||||
await _localStorageService.RemoveItem("MesaFabApprovalRefreshToken");
|
||||
}
|
||||
|
||||
public async Task SetTokens(string jwt, string refreshToken) {
|
||||
if (string.IsNullOrWhiteSpace(jwt)) throw new ArgumentNullException("JWT cannot be null or empty");
|
||||
if (string.IsNullOrWhiteSpace(refreshToken)) throw new ArgumentNullException("Refresh token cannot be null or empty");
|
||||
|
||||
_cache.Set<string>("MesaFabApprovalJwt", jwt);
|
||||
await _localStorageService.AddItem("MesaFabApprovalJwt", jwt);
|
||||
_cache.Set<string>("MesaFabApprovalRefreshToken", refreshToken);
|
||||
await _localStorageService.AddItem("MesaFabApprovalRefreshToken", refreshToken);
|
||||
}
|
||||
|
||||
public async Task SetLoginId(string loginId) {
|
||||
if (string.IsNullOrWhiteSpace(loginId)) throw new ArgumentNullException("LoginId cannot be null or empty");
|
||||
|
||||
_cache.Set<string>("MesaFabApprovalUserId", loginId);
|
||||
await _localStorageService.AddItem("MesaFabApprovalUserId", loginId);
|
||||
}
|
||||
|
||||
public async Task SetCurrentUser(User user) {
|
||||
if (user is null) throw new ArgumentNullException("User cannot be null");
|
||||
|
||||
_cache.Set<User>("MesaFabApprovalCurrentUser", user);
|
||||
await _localStorageService.AddItem<User>("MesaFabApprovalCurrentUser", user);
|
||||
}
|
||||
|
||||
public async Task ClearCurrentUser() {
|
||||
_cache.Remove("MesaFabApprovalCurrentUser");
|
||||
await _localStorageService.RemoveItem("MesaFabApprovalCurrentUser");
|
||||
_cache.Remove("MesaFabApprovalUserId");
|
||||
await _localStorageService.RemoveItem("MesaFabApprovalUserId");
|
||||
}
|
||||
|
||||
public async Task<User> GetCurrentUser() {
|
||||
User? currentUser = null;
|
||||
|
||||
currentUser = _cache.Get<User>("MesaFabApprovalCurrentUser") ??
|
||||
await _localStorageService.GetItem<User>("MesaFabApprovalCurrentUser");
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
public async Task<AuthTokens> GetAuthTokens() {
|
||||
AuthTokens? authTokens = null;
|
||||
|
||||
string? jwt = _cache.Get<string>("MesaFabApprovalJwt");
|
||||
if (jwt is null) jwt = await _localStorageService.GetItem("MesaFabApprovalJwt");
|
||||
|
||||
string? refreshToken = _cache.Get<string>("MesaFabApprovalRefreshToken");
|
||||
if (refreshToken is null) refreshToken = await _localStorageService.GetItem("MesaFabApprovalRefreshToken");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(jwt) && !string.IsNullOrWhiteSpace(refreshToken)) {
|
||||
authTokens = new() {
|
||||
JwtToken = jwt,
|
||||
RefreshToken = refreshToken
|
||||
};
|
||||
}
|
||||
|
||||
return authTokens;
|
||||
}
|
||||
|
||||
public async Task<string> GetLoginId() {
|
||||
string? loginId = _cache.Get<string>("MesaFabApprovalUserId");
|
||||
if (loginId is null) loginId = await _localStorageService.GetItem("MesaFabApprovalUserId");
|
||||
|
||||
return loginId;
|
||||
}
|
||||
|
||||
public ClaimsPrincipal GetClaimsPrincipalFromJwt(string jwt) {
|
||||
if (string.IsNullOrWhiteSpace(jwt)) throw new ArgumentException("JWT cannot be null or empty");
|
||||
|
||||
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
|
||||
|
||||
if (!tokenHandler.CanReadToken(jwt)) {
|
||||
throw new Exception("Unable to parse JWT from API");
|
||||
}
|
||||
|
||||
JwtSecurityToken jwtSecurityToken = tokenHandler.ReadJwtToken(jwt);
|
||||
|
||||
ClaimsIdentity identity = new ClaimsIdentity(jwtSecurityToken.Claims, "MesaFabApprovalWasm");
|
||||
|
||||
return new(identity);
|
||||
}
|
||||
}
|
44
MesaFabApproval.Client/Services/CAService.cs
Normal file
44
MesaFabApproval.Client/Services/CAService.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface ICAService {
|
||||
Task<bool> CANumberIsValid(int number);
|
||||
}
|
||||
|
||||
public class CAService : ICAService {
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public CAService(IHttpClientFactory httpClientFactory) {
|
||||
_httpClientFactory = httpClientFactory ??
|
||||
throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
}
|
||||
|
||||
public async Task<bool> CANumberIsValid(int number) {
|
||||
if (number <= 0) return false;
|
||||
|
||||
try {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"ca/isValidCANumber?number={number}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
bool isValid = JsonSerializer.Deserialize<bool>(responseContent, jsonSerializerOptions);
|
||||
|
||||
return isValid;
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new Exception($"Unable to determine if {number} is a valid CA#, because {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
51
MesaFabApproval.Client/Services/CustomerService.cs
Normal file
51
MesaFabApproval.Client/Services/CustomerService.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface ICustomerService {
|
||||
Task<IEnumerable<string>> GetAllCustomerNames();
|
||||
}
|
||||
|
||||
public class CustomerService : ICustomerService {
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public CustomerService(IMemoryCache cache, IHttpClientFactory httpClientFactory) {
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ??
|
||||
throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetAllCustomerNames() {
|
||||
IEnumerable<string>? allCustomerNames = null;
|
||||
|
||||
allCustomerNames = _cache.Get<IEnumerable<string>>("allCustomerNames");
|
||||
|
||||
if (allCustomerNames is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"customer/all");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
allCustomerNames = JsonSerializer.Deserialize<IEnumerable<string>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse names from API response");
|
||||
|
||||
_cache.Set($"allCustomerNames", allCustomerNames, DateTimeOffset.Now.AddHours(1));
|
||||
} else {
|
||||
throw new Exception($"Unable to get all customer names, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return allCustomerNames;
|
||||
}
|
||||
}
|
52
MesaFabApproval.Client/Services/ECNService.cs
Normal file
52
MesaFabApproval.Client/Services/ECNService.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IECNService {
|
||||
Task<string> ECNNumberIsValidStr(int ecnNumber);
|
||||
Task<bool> ECNNumberIsValid(int number);
|
||||
}
|
||||
|
||||
public class ECNService : IECNService {
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public ECNService(IHttpClientFactory httpClientFactory) {
|
||||
_httpClientFactory = httpClientFactory ??
|
||||
throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
}
|
||||
|
||||
public async Task<string> ECNNumberIsValidStr(int ecnNumber) {
|
||||
if (ecnNumber <= 0 || !await ECNNumberIsValid(ecnNumber))
|
||||
return $"{ecnNumber} is not a valid ECN#";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> ECNNumberIsValid(int number) {
|
||||
if (number <= 0) return false;
|
||||
|
||||
try {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"ecn/isValidEcnNumber?number={number}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
bool isValid = JsonSerializer.Deserialize<bool>(responseContent, jsonSerializerOptions);
|
||||
|
||||
return isValid;
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new Exception($"Unable to determine if {number} is a valid ECN#, because {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
49
MesaFabApproval.Client/Services/LocalStorageService.cs
Normal file
49
MesaFabApproval.Client/Services/LocalStorageService.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface ILocalStorageService {
|
||||
Task AddItem(string key, string value);
|
||||
Task AddItem<T>(string key, T value);
|
||||
Task RemoveItem(string key);
|
||||
Task<string> GetItem(string key);
|
||||
Task<T?> GetItem<T>(string key);
|
||||
}
|
||||
|
||||
public class LocalStorageService : ILocalStorageService {
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
|
||||
public LocalStorageService(IJSRuntime jsRuntime) {
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task AddItem(string key, string value) {
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value);
|
||||
}
|
||||
|
||||
public async Task AddItem<T>(string key, T value) {
|
||||
string item = JsonSerializer.Serialize(value);
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, item);
|
||||
}
|
||||
|
||||
public async Task RemoveItem(string key) {
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
|
||||
}
|
||||
|
||||
public async Task<string> GetItem(string key) {
|
||||
return await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
|
||||
}
|
||||
|
||||
public async Task<T?> GetItem<T>(string key) {
|
||||
string item = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
return JsonSerializer.Deserialize<T>(item, jsonSerializerOptions);
|
||||
}
|
||||
}
|
755
MesaFabApproval.Client/Services/MRBService.cs
Normal file
755
MesaFabApproval.Client/Services/MRBService.cs
Normal file
@ -0,0 +1,755 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
using MesaFabApproval.Shared.Utilities;
|
||||
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
using MudBlazor;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IMRBService {
|
||||
Task<IEnumerable<MRB>> GetAllMRBs(bool bypassCache);
|
||||
Task<MRB> GetMRBById(int id, bool bypassCache = false);
|
||||
Task<MRB> GetMRBByTitle(string title, bool bypassCache);
|
||||
Task CreateNewMRB(MRB mrb);
|
||||
Task RecallMRB(MRB mrb, User recallUser);
|
||||
Task DeleteMRB(int mrbNumber);
|
||||
Task UpdateMRB(MRB mrb);
|
||||
Task SubmitForApproval(MRB mrb);
|
||||
Task GenerateActionTasks(MRB mrb, MRBAction action);
|
||||
Task CreateMRBAction(MRBAction mrbAction);
|
||||
Task<IEnumerable<MRBAction>> GetMRBActionsForMRB(int mrbNumber, bool bypassCache);
|
||||
Task UpdateMRBAction(MRBAction mrbAction);
|
||||
Task DeleteMRBAction(MRBAction mrbAction);
|
||||
Task UploadAttachments(IEnumerable<IBrowserFile> files, int mrbNumber);
|
||||
Task UploadActionAttachments(IEnumerable<IBrowserFile> files, int actionId);
|
||||
Task<IEnumerable<MRBAttachment>> GetAllAttachmentsForMRB(int mrbNumber, bool bypassCache);
|
||||
Task<IEnumerable<MRBActionAttachment>> GetAllActionAttachmentsForMRB(int mrbNumber, bool bypassCache);
|
||||
Task DeleteAttachment(MRBAttachment attachment);
|
||||
Task NotifyNewApprovals(MRB mrb);
|
||||
Task NotifyApprovers(MRBNotification notification);
|
||||
Task NotifyOriginator(MRBNotification notification);
|
||||
Task NotifyQAPreApprover(MRBNotification notification);
|
||||
Task<bool> NumberIsValid(int number);
|
||||
}
|
||||
|
||||
public class MRBService : IMRBService {
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ISnackbar _snackbar;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IApprovalService _approvalService;
|
||||
|
||||
public MRBService(IMemoryCache cache,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ISnackbar snackbar,
|
||||
IUserService userService,
|
||||
IApprovalService approvalService) {
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
_snackbar = snackbar ?? throw new ArgumentNullException("ISnackbar not injected");
|
||||
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
|
||||
_approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected");
|
||||
}
|
||||
|
||||
public async Task CreateNewMRB(MRB mrb) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, "mrb/new");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(mrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to generate new MRB, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
mrb = await GetMRBByTitle(mrb.Title, true);
|
||||
|
||||
_cache.Set($"mrb{mrb.MRBNumber}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"mrb{mrb.Title}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
IEnumerable<MRB>? allMrbs = _cache.Get<IEnumerable<MRB>>("allMrbs");
|
||||
if (allMrbs is not null) {
|
||||
List<MRB> mrbList = allMrbs.ToList();
|
||||
mrbList.Add(mrb);
|
||||
_cache.Set("allMrbs", mrbList);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RecallMRB(MRB mrb, User recallUser) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (mrb.StageNo < 1) throw new ArgumentException("MRB already in Draft stage");
|
||||
if (mrb.StageNo >= 4) throw new Exception("you cannot recall a completed MRB");
|
||||
|
||||
mrb.StageNo = 0;
|
||||
mrb.SubmittedDate = DateTimeUtilities.MIN_DT;
|
||||
mrb.ApprovalDate = DateTimeUtilities.MAX_DT;
|
||||
mrb.CloseDate = DateTimeUtilities.MAX_DT;
|
||||
await UpdateMRB(mrb);
|
||||
|
||||
IEnumerable<Approval> approvals = await _approvalService.GetApprovalsForIssueId(mrb.MRBNumber, false);
|
||||
|
||||
foreach (Approval approval in approvals) {
|
||||
if (approval.CompletedDate >= DateTimeUtilities.MAX_DT) {
|
||||
string comment = $"Recalled by {recallUser.GetFullName()}.";
|
||||
approval.Comments = comment;
|
||||
|
||||
approval.CompletedDate = DateTime.Now;
|
||||
approval.ItemStatus = -1;
|
||||
|
||||
await _approvalService.UpdateApproval(approval);
|
||||
}
|
||||
}
|
||||
|
||||
string message = $"MRB# {mrb.MRBNumber} [{mrb.Title}] has been recalled by {recallUser.GetFullName()}.";
|
||||
MRBNotification notification = new() { Message = message, MRB = mrb };
|
||||
|
||||
await NotifyApprovers(notification);
|
||||
}
|
||||
|
||||
public async Task DeleteMRB(int mrbNumber) {
|
||||
if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB#");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"mrb/delete?mrbNumber={mrbNumber}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to delete MRB# {mrbNumber}, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
IEnumerable<MRB> allMRBs = await GetAllMRBs(true);
|
||||
_cache.Set("allMrbs", allMRBs);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MRB>> GetAllMRBs(bool bypassCache) {
|
||||
try {
|
||||
IEnumerable<MRB>? allMRBs = null;
|
||||
if (!bypassCache) allMRBs = _cache.Get<IEnumerable<MRB>>("allMrbs");
|
||||
|
||||
if (allMRBs is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/all?bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
allMRBs = JsonSerializer.Deserialize<IEnumerable<MRB>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse MRBs from API response");
|
||||
|
||||
_cache.Set($"allMrbs", allMRBs, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception($"Unable to get all MRBs, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return allMRBs;
|
||||
} catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> NumberIsValid(int number) {
|
||||
try {
|
||||
if (number <= 0) return false;
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/numberIsValid?number={number}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
bool isValid = JsonSerializer.Deserialize<bool>(responseContent, jsonSerializerOptions);
|
||||
|
||||
return isValid;
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new Exception($"Unable to determine if {number} is a valid MRB#, because {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<MRB> GetMRBById(int id, bool bypassCache=false) {
|
||||
if (id <= 0) throw new ArgumentException($"Invalid MRB number: {id}");
|
||||
|
||||
MRB? mrb = null;
|
||||
if (!bypassCache)
|
||||
mrb = _cache.Get<MRB>($"mrb{id}");
|
||||
|
||||
if (mrb is null && !bypassCache) mrb = _cache.Get<IEnumerable<MRB>>("allMrbs")?.FirstOrDefault(m => m.MRBNumber == id);
|
||||
|
||||
if (mrb is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/getById?id={id}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
mrb = JsonSerializer.Deserialize<MRB>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse MRB from API response");
|
||||
|
||||
_cache.Set($"mrb{mrb.MRBNumber}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
} else {
|
||||
throw new Exception($"Unable to get MRB by Id, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return mrb;
|
||||
}
|
||||
|
||||
public async Task<MRB> GetMRBByTitle(string title, bool bypassCache) {
|
||||
if (string.IsNullOrWhiteSpace(title)) throw new ArgumentException("Title cannot be null or empty");
|
||||
|
||||
MRB? mrb = null;
|
||||
if (!bypassCache) mrb = _cache.Get<MRB>($"mrb{title}");
|
||||
|
||||
if (mrb is null && !bypassCache)
|
||||
mrb = _cache.Get<IEnumerable<MRB>>("allMrbs")?.FirstOrDefault(m => m.Title.Equals(title));
|
||||
|
||||
if (mrb is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/getByTitle?title={title}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
mrb = JsonSerializer.Deserialize<MRB>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse MRB from API response");
|
||||
|
||||
_cache.Set($"mrb{mrb.Title}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
} else {
|
||||
throw new Exception($"Unable to get MRB by title, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return mrb;
|
||||
}
|
||||
|
||||
public async Task UpdateMRB(MRB mrb) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"mrb");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(mrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to update MRB, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
_cache.Set($"mrb{mrb.MRBNumber}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"mrb{mrb.Title}", mrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
IEnumerable<MRB>? allMrbs = _cache.Get<IEnumerable<MRB>>("allMrbs");
|
||||
if (allMrbs is not null) {
|
||||
List<MRB> mrbList = allMrbs.ToList();
|
||||
mrbList.RemoveAll(m => m.MRBNumber == mrb.MRBNumber);
|
||||
mrbList.Add(mrb);
|
||||
_cache.Set("allMrbs", mrbList);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreateMRBAction(MRBAction mrbAction) {
|
||||
if (mrbAction is null) throw new ArgumentNullException("MRB action cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, "mrbAction");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(mrbAction),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to create new MRB action, because {responseMessage.ReasonPhrase}");
|
||||
|
||||
await GetMRBActionsForMRB(mrbAction.MRBNumber, true);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MRBAction>> GetMRBActionsForMRB(int mrbNumber, bool bypassCache) {
|
||||
if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB#");
|
||||
|
||||
IEnumerable<MRBAction>? mrbActions = null;
|
||||
if (!bypassCache)
|
||||
mrbActions = _cache.Get<IEnumerable<MRBAction>>($"mrbActions{mrbNumber}");
|
||||
|
||||
if (mrbActions is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrbAction?mrbNumber={mrbNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
mrbActions = JsonSerializer.Deserialize<IEnumerable<MRBAction>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<MRBAction>();
|
||||
|
||||
if (mrbActions.Count() > 0)
|
||||
_cache.Set($"mrbActions{mrbNumber}", mrbActions, DateTimeOffset.Now.AddMinutes(5));
|
||||
} else {
|
||||
throw new Exception($"Unable to get MRB {mrbNumber} actions, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return mrbActions;
|
||||
}
|
||||
|
||||
public async Task UpdateMRBAction(MRBAction mrbAction) {
|
||||
if (mrbAction is null) throw new ArgumentNullException("MRB action cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"mrbAction");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(mrbAction),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) {
|
||||
throw new Exception($"Unable to update MRB action, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
IEnumerable<MRBAction>? mrbActions = _cache.Get<IEnumerable<MRBAction>>($"mrbActions{mrbAction.MRBNumber}");
|
||||
if (mrbActions is not null) {
|
||||
List<MRBAction> mrbActionList = mrbActions.ToList();
|
||||
mrbActionList.RemoveAll(a => a.ActionID == mrbAction.ActionID);
|
||||
mrbActionList.Add(mrbAction);
|
||||
_cache.Set($"mrbActions{mrbAction.MRBNumber}", mrbActionList, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteMRBAction(MRBAction mrbAction) {
|
||||
if (mrbAction is null) throw new ArgumentNullException("MRB action cannot be null");
|
||||
if (mrbAction.ActionID <= 0) throw new ArgumentException($"{mrbAction.ActionID} is not a valid MRBActionID");
|
||||
if (mrbAction.MRBNumber <= 0) throw new ArgumentException($"{mrbAction.MRBNumber} is not a valid MRBNumber");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
string route = $"mrbAction?mrbActionID={mrbAction.ActionID}&mrbNumber={mrbAction.MRBNumber}";
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, route);
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to delete MRB action {mrbAction.ActionID}");
|
||||
|
||||
IEnumerable<MRBAction>? mrbActions = _cache.Get<IEnumerable<MRBAction>>($"mrbActions{mrbAction.MRBNumber}");
|
||||
if (mrbActions is not null) {
|
||||
List<MRBAction> mrbActionList = mrbActions.ToList();
|
||||
mrbActionList.RemoveAll(a => a.ActionID == mrbAction.ActionID);
|
||||
_cache.Set($"mrbActions{mrbAction.MRBNumber}", mrbActionList, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UploadAttachments(IEnumerable<IBrowserFile> files, int mrbNumber) {
|
||||
if (files is null) throw new ArgumentNullException("Files cannot be null");
|
||||
if (files.Count() <= 0) throw new ArgumentException("Files cannot be empty");
|
||||
if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB number");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/attach?mrbNumber={mrbNumber}");
|
||||
|
||||
using MultipartFormDataContent content = new MultipartFormDataContent();
|
||||
|
||||
foreach (IBrowserFile file in files) {
|
||||
try {
|
||||
long maxFileSize = 1024L * 1024L * 1024L * 2L;
|
||||
StreamContent fileContent = new StreamContent(file.OpenReadStream(maxFileSize));
|
||||
|
||||
FileExtensionContentTypeProvider contentTypeProvider = new FileExtensionContentTypeProvider();
|
||||
|
||||
const string defaultContentType = "application/octet-stream";
|
||||
|
||||
if (!contentTypeProvider.TryGetContentType(file.Name, out string? contentType)) {
|
||||
contentType = defaultContentType;
|
||||
}
|
||||
|
||||
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
|
||||
content.Add(content: fileContent, name: "\"files\"", fileName: file.Name);
|
||||
} catch (Exception ex) {
|
||||
_snackbar.Add($"File {file.Name} not saved, because {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
requestMessage.Content = content;
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to save attachments, because {responseMessage.ReasonPhrase}");
|
||||
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
IEnumerable<UploadResult> results = JsonSerializer.Deserialize<IEnumerable<UploadResult>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<UploadResult>();
|
||||
|
||||
foreach (UploadResult result in results) {
|
||||
if (result.UploadSuccessful) {
|
||||
_snackbar.Add($"{result.FileName} successfully uploaded", Severity.Success);
|
||||
} else {
|
||||
_snackbar.Add($"{result.FileName} not uploaded, because {result.Error}", Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
await GetAllAttachmentsForMRB(mrbNumber, true);
|
||||
}
|
||||
|
||||
public async Task UploadActionAttachments(IEnumerable<IBrowserFile> files, int actionId) {
|
||||
if (files is null) throw new ArgumentNullException("Files cannot be null");
|
||||
if (files.Count() <= 0) throw new ArgumentException("Files cannot be empty");
|
||||
if (actionId <= 0) throw new ArgumentException($"{actionId} is not a valid MRB action ID");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/action/attach?actionId={actionId}");
|
||||
|
||||
using MultipartFormDataContent content = new MultipartFormDataContent();
|
||||
|
||||
foreach (IBrowserFile file in files) {
|
||||
try {
|
||||
long maxFileSize = 1024L * 1024L * 1024L * 2L;
|
||||
StreamContent fileContent = new StreamContent(file.OpenReadStream(maxFileSize));
|
||||
|
||||
FileExtensionContentTypeProvider contentTypeProvider = new FileExtensionContentTypeProvider();
|
||||
|
||||
const string defaultContentType = "application/octet-stream";
|
||||
|
||||
if (!contentTypeProvider.TryGetContentType(file.Name, out string? contentType)) {
|
||||
contentType = defaultContentType;
|
||||
}
|
||||
|
||||
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
|
||||
content.Add(content: fileContent, name: "\"files\"", fileName: file.Name);
|
||||
} catch (Exception ex) {
|
||||
_snackbar.Add($"File {file.Name} not saved, because {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
requestMessage.Content = content;
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to save action attachments, because {responseMessage.ReasonPhrase}");
|
||||
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
IEnumerable<UploadResult> results = JsonSerializer.Deserialize<IEnumerable<UploadResult>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<UploadResult>();
|
||||
|
||||
foreach (UploadResult result in results) {
|
||||
if (result.UploadSuccessful) {
|
||||
_snackbar.Add($"{result.FileName} successfully uploaded", Severity.Success);
|
||||
} else {
|
||||
_snackbar.Add($"{result.FileName} not uploaded, because {result.Error}", Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
await GetAllAttachmentsForMRB(actionId, true);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MRBAttachment>> GetAllAttachmentsForMRB(int mrbNumber, bool bypassCache) {
|
||||
if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB#");
|
||||
|
||||
IEnumerable<MRBAttachment>? mrbAttachments = null;
|
||||
if (!bypassCache)
|
||||
mrbAttachments = _cache.Get<IEnumerable<MRBAttachment>>($"mrbAttachments{mrbNumber}");
|
||||
|
||||
if (mrbAttachments is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/attachments?mrbNumber={mrbNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
mrbAttachments = JsonSerializer.Deserialize<IEnumerable<MRBAttachment>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<MRBAttachment>();
|
||||
|
||||
if (mrbAttachments.Count() > 0)
|
||||
_cache.Set($"mrbAttachments{mrbNumber}", mrbAttachments, DateTimeOffset.Now.AddMinutes(5));
|
||||
} else {
|
||||
throw new Exception($"Unable to get MRB {mrbNumber} attachments, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return mrbAttachments;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MRBActionAttachment>> GetAllActionAttachmentsForMRB(int mrbNumber, bool bypassCache) {
|
||||
if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB#");
|
||||
|
||||
IEnumerable<MRBActionAttachment>? actionAttachments = null;
|
||||
if (!bypassCache)
|
||||
actionAttachments = _cache.Get<IEnumerable<MRBActionAttachment>>($"mrbActionAttachments{mrbNumber}");
|
||||
|
||||
if (actionAttachments is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"mrb/action/attachments?mrbNumber={mrbNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
actionAttachments = JsonSerializer.Deserialize<IEnumerable<MRBActionAttachment>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<MRBActionAttachment>();
|
||||
|
||||
if (actionAttachments.Count() > 0)
|
||||
_cache.Set($"mrbActionAttachments{mrbNumber}", actionAttachments, DateTimeOffset.Now.AddMinutes(5));
|
||||
} else {
|
||||
throw new Exception($"Unable to get MRB {mrbNumber} action attachments, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
||||
return actionAttachments;
|
||||
}
|
||||
|
||||
public async Task DeleteAttachment(MRBAttachment attachment) {
|
||||
if (attachment is null) throw new ArgumentNullException("MRB attachment cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, "mrb/attach");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(attachment),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to delete MRB attachment");
|
||||
|
||||
IEnumerable<MRBAttachment>? mrbAttachments = _cache.Get<IEnumerable<MRBAttachment>>($"mrbAttachments{attachment.MRBNumber}");
|
||||
if (mrbAttachments is not null) {
|
||||
List<MRBAttachment> mrbAttachmentList = mrbAttachments.ToList();
|
||||
mrbAttachmentList.RemoveAll(a => a.AttachmentID == attachment.AttachmentID);
|
||||
_cache.Set($"mrbAttachments{attachment.MRBNumber}", mrbAttachmentList, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SubmitForApproval(MRB mrb) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
|
||||
string roleName = "QA_PRE_APPROVAL";
|
||||
string subRoleName = "QA_PRE_APPROVAL";
|
||||
|
||||
if (mrb.StageNo > 1) {
|
||||
roleName = "MRB Approver";
|
||||
subRoleName = "MRBApprover";
|
||||
}
|
||||
|
||||
int roleId = await _approvalService.GetRoleIdForRoleName(roleName);
|
||||
|
||||
if (roleId <= 0) throw new Exception($"could not find {roleName} role ID");
|
||||
|
||||
IEnumerable<SubRole> subRoles = await _approvalService.GetSubRolesForSubRoleName(subRoleName, roleId);
|
||||
|
||||
foreach (SubRole subRole in subRoles) {
|
||||
IEnumerable<User> members = await _approvalService.GetApprovalGroupMembers(subRole.SubRoleID);
|
||||
|
||||
foreach (User member in members) {
|
||||
Approval approval = new() {
|
||||
IssueID = mrb.MRBNumber,
|
||||
RoleName = roleName,
|
||||
SubRole = subRole.SubRoleName,
|
||||
UserID = member.UserID,
|
||||
SubRoleID = subRole.SubRoleID,
|
||||
AssignedDate = DateTime.Now,
|
||||
Step = mrb.StageNo
|
||||
};
|
||||
|
||||
await _approvalService.CreateApproval(approval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task GenerateActionTasks(MRB mrb, MRBAction action) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (action is null) throw new ArgumentNullException("MRBAction cannot be null");
|
||||
|
||||
string roleName = "MRB Actions";
|
||||
string subRoleName = "MRBActions";
|
||||
|
||||
int roleId = await _approvalService.GetRoleIdForRoleName(roleName);
|
||||
|
||||
if (roleId <= 0) throw new Exception($"could not find {roleName} role ID");
|
||||
|
||||
IEnumerable<SubRole> subRoles = await _approvalService.GetSubRolesForSubRoleName(subRoleName, roleId);
|
||||
|
||||
foreach (SubRole subRole in subRoles) {
|
||||
IEnumerable<User> members = await _approvalService.GetApprovalGroupMembers(subRole.SubRoleID);
|
||||
|
||||
foreach (User member in members) {
|
||||
Approval approval = new() {
|
||||
IssueID = action.MRBNumber,
|
||||
RoleName = roleName,
|
||||
SubRole = subRole.SubRoleName,
|
||||
UserID = member.UserID,
|
||||
SubRoleID = subRole.SubRoleID,
|
||||
AssignedDate = DateTime.Now,
|
||||
Step = mrb.StageNo,
|
||||
SubRoleCategoryItem = subRole.SubRoleCategoryItem,
|
||||
TaskID = action.ActionID
|
||||
};
|
||||
|
||||
await _approvalService.CreateApproval(approval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task NotifyNewApprovals(MRB mrb) {
|
||||
if (mrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/notify/new-approvals");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(mrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify new MRB approvers, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyApprovers(MRBNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (notification.MRB is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/notify/approvers");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify MRB approvers, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyOriginator(MRBNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (notification.MRB is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/notify/originator");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify MRB originator, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyQAPreApprover(MRBNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (notification.MRB is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"mrb/notify/qa-pre-approver");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify QA pre approver, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
|
||||
using MudBlazor;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public class MesaFabApprovalAuthStateProvider : AuthenticationStateProvider, IDisposable {
|
||||
private readonly IAuthenticationService _authService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly ISnackbar _snackbar;
|
||||
|
||||
public User? CurrentUser { get; private set; }
|
||||
|
||||
public MesaFabApprovalAuthStateProvider(IAuthenticationService authService,
|
||||
ISnackbar snackbar,
|
||||
IUserService userService) {
|
||||
_authService = authService ??
|
||||
throw new ArgumentNullException("IAuthenticationService not injected");
|
||||
_snackbar = snackbar ??
|
||||
throw new ArgumentNullException("ISnackbar not injected");
|
||||
_userService = userService ??
|
||||
throw new ArgumentNullException("IUserService not injected");
|
||||
AuthenticationStateChanged += OnAuthenticationStateChangedAsync;
|
||||
}
|
||||
|
||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync() {
|
||||
ClaimsPrincipal principal = new();
|
||||
try {
|
||||
principal = await _authService.FetchAuthState();
|
||||
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
|
||||
return new(principal);
|
||||
} catch (Exception ex) {
|
||||
return new(new ClaimsPrincipal());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StateHasChanged(ClaimsPrincipal principal) {
|
||||
if (principal is null) throw new ArgumentNullException("ClaimsPrincipal cannot be null");
|
||||
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));
|
||||
}
|
||||
|
||||
public async Task LoginAsync(string loginId, string password) {
|
||||
try {
|
||||
if (string.IsNullOrWhiteSpace(loginId)) throw new ArgumentException("LoginId cannot be null or empty");
|
||||
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Password cannot be null or empty");
|
||||
|
||||
ClaimsPrincipal principal = await _authService.SendAuthenticationRequest(loginId, password);
|
||||
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));
|
||||
} catch (Exception ex) {
|
||||
_snackbar.Add(ex.Message, Severity.Error);
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(new())));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoginLocal() {
|
||||
try {
|
||||
ClaimsPrincipal principal = await _authService.AttemptLocalUserAuth();
|
||||
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));
|
||||
} catch (Exception ex) {
|
||||
_snackbar.Add(ex.Message, Severity.Error);
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(new())));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Logout() {
|
||||
CurrentUser = null;
|
||||
await _authService.ClearTokens();
|
||||
await _authService.ClearCurrentUser();
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(new())));
|
||||
}
|
||||
|
||||
public void Dispose() => AuthenticationStateChanged -= OnAuthenticationStateChangedAsync;
|
||||
|
||||
private async void OnAuthenticationStateChangedAsync(Task<AuthenticationState> task) {
|
||||
try {
|
||||
AuthenticationState authenticationState = await task;
|
||||
if (authenticationState is not null) {
|
||||
ClaimsPrincipal principal = await _authService.FetchAuthState();
|
||||
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// _snackbar.Add($"Unable to fetch authentication state, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
}
|
263
MesaFabApproval.Client/Services/PCRBService.cs
Normal file
263
MesaFabApproval.Client/Services/PCRBService.cs
Normal file
@ -0,0 +1,263 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
using MudBlazor;
|
||||
|
||||
namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IPCRBService {
|
||||
Task<string> IdIsValid(string id);
|
||||
Task<IEnumerable<PCRB>> GetAllPCRBs(bool bypassCache);
|
||||
Task CreateNewPCRB(PCRB pcrb);
|
||||
Task<PCRB> GetPCRBByPlanNumber(int planNumber, bool bypassCache);
|
||||
Task<PCRB> GetPCRBByTitle(string title, bool bypassCache);
|
||||
Task UpdatePCRB(PCRB pcrb);
|
||||
Task DeletePCRB(int planNumber);
|
||||
}
|
||||
|
||||
public class PCRBService : IPCRBService {
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ISnackbar _snackbar;
|
||||
|
||||
public PCRBService(IMemoryCache cache, IHttpClientFactory httpClientFactory, ISnackbar snackbar) {
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
_snackbar = snackbar ?? throw new ArgumentNullException("ISnackbar not injected");
|
||||
}
|
||||
|
||||
public async Task<string> IdIsValid(string id) {
|
||||
bool isMatch = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(id)) isMatch = false;
|
||||
|
||||
try {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/getByPlanNumber?planNumber={id}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
PCRB? pcrb = JsonSerializer.Deserialize<PCRB>(responseContent, jsonSerializerOptions);
|
||||
|
||||
if (pcrb is null) isMatch = false;
|
||||
} else {
|
||||
isMatch = false;
|
||||
}
|
||||
} catch (Exception) {
|
||||
isMatch = false;
|
||||
}
|
||||
|
||||
if (!isMatch) return $"{id} is not a valid PCRB#";
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCRB>> GetAllPCRBs(bool bypassCache) {
|
||||
try {
|
||||
IEnumerable<PCRB>? allPCRBs = null;
|
||||
if (!bypassCache) allPCRBs = _cache.Get<IEnumerable<PCRB>>("allPCRBs");
|
||||
|
||||
if (allPCRBs is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/all?bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
allPCRBs = JsonSerializer.Deserialize<IEnumerable<PCRB>>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("Unable to parse PCRBs from API response");
|
||||
|
||||
_cache.Set($"allPCRBs", allPCRBs, DateTimeOffset.Now.AddMinutes(15));
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
return allPCRBs;
|
||||
} catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreateNewPCRB(PCRB pcrb) {
|
||||
if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(pcrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
PCRB newPCRB = await GetPCRBByTitle(pcrb.Title, true);
|
||||
|
||||
_cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
IEnumerable<PCRB>? allPCRBs = _cache.Get<IEnumerable<PCRB>>("allPCRBs");
|
||||
if (allPCRBs is not null) {
|
||||
List<PCRB> pcrbList = allPCRBs.ToList();
|
||||
pcrbList.Add(newPCRB);
|
||||
_cache.Set("allPCRBs", pcrbList);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PCRB> GetPCRBByPlanNumber(int planNumber, bool bypassCache) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB plan #");
|
||||
|
||||
PCRB? pcrb = null;
|
||||
if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{planNumber}");
|
||||
|
||||
if (pcrb is null && !bypassCache)
|
||||
pcrb = _cache.Get<IEnumerable<PCRB>>("allPCRBs")?.FirstOrDefault(m => m.PlanNumber == planNumber);
|
||||
|
||||
if (pcrb is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage =
|
||||
new(HttpMethod.Get, $"pcrb/getByPlanNumber?planNumber={planNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
pcrb = JsonSerializer.Deserialize<PCRB>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("unable to parse PCRB from API response");
|
||||
|
||||
_cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
if (bypassCache) {
|
||||
IEnumerable<PCRB>? allPCRBs = _cache.Get<IEnumerable<PCRB>>("allPCRBs");
|
||||
if (allPCRBs is not null) {
|
||||
List<PCRB> pcrbList = allPCRBs.ToList();
|
||||
pcrbList.RemoveAll(p => p.PlanNumber == planNumber);
|
||||
pcrbList.Add(pcrb);
|
||||
_cache.Set("allPCRBs", pcrbList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pcrb;
|
||||
}
|
||||
|
||||
public async Task<PCRB> GetPCRBByTitle(string title, bool bypassCache) {
|
||||
if (string.IsNullOrWhiteSpace(title)) throw new ArgumentNullException("title cannot be null");
|
||||
|
||||
PCRB? pcrb = null;
|
||||
if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{title}");
|
||||
|
||||
if (pcrb is null && !bypassCache)
|
||||
pcrb = _cache.Get<IEnumerable<PCRB>>("allPCRBs")?.FirstOrDefault(m => m.Title.Equals(title));
|
||||
|
||||
if (pcrb is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage =
|
||||
new(HttpMethod.Get, $"pcrb/getByTitle?title={title}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
pcrb = JsonSerializer.Deserialize<PCRB>(responseContent, jsonSerializerOptions) ??
|
||||
throw new Exception("unable to parse PCRB from API response");
|
||||
|
||||
_cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
if (bypassCache) {
|
||||
IEnumerable<PCRB>? allPCRBs = _cache.Get<IEnumerable<PCRB>>("allPCRBs");
|
||||
if (allPCRBs is not null) {
|
||||
List<PCRB> pcrbList = allPCRBs.ToList();
|
||||
pcrbList.RemoveAll(p => p.PlanNumber == pcrb.PlanNumber);
|
||||
pcrbList.Add(pcrb);
|
||||
_cache.Set("allPCRBs", pcrbList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pcrb;
|
||||
}
|
||||
|
||||
public async Task UpdatePCRB(PCRB pcrb) {
|
||||
if (pcrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(pcrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
_cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
_cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1));
|
||||
|
||||
IEnumerable<PCRB>? allPCRBs = _cache.Get<IEnumerable<PCRB>>("allPCRBs");
|
||||
if (allPCRBs is not null) {
|
||||
List<PCRB> pcrbList = allPCRBs.ToList();
|
||||
pcrbList.RemoveAll(m => m.PlanNumber == pcrb.PlanNumber);
|
||||
pcrbList.Add(pcrb);
|
||||
_cache.Set("allPCRBs", pcrbList);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeletePCRB(int planNumber) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB plan #");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/delete?planNumber={planNumber}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
IEnumerable<PCRB> allPCRBs = await GetAllPCRBs(true);
|
||||
_cache.Set("allPCRBs", allPCRBs);
|
||||
}
|
||||
}
|
208
MesaFabApproval.Client/Services/UserService.cs
Normal file
208
MesaFabApproval.Client/Services/UserService.cs
Normal file
@ -0,0 +1,208 @@
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Http;
|
||||
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)
|
||||
throw new Exception("unable to fetch all active users");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user