Skip to content

Commit

Permalink
Feat/ny brukerflate/1035 enkelttjenester på brukerside (#1064)
Browse files Browse the repository at this point in the history
* Add single rights section to user access page

* chore: Adjust font sizes in SingleRightsSection.module.css

* chore: Implement GetSingleRightsForRightholder method in SingleRightService

* chore: Add GetSingleRightsForUser test case to SingleRightControllerTest

* map to frontend on getting resources

* Adjust SingleRightsSection styling and add pagination

* lint fix

* Add test case for GetSingleRightsForUser handling error

* add case in test-data

* Refactor AccessManagementClient.cs to handle getting single rights for a rightholder

- Updated the GetSingleRightsForRightholder method in AccessManagementClient.cs to use a temporary endpoint URL until the actual backend endpoint is available
- Added error handling for unexpected response status from Access Management
- Implemented a placeholder method for revoking single rights delegation in AccessManagementClient.cs
- Made necessary changes in AccessManagementClientMock.cs to match the changes in AccessManagementClient.cs

* Refactor logging message in SingleRightController.cs

* Refactor AccessManagementClient.cs to remove unused method

* Refactor SingleRightService.cs to improve resource retrieval

* Refactor SingleRightController.cs to remove unnecessary null check

* Refactor SingleRightService.cs to handle getting single rights for a rightholder

* lint

* Refactor SingleRightService.cs to remove unnecessary whitespace

* single rights title in en.json

* Refactor SingleRightControllerTest.cs to use AssertionUtil for comparing expected and actual responses

* Refactor usePagination.ts to optimize pagination logic

* Refactor CSS to add min-height to SingleRightsSection
  • Loading branch information
sonwit authored Sep 12, 2024
1 parent e384fc7 commit 028cb6b
Show file tree
Hide file tree
Showing 39 changed files with 3,022 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,13 @@ public interface IAccessManagementClient
/// </param>
/// <returns></returns>
Task<HttpResponseMessage> CreateSingleRightsDelegation(string party, DelegationInput delegation);

/// <summary>
/// Retrieves the single rights for a specific right holder.
/// </summary>
/// <param name="party">The party identifier.</param>
/// <param name="userId">The user identifier.</param>
/// <returns></returns>
Task<HttpResponseMessage> GetSingleRightsForRightholder(string party, string userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Altinn.AccessManagement.UI.Core.Enums
/// <summary>
/// Enum for the different reference sources for resources in the resource registry
/// </summary>
public enum ReferenceSource : int
public enum ReferenceSource
{
/// <summary>
/// Default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Altinn.AccessManagement.UI.Core.Models;
using Altinn.AccessManagement.UI.Core.Models.ResourceRegistry.Frontend;
using Altinn.AccessManagement.UI.Core.Models.SingleRight;
using Altinn.AccessManagement.UI.Core.Models.SingleRight.CheckDelegationAccess;

Expand Down Expand Up @@ -42,5 +43,20 @@ public interface ISingleRightService
/// </param>
/// <returns></returns>
Task<HttpResponseMessage> ClearAccessCacheOnRecipient(string party, BaseAttribute recipient);

/// <summary>
/// Gets the single-rights for a given rightholder
/// </summary>
/// <param name="languageCode">
/// The language code for the request
/// </param>
/// <param name="party">
/// The party from which the rights have been given (delegator)
/// </param>
/// <param name="userId">
/// The user id of the rightholder
/// </param>
/// <returns></returns>
Task<List<ServiceResourceFE>> GetSingleRightsForRightholder(string languageCode, string party, string userId);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Text.Json;
using Altinn.AccessManagement.UI.Core.ClientInterfaces;
using Altinn.AccessManagement.UI.Core.Models;
using Altinn.AccessManagement.UI.Core.Models.SingleRight;
using Altinn.AccessManagement.UI.Core.Models.SingleRight.CheckDelegationAccess;
using Altinn.AccessManagement.UI.Core.Models.ResourceRegistry.Frontend;
using Altinn.AccessManagement.UI.Core.Services.Interfaces;

namespace Altinn.AccessManagement.UI.Core.Services
Expand All @@ -10,13 +10,20 @@ namespace Altinn.AccessManagement.UI.Core.Services
public class SingleRightService : ISingleRightService
{
private readonly IAccessManagementClient _accessManagementClient;
private readonly IResourceService _resourceService;

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

/// <summary>
/// Initializes a new instance of the <see cref="SingleRightService" /> class.
/// </summary>
public SingleRightService(IAccessManagementClient accessManagementClient)
public SingleRightService(IAccessManagementClient accessManagementClient, IResourceService resourceService)
{
_accessManagementClient = accessManagementClient;
_resourceService = resourceService;
}

/// <inheritdoc />
Expand All @@ -36,5 +43,42 @@ public async Task<HttpResponseMessage> ClearAccessCacheOnRecipient(string party,
{
return await _accessManagementClient.ClearAccessCacheOnRecipient(party, recipient);
}

/// <inheritdoc />
public async Task<List<ServiceResourceFE>> GetSingleRightsForRightholder(string languageCode, string party, string userId)
{
var res = await _accessManagementClient.GetSingleRightsForRightholder(party, userId);
var results = await res.Content.ReadAsStringAsync();

var delegationOutput = JsonSerializer.Deserialize<List<DelegationOutput>>(results, options);
List<ServiceResourceFE> serviceResourceFE = new List<ServiceResourceFE>();
foreach (var item in delegationOutput)
{
var resourceId = item.RightDelegationResults?.FirstOrDefault()?.Resource?.FirstOrDefault()?.Value;
if (string.IsNullOrEmpty(resourceId))
{
continue;
}

var resource = await _resourceService.GetResource(resourceId);
serviceResourceFE.Add(new ServiceResourceFE(
resource.Identifier,
resource.Title?.GetValueOrDefault(languageCode) ?? resource.Title?.GetValueOrDefault("nb"),
resourceType: resource.ResourceType,
status: resource.Status,
resourceReferences: resource.ResourceReferences,
resourceOwnerName: resource.HasCompetentAuthority?.Name?.GetValueOrDefault(languageCode) ?? resource.HasCompetentAuthority?.Name?.GetValueOrDefault("nb"),
resourceOwnerOrgNumber: resource.HasCompetentAuthority?.Organization,
rightDescription: resource.RightDescription?.GetValueOrDefault(languageCode) ?? resource.RightDescription?.GetValueOrDefault("nb"),
description: resource.Description?.GetValueOrDefault(languageCode) ?? resource.Description?.GetValueOrDefault("nb"),
visible: resource.Visible,
delegable: resource.Delegable,
contactPoints: resource.ContactPoints,
spatial: resource.Spatial,
authorizationReference: resource.AuthorizationReference));
}

return serviceResourceFE;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,5 +263,22 @@ public async Task<HttpResponseMessage> CreateSingleRightsDelegation(string party
HttpResponseMessage response = await _client.PostAsync(token, endpointUrl, requestBody);
return response;
}

/// <inheritdoc />
public async Task<HttpResponseMessage> GetSingleRightsForRightholder(string party, string userId)
{
string endpointUrl = $"todo/{party}/{userId}"; // TODO: Switch with actual backend endpoint when available
string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _platformSettings.JwtCookieName);

HttpResponseMessage response = await _client.GetAsync(token, endpointUrl);

if (response.StatusCode == HttpStatusCode.OK)
{
return response;
}

_logger.LogError("Getting single rights from accessmanagement failed with {StatusCode}", response.StatusCode);
throw new HttpStatusException("StatusError", "Unexpected response status from Access Management", response.StatusCode, Activity.Current?.Id ?? _httpContextAccessor.HttpContext?.TraceIdentifier);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"title": {
"en": "A3 app",
"nb": "A3 app",
"nn": "A3 app"
},
"sector": null,
"status": null,
"limitedByRRR": false,
"SelfIdentifiedUserEnabled": false,
"EnterpriseUserEnabled": false,
"homepage": null,
"isPartOf": null,
"keywords": null,
"identifier": "app_ttd_a3-app",
"contactPoints": [
{
"category": "Some category",
"email": "email@someemaildigdir.no",
"telephone": "12345678",
"contactPage": "Some page (webpage maybe?)"
}
],
"visible": true,
"delegable": true,
"description": {
"en": "An Altinn 3 app",
"nb": "En Altinn 3 app",
"nn": "En Altinn 3 app"
},
"resourceType": "AltinnApp",
"thematicArea": null,
"isPublicService": true,
"rightDescription": {
"en": "Gives access an A3 app.",
"nb": "Gir tilgang til en A3 app.",
"nn": "Gir tilgang til en A3 app."
},
"resourceReferences": [
{
"referenceSource": "Altinn3",
"reference": "ttd/a3-app",
"referenceType": "ApplicationId"
}
],
"authorizationReference": [
{
"id": "urn:altinn:app",
"value": "a3-app"
},
{
"id": "urn:altinn:org",
"value": "ttd"
}
],
"hasCompetentAuthority": {
"orgcode": "TTD",
"organization": "123456789",
"name": {
"en": "Testdepartementet",
"nb": "Testdepartementet",
"nn": "Testdepartementet"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"title": {
"en": "A3 app 2",
"nb": "A3 app 2",
"nn": "A3 app 2"
},
"sector": null,
"status": null,
"limitedByRRR": false,
"SelfIdentifiedUserEnabled": false,
"EnterpriseUserEnabled": false,
"homepage": null,
"isPartOf": null,
"keywords": null,
"identifier": "app_ttd_a3-app2",
"contactPoints": [
{
"category": "Some category",
"email": "email@someemaildigdir.no",
"telephone": "12345678",
"contactPage": "Some page (webpage maybe?)"
}
],
"visible": true,
"delegable": true,
"description": {
"en": "An Altinn 3 app",
"nb": "En Altinn 3 app",
"nn": "En Altinn 3 app"
},
"resourceType": "AltinnApp",
"thematicArea": null,
"isPublicService": true,
"rightDescription": {
"en": "Gives access an A3 app.",
"nb": "Gir tilgang til en A3 app.",
"nn": "Gir tilgang til en A3 app."
},
"resourceReferences": [
{
"referenceSource": "Altinn3",
"reference": "ttd/a3-app2",
"referenceType": "ApplicationId"
}
],
"authorizationReference": [
{
"id": "urn:altinn:app",
"value": "a3-app2"
},
{
"id": "urn:altinn:org",
"value": "ttd"
}
],
"hasCompetentAuthority": {
"orgcode": "TTD",
"organization": "123456789",
"name": {
"en": "Testdepartementet",
"nb": "Testdepartementet",
"nn": "Testdepartementet"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"title": {
"en": "Automation Regression",
"nb": "Automation Regression",
"nn": "Automation Regression"
},
"sector": null,
"status": null,
"limitedByRRR": false,
"SelfIdentifiedUserEnabled": false,
"EnterpriseUserEnabled": false,
"homepage": null,
"isPartOf": null,
"keywords": null,
"identifier": "appid-136",
"contactPoints": [
{
"category": "Some category",
"email": "email@someemaildigdir.no",
"telephone": "12345678",
"contactPage": "Some page (webpage maybe?)"
}
],
"description": null,
"resourceType": "MaskinportenSchema",
"thematicArea": null,
"isPublicService": true,
"rightDescription": {
"en": "Allows you to test maskinporten changes as part of automation testing",
"nb": "Gir anledning til a teste maskinporten som en del av automatiserte tester",
"nn": "Gjer hove til a teste maskinporten som en del av automatiserte tester"
},
"resourceReferences": [
{
"reference": "911f9e93-1541-429d-a8c6-a06f9a52d827",
"referenceType": "DelegationSchemeId",
"referenceSource": "Altinn2"
},
{
"reference": "altinn:test/theworld.write",
"referenceType": "MaskinportenScope",
"referenceSource": "Altinn2"
},
{
"reference": "altinn:test/theworld.admin",
"referenceType": "MaskinportenScope",
"referenceSource": "Altinn2"
},
{
"reference": "AppId:136",
"referenceType": "ServiceCode",
"referenceSource": "Altinn2"
},
{
"reference": "1",
"referenceType": "ServiceEditionCode",
"referenceSource": "Altinn2"
}
],
"authorizationReference": [
{
"id": "urn:altinn:resource",
"value": "appid-136"
}
],
"hasCompetentAuthority": {
"orgcode": "SKD",
"organization": "974761076",
"name": {
"en": "Skatteetaten",
"nb": "Skatteetaten",
"nn": "Skatteetaten"
}
}
}
Loading

0 comments on commit 028cb6b

Please sign in to comment.