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

feat: add support for access packages in policy editor #13921

Draft
wants to merge 42 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
674a216
access packages in policy editor WIP
mgunnerud Oct 3, 2024
e6bf5ed
Merge remote-tracking branch 'origin/main' into feat/13686-support-ac…
mgunnerud Oct 5, 2024
7c78ca7
show number of available packages in accordion heading
mgunnerud Oct 7, 2024
5637ef8
minor changes
mgunnerud Oct 7, 2024
d79fa21
add mock data to fix tests
mgunnerud Oct 7, 2024
19f5013
accessPackages are optional
mgunnerud Oct 7, 2024
451930f
accessPackages are optional
mgunnerud Oct 7, 2024
48de24f
Merge remote-tracking branch 'origin/main' into feat/13686-support-ac…
mgunnerud Oct 7, 2024
fbb1af5
move test code for access packages to backend
mgunnerud Oct 8, 2024
1f021a1
show services in use for each access package
mgunnerud Oct 9, 2024
3289c07
refactor access package hierarcy
mgunnerud Oct 10, 2024
0c047df
fix test data
mgunnerud Oct 10, 2024
f8e3056
show service owner in list of access package services
mgunnerud Oct 10, 2024
6dd588c
Merge remote-tracking branch 'origin/main' into feat/13686-support-ac…
mgunnerud Oct 19, 2024
76dcd78
add access package accordion
mgunnerud Oct 21, 2024
017ecd6
add accordions for access package + category icons
mgunnerud Oct 21, 2024
aaba8eb
minor changes + better testdata
mgunnerud Oct 21, 2024
f3aebd4
Merge remote-tracking branch 'origin/main' into feat/13686-support-ac…
mgunnerud Oct 22, 2024
68e7d39
show icon for resources in access package
mgunnerud Oct 23, 2024
c54461c
add test data
mgunnerud Oct 23, 2024
cc1e5ef
rollback change
mgunnerud Oct 23, 2024
7d05441
simplification
mgunnerud Oct 23, 2024
04b98d9
refactor
mgunnerud Oct 23, 2024
3dc3e72
add translations for access packages
mgunnerud Oct 23, 2024
b8ed9d1
accessibility improvements
mgunnerud Oct 23, 2024
b654d88
accesspackage can be in several categories
mgunnerud Oct 23, 2024
f3e91a3
replace category with tag
mgunnerud Oct 23, 2024
7c841d7
add tagGroup headings
mgunnerud Oct 23, 2024
94410a4
more testdata
mgunnerud Oct 23, 2024
36e7bdf
refactor after model change
mgunnerud Oct 24, 2024
b33411c
refactor variable name
mgunnerud Oct 24, 2024
261de72
refactor
mgunnerud Oct 24, 2024
03b1852
add tests for access packages in policy editor
mgunnerud Oct 25, 2024
04cad4e
dotnet format
mgunnerud Oct 25, 2024
4345d1d
Merge branch 'main' into feat/13686-support-access-packages-in-policy…
mgunnerud Oct 25, 2024
015d9d7
null check
mgunnerud Oct 25, 2024
471e8de
Merge branch 'feat/13686-support-access-packages-in-policy-editor-v1'…
mgunnerud Oct 25, 2024
e46058f
add feature flag for access packages
mgunnerud Oct 25, 2024
5f06c17
Merge branch 'main' into feat/13686-support-access-packages-in-policy…
mgunnerud Oct 25, 2024
888efe8
replace iconUrl with logoUrl
mgunnerud Oct 28, 2024
c947ac9
Merge branch 'feat/13686-support-access-packages-in-policy-editor-v1'…
mgunnerud Oct 28, 2024
a1d783f
add min-height to resources in access package row
mgunnerud Oct 28, 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
2 changes: 2 additions & 0 deletions backend/PolicyAdmin/Models/PolicyRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class PolicyRule

public List<string>? Subject { get; set; }

public List<string>? AccessPackages { get; set; }

public List<string>? Actions { get; set; }

public List<List<string>>? Resources { get; set; }
Expand Down
15 changes: 14 additions & 1 deletion backend/PolicyAdmin/PolicyConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public static ResourcePolicy ConvertPolicy(XacmlPolicy xacmlPolicy)
rule.Description = xr.Description;

rule.Subject = new List<string>();
rule.AccessPackages = new List<string>();
rule.Actions = new List<string>();
rule.Resources = new List<List<string>>();

Expand All @@ -31,7 +32,9 @@ public static ResourcePolicy ConvertPolicy(XacmlPolicy xacmlPolicy)
{
foreach (XacmlAllOf allOf in anyOf.AllOf)
{
List<string>? subject = GetRuleSubjects(allOf);
List<string>? subject = GetRuleSubjects(allOf)?.Where(x => !x.StartsWith("urn:altinn:accesspackage")).ToList();

List<string>? accessPackages = GetRuleSubjects(allOf)?.Where(x => x.StartsWith("urn:altinn:accesspackage")).ToList();

List<string>? resource = GetRuleResources(allOf);

Expand All @@ -42,6 +45,11 @@ public static ResourcePolicy ConvertPolicy(XacmlPolicy xacmlPolicy)
rule.Subject.AddRange(subject);
}

if (accessPackages != null)
{
rule.AccessPackages.AddRange(accessPackages);
}

if (action != null)
{
rule.Actions.AddRange(action);
Expand Down Expand Up @@ -195,6 +203,11 @@ private static XacmlRule ConvertRule(PolicyRule policyRule)
ruleAnyOfs.Add(GetSubjectAnyOfs(policyRule.Subject));
}

if (policyRule.AccessPackages != null && policyRule.AccessPackages.Count > 0)
{
ruleAnyOfs.Add(GetSubjectAnyOfs(policyRule.AccessPackages));
}

if (policyRule.Resources != null && policyRule.Resources.Count > 0)
{
ruleAnyOfs.Add(GetResourceAnyOfs(policyRule.Resources));
Expand Down
212 changes: 212 additions & 0 deletions backend/src/Designer/Controllers/ResourceAdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,218 @@ public async Task<ActionResult<List<EuroVocTerm>>> GetEuroVoc(CancellationToken
return sectors;
}

[HttpGet]
[Route("designer/api/{org}/resources/accesspackages")]
public async Task<ActionResult> GetAccessPackages(string org, CancellationToken cancellationToken)
{
// 1. GET accesspackages (mocked for now)
AccessPackageArea transportArea = new()
{
Id = "589217CF-6070-474F-9989-8C5359C740F4",
Name = "Transport og lagring",
Description = "Denne tilgangspakken er relevant for alle tjenester rettet mot virksomheter med aktivitet innen transport og lagring",
ShortDescription = "Tjenester rettet mot virksomheter med aktivitet innen transport og lagring",
IconName = "TruckIcon"
};
AccessPackageArea skattArea = new()
{
Id = "F52ADD40-6748-4E89-875A-63D3E153605D",
Name = "Skatt og Merverdiavgift",
Description = "Denne tilgangspakken er relevant for alle virksomheter som betaler eller rapporterer inn informasjon knyttet til skatt, avgift regnskap og toll",
ShortDescription = "Tjenester som angår skatt, avgift, regnskap og toll",
IconName = "BankNoteIcon"
};
AccessPackageArea jordbrukArea = new()
{
Id = "tag_jordbruk",
IconName = "PlantIcon",
ShortDescription = "Tjenester rettet mot virksomheter med aktivitet innen jordbruk, skogbruk, jakt, fiske og akvakultur",
Name = "Jordbruk, skogbruk, jakt, fiske og akvakultur",
Description = "Denne tilgangspakken er relevant for tjenester rettet mot virksomheter med aktivitet innen jordbruk, skogbruk, jakt, fiske og akvakultur.",
};
AccessPackageArea revisorArea = new()
{
Id = "tag_regnskapsforer",
IconName = "ReceiptIcon",
ShortDescription = "Tjenester som det er naturlig at en regnskapsfører utfører på vegne av sine kunder",
Name = "Regnskapsførere",
Description = "Denne fullmakten gir tilgang til alle tjenester som det er naturlig at en regnskapsfører utfører på vegne av sine kunder",
};

List<AccessPackage> accessPackages =
[
new()
{
Id = "urn:altinn:accesspackage:foretaksskatt",
Urn = "urn:altinn:accesspackage:foretaksskatt",
Name = "Foretaksskatt",
Description = "Denne tilgangspakken gir fullmakter til tjenester knyttet til skatt for foretak.",
Tags = [],
Area = skattArea
},
new()
{
Id = "urn:altinn:accesspackage:skattegrunnlag",
Urn = "urn:altinn:accesspackage:skattegrunnlag",
Name = "Skattegrunnlag",
Description = "Denne tilgangspakken gir fullmakter til tjenester knyttet til innhenting av skattegrunnlag.",
Tags = [],
Area = skattArea
},
new()
{
Id = "urn:altinn:accesspackage:merverdiavgift",
Urn = "urn:altinn:accesspackage:merverdiavgift",
Name = "Merverdiavgift",
Description = "Denne tilgangspakken gir fullmakter til tjenester knyttet til merverdiavgift.",
Tags = [],
Area = skattArea
},
new()
{
Id = "urn:altinn:accesspackage:sjofart",
Urn = "urn:altinn:accesspackage:sjofart",
Name = "Sjøfart",
Description = "Denne fullmakten gir tilgang til alle tjenester knyttet til skipsarbeidstakere og fartøy til sjøs.",
Tags = [],
Area = transportArea
},
new()
{
Id = "urn:altinn:accesspackage:lufttransport",
Urn = "urn:altinn:accesspackage:lufttransport",
Name = "Lufttransport",
Description = "Denne fullmakten gir tilgang til alle tjenester knyttet til luftfartøy og romfartøy.",
Tags = [],
Area = transportArea
},
new()
{
Id = "urn:altinn:accesspackage:jordbruk",
Urn = "urn:altinn:accesspackage:jordbruk",
Name = "Jordbruk",
Description = "Denne tilgangspakken gir tilgang til tjenester knyttet til jordbruk. Ved regelverksendringer eller innføring av nye digitale tjenester kan det bli endringer i tilganger som fullmakten gir",
Tags = [],
Area = jordbrukArea
},
new()
{
Id = "urn:altinn:accesspackage:fiske",
Urn = "urn:altinn:accesspackage:fiske",
Name = "Fiske",
Description = "Denne tilgangspakken gir fullmakter til tjenester knyttet til fiske. Ved regelverksendringer eller innføring av nye digitale tjenester kan det bli endringer i tilganger som fullmakten gir",
Tags = [],
Area = jordbrukArea
},
new()
{
Id = "urn:altinn:accesspackage:regnskapsforermedsigneringsrettighet",
Urn = "urn:altinn:accesspackage:regnskapsforermedsigneringsrettighet",
Name = "Regnskapsfører med signeringsrettighet",
Description = "Denne fullmakten gir tilgang til regnskapfører å kunne signere på vegne av kunden for alle tjenester som krever signeringsrett. Dette er tjenester som man har vurdert det som naturlig at en regnskapsfører utfører på vegne av sin kunde. Fullmakten gis kun til autoriserte regnskapsførere. Fullmakt hos regnskapfører oppstår når kunden registrerer regnskapsfører i Enhetsregisteret. Ved regelverksendringer eller innføring av nye digitale tjenester kan det bli endringer i tilganger som fullmakten gir.",
Tags = [],
Area = revisorArea
},
new()
{
Id = "urn:altinn:accesspackage:regnskapsforerutensigneringsrettighet",
Urn = "urn:altinn:accesspackage:regnskapsforerutensigneringsrettighet",
Name = "Regnskapsfører uten signeringsrettighet",
Description = "Denne fullmakten gir tilgang til å kunne utføre alle tjenester som ikke krever signeringsrett. Dette er tjenester som man har vurdert det som naturlig at en regnskapsfører utfører på vegne av sin kunde. Fullmakten gis kun til autoriserte regnskapsførere. Fullmakt hos regnskapfører oppstår når kunden registrerer regnskapsfører i Enhetsregisteret. Ved regelverksendringer eller innføring av nye digitale tjenester kan det bli endringer i tilganger som fullmakten gir.",
Tags = [],
Area = revisorArea
},
new()
{
Id = "urn:altinn:accesspackage:regnskapsforerlonn",
Urn = "urn:altinn:accesspackage:regnskapsforerlonn",
Name = "Regnskapsfører lønn",
Description = "Denne fullmakten gir tilgang til regnskapsfører å rapportere lønn for sin kunde. Dette er tjenester som man har vurdert det som naturlig at en regnskapsfører utfører på vegne av sin kunde. Fullmakten gis kun til autoriserte regnskapsførere. Fullmakt hos regnskapfører oppstår når kunden registrerer regnskapsfører i Enhetsregisteret. Ved regelverksendringer eller innføring av nye digitale tjenester kan det bli endringer i tilganger som fullmakten gir.",
Tags = [],
Area = revisorArea
}
];

string env = "tt02";
IEnumerable<string> subjects = accessPackages.Select(accessPackage => accessPackage.Urn);

OrgList orgList = await GetOrgList();

// 2. POST to get all resources per access package
List<SubjectResources> subjectResources = await _resourceRegistry.GetSubjectResources(subjects.ToList(), env);
subjectResources.Add(new SubjectResources()
{
Subject = new AttributeMatchV2()
{
Type = "",
Value = "",
Urn = "urn:altinn:accesspackage:regnskapsforerlonn"
},
Resources = new List<AttributeMatchV2>() {
new AttributeMatchV2() {
Type = "",
Value = "brg-maskinportenschemaid-5",
Urn = ""
},
new AttributeMatchV2() {
Type = "",
Value = "mat-maskinportenschemaid-54",
Urn = ""
},
new AttributeMatchV2() {
Type = "",
Value = "skd-maskinportenschemaid-32",
Urn = ""
},
new AttributeMatchV2() {
Type = "",
Value = "slk-maskinportenschemaid-81",
Urn = ""
},
new AttributeMatchV2() {
Type = "",
Value = "nav-maskinportenschemaid-141",
Urn = ""
},
new AttributeMatchV2() {
Type = "",
Value = "svv-maskinportenschemaid-249",
Urn = ""
}
}
});

// 3. GET full list of resources
List<ServiceResource> environmentResources = await _resourceRegistry.GetResourceList(env, false);

// 4. map resource to access package based on data from step 2.
accessPackages.ForEach(accessPackage =>
{
List<AttributeMatchV2> resources = subjectResources.Find(x => x.Subject.Urn == accessPackage.Urn)?.Resources;

resources?.ForEach(resourceMatch =>
{
ServiceResource fullResource = environmentResources.Find(x => x.Identifier == resourceMatch.Value);

if (fullResource != null)
{
orgList.Orgs.TryGetValue(fullResource.HasCompetentAuthority.Orgcode.ToLower(), out Org organization);

accessPackage.Services.Add(new AccessPackageService()
{
Identifier = resourceMatch.Value,
Title = fullResource?.Title,
HasCompetentAuthority = fullResource.HasCompetentAuthority,
LogoUrl = organization.Logo
});
}

});
});

return Ok(accessPackages);
}

[HttpGet]
[Route("designer/api/{org}/resources/altinn2linkservices/{env}")]
public async Task<ActionResult<List<AvailableService>>> GetAltinn2LinkServices(string org, string env)
Expand Down
23 changes: 23 additions & 0 deletions backend/src/Designer/Models/AccessPackage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#nullable enable

using System.Collections.Generic;

namespace Altinn.Studio.Designer.Models
{
public class AccessPackage
{
public required string Id { get; set; }

public required string Urn { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public List<AccessPackageTag> Tags { get; set; } = [];

public AccessPackageArea Area { get; set; }

public List<AccessPackageService> Services { get; set; } = [];
}
}
17 changes: 17 additions & 0 deletions backend/src/Designer/Models/AccessPackageArea.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#nullable enable

namespace Altinn.Studio.Designer.Models
{
public class AccessPackageArea
{
public required string Id { get; set; }

public string Name { get; set; }

Check warning on line 9 in backend/src/Designer/Models/AccessPackageArea.cs

View workflow job for this annotation

GitHub Actions / Run integration tests against actual gitea and db

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public string Description { get; set; }

public string ShortDescription { get; set; }

public string IconName { get; set; }
}
}
15 changes: 15 additions & 0 deletions backend/src/Designer/Models/AccessPackageService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;

namespace Altinn.Studio.Designer.Models
{
public class AccessPackageService
{
public string Identifier { get; set; }

public Dictionary<string, string> Title { get; set; }

public CompetentAuthority HasCompetentAuthority { get; set; }

public string LogoUrl { get; set; }
}
}
11 changes: 11 additions & 0 deletions backend/src/Designer/Models/AccessPackageTag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#nullable enable

namespace Altinn.Studio.Designer.Models
{
public class AccessPackageTag
{
public required string Id { get; set; }

public string Name { get; set; }
}
}
28 changes: 28 additions & 0 deletions backend/src/Designer/Models/AttributeMatchV2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations;

namespace Altinn.Studio.Designer.Models
{
/// <summary>
/// This model describes a pair of AttributeId and AttributeValue for use in matching in XACML policies, for instance a resource, a user, a party or an action.
/// </summary>
public class AttributeMatchV2
{
/// <summary>
/// Gets or sets the attribute id for the match
/// </summary>
[Required]
public required string Type { get; set; }

/// <summary>
/// Gets or sets the attribute value for the match
/// </summary>
[Required]
public required string Value { get; set; }

/// <summary>
/// The urn for the attribute
/// </summary>
[Required]
public required string Urn { get; set; }
}
}
9 changes: 9 additions & 0 deletions backend/src/Designer/Models/Dto/SubjectResourcesDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace Altinn.Studio.Designer.Models.Dto
{
public class SubjectResourcesDto
{
public List<SubjectResources> Data { get; set; }
}
}
Loading
Loading