Skip to content

Commit f061198

Browse files
authored
Add endpoints for customer delegation to agent systemuser (#1347)
* WIP * fix route params * fix mock data * fix some tests * fix assignment data: return assignment id to frontend * fixes * fix test * fix tests * handle errors * add test for negative case * add tests for remove agent delegation * fix code smells * remove using * return empty list instead of error in agent delegations mock * enable agent delegation mock * rename * refactor nesting * remove mock * refactor * fix url * fixes * fix tests * fix * fix * fix typo * refactor
1 parent e69d82d commit f061198

30 files changed

+873
-84
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Altinn.AccessManagement.UI.Core.Models.SystemUser;
2+
using Altinn.Authorization.ProblemDetails;
3+
4+
namespace Altinn.AccessManagement.UI.Core.ClientInterfaces
5+
{
6+
/// <summary>
7+
/// Interface for client wrapper for integration with the systemuser client delegation API
8+
/// </summary>
9+
public interface ISystemUserAgentDelegationClient
10+
{
11+
/// <summary>
12+
/// Return delegated customers for this system user
13+
/// </summary>
14+
/// <param name="partyId">The party id of the party owning system user to retrieve delegated customers from</param>
15+
/// <param name="systemUserGuid">The system user UUID to retrieve delegated customers from</param>
16+
/// <param name="cancellationToken">Cancellation token</param>
17+
/// <returns>List of delegated customers for system user</returns>
18+
Task<List<AgentDelegation>> GetSystemUserAgentDelegations(int partyId, Guid systemUserGuid, CancellationToken cancellationToken);
19+
20+
/// <summary>
21+
/// Add client to system user
22+
/// </summary>
23+
/// <param name="partyId">The party id of the party owning system user to add customer to</param>
24+
/// <param name="systemUserGuid">The system user UUID to add customer to</param>
25+
/// <param name="delegationRequest">The party uuid of the customer to add + partyUuid of system user owner party</param>
26+
/// <param name="cancellationToken">Cancellation token</param>
27+
/// <returns>New AgentDelegation with delegation info</returns>
28+
Task<Result<AgentDelegation>> AddClient(int partyId, Guid systemUserGuid, AgentDelegationRequest delegationRequest, CancellationToken cancellationToken);
29+
30+
/// <summary>
31+
/// Remove client from system user
32+
/// </summary>
33+
/// <param name="partyId">The party id of the party owning system user to remove customer from</param>
34+
/// <param name="systemUserGuid">The system user UUID to remove customer from</param>
35+
/// <param name="assignmentId">The assignment id to remove</param>
36+
/// <param name="cancellationToken">Cancellation token</param>
37+
/// <returns>Boolean result of remove</returns>
38+
Task<Result<bool>> RemoveClient(int partyId, Guid systemUserGuid, Guid assignmentId, CancellationToken cancellationToken);
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace Altinn.AccessManagement.UI.Core.Models.SystemUser
2+
{
3+
/// <summary>
4+
/// A client delegation to a system user
5+
/// </summary>
6+
public class AgentDelegation
7+
{
8+
/// <summary>
9+
/// Assignment id
10+
/// </summary>
11+
public Guid Id { get; init; }
12+
13+
/// <summary>
14+
/// From party
15+
/// </summary>
16+
public DelegationParty From { get; init; }
17+
18+
/// <summary>
19+
/// To party
20+
/// </summary>
21+
public DelegationParty To { get; init; }
22+
23+
/// <summary>
24+
/// Facilitator - the agent system user
25+
/// </summary>
26+
public DelegationParty Facilitator { get; init; }
27+
}
28+
29+
/// <summary>
30+
/// Delegation Party for AgentDelegation
31+
/// </summary>
32+
public class DelegationParty
33+
{
34+
/// <summary>
35+
/// Party id
36+
/// </summary>
37+
public Guid Id { get; init; }
38+
39+
/// <summary>
40+
/// Party name
41+
/// </summary>
42+
public string Name { get; init; }
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Altinn.AccessManagement.UI.Core.Models.SystemUser
2+
{
3+
/// <summary>
4+
/// Payload when adding a party to agent system user
5+
/// </summary>
6+
public class AgentDelegationRequest
7+
{
8+
/// <summary>
9+
/// The party uuid to add
10+
/// </summary>
11+
public Guid CustomerId { get; set; }
12+
13+
/// <summary>
14+
/// PartyUuid of party which owns the agent system user
15+
/// </summary>
16+
public Guid FacilitatorId { get; set; }
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Altinn.AccessManagement.UI.Core.Models.SystemUser.Frontend
2+
{
3+
/// <summary>
4+
/// A client delegation to a system user
5+
/// </summary>
6+
public class AgentDelegationFE
7+
{
8+
/// <summary>
9+
/// Assignment uuid
10+
/// </summary>
11+
public Guid AssignmentId { get; set; }
12+
13+
/// <summary>
14+
/// Delegated customer party uuid
15+
/// </summary>
16+
public Guid CustomerId { get; set; }
17+
}
18+
}

backend/src/Altinn.AccessManagement.UI/Altinn.AccessManagement.UI.Core/Models/SystemUser/Frontend/AgentDelegationPartyFE.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ public class AgentDelegationPartyFE
88
/// <summary>
99
/// Party UUID
1010
/// </summary>
11-
public required Guid Uuid { get; set; }
12-
13-
/// <summary>
14-
/// Party Id
15-
/// </summary>
16-
public int Id { get; set; }
11+
public required Guid Id { get; set; }
1712

1813
/// <summary>
1914
/// Party display name

backend/src/Altinn.AccessManagement.UI/Altinn.AccessManagement.UI.Core/Services/Interfaces/ISystemUserAgentDelegationService.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Altinn.AccessManagement.UI.Core.Enums;
2+
using Altinn.AccessManagement.UI.Core.Models.SystemUser;
23
using Altinn.AccessManagement.UI.Core.Models.SystemUser.Frontend;
34
using Altinn.Authorization.ProblemDetails;
45

@@ -16,6 +17,35 @@ public interface ISystemUserAgentDelegationService
1617
/// <param name="customerType">Customer type to get</param>
1718
/// <param name="cancellationToken">Cancellation token</param>
1819
/// <returns>List of all party customers</returns>
19-
Task<Result<List<AgentDelegationPartyFE>>> GetPartyCustomers(Guid partyUuid, CustomerRoleType customerType, CancellationToken cancellationToken);
20+
Task<List<AgentDelegationPartyFE>> GetPartyCustomers(Guid partyUuid, CustomerRoleType customerType, CancellationToken cancellationToken);
21+
22+
/// <summary>
23+
/// Return delegated customers for this system user
24+
/// </summary>
25+
/// <param name="partyId">The party UUID of the party owning system user to retrieve delegated customers from</param>
26+
/// <param name="systemUserGuid">The system user UUID to retrieve delegated customers from</param>
27+
/// <param name="cancellationToken">Cancellation token</param>
28+
/// <returns>List of delegated customers for system user</returns>
29+
Task<List<AgentDelegationFE>> GetSystemUserAgentDelegations(int partyId, Guid systemUserGuid, CancellationToken cancellationToken);
30+
31+
/// <summary>
32+
/// Add client to system user
33+
/// </summary>
34+
/// <param name="partyId">The party id of the party owning system user to add customer to</param>
35+
/// <param name="systemUserGuid">The system user UUID to add customer to</param>
36+
/// <param name="delegationRequest">Payload to send to add client</param>
37+
/// <param name="cancellationToken">Cancellation token</param>
38+
/// <returns>AgentDelegationFE with assignment id and customer id</returns>
39+
Task<Result<AgentDelegationFE>> AddClient(int partyId, Guid systemUserGuid, AgentDelegationRequest delegationRequest, CancellationToken cancellationToken);
40+
41+
/// <summary>
42+
/// Remove client from system user
43+
/// </summary>
44+
/// <param name="partyId">The party id of the party owning system user to remove customer from</param>
45+
/// <param name="systemUserGuid">The system user UUID to remove customer from</param>
46+
/// <param name="assignmentId">The assignment id to remove</param>
47+
/// <param name="cancellationToken">Cancellation token</param>
48+
/// <returns>Boolean result of remove</returns>
49+
Task<Result<bool>> RemoveClient(int partyId, Guid systemUserGuid, Guid assignmentId, CancellationToken cancellationToken);
2050
}
2151
}

backend/src/Altinn.AccessManagement.UI/Altinn.AccessManagement.UI.Core/Services/SystemUserAgentDelegationService.cs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,76 @@ namespace Altinn.AccessManagement.UI.Core.Services
1111
/// <inheritdoc />
1212
public class SystemUserAgentDelegationService : ISystemUserAgentDelegationService
1313
{
14+
private readonly ISystemUserAgentDelegationClient _systemUserAgentDelegationClient;
1415
private readonly IRegisterClient _registerClient;
1516

1617
/// <summary>
17-
/// Initializes a new instance of the <see cref="SystemUserService"/> class.
18+
/// Initializes a new instance of the <see cref="SystemUserAgentDelegationService"/> class.
1819
/// </summary>
20+
/// <param name="systemUserAgentDelegationClient">The system user client administration client.</param>
1921
/// <param name="registerClient">The register client</param>
2022
public SystemUserAgentDelegationService(
23+
ISystemUserAgentDelegationClient systemUserAgentDelegationClient,
2124
IRegisterClient registerClient)
2225
{
26+
_systemUserAgentDelegationClient = systemUserAgentDelegationClient;
2327
_registerClient = registerClient;
2428
}
2529

2630
/// <inheritdoc />
27-
public async Task<Result<List<AgentDelegationPartyFE>>> GetPartyCustomers(Guid partyUuid, CustomerRoleType customerType, CancellationToken cancellationToken)
31+
public async Task<List<AgentDelegationPartyFE>> GetPartyCustomers(Guid partyUuid, CustomerRoleType customerType, CancellationToken cancellationToken)
2832
{
2933
CustomerList regnskapsforerCustomers = await _registerClient.GetPartyCustomers(partyUuid, customerType, cancellationToken);
3034
return MapCustomerListToCustomerFE(regnskapsforerCustomers);
3135
}
3236

37+
/// <inheritdoc />
38+
public async Task<List<AgentDelegationFE>> GetSystemUserAgentDelegations(int partyId, Guid systemUserGuid, CancellationToken cancellationToken)
39+
{
40+
List<AgentDelegation> delegations = await _systemUserAgentDelegationClient.GetSystemUserAgentDelegations(partyId, systemUserGuid, cancellationToken);
41+
return delegations.Select(x => new AgentDelegationFE()
42+
{
43+
AssignmentId = x.Id,
44+
CustomerId = x.From.Id,
45+
}).ToList();
46+
}
47+
48+
/// <inheritdoc />
49+
public async Task<Result<AgentDelegationFE>> AddClient(int partyId, Guid systemUserGuid, AgentDelegationRequest delegationRequest, CancellationToken cancellationToken)
50+
{
51+
Result<AgentDelegation> newAgentDelegation = await _systemUserAgentDelegationClient.AddClient(partyId, systemUserGuid, delegationRequest, cancellationToken);
52+
53+
if (newAgentDelegation.IsProblem)
54+
{
55+
return new Result<AgentDelegationFE>(newAgentDelegation.Problem);
56+
}
57+
58+
return new AgentDelegationFE()
59+
{
60+
AssignmentId = newAgentDelegation.Value.Id,
61+
CustomerId = newAgentDelegation.Value.From.Id,
62+
};
63+
}
64+
65+
/// <inheritdoc />
66+
public async Task<Result<bool>> RemoveClient(int partyId, Guid systemUserGuid, Guid assignmentId, CancellationToken cancellationToken)
67+
{
68+
Result<bool> response = await _systemUserAgentDelegationClient.RemoveClient(partyId, systemUserGuid, assignmentId, cancellationToken);
69+
if (response.IsProblem)
70+
{
71+
return new Result<bool>(response.Problem);
72+
}
73+
74+
return response.Value;
75+
}
76+
3377
private static List<AgentDelegationPartyFE> MapCustomerListToCustomerFE(CustomerList customers)
3478
{
3579
return customers.Data.Select(x =>
3680
{
3781
return new AgentDelegationPartyFE()
3882
{
39-
Id = x.PartyId,
40-
Uuid = x.PartyUuid,
83+
Id = x.PartyUuid,
4184
Name = x.DisplayName,
4285
OrgNo = x.OrganizationIdentifier
4386
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using System.Net.Http.Json;
3+
using System.Text.Json;
4+
using Altinn.AccessManagement.UI.Core.ClientInterfaces;
5+
using Altinn.AccessManagement.UI.Core.Extensions;
6+
using Altinn.AccessManagement.UI.Core.Helpers;
7+
using Altinn.AccessManagement.UI.Core.Models.SystemUser;
8+
using Altinn.AccessManagement.UI.Integration.Configuration;
9+
using Altinn.Authorization.ProblemDetails;
10+
using Microsoft.AspNetCore.Http;
11+
using Microsoft.Extensions.Logging;
12+
using Microsoft.Extensions.Options;
13+
14+
namespace Altinn.AccessManagement.UI.Integration.Clients
15+
{
16+
/// <summary>
17+
/// client that integrates with the agent deletation api
18+
/// </summary>
19+
[ExcludeFromCodeCoverage]
20+
public class SystemUserAgentDelegationClient : ISystemUserAgentDelegationClient
21+
{
22+
private readonly ILogger _logger;
23+
private readonly HttpClient _client;
24+
private readonly IHttpContextAccessor _httpContextAccessor;
25+
private readonly PlatformSettings _platformSettings;
26+
private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="SystemUserAgentDelegationClient"/> class
30+
/// </summary>
31+
/// <param name="httpClient">http client</param>
32+
/// <param name="logger">the handler for logger service</param>
33+
/// <param name="httpContextAccessor">the handler for httpcontextaccessor service</param>
34+
/// <param name="platformSettings"> platform settings configuration</param>
35+
public SystemUserAgentDelegationClient(
36+
HttpClient httpClient,
37+
ILogger<SystemUserAgentDelegationClient> logger,
38+
IHttpContextAccessor httpContextAccessor,
39+
IOptions<PlatformSettings> platformSettings)
40+
{
41+
_logger = logger;
42+
_httpContextAccessor = httpContextAccessor;
43+
_platformSettings = platformSettings.Value;
44+
httpClient.BaseAddress = new Uri(_platformSettings.ApiAuthenticationEndpoint);
45+
httpClient.DefaultRequestHeaders.Add(_platformSettings.SubscriptionKeyHeaderName, _platformSettings.SubscriptionKey);
46+
_client = httpClient;
47+
}
48+
49+
/// <inheritdoc/>
50+
public async Task<List<AgentDelegation>> GetSystemUserAgentDelegations(int partyId, Guid systemUserGuid, CancellationToken cancellationToken)
51+
{
52+
try
53+
{
54+
string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _platformSettings.JwtCookieName);
55+
string endpointUrl = $"systemuser/agent/{partyId}/{systemUserGuid}/delegation";
56+
57+
HttpResponseMessage response = await _client.GetAsync(token, endpointUrl);
58+
string responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
59+
60+
if (response.IsSuccessStatusCode)
61+
{
62+
return JsonSerializer.Deserialize<List<AgentDelegation>>(responseContent, _serializerOptions);
63+
}
64+
65+
_logger.LogError("AccessManagement.UI // SystemUserAgentDelegationClient // GetSystemUserAgentDelegations // Unexpected HttpStatusCode: {StatusCode}\n {responseBody}", response.StatusCode, responseContent);
66+
return [];
67+
}
68+
catch (Exception ex)
69+
{
70+
_logger.LogError(ex, "AccessManagement.UI // SystemUserAgentDelegationClient // GetSystemUserAgentDelegations // Exception");
71+
throw;
72+
}
73+
}
74+
75+
/// <inheritdoc/>
76+
public async Task<Result<AgentDelegation>> AddClient(int partyId, Guid systemUserGuid, AgentDelegationRequest delegationRequest, CancellationToken cancellationToken)
77+
{
78+
try
79+
{
80+
string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _platformSettings.JwtCookieName);
81+
string endpointUrl = $"systemuser/agent/{partyId}/{systemUserGuid}/delegation";
82+
StringContent requestBody = new StringContent(JsonSerializer.Serialize(delegationRequest, _serializerOptions), System.Text.Encoding.UTF8, "application/json");
83+
84+
HttpResponseMessage response = await _client.PostAsync(token, endpointUrl, requestBody);
85+
string responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
86+
87+
if (response.IsSuccessStatusCode)
88+
{
89+
return JsonSerializer.Deserialize<AgentDelegation>(responseContent, _serializerOptions);
90+
}
91+
92+
_logger.LogError("AccessManagement.UI // SystemUserAgentDelegationClient // AddClient // Unexpected HttpStatusCode: {StatusCode}\n {responseBody}", response.StatusCode, responseContent);
93+
AltinnProblemDetails problemDetails = await response.Content.ReadFromJsonAsync<AltinnProblemDetails>(cancellationToken);
94+
return ProblemMapper.MapToAuthUiError(problemDetails?.ErrorCode.ToString());
95+
}
96+
catch (Exception ex)
97+
{
98+
_logger.LogError(ex, "AccessManagement.UI // SystemUserAgentDelegationClient // AddClient // Exception");
99+
throw;
100+
}
101+
}
102+
103+
/// <inheritdoc/>
104+
public async Task<Result<bool>> RemoveClient(int partyId, Guid systemUserGuid, Guid assignmentId, CancellationToken cancellationToken)
105+
{
106+
try
107+
{
108+
string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _platformSettings.JwtCookieName);
109+
string endpointUrl = $"systemuser/agent/{partyId}/{systemUserGuid}/delegation/{assignmentId}";
110+
111+
HttpResponseMessage response = await _client.DeleteAsync(token, endpointUrl);
112+
string responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
113+
114+
if (response.IsSuccessStatusCode)
115+
{
116+
return JsonSerializer.Deserialize<bool>(responseContent, _serializerOptions);
117+
}
118+
119+
_logger.LogError("AccessManagement.UI // SystemUserAgentDelegationClient // RemoveClient // Unexpected HttpStatusCode: {StatusCode}\n {responseBody}", response.StatusCode, responseContent);
120+
AltinnProblemDetails problemDetails = await response.Content.ReadFromJsonAsync<AltinnProblemDetails>(cancellationToken);
121+
return ProblemMapper.MapToAuthUiError(problemDetails?.ErrorCode.ToString());
122+
}
123+
catch (Exception ex)
124+
{
125+
_logger.LogError(ex, "AccessManagement.UI // SystemUserAgentDelegationClient // RemoveClient // Exception");
126+
throw;
127+
}
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)