Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update builder to standard set in correspondance #909

Merged
merged 13 commits into from
Dec 2, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ namespace Altinn.App.Core.Features.Signing.Mocks;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public class CorrespondanceClientMock
{
public async Task<InitializeCorrespondencesResponseMock> Initialize(InitializeCorrespondenceRequestMock requestMock)
public static async Task<InitializeCorrespondencesResponseMock> Initialize(
InitializeCorrespondenceRequestMock requestMock
)
{
var responseMock = new InitializeCorrespondencesResponseMock
{
Expand Down
60 changes: 42 additions & 18 deletions src/Altinn.App.Core/Features/Signing/SigningDelegationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Altinn.App.Core.Features.Signing.Models;
using Altinn.App.Core.Helpers;
using Altinn.App.Core.Internal.AccessManagement;
using Altinn.App.Core.Internal.AccessManagement.Builders;
using Altinn.App.Core.Internal.AccessManagement.Models;
using Altinn.App.Core.Internal.AccessManagement.Models.Shared;
using Altinn.Platform.Storage.Interface.Models;
Expand All @@ -26,25 +27,48 @@ CancellationToken ct
{
if (state.IsAccessDelegated is false)
{
// csharpier-ignore-start
string appResourceId = AppIdHelper.ToResourceId(instance.AppId);
DelegationRequest delegation = DelegationRequestBuilder
.CreateBuilder(appResourceId, instance.Id)
.WithDelegator(new Delegator { IdType = DelegationConst.Party, Id = "" }) // TODO: assign delegator
.WithRecipient(new Delegatee { IdType = DelegationConst.Party, Id = signeeContext.PartyId.ToString() })
.AddRight()
.WithAction(DelegationConst.ActionId, ActionType.Read)
.AddResource(DelegationConst.Resource, appResourceId) // TODO: translate app id to altinn resource id
.AddResource(DelegationConst.Task, taskId)
.BuildRight()
.AddRight()
.WithAction(DelegationConst.ActionId, ActionType.Sign)
.AddResource(DelegationConst.Resource, appResourceId) // TODO: translate app id to altinn resource id
.AddResource(DelegationConst.Task, taskId)
.BuildRight()
DelegationRequest delegationRequest = DelegationBuilder
.Create()
.WithApplicationId(instance.AppId)
.WithInstanceId(instance.Id)
.WithDelegator(new Delegator { IdType = DelegationConst.Party, Id = "" })
.WithRecipient(
new Delegatee { IdType = DelegationConst.Party, Id = signeeContext.PartyId.ToString() }
)
.WithRights(
[
AccessRightBuilder
.Create()
.WithAction(DelegationConst.ActionId, ActionType.Read)
HauklandJ marked this conversation as resolved.
Show resolved Hide resolved
.WithResources(
[
new Resource
{
Type = DelegationConst.Resource,
Value = AppIdHelper.ToResourceId(instance.AppId)
},
new Resource { Type = DelegationConst.Task, Value = taskId }
]
)
.Build(),
AccessRightBuilder
.Create()
.WithAction(DelegationConst.ActionId, ActionType.Sign)
.WithResources(
[
new Resource
{
Type = DelegationConst.Resource,
Value = AppIdHelper.ToResourceId(instance.AppId)
},
new Resource { Type = DelegationConst.Task, Value = taskId }
]
)
.Build()
]
)
.Build();
// csharpier-ignore-end
var response = await accessManagementClient.DelegateRights(delegation, ct);
var response = await accessManagementClient.DelegateRights(delegationRequest, ct);
state.IsAccessDelegated = await Task.FromResult(true);
}
}
Expand Down
34 changes: 34 additions & 0 deletions src/Altinn.App.Core/Helpers/AppIdHelper.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Diagnostics.CodeAnalysis;

namespace Altinn.App.Core.Helpers;

internal sealed class AppIdHelper
Expand All @@ -6,4 +8,36 @@ internal static string ToResourceId(string appId)
{
return ""; //TODO
}

internal static bool IsResourceId(string appId)
{
return false; //TODO
}

internal static bool TryGetResourceId(string appId, [NotNullWhen(true)] out string? resourceId)
{
if (string.IsNullOrEmpty(appId))
{
resourceId = null;
return false;
}

if (IsResourceId(appId))
{
resourceId = appId;
return true;
}

resourceId = ToResourceId(appId);

if (IsResourceId(resourceId))
{
return true;
}
else
{
resourceId = null;
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Altinn.App.Core.Internal.App;
using Altinn.Common.AccessTokenClient.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Altinn.App.Core.Internal.AccessManagement;

Expand All @@ -21,7 +22,7 @@ internal sealed class AccessManagementClient(
HttpClient httpClient,
IAppMetadata appMetadata,
IAccessTokenGenerator accessTokenGenerator,
PlatformSettings platformSettings,
IOptions<PlatformSettings> platformSettings,
Telemetry? telemetry = null
) : IAccessManagementClient
{
Expand All @@ -36,7 +37,7 @@ public async Task<DelegationResponse> DelegateRights(DelegationRequest delegatio

HttpResponseMessage? httpResponseMessage = null;
string? httpContent = null;
UrlHelper urlHelper = new(platformSettings);
UrlHelper urlHelper = new(platformSettings.Value);
try
{
var application = await appMetadata.GetApplicationMetadata();
Expand Down Expand Up @@ -71,9 +72,10 @@ public async Task<DelegationResponse> DelegateRights(DelegationRequest delegatio
}
catch (Exception e)
{
var ex = new DelegationException(
var ex = new AccessManagementRequestException(
$"Something went wrong when processing the access management request.",
httpResponseMessage,
null,
httpResponseMessage?.StatusCode,
httpContent,
e
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Altinn.App.Core.Internal.AccessManagement.Models;
using Altinn.App.Core.Internal.AccessManagement.Models.Shared;

namespace Altinn.App.Core.Internal.AccessManagement.Builders;

internal interface IAccessRightBuilderStart
{
IAccessRightBuilderAction WithAction(string type, string value);
}

internal interface IAccessRightBuilderAction
{
IAccessRightBuilder WithResource(string type, string value);
IAccessRightBuilder WithResources(List<Resource> resources);
}

internal interface IAccessRightBuilder : IAccessRightBuilderStart, IAccessRightBuilderAction
{
RightRequest Build();
}

internal sealed class AccessRightBuilder : IAccessRightBuilder
{
private AltinnAction? _action;
private List<Resource>? _resources;

private AccessRightBuilder() { }

public static IAccessRightBuilderStart Create() => new AccessRightBuilder();

public IAccessRightBuilderAction WithAction(string type, string value)
{
_action = new AltinnAction { Type = type, Value = value };
return this;
}

public IAccessRightBuilder WithResource(string type, string value)
{
_resources = [new Resource { Type = type, Value = value }];

return this;
}

public IAccessRightBuilder WithResources(List<Resource> resources)
{
_resources = [.. _resources ?? [], .. resources];
return this;
}

public RightRequest Build()
{
return new RightRequest { Action = _action, Resource = _resources ?? [] };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using System.Diagnostics.CodeAnalysis;
using Altinn.App.Core.Helpers;
using Altinn.App.Core.Internal.AccessManagement.Exceptions;
using Altinn.App.Core.Internal.AccessManagement.Models;
using Altinn.App.Core.Internal.AccessManagement.Models.Shared;

namespace Altinn.App.Core.Internal.AccessManagement.Builders;

internal abstract class DelegationBuilderBase
{
internal static void NotNullOrEmpty([NotNull] object? value, string? errorMessage = null)
{
if (
value is null
|| value is string str && string.IsNullOrWhiteSpace(str)
|| value is ReadOnlyMemory<byte> { IsEmpty: true }
)
{
throw new AccessManagementArgumentException(errorMessage); // TODO: add custom exception
}
}
}

internal interface IDelegationBuilderStart
{
IDelegationBuilderApplicationId WithApplicationId(string applicationId);
}

internal interface IDelegationBuilderApplicationId
{
IDelegationBuilderInstanceId WithInstanceId(string instanceId);
}

internal interface IDelegationBuilderInstanceId
{
IDelegationBuilderDelegator WithDelegator(Delegator delegator);
}

internal interface IDelegationBuilderDelegator
{
IDelegationBuilderRecipient WithRecipient(Delegatee recipient);
}

internal interface IDelegationBuilderRecipient
{
IDelegationBuilder WithRight(RightRequest rightRequest);
IDelegationBuilder WithRights(List<RightRequest> rightRequests);
}

internal interface IDelegationBuilder
: IDelegationBuilderStart,
IDelegationBuilderApplicationId,
IDelegationBuilderInstanceId,
IDelegationBuilderDelegator,
IDelegationBuilderRecipient
{
DelegationRequest Build();
}

internal sealed class DelegationBuilder : DelegationBuilderBase, IDelegationBuilder
{
private string? _applicationId;
private string? _instanceId;
private Delegator? _delegator;
private Delegatee? _recipient;
private List<RightRequest>? _rights;

private DelegationBuilder() { }

public static IDelegationBuilderStart Create() => new DelegationBuilder();

public IDelegationBuilderApplicationId WithApplicationId(string applicationId)
{
NotNullOrEmpty(applicationId, nameof(applicationId));
_applicationId = AppIdHelper.TryGetResourceId(applicationId, out string? resourceId)
? resourceId
: throw new ArgumentException("Invalid application ID", nameof(applicationId));
return this;
}

public IDelegationBuilderInstanceId WithInstanceId(string instanceId)
{
NotNullOrEmpty(instanceId, nameof(instanceId));
_instanceId = instanceId;
return this;
}

public IDelegationBuilderDelegator WithDelegator(Delegator delegator)
{
NotNullOrEmpty(delegator, nameof(delegator));
_delegator = delegator;
return this;
}

public IDelegationBuilderRecipient WithRecipient(Delegatee recipient)
{
NotNullOrEmpty(recipient, nameof(recipient));
_recipient = recipient;
return this;
}

public IDelegationBuilder WithRight(RightRequest rightRequest)
{
_rights = [rightRequest];
return this;
}

public IDelegationBuilder WithRights(List<RightRequest> rightRequests)
{
_rights = [.. _rights ?? [], .. rightRequests];
return this;
}

public IDelegationBuilder WithRight(AccessRightBuilder rightBuilder)
{
_rights = [rightBuilder.Build()];
return this;
}

public DelegationRequest Build()
{
NotNullOrEmpty(_applicationId, nameof(_applicationId));
NotNullOrEmpty(_instanceId, nameof(_instanceId));
NotNullOrEmpty(_delegator, nameof(_delegator));
NotNullOrEmpty(_recipient, nameof(_recipient));
NotNullOrEmpty(_rights, nameof(_rights));

return new DelegationRequest
{
ResourceId = _applicationId,
InstanceId = _instanceId,
From = _delegator,
To = _recipient,
Rights = _rights
};
}
}
Loading
Loading