mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 21:46:30 +00:00
127 lines
4.3 KiB
C#
127 lines
4.3 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Net;
|
|
using System.Net.Http.Headers;
|
|
using System.Security;
|
|
using System.Text;
|
|
using Azaion.CommonSecurity.DTO;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Azaion.CommonSecurity.Services;
|
|
|
|
public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
|
{
|
|
const string JSON_MEDIA = "application/json";
|
|
|
|
private static ApiConfig _apiConfig = null!;
|
|
|
|
private string Email { get; set; } = null!;
|
|
private SecureString Password { get; set; } = new();
|
|
private string JwtToken { get; set; } = null!;
|
|
public User User { get; set; } = null!;
|
|
|
|
public static AzaionApiClient Create(ApiCredentials credentials)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(SecurityConstants.CONFIG_PATH))
|
|
throw new FileNotFoundException(SecurityConstants.CONFIG_PATH);
|
|
var configStr = File.ReadAllText(SecurityConstants.CONFIG_PATH);
|
|
_apiConfig = JsonConvert.DeserializeObject<SecureAppConfig>(configStr)!.ApiConfig;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
_apiConfig = new ApiConfig
|
|
{
|
|
Url = SecurityConstants.DEFAULT_API_URL,
|
|
RetryCount = SecurityConstants.DEFAULT_API_RETRY_COUNT ,
|
|
TimeoutSeconds = SecurityConstants.DEFAULT_API_TIMEOUT_SECONDS
|
|
};
|
|
}
|
|
|
|
var api = new AzaionApiClient(new HttpClient
|
|
{
|
|
BaseAddress = new Uri(_apiConfig.Url),
|
|
Timeout = TimeSpan.FromSeconds(_apiConfig.TimeoutSeconds)
|
|
});
|
|
|
|
api.EnterCredentials(credentials);
|
|
return api;
|
|
}
|
|
|
|
public void EnterCredentials(ApiCredentials credentials)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(credentials.Email) || string.IsNullOrWhiteSpace(credentials.Password))
|
|
throw new Exception("Email or password is empty!");
|
|
|
|
Email = credentials.Email;
|
|
Password = credentials.Password.ToSecureString();
|
|
}
|
|
|
|
public async Task<Stream> GetResource(string fileName, string password, HardwareInfo hardware)
|
|
{
|
|
var response = await Send(httpClient, new HttpRequestMessage(HttpMethod.Post, $"/resources/get/{_apiConfig.ResourcesFolder}")
|
|
{
|
|
Content = new StringContent(JsonConvert.SerializeObject(new { fileName, password, hardware }), Encoding.UTF8, JSON_MEDIA)
|
|
});
|
|
return await response.Content.ReadAsStreamAsync();
|
|
}
|
|
|
|
private async Task Authorize()
|
|
{
|
|
if (string.IsNullOrEmpty(Email) || Password.Length == 0)
|
|
throw new Exception("Email or password is empty! Please do EnterCredentials first!");
|
|
|
|
var payload = new
|
|
{
|
|
email = Email,
|
|
password = Password.ToRealString()
|
|
};
|
|
var response = await httpClient.PostAsync(
|
|
"login",
|
|
new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, JSON_MEDIA));
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
throw new Exception($"EnterCredentials failed: {response.StatusCode}");
|
|
|
|
var responseData = await response.Content.ReadAsStringAsync();
|
|
|
|
var result = JsonConvert.DeserializeObject<LoginResponse>(responseData);
|
|
|
|
if (string.IsNullOrEmpty(result?.Token))
|
|
throw new Exception("JWT Token not found in response");
|
|
|
|
var handler = new JwtSecurityTokenHandler();
|
|
var token = handler.ReadJwtToken(result.Token);
|
|
|
|
User = new User(token.Claims);
|
|
JwtToken = result.Token;
|
|
}
|
|
|
|
private async Task<HttpResponseMessage> Send(HttpClient client, HttpRequestMessage request)
|
|
{
|
|
if (string.IsNullOrEmpty(JwtToken))
|
|
await Authorize();
|
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
|
var response = await client.SendAsync(request);
|
|
|
|
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
|
{
|
|
await Authorize();
|
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
|
response = await client.SendAsync(request);
|
|
}
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
return response;
|
|
|
|
var result = await response.Content.ReadAsStringAsync();
|
|
throw new Exception($"Failed: {response.StatusCode}! Result: {result}");
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
httpClient.Dispose();
|
|
Password.Dispose();
|
|
}
|
|
} |