Added skoruba api integration
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
<!-- Database -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Duende.AccessTokenManagement" Version="4.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="10.0.12" />
|
||||
@@ -26,6 +27,8 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
|
||||
|
||||
<Using Include="Refit" />
|
||||
<Using Include="FluentResults" />
|
||||
<Using Include="System.Reflection" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore.Design" />
|
||||
@@ -37,7 +40,10 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.12" />
|
||||
|
||||
<Using Include="Microsoft.OpenApi" />
|
||||
<Using Include="Microsoft.AspNetCore.OpenApi" />
|
||||
<Using Include="Microsoft.AspNetCore.Http" />
|
||||
<Using Include="System.Net.Http.Json" />
|
||||
<Using Include="Microsoft.Extensions.Configuration" />
|
||||
<Using Include="Microsoft.Extensions.DependencyInjection" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using PostFundManagement.Domain.Models.Security;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Security;
|
||||
|
||||
public interface ISecurityConnectApi
|
||||
{
|
||||
[Post("/connect/token")]
|
||||
ValueTask<HttpResponseMessage> GetToken([Body(BodySerializationMethod.UrlEncoded)] TokenRequest request, CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace PostFundManagement.Infrastructure.Security;
|
||||
|
||||
public sealed class OpenApiBearerSecuritySchemeTransformer : IOpenApiDocumentTransformer
|
||||
{
|
||||
public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
var bearerScheme = new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "bearer",
|
||||
Description = "JWT Authorization header using the Bearer scheme",
|
||||
};
|
||||
|
||||
document.AddComponent("Bearer", bearerScheme);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Models.Security;
|
||||
using static PostFundManagement.Domain.Extensions.Constants;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Security;
|
||||
|
||||
public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClientFactory httpClientFactory) : ISkorubaUserService
|
||||
{
|
||||
public async Task<Result<string>> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<string>>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var response = await httpClient.PostAsJsonAsync("api/users", request, cancellationToken);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await response.Content.ReadFromJsonAsync<UserResponse>(cancellationToken: cancellationToken);
|
||||
|
||||
return Result.FailIf(created is null, CreateError.Create("User ID missing from creation response."))
|
||||
.ToResult(created?.Id!);
|
||||
}));
|
||||
|
||||
public async Task<Result<UserResponse>> GetUserAsync(string userId, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<UserResponse>>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var result = await httpClient.GetFromJsonAsync<UserResponse>($"api/users/{userId}", cancellationToken);
|
||||
|
||||
return Result.FailIf(result is null, NotFoundError.Create($"User {userId} not found."))
|
||||
.ToResult(result!);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateUserAsync(UpdateUserRequest request, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var response = await httpClient.PutAsJsonAsync("api/users", request, cancellationToken);
|
||||
|
||||
return Result.OkIf(response.IsSuccessStatusCode, UpdateError.Create("Failed to update user."));
|
||||
}));
|
||||
|
||||
public async Task<Result> SetUserLockoutAsync(string userId, bool disabled, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var user = await httpClient.GetFromJsonAsync<UpdateUserRequest>($"api/users/{userId}", cancellationToken);
|
||||
|
||||
if(user is null)
|
||||
return Result.Fail(NotFoundError.Create($"User {userId} not found."));
|
||||
|
||||
var updated = user with
|
||||
{
|
||||
LockoutEnabled = true,
|
||||
LockoutEnd = disabled ? DateTimeOffset.UtcNow.AddYears(100) : null
|
||||
};
|
||||
|
||||
var response = await httpClient.PutAsJsonAsync("api/users", updated, cancellationToken);
|
||||
|
||||
return Result.OkIf(response.IsSuccessStatusCode, UpdateError.Create("Failed to update user lockout status."));
|
||||
}));
|
||||
|
||||
public async Task<Result> AddClaimAsync(string userId, string claimType, string claimValue, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var payload = new { UserId = userId, ClaimType = claimType, ClaimValue = claimValue };
|
||||
|
||||
var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/claims", payload, cancellationToken);
|
||||
|
||||
return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user claim."));
|
||||
}));
|
||||
|
||||
public async Task<Result> RemoveClaimAsync(string userId, int claimId, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result>>)(async () =>
|
||||
{
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
var response = await httpClient.DeleteAsync($"api/users/{userId}/claims/{claimId}", cancellationToken);
|
||||
|
||||
return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user claim."));
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user