Files
pfm/PostFundManagement.Application/Services/Shared/TokenService.cs
T
2026-10-04 14:31:06 +02:00

45 lines
2.2 KiB
C#

using PostFundManagement.Domain.Configuration.Security;
using PostFundManagement.Domain.Errors;
using PostFundManagement.Domain.Models.Security;
using PostFundManagement.Infrastructure.Security;
namespace PostFundManagement.Application.Services.Shared;
public sealed class TokenService(ISecurityConnectApi connectApi, IOptions<SecurityClientSettings> clientOptions)
{
private readonly SecurityClientSettings clientSettings = clientOptions.Value;
public async Task<Result<Domain.Models.Security.TokenResponse>> GenerateAsync(CancellationToken cancellationToken = default) =>
await Result.Try((Func<Task<Result<Domain.Models.Security.TokenResponse>>>)(async () =>
{
using var response = await connectApi.GetToken(new Domain.Models.Security.TokenRequest
{
ClientId = clientSettings.ClientId,
ClientSecret = clientSettings.ClientSecret,
GrantType = clientSettings.GrantType,
Scope = clientSettings.Scope,
}, cancellationToken);
var contentRaw = await response.Content.ReadAsStringAsync(cancellationToken);
if (string.IsNullOrWhiteSpace(contentRaw))
return Result.Fail(ValidationError.Create($"The authentication endpoint returned an empty payload. Status code: {response.StatusCode}"));
if (response.IsSuccessStatusCode)
{
var tokenResponse = JsonSerializer.Deserialize<Domain.Models.Security.TokenResponse>(contentRaw);
return Result.FailIf(string.IsNullOrWhiteSpace(tokenResponse?.AccessToken),
NotFoundError.Create("Authentication succeeded, but no access token was found in the response payload."))
.ToResult(tokenResponse!);
}
return await Result.Try((Func<Task<Result<Domain.Models.Security.TokenResponse>>>)(async () =>
{
var errorResult = JsonSerializer.Deserialize<TokenErrorResponse>(contentRaw);
return Result.OkIf(errorResult is not null,
CreateError.Create($"{errorResult!.Error}: {errorResult.ErrorDescription}"));
}));
}));
}