diff --git a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs index 469030c..fa5e435 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs index 62ff7be..22b4d41 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs new file mode 100644 index 0000000..9a83ce9 --- /dev/null +++ b/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs @@ -0,0 +1,35 @@ +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models; + +namespace PostFundManagement.Api.Endpoints.Communications; + +[ApiVersionTarget(1)] +public sealed class GetIApplicantDataEndpoint : IEndpoint +{ + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/communications/applicants/{applicantUserId:Guid}/all", async (Guid applicantUserId, + ICommunicationsService service, CancellationToken cancellationtToken = default ) => + await service.GetApplicantDataAsync(applicantUserId, cancellationtToken) switch + { + { IsSuccess: true, Value: var applicantData } => Results.Ok(applicantData), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Gets an applicant's data") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetIApplicantDataEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Communications) + .CacheOutput(); + } +} diff --git a/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs index c4932e6..6ab11d0 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs @@ -4,8 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using static PostFundManagement.Application.Extensions.General; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs index 80e2d30..f8d1b8c 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs @@ -4,8 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using static PostFundManagement.Application.Extensions.General; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs index 79c606a..97f45ca 100644 --- a/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs @@ -5,7 +5,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs index 62e123d..e16d041 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs index f4caad6..70e563d 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs index eea7d47..90a5343 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs index 0222ef2..24b2e17 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs index 0624477..32eb996 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs index 3c910d5..188fb18 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs index d36afa5..292311a 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs index e4b500a..c23a25b 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs index f65efb8..59a8cda 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs index c39e9ec..3ebac97 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs index 3c617ac..c76f0f3 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs index 4db42ba..eddb256 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs index 3424687..8fae8cb 100644 --- a/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs index cbc225d..623c676 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs index f9418c4..f272f78 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs index 6a093b7..b4eccbb 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs index 95118d4..ca185d1 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs index b498ec2..2cdb88d 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs index 9d78329..3b4539e 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs index ecd2fb6..d0cb01f 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs index 11ecc5e..79f0b5f 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs index 1ca8f40..37167ef 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs index 8ecb1ae..cc955e2 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs index b0d0f70..cbbc176 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs index ff8f53a..8fc7880 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs index 80a6073..e382dc5 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs index 334bde9..5146d0b 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs index 8c38558..d85f8f8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs index 6f0fffa..3cd15b5 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs index 572f11e..12766ba 100644 --- a/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs index 7f086d0..1f2b0e9 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs index 83db06a..cffe719 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs index 96f841b..3c4f3ce 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs index 496a984..698bbcf 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs index 3f08d06..0cbf1c8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs index 82d22ae..451de3b 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs index 8229e24..6c20b65 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs index b2f5f56..479738d 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs index 311ec87..deef39e 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs index fc3de4f..7140de3 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs index aabc0f5..f000a72 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs index 850aeeb..86816ad 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs index 0d22bcf..70a3e62 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs @@ -1,10 +1,9 @@ using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; -using PostFundManagement.Domain.Entities; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; +using PostFundManagement.Domain.Models; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs index e4f954c..64475d7 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Entities; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs index 292b542..4246258 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs index c493bc9..21964d8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs index d8cc5d9..385fd8a 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs index ca065eb..8e36634 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs index 7e2ee74..377f5bd 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs index 6e104e1..56bd98a 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs index 8d2b2b6..aab4043 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs index a57a7bd..d2e80d5 100644 --- a/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs index 76162ca..1524d88 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs index 393b8ee..06c3a79 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs index c7f0696..c8b8cfb 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs index 30b84d5..69f1137 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs index 46ea9b1..4730670 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs index efa6aab..88d7956 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs index 4595a7f..bc5f4b8 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs index 5bea5a6..5a82bfe 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs index e2bc190..bb480b3 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs index 0d6ec67..b7071ec 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs index 30f7b2f..e1ab7a9 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs index 51312b2..1acab9e 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs index 1cf7e7f..7b6f4ef 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs index 921972d..644bce6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs index ffc1f99..18fba1c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs index ded7561..7b85f6b 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs index af1119f..438b795 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs index 9c9d352..3da9e67 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs index 0be71f6..2ad2cb3 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs index 7fa0c10..70a25f4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs index 2cd9be9..d8fa107 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs index f8a86fc..23093e4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs index 1cae920..040c33c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs index 071cbad..a0bc0f4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs index 1a192cc..462acb8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs index b910f67..5229d77 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs index 08fef13..5d94dd6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs index b2882cd..921a9e8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs index 35db03a..efd4ac0 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs index c4573bc..49cd9e5 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs index 62efa73..a4f03e4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs index 44b84ce..c461a81 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs index 96e5c96..cd7d4d6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs index 2084381..3e13e39 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs index 3cd77ca..929a9dc 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs index dab6d2a..3362d77 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs index 17b8d4b..7a445fb 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs index a36b877..c6be951 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs index 26e5567..493b68b 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs index 2ebea23..da811dc 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs index fd3aff8..3b9daf8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs index a9d224f..279bd66 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs index 8259aac..07c2e1f 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs index 580fd3e..52fdd25 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs index d9eecea..e4d1795 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs index 134af82..8f72bd1 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs index 2a2033f..42d84c7 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs index 7ef1ebb..b529654 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs index de8a0dd..019acdb 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs index f1497dc..98b9845 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs index 0c9d6aa..79d14e0 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs index dc08e86..c4a3d5c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs index 3513f13..205850d 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs index ace3d84..4cc6cdb 100644 --- a/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs @@ -1,5 +1,36 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class AddUserClaimEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class AddUserClaimEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPatch("api/users/user/claims", async (AddUserClaimRequest request, HttpContext context, + IUserService userService, CancellationToken cancellationToken = default) => + await userService.AddUserClaimAsync(request, userId: context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Adds a claim to a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(AddUserClaimEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs index 489399e..359bb42 100644 --- a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class AddUserRoleEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class AddUserRoleEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPatch("api/users/{userId:Guid}/roles/{roleId:Guid}", async (Guid userId, Guid roleId, HttpContext context, + IUserService userService, CancellationToken cancellationToken = default) => + await userService.AddUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Adds a role to a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(AddUserRoleEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs index fca9d81..520b95d 100644 --- a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs @@ -1,5 +1,37 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class CreateUserEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class CreateUserEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPost("/api/users/{tenantId}/{idNumber}", async (string tenantId, string idNumber, CreateUserRequest request, HttpContext context, IUserService userService, + CancellationToken cancellationToken = default) => + await userService.CreateUserAsync(tenantId, idNumber, request, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.Forbid(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Creates a new user in the system") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(CreateUserEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status403Forbidden) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs index c96246d..fd8d4fa 100644 --- a/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs @@ -1,6 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class DeleteUserClaimEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class DeleteUserClaimEndpoint : IEndpoint { - + public void Map(IEndpointRouteBuilder builder) + { + builder.MapDelete("api/users/{targetUserId:Guid}/claims/{claimId}", async (string claimId, Guid targetUserId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.DeleteUserClaimAsync(claimIdHash: claimId, targetUserId: targetUserId, userId: context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.Forbid(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Deletes a claim from a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(DeleteUserClaimEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs index e756806..5938916 100644 --- a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class DeleteUserRoleEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class DeleteUserRoleEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapDelete("api/users/{userId:Guid}/roles/{roleId:Guid}", async (Guid userId, Guid roleId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.DeleteUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Delete user role") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(DeleteUserRoleEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs new file mode 100644 index 0000000..15d3f6b --- /dev/null +++ b/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs @@ -0,0 +1,34 @@ +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; + +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetRoleClaimsEndpoint : IEndpoint +{ + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/system/roles/{roleId:Guid}/claims", async (Guid roleId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetRoleClaimsAsync(roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var claims } => Results.Ok(claims), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get system role claims") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetRoleClaimsEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } +} diff --git a/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs index fd50ffc..d289bc5 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class GetSystemRolesEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetSystemRolesEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/system/roles", async (HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetSystemRolesAsync(context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var roles } => Results.Ok(roles), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get system roles") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetSystemRolesEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs index d425540..4a2d4d4 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs @@ -1,6 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using Claim = PostFundManagement.Domain.Models.Security.Claim; -public class GetUserClaimsEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetUserClaimsEndpoint : IEndpoint { - + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/{userId:Guid}/claims", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetUserClaimsAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var claims } => Results.Ok(claims), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get user claims") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetUserClaimsEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs index a32ee3c..43749cf 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; @@ -18,7 +17,7 @@ public sealed class GetUserEndpoint : IEndpoint await service.GetUserAsync(userId, cancellationToken) switch { { IsSuccess: true, Value: var user } => Results.Ok(user), - var r when r.HasError() => Results.NotFound(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), var r => Results.InternalServerError(r.Errors.ToProblems()) }) .WithDescription("Gets the metadata of a single user.") @@ -26,8 +25,8 @@ public sealed class GetUserEndpoint : IEndpoint .WithName(typeof(GetUserEndpoint).ToEndpointName()) .MapToApiVersion(new ApiVersion(1)) .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) .Produces(StatusCodes.Status500InternalServerError) .WithTags(EndpointTags.Users) .CacheOutput(); diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs index 3eb3739..367de1d 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class GetUserRolesEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetUserRolesEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/{userId:Guid}/roles", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetUserRolesAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var roles } => Results.Ok(roles), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get user roles") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetUserRolesEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs index a3b4915..15e610c 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs @@ -5,7 +5,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs index d9f9905..1d00f5a 100644 --- a/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class LogUserOutEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class LogUserOutEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPut("api/users/{userId:Guid}/session/logout", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.LogoutUserAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Logout user session") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(LogUserOutEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs index b8173d0..c58aac9 100644 --- a/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class SetUserLockoutEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class SetUserLockoutEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPut("api/users/{userId:Guid}/session/lockout/{disable:bool}", async (Guid userId, bool disable, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.SetUserLockoutAsync(userId, context.GetUserId(), disable, cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Lock user session") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(SetUserLockoutEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs index 6fee673..faea1cc 100644 --- a/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs index 3c48131..8159eb6 100644 --- a/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/PostFundManagement.Api.csproj b/PostFundManagement.Api/PostFundManagement.Api.csproj index b1f4f21..ef0be7e 100644 --- a/PostFundManagement.Api/PostFundManagement.Api.csproj +++ b/PostFundManagement.Api/PostFundManagement.Api.csproj @@ -87,6 +87,12 @@ + + + + + + diff --git a/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs b/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs index 23149ff..3eaf3e6 100644 --- a/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs +++ b/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs @@ -33,4 +33,7 @@ public interface ICommunicationsService [Log] Task> GetNotificationAsync(string notificationIdHash, CancellationToken cancellationToken = default); + + [Log] + Task> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Application/Abstractions/Services/IToolService.cs b/PostFundManagement.Application/Abstractions/Services/IToolService.cs deleted file mode 100644 index c848b6f..0000000 --- a/PostFundManagement.Application/Abstractions/Services/IToolService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PostFundManagement.Application.Abstractions.Services; - -public interface IToolService -{ - Task> EncodeLong(long id, CancellationToken cancellationToken); -} diff --git a/PostFundManagement.Application/Abstractions/Services/IUserService.cs b/PostFundManagement.Application/Abstractions/Services/IUserService.cs index bb206cb..1666db4 100644 --- a/PostFundManagement.Application/Abstractions/Services/IUserService.cs +++ b/PostFundManagement.Application/Abstractions/Services/IUserService.cs @@ -2,6 +2,7 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Attributes; using PostFundManagement.Domain.Models; +using PostFundManagement.Domain.Models.Security; namespace PostFundManagement.Application.Abstractions.Services; @@ -19,5 +20,45 @@ public interface IUserService Task UpdateUserStatusAsync(Guid userId, ActivityStatus status, CancellationToken cancellationToken = default); [Log] - Task> GetUserAsync(Guid userId, CancellationToken cancellationToken); + Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Application/Extensions/Postgres.cs b/PostFundManagement.Application/Extensions/Postgres.cs index ef640a8..4fa1a83 100644 --- a/PostFundManagement.Application/Extensions/Postgres.cs +++ b/PostFundManagement.Application/Extensions/Postgres.cs @@ -1,5 +1,4 @@ using PostFundManagement.Infrastructure.Database; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/Quartz.cs b/PostFundManagement.Application/Extensions/Quartz.cs index 8ae2777..3dbdb82 100644 --- a/PostFundManagement.Application/Extensions/Quartz.cs +++ b/PostFundManagement.Application/Extensions/Quartz.cs @@ -1,6 +1,5 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Quartz; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/S3.cs b/PostFundManagement.Application/Extensions/S3.cs index 89d39d8..38a5e0a 100644 --- a/PostFundManagement.Application/Extensions/S3.cs +++ b/PostFundManagement.Application/Extensions/S3.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/Security.cs b/PostFundManagement.Application/Extensions/Security.cs index 5e6545a..7bb6e8f 100644 --- a/PostFundManagement.Application/Extensions/Security.cs +++ b/PostFundManagement.Application/Extensions/Security.cs @@ -1,3 +1,4 @@ +using PostFundManagement.Application.Handlers; using PostFundManagement.Application.Interceptors; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain.Abstractions; @@ -5,7 +6,6 @@ using PostFundManagement.Domain.Configuration.Security; using PostFundManagement.Domain.Extensions; using PostFundManagement.Infrastructure.Database; using PostFundManagement.Infrastructure.Security; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; @@ -25,19 +25,10 @@ public static class Security if (!authOptions.Authority.EndsWith('/')) authOptions.Authority += "/"; - services.AddClientCredentialsTokenManagement() - .AddClient(SkorubaCredentialClient, client => - { - client.TokenEndpoint = new Uri($"{authOptions.Authority}connect/token"); - client.ClientId = ClientId.Parse(authOptions.ClientId!); - client.ClientSecret = ClientSecret.Parse(authOptions.ClientSecret!); - client.Scope = Duende.AccessTokenManagement.Scope.ParseOrDefault(authOptions.Scope); - }); - - services.AddHttpClient(SkorubaHttpClient, client => - { - client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!); - }).AddClientCredentialsTokenHandler(ClientCredentialsClientName.Parse(SkorubaCredentialClient)); + services.AddTransient(); + + services.AddHttpClient(SkorubaHttpClient, client => client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!)) + .AddHttpMessageHandler(); services.AddScoped(); services.AddScoped(); diff --git a/PostFundManagement.Application/Filters/ActiveUserFilter.cs b/PostFundManagement.Application/Filters/ActiveUserFilter.cs index dba5679..19c3e0c 100644 --- a/PostFundManagement.Application/Filters/ActiveUserFilter.cs +++ b/PostFundManagement.Application/Filters/ActiveUserFilter.cs @@ -1,6 +1,4 @@ using PostFundManagement.Application.Abstractions.Services; -using static PostFundManagement.Application.Extensions.General; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Filters; diff --git a/PostFundManagement.Application/Filters/UserRoleFilter.cs b/PostFundManagement.Application/Filters/UserRoleFilter.cs index ca54e14..55b0c99 100644 --- a/PostFundManagement.Application/Filters/UserRoleFilter.cs +++ b/PostFundManagement.Application/Filters/UserRoleFilter.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Filters; diff --git a/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs b/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs new file mode 100644 index 0000000..b2ad9c0 --- /dev/null +++ b/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs @@ -0,0 +1,115 @@ +using IdentityModel.Client; +using PostFundManagement.Domain.Configuration.Security; + +namespace PostFundManagement.Application.Handlers; + +public class ClientCredentialsTokenHandler(ILogger logger, + IOptions options) : DelegatingHandler +{ + private readonly MachineIdentitySettings _settings = options.Value; + private string? _cachedToken; + private DateTime _tokenExpiry = DateTime.MinValue; + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + try + { + var token = await GetAccessTokenAsync(cancellationToken); + + if (string.IsNullOrWhiteSpace(token)) + { + logger.LogError("Failed to acquire access token for Skoruba API"); + + throw new InvalidOperationException("Unable to acquire access token"); + } + + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + logger.LogDebug("ClientCredentialsTokenHandler: Added bearer token to request"); + } + catch (Exception ex) + { + logger.LogError(ex, "Error acquiring client credentials token"); + + throw; + } + + try + { + var response = await base.SendAsync(request, cancellationToken); + + if (!response.IsSuccessStatusCode) + { + logger.LogWarning("HTTP request failed with status {StatusCode} for {Method} {RequestUri}", + response.StatusCode, request.Method, request.RequestUri); + } + + return response; + } + catch (Exception ex) + { + logger.LogError(ex, "Error sending HTTP request with client credentials token"); + + throw; + } + } + + private async Task GetAccessTokenAsync(CancellationToken cancellationToken) + { + if (!string.IsNullOrWhiteSpace(_cachedToken) && DateTime.UtcNow < _tokenExpiry) + { + logger.LogDebug("Using cached access token"); + + return _cachedToken; + } + + logger.LogDebug("Acquiring new access token from {Authority}", _settings.Authority); + + using var tokenClient = new HttpClient(); + + try + { + if (!_settings.Authority!.EndsWith('/')) _settings.Authority += "/"; + + var scope = _settings.Scope; + + var tokenRequest = new ClientCredentialsTokenRequest + { + Address = $"{_settings.Authority}connect/token", + ClientId = _settings.ClientId!, + ClientSecret = _settings.ClientSecret, + GrantType = "client_credentials", + Scope = scope, + }; + + logger.LogDebug("Sending token request to {TokenEndpoint} for client {ClientId} with scope {Scope}", + tokenRequest.Address, tokenRequest.ClientId, tokenRequest.Scope); + + var response = await tokenClient.RequestClientCredentialsTokenAsync(tokenRequest, cancellationToken); + + if (response.IsError) + { + logger.LogError("Token request error: {Error} - {ErrorDescription}. Full response: {Raw}", + response.Error, response.ErrorDescription, response.Raw); + + return null; + } + + _cachedToken = response.AccessToken; + + var expiresIn = response.ExpiresIn > 0 ? response.ExpiresIn : 3600; + + _tokenExpiry = DateTime.UtcNow.AddSeconds(expiresIn * 0.9); + + logger.LogDebug("Successfully acquired access token, expires at {Expiry}", _tokenExpiry); + + return _cachedToken; + } + catch (Exception ex) + { + logger.LogError(ex, "Exception occurred while acquiring client credentials token"); + + throw; + } + } +} diff --git a/PostFundManagement.Application/PostFundManagement.Application.csproj b/PostFundManagement.Application/PostFundManagement.Application.csproj index 44bdc83..96108ea 100644 --- a/PostFundManagement.Application/PostFundManagement.Application.csproj +++ b/PostFundManagement.Application/PostFundManagement.Application.csproj @@ -36,6 +36,12 @@ + + + + + + diff --git a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs index ced8a19..8a185a4 100644 --- a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs +++ b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Communications; @@ -13,6 +12,28 @@ public sealed class CommunicationsCacheService(CommunicationsService service, ID public async Task CreateNotificationAsync(CreateNotificationRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateNotificationAsync(request, userId, cancellationToken); + public async Task> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetApplicantDataAsync(applicantUserId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getapplicantdata-{applicantUserId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var result = await service.GetApplicantDataAsync(applicantUserId, cancellationToken); + + if (result.IsFailed) return result; + + await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); + } + + return Result.Ok(cached!.FromJson()); + })); + public async Task> GetApplicantInviteAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { diff --git a/PostFundManagement.Application/Services/Communications/CommunicationsService.cs b/PostFundManagement.Application/Services/Communications/CommunicationsService.cs index 7151876..90958d2 100644 --- a/PostFundManagement.Application/Services/Communications/CommunicationsService.cs +++ b/PostFundManagement.Application/Services/Communications/CommunicationsService.cs @@ -9,7 +9,7 @@ using PostFundManagement.Infrastructure.Database; namespace PostFundManagement.Application.Services.Communications; -public sealed class CommunicationsService(IDbContextFactory contextFactory, +public sealed class CommunicationsService(IDbContextFactory contextFactory, HashService hashService, ITenantContextService tenantContext) : ICommunicationsService { public async Task> SendInviteAsync(InviteRequest request, Guid userId, CancellationToken cancellationToken = default) => @@ -39,12 +39,12 @@ public sealed class CommunicationsService(IDbContextFactory 0, + return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create entry, contact support")); })); @@ -164,4 +164,59 @@ public sealed class CommunicationsService(IDbContextFactory> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var invites = await context.Invites.AsNoTracking() + .Where(i => i.Recipient == applicantUserId) + .OrderByDescending(o => o.Id) + .ToListAsync(cancellationToken); + + var applicantData = new List(); + + foreach (var invite in invites) + { + var outputInvite = invite.Map(); + + var contract = (await context.Contracts.AsNoTracking() + .FirstOrDefaultAsync(c => c.Id == invite.ContractId, cancellationToken))?.Map(); + + var fundingOrganisation = (await context.Organisations.AsNoTracking() + .FirstOrDefaultAsync(o => o.Id == invite.OrganisationId, cancellationToken))?.Map(); + + var invitedOrganisation = (await context.Organisations.AsNoTracking() + .FirstOrDefaultAsync(o => o.Id == invite.InvitedOrganisationId, cancellationToken))?.Map(); + + var awards = (await context.Awards.AsNoTracking() + .Where(a => a.Id == invite.AwardId) + .ToListAsync(cancellationToken))?.Select(a => a.Map()).ToArray(); + + var projectIds = (await context.Awards.AsNoTracking() + .Where(a => a.Id == invite.AwardId && a.ProjectId.HasValue) + .Select(a => a.ProjectId!.Value) + .Distinct() + .ToListAsync(cancellationToken)) ?? []; + + var projects = (await context.Projects.AsNoTracking() + .Where(p => projectIds.Contains(p.Id)) + .ToListAsync(cancellationToken))?.Select(p => p.Map()).ToArray() ?? []; + + var data = new ApplicantData + { + Invite = outputInvite, + Contract = contract, + Awards = awards!, + FundingOrganisation = fundingOrganisation, + InvitedOrganisation = invitedOrganisation, + Projects = projects + }; + + applicantData.Add(data); + } + + return Result.Ok(applicantData.ToArray()); + })); } diff --git a/PostFundManagement.Application/Services/Communications/Records.cs b/PostFundManagement.Application/Services/Communications/Records.cs index 706df2f..93e340c 100644 --- a/PostFundManagement.Application/Services/Communications/Records.cs +++ b/PostFundManagement.Application/Services/Communications/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Communications; diff --git a/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs b/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs index 91f386d..3be2893 100644 --- a/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs +++ b/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Evidence; diff --git a/PostFundManagement.Application/Services/Evidence/Records.cs b/PostFundManagement.Application/Services/Evidence/Records.cs index 7bfc003..c03a29f 100644 --- a/PostFundManagement.Application/Services/Evidence/Records.cs +++ b/PostFundManagement.Application/Services/Evidence/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Evidence; diff --git a/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs b/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs index 032afef..c229cd4 100644 --- a/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs +++ b/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Execution; diff --git a/PostFundManagement.Application/Services/Execution/Records.cs b/PostFundManagement.Application/Services/Execution/Records.cs index 81b466e..1f17eaa 100644 --- a/PostFundManagement.Application/Services/Execution/Records.cs +++ b/PostFundManagement.Application/Services/Execution/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Execution; diff --git a/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs b/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs index 030fcc7..8deb7fd 100644 --- a/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs +++ b/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Governance; diff --git a/PostFundManagement.Application/Services/Governance/Records.cs b/PostFundManagement.Application/Services/Governance/Records.cs index d37e3e1..a8f3d7c 100644 --- a/PostFundManagement.Application/Services/Governance/Records.cs +++ b/PostFundManagement.Application/Services/Governance/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Governance; diff --git a/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs b/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs index e8c3bb1..ef14bed 100644 --- a/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs +++ b/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Grants; diff --git a/PostFundManagement.Application/Services/Grants/Records.cs b/PostFundManagement.Application/Services/Grants/Records.cs index c8f5ebe..fbe18c5 100644 --- a/PostFundManagement.Application/Services/Grants/Records.cs +++ b/PostFundManagement.Application/Services/Grants/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Grants; diff --git a/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs b/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs index 392f91b..9f7adbf 100644 --- a/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs +++ b/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Projects; diff --git a/PostFundManagement.Application/Services/Projects/Records.cs b/PostFundManagement.Application/Services/Projects/Records.cs index 17fba04..87cf9ed 100644 --- a/PostFundManagement.Application/Services/Projects/Records.cs +++ b/PostFundManagement.Application/Services/Projects/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Projects; diff --git a/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs b/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs index 7aede7c..1b24434 100644 --- a/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs +++ b/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Shared; diff --git a/PostFundManagement.Application/Services/Users/UserCacheService.cs b/PostFundManagement.Application/Services/Users/UserCacheService.cs index 9c25c7b..cee62f5 100644 --- a/PostFundManagement.Application/Services/Users/UserCacheService.cs +++ b/PostFundManagement.Application/Services/Users/UserCacheService.cs @@ -3,13 +3,79 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; +using PostFundManagement.Domain.Models.Security; +using Claim = PostFundManagement.Domain.Models.Security.Claim; namespace PostFundManagement.Application.Services.Users; -public sealed class UserCacheService(UserService service, IDistributedCache cache, +public sealed class UserCacheService(UserService service, IDistributedCache cache, IFeatureManager featureManager) : ServiceCacheBase, IUserService { + public async Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default) => + await service.AddUserClaimAsync(request, userId, cancellationToken); + + public async Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await service.AddUserRoleAsync(targetUserId, roleId, userId, cancellationToken); + + public async Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => + await service.CreateUserAsync(tenantIdHash, idNumberHash, request, userId, cancellationToken); + + public async Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await service.DeleteUserClaimAsync(claimIdHash, targetUserId, userId, cancellationToken); + + public async Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await service.DeleteUserRoleAsync(targetUserId, roleId, userId, cancellationToken); + + public async Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetRoleClaimsAsync(roleId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getsystemroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var claimResult = await service.GetRoleClaimsAsync(roleId, userId, cancellationToken); + + if (claimResult.IsFailed) return claimResult; + + await cache.SetStringAsync(cacheKey, claimResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return claimResult; + } + + return Result.Ok(cached.FromJson()); + })); + + public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetSystemRolesAsync(userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getsystemroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var rolesResult = await service.GetSystemRolesAsync(userId, cancellationToken); + + if (rolesResult.IsFailed) return rolesResult; + + await cache.SetStringAsync(cacheKey, rolesResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return rolesResult; + } + + return Result.Ok(cached.FromJson()); + })); + public async Task> GetUserAsync(Guid userId, CancellationToken cancellationToken) => await Result.Try((Func>>)(async () => { @@ -20,7 +86,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach var cached = await cache.GetStringAsync(cacheKey, cancellationToken); - if(string.IsNullOrWhiteSpace(cached)) + if (string.IsNullOrWhiteSpace(cached)) { var userResult = await service.GetUserAsync(userId, cancellationToken); @@ -34,6 +100,56 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach return Result.Ok(cached.FromJson()); })); + public async Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetUserClaimsAsync(targetUserId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getuserclaims-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var claimsResult = await service.GetUserClaimsAsync(targetUserId, userId, cancellationToken); + + if (claimsResult.IsFailed) return claimsResult; + + await cache.SetStringAsync(cacheKey, claimsResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return claimsResult; + } + + return Result.Ok(cached.FromJson()); + })); + + public async Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetUserRolesAsync(targetUserId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getuserroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var rolesResult = await service.GetUserRolesAsync(targetUserId, userId, cancellationToken); + + if (rolesResult.IsFailed) return rolesResult; + + await cache.SetStringAsync(cacheKey, rolesResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return rolesResult; + } + + return Result.Ok(cached.FromJson()); + })); + public async Task> GetUsersAsync(Pagination pagination, UserFilterRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { @@ -51,7 +167,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach if (usersResult.IsFailed) return usersResult; - await cache.SetStringAsync(cacheKey, usersResult.Value.ToJson(), + await cache.SetStringAsync(cacheKey, usersResult.Value.ToJson(), cacheOptions, cancellationToken); return usersResult; @@ -60,9 +176,15 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach return Result.Ok(cached.FromJson()); })); + public async Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await service.LogoutUserAsync(targetUserId, userId, cancellationToken); + + public async Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default) => + await service.SetUserLockoutAsync(targetUserId, userId, disable, cancellationToken); + public async Task SyncUserAsync(Guid userId, string email, string role, CancellationToken cancellationToken = default) => await service.SyncUserAsync(userId, email, role, cancellationToken); - + public async Task UpdateUserStatusAsync(Guid userId, ActivityStatus status, CancellationToken cancellationToken = default) => await service.UpdateUserStatusAsync(userId, status, cancellationToken); } diff --git a/PostFundManagement.Application/Services/Users/UserService.cs b/PostFundManagement.Application/Services/Users/UserService.cs index 755ddc6..5c25bcf 100644 --- a/PostFundManagement.Application/Services/Users/UserService.cs +++ b/PostFundManagement.Application/Services/Users/UserService.cs @@ -1,14 +1,18 @@ using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; +using PostFundManagement.Domain.Models.Security; using PostFundManagement.Infrastructure.Database; +using Claim = PostFundManagement.Domain.Models.Security.Claim; namespace PostFundManagement.Application.Services.Users; -public sealed class UserService(IDbContextFactory contextFactory, ITenantContextService tenantContext) : IUserService +public sealed class UserService(IDbContextFactory contextFactory, ITenantContextService tenantContext, + ISkorubaUserService skorubaService, HashService hashService) : IUserService { public async Task SyncUserAsync(Guid userId, string email, string role, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => @@ -113,4 +117,212 @@ public sealed class UserService(IDbContextFactory contextF return Result.FailIf(tenantUser == null, NotFoundError.Create("User not found.")) .ToResult(tenantUser!.User?.Map()!); })); + + public async Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var tenantIdHashDecode = hashService.DecodeLongIdHash(tenantIdHash); + + if (tenantIdHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(tenantIdHashDecode.Errors)); + + var tenantId = tenantIdHashDecode.Value; + + var idNumberHashDecode = await hashService.DecodeHexHash(idNumberHash); + + if (idNumberHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(idNumberHashDecode.Errors)); + + var idNumber = idNumberHashDecode.Value.Trim(); + + var email = request.Email?.Trim().ToLowerInvariant(); + + if (string.IsNullOrWhiteSpace(email)) + return Result.Fail(ValidationError.Create("Email is required.")); + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + if (await context.Users.AnyAsync(u => u.Email == email, cancellationToken)) + return Result.Fail(ValidationError.Create("User with this email already exists.")); + + var createUserResult = await skorubaService.CreateUserAsync(request, cancellationToken); + + if (createUserResult.IsFailed) + return Result.Fail(CreateError.Create("Failed to create user.")); + + var newUserId = Guid.Parse(createUserResult.Value.Trim()); + + var availableRolesResult = await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken); + + if (availableRolesResult.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve available roles.")); + + var defaultRole = availableRolesResult.Value.FirstOrDefault(r => r.Name == "Contributor"); + + if (defaultRole == null) + return Result.Fail(NotFoundError.Create("Role 'Contributor' not found.")); + + var roleAssignmentResult = await skorubaService.AddRoleAsync(newUserId, Guid.Parse(defaultRole.Id), cancellationToken); + + if (roleAssignmentResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to assign role to user.")); + + var newUser = context.Users.Add(new Domain.Entities.User + { + Id = newUserId, + Email = email, + Status = ActivityStatus.Active, + LastLoginAt = DateTime.UtcNow, + IdNumber = idNumber, + Role = defaultRole.Name, + }); + + context.TenantUsers.Add(new Domain.Entities.TenantUser + { + CreatedAt = DateTime.UtcNow, + CreatedBy = userId, + Status = ActivityStatus.Active, + TenantId = tenantId, + UserId = newUserId, + }); + + return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create user, contact support")); + })); + + public async Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var claimIdHashDecode = hashService.DecodeIntIdHash(claimIdHash); + + if (claimIdHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(claimIdHashDecode.Errors)); + + var claimId = claimIdHashDecode.Value; + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + if (!await context.Users.AnyAsync(u => u.Id == targetUserId, cancellationToken)) + return Result.Fail(NotFoundError.Create("User not found.")); + + var claimDeleteResult = await skorubaService.RemoveClaimAsync(targetUserId, claimId, cancellationToken); + + return Result.OkIf(claimDeleteResult.IsSuccess, ValidationError.Create("Failed to delete user claim.") + .CausedBy(claimDeleteResult.Errors)); + })); + + public async Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var lockoutResult = await skorubaService.SetUserLockoutAsync(targetUserId, disable, cancellationToken); + + if(lockoutResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to set user lockout.") + .CausedBy(lockoutResult.Errors)); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, disable ? ActivityStatus.Disabled : ActivityStatus.Active), cancellationToken); + + changedTotal += await context.TenantUsers.Where(f => f.UserId == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, disable ? ActivityStatus.Disabled : ActivityStatus.Active), cancellationToken); + + return Result.OkIf(lockoutResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to set user lockout.") + .CausedBy(lockoutResult.Errors)); + })); + + public async Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var logoutResult = await skorubaService.InvalidateUserSessionAsync(targetUserId, cancellationToken); + + return Result.OkIf(logoutResult.IsSuccess, ValidationError.Create("Failed to logout user.") + .CausedBy(logoutResult.Errors)); + })); + + public async Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetUserRolesAsync(targetUserId, cancellationToken: cancellationToken))); + + public async Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetUserClaimsAsync(targetUserId, cancellationToken: cancellationToken))); + + public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken))); + + public async Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Role, string.Empty), cancellationToken); + + var roleDeleteResult = await skorubaService.RemoveRoleAsync(targetUserId, roleId, cancellationToken); + + return Result.OkIf(roleDeleteResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to delete user role.") + .CausedBy(roleDeleteResult.Errors)); + })); + + public async Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var addClaimResult = await skorubaService.AddClaimAsync(request.UserId, request.ClaimType, request.ClaimValue, cancellationToken); + + return Result.OkIf(addClaimResult.IsSuccess, ValidationError.Create("Failed to add user claim.") + .CausedBy(addClaimResult.Errors)); + })); + + public async Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var userRolesResult = await skorubaService.GetUserRolesAsync(targetUserId, cancellationToken: cancellationToken); + + if (userRolesResult.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve user roles.") + .CausedBy(userRolesResult.Errors)); + + foreach (var role in userRolesResult.Value) + { + var deleteRoleResult = await skorubaService.RemoveRoleAsync(targetUserId, Guid.Parse(role.Id), cancellationToken); + + if (deleteRoleResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to remove existing user role.") + .CausedBy(deleteRoleResult.Errors)); + } + + var roleAddResult = await skorubaService.AddRoleAsync(targetUserId, roleId, cancellationToken); + + if(roleAddResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to add user role.") + .CausedBy(roleAddResult.Errors)); + + var systemRoles = await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken); + + if (systemRoles.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve system roles.") + .CausedBy(systemRoles.Errors)); + + var targetRole = systemRoles.Value.FirstOrDefault(r => r.Id == roleId.ToString()); + + if (targetRole == null) + return Result.Fail(NotFoundError.Create("Role not found.")); + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Role, targetRole.Name), cancellationToken); + + return Result.OkIf(roleAddResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to add user role.") + .CausedBy(roleAddResult.Errors)); + })); + + public async Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetRoleClaimsAsync(roleId, cancellationToken))); } diff --git a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs index 8cf3968..f0f9faf 100644 --- a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs +++ b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs @@ -9,6 +9,10 @@ public interface ISkorubaUserService [Audit] Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default); + [Log] + [Audit] + Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken = default); + [Log] Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default); @@ -30,18 +34,24 @@ public interface ISkorubaUserService [Log] [Audit] - Task AddRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default); + Task AddRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default); [Log] [Audit] - Task RemoveRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default); + Task RemoveRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default); [Log] Task> GetAvailableRolesAsync(string? searchText = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); [Log] - Task> GetUserRolesAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + Task> GetUserRolesAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); [Log] - Task> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + + [Log] + Task> GetRoleClaimsAsync(Guid roleId, CancellationToken cancellationToken = default); + + [Log] + Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs b/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs index a917b66..f705aa0 100644 --- a/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs +++ b/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs @@ -9,4 +9,4 @@ public sealed class MachineIdentitySettings public string? ClientId { get; set; } public string? ClientSecret { get; set; } -} \ No newline at end of file +} diff --git a/PostFundManagement.Domain/Entities/Activity.cs b/PostFundManagement.Domain/Entities/Activity.cs index b2c059f..a6fe592 100644 --- a/PostFundManagement.Domain/Entities/Activity.cs +++ b/PostFundManagement.Domain/Entities/Activity.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/AuditLog.cs b/PostFundManagement.Domain/Entities/AuditLog.cs index cb70df6..4febf16 100644 --- a/PostFundManagement.Domain/Entities/AuditLog.cs +++ b/PostFundManagement.Domain/Entities/AuditLog.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Entities/Beneficiary.cs b/PostFundManagement.Domain/Entities/Beneficiary.cs index e9e2d0f..9737fd4 100644 --- a/PostFundManagement.Domain/Entities/Beneficiary.cs +++ b/PostFundManagement.Domain/Entities/Beneficiary.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Budget.cs b/PostFundManagement.Domain/Entities/Budget.cs index 7123756..099946d 100644 --- a/PostFundManagement.Domain/Entities/Budget.cs +++ b/PostFundManagement.Domain/Entities/Budget.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/ChangeRequest.cs b/PostFundManagement.Domain/Entities/ChangeRequest.cs index a95c84a..c885093 100644 --- a/PostFundManagement.Domain/Entities/ChangeRequest.cs +++ b/PostFundManagement.Domain/Entities/ChangeRequest.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/ComplianceItem.cs b/PostFundManagement.Domain/Entities/ComplianceItem.cs index e67faa2..9660313 100644 --- a/PostFundManagement.Domain/Entities/ComplianceItem.cs +++ b/PostFundManagement.Domain/Entities/ComplianceItem.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Indicator.cs b/PostFundManagement.Domain/Entities/Indicator.cs index 1215875..b31d03e 100644 --- a/PostFundManagement.Domain/Entities/Indicator.cs +++ b/PostFundManagement.Domain/Entities/Indicator.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Instrument.cs b/PostFundManagement.Domain/Entities/Instrument.cs index 85453ed..6adf209 100644 --- a/PostFundManagement.Domain/Entities/Instrument.cs +++ b/PostFundManagement.Domain/Entities/Instrument.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Issue.cs b/PostFundManagement.Domain/Entities/Issue.cs index 47c132a..48be6f9 100644 --- a/PostFundManagement.Domain/Entities/Issue.cs +++ b/PostFundManagement.Domain/Entities/Issue.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Milestone.cs b/PostFundManagement.Domain/Entities/Milestone.cs index 85a9581..142a00b 100644 --- a/PostFundManagement.Domain/Entities/Milestone.cs +++ b/PostFundManagement.Domain/Entities/Milestone.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Notification.cs b/PostFundManagement.Domain/Entities/Notification.cs index 1da94a1..7ce906b 100644 --- a/PostFundManagement.Domain/Entities/Notification.cs +++ b/PostFundManagement.Domain/Entities/Notification.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Organisation.cs b/PostFundManagement.Domain/Entities/Organisation.cs index fce062b..8d0df3a 100644 --- a/PostFundManagement.Domain/Entities/Organisation.cs +++ b/PostFundManagement.Domain/Entities/Organisation.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Entities/Outcome.cs b/PostFundManagement.Domain/Entities/Outcome.cs index fbd8358..8991a8a 100644 --- a/PostFundManagement.Domain/Entities/Outcome.cs +++ b/PostFundManagement.Domain/Entities/Outcome.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Portfolio.cs b/PostFundManagement.Domain/Entities/Portfolio.cs index 76643b2..34cee15 100644 --- a/PostFundManagement.Domain/Entities/Portfolio.cs +++ b/PostFundManagement.Domain/Entities/Portfolio.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Programme.cs b/PostFundManagement.Domain/Entities/Programme.cs index 7f5f25f..2388bc8 100644 --- a/PostFundManagement.Domain/Entities/Programme.cs +++ b/PostFundManagement.Domain/Entities/Programme.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Project.cs b/PostFundManagement.Domain/Entities/Project.cs index fb4612f..1a5c962 100644 --- a/PostFundManagement.Domain/Entities/Project.cs +++ b/PostFundManagement.Domain/Entities/Project.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Risk.cs b/PostFundManagement.Domain/Entities/Risk.cs index 0591cc6..7c94d1f 100644 --- a/PostFundManagement.Domain/Entities/Risk.cs +++ b/PostFundManagement.Domain/Entities/Risk.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Rule.cs b/PostFundManagement.Domain/Entities/Rule.cs index e4ae1b4..c4688eb 100644 --- a/PostFundManagement.Domain/Entities/Rule.cs +++ b/PostFundManagement.Domain/Entities/Rule.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/SiteVisit.cs b/PostFundManagement.Domain/Entities/SiteVisit.cs index eee8e43..ad2b6ed 100644 --- a/PostFundManagement.Domain/Entities/SiteVisit.cs +++ b/PostFundManagement.Domain/Entities/SiteVisit.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Tenant.cs b/PostFundManagement.Domain/Entities/Tenant.cs index 6bab5aa..58582dc 100644 --- a/PostFundManagement.Domain/Entities/Tenant.cs +++ b/PostFundManagement.Domain/Entities/Tenant.cs @@ -1,6 +1,4 @@ -using static PostFundManagement.Domain.Extensions.Constants; - -namespace PostFundManagement.Domain.Entities; +namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] public class Tenant : Models.Tenant diff --git a/PostFundManagement.Domain/Entities/User.cs b/PostFundManagement.Domain/Entities/User.cs index 270427f..00be259 100644 --- a/PostFundManagement.Domain/Entities/User.cs +++ b/PostFundManagement.Domain/Entities/User.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Enums.cs b/PostFundManagement.Domain/Enums.cs index 7482db7..bb75ca1 100644 --- a/PostFundManagement.Domain/Enums.cs +++ b/PostFundManagement.Domain/Enums.cs @@ -9,7 +9,7 @@ public enum EmailStatuses : int Disconnected = 4, TooManyConnections = 5, ConnectionAborted = 6, - Success = 7 + Success = 7, } public enum NotificationStatus : int @@ -22,7 +22,7 @@ public enum NotificationStatus : int Read = 6, Failed = 7, Cancelled = 8, - Bounced = 9 + Bounced = 9, } public enum NotificationPlatform : int @@ -35,7 +35,7 @@ public enum NotificationPlatform : int Teams = 6, Slack = 7, Webhook = 8, - Other = 99 + Other = 99, } public enum EvidenceType : int @@ -51,7 +51,7 @@ public enum EvidenceType : int ProcurementDocument = 9, TechnicalSpecificationOrDesign = 10, VideoRecording = 11, - Other = 99 + Other = 99, } public enum ProjectType : int @@ -66,7 +66,7 @@ public enum ProjectType : int SocialImpactAndCommunityDevelopment = 8, TechnologyTransferAndAdoption = 9, Innovation = 10, - Other = 99 + Other = 99, } public enum IndustrySector : int @@ -88,7 +88,7 @@ public enum IndustrySector : int RetailAndConsumerGoods = 15, TourismAndHospitality = 16, WaterAndSanitation = 17, - Other = 99 + Other = 99, } public enum OrganisationType : int @@ -132,7 +132,7 @@ public enum OrganisationType : int // Consortium & Special Vehicles Consortium = 26, // Unincorporated joint venture - SpecialPurposeVehicle = 27 // SPV / Joint Venture Entity + SpecialPurposeVehicle = 27, // SPV / Joint Venture Entity } public enum Priority : int @@ -140,7 +140,7 @@ public enum Priority : int Low = 1, Medium = 2, High = 3, - Critical = 4 + Critical = 4, } public enum UnitOfMeasure : int @@ -153,7 +153,7 @@ public enum UnitOfMeasure : int Volume = 6, DurationDays = 7, DurationMonths = 8, - Ratio = 9 + Ratio = 9, } public enum ContractStatus : int { @@ -162,7 +162,7 @@ public enum ContractStatus : int Active = 3, Expired = 4, Terminated = 5, - Amended = 6 + Amended = 6, } public enum RiskLikelihood : int @@ -171,7 +171,7 @@ public enum RiskLikelihood : int Unlikely = 2, Possible = 3, Likely = 4, - AlmostCertain = 5 + AlmostCertain = 5, } public enum RiskImpact : int @@ -180,7 +180,7 @@ public enum RiskImpact : int Minor = 2, Moderate = 3, Major = 4, - Critical = 5 + Critical = 5, } public enum ApprovalStatus : int @@ -189,12 +189,12 @@ public enum ApprovalStatus : int Review = 2, Approved = 3, Rejected = 4, - Removed = 5 + Removed = 5, } public enum ActivityStatus : int { Active = 1, Inactive = 2, - Disabled = 3 + Disabled = 3, } \ No newline at end of file diff --git a/PostFundManagement.Domain/Health/PostgresHealthCheck.cs b/PostFundManagement.Domain/Health/PostgresHealthCheck.cs index 39b58ce..003572f 100644 --- a/PostFundManagement.Domain/Health/PostgresHealthCheck.cs +++ b/PostFundManagement.Domain/Health/PostgresHealthCheck.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Health; public sealed class PostgresHealthCheck(IConfiguration configuration) : IHealthCheck diff --git a/PostFundManagement.Domain/Health/QuartzHealthCheck.cs b/PostFundManagement.Domain/Health/QuartzHealthCheck.cs index e66b880..78090a4 100644 --- a/PostFundManagement.Domain/Health/QuartzHealthCheck.cs +++ b/PostFundManagement.Domain/Health/QuartzHealthCheck.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Health; public sealed class QuartzHealthCheck(ISchedulerFactory schedulerFactory) : IHealthCheck diff --git a/PostFundManagement.Domain/Models/ApplicantData.cs b/PostFundManagement.Domain/Models/ApplicantData.cs new file mode 100644 index 0000000..3033888 --- /dev/null +++ b/PostFundManagement.Domain/Models/ApplicantData.cs @@ -0,0 +1,16 @@ +namespace PostFundManagement.Domain.Models; + +public sealed class ApplicantData +{ + public Invite? Invite { get; set; } + + public Contract? Contract { get; set; } + + public Organisation? FundingOrganisation { get; set; } + + public Organisation? InvitedOrganisation { get; set; } + + public Award[] Awards { get; set; } = []; + + public Project[] Projects { get; set; } = []; +} diff --git a/PostFundManagement.Domain/Models/Security/Contracts.cs b/PostFundManagement.Domain/Models/Security/Contracts.cs index bfbf504..86ea49e 100644 --- a/PostFundManagement.Domain/Models/Security/Contracts.cs +++ b/PostFundManagement.Domain/Models/Security/Contracts.cs @@ -1,15 +1,55 @@ -namespace PostFundManagement.Domain.Models.Security; +using System.ComponentModel.DataAnnotations; -public sealed record CreateUserRequest(string UserName, string Email, string Password, bool EmailConfirmed = true, string? PhoneNumber = null, bool PhoneNumberConfirmed = false); +namespace PostFundManagement.Domain.Models.Security; -public sealed record UpdateUserRequest(string Id, string UserName, string Email, bool EmailConfirmed, string? PhoneNumber, bool PhoneNumberConfirmed, bool LockoutEnabled, DateTimeOffset? LockoutEnd, int AccessFailedCount, bool TwoFactorEnabled); +public abstract class SkorubaUser +{ + [JsonPropertyName("id")] + public string? UserId { get; set; } + + [JsonPropertyName("userName")] + public string? UserName { get; set; } + + [JsonPropertyName("email")] + public string? Email { get; set; } + + [JsonPropertyName("emailConfirmed")] + public bool EmailConfirmed { get; set; } + + [JsonPropertyName("phoneNumber")] + public string? PhoneNumber { get; set; } + + [JsonPropertyName("phoneNumberConfirmed")] + public bool PhoneNumberConfirmed { get; set; } + + [JsonPropertyName("LockoutEnabled")] + public bool LockoutEnabled { get; set; } + + [JsonPropertyName("twoFactorEnabled")] + public bool TwoFactorEnabled { get; set; } + + [JsonPropertyName("accessFailedCount")] + public int AccessFailedCount { get; set; } + + [JsonPropertyName("lockoutEnd")] + public DateTimeOffset? LockoutEnd { get; set; } +} + +public sealed class UserLockOutRequest : SkorubaUser; +public sealed class CreateUserRequest : SkorubaUser; +public sealed class UpdateUserRequest : SkorubaUser; + +public sealed record AddUserClaimRequest([Required] Guid UserId, + [Required] int ClaimId, + [Required][MaxLength(LabelLength)] string ClaimType, + [Required][MaxLength(LabelLength)] string ClaimValue); public sealed record Claim(string ClaimType, string ClaimValue, int? ClaimId = null); -public record ClaimsResponse(int TotalCount, int PageSize, ICollection Claims); +public sealed record ClaimsResponse(int TotalCount, int PageSize, ICollection Claims); public sealed record UserResponse(string Id, string UserName, string Email, bool IsLockedOut, bool LockoutEnabled); -public record Role(string Id, string Name); +public sealed record Role(string Id, string Name); -public record RolesResponse(int TotalCount, int PageSize, ICollection Roles); \ No newline at end of file +public sealed record RolesResponse(int TotalCount, int PageSize, ICollection Roles); \ No newline at end of file diff --git a/PostFundManagement.Domain/PostFundManagement.Domain.csproj b/PostFundManagement.Domain/PostFundManagement.Domain.csproj index e1690af..80faa44 100644 --- a/PostFundManagement.Domain/PostFundManagement.Domain.csproj +++ b/PostFundManagement.Domain/PostFundManagement.Domain.csproj @@ -25,205 +25,210 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - + + + - - + + - - - - - - + + + + + + - - + + - - - - + + + + - - - - + + + + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + - - - + + + - - - - - - - + + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - - - - - + + + + + + + - - - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs b/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs index 6046775..eae18cf 100644 --- a/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs +++ b/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Infrastructure.Database.Factories; public sealed partial class ApplicationDbContextFactory : IDesignTimeDbContextFactory diff --git a/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs b/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs index b54ff53..8ea22a5 100644 --- a/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs +++ b/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Infrastructure.Database.Factories; public sealed class DataProtectionDbContextFactory : IDesignTimeDbContextFactory diff --git a/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj b/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj index 4d741b3..6451b3a 100644 --- a/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj +++ b/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj @@ -34,6 +34,11 @@ + + + + + diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index 8389656..366477f 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -1,20 +1,19 @@ 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 class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkorubaUserService { public async Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.PostAsJsonAsync("api/users", request, cancellationToken); if (!response.IsSuccessStatusCode) - return Result.Fail(CreateError.Create("Failed to create user.")); + return Result.Fail(CreateError.Create(response.ReasonPhrase!)); var created = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken); @@ -25,7 +24,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var result = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); return Result.FailIf(result is null, NotFoundError.Create($"User {userId} not found.")) @@ -35,7 +34,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task UpdateUserAsync(UpdateUserRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.PutAsJsonAsync("api/users", request, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, UpdateError.Create("Failed to update user.")); @@ -44,15 +43,23 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task SetUserLockoutAsync(Guid userId, bool disabled, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var user = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); if (user is null) return Result.Fail(NotFoundError.Create($"User {userId} not found.")); - var updated = user with + var updated = new UserLockOutRequest { + UserId = userId.ToString(), + UserName = user.UserName, + Email = user.Email, + EmailConfirmed = user.EmailConfirmed, + PhoneNumber = user.PhoneNumber, + PhoneNumberConfirmed = user.PhoneNumberConfirmed, LockoutEnabled = true, + TwoFactorEnabled = user.TwoFactorEnabled, + AccessFailedCount = user.AccessFailedCount, LockoutEnd = disabled ? DateTimeOffset.UtcNow.AddYears(100) : null }; @@ -64,10 +71,10 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task AddClaimAsync(Guid userId, string claimType, string claimValue, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); - var payload = new { UserId = userId, ClaimType = claimType, ClaimValue = claimValue }; + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var payload = new { userId = userId, claimType = claimType, claimValue = claimValue }; - var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/claims", payload, cancellationToken); + var response = await httpClient.PostAsJsonAsync($"api/users/claims", payload, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user claim.")); })); @@ -75,16 +82,19 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task RemoveClaimAsync(Guid userId, int claimId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); - var response = await httpClient.DeleteAsync($"api/users/{userId}/claims/{claimId}", cancellationToken); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var response = await httpClient.DeleteAsync($"api/users/{userId}/Claims?claimId={claimId}", cancellationToken); - return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user claim.")); + if(response.StatusCode == System.Net.HttpStatusCode.NotFound) + return Result.Fail(NotFoundError.Create($"Claim {claimId} for user {userId} not found.")); + + return Result.OkIf(response.IsSuccessStatusCode, ValidationError.Create("Failed to remove user claim.")); })); - public async Task> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + public async Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var result = await httpClient.GetFromJsonAsync($"api/users/{userId}/claims?page={page}&pageSize={pageSize}", cancellationToken); @@ -92,41 +102,65 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie .ToResult(result?.Claims.ToArray() ?? []); })); - public async Task AddRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default) => + public async Task AddRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); - var payload = new { UserId = userId, RoleId = roleId }; + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var payload = new { userId = userId, roleId = roleId }; - var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/roles", payload, cancellationToken); + var response = await httpClient.PostAsJsonAsync($"api/users/roles", payload, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user role.")); })); - public async Task RemoveRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default) => + public async Task RemoveRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); - var response = await httpClient.DeleteAsync($"api/users/{userId}/roles/{roleId}", cancellationToken); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + + var request = new HttpRequestMessage(HttpMethod.Delete, "api/Users/Roles") + { + Content = JsonContent.Create(new + { + userId = userId.ToString(), + roleId = roleId.ToString() + }) + }; + + var response = await httpClient.SendAsync(request, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user role.")); })); - public async Task> GetUserRolesAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + public async Task> GetUserRolesAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var result = await httpClient.GetFromJsonAsync($"api/users/{userId}/roles?page={page}&pageSize={pageSize}", cancellationToken); + var result = await httpClient.GetFromJsonAsync($"api/Users/{userId}/Roles?page={page}&pageSize={pageSize}", cancellationToken); return Result.FailIf(result is null, NotFoundError.Create($"Roles for user {userId} could not be retrieved.")) .ToResult(result?.Roles?.ToArray() ?? []); })); + public async Task> GetRoleClaimsAsync(Guid roleId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + + var page = 1; + var pageSize = 100; + + var result = await httpClient.GetFromJsonAsync($"api/roles/{roleId}/claims?page={page}&pageSize={pageSize}", cancellationToken); + + return Result.FailIf(result is null, NotFoundError.Create($"Claims for role {roleId} could not be retrieved.")) + .ToResult(result?.Claims.ToArray() ?? []); + })); + public async Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var user = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); if (user is null) @@ -139,17 +173,28 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetAvailableRolesAsync(string? searchText = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => - { - var httpClient = httpClientFactory.CreateClient(); + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var query = $"api/roles?page={page}&pageSize={pageSize}"; + var query = $"api/roles?page={page}&pageSize={pageSize}"; - if (!string.IsNullOrWhiteSpace(searchText)) - query += $"&searchText={Uri.EscapeDataString(searchText)}"; + if (!string.IsNullOrWhiteSpace(searchText)) + query += $"&searchText={Uri.EscapeDataString(searchText)}"; - var result = await httpClient.GetFromJsonAsync(query, cancellationToken); + var result = await httpClient.GetFromJsonAsync(query, cancellationToken); - return Result.FailIf(result is null, NotFoundError.Create("Available roles could not be retrieved.")) - .ToResult(result?.Roles?.ToArray() ?? []); - })); + return Result.FailIf(result is null, NotFoundError.Create("Available roles could not be retrieved.")) + .ToResult(result?.Roles?.ToArray() ?? []); + })); + + public async Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var result = await httpClient.DeleteAsync($"api/users/{userId}", cancellationToken); + + return result.StatusCode == System.Net.HttpStatusCode.NotFound + ? Result.Fail(NotFoundError.Create($"User {userId} not found.")) + : Result.OkIf(result.IsSuccessStatusCode, UpdateError.Create("Failed to remove user.")); + })); } \ No newline at end of file diff --git a/PostFundManagement.Tests/DebugOnlyFactAttribute.cs b/PostFundManagement.Tests/DebugOnlyFactAttribute.cs new file mode 100644 index 0000000..b32aeb8 --- /dev/null +++ b/PostFundManagement.Tests/DebugOnlyFactAttribute.cs @@ -0,0 +1,12 @@ +namespace PostFundManagement.Tests; + +public class DebugOnlyFactAttribute : FactAttribute +{ + public DebugOnlyFactAttribute() + { + if (!Debugger.IsAttached) + { + Skip = "This test only runs when a debugger is attached."; + } + } +} diff --git a/PostFundManagement.Tests/PostFundManagement.Tests.csproj b/PostFundManagement.Tests/PostFundManagement.Tests.csproj new file mode 100644 index 0000000..7e7e4ae --- /dev/null +++ b/PostFundManagement.Tests/PostFundManagement.Tests.csproj @@ -0,0 +1,40 @@ + + + + net10.0 + enable + enable + false + 079fcde1-9b10-4402-9624-5f0827b4dbfd + + + + + PreserveNewest + true + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs new file mode 100644 index 0000000..e6dea26 --- /dev/null +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -0,0 +1,227 @@ +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Models.Security; +using PostFundManagement.Infrastructure.Database.Services; +using static PostFundManagement.Domain.Extensions.Constants; + +namespace PostFundManagement.Tests; + +public class SkorubaUserServiceGetUserRolesIntegrationTests +{ + private readonly ISkorubaUserService _skorubaService; + private readonly IHttpClientFactory _httpClientFactory; + + public SkorubaUserServiceGetUserRolesIntegrationTests() + { + var services = new ServiceCollection(); + + // Load configuration from environment and secrets + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: true) + .AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true) + .AddEnvironmentVariables() + .Build(); + + services.AddSingleton(configuration); + services.AddHttpClient(); + + // Register the Skoruba HTTP client with the actual DI configuration + services.AddSkorubaApiService(configuration) + .AddRegisterServicesWithCaching(configuration) + .AddEndpointAndServiceCaching(configuration) + .AddSharedServices() + .AddHashServices(configuration) + .AddApplicationDbContext(configuration) + .AddHttpContextAccessor() + .AddTransient(); + + var serviceProvider = services.BuildServiceProvider(); + _skorubaService = serviceProvider.GetRequiredService(); + _httpClientFactory = serviceProvider.GetRequiredService(); + } + + [DebugOnlyFact] + public void HttpClientFactory_HasSkorubaHttpClientConfigured() + { + // Act + var httpClient = _httpClientFactory.CreateClient(SkorubaHttpClient); + + // Assert + Assert.NotNull(httpClient); + Assert.NotNull(httpClient.BaseAddress); + } + + [DebugOnlyFact] + public async Task CreateUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var newUser = new CreateUserRequest + { + UserName = "testuser", + Email = "testuser@example.com", + EmailConfirmed = true, + }; + + // Act + var result = await _skorubaService.CreateUserAsync(newUser); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task DeleteUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("3b001832-c78d-4705-9bc2-0f2f2ebb35b7"); + + // Act + var result = await _skorubaService.RemoveUserAsync(userId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task LockoutUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + + // Act + var result = await _skorubaService.SetUserLockoutAsync(userId, true); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task UnlockUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + + // Act + var result = await _skorubaService.SetUserLockoutAsync(userId, false); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task GetUserRolesAsync_SendsProperlyFormattedRequest() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var page = 1; + var pageSize = 25; + + // Act + var result = await _skorubaService.GetUserRolesAsync(userId, page, pageSize); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task AddUserRoleAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var roleId = Guid.Parse("34b03edc-cda4-4380-b7a5-3310933b75ab"); // Contributor role ID + + // Act + var result = await _skorubaService.AddRoleAsync(userId, roleId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task RemoveUserRoleAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var roleId = Guid.Parse("34b03edc-cda4-4380-b7a5-3310933b75ab"); // Contributor role ID + + // Act + var result = await _skorubaService.RemoveRoleAsync(userId, roleId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task GetUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var page = 1; + var pageSize = 25; + + // Act + var result = await _skorubaService.GetUserClaimsAsync(userId, page, pageSize); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task AddUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var claimType = "test-claim"; + var claimValue = "test-value"; + + // Act + var result = await _skorubaService.AddClaimAsync(userId, claimType, claimValue); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task RemoveUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var claimType = "test-claim"; + + var userClaimsResult = await _skorubaService.GetUserClaimsAsync(userId); + var matchingClaim = userClaimsResult.Value?.FirstOrDefault(c => c.ClaimType == claimType); + + Assert.NotNull(matchingClaim); + + // Act + var result = await _skorubaService.RemoveClaimAsync(userId, matchingClaim!.ClaimId!.Value); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task GetUserRolesAsync_RespectsCancellationToken() + { + // Arrange + var userId = Guid.NewGuid(); + var cts = new CancellationTokenSource(); + cts.Cancel(); + + // Act & Assert + await Assert.ThrowsAsync(async () => + { + await _skorubaService.GetUserRolesAsync(userId, cancellationToken: cts.Token); + }); + } +} diff --git a/PostFundManagement.Tests/appsettings.json b/PostFundManagement.Tests/appsettings.json new file mode 100644 index 0000000..58a2660 --- /dev/null +++ b/PostFundManagement.Tests/appsettings.json @@ -0,0 +1,45 @@ +{ + "EnableServiceCaching": true, + "CorsOrigins": [ + "https://console.ifri.khongisa.co.za", + "https://localhost:7208" + ], + "GeneralS3Settings": { + "ServiceUrl": "https://s3.garage.khongisa.co.za", + "Region": "garage", + "BucketName": "pfm", + "CdnBaseUrl": "https://pfm.cdn.khongisa.co.za" + }, + "Monitoring": { + "Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889", + "ServiceName": "Pfm.DEV" + }, + "SecuritySettings": { + "Authority": "https://sts.security.khongisa.co.za", + "Audience": "pfm-api-dev" + }, + "MachineIdentitySettings": { + "Authority": "https://sts.security.khongisa.co.za", + "Scope": "skoruba_identity_admin_api" + }, + "Logging": { + "LogLevel": { + "Default": "Warning", + "Quartz": "Error", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore.Database": "Error", + "Microsoft.EntityFrameworkCore.Update": "Error" + } + }, + "EmailProcessorCron": "0 */5 * * * ?", + "Email": { + "SmtpServer": "smtp.example.com", + "SmtpPort": 587, + "SenderEmail": "noreply@example.com", + "SenderName": "Example" + }, + "HasherSettings": { + "MinHashLength": 11 + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/PostFundManagement.slnx b/PostFundManagement.slnx index 9982c4f..169329b 100644 --- a/PostFundManagement.slnx +++ b/PostFundManagement.slnx @@ -11,4 +11,5 @@ + diff --git a/docker-compose.yml b/docker-compose.yml index 16592c8..cd0643d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,12 @@ services: - SecuritySettings__ClientId=${SECURITY_CLIENT_ID} - SecuritySettings__ClientSecret=${SECURITY_CLIENT_SECRET} + # Skoruba Duende Administration Security Overrides + - MachineIdentitySettings__Authority=${ADMIN_SECURITY_AUTHORITY:-https://sts.security.khongisa.co.za} + - MachineIdentitySettings__Scope=${ADMIN_SECURITY_AUDIENCE} + - MachineIdentitySettings__ClientId=${ADMIN_SECURITY_CLIENT_ID} + - MachineIdentitySettings__ClientSecret=${ADMIN_SECURITY_CLIENT_SECRET} + # Data Protection Overrides - DataProtection__Certificate=${DATA_PROTECTION_CERTIFICATE} - DataProtection__Password=${DATA_PROTECTION_CERTIFICATE_PASSWORD}