69 lines
2.1 KiB
C#
69 lines
2.1 KiB
C#
using interfaces;
|
|
using Microsoft.Extensions.Options;
|
|
using options;
|
|
|
|
namespace services;
|
|
|
|
internal class SmappeeTokenService : IBearerTokenService
|
|
{
|
|
private readonly ChargerOptions options;
|
|
private readonly IHttpClientFactory httpClientFactory;
|
|
|
|
private TokenData? tokenData = null;
|
|
|
|
public SmappeeTokenService(
|
|
IOptions<ChargerOptions> options,
|
|
IHttpClientFactory httpClientFactory
|
|
)
|
|
{
|
|
this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
|
|
this.httpClientFactory =
|
|
httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
|
|
}
|
|
|
|
public async ValueTask<string> GetToken(bool forceNewToken)
|
|
{
|
|
if (
|
|
tokenData == null
|
|
|| tokenData.Expiration < DateTime.UtcNow.AddSeconds(-10)
|
|
|| forceNewToken
|
|
)
|
|
{
|
|
tokenData = await RequestNewToken();
|
|
}
|
|
return tokenData.Token;
|
|
}
|
|
|
|
private async Task<TokenData> RequestNewToken()
|
|
{
|
|
var httpClient = httpClientFactory.CreateClient("smappeeTokenService");
|
|
httpClient.BaseAddress = options.Url;
|
|
|
|
var result = await httpClient.PostAsync(
|
|
"/dev/v3/oauth2/token",
|
|
new FormUrlEncodedContent(
|
|
new Dictionary<string, string>
|
|
{
|
|
["grant_type"] = "password",
|
|
["client_id"] = options.ClientId,
|
|
["client_secret"] = options.ClientSecret,
|
|
["username"] = options.UserName,
|
|
["password"] = options.Password,
|
|
}
|
|
)
|
|
);
|
|
result.EnsureSuccessStatusCode();
|
|
var tokenResponse =
|
|
await result.Content.ReadFromJsonAsync<TokenResponse>()
|
|
?? throw new InvalidOperationException("Token could not be fetched");
|
|
return new TokenData(
|
|
tokenResponse.access_token,
|
|
DateTime.UtcNow.AddSeconds(tokenResponse.expires_in)
|
|
);
|
|
}
|
|
|
|
record TokenResponse(string access_token, int expires_in);
|
|
|
|
record TokenData(string Token, DateTime Expiration);
|
|
}
|