304 lines
13 KiB
C#
304 lines
13 KiB
C#
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}");
|
|
}
|
|
|
|
await GetApprovalsForIssueId(approval.IssueID, true);
|
|
await GetApprovalsForUserId(approval.UserID, true);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|