Skip to content

Commit

Permalink
Merge branch 'main' into ci/ensure-proper-diff-in-check-changes-2
Browse files Browse the repository at this point in the history
  • Loading branch information
arealmaas authored Oct 31, 2024
2 parents 1b3f40c + 4974676 commit f114ca3
Show file tree
Hide file tree
Showing 16 changed files with 437 additions and 91 deletions.
60 changes: 60 additions & 0 deletions .github/workflows/dispatch-k6-performance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Run K6 performance test

on:
workflow_dispatch:
inputs:
apiVersion:
description: 'API Version'
required: true
default: 'v1'
environment:
description: 'Environment'
required: true
default: 'staging'
type: choice
options:
- test
- staging
- performance
tokens:
description: 'Tokens to generate; for create dialog, search, none, or both'
required: true
default: 'both'
type: choice
options:
- both
- enterprise
- personal
- none
vus:
description: 'Number of VUS'
required: true
type: number
default: 10
duration:
description: 'Duration of test, ie 30s, 1m, 10m'
required: true
default: 1m
type: string
testSuitePath:
description: 'Path to test suite to run'
required: true
default: 'tests/k6/tests/serviceowner/performance/create-dialog.js'

jobs:
k6-performance:
name: "Run K6 performance test"
uses: ./.github/workflows/workflow-run-k6-performance.yml
secrets:
TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }}
TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }}
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}
with:
environment: ${{ inputs.environment }}
apiVersion: ${{ inputs.apiVersion }}
testSuitePath: ${{ inputs.testSuitePath }}
vus: ${{ inputs.vus }}
duration: ${{ inputs.duration }}
tokens: ${{ inputs.tokens }}

55 changes: 55 additions & 0 deletions .github/workflows/workflow-run-k6-performance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Run K6 performance tests

on:
workflow_call:
inputs:
apiVersion:
required: true
type: string
environment:
required: true
type: string
testSuitePath:
required: true
type: string
vus:
required: true
type: number
duration:
required: true
type: string
tokens:
required: true
type: string
secrets:
TOKEN_GENERATOR_USERNAME:
required: true
TOKEN_GENERATOR_PASSWORD:
required: true
K6_CLOUD_TOKEN:
required: true
K6_CLOUD_PROJECT_ID:
required: true

jobs:
k6-test:
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup k6
uses: grafana/setup-k6-action@v1
- name: Run K6 tests (${{ inputs.testSuitePath }})
run: |
./tests/k6/tests/scripts/generate_tokens.sh ./tests/k6/tests/performancetest_data ${{ inputs.tokens }}
k6 run ${{ inputs.testSuitePath }} --quiet --log-output=stdout --include-system-env-vars --vus=${{ inputs.vus }} --duration=${{ inputs.duration }}
env:
API_ENVIRONMENT: ${{ inputs.environment }}
API_VERSION: ${{ inputs.apiVersion }}
TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }}
TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }}
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,10 @@ FodyWeavers.xsd

# MacOS
.DS_Store

# Secrets file used by act
.secrets

# Generated files with tokens
**/.endusers-with-tokens.csv
**/.serviceowners-with-tokens.csv
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## [1.27.1](https://github.com/digdir/dialogporten/compare/v1.27.0...v1.27.1) (2024-10-30)


### Bug Fixes

* Simplify subject attribute matching ([#1348](https://github.com/digdir/dialogporten/issues/1348)) ([55159b7](https://github.com/digdir/dialogporten/commit/55159b772578e58d3406dd8028e9c14d9b3254e1))

## [1.27.0](https://github.com/digdir/dialogporten/compare/v1.26.3...v1.27.0) (2024-10-29)


### Features

* Add restrictions to Transmissions reference hierarchy ([#1310](https://github.com/digdir/dialogporten/issues/1310)) ([e3d53ca](https://github.com/digdir/dialogporten/commit/e3d53cafbbb7157d8439c23745d6b23cbbaeea17))
* **graphql:** configure opentelemetry ([#1343](https://github.com/digdir/dialogporten/issues/1343)) ([e31c08b](https://github.com/digdir/dialogporten/commit/e31c08b0ddcad8b43db2c1ce7f46be5b924fdb9d))
* **infrastructure:** add availability test for apim ([#1327](https://github.com/digdir/dialogporten/issues/1327)) ([1f9fa2b](https://github.com/digdir/dialogporten/commit/1f9fa2b3fbb7ea9bd84ddde5f99697724785921d))
* **service:** configure opentelemetry ([#1342](https://github.com/digdir/dialogporten/issues/1342)) ([513d5e4](https://github.com/digdir/dialogporten/commit/513d5e4bf3345ecf70c5adb858143025db2738fa))
* **utils:** configure open telemetry tracing for masstransit in aspnet package ([#1344](https://github.com/digdir/dialogporten/issues/1344)) ([5ec3b84](https://github.com/digdir/dialogporten/commit/5ec3b84be6955963cda92ab209510ad01d4dda90))

## [1.26.3](https://github.com/digdir/dialogporten/compare/v1.26.2...v1.26.3) (2024-10-23)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ public async Task<AuthorizedPartiesResult> GetAuthorizedParties(IPartyIdentifier
CancellationToken cancellationToken = default)
{
var authorizedPartiesRequest = new AuthorizedPartiesRequest(authenticatedParty);
var authorizedParties = await _partiesCache.GetOrSetAsync(authorizedPartiesRequest.GenerateCacheKey(), async token
=> await PerformAuthorizedPartiesRequest(authorizedPartiesRequest, token), token: cancellationToken);

// var authorizedParties = await _partiesCache.GetOrSetAsync(authorizedPartiesRequest.GenerateCacheKey(), async token
// => await PerformAuthorizedPartiesRequest(authorizedPartiesRequest, token), token: cancellationToken);
var authorizedParties = await PerformAuthorizedPartiesRequest(authorizedPartiesRequest, cancellationToken);
return flatten ? GetFlattenedAuthorizedParties(authorizedParties) : authorizedParties;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Altinn.Authorization.ABAC.Xacml.JsonProfile;
using System.Diagnostics;
using Altinn.Authorization.ABAC.Xacml.JsonProfile;
using System.Security.Claims;

using Digdir.Domain.Dialogporten.Application.Common.Extensions;
using Digdir.Domain.Dialogporten.Application.Externals.AltinnAuthorization;
using Digdir.Domain.Dialogporten.Domain.Parties;
Expand All @@ -10,20 +12,29 @@ namespace Digdir.Domain.Dialogporten.Infrastructure.Altinn.Authorization;
internal static class DecisionRequestHelper
{
private const string SubjectId = "s1";
private const string AltinnUrnNsPrefix = "urn:altinn:";

private const string PidClaimType = "pid";
private const string ConsumerClaimType = "consumer";
private const string UserIdClaimType = "urn:altinn:userid";
private const string RarAuthorizationDetailsClaimType = "authorization_details";

private const string AttributeIdAction = "urn:oasis:names:tc:xacml:1.0:action:action-id";
private const string AttributeIdResource = "urn:altinn:resource";
private const string AttributeIdResourceInstance = "urn:altinn:resourceinstance";
private const string AltinnAutorizationDetailsClaim = "authorization_details";
private const string AttributeIdSubResource = "urn:altinn:subresource";

private const string AttributeIdOrg = "urn:altinn:org";
private const string AttributeIdApp = "urn:altinn:app";
private const string AttributeIdSystemUser = "urn:altinn:systemuser:uuid";
private const string AttributeIdAppInstance = "urn:altinn:instance-id";

private const string AttributeIdUserId = "urn:altinn:userid";
private const string AttributeIdPerson = "urn:altinn:person:identifier-no";
private const string AttributeIdSystemUser = "urn:altinn:systemuser:uuid";

// The order of these attribute types is important as we want to prioritize the most specific claim types.
private static readonly List<string> PrioritizedClaimTypes = [AttributeIdUserId, AttributeIdPerson, AttributeIdSystemUser];

private const string ReservedResourcePrefixForApps = "app_";
private const string AttributeIdAppInstance = "urn:altinn:instance-id";
private const string AttributeIdSubResource = "urn:altinn:subresource";

private const string PermitResponse = "Permit";

public static XacmlJsonRequestRoot CreateDialogDetailsRequest(DialogDetailsAuthorizationRequest request)
Expand Down Expand Up @@ -71,39 +82,42 @@ public static DialogDetailsAuthorizationResult CreateDialogDetailsResponse(List<
};
}

private static List<XacmlJsonCategory> CreateAccessSubjectCategory(IEnumerable<Claim> claims)
{
var attributes = claims
.Select(x => x switch
private static List<XacmlJsonCategory> CreateAccessSubjectCategory(IEnumerable<Claim> claims) =>
// The PDP expects for the most part only a single subject attribute, and will even fail the request
// for some types (e.g. the urn:altinn:systemuser:uuid) if there are multiple subject attributes (for
// security reasons). We therefore need to filter out the relevant attributes and only include those,
// which in essence is the pid and the system user uuid. In addition, we also utilize urn:altinn:userid
// if present instead of the pid as a simple optimization as this offloads the PDP from having to look up
// the user id from the pid. See PrioritizedClaimTypes for the order of prioritization.
claims.Select(claim => claim.Type switch
{
UserIdClaimType => new XacmlJsonCategory
{
{ Type: PidClaimType } => new XacmlJsonAttribute { AttributeId = NorwegianPersonIdentifier.Prefix, Value = x.Value },
{ Type: var type } when type.StartsWith(AltinnUrnNsPrefix, StringComparison.Ordinal) => new() { AttributeId = type, Value = x.Value },
{ Type: ConsumerClaimType } when x.TryGetOrganizationNumber(out var organizationNumber) => new() { AttributeId = NorwegianOrganizationIdentifier.Prefix, Value = organizationNumber },
{ Type: AltinnAutorizationDetailsClaim } => new() { AttributeId = AttributeIdSystemUser, Value = GetSystemUserId(x) },
_ => null
})
.Where(x => x is not null)
.Cast<XacmlJsonAttribute>()
.ToList();

// If we're authorizing a person (i.e. ID-porten token), we are not interested in the consumer-claim (organization number)
// as that is not relevant for the authorization decision (it's just the organization owning the OAuth client).
// The same goes if urn:altinn:userid is present, which might be present if using a legacy enterprise user token
if (attributes.Any(x => x.AttributeId == NorwegianPersonIdentifier.Prefix) ||
attributes.Any(x => x.AttributeId == AttributeIdUserId))
Id = SubjectId,
Attribute = [new() { AttributeId = AttributeIdUserId, Value = claim.Value }]
},
PidClaimType => new XacmlJsonCategory
{
Id = SubjectId,
Attribute = [new() { AttributeId = AttributeIdPerson, Value = claim.Value }]
},
RarAuthorizationDetailsClaimType when new ClaimsPrincipal(new ClaimsIdentity(new[] { claim })).TryGetSystemUserId(out var systemUserId) => new XacmlJsonCategory
{
Id = SubjectId,
Attribute =
[
new XacmlJsonAttribute { AttributeId = AttributeIdSystemUser, Value = systemUserId }
]
},
_ => null
})
.Where(x => x != null)
.MinBy(x => PrioritizedClaimTypes.IndexOf(x!.Attribute[0].AttributeId)) switch
{
attributes.RemoveAll(x => x.AttributeId == NorwegianOrganizationIdentifier.Prefix);
}

return [new() { Id = SubjectId, Attribute = attributes }];
}

private static string GetSystemUserId(Claim claim)
{
var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity([claim]));
claimsPrincipal.TryGetSystemUserId(out var systemUserId);
return systemUserId!;
}
{ } validCategory => new List<XacmlJsonCategory> { validCategory },
_ => throw new UnreachableException(
"Unable to find a suitable subject attribute for the authorization request. Having a known user type should be enforced during authentication (see UserTypeValidationMiddleware)."),
};

private static List<XacmlJsonCategory> CreateActionCategories(
List<AltinnAction> altinnActions, out Dictionary<string, string> actionIdByName)
Expand Down
Loading

0 comments on commit f114ca3

Please sign in to comment.