1
0

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
}