diff --git a/.azuredevops/pipelines/build-v2.yml b/.azuredevops/pipelines/build-v2.yml
index 5256325..851bc65 100644
--- a/.azuredevops/pipelines/build-v2.yml
+++ b/.azuredevops/pipelines/build-v2.yml
@@ -173,8 +173,8 @@ steps:
BasePath: '$(BasePath)'
PublicHostName: '$(CtsPublicHostNameUrl)'
SecureHostName: '$(CtsSecureHostNameUrl)'
- Certificate__CertThumbprintNameHttpHeaderName: 'X-SSLClientCertThumbprint'
- Certificate__CertCommonNameHttpHeaderName: 'X-SSLClientCertCN'
+ Certificate__CertThumbprintNameHttpHeaderName: '$(CtsSettings__CertThumbprintNameHttpHeaderName)'
+ Certificate__CertCommonNameHttpHeaderName: '$(CtsSettings_CertCommonNameHttpHeaderName)'
# Run trx formatter to output .MD and .CSV
- script: |
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 5870a61..2f1a244 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -55,11 +55,11 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -70,7 +70,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
- uses: github/codeql-action/autobuild@v2
+ uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -84,4 +84,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 18c1240..1dcea1f 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout Register
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
path: ./mock-register
@@ -84,7 +84,7 @@ jobs:
# Archive unit test results
- name: Archive unit test results
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
if: always()
with:
name: unit-test-results
@@ -92,7 +92,7 @@ jobs:
# Archive integration test results
- name: Archive integration test results
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
if: always()
with:
name: integration-test-results
@@ -100,7 +100,7 @@ jobs:
# Archive mock register logs
- name: Archive mock register logs
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
if: always()
with:
name: integration-test-artifacts
diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml
index 35a8131..516447c 100644
--- a/.github/workflows/sonarcloud-analysis.yml
+++ b/.github/workflows/sonarcloud-analysis.yml
@@ -37,7 +37,7 @@ jobs:
with:
java-version: 17
distribution: 'zulu' # Alternative distribution options are available.
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
if: ${{ env.sonarSecret != 0 }} # Only run scan if secret use is allowed - requires secrets to run successfully
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml
index e9ddb8c..ced2e2a 100644
--- a/.github/workflows/test-report.yml
+++ b/.github/workflows/test-report.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Publish Unit Test Report
uses: dorny/test-reporter@v1
@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Publish Integration Test Report
uses: dorny/test-reporter@v1
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6fab27f..ff9afa6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [2.2.0] - 2025-03-19
+### Changed
+- Updated NuGet packages
+- Fixed multiple build warnings to improve code quality and maintainability
+
## [2.1.0] - 2024-08-16
### Changed
- Updated NuGet packages
diff --git a/README.md b/README.md
index a681fbb..c124a03 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@

-[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.31.0/#introduction)
+[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.33.0/#introduction)
[](https://dotnet.microsoft.com/)
[](https://docs.microsoft.com/en-us/dotnet/csharp/)
[](./LICENSE)
@@ -12,7 +12,7 @@ This project includes source code, documentation and instructions for the Consum
The ACCC operates the CDR Register within the CDR ecosystem. This repository contains a mock implementation of the CDR Register and is offered to help the community in the development and testing of their CDR solutions.
## Mock Register - Alignment
-The Mock Register aligns to [v1.31.0](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.31.0/#introduction) of the [Consumer Data Standards](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.31.0/#introduction).
+The Mock Register aligns to [v1.33.0](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.33.0/#introduction) of the [Consumer Data Standards](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.33.0/#introduction).
## Getting Started
There are a number of ways that the artefacts within this project can be used:
diff --git a/SECURITY.md b/SECURITY.md
index b434d53..a55db80 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -11,7 +11,7 @@ Visit our [Responsible disclosure of security vulnerabilities policy](https://ww
| Version | Supported |
| ------- | ------------------ |
-| 2.1.x | :white_check_mark: |
+| 2.2.x | :white_check_mark: |
| 1.x.x | :x: |
## Reporting a Vulnerability
diff --git a/Source/.editorconfig b/Source/.editorconfig
new file mode 100644
index 0000000..6487a11
--- /dev/null
+++ b/Source/.editorconfig
@@ -0,0 +1,286 @@
+# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
+###############################
+# Core EditorConfig Options #
+###############################
+# All files
+[*]
+indent_style = space
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+indent_size = 4
+end_of_line = crlf
+dotnet_style_namespace_match_folder = true:suggestion
+# Code files
+[*.{cs,csx}]
+indent_size = 4
+insert_final_newline = true
+charset = utf-8-bom
+###############################
+# .NET Coding Conventions #
+###############################
+[*.{cs}]
+# Organize usings
+dotnet_sort_system_directives_first = true
+# this. preferences
+dotnet_style_qualification_for_field = false:silent
+dotnet_style_qualification_for_property = false:silent
+dotnet_style_qualification_for_method = false:silent
+dotnet_style_qualification_for_event = false:silent
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:silent
+dotnet_style_predefined_type_for_member_access = true:silent
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
+dotnet_style_readonly_field = true:suggestion
+# Expression-level preferences
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+###############################
+# Naming Conventions #
+###############################
+# Style Definitions
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+# Use PascalCase for constant fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+dotnet_diagnostic.SA1309.severity = none
+dotnet_diagnostic.SA1310.severity = none
+###############################
+# C# Coding Conventions #
+###############################
+[*.cs]
+# var preferences
+csharp_style_var_for_built_in_types = true:silent
+csharp_style_var_when_type_is_apparent = true:silent
+csharp_style_var_elsewhere = true:silent
+# Expression-bodied members
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+# Pattern matching preferences
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+# Null-checking preferences
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+# Modifier preferences
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
+# Expression-level preferences
+csharp_prefer_braces = true:silent
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+###############################
+# C# Formatting Rules #
+###############################
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+# Indentation preferences
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+# Wrapping preferences
+csharp_preserve_single_line_statements = true
+csharp_preserve_single_line_blocks = true
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_style_namespace_declarations = block_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_prefer_primary_constructors = true:suggestion
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+
+#Readability Rules
+
+#A call to an instance member of the local class or a base class is not prefixed with 'this.'
+dotnet_diagnostic.SA1101.severity = none
+
+#The parameter spans multiple lines
+dotnet_diagnostic.SA1118.severity = none
+
+#Spacing Rules
+dotnet_diagnostic.SA1010.severity = none
+
+
+#Documentation Rules
+
+# SA1600: Elements should be documented
+dotnet_diagnostic.SA1600.severity = none
+
+#file header is missing
+dotnet_diagnostic.SA1633.severity = none
+
+#Enumeration items should be documented
+dotnet_diagnostic.SA1602.severity = none
+
+# SA1623: summary text should begin with: 'Gets or sets'
+dotnet_diagnostic.SA1623.severity = none
+
+# documentation for parameter 'cdrArrangementId' is missing
+dotnet_diagnostic.SA1611.severity = none
+
+# Parameter '' has no matching param tag in the XML comment
+dotnet_diagnostic.CS1591.severity = none
+
+# Element return value should be documented
+dotnet_diagnostic.SA1615.severity = none
+
+#parameter has no matching tag in xml
+dotnet_diagnostic.CS1573.severity = none
+
+
+#Ordering Rules
+
+#static members should appear before non-static members
+dotnet_diagnostic.SA1204.severity = none
+
+# public members should come before private
+dotnet_diagnostic.SA1202.severity = none
+
+# 'public' members should come before 'private' members
+dotnet_diagnostic.SA1200.severity = none
+
+# using directive ordering
+dotnet_diagnostic.SA1208.severity = none
+
+# field should not follow class
+dotnet_diagnostic.SA1201.severity = none
+
+#Maintainability
+
+# S2325: Methods and properties that don't access instance data should be static
+dotnet_diagnostic.S2325.severity = none
+
+[*.cs]
+# Disable xUnit1013 warning
+dotnet_diagnostic.xUnit1013.severity = none
+csharp_prefer_system_threading_lock = true:suggestion
+#region should not be located within a code element
+dotnet_diagnostic.SA1123.severity = none
+dotnet_diagnostic.SA1601.severity = none
+dotnet_diagnostic.SA1616.severity = none
+dotnet_diagnostic.SA1108.severity = none
+
+# A multi-line initializer in a C# code file should use a comma on the last line.
+dotnet_diagnostic.SA1413.severity = none
+
+# Ignore rules for Testing Projects
+[/*Tests*/**]
+# SA1025: Code should not contain multiple whitespace in a row.(This is usefull for InlineData documentation.)
+dotnet_diagnostic.SA1025.severity = none
+# A C# code file contains more than one unique type.
+dotnet_diagnostic.SA1402.severity = none
+# A constant field is placed beneath a non-constant field.
+dotnet_diagnostic.SA1203.severity = none
+
+# Ignore rules for Controllers
+[**/Controllers/**]
+# This controller has multiple responsibilities and could be split into 2 smaller controllers. (https://rules.sonarsource.com/csharp/RSPEC-6960)
+dotnet_diagnostic.S6960.severity = none
+# Use model binding instead of accessing the raw request data (https://rules.sonarsource.com/csharp/RSPEC-6932)
+dotnet_diagnostic.S6932.severity = none
+# In the context of ASP.NET Core MVC web applications, both model binding and model validation are processes that take place prior to the execution of a controller action.
+dotnet_diagnostic.S6967.severity = none
+
+
+[DiscoveryDocument.cs]
+# A closing square bracket within a C# statement is not spaced correctly.(There is an issue with identifying nullable array properties.)
+dotnet_diagnostic.SA1011.severity = none
+
+[JwtSecurityTokenExtensions.cs]
+# A closing square bracket within a C# statement is not spaced correctly.(There is an issue with identifying nullable array properties.)
+dotnet_diagnostic.SA1011.severity = none
+
+[AccessToken.cs]
+# The parameters to a C# method or indexer call or declaration are not all on the same line or each on a separate line. (Test methods with many parameters)
+dotnet_diagnostic.SA1117.severity = none
+
+[JsonWebKey.cs]
+# The name of a C# element does not begin with an upper-case letter. (Json property mapping)
+dotnet_diagnostic.SA1300.severity = none
+
+[JsonWebKeySet.cs]
+# The name of a C# element does not begin with an upper-case letter. (Json property mapping)
+dotnet_diagnostic.SA1300.severity = none
+
+[ClientAssertionRequest.cs]
+# The name of a C# element does not begin with an upper-case letter. (Json property mapping)
+dotnet_diagnostic.SA1300.severity = none
+
+[AccessToken.cs]
+# The name of a C# element does not begin with an upper-case letter. (Json property mapping)
+dotnet_diagnostic.SA1300.severity = none
+
+[SoftwareStatementAssertionModel.cs]
+# The name of a C# element does not begin with an upper-case letter. (Json property mapping)
+dotnet_diagnostic.SA1300.severity = none
+
+[DataRecipientStatus.cs]
+# A C# code file contains more than one unique type.
+dotnet_diagnostic.SA1402.severity = none
+
+[ExpectedApiErrors.cs]
+# Remove this empty class, write its code or make it an "interface".
+dotnet_diagnostic.S2094.severity = none
+
+[Program.cs]
+# Using platform dependent API on a component makes the code no longer work across all platforms.
+dotnet_diagnostic.CA1416.severity = none
+
+
diff --git a/Source/CDR.Register.API.Gateway.TLS/CDR.Register.API.Gateway.TLS.csproj b/Source/CDR.Register.API.Gateway.TLS/CDR.Register.API.Gateway.TLS.csproj
index c301e8e..04ecd02 100644
--- a/Source/CDR.Register.API.Gateway.TLS/CDR.Register.API.Gateway.TLS.csproj
+++ b/Source/CDR.Register.API.Gateway.TLS/CDR.Register.API.Gateway.TLS.csproj
@@ -4,6 +4,7 @@
$(Version)
$(Version)
$(Version)
+ true
@@ -19,14 +20,23 @@
-
-
-
+
+
+
+
-
+
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
\ No newline at end of file
diff --git a/Source/CDR.Register.API.Gateway.TLS/Program.cs b/Source/CDR.Register.API.Gateway.TLS/Program.cs
index 3d0e612..4fccbed 100644
--- a/Source/CDR.Register.API.Gateway.TLS/Program.cs
+++ b/Source/CDR.Register.API.Gateway.TLS/Program.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Security.Authentication;
using Microsoft.AspNetCore.Builder;
@@ -6,7 +6,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
-using Serilog.Events;
namespace CDR.Register.API.Gateway.TLS
{
@@ -22,7 +21,7 @@ public static int Main(string[] args)
.Build();
Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
+ .ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
diff --git a/Source/CDR.Register.API.Gateway.mTLS/CDR.Register.API.Gateway.mTLS.csproj b/Source/CDR.Register.API.Gateway.mTLS/CDR.Register.API.Gateway.mTLS.csproj
index 143d4f0..8e98bcb 100644
--- a/Source/CDR.Register.API.Gateway.mTLS/CDR.Register.API.Gateway.mTLS.csproj
+++ b/Source/CDR.Register.API.Gateway.mTLS/CDR.Register.API.Gateway.mTLS.csproj
@@ -4,6 +4,7 @@
$(Version)
$(Version)
$(Version)
+ True
@@ -28,16 +29,25 @@
-
-
-
+
+
+
+
-
+
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.API.Gateway.mTLS/Program.cs b/Source/CDR.Register.API.Gateway.mTLS/Program.cs
index cea2a9f..d506ace 100644
--- a/Source/CDR.Register.API.Gateway.mTLS/Program.cs
+++ b/Source/CDR.Register.API.Gateway.mTLS/Program.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Net.Security;
using System.Security.Authentication;
@@ -8,13 +8,11 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
-using Serilog.Events;
-namespace CDR.Register.API.Gateway.mTLS
+namespace CDR.Register.API.Gateway.Mtls
{
public static class Program
{
-
public static int Main(string[] args)
{
var configuration = new ConfigurationBuilder()
@@ -25,7 +23,7 @@ public static int Main(string[] args)
.Build();
Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
+ .ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
@@ -87,13 +85,13 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
// Set the cipher suites dictated by the CDS.
- sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
- new[] {
+ sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(new[]
+ {
TlsCipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- });
+ });
};
}
});
diff --git a/Source/CDR.Register.API.Gateway.mTLS/Startup.cs b/Source/CDR.Register.API.Gateway.mTLS/Startup.cs
index a08c311..e5a6eaf 100644
--- a/Source/CDR.Register.API.Gateway.mTLS/Startup.cs
+++ b/Source/CDR.Register.API.Gateway.mTLS/Startup.cs
@@ -1,5 +1,4 @@
-using System.Configuration;
-using System.Security.Cryptography.X509Certificates;
+using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using CDR.Register.API.Infrastructure;
using CDR.Register.API.Infrastructure.Exceptions;
@@ -18,7 +17,7 @@
using Serilog;
using static System.Net.Mime.MediaTypeNames;
-namespace CDR.Register.API.Gateway.mTLS
+namespace CDR.Register.API.Gateway.Mtls
{
public class Startup
{
@@ -61,6 +60,7 @@ public void ConfigureServices(IServiceCollection services)
}
};
})
+
// Adding an ICertificateValidationCache results in certificate auth caching the results.
// The default implementation uses a memory cache.
.AddCertificateCache();
@@ -90,7 +90,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
context.Response.StatusCode = StatusCodes.Status502BadGateway;
}
-
+
context.Response.ContentType = Text.Plain;
await context.Response.WriteAsync($"An error occurred handling the request: {ex?.Message}");
});
diff --git a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/CDR.Register.API.Infrastructure.Tests.UnitTests.csproj b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/CDR.Register.API.Infrastructure.Tests.UnitTests.csproj
index 5571ba6..8c867b3 100644
--- a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/CDR.Register.API.Infrastructure.Tests.UnitTests.csproj
+++ b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/CDR.Register.API.Infrastructure.Tests.UnitTests.csproj
@@ -5,11 +5,13 @@
$(Version)
$(Version)
$(Version)
+ True
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -19,6 +21,14 @@
all
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Certificates/CertificateValidatorTests.cs b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Certificates/CertificateValidatorTests.cs
index 23d0d01..725c2d9 100644
--- a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Certificates/CertificateValidatorTests.cs
+++ b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Certificates/CertificateValidatorTests.cs
@@ -1,6 +1,5 @@
-using System;
+using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using CDR.Register.API.Infrastructure.Exceptions;
@@ -17,11 +16,12 @@ public class CertificateValidatorTests
[Fact]
public void IsValid_ValidCertificate_ShouldReturnTrue()
{
- // Arrange.
+ // Arrange.
var logger = Substitute.For>();
var rootCaPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ca.pem");
- var inMemorySettings = new Dictionary {
- {"RootCACertificatePath", rootCaPath}
+ var inMemorySettings = new Dictionary
+ {
+ { "RootCACertificatePath", rootCaPath }
};
IConfiguration configuration = new ConfigurationBuilder()
@@ -45,15 +45,14 @@ public void IsValid_NullCertificate_ShouldThrowException()
// Arrange.
var logger = Substitute.For>();
var rootCaPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ca.pem");
- var inMemorySettings = new Dictionary {
- {"RootCACertificatePath", rootCaPath}
+ var inMemorySettings = new Dictionary
+ {
+ { "RootCACertificatePath", rootCaPath }
};
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
- var clientCertPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "client.pfx");
- var goodClientCert = new X509Certificate2(clientCertPath, "#M0ckDataRecipient#");
var validator = new CertificateValidator(logger, configuration);
// Act.
@@ -65,11 +64,12 @@ public void IsValid_NullCertificate_ShouldThrowException()
[Fact]
public void IsValid_SelfSignedCertificate_ShouldReturnFalse()
{
- // Arrange.
+ // Arrange.
var logger = Substitute.For>();
var rootCaPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ca.pem");
- var inMemorySettings = new Dictionary {
- {"RootCACertificatePath", rootCaPath}
+ var inMemorySettings = new Dictionary
+ {
+ { "RootCACertificatePath", rootCaPath }
};
IConfiguration configuration = new ConfigurationBuilder()
@@ -86,11 +86,12 @@ public void IsValid_SelfSignedCertificate_ShouldReturnFalse()
[Fact]
public void IsValid_FakeMockCDRCACertificate_ShouldReturnFalse()
{
- // Arrange.
+ // Arrange.
var logger = Substitute.For>();
var rootCaPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ca.pem");
- var inMemorySettings = new Dictionary {
- {"RootCACertificatePath", rootCaPath}
+ var inMemorySettings = new Dictionary
+ {
+ { "RootCACertificatePath", rootCaPath }
};
IConfiguration configuration = new ConfigurationBuilder()
@@ -109,11 +110,12 @@ public void IsValid_FakeMockCDRCACertificate_ShouldReturnFalse()
[Fact]
public void IsValid_NonMockCDRCACertificate_ShouldReturnFalse()
{
- // Arrange.
+ // Arrange.
var logger = Substitute.For>();
var rootCaPath = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ca.pem");
- var inMemorySettings = new Dictionary {
- {"RootCACertificatePath", rootCaPath}
+ var inMemorySettings = new Dictionary
+ {
+ { "RootCACertificatePath", rootCaPath }
};
IConfiguration configuration = new ConfigurationBuilder()
@@ -128,6 +130,5 @@ public void IsValid_NonMockCDRCACertificate_ShouldReturnFalse()
// Assert.
}
-
}
}
diff --git a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
index 9efecaa..4ca5982 100644
--- a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
+++ b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
@@ -1,4 +1,4 @@
-using CDR.Register.API.Infrastructure.Versioning;
+using CDR.Register.API.Infrastructure.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using NSubstitute;
@@ -11,7 +11,6 @@ namespace CDR.Register.API.Infrastructure.Tests.UnitTests.Versioning
[Trait("Category", "UnitTests")]
public partial class CdrVersionReaderTests
{
-
[Fact]
public void Read_DataHolderStatus_NoXvHeader_ShouldReturn1()
{
@@ -37,7 +36,7 @@ public void Read_DataHolderStatus_EmptyXvHeader_ShouldReturn1()
var expectedVersion = "1";
var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues(""));
+ mockHttpHeaders.Add("x-v", new StringValues(string.Empty));
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/status"));
@@ -74,7 +73,7 @@ public void Read_EmptyXvHeader_ShouldReturnMissingVersion()
var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues(""));
+ mockHttpHeaders.Add("x-v", new StringValues(string.Empty));
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
@@ -95,7 +94,7 @@ public void Read_NullXvHeader_ShouldReturnMissingVersion()
var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues());
+ mockHttpHeaders.Add("x-v", default);
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
@@ -363,4 +362,4 @@ public void Read_ValidXvInvalidXminV_ShouldReturnInvalidVersion()
Assert.Equal(expectedVersion, actualVersion);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicies.cs b/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicies.cs
index e56990d..345a994 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicies.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicies.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
-using System;
-using Microsoft.OpenApi.Extensions;
+using System;
+using System.Collections.Generic;
using System.Linq;
+using Microsoft.OpenApi.Extensions;
namespace CDR.Register.API.Infrastructure.Authorization
{
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicyAttribute.cs b/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicyAttribute.cs
index cd1ec0a..75649ce 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicyAttribute.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/AuthorisationPolicyAttribute.cs
@@ -15,9 +15,13 @@ public AuthorisationPolicyAttribute(string name, string? scopeRequirement, bool
}
public string Name { get; private set; }
+
public string? ScopeRequirement { get; private set; }
+
public bool HasMtlsRequirement { get; private set; }
+
public bool HasHolderOfKeyRequirement { get; private set; }
+
public bool HasAccessTokenRequirement { get; private set; }
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/DataRecipientSoftwareProductIdHandler.cs b/Source/CDR.Register.API.Infrastructure/Authorization/DataRecipientSoftwareProductIdHandler.cs
index 196cad4..ca6e4a5 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/DataRecipientSoftwareProductIdHandler.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/DataRecipientSoftwareProductIdHandler.cs
@@ -32,6 +32,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. Access token is missing 'client_id' claim for issuer '{Issuer}'.", requirement.Issuer);
}
+
return Task.CompletedTask;
}
@@ -42,6 +43,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. Access token is missing 'client_id' claim.");
}
+
return Task.CompletedTask;
}
@@ -54,6 +56,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. Access token client_id '{AccessTokenClientId}' does not match request softwareProductId '{RequestDataRecipientProductId}'", accessTokenClientId, requestDataRecipientProductId);
}
+
return Task.CompletedTask;
}
@@ -62,4 +65,4 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
return Task.CompletedTask;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/MTLSHandler.cs b/Source/CDR.Register.API.Infrastructure/Authorization/MTLSHandler.cs
index f61aa43..eef6041 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/MTLSHandler.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/MTLSHandler.cs
@@ -5,8 +5,6 @@
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json.Linq;
using Serilog.Context;
-using System.Configuration;
-using System.Linq;
using System.Threading.Tasks;
namespace CDR.Register.API.Infrastructure.Authorization
@@ -21,7 +19,7 @@ public MtlsHandler(IHttpContextAccessor httpContextAccessor, ILogger(Constants.ConfigurationKeys.CertThumbprintNameHttpHeaderName) ?? Constants.Headers.X_TLS_CLIENT_CERT_THUMBPRINT;
@@ -50,6 +46,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. Request header 'X-TlsClientCertThumbprint' is missing.");
}
+
return Task.CompletedTask;
}
@@ -67,6 +64,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. cnf:x5t#S256 claim is missing from access token.");
}
+
return Task.CompletedTask;
}
@@ -76,6 +74,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. X-TlsClientCertThumbprint request header value '{RequestHeaderClientCertThumprint}' does not match access token cnf:x5t#S256 claim value '{AccessTokenClientCertThumbprint}'", requestHeaderClientCertThumprint, accessTokenClientCertThumbprint);
}
+
return Task.CompletedTask;
}
@@ -84,4 +83,4 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
return Task.CompletedTask;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/PolicyAuthorizeAttribute.cs b/Source/CDR.Register.API.Infrastructure/Authorization/PolicyAuthorizeAttribute.cs
index 3b25665..34f9d3f 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/PolicyAuthorizeAttribute.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/PolicyAuthorizeAttribute.cs
@@ -1,5 +1,4 @@
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.Domain.Models;
+using CDR.Register.Domain.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
@@ -13,11 +12,11 @@ namespace CDR.Register.API.Infrastructure.Authorization
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class PolicyAuthorizeAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter
{
- public readonly RegisterAuthorisationPolicy policy;
+ public RegisterAuthorisationPolicy RegisterAuthorisationPolicy { get; private set; }
public PolicyAuthorizeAttribute(RegisterAuthorisationPolicy policy)
{
- this.policy = policy;
+ this.RegisterAuthorisationPolicy = policy;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
@@ -25,14 +24,16 @@ public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
var authorizationService = (IAuthorizationService?)context.HttpContext.RequestServices.GetService(typeof(IAuthorizationService));
if (authorizationService == null)
- {
- return;
+ {
+ return;
}
- var authorizationResult = await authorizationService.AuthorizeAsync(context.HttpContext.User, policy.ToString());
+ var authorizationResult = await authorizationService.AuthorizeAsync(context.HttpContext.User, RegisterAuthorisationPolicy.ToString());
if (authorizationResult.Succeeded)
+ {
return;
+ }
if (authorizationResult.Failure.FailedRequirements.Any(r => r.GetType() == typeof(MtlsRequirement)))
{
@@ -43,4 +44,4 @@ public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
context.Result = new RegisterForbidResult(new ResponseErrorList(StatusCodes.Status403Forbidden.ToString(), HttpStatusCode.Forbidden.ToString(), "You do not have permission to access this resource."));
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterAuthorisationPolicy.cs b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterAuthorisationPolicy.cs
index 7324949..0914518 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterAuthorisationPolicy.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterAuthorisationPolicy.cs
@@ -4,7 +4,7 @@ namespace CDR.Register.API.Infrastructure.Authorization
{
public enum RegisterAuthorisationPolicy
{
- [AuthorisationPolicy("DataHolderBrandsApiMultiIndustry", CdsRegistrationScopes.Read, true, false,false)]
+ [AuthorisationPolicy("DataHolderBrandsApiMultiIndustry", CdsRegistrationScopes.Read, true, false, false)]
DataHolderBrandsApiMultiIndustry,
[AuthorisationPolicy("GetSSAMultiIndustry", CdsRegistrationScopes.Read, true, false, false)]
GetSSAMultiIndustry
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterForbidResult.cs b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterForbidResult.cs
index 0251492..71135b0 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterForbidResult.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterForbidResult.cs
@@ -1,5 +1,4 @@
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.Domain.Models;
+using CDR.Register.Domain.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -7,12 +6,14 @@ namespace CDR.Register.API.Infrastructure.Authorization
{
public class RegisterForbidResult : ObjectResult
{
- public RegisterForbidResult(ResponseErrorList errorList) : base(errorList)
+ public RegisterForbidResult(ResponseErrorList errorList)
+ : base(errorList)
{
this.StatusCode = StatusCodes.Status403Forbidden;
}
- public RegisterForbidResult(Error error) : this(new ResponseErrorList(error))
+ public RegisterForbidResult(Error error)
+ : this(new ResponseErrorList(error))
{
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterUnauthorizedResult.cs b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterUnauthorizedResult.cs
index 6b82300..4f8f8d3 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/RegisterUnauthorizedResult.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/RegisterUnauthorizedResult.cs
@@ -1,5 +1,4 @@
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.Domain.Models;
+using CDR.Register.Domain.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -7,12 +6,14 @@ namespace CDR.Register.API.Infrastructure.Authorization
{
public class RegisterUnauthorizedResult : ObjectResult
{
- public RegisterUnauthorizedResult(ResponseErrorList errorList) : base(errorList)
+ public RegisterUnauthorizedResult(ResponseErrorList errorList)
+ : base(errorList)
{
this.StatusCode = StatusCodes.Status401Unauthorized;
}
- public RegisterUnauthorizedResult(Error error) : this(new ResponseErrorList(error))
+ public RegisterUnauthorizedResult(Error error)
+ : this(new ResponseErrorList(error))
{
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/ScopeHandler.cs b/Source/CDR.Register.API.Infrastructure/Authorization/ScopeHandler.cs
index c7868f3..ae33ef4 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/ScopeHandler.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/ScopeHandler.cs
@@ -30,6 +30,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
{
_logger.LogError("Unauthorized request. Access token is missing 'scope' claim.");
}
+
return Task.CompletedTask;
}
@@ -40,7 +41,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
// The space character is used to seperate the scopes as this is in line with CDS specifications.
string[] requiredScopes = requirement.Scope.Split(' ');
- if (userClaimScopes!=null && userClaimScopes.Intersect(requiredScopes).Any())
+ if (userClaimScopes != null && userClaimScopes.Intersect(requiredScopes).Any())
{
context.Succeed(requirement);
}
@@ -48,4 +49,4 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte
return Task.CompletedTask;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.API.Infrastructure/Authorization/ScopeRequirement.cs b/Source/CDR.Register.API.Infrastructure/Authorization/ScopeRequirement.cs
index 9dde007..cf4bf5c 100644
--- a/Source/CDR.Register.API.Infrastructure/Authorization/ScopeRequirement.cs
+++ b/Source/CDR.Register.API.Infrastructure/Authorization/ScopeRequirement.cs
@@ -11,5 +11,5 @@ public ScopeRequirement(string? scope)
{
Scope = scope ?? throw new ArgumentNullException(nameof(scope));
}
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj b/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
index a332dc1..e525df7 100644
--- a/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
+++ b/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
@@ -5,13 +5,15 @@
$(Version)
$(Version)
enable
+ True
-
+
-
-
+
+
+
@@ -23,6 +25,14 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.API.Infrastructure/Certificates/CertificateValidator.cs b/Source/CDR.Register.API.Infrastructure/Certificates/CertificateValidator.cs
index 11eb189..7f2ab1f 100644
--- a/Source/CDR.Register.API.Infrastructure/Certificates/CertificateValidator.cs
+++ b/Source/CDR.Register.API.Infrastructure/Certificates/CertificateValidator.cs
@@ -22,14 +22,14 @@ public CertificateValidator(ILogger logger, IConfiguration
public void ValidateClientCertificate(X509Certificate2 clientCert)
{
- _logger.LogInformation("Validating certificate within the {Name}",nameof(CertificateValidator));
+ _logger.LogInformation("Validating certificate within the {Name}", nameof(CertificateValidator));
if (clientCert == null)
{
throw new ArgumentNullException(nameof(clientCert));
}
- var rootCAPath = _config.GetValue("RootCACertificatePath")??throw new ClientCertificateException("Root CA Certificate path not configured");
+ var rootCAPath = _config.GetValue("RootCACertificatePath") ?? throw new ClientCertificateException("Root CA Certificate path not configured");
// Validate that the certificate has been issued by the Mock CDR CA.
var rootCACertificate = new X509Certificate2(rootCAPath);
diff --git a/Source/CDR.Register.API.Infrastructure/Constants.cs b/Source/CDR.Register.API.Infrastructure/Constants.cs
index 7a2b03a..b2081d7 100644
--- a/Source/CDR.Register.API.Infrastructure/Constants.cs
+++ b/Source/CDR.Register.API.Infrastructure/Constants.cs
@@ -13,7 +13,7 @@ public static class Headers
public static class ConfigurationKeys
{
public const string BasePath = "BasePath";
- public const string BasePathExpression = "BasePathExpression";
+ public const string BasePathExpression = "BasePathExpression";
public const string PublicHostName = "PublicHostName";
public const string SecureHostName = "SecureHostName";
public const string OidcMetadataAddress = "OidcMetadataAddress";
@@ -28,6 +28,5 @@ public static class Versioning
{
public const string GroupNameFormat = "'v'VVV";
}
-
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Exceptions/ClientCertificateException.cs b/Source/CDR.Register.API.Infrastructure/Exceptions/ClientCertificateException.cs
index 73f001d..a0c6e25 100644
--- a/Source/CDR.Register.API.Infrastructure/Exceptions/ClientCertificateException.cs
+++ b/Source/CDR.Register.API.Infrastructure/Exceptions/ClientCertificateException.cs
@@ -4,11 +4,13 @@ namespace CDR.Register.API.Infrastructure.Exceptions
{
public class ClientCertificateException : Exception
{
- public ClientCertificateException(string message) : base($"An error occurred validating the client certificate: {message}")
+ public ClientCertificateException(string message)
+ : base($"An error occurred validating the client certificate: {message}")
{
}
- public ClientCertificateException(string message, Exception ex) : base($"An error occurred validating the client certificate: {message}", ex)
+ public ClientCertificateException(string message, Exception ex)
+ : base($"An error occurred validating the client certificate: {message}", ex)
{
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Extensions.cs b/Source/CDR.Register.API.Infrastructure/Extensions.cs
index efd4ed7..5868be0 100644
--- a/Source/CDR.Register.API.Infrastructure/Extensions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Extensions.cs
@@ -37,7 +37,7 @@ public static class Extensions
public static string GetInfosecBaseUrl(this IConfiguration configuration, HttpContext? context, bool isSecure = false)
{
var basePath = string.Empty;
- if (context.Request != null && context.Request.PathBase.HasValue)
+ if (context?.Request != null && context.Request.PathBase.HasValue)
{
basePath = context.Request.PathBase.ToString();
}
@@ -50,10 +50,8 @@ public static string GetInfosecBaseUrl(this IConfiguration configuration, HttpCo
}
///
- /// CTS conformance ids must be validated
- ///
- ///
- ///
+ /// CTS conformance ids must be validated.
+ ///
public static bool ValidateIssuer(this HttpContext context)
{
if (context.Request != null && context.Request.PathBase.HasValue)
@@ -65,7 +63,7 @@ public static bool ValidateIssuer(this HttpContext context)
return false;
}
- // For a stronger match validating dynamic base path with an conformance ID instead of confromanceId only
+ // For a stronger match validating dynamic base path with an conformance ID instead of confromanceId only
return issuer?.Contains(context.Request.PathBase) ?? false;
}
@@ -79,7 +77,7 @@ public static void UseBasePathOrExpression(this IApplicationBuilder app, IConfig
{
app.UsePathBase(basePath);
}
-
+
// A dynamic base path can be set by the Mock Register:BasePathExpression app setting.
// This allows a regular expression to be set and matched rather than a static base path.
var basePathExpression = configuration.GetValue(Constants.ConfigurationKeys.BasePathExpression);
@@ -88,12 +86,12 @@ public static void UseBasePathOrExpression(this IApplicationBuilder app, IConfig
app.Use((context, next) =>
{
var matches = Regex.Matches(context.Request.Path, basePathExpression, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase, matchTimeout: TimeSpan.FromMilliseconds(500));
- if (matches.Count!=0)
+ if (matches.Count != 0)
{
var path = matches[0].Groups[0].Value;
var remainder = matches[0].Groups[1].Value;
context.Request.Path = $"/{remainder}";
- context.Request.PathBase = path.Replace(remainder, "").TrimEnd('/');
+ context.Request.PathBase = path.Replace(remainder, string.Empty).TrimEnd('/');
}
return next(context);
@@ -125,6 +123,7 @@ public static void AddAuthenticationAuthorization(this IServiceCollection servic
{
var metadataAddress = configuration.GetValue(Constants.ConfigurationKeys.OidcMetadataAddress);
var jwks = Task.Run(() => LoadJwks($"{metadataAddress}/jwks", configuration)).Result;
+
// Default 2 mins*
var clockSkew = configuration.GetValue(Constants.ConfigurationKeys.ClockSkewSeconds, 120);
@@ -162,9 +161,9 @@ public static void AddAuthenticationAuthorization(this IServiceCollection servic
services.AddMvcCore().AddAuthorization(options =>
{
var allAuthPolicies = AuthorisationPolicies.GetAllPolicies();
-
- //Apply all listed policities from a single source of truth that is also used for self-documentation
- foreach(var pol in allAuthPolicies)
+
+ // Apply all listed policities from a single source of truth that is also used for self-documentation
+ foreach (var pol in allAuthPolicies)
{
options.AddPolicy(pol.Name, policy =>
{
@@ -179,10 +178,9 @@ public static void AddAuthenticationAuthorization(this IServiceCollection servic
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
-
}
- static async Task LoadJwks(string jwksUri, IConfiguration configuration)
+ private static async Task LoadJwks(string jwksUri, IConfiguration configuration)
{
var handler = new HttpClientHandler();
handler.SetServerCertificateValidation(configuration);
@@ -195,7 +193,7 @@ public static void AddAuthenticationAuthorization(this IServiceCollection servic
public static string GetHostName(this string url)
{
- return url.Replace("https://", "").Replace("http://", "").Split('/')[0];
+ return url.Replace("https://", string.Empty).Replace("http://", string.Empty).Split('/')[0];
}
public static LinksPaginated GetPaginated(
@@ -230,6 +228,7 @@ public static LinksPaginated GetPaginated(
{
links.Prev = controller.GetPageUri(routeName, updatedSince, currentPage - 1, pageSize, hostName);
}
+
if (currentPage >= totalPages)
{
links.Next = null;
@@ -264,19 +263,20 @@ public static string GetHostNameAsUri(this ControllerBase controller, IConfigura
{
if (controller.Request.Headers.TryGetValue("X-Forwarded-Host", out StringValues forwardedHosts))
{
- hostNameToUse = forwardedHosts[0];
+ hostNameToUse = forwardedHosts[0];
}
else
{
hostNameToUse = hostName;
}
- if (hostNameToUse!= null && !hostNameToUse.StartsWith("https", StringComparison.OrdinalIgnoreCase))
+ if (hostNameToUse != null && !hostNameToUse.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
- hostNameToUse = "https://" + hostNameToUse;
+ hostNameToUse = "https://" + hostNameToUse;
}
}
- return hostNameToUse ?? "";
+
+ return hostNameToUse ?? string.Empty;
}
public static Uri? GetPageUri(
@@ -323,13 +323,13 @@ public static string GetHostNameAsUri(this ControllerBase controller, IConfigura
return new Uri(url.Replace(currentHost, newHostName));
}
- private static Uri ReplaceUriHost(string url, string newHost = null)
+ private static Uri ReplaceUriHost(string url, string? newHost = null)
{
- Uri originalUri = new(url);
- Uri replaceUri = new(newHost);
+ Uri originalUri = new Uri(url);
+ Uri replaceUri = new Uri(newHost ?? string.Empty);
// Update the Uri components
- UriBuilder modifiedUriBuilder = new(originalUri)
+ UriBuilder modifiedUriBuilder = new UriBuilder(originalUri)
{
Host = replaceUri.Host,
Port = replaceUri.IsDefaultPort ? -1 : replaceUri.Port,
@@ -341,9 +341,13 @@ private static Uri ReplaceUriHost(string url, string newHost = null)
public static Industry ToIndustry(this string industry)
{
if (Enum.IsDefined(typeof(Industry), industry.ToUpper()))
+ {
return (Industry)Enum.Parse(typeof(Industry), industry, true);
+ }
else
+ {
throw new NotSupportedException($"Invalid industry: {industry}");
+ }
}
public static IEnumerable GetValueAsList(this IConfiguration configuration, string key, string delimiter)
@@ -361,12 +365,12 @@ public static string GetClientCertificateThumbprint(this HttpContext context, IC
{
var certThumbprintNameHttpHeaderName = configuration.GetValue(Constants.ConfigurationKeys.CertThumbprintNameHttpHeaderName) ?? Constants.Headers.X_TLS_CLIENT_CERT_THUMBPRINT;
- if (context.Request.Headers.TryGetValue(certThumbprintNameHttpHeaderName, out StringValues headerThumbprints) && headerThumbprints.Count > 0)
+ if (context.Request.Headers.TryGetValue(certThumbprintNameHttpHeaderName, out StringValues headerThumbprints) && headerThumbprints.Count > 0)
{
- return headerThumbprints[0] ?? "";
+ return headerThumbprints[0] ?? string.Empty;
}
- return "";
+ return string.Empty;
}
public static string GetClientCertificateCommonName(this HttpContext context, ILogger logger, IConfiguration configuration)
@@ -376,7 +380,7 @@ public static string GetClientCertificateCommonName(this HttpContext context, IL
if (context.Request.Headers.TryGetValue(certCommonNameHttpHeaderName, out StringValues headerCommonNames) && headerCommonNames.Count > 0)
{
- headerCommonName = headerCommonNames[0] ?? "";
+ headerCommonName = headerCommonNames[0] ?? string.Empty;
}
else
{
@@ -425,11 +429,10 @@ public static string GetCommonNameFromDistinguishedName(this string distinguishe
{
try
{
- X500DistinguishedName dn = new(distinguishedName);
+ X500DistinguishedName dn = new X500DistinguishedName(distinguishedName);
var cnAttribute = Array.Find(
- dn.Decode(X500DistinguishedNameFlags.UseNewLines).Split('\n'),
+ dn.Decode(X500DistinguishedNameFlags.UseNewLines).Split('\n'),
attr => attr.Trim().StartsWith("CN="));
-
if (cnAttribute != null)
{
@@ -442,7 +445,6 @@ public static string GetCommonNameFromDistinguishedName(this string distinguishe
{
return string.Empty;
}
-
}
public static IServiceCollection AddCdrSwaggerGen(this IServiceCollection services, Action configureRegisterSwaggerOptions, bool isVersioned = true)
@@ -456,12 +458,11 @@ public static IServiceCollection AddCdrSwaggerGen(this IServiceCollection servic
{
services.AddTransient, ConfigureSwaggerOptions>();
- //Required for our Swagger setup to work when endpoints have been versioned
+ // Required for our Swagger setup to work when endpoints have been versioned
services.AddVersionedApiExplorer(opt =>
{
opt.GroupNameFormat = options.VersionedApiGroupNameFormat;
});
-
}
else
{
diff --git a/Source/CDR.Register.API.Infrastructure/Extensions/AttributeExtensions.cs b/Source/CDR.Register.API.Infrastructure/Extensions/AttributeExtensions.cs
index c5a5eca..4b1a2c3 100644
--- a/Source/CDR.Register.API.Infrastructure/Extensions/AttributeExtensions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Extensions/AttributeExtensions.cs
@@ -11,12 +11,13 @@ public static IEnumerable
diff --git a/Source/CDR.Register.Admin.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Admin.xml b/Source/CDR.Register.Admin.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Admin.xml
index 8ef1134..104b87a 100644
--- a/Source/CDR.Register.Admin.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Admin.xml
+++ b/Source/CDR.Register.Admin.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Admin.xml
@@ -8,13 +8,13 @@
This controller action provides an implementation of a JWKS for a Mock Data Recipient.
- JWKS
+ JWKS.
This controller action produces a client assertion for a mock data recipient.
- Client assertion string
+ Client assertion string.
This client assertion can then be used in a private key jwt request.
@@ -23,7 +23,14 @@
This controller action produces a self signed JWT for the mock register.
- Self Signed JWT
+ Self Signed JWT.
+
+
+
+ Configure Serilog logging.
+
+ App configuration.
+ Set to True if the database is ready and the MSSqlServer sink will be configured.
diff --git a/Source/CDR.Register.Admin.API/Controllers/AdminController.cs b/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
index de21902..6f5a000 100644
--- a/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
+++ b/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
@@ -15,7 +15,6 @@
using Newtonsoft.Json.Serialization;
using System;
using System.IO;
-using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
@@ -46,13 +45,15 @@ public async Task LoadData()
{
using var reader = new StreamReader(Request.Body);
string json = await reader.ReadToEndAsync();
- string respMsg = "";
+ string respMsg = string.Empty;
try
{
bool updated = await _dbContext.SeedDatabaseFromJson(json, _logger, true);
if (updated)
+ {
Response.StatusCode = StatusCodes.Status200OK;
+ }
else
{
Response.StatusCode = StatusCodes.Status400BadRequest;
@@ -78,7 +79,7 @@ public async Task LoadData()
[ServiceFilter(typeof(LogActionEntryAttribute))]
public async Task GetData()
{
- //We need to override the usual default settings so that the FK Ids can use their int values instead of their string values
+ // We need to override the usual default settings so that the FK Ids can use their int values instead of their string values
var apiSpecificSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
@@ -150,7 +151,7 @@ public async Task SaveDataRecipient()
return BadRequest(new Error(Domain.Constants.ErrorTitles.InvalidField, Domain.Constants.ErrorCodes.Cds.InvalidField, "Empty LegalEntity received"));
}
- var legalEntity = System.Text.Json.JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //This is inconsistent with other serializers
+ var legalEntity = System.Text.Json.JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); // This is inconsistent with other serializers
var errors = legalEntity?.GetValidationErrors(new LegalEntityValidator());
if (errors?.Errors.Count > 0)
diff --git a/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs b/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
index e155ade..6f9c80c 100644
--- a/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
+++ b/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
@@ -15,9 +15,8 @@ namespace CDR.Register.Admin.API.Controllers
[ApiController]
[Route("[controller]")]
[ApiVersionNeutral]
- public class LoopbackController : Controller
+ public class LoopbackController : ControllerBase
{
-
private readonly IConfiguration _config;
public LoopbackController(IConfiguration config)
@@ -28,7 +27,7 @@ public LoopbackController(IConfiguration config)
///
/// This controller action provides an implementation of a JWKS for a Mock Data Recipient.
///
- /// JWKS
+ /// JWKS.
[HttpGet]
[Route("MockDataRecipientJwks")]
[ServiceFilter(typeof(LogActionEntryAttribute))]
@@ -36,7 +35,7 @@ public IActionResult MockDataRecipientJwks()
{
var cert = new X509Certificate2("Certificates/client.pem");
var key = cert.GetRSAPublicKey();
- var rsaParams = key.ExportParameters(false);
+ var rsaParams = key!.ExportParameters(false);
var kid = GenerateKid(rsaParams, out var e, out var n);
var jwk = new CDR.Register.API.Infrastructure.Models.JsonWebKey()
{
@@ -48,7 +47,7 @@ public IActionResult MockDataRecipientJwks()
key_ops = new string[] { "sign", "verify" }
};
- return Ok(new CDR.Register.API.Infrastructure.Models.JsonWebKeySet()
+ return new OkObjectResult(new CDR.Register.API.Infrastructure.Models.JsonWebKeySet()
{
keys = new CDR.Register.API.Infrastructure.Models.JsonWebKey[] { jwk }
});
@@ -57,7 +56,7 @@ public IActionResult MockDataRecipientJwks()
///
/// This controller action produces a client assertion for a mock data recipient.
///
- /// Client assertion string
+ /// Client assertion string.
///
/// This client assertion can then be used in a private key jwt request.
///
@@ -67,7 +66,7 @@ public IActionResult MockDataRecipientJwks()
public IActionResult MockDataRecipientClientAssertion()
{
var privateKeyRaw = System.IO.File.ReadAllText("Certificates/client.key");
- var privateKey = privateKeyRaw.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r\n", "").Trim();
+ var privateKey = privateKeyRaw.Replace("-----BEGIN PRIVATE KEY-----", string.Empty).Replace("-----END PRIVATE KEY-----", string.Empty).Replace("\r\n", string.Empty).Trim();
var privateKeyBytes = Convert.FromBase64String(privateKey);
string audience = _config.GetValue("IdentityServerTokenUri") ?? "https://localhost:7001/idp/connect/token";
@@ -79,7 +78,7 @@ public IActionResult MockDataRecipientClientAssertion()
if (Request.Query.TryGetValue("aud", out var aud))
{
- audience = aud.ToString();
+ audience = aud.ToString();
}
using (var rsa = RSA.Create())
@@ -116,14 +115,14 @@ public IActionResult MockDataRecipientClientAssertion()
///
/// This controller action produces a self signed JWT for the mock register.
///
- /// Self Signed JWT
+ /// Self Signed JWT.
[HttpGet]
[Route("RegisterSelfSignedJwt")]
[ServiceFilter(typeof(LogActionEntryAttribute))]
public IActionResult RegisterSelfSignedJwt(
[FromQuery] string aud)
{
- var cert = new X509Certificate2(_config.GetValue("SigningCertificate:Path") ?? "", _config.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable);
+ var cert = new X509Certificate2(_config.GetValue("SigningCertificate:Path") ?? string.Empty, _config.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable);
var signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSsaPssSha256);
var descriptor = new SecurityTokenDescriptor
@@ -153,14 +152,15 @@ private static string GenerateKid(RSAParameters rsaParams, out string e, out str
{
e = Base64UrlEncoder.Encode(rsaParams.Exponent);
n = Base64UrlEncoder.Encode(rsaParams.Modulus);
- var dict = new Dictionary() {
- {"e", e},
- {"kty", "RSA"},
- {"n", n}
+ var dict = new Dictionary()
+ {
+ { "e", e },
+ { "kty", "RSA" },
+ { "n", n }
};
var hash = SHA256.Create();
var hashBytes = hash.ComputeHash(System.Text.Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(dict)));
return Base64UrlEncoder.Encode(hashBytes);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Admin.API/Extensions/ServiceCollectionExtensions.cs b/Source/CDR.Register.Admin.API/Extensions/ServiceCollectionExtensions.cs
index acc10e8..f341373 100644
--- a/Source/CDR.Register.Admin.API/Extensions/ServiceCollectionExtensions.cs
+++ b/Source/CDR.Register.Admin.API/Extensions/ServiceCollectionExtensions.cs
@@ -39,7 +39,7 @@ public static IServiceCollection AddRegisterAdminAuth(this IServiceCollection se
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
- // Sets the authority to Azure AD.
+ // Sets the authority to Azure AD.
options.Authority = issuer;
options.TokenValidationParameters = new TokenValidationParameters()
{
@@ -51,6 +51,7 @@ public static IServiceCollection AddRegisterAdminAuth(this IServiceCollection se
// Validates that the intended audience for the access token is the API app.
ValidateAudience = true,
+
// the application id of the API App Registration.
ValidAudience = clientId,
diff --git a/Source/CDR.Register.Admin.API/Filters/ApiAuthorizeAttribute.cs b/Source/CDR.Register.Admin.API/Filters/ApiAuthorizeAttribute.cs
index 3ed4ea7..3d65691 100644
--- a/Source/CDR.Register.Admin.API/Filters/ApiAuthorizeAttribute.cs
+++ b/Source/CDR.Register.Admin.API/Filters/ApiAuthorizeAttribute.cs
@@ -13,34 +13,34 @@ namespace CDR.Register.Admin.API.Filters
public class ApiAuthorizeAttribute : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
- {
- var configuration = (IConfiguration)context.HttpContext.RequestServices
+ {
+ var configuration = (IConfiguration?)context.HttpContext.RequestServices
.GetService(typeof(IConfiguration));
-
+
// Ignore if the Authentication is disabled.
- var issuer = configuration.GetValue(Constants.Authorization.Issuer);
+ var issuer = configuration?.GetValue(Constants.Authorization.Issuer);
if (string.IsNullOrEmpty(issuer))
{
return;
}
- var user = context.HttpContext.User;
- if (user.Identity == null ||!user.Identity.IsAuthenticated)
+ var user = context.HttpContext.User;
+ if (user.Identity == null || !user.Identity.IsAuthenticated)
{
InvalidToken(context);
}
// Scope, Role validation must have Admin API write access
- var scopeAttributeName = configuration.GetValue(Constants.Authorization.ScopeAttributeName);
- var scopeValue = configuration.GetValue(Constants.Authorization.ScopeValue);
- var allowedScope = user.FindAll(scopeAttributeName)
+ var scopeAttributeName = configuration?.GetValue(Constants.Authorization.ScopeAttributeName);
+ var scopeValue = configuration?.GetValue(Constants.Authorization.ScopeValue);
+ var allowedScope = !string.IsNullOrEmpty(scopeAttributeName) && user.FindAll(scopeAttributeName)
.Any(x => string.Equals(x.Value, scopeValue, StringComparison.OrdinalIgnoreCase));
if (!allowedScope)
{
InvalidToken(context);
}
- static void InvalidToken (AuthorizationFilterContext context)
+ static void InvalidToken(AuthorizationFilterContext context)
{
context.Result = new JsonResult(new { error = "invalid_token" }) { StatusCode = StatusCodes.Status401Unauthorized };
context.HttpContext.Response.Headers.Append(HeaderNames.WWWAuthenticate, "Bearer error=\"invalid_token\"");
diff --git a/Source/CDR.Register.Admin.API/Program.cs b/Source/CDR.Register.Admin.API/Program.cs
index 1182b10..f746670 100644
--- a/Source/CDR.Register.Admin.API/Program.cs
+++ b/Source/CDR.Register.Admin.API/Program.cs
@@ -1,8 +1,9 @@
-using CDR.Register.API.Infrastructure;
+using CDR.Register.API.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
+using Serilog.Settings.Configuration;
using System;
using System.IO;
@@ -18,16 +19,7 @@ public static int Main(string[] args)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true)
.AddEnvironmentVariables()
.Build();
-
- Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
- .Enrich.FromLogContext()
- .Enrich.WithProcessId()
- .Enrich.WithProcessName()
- .Enrich.WithThreadId()
- .Enrich.WithThreadName()
- .Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
- .CreateLogger();
+ ConfigureSerilog(configuration);
try
{
@@ -46,6 +38,31 @@ public static int Main(string[] args)
}
}
+ ///
+ /// Configure Serilog logging.
+ ///
+ /// App configuration.
+ /// Set to True if the database is ready and the MSSqlServer sink will be configured.
+ public static void ConfigureSerilog(IConfiguration configuration, bool isDatabaseReady = false)
+ {
+ var loggerConfiguration = new LoggerConfiguration()
+ .ReadFrom.Configuration(configuration)
+ .Enrich.FromLogContext()
+ .Enrich.WithProcessId()
+ .Enrich.WithProcessName()
+ .Enrich.WithThreadId()
+ .Enrich.WithThreadName()
+ .Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
+
+ // If the database is ready, configure the SQL Server sink
+ if (isDatabaseReady)
+ {
+ loggerConfiguration.ReadFrom.Configuration(configuration, new ConfigurationReaderOptions() { SectionName = "SerilogMSSqlServerWriteTo" });
+ }
+
+ Log.Logger = loggerConfiguration.CreateLogger();
+ }
+
public static IHostBuilder CreateHostBuilder(string[] args, IConfiguration configuration) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
diff --git a/Source/CDR.Register.Admin.API/Startup.cs b/Source/CDR.Register.Admin.API/Startup.cs
index de4e81b..68b4722 100644
--- a/Source/CDR.Register.Admin.API/Startup.cs
+++ b/Source/CDR.Register.Admin.API/Startup.cs
@@ -1,10 +1,15 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net.Mime;
+using System.Threading.Tasks;
using CDR.Register.Admin.API.Business.Validators;
using CDR.Register.Admin.API.Extensions;
using CDR.Register.API.Infrastructure;
using CDR.Register.API.Infrastructure.Models;
using CDR.Register.API.Infrastructure.Versioning;
-using CDR.Register.Repository.Infrastructure;
using CDR.Register.Domain.Extensions;
+using CDR.Register.Repository.Infrastructure;
using FluentValidation;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
@@ -18,13 +23,8 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Serilog;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
using static CDR.Register.API.Infrastructure.Constants;
using Constants = CDR.Register.Admin.API.Common.Constants;
-using System;
-using System.Net.Mime;
namespace CDR.Register.Admin.API
{
@@ -56,7 +56,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddApiVersioning(options =>
{
- options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); //uses default options atm
+ options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); // uses default options atm
options.ErrorResponses = new ApiVersionErrorResponse();
options.ReportApiVersions = true;
});
@@ -68,7 +68,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddCdrSwaggerGen(opt =>
{
opt.SwaggerTitle = "Consumer Data Right (CDR) Participant Tooling - Mock Register - Admin API";
- opt.IncludeAuthentication = !string.IsNullOrEmpty(issuer); //authentication is included for CTS when the issuer is not empty
+ opt.IncludeAuthentication = !string.IsNullOrEmpty(issuer); // authentication is included for CTS when the issuer is not empty
});
}
@@ -85,7 +85,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
ResponseWriter = CustomResponseWriter
});
-
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
@@ -124,6 +123,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
logger.LogError("ServiceScope cannot be created");
throw new InvalidOperationException("Service scope could not be created.");
}
+
// Run EF database migrations.
if (RunMigrations())
{
@@ -134,6 +134,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
logger.LogError("Mirgation failed. Unable to get {Name}", nameof(RegisterDatabaseContext));
throw new InvalidOperationException($"Unable to get {nameof(RegisterDatabaseContext)}");
}
+
context?.Database.Migrate();
healthCheckMigrationMessage = "Migration completed";
@@ -147,6 +148,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
Task.Run(() => context.SeedDatabaseFromJsonFile(seedDataFilePath, logger, seedDataOverwrite)).Wait();
healthCheckSeedDataMessage = "Seeding of data completed";
}
+
+ // Re-configure logger with the DB now.
+ Program.ConfigureSerilog(Configuration, true);
}
// If we get here migration (if required) and seeding (if required) has completed
diff --git a/Source/CDR.Register.Admin.API/appsettings.Development.json b/Source/CDR.Register.Admin.API/appsettings.Development.json
index e44d96f..ee5e62b 100644
--- a/Source/CDR.Register.Admin.API/appsettings.Development.json
+++ b/Source/CDR.Register.Admin.API/appsettings.Development.json
@@ -14,7 +14,7 @@
"TokenScopeAttribute": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
},
"Serilog": {
- "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.MSSqlServer" ],
+ "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
@@ -29,63 +29,6 @@
"path": "C:\\CDR\\Logs\\cdr-mr-admin-api.log",
"outputTemplate": "{Timestamp:dd/MM/yyyy HH:mm:ss.fff zzz} {Level} [{SourceContext}] {Message}{NewLine}{Exception}"
}
- },
- {
- "Name": "MSSqlServer",
- "Args": {
- "connectionString": "Register_Logging_DB",
- "sinkOptionsSection": {
- "tableName": "LogEvents-Admin-API",
- "autoCreateSqlTable": true
- },
- "restrictedToMinimumLevel": "Verbose",
- "batchPostingLimit": 1000,
- "period": "0.00:00:10",
- "columnOptionsSection": {
- "disableTriggers": true,
- "clusteredColumnstoreIndex": false,
- "primaryKeyColumnName": "Id",
- "removeStandardColumns": [ "MessageTemplate", "Properties" ],
- "additionalColumns": [
- {
- "ColumnName": "Environment",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ProcessId",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ProcessName",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ThreadId",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "MethodName",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "SourceContext",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 100
- }
- ]
- }
- }
}
]
},
diff --git a/Source/CDR.Register.Admin.API/appsettings.Release.json b/Source/CDR.Register.Admin.API/appsettings.Release.json
index bf3ac07..333591a 100644
--- a/Source/CDR.Register.Admin.API/appsettings.Release.json
+++ b/Source/CDR.Register.Admin.API/appsettings.Release.json
@@ -14,7 +14,7 @@
"TokenScopeAttribute": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
},
"Serilog": {
- "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.MSSqlServer" ],
+ "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File"],
"MinimumLevel": "Debug",
"WriteTo": [
{
@@ -23,63 +23,6 @@
{
"Name": "File",
"Args": { "path": "/tmp/cdr-mr-admin-api.log" }
- },
- {
- "Name": "MSSqlServer",
- "Args": {
- "connectionString": "Register_Logging_DB",
- "sinkOptionsSection": {
- "tableName": "LogEvents-Admin-API",
- "autoCreateSqlTable": true
- },
- "restrictedToMinimumLevel": "Verbose",
- "batchPostingLimit": 1000,
- "period": "0.00:00:10",
- "columnOptionsSection": {
- "disableTriggers": true,
- "clusteredColumnstoreIndex": false,
- "primaryKeyColumnName": "Id",
- "removeStandardColumns": [ "MessageTemplate", "Properties" ],
- "additionalColumns": [
- {
- "ColumnName": "Environment",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ProcessId",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ProcessName",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "ThreadId",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "MethodName",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 50
- },
- {
- "ColumnName": "SourceContext",
- "DataType": "nvarchar",
- "AllowNull": true,
- "DataLength": 100
- }
- ]
- }
- }
}
]
},
diff --git a/Source/CDR.Register.Admin.API/appsettings.json b/Source/CDR.Register.Admin.API/appsettings.json
index 02136c9..0eb4f75 100644
--- a/Source/CDR.Register.Admin.API/appsettings.json
+++ b/Source/CDR.Register.Admin.API/appsettings.json
@@ -27,5 +27,67 @@
"SigningCertificate": {
"Path": "Certificates/ssa.pfx",
"Password": "#M0ckRegister#"
+ },
+ "SerilogMSSqlServerWriteTo": {
+ "Using": [ "Serilog.Sinks.MSSqlServer" ],
+ "WriteTo": [
+ {
+ "Name": "MSSqlServer",
+ "Args": {
+ "connectionString": "Register_Logging_DB",
+ "sinkOptionsSection": {
+ "tableName": "LogEvents-Admin-API",
+ "autoCreateSqlTable": true
+ },
+ "restrictedToMinimumLevel": "Verbose",
+ "batchPostingLimit": 1000,
+ "period": "0.00:00:10",
+ "columnOptionsSection": {
+ "disableTriggers": true,
+ "clusteredColumnstoreIndex": false,
+ "primaryKeyColumnName": "Id",
+ "removeStandardColumns": [ "MessageTemplate", "Properties" ],
+ "additionalColumns": [
+ {
+ "ColumnName": "Environment",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 50
+ },
+ {
+ "ColumnName": "ProcessId",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 50
+ },
+ {
+ "ColumnName": "ProcessName",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 50
+ },
+ {
+ "ColumnName": "ThreadId",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 50
+ },
+ {
+ "ColumnName": "MethodName",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 50
+ },
+ {
+ "ColumnName": "SourceContext",
+ "DataType": "nvarchar",
+ "AllowNull": true,
+ "DataLength": 100
+ }
+ ]
+ }
+ }
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs b/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
index 9ccccc9..877b070 100644
--- a/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
+++ b/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
@@ -8,6 +8,7 @@ namespace CDR.Register.Discovery.API.Business
public interface IDiscoveryService
{
Task GetDataHolderBrandsAsync(Industry industry, DateTime? updatedSince, int page, int pageSize);
+
Task GetDataRecipientsAsync(Industry industry);
}
}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/AuthDetailModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/AuthDetailModel.cs
index 6ab4634..8504251 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/AuthDetailModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/AuthDetailModel.cs
@@ -3,6 +3,7 @@
public class AuthDetailModel
{
public string RegisterUType { get; set; }
+
public string JwksEndpoint { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/DataHolderLegalEntityModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/DataHolderLegalEntityModel.cs
index 0cd08bf..82a6036 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/DataHolderLegalEntityModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/DataHolderLegalEntityModel.cs
@@ -3,17 +3,27 @@
public class DataHolderLegalEntityModel
{
public string LegalEntityId { get; set; }
+
public string LegalEntityName { get; set; }
+
public string LogoUri { get; set; }
+
public string RegistrationNumber { get; set; }
+
public string RegistrationDate { get; set; }
+
public string RegisteredCountry { get; set; }
+
public string Abn { get; set; }
+
public string Acn { get; set; }
+
public string Arbn { get; set; }
+
public string AnzsicDivision { get; set; }
+
public string OrganisationType { get; set; }
+
public string Status { get; set; }
}
-
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/DataRecipientBrandModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/DataRecipientBrandModel.cs
index 85f232d..67b9bbe 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/DataRecipientBrandModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/DataRecipientBrandModel.cs
@@ -3,9 +3,13 @@
public class DataRecipientBrandModel
{
public string DataRecipientBrandId { get; set; }
+
public string BrandName { get; set; }
+
public string LogoUri { get; set; }
+
public SoftwareProductModel[] SoftwareProducts { get; set; }
+
public string Status { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs
index 91f4503..6d4a4c5 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs
@@ -3,11 +3,15 @@
public class EndpointDetailModel
{
public string Version { get; set; }
+
public string PublicBaseUri { get; set; }
+
public string ResourceBaseUri { get; set; }
+
public string InfosecBaseUri { get; set; }
+
public string ExtensionBaseUri { get; set; }
- public string WebsiteUri { get; set; }
+ public string WebsiteUri { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs
index f09e727..18db58f 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs
@@ -6,13 +6,21 @@ namespace CDR.Register.Discovery.API.Business.Models
public class RegisterDataHolderBrandModel
{
public string DataHolderBrandId { get; set; }
+
public string BrandName { get; set; }
+
public List Industries { get; set; }
+
public string LogoUri { get; set; }
+
public DataHolderLegalEntityModel LegalEntity { get; set; }
+
public string Status { get; set; }
+
public EndpointDetailModel EndpointDetail { get; set; }
+
public AuthDetailModel[] AuthDetails { get; set; }
+
public DateTime LastUpdated { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataRecipientModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataRecipientModel.cs
index f26b585..0e06b97 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataRecipientModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataRecipientModel.cs
@@ -5,12 +5,19 @@ namespace CDR.Register.Discovery.API.Business.Models
public class RegisterDataRecipientModel
{
public Guid LegalEntityId { get; set; }
+
public string LegalEntityName { get; set; }
+
public string AccreditationNumber { get; set; }
+
public string AccreditationLevel { get; set; }
+
public string LogoUri { get; set; }
+
public DataRecipientBrandModel[] DataRecipientBrands { get; set; }
+
public string Status { get; set; }
+
public DateTime? LastUpdated { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/SoftwareProductModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/SoftwareProductModel.cs
index d99a3eb..ee84449 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/SoftwareProductModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/SoftwareProductModel.cs
@@ -3,9 +3,13 @@
public class SoftwareProductModel
{
public string SoftwareProductId { get; set; }
+
public string SoftwareProductName { get; set; }
+
public string SoftwareProductDescription { get; set; }
+
public string LogoUri { get; set; }
+
public string Status { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
index 5f5cc80..d6ab71f 100644
--- a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
@@ -7,7 +7,9 @@ namespace CDR.Register.Discovery.API.Business.Responses
public class ResponseRegisterDataHolderBrandList
{
public IEnumerable Data { get; set; }
+
public LinksPaginated Links { get; set; } = new LinksPaginated();
+
public MetaPaginated Meta { get; set; } = new MetaPaginated();
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataRecipientList.cs b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataRecipientList.cs
index 8bfa8cb..b7c3889 100644
--- a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataRecipientList.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataRecipientList.cs
@@ -8,7 +8,9 @@ namespace CDR.Register.Discovery.API.Business.Responses
public class ResponseRegisterDataRecipientList
{
public IEnumerable Data { get; set; }
+
public Links Links { get; set; } = new Links();
+
public Meta Meta { get; set; } = new Meta();
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/CDR.Register.Discovery.API.csproj b/Source/CDR.Register.Discovery.API/CDR.Register.Discovery.API.csproj
index a145e78..6000221 100644
--- a/Source/CDR.Register.Discovery.API/CDR.Register.Discovery.API.csproj
+++ b/Source/CDR.Register.Discovery.API/CDR.Register.Discovery.API.csproj
@@ -11,20 +11,29 @@
-
-
-
+
+
+
+
-
+
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs b/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
index 4ed7d81..309c243 100644
--- a/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
+++ b/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
@@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
+using System.Globalization;
using System.Net;
using System.Threading.Tasks;
@@ -19,14 +20,14 @@ namespace CDR.Register.Discovery.API.Controllers
[Consumes("application/json")]
public class DiscoveryController : ControllerBase
{
- private readonly IDiscoveryService _discoveryService;
- private readonly IDataRecipientStatusCheckService _statusCheckService;
- private readonly IConfiguration _configuration;
-
// Route names.
private const string ROUTE_GET_DATA_HOLDER_BRANDS_XV2 = "GetDataHolderBrandsXV2";
private const string ROUTE_GET_DATA_RECIPIENTS_XV3 = "GetDataRecipientsXV3";
+ private readonly IDiscoveryService _discoveryService;
+ private readonly IDataRecipientStatusCheckService _statusCheckService;
+ private readonly IConfiguration _configuration;
+
public DiscoveryController(
IDiscoveryService discoveryService,
IConfiguration configuration,
@@ -37,7 +38,6 @@ public DiscoveryController(
_statusCheckService = statusCheckService;
}
-
[HttpGet("v1/{industry}/data-holders/brands", Name = ROUTE_GET_DATA_HOLDER_BRANDS_XV2)]
[PolicyAuthorize(RegisterAuthorisationPolicy.DataHolderBrandsApiMultiIndustry)]
[ApiVersion("2")]
@@ -51,7 +51,6 @@ public async Task GetDataHolderBrandsXV2(
[FromQuery(Name = "page"), CheckPage] string page,
[FromQuery(Name = "page-size"), CheckPageSize] string pageSize)
{
-
// CTS conformance ID validations
var basePathExpression = _configuration.GetValue(Constants.ConfigurationKeys.BasePathExpression);
if (!string.IsNullOrEmpty(basePathExpression))
@@ -71,7 +70,7 @@ public async Task GetDataHolderBrandsXV2(
}
// Set the default values for the incoming parameters
- DateTime? updatedSinceDate = string.IsNullOrEmpty(updatedSince) ? (DateTime?)null : DateTime.Parse(updatedSince);
+ DateTime? updatedSinceDate = string.IsNullOrEmpty(updatedSince) ? (DateTime?)null : DateTime.Parse(updatedSince, CultureInfo.InvariantCulture);
int pageNumber = string.IsNullOrEmpty(page) ? 1 : int.Parse(page);
int pageSizeNumber = string.IsNullOrEmpty(pageSize) ? 25 : int.Parse(pageSize);
var response = await _discoveryService.GetDataHolderBrandsAsync(industry.ToIndustry(), updatedSinceDate, pageNumber, pageSizeNumber);
@@ -83,8 +82,15 @@ public async Task GetDataHolderBrandsXV2(
}
// Set pagination meta data
- response.Links = this.GetPaginated(ROUTE_GET_DATA_HOLDER_BRANDS_XV2, _configuration,
- updatedSinceDate, pageNumber, response.Meta.TotalPages.Value, pageSizeNumber, "", true);
+ response.Links = this.GetPaginated(
+ ROUTE_GET_DATA_HOLDER_BRANDS_XV2,
+ _configuration,
+ updatedSinceDate,
+ pageNumber,
+ response.Meta.TotalPages.Value,
+ pageSizeNumber,
+ string.Empty,
+ true);
return Ok(response);
}
@@ -93,12 +99,12 @@ public async Task GetDataHolderBrandsXV2(
[ReturnXV("3")]
[ApiVersion("3")]
[ETag]
- [CheckIndustry()]
+ [CheckIndustry]
[ServiceFilter(typeof(LogActionEntryAttribute))]
public async Task GetDataRecipientsXV3(string industry)
{
var response = await _discoveryService.GetDataRecipientsAsync(industry.ToIndustry());
- response.Links = this.GetSelf(_configuration, HttpContext, "");
+ response.Links = this.GetSelf(_configuration, HttpContext, string.Empty);
return Ok(response);
}
@@ -132,6 +138,7 @@ private async Task CheckSoftwareProduct()
{
return softwareProductId;
}
+
return null;
}
@@ -140,4 +147,4 @@ private async Task CheckStatus(Guid softwareProductId)
return await _statusCheckService.ValidateSoftwareProductStatus(softwareProductId);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Discovery.API/Program.cs b/Source/CDR.Register.Discovery.API/Program.cs
index fc78034..87fb76a 100644
--- a/Source/CDR.Register.Discovery.API/Program.cs
+++ b/Source/CDR.Register.Discovery.API/Program.cs
@@ -1,9 +1,8 @@
-using CDR.Register.API.Infrastructure;
+using CDR.Register.API.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
-using Serilog.Events;
using System;
using System.IO;
@@ -21,7 +20,7 @@ public static int Main(string[] args)
.Build();
Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
+ .ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
diff --git a/Source/CDR.Register.Discovery.API/Startup.cs b/Source/CDR.Register.Discovery.API/Startup.cs
index d1482c7..1171c56 100644
--- a/Source/CDR.Register.Discovery.API/Startup.cs
+++ b/Source/CDR.Register.Discovery.API/Startup.cs
@@ -1,10 +1,11 @@
-using CDR.Register.API.Infrastructure;
+using CDR.Register.API.Infrastructure;
using CDR.Register.API.Infrastructure.Filters;
using CDR.Register.API.Infrastructure.Middleware;
using CDR.Register.API.Infrastructure.Models;
using CDR.Register.API.Infrastructure.Versioning;
using CDR.Register.API.Logger;
using CDR.Register.Discovery.API.Extensions;
+using CDR.Register.Domain.Extensions;
using CDR.Register.Repository.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -14,7 +15,6 @@
using Microsoft.Extensions.Hosting;
using Serilog;
using static CDR.Register.API.Infrastructure.Constants;
-using CDR.Register.Domain.Extensions;
namespace CDR.Register.Discovery.API
{
@@ -42,7 +42,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddApiVersioning(options =>
{
- options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); //uses default options atm
+ options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); // uses default options atm
options.ErrorResponses = new ApiVersionErrorResponse();
});
diff --git a/Source/CDR.Register.Domain.UnitTests/CDR.Register.Domain.UnitTests.csproj b/Source/CDR.Register.Domain.UnitTests/CDR.Register.Domain.UnitTests.csproj
index 996e56e..51f445f 100644
--- a/Source/CDR.Register.Domain.UnitTests/CDR.Register.Domain.UnitTests.csproj
+++ b/Source/CDR.Register.Domain.UnitTests/CDR.Register.Domain.UnitTests.csproj
@@ -5,10 +5,12 @@
1.4.0
1.4.0
1.4.0
+ true
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -17,6 +19,14 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.Domain.UnitTests/DataRecipientTests.cs b/Source/CDR.Register.Domain.UnitTests/DataRecipientTests.cs
index a50597a..adc0332 100644
--- a/Source/CDR.Register.Domain.UnitTests/DataRecipientTests.cs
+++ b/Source/CDR.Register.Domain.UnitTests/DataRecipientTests.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using CDR.Register.Domain.Entities;
using Xunit;
@@ -8,7 +8,7 @@ namespace CDR.Register.Domain.UnitTests
public class DataRecipientTests
{
///
- /// When the data recipient has no brands, the last updated date should be null
+ /// When the data recipient has no brands, the last updated date should be null.
///
public static IEnumerable GetEmptyDataRecipientBrands() => new List
{
diff --git a/Source/CDR.Register.Domain/CDR.Register.Domain.csproj b/Source/CDR.Register.Domain/CDR.Register.Domain.csproj
index 0ff2078..82241ec 100644
--- a/Source/CDR.Register.Domain/CDR.Register.Domain.csproj
+++ b/Source/CDR.Register.Domain/CDR.Register.Domain.csproj
@@ -4,6 +4,7 @@
$(Version)
$(Version)
$(Version)
+ true
@@ -13,7 +14,16 @@
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Constants.cs b/Source/CDR.Register.Domain/Constants.cs
index 67c473e..980f485 100644
--- a/Source/CDR.Register.Domain/Constants.cs
+++ b/Source/CDR.Register.Domain/Constants.cs
@@ -5,7 +5,7 @@ public static class Constants
public static class ErrorCodes
{
///
- /// The error codes in this class area defined by the CDR program (not CDS)
+ /// The error codes in this class area defined by the CDR program (not CDS).
///
public static class Generic
{
@@ -24,8 +24,9 @@ public static class Generic
public const string InvalidSoftwareStatement = "invalid_software_statement";
public const string UnapprovedSoftwareStatement = "unapproved_software_statement";
}
+
///
- /// The error codes in this class must match the definition in CDS
+ /// The error codes in this class must match the definition in CDS.
///
public static class Cds
{
diff --git a/Source/CDR.Register.Domain/Entities/Brand.cs b/Source/CDR.Register.Domain/Entities/Brand.cs
index 756e041..0602624 100644
--- a/Source/CDR.Register.Domain/Entities/Brand.cs
+++ b/Source/CDR.Register.Domain/Entities/Brand.cs
@@ -5,11 +5,17 @@ namespace CDR.Register.Domain.Entities
public abstract class Brand
{
private DateTime lastUpdated;
+
public Guid BrandId { get; set; }
+
public string BrandName { get; set; }
+
public string LogoUri { get; set; }
+
public string BrandStatus { get; set; }
+
public bool IsActive { get; set; }
+
public DateTime LastUpdated { get => DateTime.SpecifyKind(lastUpdated, DateTimeKind.Utc); set => lastUpdated = value; }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/DataHolder.cs b/Source/CDR.Register.Domain/Entities/DataHolder.cs
index ed0f034..07aee85 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolder.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolder.cs
@@ -7,11 +7,17 @@ namespace CDR.Register.Domain.Entities
public class DataHolder
{
public Guid DataHolderId { get; set; }
+
public string Status { get; set; }
+
public bool IsActive { get; set; }
+
public string Industry { get; set; }
+
public List Industries { get; set; }
+
public DataHolderLegalEntity LegalEntity { get; set; }
+
public IList Brands { get; set; }
public DateTime? LastUpdated
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderAuthentication.cs b/Source/CDR.Register.Domain/Entities/DataHolderAuthentication.cs
index 1459e39..a463e8a 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderAuthentication.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderAuthentication.cs
@@ -3,6 +3,7 @@
public class DataHolderAuthentication
{
public string RegisterUType { get; set; }
+
public string JwksEndpoint { get; set; }
}
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderBrand.cs b/Source/CDR.Register.Domain/Entities/DataHolderBrand.cs
index e64945d..9f6f6ff 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderBrand.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderBrand.cs
@@ -5,8 +5,9 @@ namespace CDR.Register.Domain.Entities
public class DataHolderBrand : Brand
{
public DataHolder DataHolder { get; set; }
+
public IList DataHolderAuthentications { get; set; }
+
public DataHolderBrandServiceEndpoint DataHolderBrandServiceEndpoint { get; set; }
}
-
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs b/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
index 9042647..20c5cf6 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
@@ -3,10 +3,15 @@
public class DataHolderBrandServiceEndpoint
{
public string Version { get; set; }
+
public string PublicBaseUri { get; set; }
+
public string ResourceBaseUri { get; set; }
+
public string InfosecBaseUri { get; set; }
+
public string ExtensionBaseUri { get; set; }
+
public string WebsiteUri { get; set; }
}
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderLegalEntity.cs b/Source/CDR.Register.Domain/Entities/DataHolderLegalEntity.cs
index 6c21b2f..1bb8a9c 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderLegalEntity.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderLegalEntity.cs
@@ -7,16 +7,27 @@ public class DataHolderLegalEntity
private DateTime? _registrationDate;
public Guid LegalEntityId { get; set; }
+
public string LegalEntityName { get; set; }
+
public string LogoUri { get; set; }
+
public string RegistrationNumber { get; set; }
+
public DateTime? RegistrationDate { get => _registrationDate?.Date; set => _registrationDate = value; }
+
public string RegisteredCountry { get; set; }
+
public string Abn { get; set; }
+
public string Acn { get; set; }
+
public string Arbn { get; set; }
+
public string AnzsicDivision { get; set; }
+
public string OrganisationType { get; set; }
+
public string Status { get; set; }
}
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderStatus.cs b/Source/CDR.Register.Domain/Entities/DataHolderStatus.cs
index 230d7f9..20e1b08 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderStatus.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderStatus.cs
@@ -5,6 +5,7 @@ namespace CDR.Register.Domain.Entities
public class DataHolderStatus
{
public Guid LegalEntityId { get; set; }
+
public string Status { get; set; }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/DataRecipient.cs b/Source/CDR.Register.Domain/Entities/DataRecipient.cs
index 9755bdc..c3a53bb 100644
--- a/Source/CDR.Register.Domain/Entities/DataRecipient.cs
+++ b/Source/CDR.Register.Domain/Entities/DataRecipient.cs
@@ -7,17 +7,23 @@ namespace CDR.Register.Domain.Entities
public class DataRecipient
{
public Guid DataRecipientId { get; set; }
+
public string Status { get; set; }
+
public bool IsActive { get; set; }
+
public string Industry => "banking";
+
public DataRecipientLegalEntity LegalEntity { get; set; }
+
public IList DataRecipientBrands { get; set; }
+
public DateTime? LastUpdated
{
get
{
return this.DataRecipientBrands != null && this.DataRecipientBrands.Any()
- ? DateTime.SpecifyKind(this.DataRecipientBrands.OrderByDescending(brand => brand.LastUpdated).First().LastUpdated, DateTimeKind.Utc)
+ ? DateTime.SpecifyKind(this.DataRecipientBrands.OrderByDescending(brand => brand.LastUpdated).First().LastUpdated, DateTimeKind.Utc)
: null;
}
}
diff --git a/Source/CDR.Register.Domain/Entities/DataRecipientBrand.cs b/Source/CDR.Register.Domain/Entities/DataRecipientBrand.cs
index 45ef6e6..8e451ba 100644
--- a/Source/CDR.Register.Domain/Entities/DataRecipientBrand.cs
+++ b/Source/CDR.Register.Domain/Entities/DataRecipientBrand.cs
@@ -5,6 +5,7 @@ namespace CDR.Register.Domain.Entities
public class DataRecipientBrand : Brand
{
public DataRecipient DataRecipient { get; set; }
+
public ICollection SoftwareProducts { get; set; }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/DataRecipientLegalEntity.cs b/Source/CDR.Register.Domain/Entities/DataRecipientLegalEntity.cs
index ee754bd..80ff115 100644
--- a/Source/CDR.Register.Domain/Entities/DataRecipientLegalEntity.cs
+++ b/Source/CDR.Register.Domain/Entities/DataRecipientLegalEntity.cs
@@ -5,21 +5,33 @@ namespace CDR.Register.Domain.Entities
public class DataRecipientLegalEntity
{
public Guid LegalEntityId { get; set; }
+
public string LegalEntityName { get; set; }
+
public string LogoUri { get; set; }
+
public string OrganisationType { get; set; }
+
public string Status { get; set; }
+
public string AccreditationNumber { get; set; }
+
public string AccreditationLevelId { get; set; }
private DateTime? _registrationDate;
public string RegistrationNumber { get; set; }
+
public DateTime? RegistrationDate { get => _registrationDate?.Date; set => _registrationDate = value; }
+
public string RegisteredCountry { get; set; }
+
public string Abn { get; set; }
+
public string Acn { get; set; }
+
public string Arbn { get; set; }
+
public string AnzsicDivision { get; set; }
}
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Entities/DataRecipientStatus.cs b/Source/CDR.Register.Domain/Entities/DataRecipientStatus.cs
index 32a12d0..225b891 100644
--- a/Source/CDR.Register.Domain/Entities/DataRecipientStatus.cs
+++ b/Source/CDR.Register.Domain/Entities/DataRecipientStatus.cs
@@ -5,12 +5,14 @@ namespace CDR.Register.Domain.Entities
public class DataRecipientStatus
{
public Guid DataRecipientId { get; set; }
+
public string Status { get; set; }
}
public class DataRecipientStatusV2
{
public Guid LegalEntityId { get; set; }
+
public string Status { get; set; }
}
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Entities/SoftwareProduct.cs b/Source/CDR.Register.Domain/Entities/SoftwareProduct.cs
index 1ae67c2..3fa266f 100644
--- a/Source/CDR.Register.Domain/Entities/SoftwareProduct.cs
+++ b/Source/CDR.Register.Domain/Entities/SoftwareProduct.cs
@@ -6,22 +6,39 @@ namespace CDR.Register.Domain.Entities
public class SoftwareProduct
{
public Guid SoftwareProductId { get; set; }
+
public string SoftwareProductName { get; set; }
+
public string SoftwareProductDescription { get; set; }
+
public string LogoUri { get; set; }
+
public string SectorIdentifierUri { get; set; }
+
public string ClientUri { get; set; }
+
public string TosUri { get; set; }
+
public string PolicyUri { get; set; }
+
public string RecipientBaseUri { get; set; }
+
public string RevocationUri { get; set; }
+
public string RedirectUri { get; set; }
+
public IEnumerable RedirectUris => RedirectUri?.Split(" ");
+
public string JwksUri { get; set; }
+
public string Scope { get; set; }
+
public string Status { get; set; }
+
public bool IsActive { get; set; }
+
public ICollection Certificates { get; set; }
+
public DataRecipientBrand DataRecipientBrand { get; set; }
}
}
\ No newline at end of file
diff --git a/Source/CDR.Register.Domain/Entities/SoftwareProductInfosec.cs b/Source/CDR.Register.Domain/Entities/SoftwareProductInfosec.cs
index ae97699..2138d75 100644
--- a/Source/CDR.Register.Domain/Entities/SoftwareProductInfosec.cs
+++ b/Source/CDR.Register.Domain/Entities/SoftwareProductInfosec.cs
@@ -5,8 +5,11 @@ namespace CDR.Register.Domain.Entities
public class SoftwareProductInfosec
{
public string Id { get; set; }
+
public string Name { get; set; }
+
public string JwksUri { get; set; }
+
public IEnumerable X509Certificates { get; set; }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/SoftwareProductStatus.cs b/Source/CDR.Register.Domain/Entities/SoftwareProductStatus.cs
index 2a54272..cae0ee0 100644
--- a/Source/CDR.Register.Domain/Entities/SoftwareProductStatus.cs
+++ b/Source/CDR.Register.Domain/Entities/SoftwareProductStatus.cs
@@ -5,6 +5,7 @@ namespace CDR.Register.Domain.Entities
public class SoftwareProductStatus
{
public Guid SoftwareProductId { get; set; }
+
public string Status { get; set; }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/SoftwareStatementAssertion.cs b/Source/CDR.Register.Domain/Entities/SoftwareStatementAssertion.cs
index ed81ced..ecddcab 100644
--- a/Source/CDR.Register.Domain/Entities/SoftwareStatementAssertion.cs
+++ b/Source/CDR.Register.Domain/Entities/SoftwareStatementAssertion.cs
@@ -3,7 +3,9 @@
public class SoftwareStatementAssertion
{
public DataRecipientBrand DataRecipientBrand { get; set; }
+
public SoftwareProduct SoftwareProduct { get; set; }
+
public DataRecipientLegalEntity LegalEntity { get; set; }
}
}
diff --git a/Source/CDR.Register.Domain/Extensions/MvcBuilderExtensions.cs b/Source/CDR.Register.Domain/Extensions/MvcBuilderExtensions.cs
index a33ec1c..2f3be57 100644
--- a/Source/CDR.Register.Domain/Extensions/MvcBuilderExtensions.cs
+++ b/Source/CDR.Register.Domain/Extensions/MvcBuilderExtensions.cs
@@ -18,8 +18,7 @@ public static IMvcBuilder AddCdrNewtonsoftJson(this IMvcBuilder mvcBuilder)
options.SerializerSettings.NullValueHandling = defaultSettings.NullValueHandling;
options.SerializerSettings.Formatting = defaultSettings.Formatting;
options.SerializerSettings.Converters = defaultSettings.Converters;
- }
- );
+ });
}
}
}
diff --git a/Source/CDR.Register.Domain/Models/CdrJsonSerializerSettings.cs b/Source/CDR.Register.Domain/Models/CdrJsonSerializerSettings.cs
index c8c3ff7..217c553 100644
--- a/Source/CDR.Register.Domain/Models/CdrJsonSerializerSettings.cs
+++ b/Source/CDR.Register.Domain/Models/CdrJsonSerializerSettings.cs
@@ -7,7 +7,8 @@ namespace CDR.Register.Domain.Models
{
public class CdrJsonSerializerSettings : JsonSerializerSettings
{
- public CdrJsonSerializerSettings() : base()
+ public CdrJsonSerializerSettings()
+ : base()
{
ContractResolver = new CamelCasePropertyNamesContractResolver();
DefaultValueHandling = DefaultValueHandling.Include;
diff --git a/Source/CDR.Register.Domain/Models/Error.cs b/Source/CDR.Register.Domain/Models/Error.cs
index 67daed7..edf9bbf 100644
--- a/Source/CDR.Register.Domain/Models/Error.cs
+++ b/Source/CDR.Register.Domain/Models/Error.cs
@@ -25,25 +25,25 @@ public Error(string code, string title, string detail, string metaUrn)
}
///
- /// Error code
+ /// Error code.
///
[Required]
public string Code { get; set; }
///
- /// Error title
+ /// Error title.
///
[Required]
public string Title { get; set; }
///
- /// Error detail
+ /// Error detail.
///
[Required]
public string Detail { get; set; }
///
- /// Optional additional data for specific error types
+ /// Optional additional data for specific error types.
///
public MetaError Meta { get; set; }
}
diff --git a/Source/CDR.Register.Domain/Models/ResponseErrorList.cs b/Source/CDR.Register.Domain/Models/ResponseErrorList.cs
index 1d33bbb..e9d45b8 100644
--- a/Source/CDR.Register.Domain/Models/ResponseErrorList.cs
+++ b/Source/CDR.Register.Domain/Models/ResponseErrorList.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.Linq;
namespace CDR.Register.Domain.Models
{
@@ -31,7 +30,7 @@ public ResponseErrorList(string errorCode, string errorTitle, string errorDetail
}
///
- /// Add unexpected error to the response error list
+ /// Add unexpected error to the response error list.
///
public ResponseErrorList AddUnexpectedError(string message)
{
@@ -46,7 +45,7 @@ public ResponseErrorList AddUnexpectedError()
}
///
- /// Add invalid industry error to the response error list
+ /// Add invalid industry error to the response error list.
///
public ResponseErrorList AddInvalidIndustry()
{
@@ -115,22 +114,22 @@ public static Error InvalidDateTime()
return new Error(Constants.ErrorCodes.Cds.InvalidDateTime, Constants.ErrorTitles.InvalidDateTime, "{0} should be valid DateTimeString");
}
- public static Error InvalidPageSize() //Should be looked at compared to CDS
+ public static Error InvalidPageSize() // Should be looked at compared to CDS
{
return new Error(Constants.ErrorCodes.Cds.InvalidPageSize, Constants.ErrorTitles.InvalidPageSize, "Page size not a positive Integer");
}
- public static Error PageSizeTooLarge() //Should be looked at compared to CDS
+ public static Error PageSizeTooLarge() // Should be looked at compared to CDS
{
return new Error(Constants.ErrorCodes.Cds.InvalidField, Constants.ErrorTitles.InvalidField, "Page size too large");
}
- public static Error InvalidPage() //Should be looked at compared to CDS
+ public static Error InvalidPage() // Should be looked at compared to CDS
{
return new Error(Constants.ErrorCodes.Cds.InvalidField, Constants.ErrorTitles.InvalidField, "Page not a positive integer");
}
- public static Error PageOutOfRange() //Should be looked at compared to CDS
+ public static Error PageOutOfRange() // Should be looked at compared to CDS
{
return new Error(Constants.ErrorCodes.Cds.InvalidField, Constants.ErrorTitles.InvalidField, "Page is out of range");
}
diff --git a/Source/CDR.Register.Domain/ValueObjects/BusinessRuleError.cs b/Source/CDR.Register.Domain/ValueObjects/BusinessRuleError.cs
index 1b94df2..ca446f7 100644
--- a/Source/CDR.Register.Domain/ValueObjects/BusinessRuleError.cs
+++ b/Source/CDR.Register.Domain/ValueObjects/BusinessRuleError.cs
@@ -3,7 +3,9 @@
public class BusinessRuleError
{
public string Code { get; set; }
+
public string Title { get; set; }
+
public string Detail { get; set; }
public BusinessRuleError(string errorCode, string errorTitle, string errorDetail)
diff --git a/Source/CDR.Register.Domain/ValueObjects/Page.cs b/Source/CDR.Register.Domain/ValueObjects/Page.cs
index d3123f4..f6c3398 100644
--- a/Source/CDR.Register.Domain/ValueObjects/Page.cs
+++ b/Source/CDR.Register.Domain/ValueObjects/Page.cs
@@ -3,14 +3,17 @@
namespace CDR.Register.Domain.ValueObjects
{
- public class Page where T : IEnumerable
+ public class Page
+ where T : IEnumerable
{
public T Data { get; set; }
public int CurrentPage { get; set; }
+
public int PageSize { get; set; }
public int TotalRecords { get; set; }
+
public int TotalPages
{
get
diff --git a/Source/CDR.Register.Infosec/CDR.Register.Infosec.csproj b/Source/CDR.Register.Infosec/CDR.Register.Infosec.csproj
index c31a050..4dde46a 100644
--- a/Source/CDR.Register.Infosec/CDR.Register.Infosec.csproj
+++ b/Source/CDR.Register.Infosec/CDR.Register.Infosec.csproj
@@ -23,18 +23,27 @@
-
-
-
+
+
+
+
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.Infosec/Constants.cs b/Source/CDR.Register.Infosec/Constants.cs
index 0aa8c29..944ea7c 100644
--- a/Source/CDR.Register.Infosec/Constants.cs
+++ b/Source/CDR.Register.Infosec/Constants.cs
@@ -1,7 +1,7 @@
namespace CDR.Register.Infosec
{
public static class Constants
- {
+ {
public static class Scopes
{
public const string RegisterRead = "cdr-register:read";
diff --git a/Source/CDR.Register.Infosec/ConsumerDataRight.ParticipantTooling.MockRegister.API.Infosec.xml b/Source/CDR.Register.Infosec/ConsumerDataRight.ParticipantTooling.MockRegister.API.Infosec.xml
index da8428a..6ea86c8 100644
--- a/Source/CDR.Register.Infosec/ConsumerDataRight.ParticipantTooling.MockRegister.API.Infosec.xml
+++ b/Source/CDR.Register.Infosec/ConsumerDataRight.ParticipantTooling.MockRegister.API.Infosec.xml
@@ -6,10 +6,10 @@
-
+ Validate Client Assertion.
- client_id (form param) when provided and must match client assertion issuer and subject
- clientAssertion
+ client_id (form param) when provided and must match client assertion issuer and subject.
+ client Assertion.
diff --git a/Source/CDR.Register.Infosec/Controllers/DiscoveryController.cs b/Source/CDR.Register.Infosec/Controllers/DiscoveryController.cs
index f29abdd..1d82a77 100644
--- a/Source/CDR.Register.Infosec/Controllers/DiscoveryController.cs
+++ b/Source/CDR.Register.Infosec/Controllers/DiscoveryController.cs
@@ -1,4 +1,4 @@
-using CDR.Register.API.Infrastructure;
+using CDR.Register.API.Infrastructure;
using CDR.Register.Infosec.Models;
using IdentityModel;
using Microsoft.AspNetCore.Mvc;
@@ -48,7 +48,7 @@ public DiscoveryDocument Get()
[Route("openid-configuration/jwks")]
public API.Infrastructure.Models.JsonWebKeySet? GetJwks()
{
- var cert = new X509Certificate2(_configuration.GetValue("SigningCertificate:Path") ?? "", _configuration.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable);
+ var cert = new X509Certificate2(_configuration.GetValue("SigningCertificate:Path") ?? string.Empty, _configuration.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable);
var cert64 = Convert.ToBase64String(cert.RawData);
var signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSsaPssSha256);
var thumbprint = Base64Url.Encode(cert.GetCertHash());
@@ -75,11 +75,13 @@ public DiscoveryDocument Get()
x5c = [cert64],
alg = "PS256"
}
+
]
};
return jwks;
}
+
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Infosec/Controllers/TokenController.cs b/Source/CDR.Register.Infosec/Controllers/TokenController.cs
index 5917e3a..c190397 100644
--- a/Source/CDR.Register.Infosec/Controllers/TokenController.cs
+++ b/Source/CDR.Register.Infosec/Controllers/TokenController.cs
@@ -1,4 +1,4 @@
-using CDR.Register.API.Infrastructure;
+using CDR.Register.API.Infrastructure;
using CDR.Register.Domain.Entities;
using CDR.Register.Infosec.Interfaces;
using CDR.Register.Infosec.Models;
@@ -58,7 +58,7 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
return (false, "invalid_request", "Content-Type is not application/x-www-form-urlencoded", null);
}
- // Basic validation.
+ // Basic validation.
var basicValidationResult = ValidateBasicParameters(clientAssertion);
if (!basicValidationResult.isValid)
{
@@ -66,7 +66,7 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
}
// Grant type needs to be client_credentials.
- if (clientAssertion.grant_type!= null && !clientAssertion.grant_type.Equals("client_credentials", StringComparison.OrdinalIgnoreCase))
+ if (clientAssertion.grant_type != null && !clientAssertion.grant_type.Equals("client_credentials", StringComparison.OrdinalIgnoreCase))
{
return (false, "unsupported_grant_type", "grant_type must be client_credentials", null);
}
@@ -84,7 +84,7 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
return scopeValidationResult;
}
- // Code changes for client id optional
+ // Code changes for client id optional
// The issuer of the client assertion is the client_id of the calling data recipient.
// Need to extract the client_id (iss) from client assertion to load the client details.
var tokenValidationResult = ValidateClientAssertionToken(clientAssertion.client_assertion);
@@ -94,7 +94,7 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
}
// Validate the client assertion.
- var clientAssertionResult = await _tokenService.ValidateClientAssertion(clientAssertion.client_id ?? "", clientAssertion.client_assertion ?? "");
+ var clientAssertionResult = await _tokenService.ValidateClientAssertion(clientAssertion.client_id ?? string.Empty, clientAssertion.client_assertion ?? string.Empty);
if (!clientAssertionResult.isValid)
{
@@ -165,7 +165,7 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
{
var handler = new JwtSecurityTokenHandler();
- if (clientAssertion == null || !handler.CanReadToken(clientAssertion))
+ if (clientAssertion == null || !handler.CanReadToken(clientAssertion))
{
return (false, ErrorCodes.Generic.InvalidClient, "Invalid client_assertion - token validation error", null);
}
@@ -179,8 +179,6 @@ public async Task GetAccessToken([FromForm] ClientAssertionReques
return (true, null, null, null);
}
-
-
private bool IsValidCertificate(
SoftwareProductInfosec client)
{
@@ -196,6 +194,7 @@ private bool IsValidCertificate(
// Find a matching cert for the software product client.
var certs = client.X509Certificates.ToList();
+
// Check if there is a matching cert with the provided common name (validating the thumbprint is not required)
var matchingCert = certs.Find(c =>
c.CommonName.GetCommonName().Equals(httpHeaderCommonName, StringComparison.OrdinalIgnoreCase));
@@ -205,4 +204,4 @@ private bool IsValidCertificate(
return matchingCert != null;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Infosec/Models/DiscoveryDocument.cs b/Source/CDR.Register.Infosec/Models/DiscoveryDocument.cs
index e84fd07..8a56aa9 100644
--- a/Source/CDR.Register.Infosec/Models/DiscoveryDocument.cs
+++ b/Source/CDR.Register.Infosec/Models/DiscoveryDocument.cs
@@ -1,7 +1,7 @@
using Newtonsoft.Json;
namespace CDR.Register.Infosec.Models
-{
+{
public class DiscoveryDocument
{
[JsonProperty("issuer")]
@@ -42,6 +42,5 @@ public class DiscoveryDocument
[JsonProperty("token_endpoint_auth_signing_alg_values_supported")]
public string[]? TokenEndpointAuthSigningAlgValuesSupported { get; set; }
-
}
}
diff --git a/Source/CDR.Register.Infosec/Models/ResponseBase.cs b/Source/CDR.Register.Infosec/Models/IResponseBase.cs
similarity index 100%
rename from Source/CDR.Register.Infosec/Models/ResponseBase.cs
rename to Source/CDR.Register.Infosec/Models/IResponseBase.cs
diff --git a/Source/CDR.Register.Infosec/Program.cs b/Source/CDR.Register.Infosec/Program.cs
index 51c3e6f..b9a4904 100644
--- a/Source/CDR.Register.Infosec/Program.cs
+++ b/Source/CDR.Register.Infosec/Program.cs
@@ -1,11 +1,5 @@
-using System;
-using System.IO;
-using CDR.Register.API.Infrastructure;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Hosting;
+using CDR.Register.API.Infrastructure;
using Serilog;
-using Serilog.Events;
namespace CDR.Register.Infosec
{
@@ -21,7 +15,7 @@ public static int Main(string[] args)
.Build();
Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
+ .ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
diff --git a/Source/CDR.Register.Infosec/Services/ClientService.cs b/Source/CDR.Register.Infosec/Services/ClientService.cs
index 2d9d7e6..81a1e71 100644
--- a/Source/CDR.Register.Infosec/Services/ClientService.cs
+++ b/Source/CDR.Register.Infosec/Services/ClientService.cs
@@ -19,6 +19,7 @@ public ClientService(IRegisterInfosecRepository infosecRepository)
{
return null;
}
+
if (!Guid.TryParse(clientId, out Guid softwareProductId))
{
return null;
diff --git a/Source/CDR.Register.Infosec/Services/ITokenService.cs b/Source/CDR.Register.Infosec/Services/ITokenService.cs
index 3c438e7..3875519 100644
--- a/Source/CDR.Register.Infosec/Services/ITokenService.cs
+++ b/Source/CDR.Register.Infosec/Services/ITokenService.cs
@@ -1,11 +1,10 @@
-using System.Threading.Tasks;
-using CDR.Register.Domain.Entities;
+using CDR.Register.Domain.Entities;
using Microsoft.IdentityModel.Tokens;
namespace CDR.Register.Infosec.Interfaces
{
public interface ITokenService
- {
+ {
Task<(bool isValid, string? message, SoftwareProductInfosec? client)> ValidateClientAssertion(string client_id, string clientAssertion);
Task CreateAccessToken(
@@ -17,6 +16,5 @@ Task CreateAccessToken(
Task> GetClientKeys(SoftwareProductInfosec client);
Task> GetClientJwks(SoftwareProductInfosec client);
-
}
}
diff --git a/Source/CDR.Register.Infosec/Services/TokenService.cs b/Source/CDR.Register.Infosec/Services/TokenService.cs
index ab30a6f..5e3d9b0 100644
--- a/Source/CDR.Register.Infosec/Services/TokenService.cs
+++ b/Source/CDR.Register.Infosec/Services/TokenService.cs
@@ -33,10 +33,10 @@ public TokenService(
}
///
- ///
+ /// Validate Client Assertion.
///
- /// client_id (form param) when provided and must match client assertion issuer and subject
- /// clientAssertion
+ /// client_id (form param) when provided and must match client assertion issuer and subject.
+ /// client Assertion.
///
public async Task<(bool isValid, string? message, SoftwareProductInfosec? client)> ValidateClientAssertion(string? client_id, string clientAssertion)
{
@@ -46,7 +46,7 @@ public TokenService(
{
var handler = new JwtSecurityTokenHandler();
- // Validate the client assertion token.
+ // Validate the client assertion token.
var invalidToken = handler.ReadJwtToken(clientAssertion);
var clientId = invalidToken.Issuer;
if (string.IsNullOrEmpty(clientId))
@@ -57,8 +57,7 @@ public TokenService(
// client_id (form param) when provided and must match client assertion issuer and subject
if (!string.IsNullOrEmpty(client_id) &&
(!client_id.Equals(invalidToken.Issuer, StringComparison.OrdinalIgnoreCase) ||
- !client_id.Equals(invalidToken.Subject, StringComparison.OrdinalIgnoreCase)
- ))
+ !client_id.Equals(invalidToken.Subject, StringComparison.OrdinalIgnoreCase)))
{
return (false, "Invalid client_assertion - 'sub' and 'iss' must be set to the client_id", null);
}
@@ -122,15 +121,14 @@ private async Task BuildTokenValidationParameters(
return new TokenValidationParameters
{
ValidateIssuer = false,
- IssuerSigningKeys = (await GetClientKeys(client)),
+ IssuerSigningKeys = await GetClientKeys(client),
ValidateIssuerSigningKey = true,
ValidAudiences = validAudiences,
ValidateAudience = true,
AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
-
- bool isValid = audiences.Any(audience => validationParameters.ValidAudiences.Contains(audience, StringComparer.OrdinalIgnoreCase));
+ bool isValid = audiences.Any(audience => validationParameters.ValidAudiences.Contains(audience, StringComparer.OrdinalIgnoreCase));
if (!isValid)
{
@@ -170,12 +168,12 @@ public async Task CreateAccessToken(
string scope,
string cnf)
{
- var cert = await Task.Run(() => new X509Certificate2(_configuration.GetValue("SigningCertificate:Path") ?? "", _configuration.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable));
+ var cert = await Task.Run(() => new X509Certificate2(_configuration.GetValue("SigningCertificate:Path") ?? string.Empty, _configuration.GetValue("SigningCertificate:Password"), X509KeyStorageFlags.Exportable));
var signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSsaPssSha256);
var issuer = _configuration.GetInfosecBaseUrl(_httpContextAccessor.HttpContext);
- List claims = [new Claim("client_id", client.Id),
- new Claim("jti", Guid.NewGuid().ToString()),
+ List claims = [new Claim("client_id", client.Id),
+ new Claim("jti", Guid.NewGuid().ToString()),
new Claim("scope", scope)];
claims.Add(new Claim(
@@ -228,7 +226,7 @@ public async Task> GetClientJwks(SoftwareProductInfosec client
handler.SetServerCertificateValidation(_configuration);
var httpClient = new HttpClient(handler);
- var passUserAgent = _configuration.GetValue("PassUserAgent"); //allows CTS to attach a header for request filtering
+ var passUserAgent = _configuration.GetValue("PassUserAgent"); // allows CTS to attach a header for request filtering
if (passUserAgent)
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "mock-register");
diff --git a/Source/CDR.Register.Infosec/Startup.cs b/Source/CDR.Register.Infosec/Startup.cs
index c47017e..f12ba5a 100644
--- a/Source/CDR.Register.Infosec/Startup.cs
+++ b/Source/CDR.Register.Infosec/Startup.cs
@@ -58,7 +58,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddDataProtection()
.SetApplicationName("reg-infosec")
.PersistKeysToStackExchangeRedis(
- StackExchange.Redis.ConnectionMultiplexer.Connect(Configuration.GetConnectionString(Constants.ConnectionStringNames.Cache) ?? ""),
+ StackExchange.Redis.ConnectionMultiplexer.Connect(Configuration.GetConnectionString(Constants.ConnectionStringNames.Cache) ?? string.Empty),
"register-cache-dp-keys");
}
else
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
index 811a94b..a229f63 100644
--- a/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
@@ -22,7 +22,10 @@ namespace CDR.Register.IntegrationTests.API.Discovery
///
public class US27560_GetDataRecipients_MultiIndustry_Tests : BaseTest
{
- public US27560_GetDataRecipients_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US27560_GetDataRecipients_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
// Get expected data recipients
private static string GetExpectedDataRecipients(string url)
@@ -70,8 +73,10 @@ private static string GetExpectedDataRecipients(string url)
lastUpdated = participation.Brands.OrderByDescending(brand => brand.LastUpdated).First().LastUpdated.ToString("yyyy-MM-ddTHH:mm:ssZ")
})
.ToList(),
+
// DF: these are new properties that need to be included in the Get Data Recipients payload.
- links = new {
+ links = new
+ {
self = url
},
meta = new object()
@@ -92,18 +97,18 @@ private static string GetExpectedDataRecipients(string url)
[InlineData(3, "banking")]
[InlineData(3, "energy")]
[InlineData(3, "telco")]
- public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int XV, string industry)
+ public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int xv, string industry)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients";
var expectedDataRecipients = GetExpectedDataRecipients(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV.ToString()
+ XV = xv.ToString()
}.SendAsync();
// Assert
@@ -116,7 +121,7 @@ public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int XV,
Assert_HasContentType_ApplicationJson(response.Content);
// // Assert - Check XV
- Assert_HasHeader(XV.ToString(), response.Headers, "x-v");
+ Assert_HasHeader(xv.ToString(), response.Headers, "x-v");
// Assert - Check json
await Assert_HasContent_Json(expectedDataRecipients, response.Content);
@@ -129,18 +134,18 @@ public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int XV,
[InlineData(3, "banking")]
[InlineData(3, "energy")]
[InlineData(3, "telco")]
- public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int XV, string industry)
+ public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(int xv, string industry)
{
- // Arrange
+ // Arrange
var url = $"{GenerateDynamicCtsUrl(DISCOVERY_DOWNSTREAM_BASE_URL)}/cdr-register/v1/{industry}/data-recipients";
var expectedDataRecipients = GetExpectedDataRecipients(ReplacePublicHostName(url, DISCOVERY_DOWNSTREAM_BASE_URL));
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV.ToString()
+ XV = xv.ToString()
}.SendAsync();
// Assert
@@ -153,7 +158,7 @@ public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_DataRecipients
Assert_HasContentType_ApplicationJson(response.Content);
// // Assert - Check XV
- Assert_HasHeader(XV.ToString(), response.Headers, "x-v");
+ Assert_HasHeader(xv.ToString(), response.Headers, "x-v");
// Assert - Check json
await Assert_HasContent_Json(expectedDataRecipients, response.Content);
@@ -165,12 +170,12 @@ public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_DataRecipients
[InlineData("foo")] // AC06
public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients";
var expectedDataRecipients = GetExpectedDataRecipients(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
@@ -202,16 +207,16 @@ public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(str
public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
{
// Arrange - Get SoftwareProductsStatus and save the ETag
- var expectedETag = (await new Infrastructure.API
+ var expectedETag = (await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients",
XV = "3",
- IfNoneMatch = null, // ie If-None-Match is not set
+ IfNoneMatch = null, // ie If-None-Match is not set
}.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients",
@@ -231,29 +236,28 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
}
[Theory]
- [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-min-v is ignored when > x-v
- [InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is supported and higher than x-min-v
- [InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is supported equal to x-min-v
- [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
- [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //invalid. x-v is not supported and x-min-v invalid
- [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. Both x-v and x-min-v exceed supported version of 3
- [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is invalid with valid x-min-v
- [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is higher than supported version of 3
- [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is an empty string
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is missing
+ [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
+ [InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported equal to x-min-v
+ [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // invalid. x-v is not supported and x-min-v invalid
+ [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
public async Task ACX01_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
{
-
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/banking/data-recipients",
@@ -280,7 +284,6 @@ public async Task ACX01_VersionHeaderValidation(string? xv, string? minXv, strin
// Assert - Check error response
await Assert_HasContent_Json(expecetdError, response.Content);
}
-
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs
index f787278..0fee2aa 100644
--- a/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs
@@ -1,6 +1,4 @@
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.IntegrationTests.Infrastructure;
-using CDR.Register.IntegrationTests.Models;
+using CDR.Register.IntegrationTests.Infrastructure;
using CDR.Register.Repository.Entities;
using CDR.Register.Repository.Infrastructure;
using FluentAssertions;
@@ -8,8 +6,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using Newtonsoft.Json.Serialization;
using System;
using System.Linq;
using System.Net;
@@ -27,9 +23,14 @@ namespace CDR.Register.IntegrationTests.API.Discovery
///
public class US27562_GetDataHolderBrands_MultiIndustry_Tests : BaseTest
{
- public US27562_GetDataHolderBrands_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US27562_GetDataHolderBrands_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
// Participation/Brand/SoftwareProduct Ids
- private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup
+ private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup
+
private const string BRANDID = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
private const string SOFTWAREPRODUCTID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
@@ -78,8 +79,7 @@ static string Link(string baseUrl, DateTime? updatedSince, int? page = null, int
.Include(brand => brand.Participation.Industry)
.Where(brand =>
brand.Participation.ParticipationTypeId == ParticipationTypes.Dh &&
- (industry == null || (industry != null && brand.Participation.Industry.IndustryTypeCode == industry))
- )
+ (industry == null || (industry != null && brand.Participation.Industry.IndustryTypeCode == industry)))
.Where(brand => brand.Participation.StatusId == ParticipationStatusType.Active)
.Where(brand => brand.BrandStatusId == BrandStatusType.Active)
.Where(brand => updatedSince == null || brand.LastUpdated > updatedSince);
@@ -91,6 +91,7 @@ static string Link(string baseUrl, DateTime? updatedSince, int? page = null, int
{
throw new Exception($"Page {page} out of range. Min Page is {MINPAGE}");
}
+
var maxPage = ((totalRecords - 1) / pageSize) + 1;
if (page > maxPage)
{
@@ -191,6 +192,7 @@ static string GetUrl(string baseUrl, DateTime? updatedSince, int? queryPage, int
{
query.Add("page", queryPage.Value);
}
+
if (queryPageSize != null)
{
query.Add("page-size", queryPageSize.Value);
@@ -213,7 +215,7 @@ static string GetUrl(string baseUrl, DateTime? updatedSince, int? queryPage, int
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -247,7 +249,7 @@ static string GetUrl(string baseUrl, DateTime? updatedSince, int? queryPage, int
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
[InlineData("energy")]
[InlineData("telco")]
@@ -264,7 +266,6 @@ public async Task AC01_Get_WithNoQueryString_ShouldRespondWith_200OK_First25Reco
[InlineData("telco")]
public async Task AC01_CTS_URL_Get_WithNoQueryString_ShouldRespondWith_200OK_First25RecordsAsync(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
-
// Arrange
string conformanceId = Guid.NewGuid().ToString();
string tokenEndpoint = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL, conformanceId)}/idp/connect/token";
@@ -285,7 +286,7 @@ public async Task AC01_CTS_URL_Get_WithNoQueryString_ShouldRespondWith_200OK_Fir
CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME
}.GetAsync(addCertificateToRequest: false);
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -321,7 +322,7 @@ public async Task AC01_CTS_URL_Get_WithNoQueryString_ShouldRespondWith_200OK_Fir
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
public async Task AC02_Get_WithPageSize5_ShouldRespondWith_200OK_Page1Of5Records(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
@@ -329,7 +330,7 @@ public async Task AC02_Get_WithPageSize5_ShouldRespondWith_200OK_Page1Of5Records
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
public async Task AC03_Get_WithPageSize5_AndPage3_ShouldRespondWith_200OK_Page3Of5Records(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
@@ -337,7 +338,7 @@ public async Task AC03_Get_WithPageSize5_AndPage3_ShouldRespondWith_200OK_Page3O
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
public async Task AC04_Get_WithPageSize5_AndPage6_ShouldRespondWith_200OK_Page6Of5Records(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
@@ -345,7 +346,7 @@ public async Task AC04_Get_WithPageSize5_AndPage6_ShouldRespondWith_200OK_Page6O
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
public async Task AC05_Get_WithUpdatedSince01042021_ShouldRespondWith_200OK_2Records(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
@@ -353,7 +354,7 @@ public async Task AC05_Get_WithUpdatedSince01042021_ShouldRespondWith_200OK_2Rec
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
[InlineData("energy")]
[InlineData("telco")]
@@ -383,7 +384,7 @@ public async Task AC07_Get_WithUpdatedSinceInvalidDate_ShouldRespondWith_400BadR
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -405,7 +406,7 @@ public async Task AC07_Get_WithUpdatedSinceInvalidDate_ShouldRespondWith_400BadR
// Assert - Check error response
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
{
- // Assert - Check content type
+ // Assert - Check content type
Assert_HasContentType_ApplicationJson(response.Content);
// Assert - Check error response
@@ -426,7 +427,7 @@ public async Task AC07_Get_WithUpdatedSinceInvalidDate_ShouldRespondWith_400BadR
private static async Task Test_AC09_AC10(string? accessToken, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
{
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -478,7 +479,7 @@ public async Task AC11_Get_WithExpiredAccessToken_ShouldRespondWith_401Unauthori
// Expired at "Tuesday, May 18, 2021 11:33:45 PM GMT+10:00"
var accessToken = "eyJhbGciOiJQUzI1NiIsImtpZCI6IkFBMjRGMTg1RUUzRjY3NTA0ODA4RkM0RTI2QjEzNUI5OUU2M0JEQTkiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJxaVR4aGU0X1oxQklDUHhPSnJFMXVaNWp2YWsifQ.eyJuYmYiOjE2MjEzNDQ1MjUsImV4cCI6MTYyMTM0NDgyNSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzAwMC9pZHAiLCJhdWQiOiJjZHItcmVnaXN0ZXIiLCJjbGllbnRfaWQiOiI2ZjdhMWI4ZS04Nzk5LTQ4YTgtOTAxMS1lMzkyMDM5MWY3MTMiLCJqdGkiOiJDODRBNTM5MTA2QjI4NUJBODI2RjZGMDQ3MjU4RjBBNCIsImlhdCI6MTYyMTM0NDUyNSwic2NvcGUiOlsiY2RyLXJlZ2lzdGVyOmJhbms6cmVhZCJdLCJjbmYiOnsieDV0I1MyNTYiOiI1OEQ3NkY3QTYxQ0Q3MjZEQTFDNTRGNjg5OEU4RTY5RUE0Qzg4MDYwIn19.RTU-zrqkb-WXcJzCz62SJ4h19lj8MDyGcvLOmg0qx05WFbAsY4mEP3gsoqM1LJfq4ncw7RqSvbkCNQQ-NOnyoBHF8MGe7mzdUh3YrD0_lTg20Dkx1-l044svtP_CKTI3rXT3bZaYWce0Tb1s3mrJzfN3ja23o93FGR-wbIwHp2347b0DxjznpKBw5meLhAjS7OCx6_uMm1la6IziSQgqMd2WaA-od7w8J5br-Nn-QZZi7X1KGiPEKFDFNk8KrUdPc4NCH6t7f-Sbc34KNNEWfAOJkWdDrmsBaifSlWvSlS4nUnurGHYkmimA2JUuv3ZTqzCcLRamEER1ZoTcIs_PDw";
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -500,7 +501,7 @@ public async Task AC11_Get_WithExpiredAccessToken_ShouldRespondWith_401Unauthori
}
[Theory]
- [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData(null, HttpStatusCode.NotFound)]
[InlineData("banking")]
[InlineData("energy")]
[InlineData("telco")]
@@ -513,7 +514,7 @@ public async Task AC12_Get_WithDifferentHolderOfKey_ShouldRespondWith_401Unautho
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = ADDITIONAL_CERTIFICATE_FILENAME, // ie different holder of key
CertificatePassword = ADDITIONAL_CERTIFICATE_PASSWORD,
@@ -543,7 +544,7 @@ private static async Task Test_AC13_AC14_AC15_AC16(string queryString, HttpStatu
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -565,10 +566,10 @@ private static async Task Test_AC13_AC14_AC15_AC16(string queryString, HttpStatu
// Assert - Check error response
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
{
- // Assert - Check content type
+ // Assert - Check content type
Assert_HasContentType_ApplicationJson(response.Content);
- // Assert - Check error response
+ // Assert - Check error response
await Assert_HasContent_Json(expectedContent, response.Content);
}
}
@@ -597,7 +598,10 @@ private static async Task Test_AC13_AC14_AC15_AC16(string queryString, HttpStatu
[InlineData("foo", HttpStatusCode.BadRequest, "telco")]
public async Task AC13_Get_WithInvalidPageSize_ShouldRespondWith_400BadRequest_PageSizeMustBePositiveInteger(string pageSize, HttpStatusCode expectedStatusCode, string? industry)
{
- await Test_AC13_AC14_AC15_AC16($"page-size={pageSize}", expectedStatusCode, @"
+ await Test_AC13_AC14_AC15_AC16(
+ $"page-size={pageSize}",
+ expectedStatusCode,
+ @"
{
""errors"": [
{
@@ -633,7 +637,10 @@ await Test_AC13_AC14_AC15_AC16($"page-size={pageSize}", expectedStatusCode, @"
[InlineData("foo", HttpStatusCode.BadRequest, "telco")]
public async Task AC14_Get_WithInvalidPage_ShouldRespondWith_400BadRequest_PageMustBePositiveInteger(string page, HttpStatusCode expectedStatusCode, string? industry)
{
- await Test_AC13_AC14_AC15_AC16($"page={page}", expectedStatusCode, @"
+ await Test_AC13_AC14_AC15_AC16(
+ $"page={page}",
+ expectedStatusCode,
+ @"
{
""errors"": [
{
@@ -653,7 +660,10 @@ await Test_AC13_AC14_AC15_AC16($"page={page}", expectedStatusCode, @"
[InlineData("3", "telco")]
public async Task AC15_Get_WithPageOutOfRange_ShouldRespondWith_400BadRequest_PageExceedsMaxNumberOfPages(string page, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest)
{
- await Test_AC13_AC14_AC15_AC16($"page={page}", expectedStatusCode, @"
+ await Test_AC13_AC14_AC15_AC16(
+ $"page={page}",
+ expectedStatusCode,
+ @"
{
""errors"": [
{
@@ -673,7 +683,10 @@ await Test_AC13_AC14_AC15_AC16($"page={page}", expectedStatusCode, @"
[InlineData("1001", "telco")]
public async Task AC16_Get_WithPageSizeTooLarge_ShouldRespondWith_400BadRequest_PageSizeTooLarge(string pageSize, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest)
{
- await Test_AC13_AC14_AC15_AC16($"page-size={pageSize}", expectedStatusCode, @"
+ await Test_AC13_AC14_AC15_AC16(
+ $"page-size={pageSize}",
+ expectedStatusCode,
+ @"
{
""errors"": [
{
@@ -686,9 +699,12 @@ await Test_AC13_AC14_AC15_AC16($"page-size={pageSize}", expectedStatusCode, @"
industry);
}
- delegate void BeforeTestAC181920();
- delegate void AfterTestAC181920Request();
- private static async Task Test_AC17_AC18_AC19(HttpStatusCode expectedStatusCode,
+ private delegate void BeforeTestAC181920();
+
+ private delegate void AfterTestAC181920Request();
+
+ private static async Task Test_AC17_AC18_AC19(
+ HttpStatusCode expectedStatusCode,
BeforeTestAC181920? beforeRequest,
AfterTestAC181920Request? afterRequest,
string? industry)
@@ -699,7 +715,7 @@ private static async Task Test_AC17_AC18_AC19(HttpStatusCode expectedStatusCode,
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -724,10 +740,10 @@ private static async Task Test_AC17_AC18_AC19(HttpStatusCode expectedStatusCode,
// Assert - Check error response
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
{
- // Assert - Check content type
+ // Assert - Check content type
Assert_HasContentType_ApplicationJson(response.Content);
- // Assert - Check error response
+ // Assert - Check error response
var expectedContent = @"
{
""errors"": [
@@ -749,30 +765,30 @@ private static async Task Test_AC17_AC18_AC19(HttpStatusCode expectedStatusCode,
}
[Theory]
- [InlineData(1, HttpStatusCode.NotFound, null)] // Active
- [InlineData(2, HttpStatusCode.NotFound, null)] // Removed
- [InlineData(3, HttpStatusCode.NotFound, null)] // Suspended
- [InlineData(4, HttpStatusCode.NotFound, null)] // Revoked
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Suspended
+ [InlineData(4, HttpStatusCode.NotFound, null)] // Revoked
[InlineData(5, HttpStatusCode.NotFound, null)] // Surrendered
- [InlineData(6, HttpStatusCode.NotFound, null)] // Inactive
- [InlineData(1, HttpStatusCode.OK, "banking")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Removed
- [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden, "banking")] // Revoked
+ [InlineData(6, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "banking")] // Revoked
[InlineData(5, HttpStatusCode.Forbidden, "banking")] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden, "banking")] // Inactive
- [InlineData(1, HttpStatusCode.OK, "energy")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Removed
- [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden, "energy")] // Revoked
+ [InlineData(6, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "energy")] // Revoked
[InlineData(5, HttpStatusCode.Forbidden, "energy")] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden, "energy")] // Inactive
- [InlineData(1, HttpStatusCode.OK, "telco")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Removed
- [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden, "telco")] // Revoked
+ [InlineData(6, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "telco")] // Revoked
[InlineData(5, HttpStatusCode.Forbidden, "telco")] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden, "telco")] // Inactive
+ [InlineData(6, HttpStatusCode.Forbidden, "telco")] // Inactive
public async Task ACX17_Get_WithDataRecipientNotActive_ShouldRespondWith_403Forbidden(
int participationStatusId,
HttpStatusCode expectedStatusCode,
@@ -788,18 +804,18 @@ await Test_AC17_AC18_AC19(
}
[Theory]
- [InlineData(1, HttpStatusCode.NotFound, null)] // Active
- [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
- [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
- [InlineData(1, HttpStatusCode.OK, "banking")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
- [InlineData(1, HttpStatusCode.OK, "energy")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
- [InlineData(1, HttpStatusCode.OK, "telco")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
public async Task ACX18_Get_WithDataRecipientBrandNotActive_ShouldRespondWith_403Forbidden(
int brandStatusId,
HttpStatusCode expectedStatusCode,
@@ -811,23 +827,22 @@ await Test_AC17_AC18_AC19(
expectedStatusCode,
beforeRequest: () => SetBrandStatusId(BRANDID, brandStatusId),
afterRequest: () => SetBrandStatusId(BRANDID, saveBrandStatusId),
- industry: industry
- );
+ industry: industry);
}
[Theory]
- [InlineData(1, HttpStatusCode.NotFound, null)] // Active
- [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
- [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
- [InlineData(1, HttpStatusCode.OK, "banking")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
- [InlineData(1, HttpStatusCode.OK, "energy")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
- [InlineData(1, HttpStatusCode.OK, "telco")] // Active
- [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
public async Task ACX19_Get_WithDataRecipientSoftwareProductNotActive_ShouldRespondWith_403Forbidden(
int softwareProductStatusId,
HttpStatusCode expectedStatusCode,
@@ -839,8 +854,7 @@ await Test_AC17_AC18_AC19(
expectedStatusCode,
beforeRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, softwareProductStatusId),
afterRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, saveSoftwareProductStatusId),
- industry: industry
- );
+ industry: industry);
}
[Theory]
@@ -854,7 +868,7 @@ public async Task ACX20_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotMod
}.GetAsync();
// Arrange - Get brands and save the ETag
- var expectedETag = (await new Infrastructure.API
+ var expectedETag = (await new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -862,11 +876,11 @@ public async Task ACX20_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotMod
URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
AccessToken = accessToken,
XV = "2",
- IfNoneMatch = null, // ie If-None-Match is not set
+ IfNoneMatch = null, // ie If-None-Match is not set
}.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
// Act - Use Etag
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -899,7 +913,7 @@ public async Task ACX01_Get_WithInvalidIndustry_ShouldRespondWith_400BadRequest(
CertificatePassword = CERTIFICATE_PASSWORD
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -921,10 +935,10 @@ public async Task ACX01_Get_WithInvalidIndustry_ShouldRespondWith_400BadRequest(
// Assert - Check error response
if (response.StatusCode != HttpStatusCode.OK)
{
- // Assert - Check content type
+ // Assert - Check content type
Assert_HasContentType_ApplicationJson(response.Content);
- // Assert - Check error response
+ // Assert - Check error response
var expectedContent = @"
{
""errors"": [
@@ -955,7 +969,7 @@ public async Task ACX02_Get_WithScope_ShouldRespondWith_200OK(string? industry,
Scope = scope
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -977,36 +991,36 @@ public async Task ACX02_Get_WithScope_ShouldRespondWith_200OK(string? industry,
}
[Theory]
- [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported and higher than x-min-v
- [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
- [InlineData("2", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is supported but x-min-v (not a positive integer)
- [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v (not a positive integer)
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. Both x-v and x-min-v exceed supported version of 2
- [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is invalid with valid x-min-v
- [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is higher than supported version of 2
- [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is an empty string
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is missing
- //Also check industry specific calls
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "banking")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "energy")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "telco")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] //Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "energy")] //Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "telco")] //Unsupported. x-v is not supported and x-min-v invalid
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "banking")] //Invalid. x-v header is missing
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "energy")] //Invalid. x-v header is missing
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "telco")] //Invalid. x-v header is missing
+ [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("2", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v (not a positive integer)
+ [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v (not a positive integer)
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+
+ // Also check industry specific calls
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "banking")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "energy")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "telco")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "energy")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "telco")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "banking")] // Invalid. x-v header is missing
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "energy")] // Invalid. x-v header is missing
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "telco")] // Invalid. x-v header is missing
public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "all")
{
-
// Arrange
var accessToken = await new Infrastructure.AccessToken
{
@@ -1014,7 +1028,7 @@ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string
CertificatePassword = CERTIFICATE_PASSWORD,
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -1047,7 +1061,6 @@ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string
// Assert - Check error response
await Assert_HasContent_Json(expecetdError, response.Content);
}
-
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
index 0c17663..4e61bc1 100644
--- a/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
@@ -1,5 +1,4 @@
-using CDR.Register.Domain.Entities;
-using CDR.Register.IntegrationTests.Extensions;
+using CDR.Register.IntegrationTests.Extensions;
using CDR.Register.Repository.Infrastructure;
using FluentAssertions;
using FluentAssertions.Execution;
@@ -14,7 +13,6 @@
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
-using static System.Net.WebRequestMethods;
#nullable enable
@@ -22,25 +20,66 @@ namespace CDR.Register.IntegrationTests.API.SSA
{
///
/// Integration tests for GetSoftwareStatementAssertion.
- ///
+ ///
public class US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests : BaseTest
{
- public US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
// Participation/Brand/SoftwareProduct Ids
- private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup
+ private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup.
+
private const string BRANDID = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
private const string SOFTWAREPRODUCTID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
- enum AccessTokenType
+ private enum AccessTokenType
{
ValidAccessToken, // Get and send valid access token
InvalidAccessToken, // Send an invalid access token
ExpiredAccessToken, // Send expired access token
NoAccessToken, // Don't send any access token
- };
- delegate void BeforeSSARequest();
- delegate void AfterSSARequest();
+ }
+
+ private delegate void BeforeSSARequest();
+
+ private delegate void AfterSSARequest();
+
+ private static async Task GetAccessToken(
+ AccessTokenType accessTokenType,
+ string? getAccessTokenCertificateFilename,
+ string? getAccessTokenCertificatePassword,
+ string certificateFilename,
+ string certificatePassword)
+ {
+ // Access token
+ switch (accessTokenType)
+ {
+ case AccessTokenType.ValidAccessToken:
+ // Get the access token with the valid certificate.
+ return await new Infrastructure.AccessToken
+ {
+ CertificateFilename = getAccessTokenCertificateFilename ?? certificateFilename,
+ CertificatePassword = getAccessTokenCertificatePassword ?? certificatePassword
+ }.GetAsync();
+
+ case AccessTokenType.InvalidAccessToken:
+ return "foo";
+
+ case AccessTokenType.ExpiredAccessToken:
+ // Represents an expired access token.
+ // "exp": 1621344825
+ // Expired at "Tuesday, May 18, 2021 11:33:45 PM GMT+10:00"
+ return "eyJhbGciOiJQUzI1NiIsImtpZCI6IkFBMjRGMTg1RUUzRjY3NTA0ODA4RkM0RTI2QjEzNUI5OUU2M0JEQTkiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJxaVR4aGU0X1oxQklDUHhPSnJFMXVaNWp2YWsifQ.eyJuYmYiOjE2MjEzNDQ1MjUsImV4cCI6MTYyMTM0NDgyNSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzAwMC9pZHAiLCJhdWQiOiJjZHItcmVnaXN0ZXIiLCJjbGllbnRfaWQiOiI2ZjdhMWI4ZS04Nzk5LTQ4YTgtOTAxMS1lMzkyMDM5MWY3MTMiLCJqdGkiOiJDODRBNTM5MTA2QjI4NUJBODI2RjZGMDQ3MjU4RjBBNCIsImlhdCI6MTYyMTM0NDUyNSwic2NvcGUiOlsiY2RyLXJlZ2lzdGVyOmJhbms6cmVhZCJdLCJjbmYiOnsieDV0I1MyNTYiOiI1OEQ3NkY3QTYxQ0Q3MjZEQTFDNTRGNjg5OEU4RTY5RUE0Qzg4MDYwIn19.RTU-zrqkb-WXcJzCz62SJ4h19lj8MDyGcvLOmg0qx05WFbAsY4mEP3gsoqM1LJfq4ncw7RqSvbkCNQQ-NOnyoBHF8MGe7mzdUh3YrD0_lTg20Dkx1-l044svtP_CKTI3rXT3bZaYWce0Tb1s3mrJzfN3ja23o93FGR-wbIwHp2347b0DxjznpKBw5meLhAjS7OCx6_uMm1la6IziSQgqMd2WaA-od7w8J5br-Nn-QZZi7X1KGiPEKFDFNk8KrUdPc4NCH6t7f-Sbc34KNNEWfAOJkWdDrmsBaifSlWvSlS4nUnurGHYkmimA2JUuv3ZTqzCcLRamEER1ZoTcIs_PDw";
+
+ case AccessTokenType.NoAccessToken:
+ return null;
+
+ default:
+ throw new NotSupportedException();
+ }
+ }
private static async Task Test_GetSSA(
string certificateFilename,
@@ -59,47 +98,22 @@ private static async Task Test_GetSSA(
string brandId = BRANDID,
string softwareProductId = SOFTWAREPRODUCTID)
{
- async Task GetAccessToken()
- {
- // Access token
- switch (accessTokenType)
- {
- case AccessTokenType.ValidAccessToken:
- // Get the access token with the valid certificate.
- return await new Infrastructure.AccessToken
- {
- CertificateFilename = getAccessTokenCertificateFilename ?? certificateFilename,
- CertificatePassword = getAccessTokenCertificatePassword ?? certificatePassword
- }.GetAsync();
-
- case AccessTokenType.InvalidAccessToken:
- return "foo";
-
- case AccessTokenType.ExpiredAccessToken:
- // Represents an expired access token.
- // "exp": 1621344825
- // Expired at "Tuesday, May 18, 2021 11:33:45 PM GMT+10:00"
- return "eyJhbGciOiJQUzI1NiIsImtpZCI6IkFBMjRGMTg1RUUzRjY3NTA0ODA4RkM0RTI2QjEzNUI5OUU2M0JEQTkiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJxaVR4aGU0X1oxQklDUHhPSnJFMXVaNWp2YWsifQ.eyJuYmYiOjE2MjEzNDQ1MjUsImV4cCI6MTYyMTM0NDgyNSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzAwMC9pZHAiLCJhdWQiOiJjZHItcmVnaXN0ZXIiLCJjbGllbnRfaWQiOiI2ZjdhMWI4ZS04Nzk5LTQ4YTgtOTAxMS1lMzkyMDM5MWY3MTMiLCJqdGkiOiJDODRBNTM5MTA2QjI4NUJBODI2RjZGMDQ3MjU4RjBBNCIsImlhdCI6MTYyMTM0NDUyNSwic2NvcGUiOlsiY2RyLXJlZ2lzdGVyOmJhbms6cmVhZCJdLCJjbmYiOnsieDV0I1MyNTYiOiI1OEQ3NkY3QTYxQ0Q3MjZEQTFDNTRGNjg5OEU4RTY5RUE0Qzg4MDYwIn19.RTU-zrqkb-WXcJzCz62SJ4h19lj8MDyGcvLOmg0qx05WFbAsY4mEP3gsoqM1LJfq4ncw7RqSvbkCNQQ-NOnyoBHF8MGe7mzdUh3YrD0_lTg20Dkx1-l044svtP_CKTI3rXT3bZaYWce0Tb1s3mrJzfN3ja23o93FGR-wbIwHp2347b0DxjznpKBw5meLhAjS7OCx6_uMm1la6IziSQgqMd2WaA-od7w8J5br-Nn-QZZi7X1KGiPEKFDFNk8KrUdPc4NCH6t7f-Sbc34KNNEWfAOJkWdDrmsBaifSlWvSlS4nUnurGHYkmimA2JUuv3ZTqzCcLRamEER1ZoTcIs_PDw";
-
- case AccessTokenType.NoAccessToken:
- return null;
-
- default:
- throw new NotSupportedException();
- }
- }
-
// Arrange
- string URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{brandId}/software-products/{softwareProductId}/ssa";
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{brandId}/software-products/{softwareProductId}/ssa";
- var accessToken = await GetAccessToken();
+ var accessToken = await GetAccessToken(
+ accessTokenType,
+ getAccessTokenCertificateFilename,
+ getAccessTokenCertificatePassword,
+ certificateFilename,
+ certificatePassword);
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = certificateFilename,
CertificatePassword = certificatePassword,
HttpMethod = HttpMethod.Get,
- URL = URL,
+ URL = url,
AccessToken = accessToken,
XV = x_v,
XMinV = x_min_v
@@ -138,14 +152,14 @@ private static async Task Test_GetSSA(
[Theory]
[InlineData(3)]
- public async Task AC01_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int XV)
+ public async Task AC01_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int xv)
{
// Arrange - Get SoftwareProduct
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
- var softwareProduct = dbContext.SoftwareProducts.AsNoTracking()
+ var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
.Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
- .Single();
+ .SingleAsync();
// Arrange - Get access token
var accessToken = await new Infrastructure.AccessToken
@@ -155,18 +169,17 @@ public async Task AC01_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int XV)
}.GetAsync();
// Act - Send request to SSA API
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
HttpMethod = HttpMethod.Get,
URL = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa",
- XV = XV.ToString(),
+ XV = xv.ToString(),
AccessToken = accessToken
}.SendAsync();
- await AssertSsa(response, softwareProduct, XV);
-
+ await AssertSsa(response, softwareProduct, xv);
}
[Theory]
@@ -178,10 +191,10 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
{
// Arrange - Get SoftwareProduct
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
- var softwareProduct = dbContext.SoftwareProducts.AsNoTracking()
+ var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
.Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
- .Single();
+ .SingleAsync();
// Arrange - Get access token
var accessToken = await new Infrastructure.AccessToken
@@ -191,7 +204,7 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
}.GetAsync();
// Act - Send request to SSA API
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -202,10 +215,9 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
}.SendAsync();
await AssertSsa(response, softwareProduct, 3);
-
}
- const string EXPECTEDCONTENT_ADRSTATUSNOTACTIVE = @"
+ private const string EXPECTEDCONTENT_ADRSTATUSNOTACTIVE = @"
{
""errors"": [
{
@@ -218,11 +230,11 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
- [InlineData(2, HttpStatusCode.Forbidden)] // Removed
- [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
+ [InlineData(2, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
[InlineData(5, HttpStatusCode.Forbidden)] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
+ [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
public async Task AC03_GetSSA_WithParticipationStatusNotActive_ShouldRespondWith_403Forbidden(
int participationStatusId,
HttpStatusCode expectedStatusCode)
@@ -235,14 +247,13 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetParticipationStatusId(PARTICIPATIONID, participationStatusId),
afterRequest: () => SetParticipationStatusId(PARTICIPATIONID, saveParticipationStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
[InlineData(2, HttpStatusCode.Forbidden)] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
public async Task AC04_GetSSA_WithBrandNotActive_ShouldRespondWith_403Forbidden(
int brandStatusId,
HttpStatusCode expectedStatusCode)
@@ -255,14 +266,13 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetBrandStatusId(BRANDID, brandStatusId),
afterRequest: () => SetBrandStatusId(BRANDID, saveBrandStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
[InlineData(2, HttpStatusCode.Forbidden)] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
public async Task AC05_GetSSA_WithSoftwareProductNotActive_ShouldRespondWith_403Forbidden(
int softwareProductStatusId,
HttpStatusCode expectedStatusCode)
@@ -275,8 +285,7 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, softwareProductStatusId),
afterRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, saveSoftwareProductStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
@@ -323,19 +332,18 @@ await Test_GetSSA(
ADDITIONAL_CERTIFICATE_PASSWORD,
HttpStatusCode.Unauthorized,
getAccessTokenCertificateFilename: CERTIFICATE_FILENAME,
- getAccessTokenCertificatePassword: CERTIFICATE_PASSWORD
- );
+ getAccessTokenCertificatePassword: CERTIFICATE_PASSWORD);
}
[Theory]
[InlineData("3", "foo")]
- public async Task AC11_GetSSA_InvalidSoftwareProductId_ShouldRespondWith_404NotFound(string XV, string softwareProductId)
+ public async Task AC11_GetSSA_InvalidSoftwareProductId_ShouldRespondWith_404NotFound(string xv, string softwareProductId)
{
await Test_GetSSA(
CERTIFICATE_FILENAME,
CERTIFICATE_PASSWORD,
HttpStatusCode.NotFound,
- x_v: XV,
+ x_v: xv,
softwareProductId: softwareProductId,
expectedContent: $@"
{{
@@ -368,8 +376,7 @@ await Test_GetSSA(
CERTIFICATE_FILENAME,
CERTIFICATE_PASSWORD,
HttpStatusCode.NotFound,
- brandId: Guid.NewGuid().ToString()
- );
+ brandId: Guid.NewGuid().ToString());
}
private static async Task GetSsaJwks()
@@ -380,32 +387,31 @@ private static async Task GetSsaJwks()
var jwksClient = new HttpClient(clientHandler);
var jwksResponse = await jwksClient.GetAsync($"{TLS_BaseURL}/cdr-register/v1/jwks");
return new JsonWebKeySet(await jwksResponse.Content.ReadAsStringAsync());
- }
+ }
[Theory]
- [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-min-v is ignored when > x-v
- [InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is supported and higher than x-min-v
- [InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is supported equal to x-min-v
- [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] //Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
- [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v invalid
- [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. Both x-v and x-min-v exceed supported version of 3
- [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is invalid with valid x-min-v
- [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is higher than supported version of 3
- [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is an empty string
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is missing
+ [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
+ [InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported equal to x-min-v
+ [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
public async Task ACX01_VersionHeaderValidation(string? xv, string? xminv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
{
-
// Arrange
- string URL = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
var accessToken = await new Infrastructure.AccessToken
{
@@ -413,18 +419,17 @@ public async Task ACX01_VersionHeaderValidation(string? xv, string? xminv, strin
CertificatePassword = CERTIFICATE_PASSWORD,
}.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
HttpMethod = HttpMethod.Get,
- URL = URL,
+ URL = url,
AccessToken = accessToken,
XV = xv,
XMinV = xminv
};
-
// Act
var response = await api.SendAsync();
@@ -443,27 +448,25 @@ public async Task ACX01_VersionHeaderValidation(string? xv, string? xminv, strin
{
// Assert - Check error response
await Assert_HasContent_Json(expecetdError, response.Content);
-
}
}
-
}
+
[Trait("Category", "CTSONLY")]
[Theory]
[InlineData(3)]
- public async Task AC01_CTS_URL_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int XV)
+ public async Task AC01_CTS_URL_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int xv)
{
string conformanceId = Guid.NewGuid().ToString();
- // conformanceId = "5186c407-0114-480a-86a3-7ef072d221bc";
string tokenEndpoint = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL, conformanceId)}/idp/connect/token";
string ssasEndpoint = $"{GenerateDynamicCtsUrl(SSA_DOWNSTREAM_BASE_URL, conformanceId)}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
// Arrange - Get SoftwareProduct
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
- Repository.Entities.SoftwareProduct softwareProduct = dbContext.SoftwareProducts.AsNoTracking()
+ Repository.Entities.SoftwareProduct softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
.Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
- .Single();
+ .SingleAsync();
// Arrange - Get access token
var accessToken = await new Infrastructure.AccessToken
@@ -478,20 +481,20 @@ public async Task AC01_CTS_URL_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(in
}.GetAsync(addCertificateToRequest: false);
// Act - Send request to SSA API
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = ssasEndpoint,
- XV = XV.ToString(),
+ XV = xv.ToString(),
AccessToken = accessToken,
CertificateThumbprint = DEFAULT_CERTIFICATE_THUMBPRINT,
CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME
}.SendAsync();
- await AssertSsa(response, softwareProduct, XV);
+ await AssertSsa(response, softwareProduct, xv);
}
- private static async Task AssertSsa(HttpResponseMessage response, Repository.Entities.SoftwareProduct softwareProduct, int XV)
+ private static async Task AssertSsa(HttpResponseMessage response, Repository.Entities.SoftwareProduct softwareProduct, int xv)
{
// Assert
using (new AssertionScope())
@@ -505,44 +508,44 @@ private static async Task AssertSsa(HttpResponseMessage response, Repository.Ent
var ssaJwks = await GetSsaJwks();
// Assert - Check XV
- Assert_HasHeader(XV.ToString(), response.Headers, "x-v");
+ Assert_HasHeader(xv.ToString(), response.Headers, "x-v");
// Assert - SSA
- var SSA = new JwtSecurityTokenHandler().ReadJwtToken(await response.Content.ReadAsStringAsync());
+ var ssa = new JwtSecurityTokenHandler().ReadJwtToken(await response.Content.ReadAsStringAsync());
// Assert - SSA Header
- SSA.Header.Alg.Should().Be("PS256");
- SSA.Header.Kid.Should().Be(ssaJwks.Keys.First().Kid);
- SSA.Header.Typ.Should().Be("JWT");
+ ssa.Header.Alg.Should().Be("PS256");
+ ssa.Header.Kid.Should().Be(ssaJwks.Keys[0].Kid);
+ ssa.Header.Typ.Should().Be("JWT");
// Assert - SSA Claims
- SSA.AssertClaim("iss", "cdr-register");
+ ssa.AssertClaim("iss", "cdr-register");
- SSA.AssertClaim("iat", null);
- SSA.AssertClaim("exp", null);
- long iat = Convert.ToInt64(SSA.Claim("iat").Value);
- long exp = Convert.ToInt64(SSA.Claim("exp").Value);
+ ssa.AssertClaim("iat", null);
+ ssa.AssertClaim("exp", null);
+ long iat = Convert.ToInt64(ssa.Claim("iat").Value);
+ long exp = Convert.ToInt64(ssa.Claim("exp").Value);
exp.Should().Be(iat + 600); // Check expiry is 10 minutes (ie 600 seconds)
- SSA.AssertClaim("jti", null);
- SSA.AssertClaim("org_id", softwareProduct.Brand.BrandId.ToString());
- SSA.AssertClaim("org_name", softwareProduct.Brand.BrandName);
- SSA.AssertClaim("client_name", softwareProduct.SoftwareProductName);
- SSA.AssertClaim("client_description", softwareProduct.SoftwareProductDescription);
- SSA.AssertClaim("client_uri", softwareProduct.ClientUri);
- SSA.AssertClaimIsArray("redirect_uris", softwareProduct.RedirectUris.Split(" "));
- SSA.AssertClaim("logo_uri", softwareProduct.LogoUri);
- SSA.AssertClaim("tos_uri", softwareProduct.TosUri, true);
- SSA.AssertClaim("policy_uri", softwareProduct.PolicyUri, true);
- SSA.AssertClaim("jwks_uri", softwareProduct.JwksUri);
- SSA.AssertClaim("revocation_uri", softwareProduct.RevocationUri);
- SSA.AssertClaim("software_id", softwareProduct.SoftwareProductId.ToString());
- SSA.AssertClaim("software_roles", "data-recipient-software-product");
- SSA.AssertClaim("scope", softwareProduct.Scope);
-
- if (XV >= 2)
+ ssa.AssertClaim("jti", null);
+ ssa.AssertClaim("org_id", softwareProduct.Brand.BrandId.ToString());
+ ssa.AssertClaim("org_name", softwareProduct.Brand.BrandName);
+ ssa.AssertClaim("client_name", softwareProduct.SoftwareProductName);
+ ssa.AssertClaim("client_description", softwareProduct.SoftwareProductDescription);
+ ssa.AssertClaim("client_uri", softwareProduct.ClientUri);
+ ssa.AssertClaimIsArray("redirect_uris", softwareProduct.RedirectUris.Split(" "));
+ ssa.AssertClaim("logo_uri", softwareProduct.LogoUri);
+ ssa.AssertClaim("tos_uri", softwareProduct.TosUri, true);
+ ssa.AssertClaim("policy_uri", softwareProduct.PolicyUri, true);
+ ssa.AssertClaim("jwks_uri", softwareProduct.JwksUri);
+ ssa.AssertClaim("revocation_uri", softwareProduct.RevocationUri);
+ ssa.AssertClaim("software_id", softwareProduct.SoftwareProductId.ToString());
+ ssa.AssertClaim("software_roles", "data-recipient-software-product");
+ ssa.AssertClaim("scope", softwareProduct.Scope);
+
+ if (xv >= 2)
{
- SSA.AssertClaim("recipient_base_uri", softwareProduct.RecipientBaseUri);
+ ssa.AssertClaim("recipient_base_uri", softwareProduct.RecipientBaseUri);
}
// Assert - Validate SSA Signature
@@ -553,7 +556,7 @@ private static async Task AssertSsa(HttpResponseMessage response, Repository.Ent
RequireSignedTokens = true,
ValidateIssuerSigningKey = true,
- IssuerSigningKey = ssaJwks.Keys.First(),
+ IssuerSigningKey = ssaJwks.Keys[0],
ValidateIssuer = true,
ValidIssuer = "cdr-register",
@@ -562,7 +565,7 @@ private static async Task AssertSsa(HttpResponseMessage response, Repository.Ent
};
// Validate token (throws exception if token fails to validate)
- new JwtSecurityTokenHandler().ValidateToken(SSA.RawData, validationParameters, out var validatedToken);
+ new JwtSecurityTokenHandler().ValidateToken(ssa.RawData, validationParameters, out _);
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
index 170cf5b..87ad299 100644
--- a/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
@@ -18,11 +18,15 @@
namespace CDR.Register.IntegrationTests.API.Status
{
///
- /// Integration tests for GetDataRecipientStatus V2 endpoints
+ /// Integration tests for GetDataRecipientStatus V2 endpoints.
///
public class US27556_GetDataRecipientStatus_MultiIndustry_Tests : BaseTest
{
- public US27556_GetDataRecipientStatus_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US27556_GetDataRecipientStatus_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
private static string GetExpectedDataRecipientsStatus(string url)
{
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
@@ -51,18 +55,18 @@ private static string GetExpectedDataRecipientsStatus(string url)
[Theory]
[InlineData("2", "2")]
- public async Task AC01_AC02_Get_ShouldRespondWith_200OK_DataRecipientsStatus(string? XV, string expectedXV)
+ public async Task AC01_AC02_Get_ShouldRespondWith_200OK_DataRecipientsStatus(string? xv, string expectedXV)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/status";
var expectedDataRecipientStatus = GetExpectedDataRecipientsStatus(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV
+ XV = xv
}.SendAsync();
// Assert
@@ -85,15 +89,15 @@ public async Task AC01_AC02_Get_ShouldRespondWith_200OK_DataRecipientsStatus(str
[Trait("Category", "CTSONLY")]
[Theory]
[InlineData("2", "2")]
- public async Task AC01_AC02_CTS_URL_Get_ShouldRespondWith_200OK_DataRecipientsStatus(string? XV, string expectedXV)
+ public async Task AC01_AC02_CTS_URL_Get_ShouldRespondWith_200OK_DataRecipientsStatus(string? xv, string expectedXV)
{
- // Arrange
+ // Arrange
var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/all/data-recipients/status";
- string publicHostName = Configuration["PublicHostName"] ?? "";
- string expectedUrl = ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL);
+ string publicHostName = Configuration["PublicHostName"] ?? string.Empty;
+ string expectedUrl;
- if (String.IsNullOrEmpty(publicHostName))
+ if (string.IsNullOrEmpty(publicHostName))
{
expectedUrl = url;
}
@@ -101,14 +105,15 @@ public async Task AC01_AC02_CTS_URL_Get_ShouldRespondWith_200OK_DataRecipientsSt
{
expectedUrl = url.Replace(STATUS_DOWNSTREAM_BASE_URL, publicHostName);
}
+
var expectedDataRecipientStatus = GetExpectedDataRecipientsStatus(expectedUrl);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV
+ XV = xv
}.SendAsync();
// Assert
@@ -133,12 +138,12 @@ public async Task AC01_AC02_CTS_URL_Get_ShouldRespondWith_200OK_DataRecipientsSt
[InlineData("foo")] // AC06
public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/status";
var expectedDataRecipientsStatus = GetExpectedDataRecipientsStatus(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
@@ -170,16 +175,16 @@ public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(str
public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
{
// Arrange - Get SoftwareProductsStatus and save the ETag
- var expectedETag = (await new Infrastructure.API
+ var expectedETag = (await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/status",
XV = "2",
- IfNoneMatch = null, // ie If-None-Match is not set
+ IfNoneMatch = null, // ie If-None-Match is not set
}.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/status",
@@ -199,28 +204,27 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
}
[Theory]
- [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported and higher than x-min-v
- [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
- [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
- [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. Both x-v and x-min-v exceed supported version of 2
- [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is invalid with valid x-min-v
- [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is higher than supported version of 2
- [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is an empty string
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is missing
+ [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
{
-
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/banking/data-recipients/status",
@@ -247,7 +251,6 @@ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string
// Assert - Check error response
await Assert_HasContent_Json(expecetdError, response.Content);
}
-
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
index 00257d0..d6d51ff 100644
--- a/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
@@ -16,11 +16,15 @@
namespace CDR.Register.IntegrationTests.API.Status
{
///
- /// Integration tests for GetSoftwareProductStatus v2 endpoints
- ///
+ /// Integration tests for GetSoftwareProductStatus v2 endpoints.
+ ///
public class US27558_GetSoftwareProductStatus_MultiIndustry_Tests : BaseTest
{
- public US27558_GetSoftwareProductStatus_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US27558_GetSoftwareProductStatus_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
private static string GetExpectedSoftwareProductStatus(string url)
{
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
@@ -36,7 +40,8 @@ private static string GetExpectedSoftwareProductStatus(string url)
})
.OrderBy(sp => sp.softwareProductId.ToString())
.ToList(),
- links = new {
+ links = new
+ {
self = url
},
meta = new object()
@@ -47,18 +52,18 @@ private static string GetExpectedSoftwareProductStatus(string url)
[Theory]
[InlineData("2", "2")]
- public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_SoftwareProducts(string? XV, string expectedXV)
+ public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_SoftwareProducts(string? xv, string expectedXV)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/software-products/status";
var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV
+ XV = xv
}.SendAsync();
// Assert
@@ -81,18 +86,18 @@ public async Task AC01_Get_WithXV_ShouldRespondWith_200OK_SoftwareProducts(strin
[Trait("Category", "CTSONLY")]
[Theory]
[InlineData("2", "2")]
- public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_SoftwareProducts(string? XV, string expectedXV)
+ public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_SoftwareProducts(string? xv, string expectedXV)
{
- // Arrange
+ // Arrange
var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/all/data-recipients/brands/software-products/status";
var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL));
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
- XV = XV
+ XV = xv
}.SendAsync();
// Assert
@@ -117,12 +122,12 @@ public async Task AC01_CTS_URL_Get_WithXV_ShouldRespondWith_200OK_SoftwareProduc
[InlineData("foo")] // AC06
public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
{
- // Arrange
+ // Arrange
var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/software-products/status";
var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(url);
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = url,
@@ -154,16 +159,16 @@ public async Task AC04_AC06_Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(str
public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
{
// Arrange - Get SoftwareProductsStatus and save the ETag
- var expectedETag = (await new Infrastructure.API
+ var expectedETag = (await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/software-products/status",
XV = "2",
- IfNoneMatch = null, // ie If-None-Match is not set
+ IfNoneMatch = null, // ie If-None-Match is not set
}.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/software-products/status",
@@ -183,28 +188,27 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
}
[Theory]
- [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported and higher than x-min-v
- [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] //Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
- [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
- [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. Both x-v and x-min-v exceed supported version of 2
- [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is an obsolete version
- [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (not a positive integer) is invalid with missing x-min-v
- [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v is invalid with valid x-min-v
- [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] //Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] //Unsupported. x-v is higher than supported version of 2
- [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is an empty string
- [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] //Invalid. x-v header is missing
+ [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
{
-
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{TLS_BaseURL}/cdr-register/v1/banking/data-recipients/brands/software-products/status",
@@ -231,7 +235,6 @@ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string
// Assert - Check error response
await Assert_HasContent_Json(expecetdError, response.Content);
}
-
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Update/ExpectedErrors.cs b/Source/CDR.Register.IntegrationTests/API/Update/ExpectedErrors.cs
index 5cee650..3915cef 100644
--- a/Source/CDR.Register.IntegrationTests/API/Update/ExpectedErrors.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Update/ExpectedErrors.cs
@@ -1,11 +1,11 @@
using CDR.Register.IntegrationTests.Models;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CDR.Register.IntegrationTests.API.Update
{
- //TODO: Work out why this class exists and errors are defined in multiple places in IntTests project
public class ExpectedErrors
{
public enum ErrorType
@@ -17,10 +17,15 @@ public enum ErrorType
UnsupportedVersion,
Unauthorized
}
- private List _expectedErrors;
+
private const string CDS_ERROR_PREFIX = "urn:au-cds:error:cds-all:";
+ private readonly List _expectedErrors;
- public List errors { get => _expectedErrors.ToList(); }
+ ///
+ /// This is used in serialised JSON to compare against the actual JSON. Do not remove.
+ ///
+ [JsonProperty(PropertyName = "errors")]
+ public List Errors { get => _expectedErrors.ToList(); }
public ExpectedErrors()
{
@@ -84,7 +89,5 @@ public void AddExpectedError(ErrorType errorType, string detail)
throw new NotSupportedException($"{nameof(ErrorType)}={errorType}");
}
}
-
}
-
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
index 3116608..b915ec7 100644
--- a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
@@ -23,7 +23,10 @@ namespace CDR.Register.IntegrationTests.API.Update
{
public class US50480_UpdateDataHolders : BaseTest
{
- public US50480_UpdateDataHolders(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US50480_UpdateDataHolders(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
private const string UPDATE_DATA_HOLDER_CURRENT_API_VERSION = "1";
@@ -51,7 +54,6 @@ public async Task AC02_Add_New_DataHolder_With_Only_Mandatory_Fields_Http_200(In
// Assert participation created correctly
VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", industry.ToString(), dataHolderMetadata.Status);
-
}
[Theory]
@@ -69,7 +71,6 @@ public async Task AC02_Add_New_DataHolder_With_All_Fields_Fields_Http_200(Indust
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, response, industry);
VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", industry.ToString(), dataHolderMetadata.Status);
-
}
[Fact]
@@ -97,17 +98,16 @@ public async Task AC03_Modify_Existing_DataHolder_200()
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, modifiedResponse, Industry.Banking);
VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString(), dataHolderMetadata.Status);
-
}
[Fact]
public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
{
-
// Generate valid payload.
DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+
// Send to Register
- HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
+ await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
// Send Original request to Register
HttpResponseMessage originalResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
@@ -118,10 +118,10 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
// Generate valid payload.
DataHolderMetadata newDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
- //Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity
+ // Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity
newDataHolderMetadata.LegalEntity.LegalEntityId = originalDataHolderMetadata.LegalEntity.LegalEntityId;
- //Also modify other fields
+ // Also modify other fields
newDataHolderMetadata.BrandName = "Test Automation Modified Brand Name";
newDataHolderMetadata.EndpointDetail.PublicBaseUri = $"{TEST_DATA_BASE_URI}/ModifiedPublicBaseUri";
newDataHolderMetadata.AuthDetails.JwksEndpoint = $"{TEST_DATA_BASE_URI}/ModifiedJwks";
@@ -132,19 +132,18 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
// Assert http response and database updates.
VerifySuccessfulDataHolderUpdate(newDataHolderMetadata, modifiedResponse, Industry.Banking);
- //Also Check Original is not affected
+ // Also Check Original is not affected
VerifySuccessfulDataHolderUpdate(originalDataHolderMetadata, originalResponse, Industry.Banking);
VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString(), newDataHolderMetadata.Status);
-
}
[Fact]
public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Industry_200()
{
-
// Generate valid Banking payload.
DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+
// Send to Register
_ = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
@@ -157,10 +156,10 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Ind
// Generate valid Energy payload.
DataHolderMetadata newDataHolderMetadata = CreateValidDataholderMetadata(Industry.Energy, true);
- //Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity, and create a new participation record.
+ // Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity, and create a new participation record.
newDataHolderMetadata.LegalEntity.LegalEntityId = originalDataHolderMetadata.LegalEntity.LegalEntityId;
- //Also modify other fields
+ // Also modify other fields
newDataHolderMetadata.BrandName = "Test Automation Energy Brand Name";
newDataHolderMetadata.EndpointDetail.PublicBaseUri = $"{TEST_DATA_BASE_URI}/EnergyPublicBaseUri";
newDataHolderMetadata.AuthDetails.JwksEndpoint = $"{TEST_DATA_BASE_URI}/EnergyJwks";
@@ -176,7 +175,6 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Ind
// Verify Energy(subsequent) Participant
VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Energy.ToString(), newDataHolderMetadata.Status);
-
}
[Theory]
@@ -190,7 +188,7 @@ public async Task AC04_Missing_Version_In_Header_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingHeader, "An API version x-v header is required, but was not specified.");
// Assert Response
@@ -207,14 +205,13 @@ public async Task AC05_Invalid_Version_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.InvalidVersion, "Version is not a positive Integer.");
// Assert Response
await VerifyBadRequest(expectedErrors, response);
}
-
[Theory]
[InlineData("20")]
public async Task AC10_Unsupported_Version_Http_400(string xv)
@@ -224,7 +221,7 @@ public async Task AC10_Unsupported_Version_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.UnsupportedVersion, "Requested version is lower than the minimum version or greater than maximum version.");
// Assert Response
@@ -288,7 +285,8 @@ public async Task AC06_Missing_Mandatory_Fields_Http_400(string testId, string e
[InlineData("Max Length EndPoint - ExtensionBaseUri", "endpointDetail.extensionBaseUri", 1000)]
[InlineData("Max Length EndPoint - WebsiteUri", "endpointDetail.websiteUri", 1000)]
[InlineData("Max Length Legal Entity - Name", "legalEntity.legalEntityName", 200)]
- //we don't check accredatation number for DHs as they don't have it.
+
+ // we don't check accredatation number for DHs as they don't have it.
[InlineData("Max Length Legal Entity - logoUri", "legalEntity.logoUri", 1000)]
[InlineData("Max Length Legal Entity - Registration Number", "legalEntity.registrationNumber", 100)]
[InlineData("Max Length Legal Entity - Registered Country", "legalEntity.registeredCountry", 100)]
@@ -312,14 +310,13 @@ public async Task ACXX_Maximum_Field_Length_Exceeded(string testId, string eleme
await VerifyInvalidAndValidFieldResponse(response, dataHolderMetadata, ConvertJsonPathToPascalCase(elementUnderTest), maxLengthValue, true);
// Create dataHolder using maximum field lenght plus one
- string maxLengthPlusOneValue = (maxLength+1).GenerateRandomString();
+ string maxLengthPlusOneValue = (maxLength + 1).GenerateRandomString();
dataHolderMetadata = ReplaceModelValueBasedOnJsonPath(dataHolderMetadata, elementUnderTest, maxLengthPlusOneValue);
Log.Information($"-ve:\n{GetJsonFromModel(dataHolderMetadata)}");
// Send and verify negative scenario
HttpResponseMessage responseNegative = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
await VerifyInvalidAndValidFieldResponse(responseNegative, dataHolderMetadata, ConvertJsonPathToPascalCase(elementUnderTest), maxLengthPlusOneValue, false);
-
}
[Theory]
@@ -343,22 +340,18 @@ public async Task AC07_Valid_And_Invalid_Industry(string industry, bool isValid
switch (industry.ToUpper())
{
-
case "ENERGY":
industryEnum = Industry.Energy;
break;
- case "BANKING":
default:
industryEnum = Industry.Banking;
break;
-
}
dataHolderMetadata.Industries = dataHolderMetadata.Industries.ConvertAll(x => x.ToUpper());
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "Industries[0]", industry, isValid, industryEnum);
-
}
[Theory]
@@ -381,7 +374,6 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Status(string status, bool
dataHolderMetadata.Status = status.ToUpper();
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "Status", status, isValid);
-
}
[Theory]
@@ -407,7 +399,6 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Organisation_T
dataHolderMetadata.LegalEntity.OrganisationType = orgType.ToUpper();
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "LegalEntity.OrganisationType", orgType, isValid);
-
}
[Theory]
@@ -430,7 +421,6 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Status(string
dataHolderMetadata.LegalEntity.Status = status.ToUpper();
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "LegalEntity.Status", status, isValid);
-
}
[Theory]
@@ -451,7 +441,6 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Auth_Details_RegisterUType(
Log.Information($"modified:\n{GetJsonFromModel(dataHolderMetadata)}");
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "AuthDetails.RegisterUType", registerUType, isValid);
-
}
[Fact]
@@ -493,7 +482,6 @@ public async Task AC09_Brand_Already_Associated_With_Same_Legal_Entity_And_Diffe
HttpResponseMessage modifiedResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
await VerifyInvalidPayloadResponse(modifiedResponse, $"Brand {dataHolderMetadata.DataHolderBrandId} is already associated with the same legal entity in a different industry.");
-
}
[Trait("Category", "CTSONLY")]
@@ -577,13 +565,10 @@ private static async Task PostUpdateDataHolderRequest(strin
Log.Information($"Response from admin/metadata/data-holders API: {httpResponse.StatusCode} \n{httpResponse.Content.ReadAsStringAsync().Result}");
return httpResponse;
-
}
private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage response, DataHolderMetadata dataHolderMetadata, string field, string value, bool isValid, Industry industry = Industry.Banking)
{
- // var response = await SendToStub(GetJsonFromModel(dataHolderMetadata), isValid ? "PASS" : "InvalidField");
-
if (isValid)
{
string actualDataHolder = GetActualDataHolderFromDatabase(dataHolderMetadata.LegalEntity.LegalEntityId, dataHolderMetadata.DataHolderBrandId, industry);
@@ -601,7 +586,6 @@ private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage
private static async Task VerifyInvalidPayloadResponse(HttpResponseMessage response, string expectedErrorMessage)
{
-
ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.InvalidField, expectedErrorMessage);
@@ -612,7 +596,7 @@ private static void VerifySuccessfulDataHolderUpdate(DataHolderMetadata expected
{
using (new AssertionScope())
{
- //Check status code
+ // Check status code
httpResponseFromRegister.StatusCode.Should().Be(HttpStatusCode.OK);
string actualDataHolder = GetActualDataHolderFromDatabase(expectedDataHolderMetadata.LegalEntity.LegalEntityId, expectedDataHolderMetadata.DataHolderBrandId, industry);
@@ -625,7 +609,6 @@ private static void VerifySuccessfulDataHolderUpdate(DataHolderMetadata expected
private static DataHolderMetadata CreateValidDataholderMetadata(Industry industry, bool includeOptionalFields = false)
{
-
DataHolderMetadata dataHolderMetadata = new DataHolderMetadata();
dataHolderMetadata.DataHolderBrandId = Guid.NewGuid().ToString();
dataHolderMetadata.BrandName = "Test Automation Brand Name";
@@ -667,15 +650,13 @@ private static DataHolderMetadata CreateValidDataholderMetadata(Industry industr
dataHolderMetadata.LegalEntity.AnzsicDivision = "Test Automation Anzsic Division";
dataHolderMetadata.LegalEntity.OrganisationType = "SOLE_TRADER";
dataHolderMetadata.EndpointDetail.ExtensionBaseUri = $"{TEST_DATA_BASE_URI}/extensionBaseUri";
- };
+ }
return dataHolderMetadata;
-
}
private static string GetActualDataHolderFromDatabase(string legalEntityId, string brandId, Industry industry)
{
-
var legalEntityIdGuid = Guid.Parse(legalEntityId);
try
@@ -725,7 +706,6 @@ private static string GetActualDataHolderFromDatabase(string legalEntityId, stri
infosecBaseUri = brand.Endpoint.InfosecBaseUri,
extensionBaseUri = brand.Endpoint.ExtensionBaseUri,
websiteUri = brand.Endpoint.WebsiteUri
-
},
authDetails = new
{
diff --git a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataRecipients.cs b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataRecipients.cs
index 1781b34..aec0c69 100644
--- a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataRecipients.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataRecipients.cs
@@ -1,5 +1,4 @@
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.IntegrationTests.Extensions;
+using CDR.Register.IntegrationTests.Extensions;
using CDR.Register.IntegrationTests.Models;
using CDR.Register.Repository.Infrastructure;
using FluentAssertions;
@@ -24,7 +23,10 @@ namespace CDR.Register.IntegrationTests.API.Update
{
public class US50480_UpdateDataRecipients : BaseTest
{
- public US50480_UpdateDataRecipients(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US50480_UpdateDataRecipients(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
private const string UPDATE_DATA_RECIPIENT_CURRENT_API_VERSION = "1";
private const string DEFAULT_SCOPES = "openid profile bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:payees:read bank:regular_payments:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.usage:read energy:electricity.der:read energy:accounts.basic:read energy:accounts.basic:read energy:accounts.detail:read " +
@@ -59,12 +61,12 @@ public async Task AC03_UpdateExistingLegalEntity_Http_200()
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
// Send to Register
- var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
+ await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- //Using the same Legal Entity, update some fields.
+ // Using the same Legal Entity, update some fields.
dataRecipientMetadata.LegalEntityName = "Updated Legal Entity Name";
- dataRecipientMetadata.DataRecipientBrands.First().BrandName = "Updated Brand Name";
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductName = "Updated Software Product Name";
+ dataRecipientMetadata.DataRecipientBrands[0].BrandName = "Updated Brand Name";
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductName = "Updated Software Product Name";
// Send Updated Data Recipient to Register
var updateResponse = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
@@ -110,20 +112,19 @@ public async Task AC05_Add_Brand_To_Existing_Legal_Entiry_Http_200()
// Send to Register
_ = await PostUpdateDataRecipientRequest(GetJsonFromModel(originalDataRecipient));
-
- //Using the same Legal Entity, Add
+ // Using the same Legal Entity, Add
DataRecipientMetadata newDataRecipientMetadata = GetCopyOfDataRecipient(originalDataRecipient);
- newDataRecipientMetadata.DataRecipientBrands.First().DataRecipientBrandId = Guid.NewGuid().ToString();
- newDataRecipientMetadata.DataRecipientBrands.First().BrandName = "Brand Name 2";
- newDataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductId = Guid.NewGuid().ToString();
- newDataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductName = "Software Product Name 2";
+ newDataRecipientMetadata.DataRecipientBrands[0].DataRecipientBrandId = Guid.NewGuid().ToString();
+ newDataRecipientMetadata.DataRecipientBrands[0].BrandName = "Brand Name 2";
+ newDataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductId = Guid.NewGuid().ToString();
+ newDataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductName = "Software Product Name 2";
// Send Updated Data Recipient to Register
var updateResponse = await PostUpdateDataRecipientRequest(GetJsonFromModel(newDataRecipientMetadata));
// Assert http response and database updates.
DataRecipientMetadata expectedDataRecipientMetadata = GetCopyOfDataRecipient(originalDataRecipient);
- expectedDataRecipientMetadata.DataRecipientBrands.Add(newDataRecipientMetadata.DataRecipientBrands.First());
+ expectedDataRecipientMetadata.DataRecipientBrands.Add(newDataRecipientMetadata.DataRecipientBrands[0]);
VerifySuccessfulDataRecipientUpdate(expectedDataRecipientMetadata, updateResponse);
// Assert Participation Record created correctly
@@ -136,8 +137,8 @@ public async Task AC08_Add_Multiple_Duplicate_Certificates()
// Generate valid payload without a Software Product
DataRecipientMetadata dataRecipient = GenerateValidDataRecipient(false);
- //Add Duplicate Cert
- dataRecipient.DataRecipientBrands.First().SoftwareProducts.First().Certificates.Add(new DataRecipientMetadata.Certificate()
+ // Add Duplicate Cert
+ dataRecipient.DataRecipientBrands[0].SoftwareProducts[0].Certificates.Add(new DataRecipientMetadata.Certificate()
{
CommonName = "Test Automation Certificate Common Name",
Thumbprint = TEST_DATA_THUMBPRINT
@@ -147,7 +148,7 @@ public async Task AC08_Add_Multiple_Duplicate_Certificates()
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipient));
// Remove one of the certificates from expected results
- dataRecipient.DataRecipientBrands.First().SoftwareProducts.First().Certificates.Remove(dataRecipient.DataRecipientBrands.First().SoftwareProducts.First().Certificates.First());
+ dataRecipient.DataRecipientBrands[0].SoftwareProducts[0].Certificates.Remove(dataRecipient.DataRecipientBrands[0].SoftwareProducts[0].Certificates[0]);
// Assert http response and database updates.
VerifySuccessfulDataRecipientUpdate(dataRecipient, response);
@@ -156,7 +157,6 @@ public async Task AC08_Add_Multiple_Duplicate_Certificates()
VerifyParticipationRecord(dataRecipient.LegalEntityId, DATA_RECIPIENT_PARTICIPATION_TYPE, null, dataRecipient.Status);
}
-
[Fact]
public async Task ACXX_Add_New_Legal_Entity_With_Multiple_Software_Products_Http_200()
{
@@ -164,7 +164,7 @@ public async Task ACXX_Add_New_Legal_Entity_With_Multiple_Software_Products_Http
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
// Add second Software Product
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(new DataRecipientMetadata.SoftwareProduct()
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(new DataRecipientMetadata.SoftwareProduct()
{
SoftwareProductId = Guid.NewGuid().ToString(),
SoftwareProductName = "Test Automation Data Recipient Brand Name 001 - Software Product 002",
@@ -191,7 +191,7 @@ public async Task ACXX_Add_New_Legal_Entity_With_Multiple_Software_Products_Http
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
// Assert http response and database updates.
- dataRecipientMetadata.DataRecipientBrands.ToList().OrderBy(b => b.DataRecipientBrandId);
+ dataRecipientMetadata.DataRecipientBrands.OrderBy(b => b.DataRecipientBrandId);
// Assert http response and database updates.
VerifySuccessfulDataRecipientUpdate(dataRecipientMetadata, response);
@@ -206,7 +206,7 @@ public async Task AC10_Scope_Not_Specified_Http_200()
// Generate valid payload
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
- //Remove Scope(s)
+ // Remove Scope(s)
dataRecipientMetadata.DataRecipientBrands.ForEach(dataRecipientBrand =>
{
dataRecipientBrand.SoftwareProducts.ForEach(softwareProduct =>
@@ -218,7 +218,7 @@ public async Task AC10_Scope_Not_Specified_Http_200()
// Send to Register
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- //Update expected Data Reciepent to use default scopes.
+ // Update expected Data Reciepent to use default scopes.
dataRecipientMetadata.DataRecipientBrands.ForEach(dataRecipientBrand =>
{
dataRecipientBrand.SoftwareProducts.ForEach(softwareProduct =>
@@ -234,7 +234,6 @@ public async Task AC10_Scope_Not_Specified_Http_200()
// Assert Participation Record created correctly
VerifyParticipationRecord(dataRecipientMetadata.LegalEntityId, DATA_RECIPIENT_PARTICIPATION_TYPE, null, dataRecipientMetadata.Status);
-
}
[Fact]
@@ -251,7 +250,6 @@ public async Task AC11_Add_New_Legal_Entity_With_Only_Mandatory_Fields_Http_200(
// Assert Participation Record created correctly
VerifyParticipationRecord(dataRecipientMetadata.LegalEntityId, DATA_RECIPIENT_PARTICIPATION_TYPE, null, dataRecipientMetadata.Status);
-
}
[Fact]
@@ -260,7 +258,7 @@ public async Task AC11_Add_New_Legal_Entity_With_Only_Mandatory_Fields_And_Nil_S
// Generate valid payload with only mandatory/minimun fields.
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Clear();
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Clear();
// Send to Register
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
@@ -283,7 +281,7 @@ public async Task AC12_Missing_Version_In_Header_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingHeader, "An API version x-v header is required, but was not specified.");
// Assert Response
@@ -301,14 +299,13 @@ public async Task AC13_Invalid_Version_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.InvalidVersion, "Version is not a positive Integer.");
// Assert Response
await VerifyBadRequest(expectedErrors, response);
}
-
[Theory]
[InlineData("20")]
public async Task AC20_Unsupported_Version_Http_400(string xv)
@@ -319,7 +316,7 @@ public async Task AC20_Unsupported_Version_Http_400(string xv)
// Send to Register with blank x-v header
var response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata), xv: xv);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.UnsupportedVersion, "Requested version is lower than the minimum version or greater than maximum version.");
// Assert Response
@@ -363,7 +360,7 @@ public async Task AC14_Missing_Mandatory_Fields_Http_400(string testId, string e
string expectedMissingField = ConvertJsonPathToPascalCase(elementToRemove);
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingField, $"{expectedMissingField}");
@@ -378,25 +375,23 @@ public async Task AC14_Missing_Mandatory_Fields_Http_400(string testId, string e
// Assert Response
await VerifyBadRequest(expectedErrors, response);
-
}
[Fact]
public async Task AC14_Missing_Multiple_Mandatory_Fields_Http_400()
{
-
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient();
Log.Information($"Original Payload:\n{GetJsonFromModel(dataRecipientMetadata)}");
// Remove mandatory fields
- dataRecipientMetadata.AccreditationNumber = "";
+ dataRecipientMetadata.AccreditationNumber = string.Empty;
dataRecipientMetadata.LegalEntityName = null;
- dataRecipientMetadata.DataRecipientBrands.First().LogoUri = "";
- dataRecipientMetadata.DataRecipientBrands.First().BrandName = null;
+ dataRecipientMetadata.DataRecipientBrands[0].LogoUri = string.Empty;
+ dataRecipientMetadata.DataRecipientBrands[0].BrandName = null;
Log.Information($"Modified Payload (elements removed):\n{GetJsonFromModel(dataRecipientMetadata)}");
- ExpectedErrors expectedErrors = new();
+ ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingField, "LegalEntityName");
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingField, "AccreditationNumber");
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.MissingField, "DataRecipientBrands[0].BrandName");
@@ -407,7 +402,6 @@ public async Task AC14_Missing_Multiple_Mandatory_Fields_Http_400()
// Assert Response
await VerifyBadRequest(expectedErrors, response);
-
}
[Theory]
@@ -429,7 +423,6 @@ public async Task AC15_Valid_And_Invalid_Data_Recipient_Acreditation_Level(strin
dataRecipientMetadata.AccreditationLevel = dataRecipientMetadata.AccreditationLevel.ToUpper();
await VerifyInvalidAndValidFieldResponse(response, dataRecipientMetadata, "AccreditationLevel", accreditationLevel, isValid);
-
}
[Theory]
@@ -455,7 +448,6 @@ public async Task AC15_Valid_And_Invalid_Data_Recipient_Organisation_Type(string
dataRecipientMetadata.OrganisationType = dataRecipientMetadata.OrganisationType.ToUpper();
await VerifyInvalidAndValidFieldResponse(response, dataRecipientMetadata, "OrganisationType", orgType, isValid);
-
}
[Theory]
@@ -480,7 +472,6 @@ public async Task AC15_Valid_And_Invalid_Data_Recipient_Status(string status, bo
dataRecipientMetadata.Status = dataRecipientMetadata.Status.ToUpper();
await VerifyInvalidAndValidFieldResponse(response, dataRecipientMetadata, "Status", status, isValid);
-
}
[Theory]
@@ -495,15 +486,14 @@ public async Task AC15_Valid_And_Invalid_Data_Recipient_Brand_Status(string stat
Log.Information($"Original Payload:\n{GetJsonFromModel(dataRecipientMetadata)}");
// Modify DR Status
- dataRecipientMetadata.DataRecipientBrands.First().Status = status;
+ dataRecipientMetadata.DataRecipientBrands[0].Status = status;
Log.Information($"Modified Payload (elements removed):\n{GetJsonFromModel(dataRecipientMetadata)}");
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- dataRecipientMetadata.DataRecipientBrands.First().Status = dataRecipientMetadata.DataRecipientBrands.First().Status.ToUpper();
+ dataRecipientMetadata.DataRecipientBrands[0].Status = dataRecipientMetadata.DataRecipientBrands[0].Status.ToUpper();
await VerifyInvalidAndValidFieldResponse(response, dataRecipientMetadata, "Status", status, isValid);
-
}
[Theory]
@@ -518,15 +508,14 @@ public async Task AC15_Valid_And_Invalid_Data_Recipient_Software_Product_Status(
Log.Information($"Original Payload:\n{GetJsonFromModel(dataRecipientMetadata)}");
// Modify DR - SP Status
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().Status = status;
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].Status = status;
Log.Information($"Modified Payload (elements removed):\n{GetJsonFromModel(dataRecipientMetadata)}");
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().Status = dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().Status.ToUpper();
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].Status = dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].Status.ToUpper();
await VerifyInvalidAndValidFieldResponse(response, dataRecipientMetadata, "Status", status, isValid);
-
}
[Fact]
@@ -542,12 +531,11 @@ public async Task AC16_Brand_Already_Associated_With_Different_Legal_Entity()
Log.Information($"Modified from Database:\n{GetJsonFromModel(originalDataRecipientMetadata)}");
- string dataRecipientBrandId = originalDataRecipientMetadata.DataRecipientBrands.First().DataRecipientBrandId;
+ string dataRecipientBrandId = originalDataRecipientMetadata.DataRecipientBrands[0].DataRecipientBrandId;
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(originalDataRecipientMetadata));
- await VerifyInvalidPayloadResponse(response, originalDataRecipientMetadata, $"dataRecipientBrandId '{dataRecipientBrandId}' is already associated with a different legal entity.");
-
+ await VerifyInvalidPayloadResponse(response, $"dataRecipientBrandId '{dataRecipientBrandId}' is already associated with a different legal entity.");
}
[Fact]
@@ -559,18 +547,17 @@ public async Task AC17_Software_Product_Already_Associated_With_Dataholder_Brand
Log.Information($"original from Database:\n{GetJsonFromModel(originalDataRecipientMetadata)}");
// Get First Software Product Id.
- string softwareProductId = originalDataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductId;
+ string softwareProductId = originalDataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductId;
// Generate new Data Recipient payload and replace softwareProductId with the already associated softwareProductId (already linked to orignal Dataholder Brand).
DataRecipientMetadata generatedDataRecipientMetadata = GenerateValidDataRecipient();
- generatedDataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductId = softwareProductId;
+ generatedDataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductId = softwareProductId;
Log.Information($"Payload to send:\n{GetJsonFromModel(generatedDataRecipientMetadata)}");
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(generatedDataRecipientMetadata));
- await VerifyInvalidPayloadResponse(response, generatedDataRecipientMetadata, $"Value '{softwareProductId}' in SoftwareProductId is already associated with a different brand.");
-
+ await VerifyInvalidPayloadResponse(response, $"Value '{softwareProductId}' in SoftwareProductId is already associated with a different brand.");
}
[Fact]
@@ -579,7 +566,7 @@ public async Task AC18_Duplicate_Data_Recipient_Brands_Http_400()
// Generate valid payload with only mandatory/minimun fields.
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
- string brandId = dataRecipientMetadata.DataRecipientBrands.First().DataRecipientBrandId;
+ string brandId = dataRecipientMetadata.DataRecipientBrands[0].DataRecipientBrandId;
// Add Data Recipient Brand with duplicate id
dataRecipientMetadata.DataRecipientBrands.Add(new DataRecipientMetadata.DataRecipientBrand()
@@ -594,7 +581,7 @@ public async Task AC18_Duplicate_Data_Recipient_Brands_Http_400()
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- await VerifyInvalidPayloadResponse(response, dataRecipientMetadata, $"Duplicate DataRecipientBrandId '{brandId}' is not allowed in the same request");
+ await VerifyInvalidPayloadResponse(response, $"Duplicate DataRecipientBrandId '{brandId}' is not allowed in the same request");
}
[Fact]
@@ -604,19 +591,18 @@ public async Task AC19_Duplicate_Software_Products_Http_400()
DataRecipientMetadata dataRecipientMetadata = GenerateValidDataRecipient(false);
Log.Information($"Original Payload:\n{GetJsonFromModel(dataRecipientMetadata)}");
- string initialSoftwareProductId = dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SoftwareProductId;
+ string initialSoftwareProductId = dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SoftwareProductId;
// Add Software Product with duplicate id
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(GenerateNewSofwareProduct());
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(GenerateNewSofwareProduct());
// Set both Software Products to the same id
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.ForEach(sp => sp.SoftwareProductId = initialSoftwareProductId);
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.ForEach(sp => sp.SoftwareProductId = initialSoftwareProductId);
Log.Information($"Payload to send:\n{GetJsonFromModel(dataRecipientMetadata)}");
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- await VerifyInvalidPayloadResponse(response, dataRecipientMetadata, $"Duplicate softwareProductId '{initialSoftwareProductId}' is not allowed in the same request");
-
+ await VerifyInvalidPayloadResponse(response, $"Duplicate softwareProductId '{initialSoftwareProductId}' is not allowed in the same request");
}
[Fact]
@@ -634,15 +620,14 @@ public async Task AC19_Multiple_Duplicate_Software_Products_Http_400()
DataRecipientMetadata.SoftwareProduct softwareProduct4 = GenerateNewSofwareProduct();
softwareProduct3.SoftwareProductId = softwareProduct4.SoftwareProductId;
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(softwareProduct1);
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(softwareProduct2);
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(softwareProduct3);
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.Add(softwareProduct4);
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(softwareProduct1);
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(softwareProduct2);
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(softwareProduct3);
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts.Add(softwareProduct4);
HttpResponseMessage response = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
- await VerifyInvalidPayloadResponse(response, dataRecipientMetadata, $"Duplicate softwareProductId '{softwareProduct1.SoftwareProductId}' is not allowed in the same request");
-
+ await VerifyInvalidPayloadResponse(response, $"Duplicate softwareProductId '{softwareProduct1.SoftwareProductId}' is not allowed in the same request");
}
[Theory]
@@ -691,10 +676,8 @@ public async Task ACXX_Maximum_Field_Length_Exceeded(string testId, string eleme
// Send and verify negative scenario
HttpResponseMessage responseNegative = await PostUpdateDataRecipientRequest(GetJsonFromModel(dataRecipientMetadata));
await VerifyInvalidAndValidFieldResponse(responseNegative, dataRecipientMetadata, ConvertJsonPathToPascalCase(elementUnderTest.GetLastFieldFromJsonPath()), maxLengthPlusOneValue, false);
-
}
-
private static string RemoveEmptyJsonArrays(string json)
{
JObject jObject = JsonConvert.DeserializeObject(json);
@@ -710,7 +693,6 @@ private static DataRecipientMetadata GetCopyOfDataRecipient(DataRecipientMetadat
private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage response, DataRecipientMetadata dataRecipientMetadata, string field, string value, bool isValid)
{
-
if (isValid)
{
VerifySuccessfulDataRecipientUpdate(dataRecipientMetadata, response);
@@ -724,21 +706,19 @@ private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage
}
}
- private static async Task VerifyInvalidPayloadResponse(HttpResponseMessage response, DataRecipientMetadata dataRecipientMetadata, string expectedErrorMessage)
+ private static async Task VerifyInvalidPayloadResponse(HttpResponseMessage response, string expectedErrorMessage)
{
-
ExpectedErrors expectedErrors = new ExpectedErrors();
expectedErrors.AddExpectedError(ExpectedErrors.ErrorType.InvalidField, expectedErrorMessage);
await VerifyBadRequest(expectedErrors, response);
-
}
private static void VerifySuccessfulDataRecipientUpdate(DataRecipientMetadata expectedDataRecipientMetadata, HttpResponseMessage httpResponseFromRegister)
{
using (new AssertionScope())
{
- //Check status code
+ // Check status code
httpResponseFromRegister.StatusCode.Should().Be(HttpStatusCode.OK);
// For each data recipient, order software products and set default scope to default if missing
@@ -753,7 +733,6 @@ private static void VerifySuccessfulDataRecipientUpdate(DataRecipientMetadata ex
sp.Scope ??= DEFAULT_SCOPES;
}
}
-
}
expectedDataRecipientMetadata.DataRecipientBrands = expectedDataRecipientMetadata.DataRecipientBrands.OrderBy(b => b.DataRecipientBrandId).ToList();
@@ -771,11 +750,9 @@ private static void VerifySuccessfulDataRecipientUpdate(DataRecipientMetadata ex
private static async Task PostUpdateDataRecipientRequest(string payload, string xv = UPDATE_DATA_RECIPIENT_CURRENT_API_VERSION)
{
-
var clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
var client = new HttpClient(clientHandler);
- //var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:3500/admin/metadata/data-recipients");
var request = new HttpRequestMessage(HttpMethod.Post, $"{ADMIN_BaseURL}/admin/metadata/data-recipients");
request.Content = new StringContent($"{payload}", Encoding.UTF8, "application/json");
@@ -792,12 +769,10 @@ private static async Task PostUpdateDataRecipientRequest(st
Log.Information($"Response from admin/metadata/data-recipients API: {httpResponse.StatusCode} \n{httpResponse.Content.ReadAsStringAsync().Result}");
return httpResponse;
-
}
private static DataRecipientMetadata GenerateValidDataRecipient(bool includeOptionalFields = false)
{
-
DataRecipientMetadata dataRecipientMetadata = new DataRecipientMetadata
{
LegalEntityId = Guid.NewGuid().ToString(),
@@ -812,7 +787,7 @@ private static DataRecipientMetadata GenerateValidDataRecipient(bool includeOpti
{
DataRecipientBrandId = Guid.NewGuid().ToString(),
BrandName = "Test Automation Data Recipient Brand Name 001",
- LogoUri= $"{TEST_DATA_BASE_URI}/DRBlogo.png",
+ LogoUri = $"{TEST_DATA_BASE_URI}/DRBlogo.png",
Status = "ACTIVE",
SoftwareProducts = new List
{
@@ -832,19 +807,18 @@ private static DataRecipientMetadata GenerateValidDataRecipient(bool includeOpti
dataRecipientMetadata.Arbn = "987654321";
dataRecipientMetadata.AnzsicDivision = "Test Automation Anzsic Division";
dataRecipientMetadata.OrganisationType = "COMPANY";
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().SectorIdentifierUri = $"{TEST_DATA_BASE_URI}/SectorIdentifierUri";
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().TosUri = $"{TEST_DATA_BASE_URI}/TosUri";
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().PolicyUri = $"{TEST_DATA_BASE_URI}/PolicyUri";
- dataRecipientMetadata.DataRecipientBrands.First().SoftwareProducts.First().Scope = "openid profile cdr-register:read";
-
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].SectorIdentifierUri = $"{TEST_DATA_BASE_URI}/SectorIdentifierUri";
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].TosUri = $"{TEST_DATA_BASE_URI}/TosUri";
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].PolicyUri = $"{TEST_DATA_BASE_URI}/PolicyUri";
+ dataRecipientMetadata.DataRecipientBrands[0].SoftwareProducts[0].Scope = "openid profile cdr-register:read";
}
return dataRecipientMetadata;
-
}
+
private static DataRecipientMetadata.SoftwareProduct GenerateNewSofwareProduct()
{
- DataRecipientMetadata.SoftwareProduct softwareProduct = new()
+ DataRecipientMetadata.SoftwareProduct softwareProduct = new DataRecipientMetadata.SoftwareProduct()
{
SoftwareProductId = Guid.NewGuid().ToString(),
SoftwareProductName = "Test Automation Data Recipient Brand Name 001 - Software Product 001",
@@ -871,7 +845,6 @@ private static DataRecipientMetadata.SoftwareProduct GenerateNewSofwareProduct()
private static string GetActualDataRecipientFromDatabase(string legalEntityId)
{
-
var legalEntityIdGuid = Guid.Parse(legalEntityId);
try
@@ -902,7 +875,7 @@ private static string GetActualDataRecipientFromDatabase(string legalEntityId)
registeredCountry = participation.LegalEntity.RegisteredCountry,
abn = participation.LegalEntity.Abn,
acn = participation.LegalEntity.Acn,
- arbn = participation.LegalEntity.Arbn == "" ? null : participation.LegalEntity.Arbn,
+ arbn = participation.LegalEntity.Arbn == string.Empty ? null : participation.LegalEntity.Arbn,
anzsicDivision = participation.LegalEntity.AnzsicDivision,
organisationType = participation.LegalEntity.OrganisationType.OrganisationTypeCode.ToUpper(),
status = participation.Status.ParticipationStatusCode,
@@ -935,10 +908,8 @@ private static string GetActualDataRecipientFromDatabase(string legalEntityId)
})
}),
}),
-
});
-
string jsonRepresentation = JsonConvert.SerializeObject(expectedDataRecipients.First());
return RemoveEmptyJsonArrays(jsonRepresentation);
diff --git a/Source/CDR.Register.IntegrationTests/BaseTest.cs b/Source/CDR.Register.IntegrationTests/BaseTest.cs
index cfc6175..8bf4e23 100644
--- a/Source/CDR.Register.IntegrationTests/BaseTest.cs
+++ b/Source/CDR.Register.IntegrationTests/BaseTest.cs
@@ -31,30 +31,9 @@
namespace CDR.Register.IntegrationTests
{
- class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute
+ public abstract class BaseTest : BaseTest0, IClassFixture
{
- static int count = 0;
-
- public override void Before(MethodInfo methodUnderTest)
- {
- Log.Information($"********** Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name} **********");
- Console.WriteLine($"Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name}");
- }
-
- }
-
- // Put all tests in same collection because we need them to run sequentially since some tests are mutating DB.
- [Collection("IntegrationTests")]
- [TestCaseOrderer("CDR.Register.IntegrationTests.XUnit.Orderers.AlphabeticalOrderer", "CDR.Register.IntegrationTests")]
- [DisplayTestMethodName]
- abstract public class BaseTest0
- {
- }
-
- abstract public class BaseTest : BaseTest0, IClassFixture
- {
-
- public BaseTest(ITestOutputHelper output, TestFixture testFixture)
+ protected BaseTest(ITestOutputHelper output, TestFixture testFixture)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(theme: AnsiConsoleTheme.Code)
@@ -67,18 +46,28 @@ public BaseTest(ITestOutputHelper output, TestFixture testFixture)
.CreateLogger();
JsonConvert.DefaultSettings = () => new CdrJsonSerializerSettings();
- TestFixture=testFixture;
+ TestFixture = testFixture;
}
+ private const string REGISTER_RW = "DefaultConnection";
+
+ public static string CONNECTIONSTRING_REGISTER_RW
+ {
+ get
+ {
+ var connectionString = ConnectionStringCheck.Check(Configuration.GetConnectionString(REGISTER_RW));
+ if (connectionString == null)
+ {
+ throw new Exception($"Configuration setting for '{REGISTER_RW}' not found");
+ }
- const string REGISTER_RW = "DefaultConnection";
+ return connectionString!;
+ }
+ }
- static public string CONNECTIONSTRING_REGISTER_RW =>
- ConnectionStringCheck.Check(Configuration.GetConnectionString(REGISTER_RW)
- ?? throw new Exception($"Configuration setting for '{REGISTER_RW}' not found"));
+ private static IConfigurationRoot? configuration;
- static private IConfigurationRoot? configuration;
- static public IConfigurationRoot Configuration
+ public static IConfigurationRoot Configuration
{
get
{
@@ -107,34 +96,48 @@ static public IConfigurationRoot Configuration
// This seed data is copied from ..\CDR.Register.Admin.API\Data\ (see CDR.Register.IntegrationTests.csproj)
public static readonly string SEEDDATA_FILENAME = $"seed-data.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";
- // URLs
- static public string TLS_BaseURL => Configuration["TLS_BaseURL"]
- ?? throw new Exception($"{nameof(TLS_BaseURL)} - configuration setting not found");
- static public string MTLS_BaseURL => Configuration["MTLS_BaseURL"]
- ?? throw new Exception($"{nameof(MTLS_BaseURL)} - configuration setting not found");
- static public string ADMIN_BaseURL => Configuration["Admin_BaseURL"]
- ?? throw new Exception($"{nameof(ADMIN_BaseURL)} - configuration setting not found");
- static public readonly string ADMIN_URL = ADMIN_BaseURL + "/admin/metadata";
- static public readonly string IDENTITYSERVER_URL = MTLS_BaseURL + "/idp/connect/token";
-
// START CTS Settings
- static public string AZURE_AD_TOKEN_ENDPOINT_URL => Configuration["CtsSettings:AzureAd:TokenEndpointUrl"] ?? throw new Exception($"{nameof(AZURE_AD_TOKEN_ENDPOINT_URL)} - configuration setting not found");
- static public string AZURE_AD_CLIENT_ID => Configuration["CtsSettings:AzureAd:ClientId"] ?? throw new Exception($"{nameof(AZURE_AD_CLIENT_ID)} - configuration setting not found");
- static public string AZURE_AD_CLIENT_SECRET => Configuration["CtsSettings:AzureAd:ClientSecret"] ?? throw new Exception($"{nameof(AZURE_AD_CLIENT_SECRET)} - configuration setting not found");
- static public string AZURE_AD_UNAUTHORISED_CLIENT_ID => Configuration["CtsSettings:AzureAd:UnauthorisedClientId"] ?? throw new Exception($"{nameof(AZURE_AD_UNAUTHORISED_CLIENT_ID)} - configuration setting not found");
- static public string AZURE_AD_UNAUTHORISED_CLIENT_SECRET => Configuration["CtsSettings:AzureAd:UnauthorisedClientSecret"] ?? throw new Exception($"{nameof(AZURE_AD_UNAUTHORISED_CLIENT_SECRET)} - configuration setting not found");
- static public string AZURE_AD_SCOPE => Configuration["CtsSettings:AzureAd:Scope"] ?? throw new Exception($"{nameof(AZURE_AD_SCOPE)} - configuration setting not found");
- static public string AZURE_AD_GRANT_TYPE => Configuration["CtsSettings:AzureAd:GrantType"] ?? throw new Exception($"{nameof(AZURE_AD_GRANT_TYPE)} - configuration setting not found");
public const string EXPIRED_ACCESS_TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyJ9.eyJhdWQiOiI3YzVmZmE2Yy1jN2ZhLTRlNDktODMyZi1lZWQ0MzBmODE1MjUiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vYWZiYmE3ZDAtNjc2Zi00MGI3LTkwYmQtOGY0NjM4MDM0YjgyL3YyLjAiLCJpYXQiOjE2ODM3ODIyMTgsIm5iZiI6MTY4Mzc4MjIxOCwiZXhwIjoxNjgzNzg2MTE4LCJhaW8iOiJFMlpnWUdnS2VoSXp6ODFpMWFYazA2NG5jcU15ZU90dUNhOUs4NTB6dGNiYjhvR1g5UVVBIiwiYXpwIjoiMzA5MjJhZWUtMDc5OS00NzkxLWFkNDUtMjI2NTUwZjg2OGJlIiwiYXpwYWNyIjoiMSIsIm9pZCI6ImY0ZGZmMGU2LTQxYjMtNDFlNy1iNWFiLWQ0MzNjZTg4MTY5NiIsInJoIjoiMC5BVUVBMEtlN3IyOW50MENRdlk5R09BTkxnbXo2WDN6NngwbE9neV91MURENEZTVkJBQUEuIiwicm9sZXMiOlsiQXBpLkFkbWluLlBhcnRpY2lwYW50TWV0YURhdGEuV3JpdGUiLCJBcGkuQWRtaW4uUGFydGljaXBhbnRNZXRhRGF0YS5SZWFkIl0sInN1YiI6ImY0ZGZmMGU2LTQxYjMtNDFlNy1iNWFiLWQ0MzNjZTg4MTY5NiIsInRpZCI6ImFmYmJhN2QwLTY3NmYtNDBiNy05MGJkLThmNDYzODAzNGI4MiIsInV0aSI6IlB6SEF3aTlXY2t5dXRkbGRSSkVTQUEiLCJ2ZXIiOiIyLjAifQ.VjMh6-FRMLWAIkYloADH--fTgUVfNgN2XYx3yeJUew1JiCRpiABj4JYkieBxkQ4vrWfj79F3O1ggf2SEOy49nym037CdA3TfW83kpw7MOVHH38-VG-LR_sobAMsS40N4dwNrvsfRQxjQha8gcnskPvtYAWYOII2vfMFxrxAeChwsDGd6A-b5-vo26GyQjebZLcfhMAgu79HFKgIrQRg9MYQ5ZI2wISi2T_d43RYyluXHBtVyCRIfEmUy3aTyJBo6ZHW5omhbUgDp9otwUmwFkv4xrmdrz5ADgqaMelEVllyJrUD9de_wvAh9V5q5Bu6bJhufQoKWXgO-dKIx6baJOA";
- static public string SSA_DOWNSTREAM_BASE_URL => Configuration["SSA_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(SSA_DOWNSTREAM_BASE_URL)} - configuration setting not found");
- static public string DISCOVERY_DOWNSTREAM_BASE_URL => Configuration["Discovery_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(DISCOVERY_DOWNSTREAM_BASE_URL)} - configuration setting not found");
- static public string STATUS_DOWNSTREAM_BASE_URL => Configuration["Status_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(STATUS_DOWNSTREAM_BASE_URL)} - configuration setting not found");
- static public string IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL => Configuration["IdentityProvider_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL)} - configuration setting not found");
+ public static string AZURE_AD_TOKEN_ENDPOINT_URL => Configuration["CtsSettings:AzureAd:TokenEndpointUrl"] ?? throw new Exception($"{nameof(AZURE_AD_TOKEN_ENDPOINT_URL)} - configuration setting not found");
+
+ public static string AZURE_AD_CLIENT_ID => Configuration["CtsSettings:AzureAd:ClientId"] ?? throw new Exception($"{nameof(AZURE_AD_CLIENT_ID)} - configuration setting not found");
+
+ public static string AZURE_AD_CLIENT_SECRET => Configuration["CtsSettings:AzureAd:ClientSecret"] ?? throw new Exception($"{nameof(AZURE_AD_CLIENT_SECRET)} - configuration setting not found");
+
+ public static string AZURE_AD_UNAUTHORISED_CLIENT_ID => Configuration["CtsSettings:AzureAd:UnauthorisedClientId"] ?? throw new Exception($"{nameof(AZURE_AD_UNAUTHORISED_CLIENT_ID)} - configuration setting not found");
+
+ public static string AZURE_AD_UNAUTHORISED_CLIENT_SECRET => Configuration["CtsSettings:AzureAd:UnauthorisedClientSecret"] ?? throw new Exception($"{nameof(AZURE_AD_UNAUTHORISED_CLIENT_SECRET)} - configuration setting not found");
+
+ public static string AZURE_AD_SCOPE => Configuration["CtsSettings:AzureAd:Scope"] ?? throw new Exception($"{nameof(AZURE_AD_SCOPE)} - configuration setting not found");
+
+ public static string AZURE_AD_GRANT_TYPE => Configuration["CtsSettings:AzureAd:GrantType"] ?? throw new Exception($"{nameof(AZURE_AD_GRANT_TYPE)} - configuration setting not found");
+
+ public static string SSA_DOWNSTREAM_BASE_URL => Configuration["SSA_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(SSA_DOWNSTREAM_BASE_URL)} - configuration setting not found");
+
+ public static string DISCOVERY_DOWNSTREAM_BASE_URL => Configuration["Discovery_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(DISCOVERY_DOWNSTREAM_BASE_URL)} - configuration setting not found");
+
+ public static string STATUS_DOWNSTREAM_BASE_URL => Configuration["Status_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(STATUS_DOWNSTREAM_BASE_URL)} - configuration setting not found");
+
+ public static string IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL => Configuration["IdentityProvider_Downstream_BaseUrl"] ?? throw new Exception($"{nameof(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL)} - configuration setting not found");
public TestFixture TestFixture { get; }
- //END CTS Settings
+ // END CTS Settings
+
+ // URLs
+ public static string TLS_BaseURL => Configuration["TLS_BaseURL"]
+ ?? throw new Exception($"{nameof(TLS_BaseURL)} - configuration setting not found");
+
+ public static string MTLS_BaseURL => Configuration["MTLS_BaseURL"]
+ ?? throw new Exception($"{nameof(MTLS_BaseURL)} - configuration setting not found");
+
+ public static string ADMIN_BaseURL => Configuration["Admin_BaseURL"]
+ ?? throw new Exception($"{nameof(ADMIN_BaseURL)} - configuration setting not found");
+
+ public static readonly string ADMIN_URL = ADMIN_BaseURL + "/admin/metadata";
+
+ public static readonly string IDENTITYSERVER_URL = MTLS_BaseURL + "/idp/connect/token";
protected const string EXPECTED_UNSUPPORTED_ERROR = @"
{
@@ -170,10 +173,10 @@ static public IConfigurationRoot Configuration
}";
///
- /// Assert response content and expectedJson are equivalent
+ /// Assert response content and expectedJson are equivalent.
///
- /// The expected json
- /// The response content
+ /// The expected json.
+ /// The response content.
public static async Task Assert_HasContent_Json(string expectedJson, HttpContent content)
{
var actualJson = await content.ReadAsStringAsync();
@@ -182,14 +185,15 @@ public static async Task Assert_HasContent_Json(string expectedJson, HttpContent
}
///
- /// Assert actual json is equivalent to expected json
+ /// Assert actual json is equivalent to expected json.
///
- /// The expected json
- /// The actual json
+ /// The expected json.
+ /// The actual json.
public static void Assert_Json(string expectedJson, string actualJson)
{
Log.Information($"Verifying Actual Json:\n{actualJson}\n against expected:\n{expectedJson}");
- //Use Fluentassertions.Json to compare. Whitespace and order is ignored.
+
+ // Use Fluentassertions.Json to compare. Whitespace and order is ignored.
JToken expected = JToken.Parse(expectedJson);
JToken actual = JToken.Parse(actualJson);
actual.Should().BeEquivalentTo(expected);
@@ -197,17 +201,16 @@ public static void Assert_Json(string expectedJson, string actualJson)
///
/// Assert headers has a single header with the expected value.
- /// If expectedValue is null then just check for the existence of the header (and not it's value)
+ /// If expectedValue is null then just check for the existence of the header (and not it's value).
///
- /// The expected header value
- /// The headers to check
- /// Name of header to check
+ /// The expected header value.
+ /// The headers to check.
+ /// Name of header to check.
public static void Assert_HasHeader(string? expectedValue, HttpHeaders headers, string name)
{
headers.Should().NotBeNull();
if (headers != null)
{
- // headers.Contains(name).Should().BeTrue($"Header '{name}' is missing");
headers.Contains(name).Should().BeTrue($"should contain {name} header");
if (headers.Contains(name))
{
@@ -224,9 +227,8 @@ public static void Assert_HasHeader(string? expectedValue, HttpHeaders headers,
}
///
- /// Assert header has content type of ApplicationJson
+ /// Assert header has content type of ApplicationJson.
///
- ///
public static void Assert_HasContentType_ApplicationJson(HttpContent content)
{
content.Should().NotBeNull();
@@ -236,7 +238,7 @@ public static void Assert_HasContentType_ApplicationJson(HttpContent content)
}
///
- /// Assert claim exists
+ /// Assert claim exists.
///
public static void AssertClaim(IEnumerable claims, string claimType, string claimValue)
{
@@ -253,7 +255,7 @@ protected static string GetJsonFromModel(T model)
}
///
- /// Get status of SoftwareProduct
+ /// Get status of SoftwareProduct.
///
public static int GetSoftwareProductStatusId(string softwareProductId)
{
@@ -267,7 +269,7 @@ public static int GetSoftwareProductStatusId(string softwareProductId)
}
///
- /// Set status of SoftwareProduct
+ /// Set status of SoftwareProduct.
///
public static void SetSoftwareProductStatusId(string softwareProductId, int statusId)
{
@@ -287,11 +289,11 @@ public static void SetSoftwareProductStatusId(string softwareProductId, int stat
if (selectCommand.ExecuteScalarInt32() != 1)
{
throw new Exception("Status not updated");
- };
+ }
}
///
- /// Get status of Brand
+ /// Get status of Brand.
///
public static int GetBrandStatusId(string brandId)
{
@@ -305,7 +307,7 @@ public static int GetBrandStatusId(string brandId)
}
///
- /// Set status of Brand
+ /// Set status of Brand.
///
public static void SetBrandStatusId(string brandId, int statusId)
{
@@ -325,11 +327,11 @@ public static void SetBrandStatusId(string brandId, int statusId)
if (selectCommand.ExecuteScalarInt32() != 1)
{
throw new Exception("Status not updated");
- };
+ }
}
///
- /// Get participationid for brand
+ /// Get participationid for brand.
///
public static string GetParticipationId(string brandId)
{
@@ -343,7 +345,7 @@ public static string GetParticipationId(string brandId)
}
///
- /// Get status of Participation
+ /// Get status of Participation.
///
public static int GetParticipationStatusId(string participationId)
{
@@ -357,7 +359,7 @@ public static int GetParticipationStatusId(string participationId)
}
///
- /// Get status of Participation
+ /// Get status of Participation.
///
public static void SetParticipationStatusId(string participationId, int statusId)
{
@@ -377,8 +379,9 @@ public static void SetParticipationStatusId(string participationId, int statusId
if (selectCommand.ExecuteScalarInt32() != 1)
{
throw new Exception("Status not updated");
- };
+ }
}
+
protected static void VerifyParticipationRecord(string legalEntiryId, string expectedParticipationType, string expectedIndustryType, string expectedStatus)
{
using SqlConnection registerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
@@ -459,12 +462,10 @@ protected static void VerifyBrandLastUpdatedDateRecord(string legalEntiryId)
Log.Information($"Verifying LastUpdate Brand with Id: '{b.BrandId}' is within 120 seconds from '{DateTime.UtcNow}'");
b.LastUpdated.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(120), because: $"Brand with Id: '{b.BrandId}' was just updated/added.");
}
-
}
protected static ICollection GetActualBrandsFromDatabase(string legalEntityId)
{
-
var legalEntityIdGuid = Guid.Parse(legalEntityId);
try
@@ -492,7 +493,7 @@ protected static async Task VerifyBadRequest(ExpectedErrors expectedErrors, Http
using (new AssertionScope())
{
- //Check status code
+ // Check status code
httpResponseFromRegister.StatusCode.Should().Be(HttpStatusCode.BadRequest);
string actualErrors = await httpResponseFromRegister.Content.ReadAsStringAsync();
@@ -507,7 +508,7 @@ protected static async Task VerifyNotAcceptableRequest(ExpectedErrors expectedEr
using (new AssertionScope())
{
- //Check status code
+ // Check status code
httpResponseFromRegister.StatusCode.Should().Be(HttpStatusCode.NotAcceptable);
string actualErrors = await httpResponseFromRegister.Content.ReadAsStringAsync();
@@ -523,13 +524,12 @@ protected static async Task VerifyUnauthorisedRequest(HttpResponseMessage httpRe
using (new AssertionScope())
{
- //Check status code
+ // Check status code
httpResponseFromRegister.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
string actualErrors = await httpResponseFromRegister.Content.ReadAsStringAsync();
Assert_Json(expectedErrorJson, actualErrors);
-
}
}
@@ -549,7 +549,7 @@ protected static string ConvertJsonPathToPascalCase(string jsonPath)
{
JToken mainJoken = JObject.FromObject(model ?? throw new ArgumentNullException(nameof(model)));
- //If an array element, remove element.
+ // If an array element, remove element.
if (path.Last() == ']')
{
JToken token = mainJoken.SelectToken(path, true) ?? throw new Exception("mainJoken cannot be null.");
@@ -562,20 +562,19 @@ protected static string ConvertJsonPathToPascalCase(string jsonPath)
}
return mainJoken.ToObject();
-
}
protected static T? ReplaceModelValueBasedOnJsonPath(T model, string path, string newValue)
{
JToken mainJoken = JObject.FromObject(model ?? throw new ArgumentNullException(nameof(model)));
- JToken tokenToUpdate = mainJoken.SelectToken(path) ?? throw new Exception($"tokenToUpdate is null. Ensure json path '{path}' exists."); ;
+ JToken tokenToUpdate = mainJoken.SelectToken(path) ?? throw new Exception($"tokenToUpdate is null. Ensure json path '{path}' exists.");
tokenToUpdate.Replace(newValue);
return mainJoken.ToObject();
-
}
+
public static string GenerateDynamicCtsUrl(string baseUrl, string? conformanceId = null)
{
if (conformanceId == null)
@@ -590,9 +589,9 @@ public static string GenerateDynamicCtsUrl(string baseUrl, string? conformanceId
protected static string ReplaceSecureHostName(string url, string hostNamedToReplace)
{
- string secureHostname = Configuration["SecureHostName"] ?? "";
+ string secureHostname = Configuration["SecureHostName"] ?? string.Empty;
- if (String.IsNullOrEmpty(secureHostname))
+ if (string.IsNullOrEmpty(secureHostname))
{
return url;
}
@@ -604,9 +603,9 @@ protected static string ReplaceSecureHostName(string url, string hostNamedToRepl
protected static string ReplacePublicHostName(string url, string hostNamedToReplace)
{
- string publicHostname = Configuration["PublicHostName"] ?? "";
+ string publicHostname = Configuration["PublicHostName"] ?? string.Empty;
- if (String.IsNullOrEmpty(publicHostname))
+ if (string.IsNullOrEmpty(publicHostname))
{
return url;
}
@@ -615,6 +614,25 @@ protected static string ReplacePublicHostName(string url, string hostNamedToRepl
return url.Replace(hostNamedToReplace, publicHostname);
}
}
+ }
+ [AttributeUsage(AttributeTargets.Class)]
+ internal class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute
+ {
+ private static int count = 0;
+
+ public override void Before(MethodInfo methodUnderTest)
+ {
+ Log.Information($"********** Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name} **********");
+ Console.WriteLine($"Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name}");
+ }
+ }
+
+ // Put all tests in same collection because we need them to run sequentially since some tests are mutating DB.
+ [Collection("IntegrationTests")]
+ [TestCaseOrderer("CDR.Register.IntegrationTests.XUnit.Orderers.AlphabeticalOrderer", "CDR.Register.IntegrationTests")]
+ [DisplayTestMethodName]
+ public abstract class BaseTest0
+ {
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.IntegrationTests/CDR.Register.IntegrationTests.csproj b/Source/CDR.Register.IntegrationTests/CDR.Register.IntegrationTests.csproj
index facad0a..66df957 100644
--- a/Source/CDR.Register.IntegrationTests/CDR.Register.IntegrationTests.csproj
+++ b/Source/CDR.Register.IntegrationTests/CDR.Register.IntegrationTests.csproj
@@ -5,6 +5,7 @@
$(Version)
$(Version)
$(Version)
+ True
@@ -32,19 +33,20 @@
-
+
-
-
-
-
+
+
+
+
+
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -58,6 +60,14 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.IntegrationTests/ConnectionStringCheck.cs b/Source/CDR.Register.IntegrationTests/ConnectionStringCheck.cs
index ceff2dc..87d55a0 100644
--- a/Source/CDR.Register.IntegrationTests/ConnectionStringCheck.cs
+++ b/Source/CDR.Register.IntegrationTests/ConnectionStringCheck.cs
@@ -1,24 +1,19 @@
-#nullable enable
+#nullable enable
using System;
-using Xunit;
-using FluentAssertions.Execution;
-using FluentAssertions;
namespace CDR.Register.IntegrationTests
{
- static public class ConnectionStringCheck
+ public static class ConnectionStringCheck
{
internal const string PRODUCTION_SERVER = "prod.database.windows.net"; // public code so only use substring for matching
- // TODO - MJS - Whitelist would be better since if production database ever changes server this blacklist will fail unless someone remembers to update
- static readonly string[] Blacklist = new string[] {
- PRODUCTION_SERVER
- };
+ // MJS - Whitelist would be better since if production database ever changes server this blacklist will fail unless someone remembers to update
+ private static readonly string[] Blacklist = new string[] { PRODUCTION_SERVER };
- static public string? Check(string? connectionString)
+ public static string? Check(string? connectionString)
{
- if (!String.IsNullOrEmpty(connectionString))
+ if (!string.IsNullOrEmpty(connectionString))
{
// Reject if blacklisted string found in connectionString
foreach (string blacklisted in Blacklist)
@@ -33,53 +28,4 @@ static public class ConnectionStringCheck
return connectionString;
}
}
-
- public class ConnectionStringCheckUnitTests
- {
- const string PRODUCTION_SERVER_FOO = "foo" + ConnectionStringCheck.PRODUCTION_SERVER + "foo"; // blacklist is checking for substrings, so surround with "foo" to ensure we are testing this
-
- [Theory]
- [InlineData(PRODUCTION_SERVER_FOO)]
- [InlineData(PRODUCTION_SERVER_FOO, true)]
- public void WhenOnBlackList_ShouldThrowException(string connectionString, bool? uppercase = false)
- {
- if (uppercase == true)
- {
- connectionString = connectionString.ToUpper();
- }
-
- using (new AssertionScope())
- {
- // Act/Assert
- Action act = () => ConnectionStringCheck.Check(connectionString);
- using (new AssertionScope())
- {
- act.Should().Throw();
- }
- }
- }
-
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("foo")]
- [InlineData("sql-cdrsandbox-dev.database.windows.net")]
- [InlineData("sql-cdrsandbox-test.database.windows.net")]
- [InlineData("localhost")]
- [InlineData("mssql")]
- public void WhenNotOnBlackList_ShouldNotThrowException(string? connectionString)
- {
- using (new AssertionScope())
- {
- // Act/Assert
- string? returnedConnectionString = null;
- Action act = () => returnedConnectionString = ConnectionStringCheck.Check(connectionString);
- using (new AssertionScope())
- {
- act.Should().NotThrow();
- returnedConnectionString?.Should().Be(connectionString);
- }
- }
- }
- }
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.IntegrationTests/ConnectionStringCheckUnitTests.cs b/Source/CDR.Register.IntegrationTests/ConnectionStringCheckUnitTests.cs
new file mode 100644
index 0000000..97cb5bf
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/ConnectionStringCheckUnitTests.cs
@@ -0,0 +1,58 @@
+#nullable enable
+
+using System;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Xunit;
+
+namespace CDR.Register.IntegrationTests
+{
+ public class ConnectionStringCheckUnitTests
+ {
+ private const string PRODUCTION_SERVER_FOO = "foo" + ConnectionStringCheck.PRODUCTION_SERVER + "foo"; // blacklist is checking for substrings, so surround with "foo" to ensure we are testing this
+
+ [Theory]
+ [InlineData(PRODUCTION_SERVER_FOO)]
+ [InlineData(PRODUCTION_SERVER_FOO, true)]
+ public void WhenOnBlackList_ShouldThrowException(string connectionString, bool? uppercase = false)
+ {
+ if (uppercase == true)
+ {
+ connectionString = connectionString.ToUpper();
+ }
+
+ using (new AssertionScope())
+ {
+ // Act/Assert
+ Action act = () => ConnectionStringCheck.Check(connectionString);
+ using (new AssertionScope())
+ {
+ act.Should().Throw();
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("foo")]
+ [InlineData("sql-cdrsandbox-dev.database.windows.net")]
+ [InlineData("sql-cdrsandbox-test.database.windows.net")]
+ [InlineData("localhost")]
+ [InlineData("mssql")]
+ public void WhenNotOnBlackList_ShouldNotThrowException(string? connectionString)
+ {
+ using (new AssertionScope())
+ {
+ // Act/Assert
+ string? returnedConnectionString = null;
+ Action act = () => returnedConnectionString = ConnectionStringCheck.Check(connectionString);
+ using (new AssertionScope())
+ {
+ act.Should().NotThrow();
+ returnedConnectionString?.Should().Be(connectionString);
+ }
+ }
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/Extensions/JTokenExtensions.cs b/Source/CDR.Register.IntegrationTests/Extensions/JTokenExtensions.cs
index 6a6281a..7bb84b4 100644
--- a/Source/CDR.Register.IntegrationTests/Extensions/JTokenExtensions.cs
+++ b/Source/CDR.Register.IntegrationTests/Extensions/JTokenExtensions.cs
@@ -1,18 +1,18 @@
-using System;
+using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using System.Linq;
namespace CDR.Register.IntegrationTests.Extensions
{
- static public class JTokenExtensions
+ public static class JTokenExtensions
{
///
- /// Remove child JToken from JToken
+ /// Remove child JToken from JToken.
///
- /// JToken from which to remove child JToken
- /// Key of child to remove
- static public void Remove(this JToken jToken, string key)
+ /// JToken from which to remove child JToken.
+ /// Key of child to remove.
+ public static void Remove(this JToken jToken, string key)
{
var t = jToken[key];
@@ -32,18 +32,18 @@ static public void Remove(this JToken jToken, string key)
}
///
- /// Should a JToken be removed?
+ /// Should a JToken be removed?.
///
public delegate bool ShouldRemove(JToken jToken);
///
- /// Recursively remove child JTokens from a JToken
+ /// Recursively remove child JTokens from a JToken.
///
- /// Root JToken to start processing from
- /// Should a token be removed?
+ /// Root JToken to start processing from.
+ /// Should a token be removed?.
public static void RemoveJTokens(this JToken rootJToken, ShouldRemove shouldRemove)
{
- List jTokensToRemove = new();
+ List jTokensToRemove = [];
void DoJToken(JToken jToken)
{
@@ -55,6 +55,7 @@ void DoJToken(JToken jToken)
{
jTokensToRemove.Add(childJToken);
}
+
// Not marked for removal, so process children if applicable
else if (childJToken.HasValues)
{
@@ -75,7 +76,7 @@ void DoJToken(JToken jToken)
}
///
- /// Recursively remove null JTokens from a root JToken
+ /// Recursively remove null JTokens from a root JToken.
///
public static void RemoveNulls(this JToken rootJToken)
{
@@ -83,7 +84,7 @@ public static void RemoveNulls(this JToken rootJToken)
}
///
- /// Recursively remove empty array JTokens from a root JToken
+ /// Recursively remove empty array JTokens from a root JToken.
///
public static void RemoveEmptyArrays(this JToken rootJToken)
{
@@ -101,6 +102,7 @@ public static void RemovePath(this JToken jToken, string jsonPath)
}
public delegate JToken Replace(JToken token);
+
public static void ReplacePath(this JToken jToken, string jsonPath, Replace replace)
{
var tokens = jToken.SelectTokens(jsonPath);
@@ -112,7 +114,7 @@ public static void ReplacePath(this JToken jToken, string jsonPath, Replace repl
}
///
- /// Sort tokens under jsonPath by key
+ /// Sort tokens under jsonPath by key.
///
public static void Sort(this JToken rootToken, string jsonPath, string key)
{
@@ -134,7 +136,7 @@ public static void Sort(this JToken rootToken, string jsonPath, string key)
}
///
- /// Sort array by key
+ /// Sort array by key.
///
public static void SortArray(this JToken token, string key)
{
@@ -158,18 +160,19 @@ public static void SortArray(this JToken token, string key)
}
///
- /// Sort path arrays by key
+ /// Sort path arrays by key.
///
- /// For arrays matching this path
- /// Key to sort array by
+ /// Token to sort.
+ /// For arrays matching this path.
+ /// Key to sort array by.
public static void SortArray(this JToken token, string path, string key)
{
var tokens = token.SelectTokens(path);
- foreach (var _token in tokens)
+ foreach (var tokenToSort in tokens)
{
- _token.SortArray(key);
+ tokenToSort.SortArray(key);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.IntegrationTests/Extensions/JsonExtensions.cs b/Source/CDR.Register.IntegrationTests/Extensions/JsonExtensions.cs
index fe28f4b..4fbf405 100644
--- a/Source/CDR.Register.IntegrationTests/Extensions/JsonExtensions.cs
+++ b/Source/CDR.Register.IntegrationTests/Extensions/JsonExtensions.cs
@@ -1,4 +1,4 @@
-using System.Text.Json;
+using System.Text.Json;
using Newtonsoft.Json.Linq;
namespace CDR.Register.IntegrationTests.Extensions
@@ -6,8 +6,8 @@ namespace CDR.Register.IntegrationTests.Extensions
public static class JsonExtensions
{
///
- /// Strip comments from json string.
- /// The json will be reserialized so it's formatting may change (ie whitespace/indentation etc)
+ /// Strip comments from json string.
+ /// The json will be reserialized so it's formatting may change (ie whitespace/indentation etc).
///
public static string JsonStripComments(this string json)
{
@@ -23,7 +23,7 @@ public static string JsonStripComments(this string json)
}
///
- /// Compare json.
+ /// Compare json.
/// Json is converted to JTokens prior to comparision, thus formatting is ignore.
/// Returns true if json is equivalent, otherwise false.
///
diff --git a/Source/CDR.Register.IntegrationTests/Extensions/JwtSecurityTokenExtensions.cs b/Source/CDR.Register.IntegrationTests/Extensions/JwtSecurityTokenExtensions.cs
index 5183085..3a8a61d 100644
--- a/Source/CDR.Register.IntegrationTests/Extensions/JwtSecurityTokenExtensions.cs
+++ b/Source/CDR.Register.IntegrationTests/Extensions/JwtSecurityTokenExtensions.cs
@@ -1,4 +1,4 @@
-using System.IdentityModel.Tokens.Jwt;
+using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using FluentAssertions;
@@ -7,22 +7,23 @@
namespace CDR.Register.IntegrationTests.Extensions
{
- static public class JwtSecurityTokenExtensions
+ public static class JwtSecurityTokenExtensions
{
///
/// Get claim for claimType. Throws exception if no claim or multiple claims (ie must be a single claim for claimType).
///
///
- static public Claim Claim(this JwtSecurityToken jwt, string claimType)
- => jwt.Claims.Where(claim => claim.Type == claimType).Single();
+ public static Claim Claim(this JwtSecurityToken jwt, string claimType)
+ => jwt.Claims.Single(claim => claim.Type == claimType);
///
/// Assert JWT contains a claim with given value.
///
- /// The claim type to assert
- /// The claim value to assert. If null then claim value can be anything (it is not checked)
- /// If true then the claim itself is optional and doesn't need to exist in the claims
- static public void AssertClaim(this JwtSecurityToken jwt, string claimType, string? claimValue, bool optional = false)
+ /// The JWT token to assert.
+ /// The claim type to assert.
+ /// The claim value to assert. If null then claim value can be anything (it is not checked).
+ /// If true then the claim itself is optional and doesn't need to exist in the claims.
+ public static void AssertClaim(this JwtSecurityToken jwt, string claimType, string? claimValue, bool optional = false)
{
var claims = jwt.Claims.Where(claim => claim.Type == claimType);
@@ -43,7 +44,7 @@ static public void AssertClaim(this JwtSecurityToken jwt, string claimType, stri
}
}
- static public void AssertClaimIsArray(this JwtSecurityToken jwt, string claimType, string[]? claimValues)
+ public static void AssertClaimIsArray(this JwtSecurityToken jwt, string claimType, string[]? claimValues)
{
var claims = jwt.Claims.Where(claim => claim.Type == claimType);
diff --git a/Source/CDR.Register.IntegrationTests/Extensions/SqlExtensions.cs b/Source/CDR.Register.IntegrationTests/Extensions/SqlExtensions.cs
index e1c18f2..1775f06 100644
--- a/Source/CDR.Register.IntegrationTests/Extensions/SqlExtensions.cs
+++ b/Source/CDR.Register.IntegrationTests/Extensions/SqlExtensions.cs
@@ -1,14 +1,14 @@
-using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System;
namespace CDR.Register.IntegrationTests.Extensions
{
- static public class SqlExtensions
+ public static class SqlExtensions
{
///
- /// Execute scalar command and return result as Int32. Throw error if no results or conversion error
+ /// Execute scalar command and return result as Int32. Throw error if no results or conversion error.
///
- static public Int32 ExecuteScalarInt32(this SqlCommand command)
+ public static int ExecuteScalarInt32(this SqlCommand command)
{
var res = command.ExecuteScalar();
@@ -21,9 +21,9 @@ static public Int32 ExecuteScalarInt32(this SqlCommand command)
}
///
- /// Execute scalar command and return result as string. Throw error if no results or conversion error
+ /// Execute scalar command and return result as string. Throw error if no results or conversion error.
///
- static public string ExecuteScalarString(this SqlCommand command)
+ public static string ExecuteScalarString(this SqlCommand command)
{
var res = command.ExecuteScalar();
diff --git a/Source/CDR.Register.IntegrationTests/Extensions/StringExtensions.cs b/Source/CDR.Register.IntegrationTests/Extensions/StringExtensions.cs
index 643abbe..d92a07d 100644
--- a/Source/CDR.Register.IntegrationTests/Extensions/StringExtensions.cs
+++ b/Source/CDR.Register.IntegrationTests/Extensions/StringExtensions.cs
@@ -1,8 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace CDR.Register.IntegrationTests.Extensions
{
@@ -14,7 +11,6 @@ public static string GenerateRandomString(this int length)
Random random = new Random();
return new string(Enumerable.Repeat(allowableChars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
-
}
public static string GetLastFieldFromJsonPath(this string path)
diff --git a/Source/CDR.Register.IntegrationTests/Gateway/US12841_Gateway_MTLS_Tests.cs b/Source/CDR.Register.IntegrationTests/Gateway/US12841_Gateway_MTLS_Tests.cs
index e5b2801..2b6a1aa 100644
--- a/Source/CDR.Register.IntegrationTests/Gateway/US12841_Gateway_MTLS_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/Gateway/US12841_Gateway_MTLS_Tests.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Net.Http;
@@ -18,20 +18,24 @@ namespace CDR.Register.IntegrationTests.Gateway
{
///
/// Integration tests for mTLS Gateway.
- ///
+ ///
public class US12841_Gateway_MTLS_Tests : BaseTest
{
- public US12841_Gateway_MTLS_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US12841_Gateway_MTLS_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
// Client certificates
- const string INVALID_CERTIFICATE_FILENAME = "Certificates/client-invalid.pfx";
+ private const string INVALID_CERTIFICATE_FILENAME = "Certificates/client-invalid.pfx";
// Server certificate
- const string SERVER_CERTIFICATE_FILENAME = "Certificates/server.pfx";
- const string SERVER_CERTIFICATE_PASSWORD = "#M0ckDataHolder#";
+ private const string SERVER_CERTIFICATE_FILENAME = "Certificates/server.pfx";
+ private const string SERVER_CERTIFICATE_PASSWORD = "#M0ckDataHolder#";
// Client assertion
- private static readonly string AUDIENCE = IDENTITYSERVER_URL;
private const string SCOPE = "cdr-register:read";
+ private static readonly string AUDIENCE = IDENTITYSERVER_URL;
// Token request
private const string GRANT_TYPE = "client_credentials";
@@ -40,27 +44,28 @@ public US12841_Gateway_MTLS_Tests(ITestOutputHelper outputHelper, TestFixture te
private const string ISSUER = CLIENT_ID;
// Participation/Brand/SoftwareProduct Ids
- private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup
+ private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup
+
private const string BRANDID = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
private const string SOFTWAREPRODUCTID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
///
- /// Get HttpClient with client certificate
+ /// Get HttpClient with client certificate.
///
private static HttpClient GetClient(string certificateFilename, string certificatePassword)
{
- var _clientHandler = new HttpClientHandler();
- _clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
+ var clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
// Attach certificate
var clientCertificate = new X509Certificate2(certificateFilename, certificatePassword, X509KeyStorageFlags.Exportable);
- _clientHandler.ClientCertificates.Add(clientCertificate);
+ clientHandler.ClientCertificates.Add(clientCertificate);
- return new HttpClient(_clientHandler);
+ return new HttpClient(clientHandler);
}
///
- /// Get HttpRequestMessage for access token request
+ /// Get HttpRequestMessage for access token request.
///
private static HttpRequestMessage GetAccessTokenRequest(string certificateFilename, string certificatePassword)
{
@@ -115,8 +120,8 @@ static string BuildContent(string scope, string grant_type, string client_id, st
[Fact]
public async Task AC01_PostAccessTokenRequest_WithClientCert_ShouldRespondWith_200OK_AccessToken()
{
- // Expected JWT claims
- string JWT_CLAIM_ISS = $"{TLS_BaseURL}/idp";
+ // Expected JWT claims
+ string jwtClaimIss = $"{TLS_BaseURL}/idp";
const string JWT_CLAIM_AUD = "cdr-register";
const string JWT_CLAIM_CLIENT_ID = CLIENT_ID;
const string JWT_CLAIM_SCOPE = SCOPE;
@@ -126,7 +131,7 @@ public async Task AC01_PostAccessTokenRequest_WithClientCert_ShouldRespondWith_2
const int ACCESSTOKEN_EXPIRESIN = 300;
const string ACCESSTOKEN_TOKENTYPE = JwtBearerDefaults.AuthenticationScheme;
- // Arrange
+ // Arrange
var client = GetClient(CERTIFICATE_FILENAME, CERTIFICATE_PASSWORD);
var accessTokenRequest = GetAccessTokenRequest(CERTIFICATE_FILENAME, CERTIFICATE_PASSWORD);
@@ -156,7 +161,7 @@ public async Task AC01_PostAccessTokenRequest_WithClientCert_ShouldRespondWith_2
// Assert - Check the JWT access_token
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken.access_token);
- AssertClaim(jwt.Claims, "iss", JWT_CLAIM_ISS);
+ AssertClaim(jwt.Claims, "iss", jwtClaimIss);
AssertClaim(jwt.Claims, "aud", JWT_CLAIM_AUD);
AssertClaim(jwt.Claims, "client_id", JWT_CLAIM_CLIENT_ID);
AssertClaim(jwt.Claims, "scope", JWT_CLAIM_SCOPE);
@@ -216,8 +221,10 @@ public async Task AC04_PostAccessTokenRequest_WithServerCert_ShouldThrow_HttpReq
}
}
- delegate void BeforeDataHolderBrandsRequest();
- delegate void AfterDataHolderBrandsRequest();
+ private delegate void BeforeDataHolderBrandsRequest();
+
+ private delegate void AfterDataHolderBrandsRequest();
+
private static async Task Test_GetDataHolderBrands(
string certificateFilename,
string certificatePassword,
@@ -228,14 +235,14 @@ private static async Task Test_GetDataHolderBrands(
string expectedContent = null)
{
// DataHolderBrands
- string URL = $"{MTLS_BaseURL}/cdr-register/v1/banking/data-holders/brands";
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/banking/data-holders/brands";
const string XV = "2";
// Arrange
var client = GetClient(certificateFilename, certificatePassword);
- var request = new HttpRequestMessage(HttpMethod.Get, URL);
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("x-v", XV);
// Supply access token with request?
@@ -304,7 +311,7 @@ public async Task AC09_GetDataHolderBrands_WithNoAccessToken_AndClientCert_Shoul
await Test_GetDataHolderBrands(CERTIFICATE_FILENAME, CERTIFICATE_PASSWORD, HttpStatusCode.Unauthorized, false);
}
- const string EXPECTEDCONTENT_ADRSTATUSNOTACTIVE = @"
+ private const string EXPECTEDCONTENT_ADRSTATUSNOTACTIVE = @"
{
""errors"": [
{
@@ -337,7 +344,7 @@ await Test_GetDataHolderBrands(
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
[InlineData(2, HttpStatusCode.Forbidden)] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
public async Task AC11_GetDataHolderBrands_WithAccessToken_AndBrandStatusSetInactiveSinceTokenProvisioned_ShouldRespondWith_403Forbidden(
int brandStatusId,
HttpStatusCode expectedStatusCode)
@@ -350,17 +357,16 @@ await Test_GetDataHolderBrands(
expectedStatusCode,
beforeRequest: () => SetBrandStatusId(BRANDID, brandStatusId),
afterRequest: () => SetBrandStatusId(BRANDID, saveBrandStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
- [InlineData(2, HttpStatusCode.Forbidden)] // Removed
- [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
+ [InlineData(2, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
[InlineData(5, HttpStatusCode.Forbidden)] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
+ [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
public async Task AC12_GetDataHolderBrands_WithAccessToken_AndParticipationStatusSetInactiveSinceTokenProvisioned_ShouldRespondWith_403Forbidden(
int participationStatusId,
HttpStatusCode expectedStatusCode)
@@ -373,12 +379,13 @@ await Test_GetDataHolderBrands(
expectedStatusCode,
beforeRequest: () => SetParticipationStatusId(PARTICIPATIONID, participationStatusId),
afterRequest: () => SetParticipationStatusId(PARTICIPATIONID, saveParticipationStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
- delegate void BeforeSSARequest();
- delegate void AfterSSARequest();
+ private delegate void BeforeSSARequest();
+
+ private delegate void AfterSSARequest();
+
private static async Task Test_GetSSA(
string certificateFilename,
string certificatePassword,
@@ -388,13 +395,13 @@ private static async Task Test_GetSSA(
AfterSSARequest afterRequest = null,
string expectedContent = null)
{
- string URL = $"{MTLS_BaseURL}/cdr-register/v1/banking/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/banking/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
const string XV = "3";
// Arrange
var client = GetClient(certificateFilename, certificatePassword);
- var request = new HttpRequestMessage(HttpMethod.Get, URL);
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("x-v", XV);
// Supply access token with request?
@@ -467,7 +474,7 @@ public async Task AC17_GetSSA_WithNoAccessToken_AndClientCert_ShouldRespondWith_
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
[InlineData(2, HttpStatusCode.Forbidden)] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
public async Task AC18_GetSSA_WithAccessToken_AndSoftwareProductStatusSetInactiveSinceTokenProvisioned_ShouldRespondWith_403Forbidden(
int softwareProductStatusId,
HttpStatusCode expectedStatusCode)
@@ -480,14 +487,13 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, softwareProductStatusId),
afterRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, saveSoftwareProductStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
[InlineData(2, HttpStatusCode.Forbidden)] // Inactive
- [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
public async Task AC19_GetSSA_WithAccessToken_AndBrandStatusSetInactiveSinceTokenProvisioned_ShouldRespondWith_403Forbidden(
int brandStatusId,
HttpStatusCode expectedStatusCode)
@@ -500,17 +506,16 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetBrandStatusId(BRANDID, brandStatusId),
afterRequest: () => SetBrandStatusId(BRANDID, saveBrandStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
[Theory]
[InlineData(1, HttpStatusCode.OK)] // Active
- [InlineData(2, HttpStatusCode.Forbidden)] // Removed
- [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
- [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
+ [InlineData(2, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
[InlineData(5, HttpStatusCode.Forbidden)] // Surrendered
- [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
+ [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
public async Task AC20_GetSSA_WithAccessToken_AndParticipationStatusSetInactiveSinceTokenProvisioned_ShouldRespondWith_403Forbidden(
int participationStatusId,
HttpStatusCode expectedStatusCode)
@@ -523,8 +528,7 @@ await Test_GetSSA(
expectedStatusCode,
beforeRequest: () => SetParticipationStatusId(PARTICIPATIONID, participationStatusId),
afterRequest: () => SetParticipationStatusId(PARTICIPATIONID, saveParticipationStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE
- );
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/IdentityServer/US12665_IdentityServer_OIDC_Tests.cs b/Source/CDR.Register.IntegrationTests/IdentityServer/US12665_IdentityServer_OIDC_Tests.cs
index 867a7fa..d35564e 100644
--- a/Source/CDR.Register.IntegrationTests/IdentityServer/US12665_IdentityServer_OIDC_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/IdentityServer/US12665_IdentityServer_OIDC_Tests.cs
@@ -1,6 +1,5 @@
-using System.Net;
+using System.Net;
using System.Net.Http;
-using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Execution;
@@ -11,16 +10,19 @@ namespace CDR.Register.IntegrationTests.IdentityServer
{
///
/// Integration tests for Identity Server OIDC.
- ///
+ ///
public class US12665_IdentityServer_OIDC_Tests : BaseTest
{
- public US12665_IdentityServer_OIDC_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US12665_IdentityServer_OIDC_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
[Fact]
public async Task AC01_Get_ShouldRespondWith_200OK_OIDC()
{
-
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
@@ -30,7 +32,6 @@ public async Task AC01_Get_ShouldRespondWith_200OK_OIDC()
// Assert
await AssertOidcConfiguration(response, TLS_BaseURL, MTLS_BaseURL);
-
}
[Trait("Category", "CTSONLY")]
@@ -39,8 +40,9 @@ public async Task AC02_Get_ShouldRespondWith_200OK_OIDC()
{
// Arrange
string ctsBaseUrl = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL)}";
+
// Act
- var response = await new Infrastructure.API
+ var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
URL = $"{ctsBaseUrl}/idp/.well-known/openid-configuration",
@@ -48,7 +50,6 @@ public async Task AC02_Get_ShouldRespondWith_200OK_OIDC()
// Assert
await AssertOidcConfiguration(response, ReplacePublicHostName(ctsBaseUrl, IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL), ReplaceSecureHostName(ctsBaseUrl, IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL));
-
}
private static async Task AssertOidcConfiguration(HttpResponseMessage response, string publicBaseUrl, string secureBaseUrl)
diff --git a/Source/CDR.Register.IntegrationTests/IdentityServer/US14045_IdentityServer_Token_Tests.cs b/Source/CDR.Register.IntegrationTests/IdentityServer/US14045_IdentityServer_Token_Tests.cs
index a0bf65d..6ce50d0 100644
--- a/Source/CDR.Register.IntegrationTests/IdentityServer/US14045_IdentityServer_Token_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/IdentityServer/US14045_IdentityServer_Token_Tests.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
@@ -13,7 +13,6 @@
using FluentAssertions;
using FluentAssertions.Execution;
using Microsoft.AspNetCore.Authentication.JwtBearer;
-using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using Xunit;
@@ -26,10 +25,14 @@ namespace CDR.Register.IntegrationTests.IdentityServer
{
///
/// Integration tests for Identity Server Token Tests.
- ///
+ ///
public class US14045_IdentityServer_Token_Tests : BaseTest
{
- public US14045_IdentityServer_Token_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US14045_IdentityServer_Token_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
protected const string CLIENTASSERTION_ISSUER = "86ecb655-9eba-409c-9be3-59e7adf7080d";
protected static string CLIENTASSERTION_AUDIENCE => MTLS_BaseURL + "/idp/connect/token";
@@ -41,24 +44,24 @@ public US14045_IdentityServer_Token_Tests(ITestOutputHelper outputHelper, TestFi
private static HttpClient GetClient()
{
- var _clientHandler = new HttpClientHandler();
- _clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
+ var clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
- return new HttpClient(_clientHandler);
+ return new HttpClient(clientHandler);
}
private static HttpClient GetClientWithCertificate(
string certificateFilename = CERTIFICATE_FILENAME,
string certificatePassword = CERTIFICATE_PASSWORD)
{
- var _clientHandler = new HttpClientHandler();
- _clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
+ var clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
// Attach certificate
var clientCertificate = new X509Certificate2(certificateFilename, certificatePassword, X509KeyStorageFlags.Exportable);
- _clientHandler.ClientCertificates.Add(clientCertificate);
+ clientHandler.ClientCertificates.Add(clientCertificate);
- return new HttpClient(_clientHandler);
+ return new HttpClient(clientHandler);
}
private static string GetClientAssertion(
@@ -81,7 +84,7 @@ private static string GetClientAssertion(
}
var tokenizer = new PrivateKeyJwt(certificateFilename, certificatePassword, jtiClaim);
- return tokenizer.Generate(clientAssertionIssuer, clientAssetionAudience, subClaim, signingAlgorithm: signingAlgorithm);
+ return tokenizer.Generate(clientAssertionIssuer, clientAssetionAudience, subClaim, signingAlgorithm: signingAlgorithm!);
}
private static HttpRequestMessage GetAccessTokenRequest(
@@ -89,7 +92,7 @@ private static HttpRequestMessage GetAccessTokenRequest(
string? client_id,
string? client_assertion_type,
string? client_assertion,
- string content_type_header = "application/x-www-form-urlencoded",
+ string? content_type_header = "application/x-www-form-urlencoded",
string scope = CLIENTASSERTION_SCOPE,
string? tokenEndpointUrl = null)
{
@@ -132,7 +135,7 @@ static string BuildContent(string? grant_type, string? client_id, string? client
Content = new StringContent(
BuildContent(grant_type, client_id, client_assertion_type, client_assertion, scope),
Encoding.UTF8,
- content_type_header)
+ content_type_header!)
};
if (string.IsNullOrEmpty(content_type_header))
@@ -159,7 +162,7 @@ static async Task GetValidatedToken(AccessToken accessToken)
var jwksResponse = await jwksClient.GetAsync($"{TLS_BaseURL}/idp/.well-known/openid-configuration/jwks");
var jwks = new JsonWebKeySet(await jwksResponse.Content.ReadAsStringAsync());
- // Setup validation paramters
+ // Setup validation paramters
var validationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
@@ -167,7 +170,7 @@ static async Task GetValidatedToken(AccessToken accessToken)
RequireSignedTokens = true,
ValidateIssuerSigningKey = true,
- IssuerSigningKey = jwks.Keys.First(),
+ IssuerSigningKey = jwks.Keys[0],
ValidateIssuer = true,
ValidIssuer = $"{TLS_BaseURL}/idp",
@@ -193,7 +196,7 @@ static async Task GetValidatedToken(AccessToken accessToken)
CLIENTASSERTION_CLIENT_ASSERTION_TYPE,
clientAssertion);
- // Act
+ // Act
var response = await client.SendAsync(request);
Log.Information("Response from {IdentityServerUrl}: {StatusCode} \n{Content}", IDENTITYSERVER_URL, response.StatusCode, await response.Content.ReadAsStringAsync());
@@ -219,10 +222,10 @@ static async Task GetValidatedToken(AccessToken accessToken)
// Assert - Check scope
accessToken.scope.Should().Contain("cdr-register:read");
- // Assert - Validate access token
+ // Assert - Validate access token
SecurityToken? validatedToken = null;
Func getValidatedTokenFunc = async () => validatedToken = await GetValidatedToken(accessToken);
- await getValidatedTokenFunc.Should().NotThrowAsync(); // If token is valid then no exceptions should be thrown
+ await getValidatedTokenFunc.Should().NotThrowAsync(); // If token is valid then no exceptions should be thrown
validatedToken?.Should().NotBeNull();
// Assert - Check the cnf claim
@@ -265,16 +268,16 @@ public async Task AC04_TokenRequest_InvaldiContentType_ShouldRespondWith_400BadR
if (expectedError != null)
{
- // Assert - Check error response
+ // Assert - Check error response
await Assert_HasContent_Json(expectedError, response.Content);
}
}
}
[Theory]
- [InlineData(null)] // omit granttype
- [InlineData("")] // blank granttype
- [InlineData("foo")] // non-blank
+ [InlineData(null)] // omit granttype
+ [InlineData("")] // blank granttype
+ [InlineData("foo")] // non-blank
public async Task AC05_TokenRequest_InvalidGrantType_ShouldRespondWith_400BadRequest_ErrorResponse(string? grantType)
{
// Arrange
@@ -298,7 +301,7 @@ public async Task AC05_TokenRequest_InvalidGrantType_ShouldRespondWith_400BadReq
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
// Assert - Check error response
- var expectedContent = String.IsNullOrEmpty(grantType) ?
+ var expectedContent = string.IsNullOrEmpty(grantType) ?
@"{""error"":""invalid_client"",""error_description"":""grant_type not provided""}" :
@"{""error"":""unsupported_grant_type"",""error_description"":""grant_type must be client_credentials""}";
await Assert_HasContent_Json(expectedContent, response.Content);
@@ -306,8 +309,8 @@ public async Task AC05_TokenRequest_InvalidGrantType_ShouldRespondWith_400BadReq
}
[Theory]
- [InlineData(null)] // omit client assertion
- [InlineData("")] // blank
+ [InlineData(null)] // omit client assertion
+ [InlineData("")] // blank
[InlineData("foo")] // invalid
public async Task AC06_TokenRequest_InvalidClientAssertion_ShouldRespondWith_400BadRequest_ErrorResponse(string? clientAssertion)
{
@@ -330,7 +333,7 @@ public async Task AC06_TokenRequest_InvalidClientAssertion_ShouldRespondWith_400
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
// Assert - Check error reponse
- var expectedContent = String.IsNullOrEmpty(clientAssertion) ?
+ var expectedContent = string.IsNullOrEmpty(clientAssertion) ?
@"{""error"":""invalid_client"",""error_description"":""client_assertion not provided""}" :
@"{""error"":""invalid_client"",""error_description"":""Invalid client_assertion - token validation error""}";
await Assert_HasContent_Json(expectedContent, response.Content);
@@ -339,7 +342,7 @@ public async Task AC06_TokenRequest_InvalidClientAssertion_ShouldRespondWith_400
[Theory]
[InlineData(null)] // omit client assertion type
- [InlineData("")] // blank
+ [InlineData("")] // blank
[InlineData("foo")] // invalid
public async Task AC07_AC08_TokenRequest_InvalidClientAssertionType_ShouldRespondWith_400BadRequest_ErrorResponse(string? clientAssertionType)
{
@@ -364,7 +367,7 @@ public async Task AC07_AC08_TokenRequest_InvalidClientAssertionType_ShouldRespon
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
// Assert - Check error reponse
- var expectedContent = String.IsNullOrEmpty(clientAssertionType) ?
+ var expectedContent = string.IsNullOrEmpty(clientAssertionType) ?
@"{""error"":""invalid_client"",""error_description"":""client_assertion_type not provided""}" :
@"{""error"":""invalid_client"",""error_description"":""client_assertion_type must be urn:ietf:params:oauth:client-assertion-type:jwt-bearer""}";
await Assert_HasContent_Json(expectedContent, response.Content);
@@ -372,7 +375,7 @@ public async Task AC07_AC08_TokenRequest_InvalidClientAssertionType_ShouldRespon
}
[Theory]
- [InlineData("")] // blank
+ [InlineData("")] // blank
[InlineData("cdr-register:bank:read")] // invalid old scope
[InlineData("foo")] // invalid
public async Task AC09_TokenRequest_InvaldScope_ShouldRespondWith_400BadRequest_ErrorResponse(string scope)
@@ -413,7 +416,7 @@ public async Task AC11_TokenRequest_MissingJTI_ShouldRespondWith_400BadRequest_E
// Arrange
var client = GetClientWithCertificate();
- var clientAssertion = GetClientAssertion(jtiClaim: "");
+ var clientAssertion = GetClientAssertion(jtiClaim: string.Empty);
var request = GetAccessTokenRequest(
CLIENTASSERTION_GRANT_TYPE,
@@ -546,7 +549,7 @@ public async Task AC15_TokenRequest_DuplicateJTI_ShouldRespondWith_400BadRequest
// Assert - Check status code
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
- // Assert - Check error response
+ // Assert - Check error response
var expectedContent = @"{""error"":""invalid_client"",""error_description"":""Invalid client_assertion - 'jti' in the client assertion token must be unique""}";
await Assert_HasContent_Json(expectedContent, response.Content);
@@ -554,7 +557,7 @@ public async Task AC15_TokenRequest_DuplicateJTI_ShouldRespondWith_400BadRequest
}
[Theory]
- [InlineData(ADDITIONAL_CERTIFICATE_FILENAME, ADDITIONAL_CERTIFICATE_PASSWORD)] // invalid certificate
+ [InlineData(ADDITIONAL_CERTIFICATE_FILENAME, ADDITIONAL_CERTIFICATE_PASSWORD)] // invalid certificate
public async Task AC16_TokenRequest_ValidWithInvalidClientCertificate_ShouldRespondWith_400BadRequest_ErrorResponse(string certificateFilename, string certificatePassword)
{
// Arrange
@@ -584,10 +587,10 @@ public async Task AC16_TokenRequest_ValidWithInvalidClientCertificate_ShouldResp
}
// Use MemberData due to dynamic aud strings
- [Theory, MemberData(nameof(ValidAudienceScenarios))]
+ [Theory]
+ [MemberData(nameof(ValidAudienceScenarios))]
public async Task AC00_TokenRequest_ValidAudience(string aud, string scenarioDescription)
{
-
Log.Information("Running positive test case for valid audience of {aud} - {scenarioDescription}", aud, scenarioDescription);
// Arrange
@@ -614,7 +617,6 @@ public async Task AC00_TokenRequest_ValidAudience(string aud, string scenarioDes
string responseString = await response.Content.ReadAsStringAsync();
responseString.Should().Contain("access_token", because: aud + " - " + scenarioDescription);
}
-
}
public static IEnumerable ValidAudienceScenarios
@@ -627,10 +629,10 @@ public static IEnumerable ValidAudienceScenarios
}
// Use MemberData due to dynamic aud strings
- [Theory, MemberData(nameof(InvalidAudienceScenarios))]
+ [Theory]
+ [MemberData(nameof(InvalidAudienceScenarios))]
public async Task AC00_TokenRequest_InvalidAudience(string aud, string scenarioDescription)
{
-
Log.Information("Running negative test case for invalid audience of {aud} - {scenarioDescription}", aud, scenarioDescription);
// Arrange
@@ -638,7 +640,6 @@ public async Task AC00_TokenRequest_InvalidAudience(string aud, string scenarioD
var clientAssertion = GetClientAssertion(clientAssetionAudience: aud);
-
var request = GetAccessTokenRequest(
CLIENTASSERTION_GRANT_TYPE,
CLIENTASSERTION_CLIENT_ID,
@@ -654,10 +655,9 @@ public async Task AC00_TokenRequest_InvalidAudience(string aud, string scenarioD
// Assert - Check status code
response.StatusCode.Should().Be(HttpStatusCode.BadRequest, because: aud + " - " + scenarioDescription);
- // Assert - Check error response
+ // Assert - Check error response
await Assert_HasContent_Json(@"{""error"":""invalid_client"",""error_description"":""Invalid client_assertion - token validation error""}", response.Content);
}
-
}
public static IEnumerable InvalidAudienceScenarios
@@ -666,7 +666,7 @@ public static IEnumerable InvalidAudienceScenarios
{
yield return new string[] { $"foo", "'foo' is not a valid token endpoint or OIDC issuer" };
yield return new string[] { $"{MTLS_BaseURL}/idp/connect/token/x", "Audience is only partial Token Endpoint match (only start matches)" };
- yield return new string[] { $"foo{MTLS_BaseURL}/idp/connect/token", "Audience is only partial Token Endpoint match (only end matches)" };
+ yield return new string[] { $"foo{MTLS_BaseURL}/idp/connect/token", "Audience is only partial Token Endpoint match (only end matches)" };
yield return new string[] { $"{TLS_BaseURL}/idp/foo", "Audience is only partial OICD issuer match (only start matches)" };
yield return new string[] { $"foo{TLS_BaseURL}/idp", "Audience is only partial OICD issuer match (only end matches)" };
yield return new string[] { $"{TLS_BaseURL}/idp/connect/token", "Audience is only partial OICD issuer match - Ends with '/connect/token'" };
@@ -676,10 +676,10 @@ public static IEnumerable InvalidAudienceScenarios
// Use MemberData due to dynamic aud strings
[Trait("Category", "CTSONLY")]
- [Theory, MemberData(nameof(ValidCtsUrlAudienceScenarios))]
+ [Theory]
+ [MemberData(nameof(ValidCtsUrlAudienceScenarios))]
public static async Task AC00_TokenRequest_ValidAudience_DynamicBasePath(string aud, string scenarioDescription, string tokenEndpointUrl)
{
-
Log.Information("Running positive test case for valid audience of {aud} - {scenarioDescription}", aud, scenarioDescription);
// Arrange - Get access token
@@ -706,10 +706,9 @@ public static async Task AC00_TokenRequest_ValidAudience_DynamicBasePath(string
string responseString = await response.Content.ReadAsStringAsync();
responseString.Should().Contain("access_token", because: aud + " - " + scenarioDescription);
}
-
}
- public static IEnumerable ValidCtsUrlAudienceScenarios
+ public static IEnumerable ValidCtsUrlAudienceScenarios
{
get
{
@@ -723,10 +722,10 @@ public static IEnumerable ValidCtsUrlAudienceScenarios
// Use MemberData due to dynamic aud strings
[Trait("Category", "CTSONLY")]
- [Theory, MemberData(nameof(InvalidCtsUrlAudienceScenarios))]
+ [Theory]
+ [MemberData(nameof(InvalidCtsUrlAudienceScenarios))]
public async Task AC00_TokenRequest_InvalidAudience_DynamicBasePath(string aud, string scenarioDescription, string tokenEndpointUrl)
{
-
Log.Information("Running negative test case for audience of {aud} - {scenarioDescription}", aud, scenarioDescription);
// Arrange - Get access token
@@ -749,10 +748,9 @@ public async Task AC00_TokenRequest_InvalidAudience_DynamicBasePath(string aud,
// Assert - Check status code
response.StatusCode.Should().Be(HttpStatusCode.BadRequest, because: aud + " - " + scenarioDescription);
- // Assert - Check error response
+ // Assert - Check error response
await Assert_HasContent_Json(@"{""error"":""invalid_client"",""error_description"":""Invalid client_assertion - token validation error""}", response.Content);
}
-
}
public static IEnumerable InvalidCtsUrlAudienceScenarios
diff --git a/Source/CDR.Register.IntegrationTests/Infrastructure/API.cs b/Source/CDR.Register.IntegrationTests/Infrastructure/API.cs
index fbf87ab..e7b5fa5 100644
--- a/Source/CDR.Register.IntegrationTests/Infrastructure/API.cs
+++ b/Source/CDR.Register.IntegrationTests/Infrastructure/API.cs
@@ -1,29 +1,30 @@
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
-#nullable enable
+#nullable enable
namespace CDR.Register.IntegrationTests.Infrastructure
{
///
- /// Call API
+ /// Call API.
///
- public class API
+ public class Api
{
private const string CERTIFICATE_THUMBPRINT_HEADER_NAME = "X-SSLClientCertThumbprint";
private const string CERTIFICATE_CN_HEADER_NAME = "X-SSLClientCertCN";
+
///
- /// Filename of certificate to use.
+ /// Filename of certificate to use.
/// If null then no certificate will be attached to the request.
///
public string? CertificateFilename { get; set; }
///
- /// Password for certificate.
+ /// Password for certificate.
/// If null then no certificate password will be set.
///
public string? CertificatePassword { get; set; }
@@ -64,18 +65,22 @@ public class API
public string? IfNoneMatch { get; set; }
public string? CertificateThumbprint { get; set; } = null;
+
public string? CertificateCn { get; set; } = null;
///
/// Send a request to the API.
///
- /// The API response
+ /// The API response.
public async Task SendAsync()
{
// Build request
HttpRequestMessage BuildRequest()
{
- if (HttpMethod == null) { throw new Exception($"{nameof(API)}.{nameof(SendAsync)}.{nameof(BuildRequest)} - {nameof(HttpMethod)} not set"); }
+ if (HttpMethod == null)
+ {
+ throw new Exception($"{nameof(Api)}.{nameof(SendAsync)}.{nameof(BuildRequest)} - {nameof(HttpMethod)} not set");
+ }
var request = new HttpRequestMessage(HttpMethod, URL);
@@ -127,8 +132,7 @@ HttpClient GetClient()
clientHandler.ClientCertificates.Add(new X509Certificate2(
CertificateFilename,
CertificatePassword,
- X509KeyStorageFlags.Exportable
- ));
+ X509KeyStorageFlags.Exportable));
return new HttpClient(clientHandler);
}
diff --git a/Source/CDR.Register.IntegrationTests/Infrastructure/AccessToken.cs b/Source/CDR.Register.IntegrationTests/Infrastructure/AccessToken.cs
index 17b0ad6..818847f 100644
--- a/Source/CDR.Register.IntegrationTests/Infrastructure/AccessToken.cs
+++ b/Source/CDR.Register.IntegrationTests/Infrastructure/AccessToken.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -13,8 +13,6 @@ namespace CDR.Register.IntegrationTests.Infrastructure
{
public class AccessToken
{
- private static readonly string IDENTITYSERVER_URL = BaseTest.IDENTITYSERVER_URL;
- private static readonly string AUDIENCE = IDENTITYSERVER_URL;
private const string SCOPE = "cdr-register:read";
private const string GRANT_TYPE = "client_credentials";
private const string CLIENT_ID = "86ecb655-9eba-409c-9be3-59e7adf7080d";
@@ -22,35 +20,46 @@ public class AccessToken
private const string ISSUER = CLIENT_ID;
private const string CERTIFICATE_THUMBPRINT_HEADER_NAME = "X-SSLClientCertThumbprint";
private const string CERTIFICATE_CN_HEADER_NAME = "X-SSLClientCertCN";
+ private static readonly string IDENTITYSERVER_URL = BaseTest.IDENTITYSERVER_URL;
+ private static readonly string AUDIENCE = IDENTITYSERVER_URL;
///
- /// Filename of certificate to use.
+ /// Filename of certificate to use.
/// If null then no certificate will be attached to the request.
///
public string? CertificateFilename { get; set; }
///
- /// Password for certificate.
+ /// Password for certificate.
/// If null then no certificate password will be set.
///
public string? CertificatePassword { get; set; }
public string? Issuer { get; set; } = ISSUER;
+
public string Audience { get; set; } = AUDIENCE;
+
public string Scope { get; set; } = SCOPE;
+
public string GrantType { get; set; } = GRANT_TYPE;
+
public string? ClientId { get; set; } = CLIENT_ID;
+
public string ClientAssertionType { get; set; } = CLIENT_ASSERTION_TYPE;
+
public string TokenEndPoint { get; set; } = BaseTest.IDENTITYSERVER_URL;
+
public string? CertificateThumbprint { get; set; } = null;
+
public string? CertificateCn { get; set; } = null;
///
- /// Get HttpRequestMessage for access token request
+ /// Get HttpRequestMessage for access token request.
///
private HttpRequestMessage CreateAccessTokenRequest(
- string? certificateFilename, string? certificatePassword,
- string issuer, string audience,
+ string certificateFilename, string certificatePassword,
+ string? issuer,
+ string audience,
string scope, string grant_type, string client_id, string client_assertion_type, string? certificateThumprint, string? certificateCn)
{
static string BuildContent(string scope, string grant_type, string client_id, string client_assertion_type, string client_assertion)
@@ -86,7 +95,7 @@ static string BuildContent(string scope, string grant_type, string client_id, st
}
var tokenizer = new PrivateKeyJwt(certificateFilename, certificatePassword, Guid.NewGuid().ToString());
- var client_assertion = tokenizer.Generate(issuer, audience, issuer);
+ var client_assertion = tokenizer.Generate(issuer, audience, issuer ?? string.Empty);
var request = new HttpRequestMessage(HttpMethod.Post, TokenEndPoint)
{
@@ -108,11 +117,10 @@ static string BuildContent(string scope, string grant_type, string client_id, st
}
///
- /// Get an access token from Identity Server
+ /// Get an access token from Identity Server.
///
public async Task GetAsync(bool addCertificateToRequest = true)
{
-
HttpResponseMessage response = await SendAccessTokenRequest(addCertificateToRequest);
if (response.StatusCode != HttpStatusCode.OK)
@@ -129,25 +137,25 @@ static string BuildContent(string scope, string grant_type, string client_id, st
public async Task SendAccessTokenRequest(bool addCertificateToRequest = true)
{
- // Create ClientHandler
- var _clientHandler = new HttpClientHandler();
- _clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
+ // Create ClientHandler
+ var clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
// Attach client certificate to handler
if (CertificateFilename != null && addCertificateToRequest)
{
var clientCertificate = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.Exportable);
- _clientHandler.ClientCertificates.Add(clientCertificate);
+ clientHandler.ClientCertificates.Add(clientCertificate);
}
// Create HttpClient
- using var client = new HttpClient(_clientHandler);
+ using var client = new HttpClient(clientHandler);
// Create an access token request
var request = CreateAccessTokenRequest(
- CertificateFilename, CertificatePassword,
+ CertificateFilename!, CertificatePassword!,
Issuer, Audience,
- Scope, GrantType, ClientId, ClientAssertionType, CertificateThumbprint, CertificateCn);
+ Scope, GrantType, ClientId!, ClientAssertionType, CertificateThumbprint, CertificateCn);
// Request the access token
return await client.SendAsync(request);
diff --git a/Source/CDR.Register.IntegrationTests/Infrastructure/KeyValuePairBuilder.cs b/Source/CDR.Register.IntegrationTests/Infrastructure/KeyValuePairBuilder.cs
index 6dbab19..57616e8 100644
--- a/Source/CDR.Register.IntegrationTests/Infrastructure/KeyValuePairBuilder.cs
+++ b/Source/CDR.Register.IntegrationTests/Infrastructure/KeyValuePairBuilder.cs
@@ -3,21 +3,23 @@
namespace CDR.Register.IntegrationTests.Infrastructure
{
///
- /// Key/Value pair builder
+ /// Key/Value pair builder.
///
public class KeyValuePairBuilder
{
private readonly string _delimiter;
private readonly StringBuilder _sb = new StringBuilder();
+
///
- /// Get key/value pairs as string
+ /// Get key/value pairs as string.
///
public string Value => _sb.ToString();
private int _count = 0;
+
///
- /// Number of key/value pairs
+ /// Number of key/value pairs.
///
public int Count => _count;
@@ -27,10 +29,10 @@ public KeyValuePairBuilder(string delimiter = "&")
}
///
- /// Append key/value pair
+ /// Append key/value pair.
///
- /// Key to add
- /// Value to add
+ /// Key to add.
+ /// Value to add.
public void Add(string key, string value)
{
if (_sb.Length > 0)
@@ -44,20 +46,20 @@ public void Add(string key, string value)
}
///
- /// Add key/value pair
+ /// Add key/value pair.
///
- /// Key to add
- /// Value to add
+ /// Key to add.
+ /// Value to add.
public void Add(string key, int value)
{
Add(key, value.ToString());
}
///
- /// Add key/value pair
+ /// Add key/value pair.
///
- /// Key to add
- /// Value to add
+ /// Key to add.
+ /// Value to add.
public void Add(string key, long value)
{
Add(key, value.ToString());
diff --git a/Source/CDR.Register.IntegrationTests/Infrastructure/PrivateKeyJwt.cs b/Source/CDR.Register.IntegrationTests/Infrastructure/PrivateKeyJwt.cs
index 312cd8f..6ace4b9 100644
--- a/Source/CDR.Register.IntegrationTests/Infrastructure/PrivateKeyJwt.cs
+++ b/Source/CDR.Register.IntegrationTests/Infrastructure/PrivateKeyJwt.cs
@@ -8,6 +8,8 @@
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
+#nullable enable
+
namespace CDR.Register.IntegrationTests.Infrastructure
{
///
@@ -15,18 +17,21 @@ namespace CDR.Register.IntegrationTests.Infrastructure
///
public class PrivateKeyJwt
{
-
public string PrivateKeyBase64 { get; private set; }
- private readonly string JtiClaim;
+
+ private readonly string jtiClaim;
///
- /// Default constructor.
+ /// Initializes a new instance of the class.
///
public PrivateKeyJwt()
{
+ PrivateKeyBase64 = string.Empty;
+ jtiClaim = string.Empty;
}
///
+ /// Initializes a new instance of the class.
/// Provide the primary key to the constructor.
///
/// Base64 encoded private key.
@@ -39,9 +44,16 @@ public PrivateKeyJwt(string privateKey)
{
PrivateKeyBase64 = FormatKey(privateKey);
}
+ else
+ {
+ PrivateKeyBase64 = string.Empty;
+ }
+
+ jtiClaim = string.Empty;
}
///
+ /// Initializes a new instance of the class.
/// Provide the Pkcs8 private key from X509 certificate.
///
/// The path to the certificate.
@@ -51,15 +63,21 @@ public PrivateKeyJwt(string certFilePath, string pwd, string jtiClaim)
{
var cert = new X509Certificate2(certFilePath, pwd, X509KeyStorageFlags.Exportable);
var rsa = cert.GetRSAPrivateKey();
- var pvtKeyBytes = rsa.ExportPkcs8PrivateKey();
+ if (rsa == null)
+ {
+ PrivateKeyBase64 = string.Empty;
+ jtiClaim = string.Empty;
+ }
+
+ var pvtKeyBytes = rsa!.ExportPkcs8PrivateKey();
this.PrivateKeyBase64 = Convert.ToBase64String(pvtKeyBytes);
- JtiClaim = jtiClaim;
+ this.jtiClaim = jtiClaim;
}
///
/// Load the private key from a file.
///
- /// Path to the private key file
+ /// Path to the private key file.
public void LoadPrivateKeyFromFile(string filePath)
{
if (string.IsNullOrEmpty(filePath))
@@ -70,7 +88,6 @@ public void LoadPrivateKeyFromFile(string filePath)
if (!File.Exists(filePath))
{
throw new FileNotFoundException("filePath cannot be found");
-
}
var privateKey = File.ReadAllText(filePath);
@@ -80,11 +97,11 @@ public void LoadPrivateKeyFromFile(string filePath)
///
/// Generate the private_key_jwt using the provided private key.
///
- /// The issuer of the JWT, usually set to the softwareProductId
- /// The audience of the JWT, usually set to the target token endpoint
- /// The subject of the JWT, usually set to the softwareProductId
- /// A base64 encoded JWT
- public string Generate(string issuer, string audience, string subject, string signingAlgorithm = SecurityAlgorithms.RsaSsaPssSha256)
+ /// The issuer of the JWT, usually set to the softwareProductId.
+ /// The audience of the JWT, usually set to the target token endpoint.
+ /// The subject of the JWT, usually set to the softwareProductId.
+ /// A base64 encoded JWT.
+ public string Generate(string? issuer, string audience, string subject, string signingAlgorithm = SecurityAlgorithms.RsaSsaPssSha256)
{
if (string.IsNullOrEmpty(PrivateKeyBase64))
{
@@ -122,16 +139,15 @@ public string Generate(string issuer, string audience, string subject, string si
Audience = audience,
Expires = DateTime.UtcNow.AddMinutes(10),
Subject = new ClaimsIdentity(new List { new Claim("sub", subject) }),
- //SigningCredentials = new SigningCredentials(privateSecurityKey, SecurityAlgorithms.RsaSsaPssSha256),
SigningCredentials = new SigningCredentials(privateSecurityKey, signingAlgorithm),
NotBefore = null,
IssuedAt = null,
Claims = new Dictionary()
};
- if (!string.IsNullOrEmpty(JtiClaim))
+ if (!string.IsNullOrEmpty(jtiClaim))
{
- descriptor.Claims.Add("jti", JtiClaim);
+ descriptor.Claims.Add("jti", jtiClaim);
}
var tokenHandler = new JsonWebTokenHandler();
@@ -140,24 +156,25 @@ public string Generate(string issuer, string audience, string subject, string si
}
///
- /// Format the private key by removing the markers and newline characters,
+ /// Format the private key by removing the markers and newline characters.
///
- /// Raw private key
- /// Formatted private key
+ /// Raw private key.
+ /// Formatted private key.
private static string FormatKey(string privateKey)
{
- return privateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r\n", "").Trim();
+ return privateKey.Replace("-----BEGIN PRIVATE KEY-----", string.Empty).Replace("-----END PRIVATE KEY-----", string.Empty).Replace("\r\n", string.Empty).Trim();
}
private static string GenerateKeyId(RSAParameters rsaParams, out string e, out string n)
{
e = Base64UrlEncoder.Encode(rsaParams.Exponent);
n = Base64UrlEncoder.Encode(rsaParams.Modulus);
- var dict = new Dictionary() {
- {"e", e},
- {"kty", "RSA"},
- {"n", n}
- };
+ var dict = new Dictionary()
+ {
+ { "e", e },
+ { "kty", "RSA" },
+ { "n", n }
+ };
var hash = SHA256.Create();
var hashBytes = hash.ComputeHash(System.Text.Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(dict)));
return Base64UrlEncoder.Encode(hashBytes);
@@ -166,8 +183,8 @@ private static string GenerateKeyId(RSAParameters rsaParams, out string e, out s
///
/// Generate the KeyId (kid) used in the header of a JWT or in a JWK.
///
- /// RSA
- /// The generated kid value
+ /// RSA.
+ /// The generated kid value.
private static string GenerateKeyId(RSA rsa)
{
var rsaParameters = rsa.ExportParameters(false);
diff --git a/Source/CDR.Register.IntegrationTests/Miscellaneous/US12677_RegisterEnrolment_Tests.cs b/Source/CDR.Register.IntegrationTests/Miscellaneous/US12677_RegisterEnrolment_Tests.cs
index 6738140..a62ac87 100644
--- a/Source/CDR.Register.IntegrationTests/Miscellaneous/US12677_RegisterEnrolment_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/Miscellaneous/US12677_RegisterEnrolment_Tests.cs
@@ -1,4 +1,4 @@
-using System.IO;
+using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -15,12 +15,16 @@ namespace CDR.Register.IntegrationTests.Miscellaneous
{
///
/// Integration tests for Register Admin API.
- ///
+ ///
public class US12677_RegisterEnrolment_Tests : BaseTest
{
- public US12677_RegisterEnrolment_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US12677_RegisterEnrolment_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
///
- /// Get the repository as json
+ /// Get the repository as json.
///
private static async Task GetJson()
{
@@ -33,7 +37,7 @@ private static async Task GetJson()
}
///
- /// Load (replace) the repository from json
+ /// Load (replace) the repository from json.
///
private static async Task PostJson(string json)
{
@@ -54,12 +58,12 @@ private static async Task PostJson(string json)
[Fact]
public async Task AC01_Get_ShouldRespondWith_200OK_RepositoryAsJson()
{
- // Arrange
+ // Arrange
await TestFixture.Seeddata(); // TestFixture.InitializeAsync() seeds data but also then patches data in the database. Since we are just testing if import works need to import again (but without patching data).
var json = await File.ReadAllTextAsync(SEEDDATA_FILENAME);
var jToken = JToken.Parse(json);
- // Act
+ // Act
var response = await GetJson();
var responseJson = await response.Content.ReadAsStringAsync();
var jTokenResponse = JToken.Parse(responseJson);
@@ -133,7 +137,10 @@ static void ClearField(JToken jToken, string fieldName)
foreach (var item in jToken.SelectTokens($"..{fieldName}"))
{
var prop = item as JValue;
- if (prop != null) prop.Value = null;
+ if (prop != null)
+ {
+ prop.Value = null;
+ }
}
}
@@ -146,7 +153,7 @@ static void ClearField(JToken jToken, string fieldName)
ClearField(jToken, "legalEntityStatusId");
}
- static JToken Cleanup(JToken jToken)
+ private static JToken Cleanup(JToken jToken)
{
// Sort
jToken["legalEntities"].SortArray("legalEntityId");
@@ -160,7 +167,8 @@ static JToken Cleanup(JToken jToken)
jToken.RemoveEmptyArrays();
// Fix mismatch in version, convert to string
- jToken.ReplacePath("$..legalEntities..participations..brands..endpoint..version",
+ jToken.ReplacePath(
+ "$..legalEntities..participations..brands..endpoint..version",
t => $"{t}");
// Issues with Guids and property names having different cases... not ideal, but just convert to upper case
@@ -205,11 +213,13 @@ public async Task AC07_AC08_Get_ThenPostUpdatedData_ShouldRespondWith_200OK_Retu
static void UpdateNames(JToken jToken)
{
if (jToken["legalEntities"] != null)
+ {
foreach (var legalEntity in jToken["legalEntities"])
{
legalEntity["legalEntityName"] += " updated";
if (legalEntity["participations"] != null)
+ {
foreach (var participation in legalEntity["participations"])
{
foreach (var brand in participation["brands"])
@@ -217,13 +227,17 @@ static void UpdateNames(JToken jToken)
brand["brandName"] += " updated";
if (brand["softwareProducts"] != null)
+ {
foreach (var softwareProduct in brand["softwareProducts"])
{
softwareProduct["softwareProductName"] += " updated";
}
+ }
}
}
+ }
}
+ }
}
// Arrange
diff --git a/Source/CDR.Register.IntegrationTests/Miscellaneous/US50483_DynamicUrl_Tests.cs b/Source/CDR.Register.IntegrationTests/Miscellaneous/US50483_DynamicUrl_Tests.cs
index 33be5b9..55b293d 100644
--- a/Source/CDR.Register.IntegrationTests/Miscellaneous/US50483_DynamicUrl_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/Miscellaneous/US50483_DynamicUrl_Tests.cs
@@ -17,7 +17,10 @@ namespace CDR.Register.IntegrationTests.Miscellaneous
{
public class US50483_DynamicUrl_Tests : BaseTest
{
- public US50483_DynamicUrl_Tests(ITestOutputHelper outputHelper, TestFixture testFixture) : base(outputHelper, testFixture) { }
+ public US50483_DynamicUrl_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
private const string DEFAULT_SOFTWAREPRODUCT_ID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
@@ -45,9 +48,8 @@ public async Task AC01_Get_Data_Holder_Brands_Invalid_Certificate_Header_For_Acc
CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME
}.GetAsync(addCertificateToRequest: false);
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
-
HttpMethod = HttpMethod.Get,
URL = getDataholderBrandsUrl,
AccessToken = accessToken,
@@ -63,7 +65,6 @@ public async Task AC01_Get_Data_Holder_Brands_Invalid_Certificate_Header_For_Acc
// Assert
await VerifyInvalidTokenRepsonse(response);
-
}
[Trait("Category", "CTSONLY")]
@@ -72,7 +73,6 @@ public async Task AC01_Get_Data_Holder_Brands_Invalid_Certificate_Header_For_Acc
[InlineData("Missing Certificate Thumbprint", "", DEFAULT_CERTIFICATE_COMMON_NAME)]
public async Task AC02_Get_Access_Token_Invalid_Certificate_Header_For_Access_Token(string testDescription, string certificateThumbPrint, string certificateCommonName)
{
-
Log.Information("Executing test for {TestDescription}.\nCertificate ThumbPrint: {CertificateThumbPrint}.\nCertificateCommonName: {CertificateCommonName}", testDescription, certificateThumbPrint, certificateCommonName);
// Arrange
@@ -96,11 +96,9 @@ public async Task AC02_Get_Access_Token_Invalid_Certificate_Header_For_Access_To
// Assert
using (new AssertionScope())
{
-
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
await Assert_HasContent_Json(@"{""error"":""invalid_client"",""error_description"":""Client certificate validation failed""}", response.Content);
-
}
}
@@ -108,9 +106,8 @@ public async Task AC02_Get_Access_Token_Invalid_Certificate_Header_For_Access_To
[Fact]
public async Task AC03_Get_Access_Token_Invalid_Url_Regular_Expression_For_Access_Token()
{
-
string tokenEndpoint = $"{IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL}/foo/idp/connect/token";
-
+
// Arrange - Get access token
var accessToken = new AccessToken
{
@@ -127,13 +124,12 @@ public async Task AC03_Get_Access_Token_Invalid_Url_Regular_Expression_For_Acces
// Assert
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
-
}
[Trait("Category", "CTSONLY")]
- [Fact]
+ [Fact]
public async Task AC04_Get_Data_Holder_Brands_Invalid_Access_Token_Issuer()
- {
+ {
// Arrange
string conformanceId = Guid.NewGuid().ToString();
string mismatachedConformanceId = Guid.NewGuid().ToString();
@@ -152,9 +148,8 @@ public async Task AC04_Get_Data_Holder_Brands_Invalid_Access_Token_Issuer()
CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME
}.GetAsync(addCertificateToRequest: false);
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
-
HttpMethod = HttpMethod.Get,
URL = getDataholderBrandsUrl,
AccessToken = accessToken,
@@ -170,14 +165,12 @@ public async Task AC04_Get_Data_Holder_Brands_Invalid_Access_Token_Issuer()
// Assert
await VerifyInvalidTokenRepsonse(response);
-
}
private static async Task VerifyInvalidTokenRepsonse(HttpResponseMessage response)
{
using (new AssertionScope())
{
-
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
ExpectedErrors expectedErrors = new ExpectedErrors();
@@ -186,20 +179,17 @@ private static async Task VerifyInvalidTokenRepsonse(HttpResponseMessage respons
string actualErrors = await response.Content.ReadAsStringAsync();
Assert_Json(GetJsonFromModel(expectedErrors), actualErrors);
-
}
}
[Trait("Category", "CTSONLY")]
[Theory]
- [InlineData("Both Header and Database using only Common Name", DEFAULT_CERTIFICATE_THUMBPRINT, "Test Common Name", "Test Common Name")]
- [InlineData("Both Header and Database using Full Distinguished Name", DEFAULT_CERTIFICATE_THUMBPRINT, "CN=TestCommonName1,O=Test Org,OU=Test Org Unit,C=AU", "CN=TestCommonName1,O=Test Org,OU=Test Org Unit,C=AU")]
- [InlineData("Header using only Common Name and Database using Full Distinguished Name", DEFAULT_CERTIFICATE_THUMBPRINT, "Test Common Name 2", "CN=Test Common Name 2,O=Test Org,OU=Test Org Unit,C=AU")]
- [InlineData("Header using Full Distinguished Name and Database using only Common Name", DEFAULT_CERTIFICATE_THUMBPRINT, "CN=Test Common Name 3,O=Test Org,OU=Test Org Unit,C=AU", "Test Common Name 3")]
-
+ [InlineData("Both Header and Database using only Common Name", DEFAULT_CERTIFICATE_THUMBPRINT, "Test Common Name", "Test Common Name")]
+ [InlineData("Both Header and Database using Full Distinguished Name", DEFAULT_CERTIFICATE_THUMBPRINT, "CN=TestCommonName1,O=Test Org,OU=Test Org Unit,C=AU", "CN=TestCommonName1,O=Test Org,OU=Test Org Unit,C=AU")]
+ [InlineData("Header using only Common Name and Database using Full Distinguished Name", DEFAULT_CERTIFICATE_THUMBPRINT, "Test Common Name 2", "CN=Test Common Name 2,O=Test Org,OU=Test Org Unit,C=AU")]
+ [InlineData("Header using Full Distinguished Name and Database using only Common Name", DEFAULT_CERTIFICATE_THUMBPRINT, "CN=Test Common Name 3,O=Test Org,OU=Test Org Unit,C=AU", "Test Common Name 3")]
public async Task AC05_Get_Access_Token_With_Valid_Certificate_Header(string testDescription, string certificateThumbPrint, string certificateCommonName, string dbCommonName)
{
-
Log.Information("Executing test for {TestDescription}.\nCertificate ThumbPrint: {CertThumbPrint}.\nCertificateCommonName: {CertCommonName}.\nDatabase Common Name: {DbCommonName}.", testDescription, certificateThumbPrint, certificateCommonName, dbCommonName);
// Arrange
@@ -229,9 +219,8 @@ public async Task AC05_Get_Access_Token_With_Valid_Certificate_Header(string tes
// Send request to get Data Holders to ensure Access token works.
string validAccessToken = await accessToken.GetAsync();
- var api = new Infrastructure.API
+ var api = new Infrastructure.Api
{
-
HttpMethod = HttpMethod.Get,
URL = getDataholderBrandsUrl,
AccessToken = validAccessToken,
@@ -246,7 +235,6 @@ public async Task AC05_Get_Access_Token_With_Valid_Certificate_Header(string tes
Log.Information("Response from {GetDataholderBrandsUrl} Endpoint: {StatusCode} \n{Content}", getDataholderBrandsUrl, accessTokenResponse.StatusCode, await accessTokenResponse.Content.ReadAsStringAsync());
getDataHolderResponse.StatusCode.Should().Be(HttpStatusCode.OK, because: $"Get Data Holder should work when{testDescription}");
-
}
private static void SetCertificateCommonName(string softwareProductId, string commonName)
@@ -267,10 +255,7 @@ private static void SetCertificateCommonName(string softwareProductId, string co
if (selectCommand.ExecuteScalarInt32() == 0)
{
throw new Exception($"Common name was not updated for Software Product: {softwareProductId}");
- };
+ }
}
-
-
-
}
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/AccessToken.cs b/Source/CDR.Register.IntegrationTests/Models/AccessToken.cs
index 2e2efaf..8756cd1 100644
--- a/Source/CDR.Register.IntegrationTests/Models/AccessToken.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/AccessToken.cs
@@ -1,15 +1,16 @@
-using System.Collections.Generic;
-
-namespace CDR.Register.IntegrationTests.Models
+namespace CDR.Register.IntegrationTests.Models
{
///
- /// Access token
+ /// Access token.
///
public class AccessToken
{
public string access_token { get; set; }
+
public int expires_in { get; set; }
+
public string token_type { get; set; }
+
public string scope { get; set; }
}
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs b/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
index d888f0a..284ec98 100644
--- a/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
@@ -5,8 +5,6 @@ namespace CDR.Register.IntegrationTests.Models
{
public class DataHolderMetadata
{
-
-
[JsonProperty("dataHolderBrandId")]
public string DataHolderBrandId { get; set; }
@@ -98,7 +96,6 @@ public class LegalEntityChild
[JsonProperty("status")]
public string Status { get; set; }
- }
-
+ }
}
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/DataRecipientMetadata.cs b/Source/CDR.Register.IntegrationTests/Models/DataRecipientMetadata.cs
index 1731c0f..3206879 100644
--- a/Source/CDR.Register.IntegrationTests/Models/DataRecipientMetadata.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/DataRecipientMetadata.cs
@@ -124,7 +124,5 @@ public class SoftwareProduct
[JsonProperty("certificates")]
public List Certificates { get; set; }
}
-
-
}
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/ExpectedApiErrors.cs b/Source/CDR.Register.IntegrationTests/Models/ExpectedApiErrors.cs
index 02e9cf8..cb4aecd 100644
--- a/Source/CDR.Register.IntegrationTests/Models/ExpectedApiErrors.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/ExpectedApiErrors.cs
@@ -1,11 +1,9 @@
using Newtonsoft.Json;
-using System.Collections.Generic;
namespace CDR.Register.IntegrationTests.Models
{
public class ExpectedApiErrors
{
-
[JsonProperty("code")]
public string Code { get; set; }
@@ -17,11 +15,10 @@ public class ExpectedApiErrors
[JsonProperty("meta")]
public MetaData Meta { get; set; }
-
+
public class MetaData
{
+ // This is to get a empty JSON object
}
-
}
-
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/ExpectedDataRecipients.cs b/Source/CDR.Register.IntegrationTests/Models/ExpectedDataRecipients.cs
index 1731c56..4566a09 100644
--- a/Source/CDR.Register.IntegrationTests/Models/ExpectedDataRecipients.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/ExpectedDataRecipients.cs
@@ -14,7 +14,7 @@ public ExpectedDataRecipients()
[JsonProperty("data")]
public List Data { get; set; }
}
-
+
public class ExpectedDataRecipients_V2
{
public ExpectedDataRecipients_V2()
@@ -30,7 +30,7 @@ public class DataRecipient
{
public DataRecipient()
{
- DataRecipientBrands = new List();
+ DataRecipientBrands = new List();
}
[JsonProperty("accreditationNumber")]
@@ -62,7 +62,7 @@ public class DataRecipient_V2
{
public DataRecipient_V2()
{
- DataRecipientBrands = new List();
+ DataRecipientBrands = new List();
}
[JsonProperty("accreditationNumber")]
@@ -89,12 +89,12 @@ public DataRecipient_V2()
[JsonProperty("lastUpdated")]
public DateTime LastUpdated { get; set; }
}
-
+
public class DataRecipientBrand
{
public DataRecipientBrand()
{
- SoftwareProducts = new List();
+ SoftwareProducts = new List();
}
[JsonProperty("dataRecipientBrandId")]
@@ -112,7 +112,7 @@ public DataRecipientBrand()
[JsonProperty("status")]
public string Status { get; set; }
}
-
+
public class SoftwareProduct
{
[JsonProperty("softwareProductId")]
@@ -142,4 +142,4 @@ public class SoftwareProduct
[JsonProperty("status")]
public string Status { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.IntegrationTests/TemporalTables/US29068_TemporalTableTests.cs b/Source/CDR.Register.IntegrationTests/TemporalTables/US29068_TemporalTableTests.cs
index 8d65c39..e3b7666 100644
--- a/Source/CDR.Register.IntegrationTests/TemporalTables/US29068_TemporalTableTests.cs
+++ b/Source/CDR.Register.IntegrationTests/TemporalTables/US29068_TemporalTableTests.cs
@@ -1,167 +1,22 @@
// #define DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Dapper;
+using Dapper.Contrib.Extensions;
using FluentAssertions;
using FluentAssertions.Execution;
+using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
-using System;
-using System.Threading.Tasks;
using Xunit;
-using Dapper;
-using Microsoft.Data.SqlClient;
-using System.Collections.Generic;
-using Dapper.Contrib.Extensions;
-using System.IO;
#nullable enable
namespace CDR.Register.IntegrationTests.TemporalTables
{
- [Table("LegalEntity")]
- class LegalEntity
- {
- [ExplicitKey]
- public Guid LegalEntityId { get; set; } = Guid.NewGuid();
- public string? LegalEntityName { get; set; } = "foo";
- public string? LogoUri { get; set; } = "foo";
- }
-
- [Table("Participation")]
- class Participation
- {
- [ExplicitKey]
- public Guid ParticipationId { get; set; } = Guid.NewGuid();
- public Guid? LegalEntityId { get; set; }
- public int? ParticipationTypeId { get; set; } = 1;
- public int? IndustryId { get; set; } = 1;
- public int? StatusId { get; set; } = 1;
- }
-
- [Table("Brand")]
- class Brand
- {
- [ExplicitKey]
- public Guid BrandId { get; set; } = Guid.NewGuid();
- public string? BrandName { get; set; } = "foo";
- public string? LogoUri { get; set; } = "foo";
- public int? BrandStatusId { get; set; } = 1;
- public Guid? ParticipationId { get; set; }
- public DateTime? LastUpdated { get; set; } = DateTime.Now;
- }
-
- [Table("AuthDetail")]
- class AuthDetail
- {
- [ExplicitKey]
- public Guid BrandId { get; set; }
- public int? RegisterUTypeId { get; set; } = 1;
- public string? JwksEndpoint { get; set; } = "foo";
- }
-
- [Table("Endpoint")]
- class Endpoint
- {
- [ExplicitKey]
- public Guid BrandId { get; set; }
- public string? Version { get; set; } = "foo";
- public string? PublicBaseUri { get; set; } = "foo";
- public string? ResourceBaseUri { get; set; } = "foo";
- public string? InfosecBaseUri { get; set; } = "foo";
- public string? ExtensionBaseUri { get; set; } = "foo";
- public string? WebsiteUri { get; set; } = "foo";
- }
-
- [Table("SoftwareProduct")]
- class SoftwareProduct
- {
- [ExplicitKey]
- public Guid SoftwareProductId { get; set; } = Guid.NewGuid();
- public string? SoftwareProductName { get; set; } = "foo";
- public string? SoftwareProductDescription { get; set; } = "foo";
- public string? LogoUri { get; set; } = "foo";
- public string? SectorIdentifierUri { get; set; } = "foo";
- public string? ClientUri { get; set; } = "foo";
- public string? TosUri { get; set; } = "foo";
- public string? PolicyUri { get; set; } = "foo";
- public string? RecipientBaseUri { get; set; } = "foo";
- public string? RevocationUri { get; set; } = "foo";
- public string? RedirectUris { get; set; } = "foo";
- public string? JwksUri { get; set; } = "foo";
- public string? Scope { get; set; } = "foo";
- public int? StatusId { get; set; } = 1;
- public Guid? BrandId { get; set; }
- }
-
- [Table("SoftwareProductCertificate")]
- class SoftwareProductCertificate
- {
- [ExplicitKey]
- public Guid SoftwareProductCertificateId { get; set; } = Guid.NewGuid();
- public Guid SoftwareProductId { get; set; }
- public string? CommonName { get; set; } = "foo";
- public string? Thumbprint { get; set; } = "foo";
- }
-
- [Table("ParticipationStatus")]
- class ParticipationStatus
- {
- [ExplicitKey]
- public int? ParticipationStatusId { get; set; }
- public string? ParticipationStatusCode { get; set; }
- }
-
- static class DatabaseSeeder
- {
- static private async Task Purge(SqlConnection connection)
- {
- static async Task PurgeTable(SqlConnection connection, string tableName, bool temporal = true)
- {
- // Delete data
- await connection.ExecuteAsync($"delete {tableName}");
-
- // Now cleanup temporal data too
- if (temporal)
- {
- await connection.ExecuteAsync($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = OFF)");
- await connection.ExecuteAsync($"DELETE FROM [{tableName}History]");
- await connection.ExecuteAsync($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{tableName}History], DATA_CONSISTENCY_CHECK = OFF))");
- }
- }
-
- await PurgeTable(connection, "SoftwareProductCertificate");
- await PurgeTable(connection, "SoftwareProduct");
- await PurgeTable(connection, "Endpoint");
- await PurgeTable(connection, "AuthDetail");
- await PurgeTable(connection, "Brand");
- await PurgeTable(connection, "Participation");
- await PurgeTable(connection, "LegalEntity");
-
- // purge lookup tables
- // await PurgeTable(connection, "AccreditationLevel", false);
- // await PurgeTable(connection, "BrandStatus", false);
- // await PurgeTable(connection, "IndustryType", false);
- // await PurgeTable(connection, "LegalEntityStatus", false);
- // await PurgeTable(connection, "OrganisationType", false);
- // await PurgeTable(connection, "ParticipationStatus", false);
- // await PurgeTable(connection, "ParticipationType", false);
- // await PurgeTable(connection, "RegisterUType", false);
- // await PurgeTable(connection, "SoftwareProductStatus", false);
- }
-
- static public async Task Execute()
- {
- using var connection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
- connection.Open();
-
- await Purge(connection);
- await TestFixture.Seeddata();
-
- await connection.ExecuteAsync("delete ParticipationStatus where ParticipationStatusId = -999");
- await connection.InsertAsync(new ParticipationStatus { ParticipationStatusId = -999, ParticipationStatusCode = "foo" });
- }
- }
-
- public class US29068_TemporalTables : BaseTest0
+ public class US29068_TemporalTableTests : BaseTest0
{
private static async Task GetTableJson(SqlConnection connection, string tableName, DateTime? pointInTimeUTC = null)
{
@@ -176,16 +31,16 @@ private static async Task GetTableJson(SqlConnection connection, string
string sql = @$"
select * from {tableName}
- {(pointInTimeUTC == null ? "" : $"for system_time as of '{pointInTimeUTC:yyyy-MM-dd HH:mm:ss.fffffff}'")}
+ {(pointInTimeUTC == null ? string.Empty : $"for system_time as of '{pointInTimeUTC:yyyy-MM-dd HH:mm:ss.fffffff}'")}
order by {orderby}";
data = await connection.QueryAsync(sql);
- // return JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
return JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings { });
}
- delegate Task Mutate(SqlConnection connection);
+ private delegate Task Mutate(SqlConnection connection);
+
private async Task Test(string tableName, Mutate mutate)
{
await Test(new string[] { tableName }, mutate);
@@ -197,7 +52,7 @@ private static async Task Test(string[] tableNames, Mutate mutate)
await DatabaseSeeder.Execute();
using var registerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
- registerConnection.Open();
+ await registerConnection.OpenAsync();
var pointInTimeUTC = DateTime.UtcNow;
@@ -213,6 +68,7 @@ private static async Task Test(string[] tableNames, Mutate mutate)
{
await mutate(registerConnection);
}
+
var modifiedData = new Dictionary();
foreach (string tableName in tableNames)
{
@@ -251,12 +107,12 @@ private static async Task Test(string[] tableNames, Mutate mutate)
}
}
+ // [InlineData("AuthDetail")] // One-to-one for brand, ie can't insert another row for existing brand
+ // [InlineData("Endpoint")] // One-to-one for brand, ie can't insert another row for existing brand
[Theory]
[InlineData("LegalEntity")]
[InlineData("Participation")]
[InlineData("Brand")]
- // [InlineData("AuthDetail")] // One-to-one for brand, ie can't insert another row for existing brand
- // [InlineData("Endpoint")] // One-to-one for brand, ie can't insert another row for existing brand
[InlineData("SoftwareProduct")]
[InlineData("SoftwareProductCertificate")]
public async Task ACX01_AfterInsertingRecord_PointInTimeQueryShouldNotReturnInsertedRecord(string tableName)
@@ -268,27 +124,27 @@ await Test(tableName, async (connection) =>
"LegalEntity" => connection.InsertAsync(new LegalEntity()),
"Participation" => connection.InsertAsync(new Participation()
{
- LegalEntityId = connection.ExecuteScalar("select top 1 legalentityid from legalentity")
+ LegalEntityId = await connection.ExecuteScalarAsync("select top 1 legalentityid from legalentity")
}),
"Brand" => connection.InsertAsync(new Brand()
{
- ParticipationId = connection.ExecuteScalar("select top 1 participationid from participation")
+ ParticipationId = await connection.ExecuteScalarAsync("select top 1 participationid from participation")
}),
"AuthDetail" => connection.InsertAsync(new AuthDetail()
{
- BrandId = connection.ExecuteScalar("select top 1 brandid from brand")
+ BrandId = await connection.ExecuteScalarAsync("select top 1 brandid from brand")
}),
"Endpoint" => connection.InsertAsync(new Endpoint()
{
- BrandId = connection.ExecuteScalar("select top 1 brandid from brand")
+ BrandId = await connection.ExecuteScalarAsync("select top 1 brandid from brand")
}),
"SoftwareProduct" => connection.InsertAsync(new SoftwareProduct()
{
- BrandId = connection.ExecuteScalar("select top 1 brandid from brand")
+ BrandId = await connection.ExecuteScalarAsync("select top 1 brandid from brand")
}),
"SoftwareProductCertificate" => connection.InsertAsync(new SoftwareProductCertificate()
{
- SoftwareProductId = connection.ExecuteScalar("select top 1 softwareProductid from softwareProduct")
+ SoftwareProductId = await connection.ExecuteScalarAsync("select top 1 softwareProductid from softwareProduct")
}),
_ => throw new NotSupportedException()
};
@@ -296,67 +152,6 @@ await Test(tableName, async (connection) =>
});
}
-// FIXME - MJS - These tests fail randomly in pipeline, sometimes they work, other times not.
-/*
- [Theory]
- [InlineData("LegalEntity")]
- [InlineData("Participation")]
- [InlineData("Brand")]
- [InlineData("AuthDetail")]
- [InlineData("Endpoint")]
- [InlineData("SoftwareProduct")]
- [InlineData("SoftwareProductCertificate")]
- public async Task ACX02_AfterUpdatingRecord_PointInTimeQueryShouldNotReturnUpdatedRecord(string tableName)
- {
- await Test(tableName, async (connection) =>
- {
- var update = tableName switch
- {
- "LegalEntity" => connection.ExecuteAsync("update LegalEntity set LegalEntityName = @LegalEntityName where LegalEntityId = @LegalEntityId",
- new
- {
- LegalEntityId = await connection.ExecuteScalarAsync("select top 1 LegalEntityId from LegalEntity"),
- LegalEntityName = Guid.NewGuid().ToString()
- }),
- "Participation" => connection.ExecuteAsync("update Participation set StatusId = -999 where ParticipationId = @ParticipationId",
- new { ParticipationId = await connection.ExecuteScalarAsync("select top 1 ParticipationId from Participation") }),
- "Brand" => connection.ExecuteAsync("update Brand set BrandName = @BrandName where BrandId = @BrandId",
- new
- {
- BrandId = await connection.ExecuteScalarAsync("select top 1 BrandId from Brand"),
- BrandName = Guid.NewGuid().ToString()
- }),
- "AuthDetail" => connection.ExecuteAsync("update AuthDetail set JwksEndpoint = @JwksEndpoint where BrandId = @BrandId",
- new
- {
- BrandId = await connection.ExecuteScalarAsync("select top 1 BrandId from Brand"),
- JwksEndpoint = Guid.NewGuid().ToString()
- }),
- "Endpoint" => connection.ExecuteAsync("update Endpoint set PublicBaseUri = @PublicBaseUri where BrandId = @BrandId",
- new
- {
- BrandId = await connection.ExecuteScalarAsync("select top 1 BrandId from Brand"),
- PublicBaseUri = Guid.NewGuid().ToString()
- }),
- "SoftwareProduct" => connection.ExecuteAsync("update SoftwareProduct set SoftwareProductName = @SoftwareProductName where SoftwareProductId = @SoftwareProductId",
- new
- {
- SoftwareProductId = await connection.ExecuteScalarAsync("select top 1 SoftwareProductId from SoftwareProduct"),
- SoftwareProductName = Guid.NewGuid().ToString()
- }),
- "SoftwareProductCertificate" => connection.ExecuteAsync("update SoftwareProductCertificate set CommonName = @CommonName where SoftwareProductCertificateId = @SoftwareProductCertificateId",
- new
- {
- SoftwareProductCertificateId = await connection.ExecuteScalarAsync("select top 1 SoftwareProductCertificateId from SoftwareProductCertificate"),
- CommonName = Guid.NewGuid().ToString()
- }),
- _ => throw new NotSupportedException()
- };
- await update;
- });
- }
-*/
-
[Fact]
public async Task ACX03_AfterDeletingRecords_PointInTimeQueryShouldReturnDeletedRecords()
{
@@ -374,4 +169,174 @@ await Test(
});
}
}
+
+ [Table("LegalEntity")]
+ internal class LegalEntity
+ {
+ [ExplicitKey]
+ public Guid LegalEntityId { get; set; } = Guid.NewGuid();
+
+ public string? LegalEntityName { get; set; } = "foo";
+
+ public string? LogoUri { get; set; } = "foo";
+ }
+
+ [Table("Participation")]
+ internal class Participation
+ {
+ [ExplicitKey]
+ public Guid ParticipationId { get; set; } = Guid.NewGuid();
+
+ public Guid? LegalEntityId { get; set; }
+
+ public int? ParticipationTypeId { get; set; } = 1;
+
+ public int? IndustryId { get; set; } = 1;
+
+ public int? StatusId { get; set; } = 1;
+ }
+
+ [Table("Brand")]
+ internal class Brand
+ {
+ [ExplicitKey]
+ public Guid BrandId { get; set; } = Guid.NewGuid();
+
+ public string? BrandName { get; set; } = "foo";
+
+ public string? LogoUri { get; set; } = "foo";
+
+ public int? BrandStatusId { get; set; } = 1;
+
+ public Guid? ParticipationId { get; set; }
+
+ public DateTime? LastUpdated { get; set; } = DateTime.Now;
+ }
+
+ [Table("AuthDetail")]
+ internal class AuthDetail
+ {
+ [ExplicitKey]
+ public Guid BrandId { get; set; }
+
+ public int? RegisterUTypeId { get; set; } = 1;
+
+ public string? JwksEndpoint { get; set; } = "foo";
+ }
+
+ [Table("Endpoint")]
+ internal class Endpoint
+ {
+ [ExplicitKey]
+ public Guid BrandId { get; set; }
+
+ public string? Version { get; set; } = "foo";
+
+ public string? PublicBaseUri { get; set; } = "foo";
+
+ public string? ResourceBaseUri { get; set; } = "foo";
+
+ public string? InfosecBaseUri { get; set; } = "foo";
+
+ public string? ExtensionBaseUri { get; set; } = "foo";
+
+ public string? WebsiteUri { get; set; } = "foo";
+ }
+
+ [Table("SoftwareProduct")]
+ internal class SoftwareProduct
+ {
+ [ExplicitKey]
+ public Guid SoftwareProductId { get; set; } = Guid.NewGuid();
+
+ public string? SoftwareProductName { get; set; } = "foo";
+
+ public string? SoftwareProductDescription { get; set; } = "foo";
+
+ public string? LogoUri { get; set; } = "foo";
+
+ public string? SectorIdentifierUri { get; set; } = "foo";
+
+ public string? ClientUri { get; set; } = "foo";
+
+ public string? TosUri { get; set; } = "foo";
+
+ public string? PolicyUri { get; set; } = "foo";
+
+ public string? RecipientBaseUri { get; set; } = "foo";
+
+ public string? RevocationUri { get; set; } = "foo";
+
+ public string? RedirectUris { get; set; } = "foo";
+
+ public string? JwksUri { get; set; } = "foo";
+
+ public string? Scope { get; set; } = "foo";
+
+ public int? StatusId { get; set; } = 1;
+
+ public Guid? BrandId { get; set; }
+ }
+
+ [Table("SoftwareProductCertificate")]
+ internal class SoftwareProductCertificate
+ {
+ [ExplicitKey]
+ public Guid SoftwareProductCertificateId { get; set; } = Guid.NewGuid();
+
+ public Guid SoftwareProductId { get; set; }
+
+ public string? CommonName { get; set; } = "foo";
+
+ public string? Thumbprint { get; set; } = "foo";
+ }
+
+ [Table("ParticipationStatus")]
+ internal class ParticipationStatus
+ {
+ [ExplicitKey]
+ public int? ParticipationStatusId { get; set; }
+
+ public string? ParticipationStatusCode { get; set; }
+ }
+
+ internal static class DatabaseSeeder
+ {
+ private static async Task Purge(SqlConnection connection)
+ {
+ static async Task PurgeTable(SqlConnection connection, string tableName, bool temporal = true)
+ {
+ // Delete data
+ await connection.ExecuteAsync($"delete {tableName}");
+
+ // Now cleanup temporal data too
+ if (temporal)
+ {
+ await connection.ExecuteAsync($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = OFF)");
+ await connection.ExecuteAsync($"DELETE FROM [{tableName}History]");
+ await connection.ExecuteAsync($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{tableName}History], DATA_CONSISTENCY_CHECK = OFF))");
+ }
+ }
+
+ await PurgeTable(connection, "SoftwareProductCertificate");
+ await PurgeTable(connection, "SoftwareProduct");
+ await PurgeTable(connection, "Endpoint");
+ await PurgeTable(connection, "AuthDetail");
+ await PurgeTable(connection, "Brand");
+ await PurgeTable(connection, "Participation");
+ await PurgeTable(connection, "LegalEntity");
+ }
+
+ public static async Task Execute()
+ {
+ using var connection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
+ await connection.OpenAsync();
+
+ await Purge(connection);
+ await TestFixture.Seeddata();
+
+ await connection.ExecuteAsync("delete ParticipationStatus where ParticipationStatusId = -999");
+ await connection.InsertAsync(new ParticipationStatus { ParticipationStatusId = -999, ParticipationStatusCode = "foo" });
+ }
+ }
}
diff --git a/Source/CDR.Register.IntegrationTests/XUnit/AlphabeticalOrderer.cs b/Source/CDR.Register.IntegrationTests/XUnit/AlphabeticalOrderer.cs
index 94fb520..345f8be 100644
--- a/Source/CDR.Register.IntegrationTests/XUnit/AlphabeticalOrderer.cs
+++ b/Source/CDR.Register.IntegrationTests/XUnit/AlphabeticalOrderer.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
@@ -7,7 +7,7 @@ namespace CDR.Register.IntegrationTests.XUnit.Orderers
{
public class AlphabeticalOrderer : ITestCaseOrderer
{
- public IEnumerable OrderTestCases(IEnumerable testCases) where TTestCase : ITestCase =>
- testCases.OrderBy(testCase => testCase.TestMethod.Method.Name);
+ public IEnumerable OrderTestCases(IEnumerable testCases)
+ where TTestCase : ITestCase => testCases.OrderBy(testCase => testCase.TestMethod.Method.Name);
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/CDR.Register.Repository.csproj b/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
index a43a3d0..de7bde9 100644
--- a/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
+++ b/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
@@ -4,6 +4,7 @@
$(Version)
$(Version)
$(Version)
+ true
@@ -13,7 +14,7 @@
-
+
all
@@ -24,8 +25,16 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.Repository/Entities/AccreditationLevel.cs b/Source/CDR.Register.Repository/Entities/AccreditationLevel.cs
index d592cfe..92f6335 100644
--- a/Source/CDR.Register.Repository/Entities/AccreditationLevel.cs
+++ b/Source/CDR.Register.Repository/Entities/AccreditationLevel.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel.DataAnnotations;
namespace CDR.Register.Repository.Entities
{
@@ -12,14 +7,15 @@ public class AccreditationLevel
[Key]
public AccreditationLevelType AccreditationLevelId { get; set; }
- [MaxLength(100), Required]
+ [MaxLength(100)]
+ [Required]
public string AccreditationLevelCode { get; set; }
}
public enum AccreditationLevelType
{
- //Sponsored by Default
- Sponsored = 0,
+ // Sponsored by Default
+ Sponsored = 0,
Unrestricted = 1
}
}
diff --git a/Source/CDR.Register.Repository/Entities/AuthDetail.cs b/Source/CDR.Register.Repository/Entities/AuthDetail.cs
index 83b720e..1f76a02 100644
--- a/Source/CDR.Register.Repository/Entities/AuthDetail.cs
+++ b/Source/CDR.Register.Repository/Entities/AuthDetail.cs
@@ -6,10 +6,15 @@ namespace CDR.Register.Repository.Entities
public class AuthDetail
{
public Guid BrandId { get; set; }
+
public Brand Brand { get; set; }
+
public RegisterUTypes RegisterUTypeId { get; set; }
+
public RegisterUType RegisterUType { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
public string JwksEndpoint { get; set; }
}
}
diff --git a/Source/CDR.Register.Repository/Entities/Brand.cs b/Source/CDR.Register.Repository/Entities/Brand.cs
index c714c0e..6e46d8f 100644
--- a/Source/CDR.Register.Repository/Entities/Brand.cs
+++ b/Source/CDR.Register.Repository/Entities/Brand.cs
@@ -13,18 +13,30 @@ public Brand()
[Key]
public Guid BrandId { get; set; }
- [MaxLength(200), Required]
+
+ [MaxLength(200)]
+ [Required]
public string BrandName { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
+
public string LogoUri { get; set; }
+
public BrandStatusType BrandStatusId { get; set; }
+
public BrandStatus BrandStatus { get; set; }
+
public Guid ParticipationId { get; set; }
+
public Participation Participation { get; set; }
+
public DateTime LastUpdated { get; set; }
public virtual ICollection SoftwareProducts { get; set; }
+
public virtual ICollection AuthDetails { get; set; }
+
public virtual Endpoint Endpoint { get; set; }
}
}
diff --git a/Source/CDR.Register.Repository/Entities/BrandStatus.cs b/Source/CDR.Register.Repository/Entities/BrandStatus.cs
index 399b835..661e319 100644
--- a/Source/CDR.Register.Repository/Entities/BrandStatus.cs
+++ b/Source/CDR.Register.Repository/Entities/BrandStatus.cs
@@ -1,21 +1,22 @@
-using System;
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
namespace CDR.Register.Repository.Entities
{
- public class BrandStatus
- {
- [Key]
- public BrandStatusType BrandStatusId { get; set; }
- [MaxLength(25), Required]
- public string BrandStatusCode { get; set; }
- }
+ public class BrandStatus
+ {
+ [Key]
+ public BrandStatusType BrandStatusId { get; set; }
- public enum BrandStatusType
- {
- Unknown = 0,
- Active = 1,
- Inactive = 2,
- Removed = 3
- }
-}
\ No newline at end of file
+ [MaxLength(25)]
+ [Required]
+ public string BrandStatusCode { get; set; }
+ }
+
+ public enum BrandStatusType
+ {
+ Unknown = 0,
+ Active = 1,
+ Inactive = 2,
+ Removed = 3
+ }
+}
diff --git a/Source/CDR.Register.Repository/Entities/Endpoint.cs b/Source/CDR.Register.Repository/Entities/Endpoint.cs
index 7821da1..8cb0838 100644
--- a/Source/CDR.Register.Repository/Entities/Endpoint.cs
+++ b/Source/CDR.Register.Repository/Entities/Endpoint.cs
@@ -9,19 +9,30 @@ public class Endpoint
[Key]
[ForeignKey("Brand")]
public Guid BrandId { get; set; }
- [MaxLength(25), Required]
+
+ [MaxLength(25)]
+ [Required]
public string Version { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
public string PublicBaseUri { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
public string ResourceBaseUri { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
public string InfosecBaseUri { get; set; }
+
[MaxLength(1000)]
public string ExtensionBaseUri { get; set; }
- [MaxLength(1000), Required]
+
+ [MaxLength(1000)]
+ [Required]
public string WebsiteUri { get; set; }
- public virtual Brand Brand { get; set; }
+ public virtual Brand Brand { get; set; }
}
}
diff --git a/Source/CDR.Register.Repository/Entities/Enumerations.cs b/Source/CDR.Register.Repository/Entities/Enumerations.cs
index b5afb0a..5d50c16 100644
--- a/Source/CDR.Register.Repository/Entities/Enumerations.cs
+++ b/Source/CDR.Register.Repository/Entities/Enumerations.cs
@@ -21,7 +21,7 @@ public enum OrganisationType
public enum AccreditationLevel
{
- //Sponsored by Default
+ // Sponsored by Default
Sponsored = 0,
Unrestricted = 1
}
@@ -60,7 +60,7 @@ public enum ParticipationType
public enum RegisterUType
{
- Unknown = 0,
+ Unknown = 0,
SignedJwt = 1
}
diff --git a/Source/CDR.Register.Repository/Entities/IndustryType.cs b/Source/CDR.Register.Repository/Entities/IndustryType.cs
index 1248df3..ac5533e 100644
--- a/Source/CDR.Register.Repository/Entities/IndustryType.cs
+++ b/Source/CDR.Register.Repository/Entities/IndustryType.cs
@@ -8,7 +8,8 @@ public class IndustryType
[Key]
public Industry IndustryTypeId { get; set; }
- [MaxLength(25), Required]
+ [MaxLength(25)]
+ [Required]
public string IndustryTypeCode { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Entities/LegalEntity.cs b/Source/CDR.Register.Repository/Entities/LegalEntity.cs
index 6292ce0..3ccb294 100644
--- a/Source/CDR.Register.Repository/Entities/LegalEntity.cs
+++ b/Source/CDR.Register.Repository/Entities/LegalEntity.cs
@@ -14,10 +14,12 @@ public LegalEntity()
[Key]
public Guid LegalEntityId { get; set; }
- [MaxLength(200), Required]
+ [MaxLength(200)]
+ [Required]
public string LegalEntityName { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string LogoUri { get; set; }
[MaxLength(100)]
@@ -41,15 +43,16 @@ public LegalEntity()
public string AnzsicDivision { get; set; }
public OrganisationTypes? OrganisationTypeId { get; set; }
+
public OrganisationType OrganisationType { get; set; }
[MaxLength(100)]
public string AccreditationNumber { get; set; }
public AccreditationLevelType? AccreditationLevelId { get; set; }
+
public AccreditationLevel AccreditationLevel { get; set; }
public virtual ICollection Participations { get; set; }
-
}
}
diff --git a/Source/CDR.Register.Repository/Entities/OrganisationType.cs b/Source/CDR.Register.Repository/Entities/OrganisationType.cs
index 0433d45..75b3d5a 100644
--- a/Source/CDR.Register.Repository/Entities/OrganisationType.cs
+++ b/Source/CDR.Register.Repository/Entities/OrganisationType.cs
@@ -7,7 +7,8 @@ public class OrganisationType
[Key]
public OrganisationTypes OrganisationTypeId { get; set; }
- [MaxLength(100), Required]
+ [MaxLength(100)]
+ [Required]
public string OrganisationTypeCode { get; set; }
}
@@ -21,4 +22,4 @@ public enum OrganisationTypes
GovernmentEntity = 5,
Other = 6
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Entities/Participation.cs b/Source/CDR.Register.Repository/Entities/Participation.cs
index b18e7d6..b2dd679 100644
--- a/Source/CDR.Register.Repository/Entities/Participation.cs
+++ b/Source/CDR.Register.Repository/Entities/Participation.cs
@@ -16,15 +16,19 @@ public Participation()
public Guid ParticipationId { get; set; }
public Guid LegalEntityId { get; set; }
+
public LegalEntity LegalEntity { get; set; }
public ParticipationTypes ParticipationTypeId { get; set; }
+
public ParticipationType ParticipationType { get; set; }
public Industry? IndustryId { get; set; }
+
public IndustryType Industry { get; set; }
public ParticipationStatusType StatusId { get; set; }
+
public ParticipationStatus Status { get; set; }
public virtual ICollection Brands { get; set; }
diff --git a/Source/CDR.Register.Repository/Entities/ParticipationStatus.cs b/Source/CDR.Register.Repository/Entities/ParticipationStatus.cs
index 56559a8..96d7e2d 100644
--- a/Source/CDR.Register.Repository/Entities/ParticipationStatus.cs
+++ b/Source/CDR.Register.Repository/Entities/ParticipationStatus.cs
@@ -7,14 +7,15 @@ public class ParticipationStatus
[Key]
public ParticipationStatusType ParticipationStatusId { get; set; }
- [MaxLength(25), Required]
+ [MaxLength(25)]
+ [Required]
public string ParticipationStatusCode { get; set; }
///
/// Applicable participation types. If null or Unknown, it's available for all participation types.
///
- public ParticipationTypes? ParticipationTypeId { get; set; }
- }
+ public ParticipationTypes? ParticipationTypeId { get; set; }
+ }
public enum ParticipationStatusType
{
@@ -26,4 +27,4 @@ public enum ParticipationStatusType
Surrendered = 5,
Inactive = 6
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Entities/ParticipationType.cs b/Source/CDR.Register.Repository/Entities/ParticipationType.cs
index 2393e85..23866e6 100644
--- a/Source/CDR.Register.Repository/Entities/ParticipationType.cs
+++ b/Source/CDR.Register.Repository/Entities/ParticipationType.cs
@@ -7,7 +7,8 @@ public class ParticipationType
[Key]
public ParticipationTypes ParticipationTypeId { get; set; }
- [MaxLength(2), Required]
+ [MaxLength(2)]
+ [Required]
public string ParticipationTypeCode { get; set; }
}
@@ -17,4 +18,4 @@ public enum ParticipationTypes
Dh = 1,
Dr = 2
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Entities/RegisterUType.cs b/Source/CDR.Register.Repository/Entities/RegisterUType.cs
index c7e1239..1980d12 100644
--- a/Source/CDR.Register.Repository/Entities/RegisterUType.cs
+++ b/Source/CDR.Register.Repository/Entities/RegisterUType.cs
@@ -6,7 +6,9 @@ public class RegisterUType
{
[Key]
public RegisterUTypes RegisterUTypeId { get; set; }
- [MaxLength(25), Required]
+
+ [MaxLength(25)]
+ [Required]
public string RegisterUTypeCode { get; set; }
}
diff --git a/Source/CDR.Register.Repository/Entities/SoftwareProduct.cs b/Source/CDR.Register.Repository/Entities/SoftwareProduct.cs
index 27edab3..4746314 100644
--- a/Source/CDR.Register.Repository/Entities/SoftwareProduct.cs
+++ b/Source/CDR.Register.Repository/Entities/SoftwareProduct.cs
@@ -16,19 +16,22 @@ public SoftwareProduct()
[Key]
public Guid SoftwareProductId { get; set; }
- [MaxLength(200), Required]
+ [MaxLength(200)]
+ [Required]
public string SoftwareProductName { get; set; }
[MaxLength(4000)]
public string SoftwareProductDescription { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string LogoUri { get; set; }
[MaxLength(2048)]
public string SectorIdentifierUri { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string ClientUri { get; set; }
[MaxLength(1000)]
@@ -40,22 +43,28 @@ public SoftwareProduct()
[MaxLength(1000)]
public string RecipientBaseUri { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string RevocationUri { get; set; }
- [MaxLength(2000), Required]
+ [MaxLength(2000)]
+ [Required]
public string RedirectUris { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string JwksUri { get; set; }
- [MaxLength(1000), Required]
+ [MaxLength(1000)]
+ [Required]
public string Scope { get; set; }
public SoftwareProductStatusType StatusId { get; set; }
+
public SoftwareProductStatus Status { get; set; }
public Guid BrandId { get; set; }
+
public Brand Brand { get; set; }
public ICollection Certificates { get; set; }
diff --git a/Source/CDR.Register.Repository/Entities/SoftwareProductCertificate.cs b/Source/CDR.Register.Repository/Entities/SoftwareProductCertificate.cs
index 0a1b1f4..9e01798 100644
--- a/Source/CDR.Register.Repository/Entities/SoftwareProductCertificate.cs
+++ b/Source/CDR.Register.Repository/Entities/SoftwareProductCertificate.cs
@@ -12,10 +12,12 @@ public class SoftwareProductCertificate
public SoftwareProduct SoftwareProduct { get; set; }
- [MaxLength(2000), Required]
+ [MaxLength(2000)]
+ [Required]
public string CommonName { get; set; }
- [MaxLength(2000), Required]
+ [MaxLength(2000)]
+ [Required]
public string Thumbprint { get; set; }
}
}
diff --git a/Source/CDR.Register.Repository/Entities/SoftwareProductStatus.cs b/Source/CDR.Register.Repository/Entities/SoftwareProductStatus.cs
index f220fb2..5cd67a9 100644
--- a/Source/CDR.Register.Repository/Entities/SoftwareProductStatus.cs
+++ b/Source/CDR.Register.Repository/Entities/SoftwareProductStatus.cs
@@ -6,7 +6,9 @@ public class SoftwareProductStatus
{
[Key]
public SoftwareProductStatusType SoftwareProductStatusId { get; set; }
- [MaxLength(25), Required]
+
+ [MaxLength(25)]
+ [Required]
public string SoftwareProductStatusCode { get; set; }
}
@@ -17,4 +19,4 @@ public enum SoftwareProductStatusType
Inactive = 2,
Removed = 3
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/IRegisterAdminRepository.cs b/Source/CDR.Register.Repository/IRegisterAdminRepository.cs
index 9115f04..806b9a2 100644
--- a/Source/CDR.Register.Repository/IRegisterAdminRepository.cs
+++ b/Source/CDR.Register.Repository/IRegisterAdminRepository.cs
@@ -10,6 +10,7 @@ public interface IRegisterAdminRepository
Task GetDataHolderBrandAsync(Guid brandId);
public Task AddOrUpdateDataRecipient(DataRecipient dataRecipient);
+
Task SaveDataHolderBrand(Guid legalEntityId, DataHolderBrand dataHolderBrand);
}
}
diff --git a/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs b/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
index 0bf1297..971734f 100644
--- a/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
+++ b/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
@@ -1,6 +1,5 @@
using CDR.Register.Domain.Entities;
using CDR.Register.Domain.ValueObjects;
-using CDR.Register.Repository.Infrastructure;
using System;
using System.Threading.Tasks;
@@ -9,7 +8,9 @@ namespace CDR.Register.Repository.Interfaces
public interface IRegisterDiscoveryRepository
{
Task> GetDataHolderBrandsAsync(Infrastructure.Industry industry, DateTime? updatedSince, int page, int pageSize);
+
Task GetDataRecipientsAsync(Infrastructure.Industry industry);
+
Task GetSoftwareProductIdAsync(Guid softwareProductId);
}
}
diff --git a/Source/CDR.Register.Repository/IRegisterStatusRepository .cs b/Source/CDR.Register.Repository/IRegisterStatusRepository.cs
similarity index 91%
rename from Source/CDR.Register.Repository/IRegisterStatusRepository .cs
rename to Source/CDR.Register.Repository/IRegisterStatusRepository.cs
index 1fe6065..77e1377 100644
--- a/Source/CDR.Register.Repository/IRegisterStatusRepository .cs
+++ b/Source/CDR.Register.Repository/IRegisterStatusRepository.cs
@@ -1,5 +1,4 @@
using CDR.Register.Domain.Entities;
-using CDR.Register.Repository.Infrastructure;
using System.Threading.Tasks;
namespace CDR.Register.Repository.Interfaces
@@ -7,7 +6,9 @@ namespace CDR.Register.Repository.Interfaces
public interface IRegisterStatusRepository
{
Task GetDataRecipientStatusesAsync(Infrastructure.Industry industry);
+
Task GetSoftwareProductStatusesAsync(Infrastructure.Industry industry);
+
Task GetDataHolderStatusesAsync(Infrastructure.Industry industry);
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/IRepositoryMapper.cs b/Source/CDR.Register.Repository/IRepositoryMapper.cs
index f17bf96..35dd89d 100644
--- a/Source/CDR.Register.Repository/IRepositoryMapper.cs
+++ b/Source/CDR.Register.Repository/IRepositoryMapper.cs
@@ -5,16 +5,19 @@ namespace CDR.Register.Repository
public interface IRepositoryMapper
{
DataRecipientLegalEntity Map(Entities.LegalEntity legalEntity);
+
Entities.LegalEntity Map(DataRecipientLegalEntity legalEntity);
DataRecipientBrand Map(Entities.Brand brand);
+
Entities.Brand Map(DataRecipientBrand brand);
SoftwareProductInfosec Map(Entities.SoftwareProduct softwareProduct);
- Entities.SoftwareProduct Map(SoftwareProduct softwareProduct);
- SoftwareProduct MapSoftwareProduct(Entities.SoftwareProduct softwareProduct);
+ Entities.SoftwareProduct Map(SoftwareProduct softwareProduct);
Entities.SoftwareProductCertificate Map(SoftwareProductCertificateInfosec softwareProductCertificate);
+
+ SoftwareProduct MapSoftwareProduct(Entities.SoftwareProduct softwareProduct);
}
}
diff --git a/Source/CDR.Register.Repository/Infrastructure/ScopeConstants.cs b/Source/CDR.Register.Repository/Infrastructure/CdsRegistrationScopes.cs
similarity index 100%
rename from Source/CDR.Register.Repository/Infrastructure/ScopeConstants.cs
rename to Source/CDR.Register.Repository/Infrastructure/CdsRegistrationScopes.cs
diff --git a/Source/CDR.Register.Repository/Infrastructure/Extensions.cs b/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
index e4db886..3b70765 100644
--- a/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
@@ -1,15 +1,15 @@
using System;
-using System.Linq;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading.Tasks;
+using CDR.Register.Domain.ValueObjects;
using CDR.Register.Repository.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using DomainEntities = CDR.Register.Domain.Entities;
-using System.Collections.Generic;
-using CDR.Register.Domain.ValueObjects;
namespace CDR.Register.Repository.Infrastructure
{
@@ -57,9 +57,9 @@ public static void SeedDatabase(this ModelBuilder modelBuilder)
}
///
- /// This is the initial database seed. If there are records in the database, this will not re-seed the database
+ /// This is the initial database seed. If there are records in the database, this will not re-seed the database.
///
- public async static Task SeedDatabaseFromJsonFile(
+ public static async Task SeedDatabaseFromJsonFile(
this RegisterDatabaseContext registerDatabaseContext,
string jsonFileFullPath,
ILogger logger,
@@ -76,9 +76,9 @@ public async static Task SeedDatabaseFromJsonFile(
}
///
- /// This is the initial database seed. If there are records in the database, this will not re-seed the database
+ /// This is the initial database seed. If there are records in the database, this will not re-seed the database.
///
- public async static Task SeedDatabaseFromJson(
+ public static async Task SeedDatabaseFromJson(
this RegisterDatabaseContext registerDatabaseContext,
string json,
ILogger logger,
@@ -106,7 +106,7 @@ public async static Task SeedDatabaseFromJson(
///
/// Retrieves all participant metadata from the database, serialises to JSON and return as a string.
///
- public async static Task GetJsonFromDatabase(
+ public static async Task GetJsonFromDatabase(
this RegisterDatabaseContext registerDatabaseContext)
{
var allData = await registerDatabaseContext.LegalEntities.AsNoTracking().OrderBy(l => l.LegalEntityName)
@@ -135,9 +135,9 @@ public async static Task GetJsonFromDatabase(
///
/// Re-Seed the database from the input JSON data. All existing data in the database will be removed prior to creating the new data set.
///
- public async static Task ReSeedDatabaseFromJson(this RegisterDatabaseContext registerDatabaseContext, string json, ILogger logger)
+ public static async Task ReSeedDatabaseFromJson(this RegisterDatabaseContext registerDatabaseContext, string json, ILogger logger)
{
- using (var transaction = registerDatabaseContext.Database.BeginTransaction())
+ using (var transaction = await registerDatabaseContext.Database.BeginTransactionAsync())
{
try
{
@@ -146,11 +146,10 @@ public async static Task ReSeedDatabaseFromJson(this RegisterDatabaseConte
// Remove all existing data in the system
var existingLegalEntities = await registerDatabaseContext.LegalEntities.AsNoTracking().ToListAsync();
registerDatabaseContext.RemoveRange(existingLegalEntities);
- registerDatabaseContext.SaveChanges();
+ await registerDatabaseContext.SaveChangesAsync();
logger.LogInformation("Existing data removed from the repository.");
-
logger.LogInformation("Adding JSON data to repository...");
// Re-create all participants from the incoming JSON.
@@ -159,10 +158,10 @@ public async static Task ReSeedDatabaseFromJson(this RegisterDatabaseConte
{
var newLegalEntities = allData["legalEntities"].ToObject();
registerDatabaseContext.LegalEntities.AddRange(newLegalEntities);
- registerDatabaseContext.SaveChanges();
+ await registerDatabaseContext.SaveChangesAsync();
// Finally commit the transaction
- transaction.Commit();
+ await transaction.CommitAsync();
logger.LogInformation("JSON data added to the repository.");
return true;
@@ -172,15 +171,19 @@ public async static Task ReSeedDatabaseFromJson(this RegisterDatabaseConte
{
// Log any errors.
logger.LogError(ex, "Error while seeding the database.");
- throw;
+ throw new InvalidOperationException("Error while seeding the database.");
}
+
return false;
}
}
- public static async Task AddOrUpdateDataRecipientLegalEntity(this DomainEntities.DataRecipient dataRecipient,
- LegalEntity legalEntity, RegisterDatabaseContext registerDatabaseContext,
- IRepositoryMapper repositoryMapper, ILogger logger)
+ public static async Task AddOrUpdateDataRecipientLegalEntity(
+ this DomainEntities.DataRecipient dataRecipient,
+ LegalEntity legalEntity,
+ RegisterDatabaseContext registerDatabaseContext,
+ IRepositoryMapper repositoryMapper,
+ ILogger logger)
{
BusinessRuleError error = null;
@@ -190,29 +193,29 @@ public static async Task AddOrUpdateDataRecipientLegalEntity(
var drBrandToSave = repositoryMapper.Map(dataRecipientBrand);
drBrandToSave.LastUpdated = DateTime.UtcNow;
- //create new brand as it is a new one
- if (null == dbBrand)
+ // create new brand as it is a new one
+ if (dbBrand == null)
{
logger.LogInformation("New Brand of id:{BrandId} name:{BrandName} getting added to the repository.", dataRecipientBrand.BrandId, dataRecipientBrand.BrandName);
await registerDatabaseContext.Brands.AddAsync(drBrandToSave);
}
- //handle participation
+ // handle participation
if ((error = await drBrandToSave.AddOrUpdateDataRecipientParticipation(legalEntity, dataRecipient, registerDatabaseContext, logger)) != null)
{
logger.LogError("Update participation encountered error of {Error}", @error);
return error;
}
- //update the brand as it is an existing one.
+ // update the brand as it is an existing one.
if (dbBrand != null)
{
logger.LogInformation("Updating Brand of id:{BrandId} name:{BrandName}", dataRecipientBrand.BrandId, dataRecipientBrand.BrandName);
registerDatabaseContext.Brands.Update(drBrandToSave);
}
- //handle software products
+ // handle software products
if ((error = await drBrandToSave.UpsertRecipientBrandSoftwareProducts(registerDatabaseContext, repositoryMapper, dataRecipientBrand.SoftwareProducts, logger)) != null)
{
logger.LogError("Update SoftwareProduct encountered error of {Error}", @error);
@@ -223,10 +226,13 @@ public static async Task AddOrUpdateDataRecipientLegalEntity(
return error;
}
- public static async Task UpsertRecipientBrandSoftwareProducts(this Brand brand, RegisterDatabaseContext registerDbContext,
- IRepositoryMapper repositoryMapper, ICollection softwareProducts, ILogger logger)
+ public static async Task UpsertRecipientBrandSoftwareProducts(
+ this Brand brand,
+ RegisterDatabaseContext registerDbContext,
+ IRepositoryMapper repositoryMapper,
+ ICollection softwareProducts,
+ ILogger logger)
{
-
brand.SoftwareProducts ??= new List();
foreach (var s in softwareProducts)
@@ -237,10 +243,12 @@ public static async Task UpsertRecipientBrandSoftwareProducts
if (existingSoftwareProduct != null)
{
- //check if we getting assigned to new brand.
+ // check if we getting assigned to new brand.
if (existingSoftwareProduct.BrandId != brand.BrandId)
{
- return new BusinessRuleError("urn:au-cds:error:cds-all:Field/Invalid", "Invalid Field",
+ return new BusinessRuleError(
+ "urn:au-cds:error:cds-all:Field/Invalid",
+ "Invalid Field",
$"Value '{existingSoftwareProduct.SoftwareProductId}' in SoftwareProductId is already associated with a different brand.");
}
@@ -248,7 +256,7 @@ public static async Task UpsertRecipientBrandSoftwareProducts
registerDbContext.SoftwareProducts.Update(softwareProduct);
}
- if (null == existingSoftwareProduct)
+ if (existingSoftwareProduct == null)
{
softwareProduct.BrandId = brand.BrandId;
logger.LogInformation("Adding new SoftwareProduct of id:{SoftwareProductId} for name:{SoftwareProdcutName}", softwareProduct.SoftwareProductId, softwareProduct.SoftwareProductName);
@@ -261,17 +269,21 @@ public static async Task UpsertRecipientBrandSoftwareProducts
return null;
}
- public static async Task UpsertSoftwareProductCertificates(this SoftwareProduct softwareProduct, RegisterDatabaseContext registerDbContext,
- IRepositoryMapper repositoryMapper, ICollection certificates, ILogger logger)
+ public static async Task UpsertSoftwareProductCertificates(
+ this SoftwareProduct softwareProduct,
+ RegisterDatabaseContext registerDbContext,
+ IRepositoryMapper repositoryMapper,
+ ICollection certificates,
+ ILogger logger)
{
softwareProduct.Certificates ??= [];
foreach (var c in certificates)
{
- var existingCertificate = await registerDbContext.SoftwareProductCertificates.SingleOrDefaultAsync(cert =>
- cert.Thumbprint == c.Thumbprint &&
- cert.SoftwareProductId == softwareProduct.SoftwareProductId &&
- cert.CommonName == c.CommonName);
+ var existingCertificate = await registerDbContext.SoftwareProductCertificates.SingleOrDefaultAsync(cert =>
+ cert.Thumbprint == c.Thumbprint &&
+ cert.SoftwareProductId == softwareProduct.SoftwareProductId &&
+ cert.CommonName == c.CommonName);
if (existingCertificate != null)
{
@@ -280,29 +292,33 @@ public static async Task UpsertSoftwareProductCertificates(this SoftwareProduct
registerDbContext.SoftwareProductCertificates.Update(existingCertificate);
}
- if (null == existingCertificate)
+ if (existingCertificate == null)
{
var certificate = repositoryMapper.Map(c);
certificate.SoftwareProductId = softwareProduct.SoftwareProductId;
await registerDbContext.SoftwareProductCertificates.AddAsync(certificate);
await registerDbContext.SaveChangesAsync();
logger.LogInformation("Adding new SoftwareProductCertificate of id:{SoftwareProductCertificateId} for SoftwareProductId:{SoftwareProductId}", certificate.SoftwareProductCertificateId, certificate.SoftwareProductId);
- }
+ }
}
}
- public static async Task AddOrUpdateDataRecipientParticipation(this Brand brand, LegalEntity legalEntity,
- DomainEntities.DataRecipient dataRecipient, RegisterDatabaseContext registerDatabaseContext, ILogger logger)
+ public static async Task AddOrUpdateDataRecipientParticipation(
+ this Brand brand,
+ LegalEntity legalEntity,
+ DomainEntities.DataRecipient dataRecipient,
+ RegisterDatabaseContext registerDatabaseContext,
+ ILogger logger)
{
var existingParticipant = await registerDatabaseContext.Participations.
Include(x => x.LegalEntity).
- SingleOrDefaultAsync(p => (p.LegalEntityId == legalEntity.LegalEntityId || p.Brands.Any(b => b.BrandId == brand.BrandId) && p.ParticipationTypeId == ParticipationTypes.Dr));
+ SingleOrDefaultAsync(p => (p.LegalEntityId == legalEntity.LegalEntityId || (p.Brands.Any(b => b.BrandId == brand.BrandId) && p.ParticipationTypeId == ParticipationTypes.Dr)));
var participationStatus = (ParticipationStatusType)Enum.Parse(typeof(Entities.ParticipationStatusType), dataRecipient.LegalEntity.Status, true);
if (existingParticipant != null)
{
- //check if there is a change in the participation between brand and legal entity
+ // check if there is a change in the participation between brand and legal entity
if (existingParticipant.LegalEntityId != legalEntity.LegalEntityId)
{
return new BusinessRuleError("urn:au-cds:error:cds-all:Field/Invalid", "Invalid Field", $"dataRecipientBrandId '{brand.BrandId}' is already associated with a different legal entity.");
@@ -312,7 +328,7 @@ public static async Task AddOrUpdateDataRecipientParticipatio
existingParticipant.StatusId = participationStatus;
}
- //create the Participation if required.
+ // create the Participation if required.
if (existingParticipant == null)
{
var participant = new Participation
@@ -325,15 +341,15 @@ public static async Task AddOrUpdateDataRecipientParticipatio
legalEntity.Participations ??= new List();
legalEntity.Participations.Add(participant);
- //assigning new participation to the brand.
+ // assigning new participation to the brand.
brand.ParticipationId = participant.ParticipationId;
await registerDatabaseContext.Participations.AddAsync(participant);
await registerDatabaseContext.SaveChangesAsync();
logger.LogInformation("Adding new Participation of id:{ParticipationId} getting added to the repository.", participant.ParticipationId);
- }
+ }
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs b/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
index 068d6da..d17390b 100644
--- a/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
@@ -23,10 +23,9 @@ public MappingProfile()
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Participations.FirstOrDefault().Status.ParticipationStatusCode.ToUpper()));
CreateMap()
- .ForMember(dest => dest.OrganisationTypeId, source => source.MapFrom(source => source.OrganisationType == null ? null : Enum.Parse(typeof(Entities.OrganisationTypes), source.OrganisationType.Replace("_", ""), true)))
+ .ForMember(dest => dest.OrganisationTypeId, source => source.MapFrom(source => source.OrganisationType == null ? null : Enum.Parse(typeof(Entities.OrganisationTypes), source.OrganisationType.Replace("_", string.Empty), true)))
.ForMember(dest => dest.OrganisationType, opt => opt.Ignore());
-
CreateMap()
.ForMember(dest => dest.DataHolderId, source => source.MapFrom(source => source.ParticipationId))
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ParticipationStatusCode))
@@ -77,12 +76,11 @@ public MappingProfile()
.ForMember(dest => dest.BrandStatus, opts => opts.Ignore())
.ForMember(dest => dest.SoftwareProducts, opts => opts.Ignore());
-
CreateMap()
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.SoftwareProductStatusCode))
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => source.Status.SoftwareProductStatusId == SoftwareProductStatusType.Active))
.ForMember(dest => dest.RedirectUri, source => source.MapFrom(src => src.RedirectUris))
- .ForMember(dest => dest.RedirectUris, opts => opts.Ignore()) //Ignore this as it is a computed property with no setter
+ .ForMember(dest => dest.RedirectUris, opts => opts.Ignore()) // Ignore this as it is a computed property with no setter
.ForMember(dest => dest.DataRecipientBrand, source => source.MapFrom(s => s.Brand));
CreateMap()
@@ -102,7 +100,7 @@ public MappingProfile()
CreateMap()
.ForMember(dest => dest.RegisterUType, source => source.MapFrom(source => source.RegisterUType.RegisterUTypeCode));
CreateMap()
- .ForMember(dest => dest.RegisterUTypeId, source => source.MapFrom(source =>
+ .ForMember(dest => dest.RegisterUTypeId, source => source.MapFrom(source =>
Enum.Parse(typeof(RegisterUTypes), source.RegisterUType.Replace("-", string.Empty), true)))
.ForMember(dest => dest.JwksEndpoint, source => source.MapFrom(source => source.JwksEndpoint))
.ForMember(dest => dest.RegisterUType, opt => opt.Ignore())
@@ -113,4 +111,4 @@ public MappingProfile()
.ReverseMap();
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
index 9cbe792..bb0e3d8 100644
--- a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
@@ -4,62 +4,74 @@
namespace CDR.Register.Repository.Infrastructure
{
+ public class RegisterDatabaseContext : DbContext
+ {
+ public RegisterDatabaseContext()
+ {
+ }
- public class RegisterDatabaseContext : DbContext
- {
- public RegisterDatabaseContext()
- {
-
- }
-
- public RegisterDatabaseContext(DbContextOptions options) : base(options)
- {
- }
-
- public DbSet LegalEntities { get; set; }
- public DbSet Participations { get; set; }
- public DbSet Brands { get; set; }
- public DbSet BrandStatuses { get; set; }
- public DbSet Endpoints { get; set; }
- public DbSet AuthDetails { get; set; }
- public DbSet SoftwareProducts { get; set; }
- public DbSet IndustryTypes { get; set; }
- public DbSet OrganisationTypes { get; set; }
- public DbSet ParticicipationStatuses { get; set; }
- public DbSet ParticipationTypes { get; set; }
- public DbSet SoftwareProductStatuses { get; set; }
- public DbSet RegisterUTypes { get; set; }
- public DbSet SoftwareProductCertificates { get; set; }
-
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- foreach (var clrType in modelBuilder.Model.GetEntityTypes().Select(e => e.ClrType))
- {
- // Use the entity name instead of the Context.DbSet name
- // refs https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=fluent-api#table-name
- modelBuilder.Entity(clrType).ToTable(clrType.Name);
- }
-
- // Add composite primary keys
- modelBuilder.Entity()
- .ToTable("AuthDetail", t => t.IsTemporal())
- .HasKey(c => new { c.BrandId, c.RegisterUTypeId });
-
- // Configure 1-to-1 relationship.
- modelBuilder.Entity()
- .ToTable("Brand", t => t.IsTemporal())
- .HasOne(b => b.Endpoint)
- .WithOne(e => e.Brand);
-
- // Other, Temporal table configurations
- modelBuilder.Entity().ToTable("Endpoint", t => t.IsTemporal());
- modelBuilder.Entity().ToTable("LegalEntity", t => t.IsTemporal());
- modelBuilder.Entity().ToTable("Participation", t => t.IsTemporal());
- modelBuilder.Entity().ToTable("SoftwareProduct", t => t.IsTemporal());
- modelBuilder.Entity().ToTable("SoftwareProductCertificate", t => t.IsTemporal());
-
- // Seed the database with reference data and initial data
- modelBuilder.SeedDatabase();
- }
- }
+ public RegisterDatabaseContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public DbSet LegalEntities { get; set; }
+
+ public DbSet Participations { get; set; }
+
+ public DbSet Brands { get; set; }
+
+ public DbSet BrandStatuses { get; set; }
+
+ public DbSet Endpoints { get; set; }
+
+ public DbSet AuthDetails { get; set; }
+
+ public DbSet SoftwareProducts { get; set; }
+
+ public DbSet IndustryTypes { get; set; }
+
+ public DbSet OrganisationTypes { get; set; }
+
+ public DbSet ParticicipationStatuses { get; set; }
+
+ public DbSet ParticipationTypes { get; set; }
+
+ public DbSet SoftwareProductStatuses { get; set; }
+
+ public DbSet RegisterUTypes { get; set; }
+
+ public DbSet SoftwareProductCertificates { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ foreach (var clrType in modelBuilder.Model.GetEntityTypes().Select(e => e.ClrType))
+ {
+ // Use the entity name instead of the Context.DbSet name
+ // refs https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=fluent-api#table-name
+ modelBuilder.Entity(clrType).ToTable(clrType.Name);
+ }
+
+ // Add composite primary keys
+ modelBuilder.Entity()
+ .ToTable("AuthDetail", t => t.IsTemporal())
+ .HasKey(c => new { c.BrandId, c.RegisterUTypeId });
+
+ // Configure 1-to-1 relationship.
+ modelBuilder.Entity()
+ .ToTable("Brand", t => t.IsTemporal())
+ .HasOne(b => b.Endpoint)
+ .WithOne(e => e.Brand);
+
+ // Other, Temporal table configurations
+ modelBuilder.Entity().ToTable("Endpoint", t => t.IsTemporal());
+ modelBuilder.Entity().ToTable("LegalEntity", t => t.IsTemporal());
+ modelBuilder.Entity().ToTable("Participation", t => t.IsTemporal());
+ modelBuilder.Entity().ToTable("SoftwareProduct", t => t.IsTemporal());
+ modelBuilder.Entity().ToTable("SoftwareProductCertificate", t => t.IsTemporal());
+
+ // Seed the database with reference data and initial data
+ modelBuilder.SeedDatabase();
+ }
+ }
}
diff --git a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContextDesignTimeFactory.cs b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContextDesignTimeFactory.cs
index ec9f829..584a97f 100644
--- a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContextDesignTimeFactory.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContextDesignTimeFactory.cs
@@ -1,12 +1,11 @@
-using System;
-using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
namespace CDR.Register.Repository.Infrastructure
{
///
/// This is the DB context initialisation for the tooling such as migrations.
- /// When the tooling runs the migration, it looks first for a class that implements IDesignTimeDbContextFactory and if found,
+ /// When the tooling runs the migration, it looks first for a class that implements IDesignTimeDbContextFactory and if found,
/// it will use that for configuring the context. Runtime behavior is not affected by any configuration set in the factory class.
///
public class RegisterDatabaseContextDesignTimeFactory : IDesignTimeDbContextFactory
@@ -25,4 +24,4 @@ public RegisterDatabaseContext CreateDbContext(string[] args)
return new RegisterDatabaseContext(options);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/Infrastructure/RepositoryMapper.cs b/Source/CDR.Register.Repository/Infrastructure/RepositoryMapper.cs
index 20921fc..a0d68a8 100644
--- a/Source/CDR.Register.Repository/Infrastructure/RepositoryMapper.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/RepositoryMapper.cs
@@ -36,11 +36,6 @@ public Entities.LegalEntity Map(Domain.Entities.DataRecipientLegalEntity legalEn
return _mapper.Map(legalEntity);
}
- public Domain.Entities.SoftwareProduct MapSoftwareProduct(Entities.SoftwareProduct softwareProduct)
- {
- return _mapper.Map(softwareProduct);
- }
-
public Entities.Brand Map(DataRecipientBrand brand)
{
return _mapper.Map(brand);
@@ -55,5 +50,10 @@ public Entities.SoftwareProductCertificate Map(SoftwareProductCertificateInfosec
{
return _mapper.Map(softwareProductCertificate);
}
+
+ public Domain.Entities.SoftwareProduct MapSoftwareProduct(Entities.SoftwareProduct softwareProduct)
+ {
+ return _mapper.Map(softwareProduct);
+ }
}
}
diff --git a/Source/CDR.Register.Repository/Migrations/20211223050501_V2.cs b/Source/CDR.Register.Repository/Migrations/20211223050501_V2.cs
index 8d2c635..47aedc7 100644
--- a/Source/CDR.Register.Repository/Migrations/20211223050501_V2.cs
+++ b/Source/CDR.Register.Repository/Migrations/20211223050501_V2.cs
@@ -66,7 +66,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
table.PrimaryKey("PK_LegalEntityStatus", x => x.LegalEntityStatusId);
});
-
+
migrationBuilder.InsertData(
table: "LegalEntityStatus",
columns: new[] { "LegalEntityStatusId", "LegalEntityStatusCode" },
@@ -85,11 +85,10 @@ protected override void Up(MigrationBuilder migrationBuilder)
{ 1, "Unrestricted" }
});
- //Updating exsiting data
+ // Updating exsiting data
migrationBuilder.Sql(@"Update IndustryType Set IndustryTypeCode='Banking' where IndustryTypeId=1;
Update IndustryType Set IndustryTypeCode='Energy' where IndustryTypeId=2;");
-
migrationBuilder.CreateIndex(
name: "IX_LegalEntity_AccreditationLevelId",
table: "LegalEntity",
@@ -152,7 +151,7 @@ protected override void Down(MigrationBuilder migrationBuilder)
migrationBuilder.DropIndex(
name: "IX_LegalEntity_LegalEntityStatusId",
table: "LegalEntity");
-
+
migrationBuilder.DropColumn(
name: "AccreditationLevelId",
table: "LegalEntity");
diff --git a/Source/CDR.Register.Repository/Migrations/20221005215852_V5.cs b/Source/CDR.Register.Repository/Migrations/20221005215852_V5.cs
index 69b3b9a..090b60b 100644
--- a/Source/CDR.Register.Repository/Migrations/20221005215852_V5.cs
+++ b/Source/CDR.Register.Repository/Migrations/20221005215852_V5.cs
@@ -9,17 +9,17 @@ public partial class V5 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
- // Add the additional Participation to LE
- var participationTypeIds = new int[] { (int)ParticipationTypes.Dh, (int)ParticipationTypes.Dr };
- foreach (var participationTypeId in participationTypeIds)
- {
- migrationBuilder.Sql($"INSERT INTO [dbo].[Participation] (ParticipationId, LegalEntityId, ParticipationTypeId, IndustryId, StatusId)\r\nSELECT NEWID(), le.LegalEntityId, {participationTypeId}, 1, 1 FROM [dbo].[LegalEntity] le\r\nLEFT OUTER JOIN [dbo].[Participation] p on p.LegalEntityId = le.LegalEntityId AND p.ParticipationTypeId = {participationTypeId}\r\nWHERE p.ParticipationId IS NULL");
- }
- }
+ // Add the additional Participation to LE
+ var participationTypeIds = new int[] { (int)ParticipationTypes.Dh, (int)ParticipationTypes.Dr };
+ foreach (var participationTypeId in participationTypeIds)
+ {
+ migrationBuilder.Sql($"INSERT INTO [dbo].[Participation] (ParticipationId, LegalEntityId, ParticipationTypeId, IndustryId, StatusId)\r\nSELECT NEWID(), le.LegalEntityId, {participationTypeId}, 1, 1 FROM [dbo].[LegalEntity] le\r\nLEFT OUTER JOIN [dbo].[Participation] p on p.LegalEntityId = le.LegalEntityId AND p.ParticipationTypeId = {participationTypeId}\r\nWHERE p.ParticipationId IS NULL");
+ }
+ }
protected override void Down(MigrationBuilder migrationBuilder)
{
-
+ // Not implemented
}
}
}
diff --git a/Source/CDR.Register.Repository/Migrations/20230718020902_V7.cs b/Source/CDR.Register.Repository/Migrations/20230718020902_V7.cs
index 9afea2c..9950f8c 100644
--- a/Source/CDR.Register.Repository/Migrations/20230718020902_V7.cs
+++ b/Source/CDR.Register.Repository/Migrations/20230718020902_V7.cs
@@ -7,9 +7,9 @@ namespace CDR.Register.Repository.Migrations
public partial class V7 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
- {
- // Autognerate ADR###### as the format for AccreditationNumbers eg ADR000099 for null
- // Accreditation Number Fixing all the exisitng data.
+ {
+ // Autognerate ADR###### as the format for AccreditationNumbers eg ADR000099 for null.
+ // Accreditation Number Fixing all the exisitng data.
var sqlQuery = @"DECLARE @Counter INT;
SET @Counter = 0
@@ -27,7 +27,7 @@ FROM Participation P
protected override void Down(MigrationBuilder migrationBuilder)
{
-
+ // Not required.
}
}
}
diff --git a/Source/CDR.Register.Repository/RegisterAdminRepository.cs b/Source/CDR.Register.Repository/RegisterAdminRepository.cs
index 7b8d908..06f5473 100644
--- a/Source/CDR.Register.Repository/RegisterAdminRepository.cs
+++ b/Source/CDR.Register.Repository/RegisterAdminRepository.cs
@@ -21,9 +21,9 @@ public class RegisterAdminRepository : IRegisterAdminRepository
public RegisterAdminRepository(RegisterDatabaseContext registerDatabaseContext, IMapper mapper, IRepositoryMapper repositoryMapper, ILogger logger)
{
_registerDatabaseContext = registerDatabaseContext;
- _mapper=mapper;
+ _mapper = mapper;
_reporsitoryMapper = repositoryMapper;
- _logger=logger;
+ _logger = logger;
}
private async Task<(LegalEntity, Participation)> SaveDataHolderLegalEntity(DataHolder dataHolder)
@@ -114,7 +114,7 @@ public async Task AddOrUpdateDataRecipient(DataRecipient data
{
var existingDataRecipient = await GetDataRecipientIdAsync(dataRecipient.LegalEntity.LegalEntityId);
- using var transaction = _registerDatabaseContext.Database.BeginTransaction();
+ using var transaction = await _registerDatabaseContext.Database.BeginTransactionAsync();
LegalEntity legalEntity = _reporsitoryMapper.Map(dataRecipient.LegalEntity);
@@ -136,8 +136,8 @@ public async Task AddOrUpdateDataRecipient(DataRecipient data
{
await _registerDatabaseContext.SaveChangesAsync();
await transaction.CommitAsync();
- }
-
+ }
+
return error;
}
@@ -148,15 +148,15 @@ public async Task SaveDataHolderBrand(Guid legalEntityId, DataHolderBrand
return false;
}
- (_ , var savedParticipation) = await SaveDataHolderLegalEntity(dataHolderBrand.DataHolder);
+ (_, var savedParticipation) = await SaveDataHolderLegalEntity(dataHolderBrand.DataHolder);
// Save DH Brand
var dhBrandToSave = _mapper.Map(dataHolderBrand);
- var existingBrand = _registerDatabaseContext.Brands
+ var existingBrand = await _registerDatabaseContext.Brands
.Include(b => b.Participation)
.Include(b => b.AuthDetails)
.Include(b => b.Endpoint)
- .Where(brand => brand.BrandId == dataHolderBrand.BrandId).FirstOrDefault();
+ .Where(brand => brand.BrandId == dataHolderBrand.BrandId).FirstOrDefaultAsync();
if (existingBrand == null)
{
dhBrandToSave.LastUpdated = DateTime.UtcNow;
diff --git a/Source/CDR.Register.Repository/RegisterDiscoveryRepository.cs b/Source/CDR.Register.Repository/RegisterDiscoveryRepository.cs
index 7ba9ed0..e25d6ee 100644
--- a/Source/CDR.Register.Repository/RegisterDiscoveryRepository.cs
+++ b/Source/CDR.Register.Repository/RegisterDiscoveryRepository.cs
@@ -89,9 +89,9 @@ public async Task GetDataRecipientsAsync(Infrastructure.Industr
return _mapper.Map(allParticipants);
}
- ///
+ ///
/// The industry parameter is passed but currently not used.
- ///
+ ///
protected async Task> ProcessGetDataRecipients(Infrastructure.Industry industry)
{
return await this._registerDatabaseContext.Participations.AsNoTracking()
@@ -125,4 +125,4 @@ protected async Task> ProcessGetDataRecipients(Infrastructur
return _mapper.Map(softwareProduct);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CDR.Register.Repository/RegisterStatusRepository.cs b/Source/CDR.Register.Repository/RegisterStatusRepository.cs
index 3c066e6..99a61b2 100644
--- a/Source/CDR.Register.Repository/RegisterStatusRepository.cs
+++ b/Source/CDR.Register.Repository/RegisterStatusRepository.cs
@@ -56,8 +56,7 @@ public async Task GetDataRecipientStatusesAsync(Infrastru
{
SoftwareProductId = sp.SoftwareProductId,
Status = sp.Status.SoftwareProductStatusCode
- }
- )
+ })
.OrderBy(sp => sp.SoftwareProductId)
.ToArray();
}
diff --git a/Source/CDR.Register.Repository/SoftwareStatementAssertionRepository.cs b/Source/CDR.Register.Repository/SoftwareStatementAssertionRepository.cs
index 9756253..6a7c7f0 100644
--- a/Source/CDR.Register.Repository/SoftwareStatementAssertionRepository.cs
+++ b/Source/CDR.Register.Repository/SoftwareStatementAssertionRepository.cs
@@ -32,7 +32,6 @@ public async Task GetSoftwareStatementAssertionAsync
LegalEntity = _mapper.Map(x.Brand.Participation.LegalEntity)
})
.FirstOrDefaultAsync();
-
}
}
}
diff --git a/Source/CDR.Register.SSA.API.UnitTests/CDR.Register.SSA.API.UnitTests.csproj b/Source/CDR.Register.SSA.API.UnitTests/CDR.Register.SSA.API.UnitTests.csproj
index a7fe017..0594b09 100644
--- a/Source/CDR.Register.SSA.API.UnitTests/CDR.Register.SSA.API.UnitTests.csproj
+++ b/Source/CDR.Register.SSA.API.UnitTests/CDR.Register.SSA.API.UnitTests.csproj
@@ -5,6 +5,7 @@
$(Version)
$(Version)
$(Version)
+ True
@@ -39,9 +40,10 @@
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -50,6 +52,14 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CDR.Register.SSA.API.UnitTests/HttpClientHandlerExtensionsTests.cs b/Source/CDR.Register.SSA.API.UnitTests/HttpClientHandlerExtensionsTests.cs
index e9b1a2f..9c15801 100644
--- a/Source/CDR.Register.SSA.API.UnitTests/HttpClientHandlerExtensionsTests.cs
+++ b/Source/CDR.Register.SSA.API.UnitTests/HttpClientHandlerExtensionsTests.cs
@@ -1,8 +1,7 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
-using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using CDR.Register.API.Infrastructure;
@@ -13,20 +12,22 @@
using Serilog;
using Xunit;
+#nullable enable
+
namespace CDR.Register.SSA.API.UnitTests
{
public class HttpClientHandlerExtensionsTests
{
private readonly IConfiguration _configuration;
- private readonly HttpClientHandler _handler = null!;
+ private readonly HttpClientHandler _handler;
public HttpClientHandlerExtensionsTests()
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
- .AddInMemoryCollection(new Dictionary()
+ .AddInMemoryCollection(new Dictionary()
{
- { "EnableServerCertificateValidation", "True"},
+ { "EnableServerCertificateValidation", "True" },
})
.Build();
_configuration = configuration;
@@ -42,7 +43,10 @@ public HttpClientHandlerExtensionsTests()
public async Task ServerCertificates_ValidationEnabled_ShouldValidateSslConnection(
string certName, string certPassword, bool expected, string reason)
{
- await using (var mockEndpoint = new MockEndpoint("https://localhost:9990",
+ Log.Information($"Scenario: {reason}");
+
+ await using (var mockEndpoint = new MockEndpoint(
+ "https://localhost:9990",
Path.Combine(Directory.GetCurrentDirectory(), "Certificates", certName),
certPassword))
{
@@ -57,6 +61,7 @@ public async Task ServerCertificates_ValidationEnabled_ShouldValidateSslConnecti
{
await Assert.ThrowsAsync(async () => await client.GetAsync("https://localhost:9990"));
}
+
await mockEndpoint.Stop();
}
}
@@ -71,8 +76,11 @@ public MockEndpoint(string url, string certificatePath, string certificatePasswo
}
public string Url { get; init; }
+
private int UrlPort => new Uri(Url).Port;
+
public string CertificatePath { get; init; }
+
public string CertificatePassword { get; init; }
private IWebHost? _host;
@@ -84,10 +92,11 @@ public void Start()
_host = new WebHostBuilder()
.UseKestrel(opts =>
{
- opts.ListenAnyIP(UrlPort,
+ opts.ListenAnyIP(
+ UrlPort,
opts => opts.UseHttps(new X509Certificate2(CertificatePath, CertificatePassword, X509KeyStorageFlags.Exportable)));
})
- .UseStartup(_ => new MockEndpointStartup())
+ .UseStartup(typeof(MockEndpointStartup))
.Build();
_host.RunAsync();
@@ -103,7 +112,8 @@ public async Task Stop()
}
}
- bool _disposed;
+ private bool _disposed;
+
public async ValueTask DisposeAsync()
{
Log.Information("Calling {FUNCTION} in {ClassName}.", nameof(DisposeAsync), nameof(MockEndpoint));
@@ -117,8 +127,12 @@ public async ValueTask DisposeAsync()
GC.SuppressFinalize(this);
}
- class MockEndpointStartup
+ public class MockEndpointStartup
{
+ protected MockEndpointStartup()
+ {
+ }
+
public static void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
diff --git a/Source/CDR.Register.SSA.API.UnitTests/JwksTests.cs b/Source/CDR.Register.SSA.API.UnitTests/JwksTests.cs
index 7ecabe4..e7fb764 100644
--- a/Source/CDR.Register.SSA.API.UnitTests/JwksTests.cs
+++ b/Source/CDR.Register.SSA.API.UnitTests/JwksTests.cs
@@ -13,10 +13,11 @@ public void GenerateJwks_ValidCertificate_ShouldGenerateJwks()
{
// Arrange.
var path = Path.Combine(Directory.GetCurrentDirectory(), "Certificates", "ssa.pfx");
- var inMemorySettings = new Dictionary {
- {"SigningCertificate:Path", path},
- {"SigningCertificate:Password", "#M0ckRegister#"},
- };
+ var inMemorySettings = new Dictionary
+ {
+ { "SigningCertificate:Path", path },
+ { "SigningCertificate:Password", "#M0ckRegister#" },
+ };
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
@@ -38,6 +39,5 @@ public void GenerateJwks_ValidCertificate_ShouldGenerateJwks()
Assert.Equal("AQAB", jwk.e);
Assert.Equal(2, jwk.key_ops.Length);
}
-
}
}
diff --git a/Source/CDR.Register.SSA.API.UnitTests/TokenizerServiceTests.cs b/Source/CDR.Register.SSA.API.UnitTests/TokenizerServiceTests.cs
index 819b94a..7b0d1b6 100644
--- a/Source/CDR.Register.SSA.API.UnitTests/TokenizerServiceTests.cs
+++ b/Source/CDR.Register.SSA.API.UnitTests/TokenizerServiceTests.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
@@ -14,7 +14,6 @@
namespace CDR.Register.SSA.API.UnitTests
{
-
public class TokenizerServiceTests
{
private readonly ServiceProvider _serviceProvider;
@@ -40,7 +39,7 @@ public TokenizerServiceTests()
[Fact]
public async Task GenerateJwtTokenAsync_Success()
{
- //Arrange
+ // Arrange
var tokenizerService = _serviceProvider.GetRequiredService();
var ssa = new SoftwareStatementAssertionModel
@@ -67,18 +66,18 @@ public async Task GenerateJwtTokenAsync_Success()
software_roles = "data-recipient-software-product",
};
- //Generate the SSA JWT token
+ // Generate the SSA JWT token
var ssaToken = await tokenizerService.GenerateJwtTokenAsync(ssa);
var tokenHandler = new JwtSecurityTokenHandler();
- //Create the certificate which has only public key
+ // Create the certificate which has only public key
var cert = new X509Certificate2(_configuration["SigningCertificatePublic:Path"]);
- //Get credentials from certificate
+ // Get credentials from certificate
var certificateSecurityKey = new X509SecurityKey(cert);
- //Set token validation parameters
+ // Set token validation parameters
var validationParameters = new TokenValidationParameters()
{
IssuerSigningKey = certificateSecurityKey,
@@ -90,10 +89,11 @@ public async Task GenerateJwtTokenAsync_Success()
};
SecurityToken validatedToken;
- //Act
+
+ // Act
var principal = tokenHandler.ValidateToken(ssaToken, validationParameters, out validatedToken);
- //Assert
+ // Assert
Assert.NotNull(validatedToken);
Assert.Equal("cdr-register", validatedToken.Issuer);
Assert.Equal(17, principal.Claims.Count());
@@ -102,7 +102,7 @@ public async Task GenerateJwtTokenAsync_Success()
[Fact]
public async Task GenerateJwtTokenAsync_InvalidToken_Failure()
{
- //Arrange
+ // Arrange
var tokenizerService = _serviceProvider.GetRequiredService();
var ssa = new SoftwareStatementAssertionModel
@@ -129,21 +129,21 @@ public async Task GenerateJwtTokenAsync_InvalidToken_Failure()
software_roles = "data-recipient-software-product",
};
- //Generate the SSA JWT token
+ // Generate the SSA JWT token
var ssaToken = await tokenizerService.GenerateJwtTokenAsync(ssa);
- //Create invalid token
+ // Create invalid token
ssaToken = ssaToken.Replace('a', 'b');
var tokenHandler = new JwtSecurityTokenHandler();
-
- //Create the certificate which has only public key
+
+ // Create the certificate which has only public key
var cert = new X509Certificate2(_configuration["SigningCertificatePublic:Path"]);
- //Get credentials from certificate
+ // Get credentials from certificate
var certificateSecurityKey = new X509SecurityKey(cert);
- //Set token validation parameters
+ // Set token validation parameters
var validationParameters = new TokenValidationParameters()
{
IssuerSigningKey = certificateSecurityKey,
@@ -157,22 +157,23 @@ public async Task GenerateJwtTokenAsync_InvalidToken_Failure()
try
{
SecurityToken validatedToken;
- //Act
- var principal = tokenHandler.ValidateToken(ssaToken, validationParameters, out validatedToken);
+
+ // Act
+ tokenHandler.ValidateToken(ssaToken, validationParameters, out validatedToken);
}
catch (Exception ex)
{
- var errorMessage = ex.Message.Replace("\n", "");
- //Assert
+ var errorMessage = ex.Message.Replace("\n", string.Empty);
+
+ // Assert
Assert.StartsWith("IDX10511: Signature validation failed.", errorMessage);
}
-
}
[Fact]
public async Task GenerateJwtTokenAsync_InvalidCertificate_Failure()
{
- //Arrange
+ // Arrange
var tokenizerService = _serviceProvider.GetRequiredService