Refactoring Claims, add Server Side Messaging (#33)
* cache JWT by ApiUri, CharaIdent, SecretKey, refactor auth flow to new api * add server side message handling * update client to mainline api Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -78,6 +78,12 @@ public partial class ApiController
|
||||
_mareHub!.On(nameof(Client_AdminUpdateOrAddForbiddenFile), act);
|
||||
}
|
||||
|
||||
public void OnReceiveServerMessage(Action<MessageSeverity, string> act)
|
||||
{
|
||||
if (_initialized) return;
|
||||
_mareHub!.On(nameof(Client_ReceiveServerMessage), act);
|
||||
}
|
||||
|
||||
public Task Client_UserUpdateClientPairs(ClientPairDto dto)
|
||||
{
|
||||
var entry = PairedClients.SingleOrDefault(e => string.Equals(e.OtherUID, dto.OtherUID, System.StringComparison.Ordinal));
|
||||
@@ -213,4 +219,25 @@ public partial class ApiController
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Client_ReceiveServerMessage(MessageSeverity severity, string message)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
case MessageSeverity.Error:
|
||||
Logger.Error(message);
|
||||
_dalamudUtil.PrintErrorChat(message);
|
||||
break;
|
||||
case MessageSeverity.Warning:
|
||||
Logger.Warn(message);
|
||||
_dalamudUtil.PrintWarnChat(message);
|
||||
break;
|
||||
case MessageSeverity.Information:
|
||||
Logger.Info(message);
|
||||
_dalamudUtil.PrintInfoChat(message);
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ using MareSynchronos.FileCache;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI.Utils;
|
||||
using Microsoft.AspNetCore.Http.Connections;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -20,6 +19,8 @@ namespace MareSynchronos.WebAPI;
|
||||
|
||||
public delegate void SimpleStringDelegate(string str);
|
||||
|
||||
public record JwtCache(string ApiUrl, string CharaIdent, string SecretKey);
|
||||
|
||||
public partial class ApiController : IDisposable, IMareHubClient
|
||||
{
|
||||
public const string MainServer = "Lunae Crescere Incipientis (Central Server EU)";
|
||||
@@ -31,8 +32,8 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly FileCacheManager _fileDbManager;
|
||||
private CancellationTokenSource _connectionCancellationTokenSource;
|
||||
private Dictionary<string, string> _jwtToken = new(StringComparer.Ordinal);
|
||||
private KeyValuePair<string, string> AuthorizationJwtHeader => new("Authorization", "Bearer " + _jwtToken[SecretKey]);
|
||||
private Dictionary<JwtCache, string> _jwtToken = new();
|
||||
private KeyValuePair<string, string> AuthorizationJwtHeader => new("Authorization", "Bearer " + _jwtToken.GetValueOrDefault(new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey), string.Empty));
|
||||
|
||||
private HubConnection? _mareHub;
|
||||
|
||||
@@ -41,6 +42,7 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
|
||||
private ConnectionDto? _connectionDto;
|
||||
public ServerInfoDto ServerInfo => _connectionDto?.ServerInfo ?? new ServerInfoDto();
|
||||
public string AuthFailureMessage { get; private set; } = string.Empty;
|
||||
|
||||
public SystemInfoDto SystemInfoDto { get; private set; } = new();
|
||||
public bool IsModerator => (_connectionDto?.IsAdmin ?? false) || (_connectionDto?.IsModerator ?? false);
|
||||
@@ -167,15 +169,17 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
continue;
|
||||
}
|
||||
|
||||
AuthFailureMessage = string.Empty;
|
||||
|
||||
await StopConnection(token).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Debug("Building connection");
|
||||
|
||||
if (!_jwtToken.TryGetValue(SecretKey, out var jwtToken) || forceGetToken)
|
||||
if (!_jwtToken.TryGetValue(new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey), out var jwtToken) || forceGetToken)
|
||||
{
|
||||
Logger.Debug("Requesting new JWT token");
|
||||
Logger.Debug("Requesting new JWT");
|
||||
using HttpClient httpClient = new();
|
||||
var postUri = new Uri(new Uri(ApiUri
|
||||
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
||||
@@ -184,11 +188,13 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
var auth = BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(SecretKey))).Replace("-", "", StringComparison.OrdinalIgnoreCase);
|
||||
var result = await httpClient.PostAsync(postUri, new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("auth", auth)
|
||||
new KeyValuePair<string, string>("auth", auth),
|
||||
new KeyValuePair<string, string>("charaIdent", _dalamudUtil.PlayerNameHashed)
|
||||
})).ConfigureAwait(false);
|
||||
AuthFailureMessage = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
result.EnsureSuccessStatusCode();
|
||||
_jwtToken[SecretKey] = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Logger.Debug("JWT Token Success");
|
||||
_jwtToken[new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey)] = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Logger.Debug("JWT Success");
|
||||
}
|
||||
|
||||
while (!_dalamudUtil.IsPlayerPresent && !token.IsCancellationRequested)
|
||||
@@ -203,9 +209,10 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
|
||||
await _mareHub.StartAsync(token).ConfigureAwait(false);
|
||||
|
||||
OnReceiveServerMessage((sev, msg) => Client_ReceiveServerMessage(sev, msg));
|
||||
OnUpdateSystemInfo((dto) => Client_UpdateSystemInfo(dto));
|
||||
|
||||
_connectionDto = await Heartbeat(_dalamudUtil.PlayerNameHashed).ConfigureAwait(false);
|
||||
_connectionDto = await GetConnectionDto().ConfigureAwait(false);
|
||||
|
||||
ServerState = ServerState.Connected;
|
||||
|
||||
@@ -225,24 +232,6 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
_mareHub.Reconnected += MareHubOnReconnected;
|
||||
}
|
||||
}
|
||||
catch (HubException ex)
|
||||
{
|
||||
if (ex.Message.Contains("unauthorized", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Warn(ex.Message);
|
||||
ServerState = ServerState.Unauthorized;
|
||||
await StopConnection(token).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Warn(ex.GetType().ToString());
|
||||
Logger.Warn(ex.Message);
|
||||
Logger.Warn(ex.StackTrace ?? string.Empty);
|
||||
|
||||
ServerState = ServerState.RateLimited;
|
||||
await StopConnection(token).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Logger.Warn(ex.GetType().ToString());
|
||||
@@ -423,6 +412,11 @@ public partial class ApiController : IDisposable, IMareHubClient
|
||||
return await _mareHub!.InvokeAsync<ConnectionDto>(nameof(Heartbeat), characterIdentification).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<ConnectionDto> GetConnectionDto()
|
||||
{
|
||||
return await _mareHub!.InvokeAsync<ConnectionDto>(nameof(GetConnectionDto)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> CheckClientHealth()
|
||||
{
|
||||
return await _mareHub!.InvokeAsync<bool>(nameof(CheckClientHealth)).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user