From b0839f1e24b2afdf7342722dbe0d73b82567f037 Mon Sep 17 00:00:00 2001 From: jonkjetiloye <40996230+jonkjetiloye@users.noreply.github.com> Date: Tue, 3 Oct 2023 08:33:36 +0200 Subject: [PATCH] Integrate PDP with OED as external authorization source (#474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Integrate PDP with OED as external authorization source #343 - Added new OedAuthzClient for integration with the oed-authz API - Added new dependency to Altinn.ApiClients.Maskinporten v9.0.0 - Added new OedAuthzMaskinportenClientDefinition and Configuration - Added new OedRoleAssignmentWrapper service - Added new SBL bridge API client and service for getting SSN from UserId and PartyId Other relevant changes: - ContextHandler will now retrieve and evaluate policy for the App or Resource and evaluate the subjects of the rules. If any 'urn:altinn:rolecode' subjects are found Altinn roles will be retrieved. If any 'urn:oed:rolecode' subjects are found OED roles will be retrieved. Additional PR made for studio-ops repo for both new (Maskinporten client config) and changes existing to configuration values (SBL bridge API path) * Update for PR comments * Added caching for getting the subjects from the policy * NB!: This will change will fail until ABAC project is updated with the new helper on XacmlPolicy for getting attribute values by category. - Changed some references from OED to Digitalt Dødsbo to match new naming - Renamed "urn:oed:rolecode" attributeId to "urn:digitaltdodsbo:rolecode" - Logic for extracting AttributeIds and Values reimplemented as a generic helper method on the XacmlPolicy object in ABAC project * Fix datatype returned by XacmlPolicy * Update ABAC package version to 0.0.6 * Marked OedRoleAssignmentWrapper excluded from codecoverage as integration tests rely on mock implementation * removed quotes character from log statement --------- Co-authored-by: Jon Kjetil Øye --- .../Altinn.Platform.Authorization.csproj | 3 +- src/Authorization/Clients/OedAuthzClient.cs | 47 +++++++ .../OedAuthzMaskinportenClientDefinition.cs | 36 +++++ src/Authorization/Clients/ProfileClient.cs | 34 +++++ .../Configuration/GeneralSettings.cs | 5 + .../OedAuthzMaskinportenClientSettings.cs | 61 +++++++++ .../Constants/AltinnXacmlConstants.cs | 5 + .../Constants/XacmlRequestAttribute.cs | 5 + src/Authorization/Helpers/PolicyHelper.cs | 2 +- .../Models/Oed/OedRoleAssignment.cs | 32 +++++ .../Models/Oed/OedRoleAssignmentRequest.cs | 18 +++ .../Models/Oed/OedRoleAssignments.cs | 16 +++ src/Authorization/Program.cs | 13 +- .../Services/Implementation/ContextHandler.cs | 127 +++++++++++++++++- .../DelegationContextHandler.cs | 7 +- .../OedRoleAssignmentWrapper.cs | 86 ++++++++++++ .../Services/Implementation/PartiesWrapper.cs | 34 ++++- .../Services/Implementation/ProfileWrapper.cs | 60 +++++++++ .../Services/Implementation/RolesWrapper.cs | 2 +- .../Interface/IOedRoleAssignmentWrapper.cs | 20 +++ .../Services/Interface/IParties.cs | 7 + .../Services/Interface/IProfile.cs | 18 +++ src/Authorization/appsettings.json | 11 +- ...form.Authorization.IntegrationTests.csproj | 45 +++++++ .../AltinnApps_DecisionTests.cs | 32 +++++ test/IntegrationTests/ContextHandlerTest.cs | 17 ++- .../eb0d2b21-fef9-4b85-9985-c4ba271c4678.json | 30 +++++ .../3.0/AltinnApps/AltinnApps0021Policy.xml | 110 +++++++++++++++ .../3.0/AltinnApps/AltinnApps0024Policy.xml | 110 +++++++++++++++ .../3.0/AltinnApps/AltinnApps0025Policy.xml | 110 +++++++++++++++ ...s_OedFormuesfullmakt_Json_PermitPolicy.xml | 50 +++++++ ...OedFormuesfullmakt_Json_PermitRequest.json | 36 +++++ ...edFormuesfullmakt_Json_PermitResponse.json | 39 ++++++ ...ps_OedFormuesfullmakt_Xml_PermitPolicy.xml | 50 +++++++ ...s_OedFormuesfullmakt_Xml_PermitRequest.xml | 19 +++ ..._OedFormuesfullmakt_Xml_PermitResponse.xml | 28 ++++ ...uesfullmakt_Json_IndeterminateRequest.json | 40 ++++++ ...esfullmakt_Json_IndeterminateResponse.json | 19 +++ ...OedFormuesfullmakt_Json_PermitRequest.json | 40 ++++++ ...edFormuesfullmakt_Json_PermitResponse.json | 32 +++++ ...rmuesfullmakt_Xml_IndeterminateRequest.xml | 22 +++ ...muesfullmakt_Xml_IndeterminateResponse.xml | Bin 0 -> 1324 bytes ...y_OedFormuesfullmakt_Xml_PermitRequest.xml | 22 +++ ..._OedFormuesfullmakt_Xml_PermitResponse.xml | Bin 0 -> 2028 bytes .../oed-role-formuesfullmakt/policy.xml | 46 +++++++ .../OedRoleAssignmentWrapperMock.cs | 29 ++++ .../MockServices/PartiesMock.cs | 11 ++ .../MockServices/ProfileMock.cs | 26 ++++ .../ResourceRegistry_DecisionTests.cs | 64 ++++++++- 49 files changed, 1658 insertions(+), 18 deletions(-) create mode 100644 src/Authorization/Clients/OedAuthzClient.cs create mode 100644 src/Authorization/Clients/OedAuthzMaskinportenClientDefinition.cs create mode 100644 src/Authorization/Clients/ProfileClient.cs create mode 100644 src/Authorization/Configuration/OedAuthzMaskinportenClientSettings.cs create mode 100644 src/Authorization/Models/Oed/OedRoleAssignment.cs create mode 100644 src/Authorization/Models/Oed/OedRoleAssignmentRequest.cs create mode 100644 src/Authorization/Models/Oed/OedRoleAssignments.cs create mode 100644 src/Authorization/Services/Implementation/OedRoleAssignmentWrapper.cs create mode 100644 src/Authorization/Services/Implementation/ProfileWrapper.cs create mode 100644 src/Authorization/Services/Interface/IOedRoleAssignmentWrapper.cs create mode 100644 src/Authorization/Services/Interface/IProfile.cs create mode 100644 test/IntegrationTests/Data/Instances/50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0021Policy.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0024Policy.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0025Policy.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitPolicy.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitRequest.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitResponse.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitPolicy.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitRequest.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitResponse.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateRequest.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateResponse.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitRequest.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitResponse.json create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateRequest.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateResponse.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_PermitRequest.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_PermitResponse.xml create mode 100644 test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/oed-role-formuesfullmakt/policy.xml create mode 100644 test/IntegrationTests/MockServices/OedRoleAssignmentWrapperMock.cs create mode 100644 test/IntegrationTests/MockServices/ProfileMock.cs diff --git a/src/Authorization/Altinn.Platform.Authorization.csproj b/src/Authorization/Altinn.Platform.Authorization.csproj index 06622ccd..48b90739 100644 --- a/src/Authorization/Altinn.Platform.Authorization.csproj +++ b/src/Authorization/Altinn.Platform.Authorization.csproj @@ -7,6 +7,7 @@ + @@ -15,7 +16,7 @@ - + diff --git a/src/Authorization/Clients/OedAuthzClient.cs b/src/Authorization/Clients/OedAuthzClient.cs new file mode 100644 index 00000000..f1560c45 --- /dev/null +++ b/src/Authorization/Clients/OedAuthzClient.cs @@ -0,0 +1,47 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Altinn.Platform.Authorization.Configuration; +using Microsoft.Extensions.Options; + +namespace Altinn.Platform.Authorization.Clients +{ + /// + /// Client configuration for Oed Authz API integration + /// + public class OedAuthzClient + { + /// + /// Gets an instance of httpclient from httpclientfactory + /// + public HttpClient Client { get; } + + /// + /// Initializes the http client for retrieving Oed Authz role-assignments + /// + /// the http client + /// the general settings configured for the authorization component + public OedAuthzClient(HttpClient client, IOptions settings) + { + GeneralSettings generalSettings = settings.Value; + Client = client; + Client.BaseAddress = new Uri(generalSettings.OedAuthzApiEndpoint); + Client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + } + + /// + /// post request that gets OED roleassignments + /// + /// the request body + /// the bearer token + /// A representing the result of the asynchronous operation. + public async Task GetOedRoleAssignments(StringContent requestBody, AuthenticationHeaderValue token) + { + Client.DefaultRequestHeaders.Authorization = token; + string endpoint = Client.BaseAddress + "v1/pip"; + return await Client.PostAsync(endpoint, requestBody); + } + } +} diff --git a/src/Authorization/Clients/OedAuthzMaskinportenClientDefinition.cs b/src/Authorization/Clients/OedAuthzMaskinportenClientDefinition.cs new file mode 100644 index 00000000..bf81a4e0 --- /dev/null +++ b/src/Authorization/Clients/OedAuthzMaskinportenClientDefinition.cs @@ -0,0 +1,36 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using Altinn.ApiClients.Maskinporten.Interfaces; +using Altinn.ApiClients.Maskinporten.Models; +using Altinn.Platform.Authorization.Configuration; +using Microsoft.Extensions.Options; + +namespace Altinn.Platform.Authorization.Clients +{ + /// + /// Maskinporten client definition for OED Authz API integration + /// + public class OedAuthzMaskinportenClientDefinition : IClientDefinition + { + /// + public IMaskinportenSettings ClientSettings { get; set; } + + /// + /// Initializes a new instance of the class + /// + /// Maskinporten client settings + public OedAuthzMaskinportenClientDefinition(IOptions clientSettings) => ClientSettings = clientSettings.Value; + + /// + public Task GetClientSecrets() + { + ClientSecrets clientSecrets = new ClientSecrets(); + + byte[] bytesFromBase64Jwk = Convert.FromBase64String(ClientSettings.EncodedJwk); + string jwkJson = Encoding.UTF8.GetString(bytesFromBase64Jwk); + clientSecrets.ClientKey = new Microsoft.IdentityModel.Tokens.JsonWebKey(jwkJson); + return Task.FromResult(clientSecrets); + } + } +} \ No newline at end of file diff --git a/src/Authorization/Clients/ProfileClient.cs b/src/Authorization/Clients/ProfileClient.cs new file mode 100644 index 00000000..748edb0c --- /dev/null +++ b/src/Authorization/Clients/ProfileClient.cs @@ -0,0 +1,34 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using Altinn.Platform.Authorization.Configuration; +using Microsoft.Extensions.Options; + +namespace Altinn.Platform.Authorization.Clients +{ + /// + /// Client configuration for profile api + /// + public class ProfileClient + { + /// + /// Gets an instance of httpclient from httpclientfactory + /// + public HttpClient Client { get; } + + /// + /// Initializes the http client for actor + /// + /// the http client + /// the general settings configured for the authorization component + public ProfileClient(HttpClient client, IOptions generalSettings) + { + GeneralSettings settings = generalSettings.Value; + Client = client; + Client.BaseAddress = new Uri(settings.GetBridgeApiEndpoint); + Client.Timeout = new TimeSpan(0, 0, 30); + Client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + } + } +} diff --git a/src/Authorization/Configuration/GeneralSettings.cs b/src/Authorization/Configuration/GeneralSettings.cs index 54f54735..75c75398 100644 --- a/src/Authorization/Configuration/GeneralSettings.cs +++ b/src/Authorization/Configuration/GeneralSettings.cs @@ -61,6 +61,11 @@ public string GetBridgeApiEndpoint /// public string OpenIdWellKnownEndpoint { get; set; } + /// + /// Gets or sets the OED api endpoint + /// + public string OedAuthzApiEndpoint { get; set; } + /// /// Gets the SBL base adress from kubernetes environment variables and appsettings if environment variable is not set /// diff --git a/src/Authorization/Configuration/OedAuthzMaskinportenClientSettings.cs b/src/Authorization/Configuration/OedAuthzMaskinportenClientSettings.cs new file mode 100644 index 00000000..67664388 --- /dev/null +++ b/src/Authorization/Configuration/OedAuthzMaskinportenClientSettings.cs @@ -0,0 +1,61 @@ +using Altinn.ApiClients.Maskinporten.Interfaces; + +namespace Altinn.Platform.Authorization.Configuration +{ + /// + /// Configuration for Maskinporten Client for Oed role-assignments API integration + /// + public class OedAuthzMaskinportenClientSettings : IMaskinportenSettings + { + /// + public string Environment { get; set; } + + /// + public string ClientId { get; set; } + + /// + public string Scope { get; set; } + + /// + public string EncodedJwk { get; set; } + + /// + public string Resource { get; set; } + + /// + public string CertificatePkcs12Path { get; set; } + + /// + public string CertificatePkcs12Password { get; set; } + + /// + public string CertificateStoreThumbprint { get; set; } + + /// + public string EncodedX509 { get; set; } + + /// + public string ConsumerOrgNo { get; set; } + + /// + public string EnterpriseUserName { get; set; } + + /// + public string EnterpriseUserPassword { get; set; } + + /// + public bool? ExhangeToAltinnToken { get; set; } + + /// + public string TokenExchangeEnvironment { get; set; } + + /// + public bool? UseAltinnTestOrg { get; set; } + + /// + public bool? EnableDebugLogging { get; set; } + + /// + public bool? OverwriteAuthorizationHeader { get; set; } + } +} \ No newline at end of file diff --git a/src/Authorization/Constants/AltinnXacmlConstants.cs b/src/Authorization/Constants/AltinnXacmlConstants.cs index 27b6b6cc..1184c486 100644 --- a/src/Authorization/Constants/AltinnXacmlConstants.cs +++ b/src/Authorization/Constants/AltinnXacmlConstants.cs @@ -80,6 +80,11 @@ public static class MatchAttributeIdentifiers /// Role Code attribute match indentifier /// public const string RoleAttribute = "urn:altinn:rolecode"; + + /// + /// Digitalt Dødsbo Role Code Attribute match identifier + /// + public const string OedRoleAttribute = "urn:digitaltdodsbo:rolecode"; } /// diff --git a/src/Authorization/Constants/XacmlRequestAttribute.cs b/src/Authorization/Constants/XacmlRequestAttribute.cs index 5dfd2c88..c294c53b 100644 --- a/src/Authorization/Constants/XacmlRequestAttribute.cs +++ b/src/Authorization/Constants/XacmlRequestAttribute.cs @@ -55,6 +55,11 @@ public static class XacmlRequestAttribute /// public const string RoleAttribute = "urn:altinn:rolecode"; + /// + /// Digitalt Dødsbo Role Code Attribute match identifier + /// + public const string OedRoleAttribute = "urn:digitaltdodsbo:rolecode"; + /// /// xacml string that represents resource /// diff --git a/src/Authorization/Helpers/PolicyHelper.cs b/src/Authorization/Helpers/PolicyHelper.cs index feeddde4..e38a201f 100644 --- a/src/Authorization/Helpers/PolicyHelper.cs +++ b/src/Authorization/Helpers/PolicyHelper.cs @@ -1,6 +1,6 @@ using System; -using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; diff --git a/src/Authorization/Models/Oed/OedRoleAssignment.cs b/src/Authorization/Models/Oed/OedRoleAssignment.cs new file mode 100644 index 00000000..9cf20034 --- /dev/null +++ b/src/Authorization/Models/Oed/OedRoleAssignment.cs @@ -0,0 +1,32 @@ +using System; +using System.Text.Json.Serialization; + +namespace Altinn.Platform.Authorization.Models.Oed +{ + /// + /// Model for OED role assignment + /// + public class OedRoleAssignment + { + /// + /// The OED/Digitalt dødsbo role code + /// + [JsonPropertyName("urn:digitaltdodsbo:rolecode")] + public string OedRoleCode { get; set; } + + /// + /// The deceased person's pid + /// + public string From { get; set; } + + /// + /// The inheriting person's pid + /// + public string To { get; set; } + + /// + /// The datetime created + /// + public DateTime Created { get; set; } + } +} \ No newline at end of file diff --git a/src/Authorization/Models/Oed/OedRoleAssignmentRequest.cs b/src/Authorization/Models/Oed/OedRoleAssignmentRequest.cs new file mode 100644 index 00000000..b084f091 --- /dev/null +++ b/src/Authorization/Models/Oed/OedRoleAssignmentRequest.cs @@ -0,0 +1,18 @@ +namespace Altinn.Platform.Authorization.Models +{ + /// + /// Model for requesting OED/Digitalt dødsbo role assignments between two persons + /// + public class OedRoleAssignmentRequest + { + /// + /// The person the OED/Digitalt dødsbo role if provided from (the deceased) + /// + public string From { get; set; } + + /// + /// The person the OED/Digitalt dødsbo role if provided to + /// + public string To { get; set; } + } +} \ No newline at end of file diff --git a/src/Authorization/Models/Oed/OedRoleAssignments.cs b/src/Authorization/Models/Oed/OedRoleAssignments.cs new file mode 100644 index 00000000..b91a2efc --- /dev/null +++ b/src/Authorization/Models/Oed/OedRoleAssignments.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Altinn.Platform.Authorization.Models.Oed; + +namespace Altinn.Platform.Authorization.Models +{ + /// + /// Model for a list of OED/Digitalt dødsbo role assignment + /// + public class OedRoleAssignments + { + /// + /// The list of OED/Digitalt dødsbo role assignments + /// + public List RoleAssignments { get; set; } + } +} \ No newline at end of file diff --git a/src/Authorization/Program.cs b/src/Authorization/Program.cs index bb9897a5..f42570d4 100644 --- a/src/Authorization/Program.cs +++ b/src/Authorization/Program.cs @@ -2,7 +2,10 @@ using System.IO; using System.Reflection; using System.Threading.Tasks; - +using Altinn.ApiClients.Maskinporten.Config; +using Altinn.ApiClients.Maskinporten.Extensions; +using Altinn.ApiClients.Maskinporten.Interfaces; +using Altinn.ApiClients.Maskinporten.Services; using Altinn.Authorization.ABAC.Interface; using Altinn.Common.AccessTokenClient.Services; using Altinn.Common.PEP.Authorization; @@ -196,7 +199,9 @@ void ConfigureServices(IServiceCollection services, IConfiguration config) services.AddHealthChecks().AddCheck("authorization_health_check"); services.AddSingleton(config); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -208,16 +213,22 @@ void ConfigureServices(IServiceCollection services, IConfiguration config) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.Configure(config.GetSection("GeneralSettings")); services.Configure(config.GetSection("AzureStorageConfiguration")); services.Configure(config.GetSection("AzureCosmosSettings")); services.Configure(config.GetSection("PostgreSQLSettings")); services.Configure(config.GetSection("PlatformSettings")); + OedAuthzMaskinportenClientSettings oedAuthzMaskinportenClientSettings = config.GetSection("OedAuthzMaskinportenClientSettings").Get(); + services.Configure(config.GetSection("OedAuthzMaskinportenClientSettings")); + services.AddMaskinportenHttpClient(oedAuthzMaskinportenClientSettings); services.AddHttpClient(); services.AddHttpClient(); + services.AddHttpClient(); services.AddHttpClient(); services.AddHttpClient(); services.AddHttpClient(); + services.AddHttpClient(); services.TryAddSingleton(); services.AddSingleton(); services.AddTransient(); diff --git a/src/Authorization/Services/Implementation/ContextHandler.cs b/src/Authorization/Services/Implementation/ContextHandler.cs index d55f8f43..fccac830 100644 --- a/src/Authorization/Services/Implementation/ContextHandler.cs +++ b/src/Authorization/Services/Implementation/ContextHandler.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Altinn.Authorization.ABAC.Constants; @@ -7,10 +8,13 @@ using Altinn.Authorization.ABAC.Xacml; using Altinn.Platform.Authorization.Configuration; using Altinn.Platform.Authorization.Constants; +using Altinn.Platform.Authorization.Helpers; using Altinn.Platform.Authorization.Models; +using Altinn.Platform.Authorization.Models.Oed; using Altinn.Platform.Authorization.Repositories.Interface; using Altinn.Platform.Authorization.Services.Interface; using Altinn.Platform.Authorization.Services.Interfaces; +using Altinn.Platform.Profile.Models; using Altinn.Platform.Register.Models; using Altinn.Platform.Storage.Interface.Models; using Authorization.Platform.Authorization.Models; @@ -32,29 +36,38 @@ public class ContextHandler : IContextHandler { private readonly IInstanceMetadataRepository _policyInformationRepository; private readonly IRoles _rolesWrapper; + private readonly IOedRoleAssignmentWrapper _oedRolesWrapper; private readonly IParties _partiesWrapper; + private readonly IProfile _profileWrapper; private readonly IMemoryCache _memoryCache; private readonly GeneralSettings _generalSettings; private readonly IRegisterService _registerService; + private readonly IPolicyRetrievalPoint _prp; /// /// Initializes a new instance of the class /// /// the policy information repository handler /// the roles handler + /// service handling oed role retireval /// the party information handler + /// the user profile information handler /// The cache handler /// The app settings /// Register service + /// service handling policy retireval public ContextHandler( - IInstanceMetadataRepository policyInformationRepository, IRoles rolesWrapper, IParties partiesWrapper, IMemoryCache memoryCache, IOptions settings, IRegisterService registerService) + IInstanceMetadataRepository policyInformationRepository, IRoles rolesWrapper, IOedRoleAssignmentWrapper oedRolesWrapper, IParties partiesWrapper, IProfile profileWrapper, IMemoryCache memoryCache, IOptions settings, IRegisterService registerService, IPolicyRetrievalPoint prp) { _policyInformationRepository = policyInformationRepository; _rolesWrapper = rolesWrapper; + _oedRolesWrapper = oedRolesWrapper; _partiesWrapper = partiesWrapper; + _profileWrapper = profileWrapper; _memoryCache = memoryCache; _generalSettings = settings.Value; _registerService = registerService; + _prp = prp; } /// @@ -296,9 +309,36 @@ protected async Task EnrichSubjectAttributes(XacmlContextRequest request, string return; } - List roleList = await GetRoles(subjectUserId, resourcePartyId); + XacmlPolicy xacmlPolicy = await _prp.GetPolicyAsync(request); + if (xacmlPolicy == null) + { + return; + } + + IDictionary> subjectAttributes = xacmlPolicy.GetAttributeDictionaryByCategory(XacmlConstants.MatchAttributeCategory.Subject); + if (subjectAttributes.ContainsKey(AltinnXacmlConstants.MatchAttributeIdentifiers.OedRoleAttribute)) + { + string subjectSsn = await GetSsnForUser(subjectUserId); + string resourceSsn = await GetSSnForParty(resourcePartyId); - subjectContextAttributes.Attributes.Add(GetRoleAttribute(roleList)); + if (!string.IsNullOrWhiteSpace(subjectSsn) && !string.IsNullOrWhiteSpace(resourceSsn)) + { + List oedRoleAssignments = await GetOedRoleAssignments(resourceSsn, subjectSsn); + if (oedRoleAssignments.Count != 0) + { + subjectContextAttributes.Attributes.Add(GetOedRoleAttributes(oedRoleAssignments)); + } + } + } + + if (subjectAttributes.ContainsKey(AltinnXacmlConstants.MatchAttributeIdentifiers.RoleAttribute)) + { + List roleList = await GetRoles(subjectUserId, resourcePartyId); + if (roleList.Count != 0) + { + subjectContextAttributes.Attributes.Add(GetRoleAttribute(roleList)); + } + } } /// @@ -317,6 +357,22 @@ protected XacmlAttribute GetRoleAttribute(List roles) return attribute; } + /// + /// Gets a XacmlAttribute model for the list of oed role attributes + /// + /// The list of oedRoleAssignments + /// XacmlAttribute + protected XacmlAttribute GetOedRoleAttributes(List oedRoleAssignments) + { + XacmlAttribute attribute = new XacmlAttribute(new Uri(XacmlRequestAttribute.OedRoleAttribute), false); + foreach (OedRoleAssignment oedRoleAssignment in oedRoleAssignments) + { + attribute.AttributeValues.Add(new XacmlAttributeValue(new Uri(XacmlConstants.DataTypes.XMLString), oedRoleAssignment.OedRoleCode)); + } + + return attribute; + } + /// /// Gets a XacmlAttribute model for a list of party ids /// @@ -406,9 +462,74 @@ protected async Task> GetKeyRolePartyIds(int subjectUserId) return keyrolePartyIds; } + /// + /// Gets a list of role assignments between to persons (if exists) from the OED Authz PIP API + /// + /// the party which the role assignment provides access on behalf of + /// the role assignment recipient party + /// list of OED/Digitalt dødsbo Role Assignments + protected async Task> GetOedRoleAssignments(string from, string to) + { + string cacheKey = GetOedRoleassignmentCacheKey(from, to); + + if (!_memoryCache.TryGetValue(cacheKey, out List oedRoles)) + { + oedRoles = await _oedRolesWrapper.GetOedRoleAssignments(from, to); + + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetPriority(CacheItemPriority.High) + .SetAbsoluteExpiration(new TimeSpan(0, _generalSettings.RoleCacheTimeout, 0)); + + _memoryCache.Set(cacheKey, oedRoles, cacheEntryOptions); + } + + return oedRoles; + } + private string GetCacheKey(int userId, int partyId) { return "rolelist_" + userId + "_" + partyId; } + + private string GetOedRoleassignmentCacheKey(string from, string to) + { + return $"oed{from}_{to}"; + } + + private async Task GetSsnForUser(int userId) + { + string cacheKey = $"uid:{userId}"; + + if (!_memoryCache.TryGetValue(cacheKey, out UserProfile userProfile)) + { + userProfile = await _profileWrapper.GetUserProfile(userId); + + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetPriority(CacheItemPriority.High) + .SetAbsoluteExpiration(new TimeSpan(0, _generalSettings.RoleCacheTimeout, 0)); + + _memoryCache.Set(cacheKey, userProfile, cacheEntryOptions); + } + + return userProfile?.Party?.SSN; + } + + private async Task GetSSnForParty(int partyId) + { + string cacheKey = $"p:{partyId}"; + + if (!_memoryCache.TryGetValue(cacheKey, out Party party)) + { + party = await _partiesWrapper.GetParty(partyId); + + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetPriority(CacheItemPriority.High) + .SetAbsoluteExpiration(new TimeSpan(0, _generalSettings.RoleCacheTimeout, 0)); + + _memoryCache.Set(cacheKey, party, cacheEntryOptions); + } + + return party?.SSN; + } } } diff --git a/src/Authorization/Services/Implementation/DelegationContextHandler.cs b/src/Authorization/Services/Implementation/DelegationContextHandler.cs index 9b5f2bb6..d516bd98 100644 --- a/src/Authorization/Services/Implementation/DelegationContextHandler.cs +++ b/src/Authorization/Services/Implementation/DelegationContextHandler.cs @@ -26,12 +26,15 @@ public class DelegationContextHandler : ContextHandler, IDelegationContextHandle /// /// the policy information repository handler /// the roles handler + /// the oed roles handler /// the party information handler + /// the user profile information handler /// The cache handler /// The app settings /// Register service - public DelegationContextHandler(IInstanceMetadataRepository policyInformationRepository, IRoles rolesWrapper, IParties partiesWrapper, IMemoryCache memoryCache, IOptions settings, IRegisterService registerService) - : base(policyInformationRepository, rolesWrapper, partiesWrapper, memoryCache, settings, registerService) + /// the policy retrieval point service + public DelegationContextHandler(IInstanceMetadataRepository policyInformationRepository, IRoles rolesWrapper, IOedRoleAssignmentWrapper oedRolesWrapper, IParties partiesWrapper, IProfile profileWrapper, IMemoryCache memoryCache, IOptions settings, IRegisterService registerService, IPolicyRetrievalPoint prp) + : base(policyInformationRepository, rolesWrapper, oedRolesWrapper, partiesWrapper, profileWrapper, memoryCache, settings, registerService, prp) { } diff --git a/src/Authorization/Services/Implementation/OedRoleAssignmentWrapper.cs b/src/Authorization/Services/Implementation/OedRoleAssignmentWrapper.cs new file mode 100644 index 00000000..ee5ec025 --- /dev/null +++ b/src/Authorization/Services/Implementation/OedRoleAssignmentWrapper.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Altinn.ApiClients.Maskinporten.Interfaces; +using Altinn.ApiClients.Maskinporten.Models; +using Altinn.Platform.Authorization.Clients; +using Altinn.Platform.Authorization.Configuration; +using Altinn.Platform.Authorization.Models; +using Altinn.Platform.Authorization.Models.Oed; +using Altinn.Platform.Authorization.Services.Interface; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Altinn.Platform.Authorization.Services.Implementation +{ + /// + /// Service implementation for OED Role Assignment integration + /// + [ExcludeFromCodeCoverage] + public class OedRoleAssignmentWrapper : IOedRoleAssignmentWrapper + { + private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + private readonly OedAuthzClient _oedAuthz; + private readonly IMaskinportenService _maskinportenService; + private readonly OedAuthzMaskinportenClientSettings _maskinportenClientSettings; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class + /// + /// logger + /// the client handler for OED api + /// the maskinporten service + /// The maskinporten client settings + public OedRoleAssignmentWrapper(ILogger logger, OedAuthzClient oedAuthzClient, IMaskinportenService maskinportenService, IOptions maskinportenClientSettings) + { + _logger = logger; + _oedAuthz = oedAuthzClient; + _maskinportenService = maskinportenService; + _maskinportenClientSettings = maskinportenClientSettings.Value; + } + + /// + public async Task> GetOedRoleAssignments(string from, string to) + { + try + { + TokenResponse tokenResponse = await _maskinportenService.GetToken(_maskinportenClientSettings.EncodedJwk, _maskinportenClientSettings.Environment, _maskinportenClientSettings.ClientId, _maskinportenClientSettings.Scope, string.Empty); + _oedAuthz.Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken); + + OedRoleAssignments oedRoleAssignmentResponse = new() { RoleAssignments = new List() }; + OedRoleAssignmentRequest oedRoleAssignmentRequest = new OedRoleAssignmentRequest + { + From = from, + To = to + }; + + StringContent requestBody = new StringContent(JsonSerializer.Serialize(oedRoleAssignmentRequest), Encoding.UTF8, "application/json"); + + HttpResponseMessage response = await _oedAuthz.Client.PostAsync("api/v1/pip", requestBody); + string responseContent = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + { + oedRoleAssignmentResponse = JsonSerializer.Deserialize(responseContent, _serializerOptions); + } + else + { + _logger.LogError("OedAuthz // OedRoleAssignmentWrapper // GetOedRoleAssignments // Failed // Unexpected Exception // Unexpected HttpStatusCode: {statusCode}\n {responseContent}", response.StatusCode, responseContent); + } + + return oedRoleAssignmentResponse.RoleAssignments; + } + catch (Exception ex) + { + _logger.LogError(ex, "OedAuthz // OedRoleAssignmentWrapper // GetOedRoleAssignments // Failed // Unexpected Exception"); + throw; + } + } + } +} \ No newline at end of file diff --git a/src/Authorization/Services/Implementation/PartiesWrapper.cs b/src/Authorization/Services/Implementation/PartiesWrapper.cs index 94eafb5d..9092b82b 100644 --- a/src/Authorization/Services/Implementation/PartiesWrapper.cs +++ b/src/Authorization/Services/Implementation/PartiesWrapper.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Net; using System.Net.Http; using System.Text; +using System.Text.Json; using System.Threading.Tasks; using Altinn.Platform.Authorization.Clients; using Altinn.Platform.Authorization.Models; @@ -20,6 +22,7 @@ namespace Altinn.Platform.Authorization.Services.Implementation [ExcludeFromCodeCoverage] public class PartiesWrapper : IParties { + private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; private readonly PartyClient _partyClient; private readonly ILogger _logger; @@ -41,7 +44,7 @@ public async Task> GetParties(int userId) try { - string endpointUrl = $"parties?userid={userId}"; + string endpointUrl = $"authorization/api/parties?userid={userId}"; HttpResponseMessage response = await _partyClient.Client.GetAsync(endpointUrl); string partiesDataList = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) @@ -60,6 +63,31 @@ public async Task> GetParties(int userId) return partiesList; } + /// + public async Task GetParty(int partyId) + { + try + { + string endpointUrl = $"register/api/parties/{partyId}"; + + HttpResponseMessage response = await _partyClient.Client.GetAsync(endpointUrl); + string responseContent = await response.Content.ReadAsStringAsync(); + + if (response.StatusCode == HttpStatusCode.OK) + { + return System.Text.Json.JsonSerializer.Deserialize(responseContent, _serializerOptions); + } + + _logger.LogError("SBL-Bridge // PartiesWrapper // GetParty // Failed // Unexpected HttpStatusCode: {statusCode}\n {responseContent}", response.StatusCode, responseContent); + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "SBL-Bridge // PartiesWrapper // GetParty // Failed // Unexpected Exception"); + throw; + } + } + /// public async Task> GetKeyRoleParties(int userId) { @@ -67,7 +95,7 @@ public async Task> GetKeyRoleParties(int userId) try { - string endpointUrl = $"partieswithkeyroleaccess?userid={userId}"; + string endpointUrl = $"authorization/api/partieswithkeyroleaccess?userid={userId}"; HttpResponseMessage response = await _partyClient.Client.GetAsync(endpointUrl); string responseBody = await response.Content.ReadAsStringAsync(); @@ -97,7 +125,7 @@ public async Task> GetMainUnits(MainUnitQuery subunitPartyIds) HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethod.Get, - RequestUri = new Uri($"{_partyClient.Client.BaseAddress}partyparents"), + RequestUri = new Uri($"{_partyClient.Client.BaseAddress}authorization/api/partyparents"), Content = new StringContent(JsonConvert.SerializeObject(subunitPartyIds), Encoding.UTF8, "application/json") }; diff --git a/src/Authorization/Services/Implementation/ProfileWrapper.cs b/src/Authorization/Services/Implementation/ProfileWrapper.cs new file mode 100644 index 00000000..df11f051 --- /dev/null +++ b/src/Authorization/Services/Implementation/ProfileWrapper.cs @@ -0,0 +1,60 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using Altinn.Platform.Authorization.Clients; +using Altinn.Platform.Authorization.Services.Interface; +using Altinn.Platform.Profile.Models; +using Microsoft.Extensions.Logging; + +namespace Altinn.Platform.Authorization.Services.Implementation +{ + /// + /// Wrapper for the profile api + /// + [ExcludeFromCodeCoverage] + public class ProfileWrapper : IProfile + { + private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + private readonly ProfileClient _profileClient; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class + /// + /// the client handler for profile api in Bridge + /// The logger + public ProfileWrapper(ProfileClient profileClient, ILogger logger) + { + _profileClient = profileClient; + _logger = logger; + } + + /// + public async Task GetUserProfile(int userId) + { + try + { + string endpointUrl = $"profile/api/users/{userId}"; + + HttpResponseMessage response = await _profileClient.Client.GetAsync(endpointUrl); + string responseContent = await response.Content.ReadAsStringAsync(); + + if (response.StatusCode == HttpStatusCode.OK) + { + return JsonSerializer.Deserialize(responseContent, _serializerOptions); + } + + _logger.LogError("SBL-Bridge // ProfileWrapper // GetUserProfile // Failed // Unexpected HttpStatusCode: {statusCode}\n {responseContent}", response.StatusCode, responseContent); + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "SBL-Bridge // ProfileWrapper // GetUserProfile // Failed // Unexpected Exception"); + throw; + } + } + } +} diff --git a/src/Authorization/Services/Implementation/RolesWrapper.cs b/src/Authorization/Services/Implementation/RolesWrapper.cs index 9246df7f..04de8508 100644 --- a/src/Authorization/Services/Implementation/RolesWrapper.cs +++ b/src/Authorization/Services/Implementation/RolesWrapper.cs @@ -28,7 +28,7 @@ public RolesWrapper(RolesClient rolesClient) public async Task> GetDecisionPointRolesForUser(int coveredByUserId, int offeredByPartyId) { List decisionPointRoles = new List(); - string apiurl = $"roles?coveredByUserId={coveredByUserId}&offeredByPartyId={offeredByPartyId}"; + string apiurl = $"authorization/api/roles?coveredByUserId={coveredByUserId}&offeredByPartyId={offeredByPartyId}"; HttpResponseMessage response = await _rolesClient.Client.GetAsync(apiurl); string roleList = await response.Content.ReadAsStringAsync(); diff --git a/src/Authorization/Services/Interface/IOedRoleAssignmentWrapper.cs b/src/Authorization/Services/Interface/IOedRoleAssignmentWrapper.cs new file mode 100644 index 00000000..41b18d89 --- /dev/null +++ b/src/Authorization/Services/Interface/IOedRoleAssignmentWrapper.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Altinn.Platform.Authorization.Models.Oed; + +namespace Altinn.Platform.Authorization.Services.Interface +{ + /// + /// Service mapping OED/Digitalt dødsbo role assignments + /// + public interface IOedRoleAssignmentWrapper + { + /// + /// Gets OED/Digitalt dødsbo role assignments between the deceased party and the inheriting party + /// + /// the deceased party + /// the inheriting party + /// A representing the result of the asynchronous operation. + public Task> GetOedRoleAssignments(string from, string to); + } +} \ No newline at end of file diff --git a/src/Authorization/Services/Interface/IParties.cs b/src/Authorization/Services/Interface/IParties.cs index a2979f37..860ae0f0 100644 --- a/src/Authorization/Services/Interface/IParties.cs +++ b/src/Authorization/Services/Interface/IParties.cs @@ -17,6 +17,13 @@ public interface IParties /// list of parties that the logged in user can represent Task> GetParties(int userId); + /// + /// Method that fetches a given party + /// + /// The party id + /// The party + Task GetParty(int partyId); + /// /// Method that fetches a list of PartyIds the given user id has key role access to (where the user inherit delegations to their organization) /// diff --git a/src/Authorization/Services/Interface/IProfile.cs b/src/Authorization/Services/Interface/IProfile.cs new file mode 100644 index 00000000..e1f4d956 --- /dev/null +++ b/src/Authorization/Services/Interface/IProfile.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Altinn.Platform.Profile.Models; + +namespace Altinn.Platform.Authorization.Services.Interface +{ + /// + /// Interface for actions related to profile + /// + public interface IProfile + { + /// + /// Method that fetches the user profile for a given user id + /// + /// The user id + /// The user profile + Task GetUserProfile(int userId); + } +} diff --git a/src/Authorization/appsettings.json b/src/Authorization/appsettings.json index bcffaead..170c98e2 100644 --- a/src/Authorization/appsettings.json +++ b/src/Authorization/appsettings.json @@ -30,18 +30,25 @@ }, "GeneralSettings": { "OpenIdWellKnownEndpoint": "https://platform.at22.altinn.cloud/authentication/api/v1/openid/", - "BridgeApiEndpoint": "https://at22.altinn.cloud/sblbridge/authorization/api/", + "BridgeApiEndpoint": "https://at22.altinn.cloud/sblbridge/", "RuntimeCookieName": "AltinnStudioRuntime", "SBLBaseAdress": "https://at22.altinn.cloud/", "RoleCacheTimeout": 5, "MainUnitCacheTimeout": 5, "KeyrolePartyIdsCacheTimeout": 5, "PolicyCacheTimeout": 10, - "UseStorageApiForInstanceAuthInfo": false + "UseStorageApiForInstanceAuthInfo": false, + "OedAuthzApiEndpoint": "https://oed-test-authz-app.azurewebsites.net/" }, "PlatformSettings": { "ApiRegisterEndpoint": "http://localhost:5101/register/api/v1/", "ApiStorageEndpoint": "http://localhost:5010/storage/api/v1/", "ApiResourceRegistryEndpoint": "http://localhost:5101/resourceregistry/api/v1/" + }, + "OedAuthzMaskinportenClientSettings": { + "Environment": "test", + "ClientId": "", + "Scope": "altinn:dd:internal", + "EncodedJWK": "" } } diff --git a/test/IntegrationTests/Altinn.Platform.Authorization.IntegrationTests.csproj b/test/IntegrationTests/Altinn.Platform.Authorization.IntegrationTests.csproj index 7873a7e9..5d2461a6 100644 --- a/test/IntegrationTests/Altinn.Platform.Authorization.IntegrationTests.csproj +++ b/test/IntegrationTests/Altinn.Platform.Authorization.IntegrationTests.csproj @@ -97,6 +97,15 @@ + + + + + + + + + @@ -106,13 +115,49 @@ + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + Always + + Always + + + Always + Always diff --git a/test/IntegrationTests/AltinnApps_DecisionTests.cs b/test/IntegrationTests/AltinnApps_DecisionTests.cs index 998503e8..937d8a62 100644 --- a/test/IntegrationTests/AltinnApps_DecisionTests.cs +++ b/test/IntegrationTests/AltinnApps_DecisionTests.cs @@ -312,6 +312,36 @@ public async Task PDP_Decision_DelegationPolicy_AltinnAppsOrg1App1_UserDelegatio AssertionUtil.AssertEqual(expected, contextResponse); } + [Fact] + public async Task PDP_Decision_AltinnApps_OedFormuesfullmakt_Xml_Permit() + { + string testCase = "AltinnApps_OedFormuesfullmakt_Xml_Permit"; + HttpClient client = GetTestClient(); + HttpRequestMessage httpRequestMessage = TestSetupUtil.CreateXacmlRequest(testCase); + XacmlContextResponse expected = TestSetupUtil.ReadExpectedResponse(testCase); + + // Act + XacmlContextResponse contextResponse = await TestSetupUtil.GetXacmlContextResponseAsync(client, httpRequestMessage); + + // Assert + AssertionUtil.AssertEqual(expected, contextResponse); + } + + [Fact] + public async Task PDP_Decision_AltinnApps_OedFormuesfullmakt_Json_Permit() + { + string testCase = "AltinnApps_OedFormuesfullmakt_Json_Permit"; + HttpClient client = GetTestClient(); + HttpRequestMessage httpRequestMessage = TestSetupUtil.CreateJsonProfileXacmlRequest(testCase); + XacmlJsonResponse expected = TestSetupUtil.ReadExpectedJsonProfileResponse(testCase); + + // Act + XacmlJsonResponse contextResponse = await TestSetupUtil.GetXacmlJsonProfileContextResponseAsync(client, httpRequestMessage); + + // Assert + AssertionUtil.AssertEqual(expected, contextResponse); + } + private HttpClient GetTestClient() { HttpClient client = _factory.WithWebHostBuilder(builder => @@ -322,7 +352,9 @@ private HttpClient GetTestClient() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton, JwtCookiePostConfigureOptionsStub>(); diff --git a/test/IntegrationTests/ContextHandlerTest.cs b/test/IntegrationTests/ContextHandlerTest.cs index 312d4020..01d08c2f 100644 --- a/test/IntegrationTests/ContextHandlerTest.cs +++ b/test/IntegrationTests/ContextHandlerTest.cs @@ -6,9 +6,10 @@ using Altinn.Platform.Authorization.IntegrationTests.Util; using Altinn.Platform.Authorization.Services.Implementation; using Altinn.Platform.Events.Tests.Mocks; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; - +using Moq; using Xunit; namespace Altinn.Platform.Authorization.IntegrationTests @@ -19,16 +20,22 @@ namespace Altinn.Platform.Authorization.IntegrationTests public class ContextHandlerTest { private readonly ContextHandler _contextHandler; + private HttpContext _httpContext = new DefaultHttpContext(); public ContextHandlerTest() { + Mock httpContextAccessorMock = new Mock(); + httpContextAccessorMock.Setup(h => h.HttpContext).Returns(_httpContext); _contextHandler = new ContextHandler( new InstanceMetadataRepositoryMock(), new RolesMock(), + new OedRoleAssignmentWrapperMock(), new PartiesMock(), + new ProfileMock(), new MemoryCache(new MemoryCacheOptions()), Options.Create(new GeneralSettings { RoleCacheTimeout = 5 }), - new RegisterServiceMock()); + new RegisterServiceMock(), + new PolicyRetrievalPointMock(httpContextAccessorMock.Object, null)); } /// @@ -46,6 +53,7 @@ public async Task ContextHandler_TC01() { // Arrange string testCase = "AltinnApps0021"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); @@ -74,6 +82,7 @@ public async Task ContextHandler_TC02() { // Arrange string testCase = "AltinnApps0022"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); @@ -102,6 +111,7 @@ public async Task ContextHandler_TC03() { // Arrange string testCase = "AltinnApps0023"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); @@ -130,6 +140,7 @@ public async Task ContextHandler_TC04() { // Arrange string testCase = "AltinnApps0024"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); @@ -158,6 +169,7 @@ public async Task ContextHandler_TC05() { // Arrange string testCase = "AltinnApps0025"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); @@ -186,6 +198,7 @@ public async Task ContextHandler_TC06() { // Arrange string testCase = "AltinnApps0026"; + _httpContext.Request.Headers.Add("testcase", testCase); XacmlContextRequest request = TestSetupUtil.CreateXacmlContextRequest(testCase); XacmlContextRequest expectedEnrichedRequest = TestSetupUtil.GetEnrichedRequest(testCase); diff --git a/test/IntegrationTests/Data/Instances/50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678.json b/test/IntegrationTests/Data/Instances/50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678.json new file mode 100644 index 00000000..2e8c3579 --- /dev/null +++ b/test/IntegrationTests/Data/Instances/50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678.json @@ -0,0 +1,30 @@ +{ + "id": "eb0d2b21-fef9-4b85-9985-c4ba271c4678", + "instanceOwner": { + "partyId": "50740574" + }, + "appId": "ttd/oedformuesfullmakt", + "org": "ttd", + "labels": [ + "oed" + ], + "created": "2023-09-07T11:48:25.4597204Z", + "lastChanged": "2023-09-07T11:48:25.4597204Z", + "dueDateTime": "2023-09-17T11:48:25.4597204Z", + "visibleDateTime": "2023-09-07T11:48:25.4597204Z", + "presentationField": { + "nb": "oedformuesfullmakt" + }, + "instanceState": { + "isDeleted": false, + "isMarkedForHardDelete": false, + "isArchived": false, + "deletedDateTime": "2034-09-07T11:48:25.4597204Z" + }, + "data": [], + "_rid": "zCw6APRA6nkBAAAAAAAAAA==", + "_self": "dbs/zCw6AA==/colls/zCw6APRA6nk=/docs/zCw6APRA6nkBAAAAAAAAAA==/", + "_etag": "\"00000000-0000-0000-8feb-f55df16b01d5\"", + "_attachments": "attachments/", + "_ts": 1572527167 +} diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0021Policy.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0021Policy.xml new file mode 100644 index 00000000..326f4e81 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0021Policy.xml @@ -0,0 +1,110 @@ + + + + + Eksempel pÃ¥ samleregel som spesifiserer at bÃ¥de REGNA, DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonene; Read og Write + + + + + regna + + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + + + + + read + + + + + + write + + + + + + + + Eksempel pÃ¥ tilleggsregel som spesifiserer at DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonen; Sign for Task: task1 + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + task1 + + + + + + + + sign + + + + + + + + + + 4 + + + + + 3 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0024Policy.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0024Policy.xml new file mode 100644 index 00000000..326f4e81 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0024Policy.xml @@ -0,0 +1,110 @@ + + + + + Eksempel pÃ¥ samleregel som spesifiserer at bÃ¥de REGNA, DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonene; Read og Write + + + + + regna + + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + + + + + read + + + + + + write + + + + + + + + Eksempel pÃ¥ tilleggsregel som spesifiserer at DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonen; Sign for Task: task1 + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + task1 + + + + + + + + sign + + + + + + + + + + 4 + + + + + 3 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0025Policy.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0025Policy.xml new file mode 100644 index 00000000..326f4e81 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps0025Policy.xml @@ -0,0 +1,110 @@ + + + + + Eksempel pÃ¥ samleregel som spesifiserer at bÃ¥de REGNA, DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonene; Read og Write + + + + + regna + + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + + + + + read + + + + + + write + + + + + + + + Eksempel pÃ¥ tilleggsregel som spesifiserer at DAGL og PRIV m/sikkerhetsnivÃ¥; 4, for ressursen; tdd/taxreport fÃ¥r tilgang til operasjonen; Sign for Task: task1 + + + + + dagl + + + + + + priv + + + + + + + + tdd + + + + taxreport + + + + task1 + + + + + + + + sign + + + + + + + + + + 4 + + + + + 3 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitPolicy.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitPolicy.xml new file mode 100644 index 00000000..f244e0ad --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitPolicy.xml @@ -0,0 +1,50 @@ + + + + + Eksempel pÃ¥ samleregel som spesifiserer at OED rollen urn:digitaltdodsbo:formuesfullmakt m/sikkerhetsnivÃ¥; 2, for ressursen; ttd/oedformuesfullmakt fÃ¥r tilgang til operasjonene; Read og Write + + + + + urn:digitaltdodsbo:formuesfullmakt + + + + + + + + ttd + + + + oedformuesfullmakt + + + + + + + + read + + + + + + write + + + + + + + + + + 2 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitRequest.json b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitRequest.json new file mode 100644 index 00000000..cb6a354a --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitRequest.json @@ -0,0 +1,36 @@ +{ + "Request": { + "ReturnPolicyIdList": true, + "AccessSubject": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:userid", + "Value": "20010440" + } + ] + } + ], + "Action": [ + { + "Attribute": [ + { + "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "Value": "read", + "DataType": "http://www.w3.org/2001/XMLSchema#string" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:instance-id", + "Value": "50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678" + } + ] + } + ] + } +} diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitResponse.json b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitResponse.json new file mode 100644 index 00000000..49b9a7d8 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Json_PermitResponse.json @@ -0,0 +1,39 @@ +{ + "Response": [ + { + "Decision": "Permit", + "Status": { + "StatusCode": { + "Value": "urn:oasis:names:tc:xacml:1.0:status:ok" + } + }, + "Obligations": [ + { + "id": "urn:altinn:obligation:authenticationLevel1", + "attributeAssignment": [ + + { + "attributeId": "urn:altinn:obligation-assignment:1", + "value": "2", + "category": "urn:altinn:minimum-authenticationlevel", + "dataType": "http://www.w3.org/2001/XMLSchema#integer", + "issuer": null + } + ] + } + ], + "Category": [ + { + "CategoryId": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "Attribute": [ + { + "AttributeId": "urn:altinn:partyid", + "DataType": "http://www.w3.org/2001/XMLSchema#string", + "Value": "50740574" + } + ] + } + ] + } + ] +} diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitPolicy.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitPolicy.xml new file mode 100644 index 00000000..f244e0ad --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitPolicy.xml @@ -0,0 +1,50 @@ + + + + + Eksempel pÃ¥ samleregel som spesifiserer at OED rollen urn:digitaltdodsbo:formuesfullmakt m/sikkerhetsnivÃ¥; 2, for ressursen; ttd/oedformuesfullmakt fÃ¥r tilgang til operasjonene; Read og Write + + + + + urn:digitaltdodsbo:formuesfullmakt + + + + + + + + ttd + + + + oedformuesfullmakt + + + + + + + + read + + + + + + write + + + + + + + + + + 2 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitRequest.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitRequest.xml new file mode 100644 index 00000000..196a9f41 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitRequest.xml @@ -0,0 +1,19 @@ + + + + + 20010440 + + + + + 50740574/eb0d2b21-fef9-4b85-9985-c4ba271c4678 + + + + + read + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitResponse.xml b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitResponse.xml new file mode 100644 index 00000000..0b029662 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/AltinnApps/AltinnApps_OedFormuesfullmakt_Xml_PermitResponse.xml @@ -0,0 +1,28 @@ + + + + Permit + + + + + + 2 + + + + + 50740574 + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateRequest.json b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateRequest.json new file mode 100644 index 00000000..26887a78 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateRequest.json @@ -0,0 +1,40 @@ +{ + "Request": { + "ReturnPolicyIdList": true, + "AccessSubject": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:userid", + "Value": "1337" + } + ] + } + ], + "Action": [ + { + "Attribute": [ + { + "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "Value": "read", + "DataType": "http://www.w3.org/2001/XMLSchema#string" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:resource", + "Value": "oed-role-formuesfullmakt" + }, + { + "AttributeId": "urn:altinn:partyid", + "Value": "50740574" + } + ] + } + ] + } +} diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateResponse.json b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateResponse.json new file mode 100644 index 00000000..89ee559d --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_IndeterminateResponse.json @@ -0,0 +1,19 @@ +{ + "response": [ + { + "decision": "NotApplicable", + "status": { + "statusMessage": null, + "statusDetails": null, + "statusCode": { + "value": "urn:oasis:names:tc:xacml:1.0:status:ok", + "statusCode": null + } + }, + "obligations": null, + "associateAdvice": null, + "category": null, + "policyIdentifierList": null + } + ] +} \ No newline at end of file diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitRequest.json b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitRequest.json new file mode 100644 index 00000000..d05d324a --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitRequest.json @@ -0,0 +1,40 @@ +{ + "Request": { + "ReturnPolicyIdList": true, + "AccessSubject": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:userid", + "Value": "20010440" + } + ] + } + ], + "Action": [ + { + "Attribute": [ + { + "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "Value": "read", + "DataType": "http://www.w3.org/2001/XMLSchema#string" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:resource", + "Value": "oed-role-formuesfullmakt" + }, + { + "AttributeId": "urn:altinn:partyid", + "Value": "50740574" + } + ] + } + ] + } +} diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitResponse.json b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitResponse.json new file mode 100644 index 00000000..67b16bb4 --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Json_PermitResponse.json @@ -0,0 +1,32 @@ +{ + "response": [ + { + "decision": "Permit", + "status": { + "statusMessage": null, + "statusDetails": null, + "statusCode": { + "value": "urn:oasis:names:tc:xacml:1.0:status:ok", + "statusCode": null + } + }, + "obligations": [ + { + "id": "urn:altinn:obligation:1", + "attributeAssignment": [ + { + "attributeId": "urn:altinn:obligation-assignment:1", + "value": "2", + "category": "urn:altinn:minimum-authenticationlevel", + "dataType": "http://www.w3.org/2001/XMLSchema#integer", + "issuer": null + } + ] + } + ], + "associateAdvice": null, + "category": null, + "policyIdentifierList": null + } + ] +} \ No newline at end of file diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateRequest.xml b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateRequest.xml new file mode 100644 index 00000000..378a61ea --- /dev/null +++ b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateRequest.xml @@ -0,0 +1,22 @@ + + + + + 1337 + + + + + oed-role-formuesfullmakt + + + 50740574 + + + + + read + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateResponse.xml b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_IndeterminateResponse.xml new file mode 100644 index 0000000000000000000000000000000000000000..b6037ed85f2e1cf45cee4ff975c6e351f8573a75 GIT binary patch literal 1324 zcmbW1OHaa35QWd$#Q)IfnuiZUa)S_}8xnP)#<;D}01*nYMdi<{-`q+lZPjQ<>Fso8 z&Y77r{dn)Fr#H>0ZN z22~7KRF~#_%6=DQ9eP$-?Ok1inyOEAOQNT|4fV(=0-=$s&8Zw~oidCv&Mi4Zt`)Ux zIsfi^4x16!f$oW)5g+;a{JpE$M6H)wCN`BPy4WaiDpvYE``xbh$(=H@DIHsJGL-~6 z_mxK)`+2Va$$z5?>*6j(&CkftHVDq^CIQd-G~`WQDb-ysa}Q8K5o^FS@~XC(q|_UG zjW4P6nddc@5txAn*oS^@Hbr~Nb|+J&WwKgqs#OfjIw~{T>LNgq)}2syFj$h)@=vg& zJUOP^V0Y|S=dym + + + + 20010440 + + + + + oed-role-formuesfullmakt + + + 50740574 + + + + + read + + + + diff --git a/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_PermitResponse.xml b/test/IntegrationTests/Data/Xacml/3.0/ResourceRegistry/ResourceRegistry_OedFormuesfullmakt_Xml_PermitResponse.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd84e7d94184cebb720a1c984e767284d329ef39 GIT binary patch literal 2028 zcmcJQ?Q7Fe6vm&g6Z{{-{M>a;$KX;s#zYuQCYy*~Ya6>_l8z)*`_HStb5qUD3n~2| zA#HkcUY_%u=iL7OHPNMhDpjIL-xVuYp_SIk^hU>esS};@eW|IQ>zO9_&NTP_PWSj1 zdh*@{&(SVZhSde0mT5!g4C|VBt6&}(&#BMhRFXA}aeC!zJM3#>W8M}#Kk}3k=k!Ah zjX-!o_6prmFTM@EmH#~2K5xl4_jszVr}}^;r^bq?iN--6PF-(f<%p}v%mcAA?hTm# zVjK3lrppDDBYh$=Au{$8IGnd?X2w>H!Fc}$PvZbhySIMK&A#sR1#BxVeRmaOLml?{ zN9wcQ(0!;AmcA5%o;edhtHTdbz%1ce;K>N|WBeI;YUbw`9%3uj%c z$R^dE=oJ-8bg_Z~s~YPHhE2&!a+!(^Lxe(X?lXPVmd&VU_=u(CmxKQ?y0zN@&BgdW>ugxJuRfleJJsCLK6TapZPoXAhl+0Mzl*M5=0i*!e%_gWno1j? z1+&((a7@I`-ZhNpyp7RB-Q#}kMyR)4WmrE?AjpZ?GUtU?;0-gMvr8L)ZrQKu|DZZ= zZM&=sJI9*X_M@v$!2h*Rb~f5BXQ + + + + Eksempel pÃ¥ samleregel som spesifiserer at bÃ¥de REGNA og DAGL m/sikkerhetsnivÃ¥; 2, for ressursen; SKD/TaxReport fÃ¥r tilgang til operasjonene; Read og Write Instantiate og Tasks; FormFilling og Signing + + + + + urn:digitaltdodsbo:formuesfullmakt + + + + + + + + oed-role-formuesfullmakt + + + + + + + + read + + + + + + write + + + + + + + + + + 2 + + + + diff --git a/test/IntegrationTests/MockServices/OedRoleAssignmentWrapperMock.cs b/test/IntegrationTests/MockServices/OedRoleAssignmentWrapperMock.cs new file mode 100644 index 00000000..ea3deaf2 --- /dev/null +++ b/test/IntegrationTests/MockServices/OedRoleAssignmentWrapperMock.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Altinn.Platform.Authorization.Models.Oed; +using Altinn.Platform.Authorization.Services.Interface; + +namespace Altinn.Platform.Authorization.IntegrationTests.MockServices +{ + public class OedRoleAssignmentWrapperMock : IOedRoleAssignmentWrapper + { + public Task> GetOedRoleAssignments(string from, string to) + { + List oedRoleAssignments = new(); + if (from == "11895696716" && to == "13923949741") + { + OedRoleAssignment oedRoleAssignment = new OedRoleAssignment + { + Created = DateTime.Now, + From = from, + To = to, + OedRoleCode = "urn:digitaltdodsbo:formuesfullmakt" + }; + oedRoleAssignments.Add(oedRoleAssignment); + } + + return Task.FromResult(oedRoleAssignments); + } + } +} \ No newline at end of file diff --git a/test/IntegrationTests/MockServices/PartiesMock.cs b/test/IntegrationTests/MockServices/PartiesMock.cs index ab28c04f..2202d406 100644 --- a/test/IntegrationTests/MockServices/PartiesMock.cs +++ b/test/IntegrationTests/MockServices/PartiesMock.cs @@ -50,6 +50,17 @@ public Task> GetParties(int userId) throw new NotImplementedException(); } + public Task GetParty(int partyId) + { + Party party = null; + if (partyId == 50740574) + { + party = new Party { PartyId = partyId, SSN = "11895696716" }; + } + + return Task.FromResult(party); + } + public Task ValidateSelectedParty(int userId, int partyId) { throw new NotImplementedException(); diff --git a/test/IntegrationTests/MockServices/ProfileMock.cs b/test/IntegrationTests/MockServices/ProfileMock.cs new file mode 100644 index 00000000..6ea015f9 --- /dev/null +++ b/test/IntegrationTests/MockServices/ProfileMock.cs @@ -0,0 +1,26 @@ +using System; +using System.Threading.Tasks; +using Altinn.Platform.Authorization.Services.Interface; +using Altinn.Platform.Profile.Models; +using Altinn.Platform.Register.Models; + +namespace Altinn.Platform.Authorization.IntegrationTests.MockServices +{ + public class ProfileMock : IProfile + { + public Task GetUserProfile(int userId) + { + UserProfile userProfile = null; + if (userId == 20010440) + { + userProfile = new UserProfile { Party = new Party { SSN = "13923949741" } }; + } + else if (userId == 1337) + { + userProfile = new UserProfile { Party = new Party { SSN = "13371337133" } }; + } + + return Task.FromResult(userProfile); + } + } +} diff --git a/test/IntegrationTests/ResourceRegistry_DecisionTests.cs b/test/IntegrationTests/ResourceRegistry_DecisionTests.cs index 93298628..31ff140a 100644 --- a/test/IntegrationTests/ResourceRegistry_DecisionTests.cs +++ b/test/IntegrationTests/ResourceRegistry_DecisionTests.cs @@ -1,6 +1,5 @@ using System.Net.Http; using System.Threading.Tasks; -using Altinn.Authorization.ABAC.Interface; using Altinn.Authorization.ABAC.Xacml; using Altinn.Authorization.ABAC.Xacml.JsonProfile; using Altinn.Platform.Authorization.Controllers; @@ -8,7 +7,6 @@ using Altinn.Platform.Authorization.IntegrationTests.Util; using Altinn.Platform.Authorization.IntegrationTests.Webfactory; using Altinn.Platform.Authorization.Repositories.Interface; -using Altinn.Platform.Authorization.Services; using Altinn.Platform.Authorization.Services.Interface; using Altinn.Platform.Authorization.Services.Interfaces; using Altinn.Platform.Events.Tests.Mocks; @@ -30,6 +28,66 @@ public ResourceRegistry_DecisionTests(CustomWebApplicationFactory(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton();