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

Chore/908 move overview org to rtk query #1045

Merged
merged 29 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
86a299f
Move stuff to bff
sonwit Aug 20, 2024
0783682
Add RevokeDelegationDto and RevokeApiDelegationOutput models and batc…
sonwit Aug 20, 2024
e54c08e
update client to use rtk-overview-org
sonwit Aug 20, 2024
1f178eb
add overviewOrg to rtk-store
sonwit Aug 20, 2024
968ae70
Refactor API delegation service
sonwit Aug 23, 2024
09f1061
Refactor API delegation service
sonwit Aug 23, 2024
e26d1f7
Refactor API delegation service
sonwit Aug 23, 2024
b1b6c57
rename layout to DelegationType
sonwit Aug 26, 2024
690e53f
Refactor DeletableListItem component and related files
sonwit Aug 26, 2024
2317676
fix cy tests
sonwit Aug 26, 2024
e5fb03c
lint
sonwit Aug 26, 2024
af5f6c2
fix tests
sonwit Aug 27, 2024
15c935a
Remove debug output and clean up code in APIDelegationControllerTest
sonwit Aug 27, 2024
0ad5133
chore: Add JSON files for partial success in revoke delegation batch
sonwit Aug 27, 2024
2a48ec9
fix revoke batch revoke function
sonwit Aug 27, 2024
747e0ee
Handle failed API delegation revocation in OverviewPageContent
sonwit Aug 27, 2024
45037b7
remove empty line to fix warning
sonwit Aug 28, 2024
aeb6885
fix: Update revoke delegation error message
sonwit Aug 28, 2024
b9750af
fix lint issues
sonwit Aug 28, 2024
2382fdd
Refactor RevokeReceivedDelegation constructor
sonwit Aug 28, 2024
3918ef2
Rename OverviewOrg to OrganizationApiSet
sonwit Aug 28, 2024
f2e65de
Update apiDelegationApi tagTypes to include 'overviewOrg' and invalid…
sonwit Aug 30, 2024
812b0d8
Update revoke delegation error message
sonwit Aug 30, 2024
d92077b
Refactor APIDelegationControllerTest to use separate method for getti…
sonwit Aug 30, 2024
6bfb84f
Move class definitions to separate file and simplfy mapping function
sonwit Aug 30, 2024
ac02342
add test data
sonwit Aug 30, 2024
91fade2
fix: Disable button when there are no items to delete
sonwit Sep 2, 2024
eb83c6f
remove newline
sonwit Sep 2, 2024
43c00c0
remove empty ilne
sonwit Sep 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
namespace Altinn.AccessManagement.UI.Core.Models
{
/// <summary>
/// Represents a set of APIs given to or recieved from an organization.
/// </summary>
public class OrganizationApiSet
{
/// <summary>
/// Gets or sets the ID of the organization.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets the name of the organization.
/// </summary>
public string Name { get; set; }

/// <summary>
/// Gets or sets the organization number.
/// </summary>
public string OrgNumber { get; set; }

/// <summary>
/// Gets or sets a set of APIs given to or recieved from an organization
/// </summary>
public List<ApiListItem> ApiList { get; set; } = new List<ApiListItem>();
}

/// <summary>
/// Represents an API item.
/// </summary>
public class ApiListItem
{
/// <summary>
/// Gets or sets the ID of the API.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets the name of the API.
/// </summary>
public string ApiName { get; set; }

/// <summary>
/// Gets or sets the owner of the API.
/// </summary>
public string Owner { get; set; }

/// <summary>
/// Gets or sets the description of the API.
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets the scopes associated with the API.
/// </summary>
public List<string> Scopes { get; set; }
}

/// <summary>
/// Represents the type of delegation.
/// </summary>
public enum DelegationType
{
/// <summary>
/// Offered delegation type.
/// </summary>
Offered,

/// <summary>
/// Received delegation type.
/// </summary>
Received
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Altinn.AccessManagement.UI.Core.Models.SingleRight;

namespace Altinn.AccessManagement.UI.Core.Models
{
/// <summary>
/// Response model for the result of a api-delegation to a recipient.
/// </summary>
public class RevokeApiDelegationOutput
{
/// <summary>
/// Gets or sets the organization identifier.
/// </summary>
public string OrgNumber { get; set; }

/// <summary>
/// Gets or sets the API identifier.
/// </summary>
public string ApiId { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the operation was successful.
/// </summary>
public bool Success { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;

namespace Altinn.AccessManagement.UI.Core.Models
{
/// <summary>
/// Represents the data transfer object for revoking an offered or received delegation.
/// </summary>
public class RevokeDelegationDTO
{
/// <summary>
/// Gets or sets the organization number.
/// </summary>
[Required]
public string OrgNumber { get; set; }

/// <summary>
/// Gets or sets the API identifier.
/// </summary>
[Required]
public string ApiId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,15 @@ public class RevokeOfferedDelegation
/// </summary>
[Required]
public List<Right> Rights { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="RevokeOfferedDelegation"/> class.
/// </summary>
/// <param name="dto">The DTO object containing the data for the delegation.</param>
public RevokeOfferedDelegation(RevokeDelegationDTO dto)
{
To = new List<IdValuePair> { new IdValuePair { Id = "urn:altinn:organizationnumber", Value = dto.OrgNumber } };
Rights = new List<Right> { new Right { Resource = new List<IdValuePair> { new IdValuePair { Id = "urn:altinn:resource", Value = dto.ApiId } } } };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,15 @@ public class RevokeReceivedDelegation
/// </summary>
[Required]
public List<Right> Rights { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="RevokeReceivedDelegation"/> class.
/// </summary>
/// <param name="dto">The data transfer object for revoking a received delegation.</param>
public RevokeReceivedDelegation(RevokeDelegationDTO dto)
{
From = new List<IdValuePair> { new IdValuePair { Id = "urn:altinn:organizationnumber", Value = dto.OrgNumber } };
Rights = new List<Right> { new Right { Resource = new List<IdValuePair> { new IdValuePair { Id = "urn:altinn:resource", Value = dto.ApiId } } } };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ public class APIDelegationService : IAPIDelegationService
private readonly IAccessManagementClient _maskinportenSchemaClient;
private readonly IResourceService _resourceService;

private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
};

/// <summary>
/// Initializes a new instance of the <see cref="APIDelegationService" /> class.
/// </summary>
Expand All @@ -36,29 +31,29 @@ public APIDelegationService(
}

/// <inheritdoc />
public async Task<List<MaskinportenSchemaDelegationFE>> GetOfferedMaskinportenSchemaDelegations(string party, string languageCode)
public async Task<List<OrganizationApiSet>> GetOfferedMaskinportenSchemaDelegations(string party, string languageCode)
{
List<MaskinportenSchemaDelegation> offeredDelegations = await _maskinportenSchemaClient.GetOfferedMaskinportenSchemaDelegations(party);
return await BuildMaskinportenSchemaDelegationFE(offeredDelegations, languageCode);
return await BuildMaskinportenSchemaDelegationFE(offeredDelegations, languageCode, DelegationType.Offered);
}

/// <inheritdoc />
public async Task<List<MaskinportenSchemaDelegationFE>> GetReceivedMaskinportenSchemaDelegations(string party, string languageCode)
public async Task<List<OrganizationApiSet>> GetReceivedMaskinportenSchemaDelegations(string party, string languageCode)
{
List<MaskinportenSchemaDelegation> receivedDelegations = await _maskinportenSchemaClient.GetReceivedMaskinportenSchemaDelegations(party);
return await BuildMaskinportenSchemaDelegationFE(receivedDelegations, languageCode);
return await BuildMaskinportenSchemaDelegationFE(receivedDelegations, languageCode, DelegationType.Received);
}

/// <inheritdoc />
public async Task<HttpResponseMessage> RevokeReceivedMaskinportenScopeDelegation(string party, RevokeReceivedDelegation delegation)
public async Task<HttpResponseMessage> RevokeReceivedMaskinportenScopeDelegation(string party, RevokeDelegationDTO delegationDTO)
{
return await _maskinportenSchemaClient.RevokeReceivedMaskinportenScopeDelegation(party, delegation);
return await _maskinportenSchemaClient.RevokeReceivedMaskinportenScopeDelegation(party, new RevokeReceivedDelegation(delegationDTO));
}

/// <inheritdoc />
public async Task<HttpResponseMessage> RevokeOfferedMaskinportenScopeDelegation(string party, RevokeOfferedDelegation delegation)
public async Task<HttpResponseMessage> RevokeOfferedMaskinportenScopeDelegation(string party, RevokeDelegationDTO delegationDTO)
{
return await _maskinportenSchemaClient.RevokeOfferedMaskinportenScopeDelegation(party, delegation);
return await _maskinportenSchemaClient.RevokeOfferedMaskinportenScopeDelegation(party, new RevokeOfferedDelegation(delegationDTO));
}

/// <inheritdoc />
Expand Down Expand Up @@ -90,7 +85,6 @@ public async Task<List<ApiDelegationOutput>> BatchCreateMaskinportenScopeDelegat
try
{
var response = await _maskinportenSchemaClient.CreateMaskinportenScopeDelegation(party, delegationObject);
string responseContent = await response.Content.ReadAsStringAsync();

delegationOutputs.Add(new ApiDelegationOutput()
{
Expand All @@ -99,9 +93,8 @@ public async Task<List<ApiDelegationOutput>> BatchCreateMaskinportenScopeDelegat
Success = response.StatusCode == System.Net.HttpStatusCode.Created
});
}
catch (Exception e)
catch
{
System.Diagnostics.Debug.WriteLine(e.Message);
delegationOutputs.Add(new ApiDelegationOutput()
{
OrgNumber = org,
Expand All @@ -121,42 +114,134 @@ public async Task<List<DelegationResponseData>> DelegationCheck(string partyId,
return await _maskinportenSchemaClient.MaskinportenSchemaDelegationCheck(partyId, request);
}

private async Task<List<MaskinportenSchemaDelegationFE>> BuildMaskinportenSchemaDelegationFE(List<MaskinportenSchemaDelegation> delegations, string languageCode)
/// <summary>
/// Revoke a batch of Maskinporten scope delegations.
/// </summary>
/// <param name="party">The party identifier.</param>
/// <param name="delegationDTOs">The list of delegation DTOs.</param>
/// <param name="type">The type of delegation.</param>
/// <returns>A list of tasks representing the HTTP response messages.</returns>
public async Task<List<RevokeApiDelegationOutput>> BatchRevokeMaskinportenScopeDelegation(string party, List<RevokeDelegationDTO> delegationDTOs, DelegationType type)
sonwit marked this conversation as resolved.
Show resolved Hide resolved
{
var responses = new List<RevokeApiDelegationOutput>();

if (type == DelegationType.Offered)
{
foreach (var delegation in delegationDTOs)
{
try
{
var response = await _maskinportenSchemaClient.RevokeOfferedMaskinportenScopeDelegation(party, new RevokeOfferedDelegation(delegation));
responses.Add(new RevokeApiDelegationOutput
{
OrgNumber = delegation.OrgNumber,
ApiId = delegation.ApiId,
Success = response.IsSuccessStatusCode,
});
}
catch
{
responses.Add(new RevokeApiDelegationOutput
{
OrgNumber = delegation.OrgNumber,
ApiId = delegation.ApiId,
Success = false
});
}
}
}
else
{
foreach (var delegation in delegationDTOs)
{
try
{
var res = await _maskinportenSchemaClient.RevokeReceivedMaskinportenScopeDelegation(party, new RevokeReceivedDelegation(delegation));
responses.Add(new RevokeApiDelegationOutput
{
OrgNumber = delegation.OrgNumber,
ApiId = delegation.ApiId,
Success = res.IsSuccessStatusCode,
});
}
catch
{
responses.Add(new RevokeApiDelegationOutput
{
OrgNumber = delegation.OrgNumber,
ApiId = delegation.ApiId,
Success = false
});
}
}
}

return responses;
}

/// <summary>
/// Builds a list of organization API sets for Maskinporten schema delegations.
/// </summary>
/// <param name="delegations">List of Maskinporten schema delegations.</param>
/// <param name="languageCode">Language code for localization.</param>
/// <param name="type">Type of delegation (Offered or Covered).</param>
/// <returns>A list of organization API sets.</returns>
/// <remarks>
/// This function processes a list of Maskinporten schema delegations and constructs a list of organization API sets.
/// It first retrieves the resources associated with the delegations. For each delegation, it creates an
/// ApiListItem object with localized resource details. It then determines the organization name and number based
/// on the delegation type. The function groups the API items by organization and returns the list of organization
/// API sets.
/// </remarks>
private async Task<List<OrganizationApiSet>> BuildMaskinportenSchemaDelegationFE(List<MaskinportenSchemaDelegation> delegations, string languageCode, DelegationType type)
{
List<string> resourceIds = delegations.Select(d => d.ResourceId).ToList();
List<ServiceResource> resources = await _resourceService.GetResources(resourceIds);

List<MaskinportenSchemaDelegationFE> result = new List<MaskinportenSchemaDelegationFE>();
List<OrganizationApiSet> overviewOrgList = new List<OrganizationApiSet>();

foreach (MaskinportenSchemaDelegation delegation in delegations)
{
MaskinportenSchemaDelegationFE delegationFE = new MaskinportenSchemaDelegationFE();
delegationFE.LanguageCode = languageCode;
delegationFE.OfferedByPartyId = delegation.OfferedByPartyId;
delegationFE.OfferedByOrganizationNumber = delegation.OfferedByOrganizationNumber;
delegationFE.OfferedByName = delegation.OfferedByName;
delegationFE.CoveredByPartyId = delegation.CoveredByPartyId;
delegationFE.CoveredByOrganizationNumber = delegation.CoveredByOrganizationNumber;
delegationFE.CoveredByName = delegation.CoveredByName;
delegationFE.PerformedByUserId = delegation.PerformedByUserId;
delegationFE.Created = delegation.Created;
delegationFE.ResourceId = delegation.ResourceId;
ServiceResource resource = resources.FirstOrDefault(r => r.Identifier == delegation.ResourceId);
if (resource != null)
var resource = resources.Find(r => r.Identifier == delegation.ResourceId);
if (resource == null)
{
delegationFE.ResourceTitle = resource.Title.GetValueOrDefault(languageCode, "nb");
delegationFE.ResourceType = resource.ResourceType;
delegationFE.ResourceOwnerOrgcode = resource.HasCompetentAuthority?.Orgcode;
delegationFE.ResourceOwnerOrgNumber = resource.HasCompetentAuthority?.Organization;
delegationFE.ResourceOwnerName = resource.HasCompetentAuthority?.Name.GetValueOrDefault(languageCode, "nb");
delegationFE.ResourceDescription = resource.Description.GetValueOrDefault(languageCode, "nb");
delegationFE.RightDescription = resource.RightDescription.GetValueOrDefault(languageCode, "nb");
delegationFE.ResourceReferences = resource.ResourceReferences;
continue;
}

result.Add(delegationFE);
var api = new ApiListItem
{
Id = delegation.ResourceId,
ApiName = resource.Title.GetValueOrDefault(languageCode, "nb"),
Owner = resource.HasCompetentAuthority?.Name.GetValueOrDefault(languageCode, "nb"),
Description = resource.RightDescription.GetValueOrDefault(languageCode, "nb"),
Scopes = resource.ResourceReferences?.Where(r => r.ReferenceType.Equals("MaskinportenScope")).Select(r => r.Reference).ToList() ?? new List<string>()
};

// Determine the organization name and number based on the delegation type.
// If the delegation type is 'Offered', use 'CoveredBy(...)'.
// Otherwise, use 'OfferedBy(...)'.
string delegationOrg = type == DelegationType.Offered ? delegation.CoveredByName : delegation.OfferedByName;
string delegationOrgNumber = type == DelegationType.Offered ? delegation.CoveredByOrganizationNumber : delegation.OfferedByOrganizationNumber;

var existingOrg = overviewOrgList.Find(org => org.Id == delegationOrg);
if (existingOrg != null)
{
existingOrg.ApiList.Add(api);
}
else
{
var newOrg = new OrganizationApiSet
{
Id = delegationOrg,
Name = delegationOrg,
OrgNumber = delegationOrgNumber,
ApiList = new List<ApiListItem> { api }
};
overviewOrgList.Add(newOrg);
}
}

return result;
return overviewOrgList;
}
}
}
}
Loading
Loading