Skip to content

Commit

Permalink
Merge branch 'main' into performance/improve-serviceowner-search-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dagfinno committed Feb 28, 2025
2 parents f4ce279 + 7b97cea commit e9dec01
Show file tree
Hide file tree
Showing 14 changed files with 174 additions and 27 deletions.
7 changes: 7 additions & 0 deletions .azure/infrastructure/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ param appInsightsSku AppInsightsSku

import { Sku as PostgresSku } from '../modules/postgreSql/create.bicep'
import { StorageConfiguration as PostgresStorageConfig } from '../modules/postgreSql/create.bicep'
import { HighAvailabilityConfiguration as PostgresHighAvailabilityConfig } from '../modules/postgreSql/create.bicep'

param postgresConfiguration {
sku: PostgresSku
storage: PostgresStorageConfig
enableIndexTuning: bool
enableQueryPerformanceInsight: bool
highAvailability: PostgresHighAvailabilityConfig?
backupRetentionDays: int
availabilityZone: string
}

import { Sku as ServiceBusSku } from '../modules/serviceBus/main.bicep'
Expand Down Expand Up @@ -214,6 +218,9 @@ module postgresql '../modules/postgreSql/create.bicep' = {
enableQueryPerformanceInsight: postgresConfiguration.enableQueryPerformanceInsight
subnetId: vnet.outputs.postgresqlSubnetId
vnetId: vnet.outputs.virtualNetworkId
highAvailability: postgresConfiguration.?highAvailability
backupRetentionDays: postgresConfiguration.backupRetentionDays
availabilityZone: postgresConfiguration.availabilityZone
tags: tags
}
}
Expand Down
6 changes: 6 additions & 0 deletions .azure/infrastructure/prod.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ param postgresConfiguration = {
}
enableIndexTuning: false
enableQueryPerformanceInsight: false
highAvailability: {
mode: 'ZoneRedundant'
standbyAvailabilityZone: '2'
}
backupRetentionDays: 32
availabilityZone: '3'
}

param redisSku = {
Expand Down
2 changes: 2 additions & 0 deletions .azure/infrastructure/staging.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ param postgresConfiguration = {
}
enableIndexTuning: true
enableQueryPerformanceInsight: true
backupRetentionDays: 7
availabilityZone: '2'
}

param redisSku = {
Expand Down
2 changes: 2 additions & 0 deletions .azure/infrastructure/test.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ param postgresConfiguration = {
}
enableIndexTuning: false
enableQueryPerformanceInsight: true
backupRetentionDays: 7
availabilityZone: '1'
}

param redisSku = {
Expand Down
2 changes: 2 additions & 0 deletions .azure/infrastructure/yt01.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ param postgresConfiguration = {
}
enableIndexTuning: true
enableQueryPerformanceInsight: true
backupRetentionDays: 7
availabilityZone: '1'
}

param redisSku = {
Expand Down
23 changes: 23 additions & 0 deletions .azure/modules/postgreSql/create.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ param enableIndexTuning bool
@description('The name of the Application Insights workspace')
param appInsightWorkspaceName string

@export()
type HighAvailabilityConfiguration = {
mode: 'ZoneRedundant' | 'SameZone' | 'Disabled'
standbyAvailabilityZone: string
}

@description('High availability configuration for the PostgreSQL server')
param highAvailability HighAvailabilityConfiguration?

@description('The availability zone for the PostgreSQL primary server')
param availabilityZone string

@description('The number of days to retain backups.')
@minValue(7)
@maxValue(35)
param backupRetentionDays int

@description('The Key Vault to store the PostgreSQL administrator login password')
@secure()
param srcKeyVault object
Expand Down Expand Up @@ -98,6 +115,10 @@ resource postgres 'Microsoft.DBforPostgreSQL/flexibleServers@2024-08-01' = {
autoGrow: storage.autoGrow
type: storage.type
}
backup: {
backupRetentionDays: backupRetentionDays
geoRedundantBackup: 'Disabled'
}
dataEncryption: {
type: 'SystemManaged'
}
Expand All @@ -106,6 +127,8 @@ resource postgres 'Microsoft.DBforPostgreSQL/flexibleServers@2024-08-01' = {
delegatedSubnetResourceId: subnetId
privateDnsZoneArmResourceId: privateDnsZone.outputs.id
}
availabilityZone: availabilityZone
highAvailability: highAvailability
}
sku: sku
resource database 'databases' = {
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci-cd-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:

deploy-infra:
name: Deploy infra to prod
if: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasInfraChanges == 'true' }}
if: ${{ needs.check-for-changes.outputs.hasInfraChanges == 'true' }}
needs: [check-for-changes]
uses: ./.github/workflows/workflow-deploy-infra.yml
secrets:
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
name: Deploy apps to prod
needs:
[check-for-changes]
if: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true' }}
if: ${{ always() && !failure() && !cancelled() && needs.check-for-changes.outputs.hasBackendChanges == 'true' }}
uses: ./.github/workflows/workflow-deploy-apps.yml
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
Expand All @@ -96,7 +96,7 @@ jobs:
environment: prod
region: norwayeast
version: ${{ inputs.version }}
runMigration: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasMigrationChanges == 'true' }}
runMigration: ${{ needs.check-for-changes.outputs.hasMigrationChanges == 'true' }}
ref: "refs/tags/v${{ inputs.version }}"

publish-sdk-to-nuget:
Expand All @@ -113,7 +113,7 @@ jobs:
store-apps-version:
name: Store Latest Deployed Apps Version as GitHub Variable
needs: [deploy-apps]
if: ${{ always() && !failure() && (github.event_name == 'workflow_dispatch' || needs.deploy-apps.outputs.deployment_executed == 'true') }}
if: ${{ always() && !failure() && (needs.deploy-apps.outputs.deployment_executed == 'true') }}
uses: ./.github/workflows/workflow-store-github-env-variable.yml
with:
variable_name: LATEST_DEPLOYED_APPS_VERSION
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# pg_dump backups
*.dump

# Local User-specific application configuration
appsettings.local.json

Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.55.5"
".": "1.56.1"
}
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## [1.56.1](https://github.com/Altinn/dialogporten/compare/v1.56.0...v1.56.1) (2025-02-27)


### Bug Fixes

* **infra:** ensure we set az for primary in postgresql ([#1973](https://github.com/Altinn/dialogporten/issues/1973)) ([b4fd665](https://github.com/Altinn/dialogporten/commit/b4fd665c2500af6c4beb27e563d6c9e2134349b6))

## [1.56.0](https://github.com/Altinn/dialogporten/compare/v1.55.5...v1.56.0) (2025-02-26)


### Features

* **infra:** enable HA and increase retention for postgresql ([#1955](https://github.com/Altinn/dialogporten/issues/1955)) ([84a3fc6](https://github.com/Altinn/dialogporten/commit/84a3fc6e6208ab0ed57de503a248ee303bca795a))


### Miscellaneous Chores

* **e2e:** put filter on createdAfter for search in cleanup-step e2e-tests ([#1970](https://github.com/Altinn/dialogporten/issues/1970)) ([f9d2099](https://github.com/Altinn/dialogporten/commit/f9d2099ba44bde76f67b772ed3fb3db80aefb55e))

## [1.55.5](https://github.com/Altinn/dialogporten/compare/v1.55.4...v1.55.5) (2025-02-26)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
<PackageId>Altinn.ApiClients.Dialogporten</PackageId>
<AssemblyName>Altinn.ApiClients.Dialogporten</AssemblyName>
<RootNamespace>Altinn.ApiClients.Dialogporten</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591,1573</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,73 @@

namespace Altinn.ApiClients.Dialogporten;

/// <summary>
/// Represents a service that can validate a dialog token.
/// </summary>
public interface IDialogTokenValidator
{
/// <summary>
/// Validates a dialog token.
/// </summary>
/// <param name="token">The token to validate.</param>
/// <param name="dialogId">The optional dialog ID associated with the token. If the token does not represent this ID, the validation will fail.</param>
/// <param name="requiredActions">The optional list of required actions for the token.</param>
/// <param name="options">The optional validation parameters.</param>
/// <returns>The result of the validation.</returns>
IValidationResult Validate(ReadOnlySpan<char> token,
Guid? dialogId = null,
string[]? requiredActions = null,
DialogTokenValidationParameters? options = null);
}

/// <summary>
/// Represents the parameters used to validate a dialog token.
/// </summary>
/// <remarks>
/// Global defaults are provided by and can be altered through <see cref="DialogTokenValidationParameters.Default"/>.
/// </remarks>
public class DialogTokenValidationParameters
{
/// <summary>
/// Gets the default validation parameters which are used when no parameters are provided.
/// </summary>
/// <remarks>
/// This may be altered to change the global default behavior of the validation.
/// </remarks>
public static DialogTokenValidationParameters Default { get; } = new();

/// <summary>
/// Gets or sets a value indicating whether to validate the token's lifetime.
/// </summary>
public bool ValidateLifetime { get; set; } = true;

/// <summary>
/// Gets or sets the clock skew to apply when validating the token's lifetime.
/// </summary>
public TimeSpan ClockSkew { get; set; } = TimeSpan.FromSeconds(10);
}

/// <summary>
/// Represents the result of a dialog token validation.
/// </summary>
public interface IValidationResult
{
/// <summary>
/// Indicates whether the token is valid based on the validation parameters.
/// </summary>
[MemberNotNullWhen(true, nameof(ClaimsPrincipal))]
bool IsValid { get; }

/// <summary>
/// A dictionary of errors that occurred during validation.
/// </summary>
Dictionary<string, List<string>> Errors { get; }

/// <summary>
/// The <see cref="ClaimsPrincipal"/> extracted from the token.
/// </summary>
/// <remarks>
/// This property will not be null if the token is valid. It will be null if the token has an invalid format.
/// </remarks>
ClaimsPrincipal? ClaimsPrincipal { get; }
}
75 changes: 54 additions & 21 deletions src/Digdir.Library.Dialogporten.WebApiClient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,72 @@ Uses refit IApiResponse on returns.

## Installation

Install nuget
Install the [nuget package](https://www.nuget.org/packages/Altinn.ApiClients.Dialogporten) through Package Manager Console:
```
Install-Package Altinn.ApiClients.Dialogporten
```

`dotnet add package Altinn.ApiClients.Dialogporten --version 1.55.2`
Or via .NET Core CLI:
```
dotnet add package Altinn.ApiClients.Dialogporten
```

## Usage
This package needs some configuration to work. The configuration is done through the `DialogportenSettings` class. The settings are as follows:
- `BaseUri` - The base URI of the Dialogporten API.
- `ThrowOnPublicKeyFetchInit` - If true, the client will throw an exception if the public key fetch fails on startup. Default true.
- `Maskinporten` - The [Maskinporten settings](https://github.com/Altinn/altinn-apiclient-maskinporten).
- `ClientId` - The client ID (secret).
- `EncodedJwk` - The encoded JWK (secret).
- `Environment` - The environment (test/prod).
- `Scope` - Whitespace separated list of scopes to use against Dialogporten.

This library provides extensions methods providing means to create dialogporten clients.
### Registering with `IServiceCollection`
There are two ways to register

Setup
#### Register through [action parameter](https://learn.microsoft.com/en-us/dotnet/core/extensions/options-library-authors#actiontoptions-parameter):
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDialogportenClient(x =>
{
x.BaseUri = "https://platform.tt02.altinn.no/dialogporten";
// x.ThrowOnPublicKeyFetchInit = false;
x.Maskinporten.ClientId = "YOUR_CLIENT_ID";
x.Maskinporten.EncodedJwk = "YOUR_ENCODED_JWK";
x.Maskinporten.Environment = "test";
x.Maskinporten.Scope = "digdir:dialogporten.serviceprovider digdir:dialogporten.serviceprovider.search";
}
```

```json
#### Register through [options instance parameter](https://learn.microsoft.com/en-us/dotnet/core/extensions/options-library-authors#options-instance-parameter):
```csharp
var builder = WebApplication.CreateBuilder(args);
var dialogportenSettings = builder.Configuration
.GetSection("DialogportenSettings")
.Get<DialogportenSettings>()!;
builder.Services.AddDialogportenClient(dialogportenSettings);
```
In this case, the configuration should look like this:
```json5
{
"dialogportenSettings": {
"BaseUri": "",
"ThrowOnPublicKeyFetchInit": "",
"DialogportenSettings": {
"BaseUri": "https://platform.tt02.altinn.no/dialogporten",
// "ThrowOnPublicKeyFetchInit": false,
"Maskinporten": {
"ClientId": "",
"Environment": "",
"Scope": "",
"EncodedJwk": ""
"ClientId": "YOUR_CLIENT_ID",
"EncodedJwk": "YOUR_ENCODED_JWK",
"Environment": "test",
"Scope": "digdir:dialogporten.serviceprovider digdir:dialogporten.serviceprovider.search"
}
}
}
```

```C#
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
### Available services
The following services are available after registration:
- [`Altinn.ApiClients.Dialogporten.Features.V1.IServiceownerApi`](./Features/V1/RefitterInterface.cs) - Used to interact with the Dialogporten ServiceOwner API.
- [`Altinn.ApiClients.Dialogporten.IDialogTokenValidator`](IDialogTokenValidator.cs) - Used to validate Dialogporten tokens.

var services = new ServiceCollection();
A background service (`IHostedService`) is also registered that periodically fetches the public key from the Dialogporten API. This is required to validate dialog token signatures.

services.AddSingleton<IConfiguration>(configuration);

services.AddDialogportenClient();
```
See [sample project](../Digdir.Library.Dialogporten.WebApiClient.WebApiSample/Program.cs) for examples on how to use the services.
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.55.5
1.56.1

0 comments on commit e9dec01

Please sign in to comment.