Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .azuredevops/pipelines/build-dr-func-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ trigger:
- releases/*

pool:
vmImage: ubuntu-latest
name: mdp-mgmt-shared
demands:
- ImageOverride -equals $(PipelineHostLinuxImage)

variables:
- group: artifacts
- group: PT-Pipeline-Common

steps:

Expand Down
4 changes: 3 additions & 1 deletion .azuredevops/pipelines/build-dr-func.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ variables:
- group: PT-Pipeline-Common

pool:
vmImage: $(Pipeline_Host_Image)
name: mdp-mgmt-shared
demands:
- ImageOverride -equals $(PipelineHostLinuxImage)

steps:
- task: UseDotNet@2
Expand Down
7 changes: 6 additions & 1 deletion .azuredevops/pipelines/build-for-fapi-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
trigger:
- none

variables:
- group: PT-Pipeline-Common

pool:
vmImage: ubuntu-latest
name: mdp-mgmt-shared
demands:
- ImageOverride -equals $(PipelineHostLinuxImage)

jobs:
- job: Build
Expand Down
45 changes: 43 additions & 2 deletions .azuredevops/pipelines/build-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,57 @@
include:
- develop

resources:
repositories:
- repository: shared-code-scanning
type: git
name: Common/shared-code-scanning
ref: refs/heads/main
trigger: none

trigger:
- develop
- main
- releases/*

parameters:
# https://github.com/microsoft/azure-pipelines-yaml/blob/master/design/runtime-parameters.md#syntax
- name: MockRegisterOverrideDependentImageTag
type: string
default: ' ' # default value; if no default, then the parameter MUST be given by the user at runtime
- name: forcePublish
type: boolean
displayName: |
Force publishing of image to ACR. When this is unticked, only builds of the main/develop branch will publish an image to ACR.
default: false

variables:
- group: artifacts
- group: PT-Pipeline-Common
- name: baseSourceDirectory
value: $(Build.SourcesDirectory)/Source


pool:
vmImage: ubuntu-latest
name: mdp-mgmt-shared
demands:
- ImageOverride -equals $(PipelineHostLinuxImage)


jobs:
- job: Build
timeoutInMinutes: 120
steps:
- script: |
echo "Cleaning auth-server folder in temp"
ls $(Agent.BuildDirectory)/s/Source/_temp/cdr-auth-server-* 2>/dev/null || "No matching folders found"
sudo rm -rf $(Agent.BuildDirectory)/s/Source/_temp/cdr-auth-server-* 2> /dev/null
displayName: Clean temp auth-server folders
condition: always()

- checkout : self
clean: true

# set the register tag to use based on the logic in the template file
- template: set-tag-name.yml
parameters:
Expand Down Expand Up @@ -123,6 +151,11 @@
docker build $(baseSourceDirectory) -f $(baseSourceDirectory)/Dockerfile.standalone -t cdr-auth-server-standalone:latest
docker image ls

- template: templates/scan-image.yml@shared-code-scanning
parameters:
Repository: cdr-auth-server-standalone
Tag: latest

###################################################################################################
# Integration tests
###################################################################################################
Expand Down Expand Up @@ -407,11 +440,19 @@

- task: Bash@3
displayName: 'Tag and push Authorisation Server image with Source Branch Name for any successful builds.'
condition: succeeded()
condition: and(
succeeded(),
or(
${{ eq(parameters.forcePublish, true) }},
eq(variables['Build.SourceBranch'], 'refs/heads/develop'),
eq(variables['Build.SourceBranch'], 'refs/heads/main'),
startsWith(variables['Build.SourceBranch'], 'refs/heads/releases/')
)
)
inputs:
targetType: inline
script: |
echo Tagging cdr-auth-server-standalone with Source Branch Name: $(Build.SourceBranchName)

Check failure on line 455 in .azuredevops/pipelines/build-v2.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Change this step to not use user-controlled data directly in the argument 'script'.

See more on https://sonarcloud.io/project/issues?id=ConsumerDataRight_authorisation-server&issues=AZ8_ReCUYH4jE23GQzUK&open=AZ8_ReCUYH4jE23GQzUK&pullRequest=31
docker tag cdr-auth-server-standalone $(SharedAcrBaseUrl).azurecr.io/cdr-auth-server-standalone:$(Build.SourceBranchName)

echo Pushing all tags to $(SharedAcrBaseUrl).azurecr.io/cdr-auth-server-standalone
Expand All @@ -426,7 +467,7 @@
echo Tagging cdr-auth-server-standalone with latest tag
docker tag cdr-auth-server-standalone $(SharedAcrBaseUrl).azurecr.io/cdr-auth-server-standalone:latest

echo Tagging cdr-auth-server-standalone with Source Branch Name-latest: $(Build.SourceBranchName)-latest

Check failure on line 470 in .azuredevops/pipelines/build-v2.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Change this step to not use user-controlled data directly in the argument 'script'.

See more on https://sonarcloud.io/project/issues?id=ConsumerDataRight_authorisation-server&issues=AZ8_ReCUYH4jE23GQzUL&open=AZ8_ReCUYH4jE23GQzUL&pullRequest=31
docker tag cdr-auth-server-standalone $(SharedAcrBaseUrl).azurecr.io/cdr-auth-server-standalone:$(Build.SourceBranchName)-latest

if [ -n "$(ObligationDate)" ]; then
Expand Down
7 changes: 6 additions & 1 deletion .azuredevops/pipelines/code-scanning.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ schedules:
# Disable standard CI build
trigger: none

variables:
- group: PT-Pipeline-Common

pool:
vmImage: 'ubuntu-latest'
name: mdp-mgmt-shared
demands:
- ImageOverride -equals $(PipelineHostLinuxImage)

extends:
template: pipeline-templates/code-scanning.yml@shared-code-scanning
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,25 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [3.1.0] - 2026-06-01
### Changed
- Migrated CDR Auth Server Standalone (CdrAuthServer.UI) from CRA to Vite
- Updated docker build (Dockerfile.standalone) to use Node 24.x
- Upgraded UI to use mui9
- Updated NuGet packages to address vulnerabilities

## [3.0.6] - 2026-06-17
### Fixed
- Patched vulnerabilities

### Added
- Enable Application insights as a logging destination

## [3.0.5] - 2026-03-18
### Changed
- Rebuild project to fix vulnerabilities in base image

## [3.0.4] - 2025-12-10
### Changed
Expand Down
45 changes: 45 additions & 0 deletions Source/CdrAuthServer.API.Logger/ApplicationInsightsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using CdrAuthServer.API.Logger;
using CdrAuthServer.Configuration;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Serilog;

/// <summary>
/// Extension functionality for configuring Application Insights.
/// </summary>
public static class ApplicationInsightsExtensions
{
/// <summary>
/// Conditionally enable Application Insights if any of the following Application Insights configuration values:
/// <list type="bullet">
/// <item><see cref="ApplicationInsightsKeys.ConnectionString">APPLICATIONINSIGHTS_CONNECTION_STRING</see></item>
/// </list>
/// </summary>
/// <param name="loggerConfiguration">The existing logger configuration to which ApplicationInsights needs to be added.</param>
/// <param name="telemetryConfiguration">The telemetry configuration.</param>
/// <param name="configuration">The application configuration.</param>
/// <returns>The logger configuration with Application Insights sink configured (if applicable).</returns>
public static LoggerConfiguration AddApplicationInsights(this LoggerConfiguration loggerConfiguration, TelemetryConfiguration? telemetryConfiguration, IConfiguration configuration)
{
var connectionString = configuration.GetValue<string>(ApplicationInsightsKeys.ConnectionString);

if (connectionString is not null)
{
loggerConfiguration.WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces);
}

return loggerConfiguration;
}

/// <summary>
/// Add application insights with register specific considerations.
/// </summary>
/// <param name="services">The services collection.</param>
public static void AddCdrApplicationInsights(this IServiceCollection services)
{
services.AddSingleton<ITelemetryInitializer, CdrApplicationInitializer>();
services.AddApplicationInsightsTelemetry();
}
}
13 changes: 13 additions & 0 deletions Source/CdrAuthServer.API.Logger/ApplicationInsightsKeys.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace CdrAuthServer.Configuration
{
/// <summary>
/// The names of environment variables / configuration keys that configure the underlying Telemetry Client used by the <see cref="Serilog.Sinks.ApplicationInsights.ApplicationInsightsSink">ApplicationInsightsSink</see>.
/// </summary>
public static class ApplicationInsightsKeys
{
/// <summary>
/// The Connection string for Application Insights.
/// </summary>
public const string ConnectionString = "APPLICATIONINSIGHTS_CONNECTION_STRING";
}
}
21 changes: 21 additions & 0 deletions Source/CdrAuthServer.API.Logger/CdrApplicationInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Reflection;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;

namespace CdrAuthServer.API.Logger;

public class CdrApplicationInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
var ass = Assembly.GetEntryAssembly()?.GetName();

if (ass is null)
{
return;
}

telemetry.Context.Component.Version = ass.Version?.ToString();
telemetry.Context.Cloud.RoleName = ass.Name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" />
<PackageReference Include="Serilog.Settings.Configuration" />
<PackageReference Include="Serilog.Sinks.OpenTelemetry">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="Serilog.Sinks.MSSqlServer">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.Reflection;
using CdrAuthServer.Configuration;
using Microsoft.Extensions.Configuration;

namespace Serilog
{
/// <summary>
/// Extension functionality for configuration OpenTelemetry.
/// Extension functionality for configuring OpenTelemetry.
/// </summary>
public static class OpenTelemetryConfigurationExtensions
{
Expand Down
5 changes: 4 additions & 1 deletion Source/CdrAuthServer.API.Logger/RequestResponseLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ public ILogger Log
get { return _logger; }
}

public RequestResponseLogger(IConfiguration configuration)
public RequestResponseLogger(IConfiguration configuration, Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryConfiguration)
{
var loggerConfiguration = new LoggerConfiguration();

// If the Serilog response loggins is disabled, do not configure it using the appsettings.
var isSerilogRequestResponseLoggerDisabled =
configuration.GetValue<bool>("SerilogRequestResponseLogger:IsDisabled", false);

if (isSerilogRequestResponseLoggerDisabled)
{
_logger = loggerConfiguration.CreateLogger();
Expand All @@ -30,6 +31,8 @@ public RequestResponseLogger(IConfiguration configuration)
var options = new ConfigurationReaderOptions { SectionName = "SerilogRequestResponseLogger" };
_logger = loggerConfiguration
.ReadFrom.Configuration(configuration, options)
.AddOpenTelemetry(configuration)
.AddApplicationInsights(telemetryConfiguration, configuration)
.Enrich.WithProperty("RequestMethod", string.Empty)
.Enrich.WithProperty("RequestBody", string.Empty)
.Enrich.WithProperty("RequestHeaders", string.Empty)
Expand Down
1 change: 1 addition & 0 deletions Source/CdrAuthServer.Domain/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static class ClaimNames
public const string ErrorDescription = "error_description";
public const string AuthTime = "auth_time";
public const string UpdatedAt = "updated_at";
public const string RecipientBaseUri = "recipient_base_uri";
}

public static class TokenTypes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using CdrAuthServer.Domain.Entities;

namespace CdrAuthServer.Domain.Repositories
{
public interface IArrangementsRepository
{
/// <summary>
/// Gets the CDR Arrangement Ids for clients matching the specified software product ids.
/// </summary>
/// <param name="softwareProductIds">The software product ids for which to find arrangements.</param>
/// <returns>The <c>cdr_arrangement_id</c> values for the provided <paramref name="softwareProductIds"/>.</returns>
Task<IEnumerable<(Client Client, string ArrangementId)>> GetArrangementIdsForSoftwareProducts(IEnumerable<string> softwareProductIds);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using System.Net;
using Xunit;
using Xunit.DependencyInjection;
using static IdentityModel.OidcConstants;
using Constants = ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Constants;

namespace CdrAuthServer.IntegrationTests.JARM
Expand Down
35 changes: 35 additions & 0 deletions Source/CdrAuthServer.Repository/ArrangementsRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace CdrAuthServer.Repository
{
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using CdrAuthServer.Domain;
using CdrAuthServer.Domain.Entities;
using CdrAuthServer.Domain.Repositories;
using CdrAuthServer.Repository.Infrastructure;
using Microsoft.EntityFrameworkCore;

public class ArrangementsRepository(CdrAuthServerDatabaseContext dbContext, IMapper mapper) : IArrangementsRepository
{
/// <inheritdoc />
public async Task<IEnumerable<(Client, string)>> GetArrangementIdsForSoftwareProducts(IEnumerable<string> softwareProductIds)
{
var arrangements = await dbContext.ClientClaims
.Where(claims => claims.Type == Constants.ClaimNames.SoftwareId)
.Where(claim => softwareProductIds.Contains(claim.Value))
.Join(
dbContext.Grants.Where(grant => grant.GrantType == Constants.GrantTypes.CdrArrangement),
claim => claim.ClientId,
grant => grant.ClientId,
(claim, grant) => new { claim.Client, ArrangementId = grant.Key, RecipientBaseUri = claim.Client.ClientClaims!.OrderBy(x => x.Id).Last(x => x.Type == Constants.ClaimNames.RecipientBaseUri) }) // The grant key is the cdr_arrangement_id
.ToArrayAsync();

return arrangements.Select(x =>
{
var client = mapper.Map<Client>(x.Client);
client.RecipientBaseUri = x.RecipientBaseUri.Value;
return (client, x.ArrangementId);
});
}
}
}
Loading
Loading