Skip to content

Commit

Permalink
Prepare authorization for system user (#479)
Browse files Browse the repository at this point in the history
* Remove unused parameter

* Events does not expect the 0192: prefix.

* Also publish recipient events when testing

* Updated example base policy
  • Loading branch information
Ceredron committed Jun 24, 2024
1 parent b42f3c0 commit 8181159
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 66 deletions.
68 changes: 25 additions & 43 deletions Test/Altinn.Broker.Tests/Data/BasePolicy.xml
Original file line number Diff line number Diff line change
@@ -1,95 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<xacml:Policy xmlns:xsl="http://www.w3.org/2001/XMLSchema-instance" xmlns:xacml="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:altinn:example:policyid:1" Version="1.0" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides">
<xacml:Target/>

<xacml:Policy
xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
xmlns:xacml ="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:md="http://www.med.example.com/schemas/record.xsd"
PolicyId="urn:oasis:names:tc:xacml:3.0:example:policyid:1"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides"
Version="1.0">
<xacml:PolicyDefaults>
<xacml:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml:XPathVersion>
</xacml:PolicyDefaults>
<xacml:Target/>
<xacml:Rule RuleId="urn:altinn:example:ruleid:1" Effect="Permit">
<xacml:Description>A rule giving ttd the right to publish and subscribe to events registered to the ttd-altinn-events-automated-tests resource as well as to read and write files to the broker service</xacml:Description>
<xacml:Description>A rule giving 991825827 the right to subscribe to events registered to altinn-broker-test-resource as well as to read and write files to the broker service</xacml:Description>
<xacml:Target>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ttd</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:org" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:app" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">991825827</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:organization:identifier-no" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker-test-resource-2</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker-test-resource</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:resource" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">publish</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">subscribe</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">subscribe</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
</xacml:Target>
</xacml:Rule>

<xacml:Rule RuleId="urn:altinn:example:ruleid:2" Effect="Permit">
<xacml:Description>A rule giving digdir the right to publish and subscribe to events registered to the digdir-altinn-events-automated-tests resource as well as to read and write files to the broker service</xacml:Description>
<xacml:Description>A rule giving 986252932 the right to receive files from altinn-broker-test-resource</xacml:Description>
<xacml:Target>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">digdir</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:org" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:app" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">986252932</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:organization:identifier-no" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker-test-resource-2</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn-broker-test-resource</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:resource" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">publish</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">subscribe</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml:AttributeValue>
Expand All @@ -98,7 +80,7 @@
</xacml:AllOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</xacml:AttributeValue>
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">subscribe</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
Expand All @@ -112,4 +94,4 @@
</xacml:AttributeAssignmentExpression>
</xacml:ObligationExpression>
</xacml:ObligationExpressions>
</xacml:Policy>
</xacml:Policy>
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public class CustomWebApplicationFactory : WebApplicationFactory<Program>
services.AddSingleton(resourceRegistryRepository.Object);
var authorizationService = new Mock<IAuthorizationService>();
authorizationService.Setup(x => x.CheckUserAccess(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<List<ResourceAccessLevel>>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);
authorizationService.Setup(x => x.CheckUserAccess(TestConstants.RESOURCE_WITH_NO_ACCESS, It.IsAny<string>(), It.IsAny<List<ResourceAccessLevel>>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(false);
authorizationService.Setup(x => x.CheckUserAccess(It.IsAny<string>(), It.IsAny<List<ResourceAccessLevel>>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);
authorizationService.Setup(x => x.CheckUserAccess(TestConstants.RESOURCE_WITH_NO_ACCESS, It.IsAny<List<ResourceAccessLevel>>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(false);
services.AddSingleton(authorizationService.Object);
var eventBus = new Mock<IEventBus>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public ConfirmDownloadCommandHandler(IFileTransferRepository fileTransferReposit
{
return Errors.FileTransferNotFound;
}
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
if (!hasAccess)
{
return Errors.FileTransferNotFound;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public DownloadFileQueryHandler(IResourceRepository resourceRepository, IService
{
return Errors.NoFileUploaded;
}
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
if (!hasAccess)
{
return Errors.NoAccessToResource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public GetFileTransferDetailsQueryHandler(IFileTransferRepository fileTransferRe
{
return Errors.FileTransferNotFound;
}
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, cancellationToken: cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, cancellationToken: cancellationToken);
if (!hasAccess)
{
return Errors.NoAccessToResource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public GetFileTransferOverviewQueryHandler(IAuthorizationService resourceRightsR
{
return Errors.FileTransferNotFound;
}
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
if (!hasAccess)
{
return Errors.NoAccessToResource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public GetFileTransfersQueryHandler(IAuthorizationService resourceRightsReposito

public async Task<OneOf<List<Guid>, Error>> Process(GetFileTransfersQueryRequest request, CancellationToken cancellationToken)
{
var hasAccess = await _resourceRightsRepository.CheckUserAccess(request.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, cancellationToken: cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(request.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, cancellationToken: cancellationToken);
if (!hasAccess)
{
return Errors.NoAccessToResource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class InitializeFileTransferCommandHandler : IHandler<InitializeFileTrans

public async Task<OneOf<Guid, Error>> Process(InitializeFileTransferCommandRequest request, CancellationToken cancellationToken)
{
var hasAccess = await _resourceRightsRepository.CheckUserAccess(request.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write }, request.IsLegacy, cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(request.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write }, request.IsLegacy, cancellationToken);
if (!hasAccess)
{
return Errors.NoAccessToResource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public UploadFileCommandHandler(IAuthorizationService resourceRightsRepository,
{
return Errors.FileTransferNotFound;
}
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, request.Token.ClientId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write }, request.IsLegacy, cancellationToken);
var hasAccess = await _resourceRightsRepository.CheckUserAccess(fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write }, request.IsLegacy, cancellationToken);
if (!hasAccess)
{
return Errors.FileTransferNotFound;
Expand Down Expand Up @@ -102,6 +102,10 @@ public UploadFileCommandHandler(IAuthorizationService resourceRightsRepository,
{
await _fileTransferStatusRepository.InsertFileTransferStatus(request.FileTransferId, FileTransferStatus.Published);
await _eventBus.Publish(AltinnEventType.Published, fileTransfer.ResourceId, request.FileTransferId.ToString(), fileTransfer.Sender.ActorExternalId, cancellationToken);
foreach (var recipient in fileTransfer.RecipientCurrentStatuses)
{
await _eventBus.Publish(AltinnEventType.Published, fileTransfer.ResourceId, request.FileTransferId.ToString(), recipient.Actor.ActorExternalId, cancellationToken);
}
}
return fileTransfer.FileTransferId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
namespace Altinn.Broker.Core.Repositories;
public interface IAuthorizationService
{
Task<bool> CheckUserAccess(string resourceId, string userId, List<ResourceAccessLevel> rights, bool IsLegacyUser = false, CancellationToken cancellationToken = default);
Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLevel> rights, bool IsLegacyUser = false, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System.Net.Http.Json;
using System.Security.Claims;
using System.Text.Json;

using Altinn.Authorization.ABAC.Xacml;
using Altinn.Authorization.ABAC.Xacml.JsonProfile;
using Altinn.Broker.Core.Domain;
using Altinn.Broker.Core.Domain.Enums;
using Altinn.Broker.Core.Options;
using Altinn.Broker.Core.Repositories;
using Altinn.Common.PEP.Helpers;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
Expand All @@ -33,7 +33,7 @@ public AltinnAuthorizationService(HttpClient httpClient, IOptions<AltinnOptions>
_logger = logger;
}

public async Task<bool> CheckUserAccess(string resourceId, string userId, List<ResourceAccessLevel> rights, bool IsLegacyUser = false, CancellationToken cancellationToken = default)
public async Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLevel> rights, bool IsLegacyUser = false, CancellationToken cancellationToken = default)
{
if (IsLegacyUser || _hostEnvironment.IsDevelopment())
{
Expand Down Expand Up @@ -76,8 +76,7 @@ private XacmlJsonRequestRoot CreateDecisionRequest(ClaimsPrincipal user, List<st
Resource = new List<XacmlJsonCategory>()
};

var subjectCategory = XacmlMappers.CreateSubjectCategory(user);
subjectCategory.Attribute = subjectCategory.Attribute.Where(attribute => attribute.AttributeId != "urn:altinn:authlevel").ToList(); // Temp fix as xcaml int32 not implemented
var subjectCategory = DecisionHelper.CreateSubjectCategory(user.Claims);
request.AccessSubject.Add(subjectCategory);
foreach (var actionType in actionTypes)
{
Expand Down
Loading

0 comments on commit 8181159

Please sign in to comment.