120 lines
3.4 KiB
C#
120 lines
3.4 KiB
C#
using System;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Flawless.Client.Remote;
|
|
using ReactiveUI;
|
|
using Refit;
|
|
|
|
namespace Flawless.Client.Service;
|
|
|
|
public class Api : BaseService<Api>
|
|
{
|
|
class ApiAuthenticationHandler : DelegatingHandler
|
|
{
|
|
public ApiAuthenticationHandler(HttpMessageHandler innerHandler) : base(innerHandler)
|
|
{
|
|
}
|
|
|
|
protected override Task<HttpResponseMessage> SendAsync(
|
|
HttpRequestMessage request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var tk = Api.C._token.Value;
|
|
if (tk != null) request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tk.Token);
|
|
return base.SendAsync(request, cancellationToken);
|
|
}
|
|
|
|
}
|
|
|
|
public IObservable<bool> IsLoggedIn => _isLoggedIn;
|
|
|
|
public IObservable<string?> ServerUrl => _serverUrl;
|
|
|
|
public IObservable<ServerStatusResponse?> Status => _status;
|
|
|
|
public IObservable<TokenInfo?> Token => _token;
|
|
|
|
public IReactiveProperty<string?> Username => _username;
|
|
|
|
private readonly ReactiveProperty<bool> _isLoggedIn = new(false);
|
|
|
|
private readonly ReactiveProperty<string?> _serverUrl = new(string.Empty);
|
|
|
|
private readonly ReactiveProperty<ServerStatusResponse?> _status = new(null);
|
|
|
|
private readonly ReactiveProperty<TokenInfo?> _token = new(null);
|
|
|
|
private readonly ReactiveProperty<string?> _username = new(string.Empty);
|
|
|
|
#region GatewayConfig
|
|
|
|
private IFlawlessServer? _gateway;
|
|
|
|
public bool IsGatewayReady => _gateway != null;
|
|
|
|
public IFlawlessServer Gateway => _gateway ?? throw new InvalidProgramException("Not set gateway yet!");
|
|
|
|
public void ClearGateway()
|
|
{
|
|
_gateway = null;
|
|
_username.Value = null;
|
|
_isLoggedIn.Value = false;
|
|
_status.Value = null;
|
|
_serverUrl.Value = null;
|
|
_token.Value = null;
|
|
}
|
|
|
|
public async ValueTask SetGatewayAsync(string host)
|
|
{
|
|
var setting = new RefitSettings()
|
|
{
|
|
HttpMessageHandlerFactory = () => new ApiAuthenticationHandler(new HttpClientHandler())
|
|
};
|
|
|
|
var tempGateway = RestService.For<IFlawlessServer>(host, setting);
|
|
_status.Value = await tempGateway.Status();
|
|
_serverUrl.Value = host;
|
|
_gateway = tempGateway;
|
|
}
|
|
|
|
public async ValueTask LoginAsync(string username, string password)
|
|
{
|
|
_token.Value = await _gateway.Login(new LoginRequest
|
|
{
|
|
Username = username,
|
|
Password = password
|
|
});
|
|
|
|
_username.Value = username;
|
|
_isLoggedIn.Value = true;
|
|
await UserService.C.DownloadUserInfoAsync(username);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region TokenOperations
|
|
|
|
public bool RequireRefreshToken()
|
|
{
|
|
if (_token.Value == null) return true;
|
|
if (DateTime.UtcNow > _token.Value.Expiration!.Value.UtcDateTime.AddMinutes(-2)) return true;
|
|
return false;
|
|
}
|
|
|
|
public async ValueTask<bool> TryRefreshTokenAsync()
|
|
{
|
|
if (_token.Value == null) return false;
|
|
try { _token.Value = await Gateway.Refresh(_token.Value); }
|
|
catch (Exception e)
|
|
{
|
|
await Console.Error.WriteLineAsync(e.ToString());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
} |