diff --git a/.azuredevops/pipelines/build-v2.yml b/.azuredevops/pipelines/build-v2.yml
index 895ebd8..49bc317 100644
--- a/.azuredevops/pipelines/build-v2.yml
+++ b/.azuredevops/pipelines/build-v2.yml
@@ -194,8 +194,8 @@ jobs:
# Output Docker Logs
- script: |
- docker logs mock-register
- docker logs cdr-auth-server-standalone
+ docker logs mock-register-cdr-auth-server-integration-tests
+ docker logs cdr-auth-server-standalone-integration-tests
displayName: 'Output Docker Logs'
condition: always()
@@ -245,8 +245,8 @@ jobs:
# Output Docker Logs
- script: |
- docker logs mock-register
- docker logs cdr-auth-server-standalone
+ docker logs mock-register-cdr-auth-server-integration-tests
+ docker logs cdr-auth-server-standalone-integration-tests
displayName: 'Output Docker Logs'
condition: always()
@@ -314,8 +314,8 @@ jobs:
# Output Docker Logs
- script: |
- docker logs mock-register
- docker logs cdr-auth-server-standalone
+ docker logs mock-register-cdr-auth-server-e2e-tests
+ docker logs cdr-auth-server-standalone-e2e-tests
displayName: 'Output Docker Logs'
condition: always()
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 62acd02..cef68d4 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.
@@ -72,4 +72,4 @@ jobs:
dotnet build ./Source/CdrAuthServer.sln --configuration '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 02dc8ca..d919a09 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout Authorisation Server
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
path: ./authorisation-server
@@ -101,7 +101,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
@@ -109,7 +109,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
@@ -117,7 +117,7 @@ jobs:
# Archive authorisation server logs
- name: Archive authorisation server logs
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
if: always()
with:
name: integration-test-artifacts
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/.gitignore b/.gitignore
index cc9a5bd..338b153 100644
--- a/.gitignore
+++ b/.gitignore
@@ -368,4 +368,7 @@ FodyWeavers.xsd
# VSCode
**/.vscode
-**/_temp
\ No newline at end of file
+**/_temp
+
+# Local test
+.runsettings
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7272f9c..6736a2d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [3.0.0] - 2025-03-19
+
+### Changed
+- Updated NuGet packages
+- Fixed multiple build warnings to improve code quality and maintainability
+- Updated npm packages used for Authorisation Server User Interface.
+
+### Removed
+- Removed all OIDC Hybrid Flow related code and functionality
+
## [2.1.0] - 2024-08-16
### Changed
diff --git a/README.md b/README.md
index 1cb4142..b8e5c55 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,7 @@

-[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.31.0/#introduction)
-[](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-holders)
-[](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-recipients)
+[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.33.0/#introduction)
+[](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-recipients)
[](https://openid.net/specs/openid-financial-api-part-2-1_0.html)
[](https://dotnet.microsoft.com/)
[](https://docs.microsoft.com/en-us/dotnet/csharp/)
@@ -17,9 +16,8 @@ The project is used in the Participant Tooling Authorisation Server, providing t
## Authorisation Server - Alignment
The Authorisation Server:
-- 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) in particular [FAPI 1.0 Migration Phase 4](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.31.0/#introduction) with backwards compatibility to Migration Phase 2 and 3;
-- has passed v5.0.0 of the [Conformance Test Suite for Data Holders](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-holders);
-- has passed v4.3.0 of the [Conformance Test Suite for Data Recipients](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-recipients);
+- 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) in particular [FAPI 1.0 Migration Phase 4](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.33.0/#introduction) with backwards compatibility to Migration Phase 2 and 3;
+- has passed v4.4.0 of the [Conformance Test Suite for Data Recipients](https://www.cdr.gov.au/for-providers/conformance-test-suite-data-recipients);
and
- is certified with the [FAPI 1.0 Advanced Profile](https://openid.net/specs/openid-financial-api-part-2-1_0.html) .
@@ -162,7 +160,7 @@ The Authorisation Server contains the following features:
- Pushed Authorization Requests
- Authorization endpoint
- Support for request_uri parameter
- - Hybrid and Authorization Code flow
+ - Authorization Code flow
- Conforms to Consumer Data Right [CX Guidelines](https://consumerdatastandards.gov.au/guidelines-and-conventions/consumer-experience-guidelines).
- Token endpoint
- Authorization Code
diff --git a/SECURITY.md b/SECURITY.md
index ef53b05..72af26d 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -11,7 +11,8 @@ Visit our [Responsible disclosure of security vulnerabilities policy](https://ww
| Version | Supported |
| ------- | ------------------ |
-| 2.1.x | :white_check_mark: |
+| 3.x.x | :white_check_mark: |
+| 2.x.x | :x: |
| 1.x.x | :x: |
diff --git a/Source/.editorconfig b/Source/.editorconfig
new file mode 100644
index 0000000..2013055
--- /dev/null
+++ b/Source/.editorconfig
@@ -0,0 +1,548 @@
+# 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
+# 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
+
+[ClientClaims.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+[AuthorizationRequestObject.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+[*Client.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+[DataRecipientRequest.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+[Introspection.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+[ClientAssertionValidatorTests.{cs}]
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+dotnet_diagnostic.CS8618.severity = silent
+
+
+[US12962_CDRAuthServer_OIDC_JWKS.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+
+[US15221_US12969_US15584_CdrAuthServer_Registration_POST.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+
+[US12964_CDRAuthServer_OIDC_JWKS.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.S1144.severity = silent
+
+[US12962_CdrAuthServer_OIDC_Configuration.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+
+[US44264_CdrAuthServer_JARM_OIDC.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.S1144.severity = silent
+
+[AuthorizationService.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+
+[DataHolderCDRArrangementRevocationService.{cs}]
+# CS8602: Dereference of a possibly null reference
+dotnet_diagnostic.CS8602.severity = silent
+
+[US44264_CdrAuthServer_JARM_Authorise.{cs}]
+# CS0649: never assigned and will always have default value
+dotnet_diagnostic.CS0649.severity = silent
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+
+[US12678_CdrAuthServer_Authorisation.{cs}]
+# CS0649: never assigned and will always have default value
+dotnet_diagnostic.CS0649.severity = silent
+dotnet_diagnostic.xUnit1026.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+dotnet_diagnostic.SA1210.severity = silent
+
+[US17652_CdrAuthServer_ArrangementRevocation.{cs}]
+dotnet_diagnostic.CS0649.severity = silent
+dotnet_diagnostic.CS8600.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+
+[DataHolderAccessToken.{cs}]
+dotnet_diagnostic.CS8601.severity = silent
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.CS8603.severity = silent
+
+[DataHolderCDRArrangementRevocationService.{cs}]
+dotnet_diagnostic.CS8601.severity = silent
+
+[US44264_CdrAuthServer_JARM_PAR.{cs}]
+dotnet_diagnostic.CS8604.severity = silent
+dotnet_diagnostic.xUnit1013.severity = silent
+
+[US12963_CdrAuthServer_Token.{cs}]
+dotnet_diagnostic.CS8600.severity = silent
+dotnet_diagnostic.CS8601.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+
+[US12968_CdrAuthServer_PAR.{cs}]
+dotnet_diagnostic.CS8625.severity = silent
+dotnet_diagnostic.CS8619.severity = silent
+
+[US15221_US12969_US15584_CdrAuthServer_Registration_POST.{cs}]
+dotnet_diagnostic.CS8604.severity = silent
+
+[US15221_US12969_US15586_CdrAuthServer_Registration_GET.{cs}]
+dotnet_diagnostic.CS8601.severity = silent
+
+[US18469_CdrAuthServer_TokenRevocation.{cs}]
+dotnet_diagnostic.CS8604.severity = silent
+
+[ClientRegistrationValidatorTests.{cs}]
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.CS8604.severity = silent
+dotnet_diagnostic.CS8620.severity = silent
+
+[JwtValidatorTest.{cs}]
+dotnet_diagnostic.CS8604.severity = silent
+dotnet_diagnostic.CS8602.severity = silent
+
+[StringExtensionsTests.{cs}]
+dotnet_diagnostic.CS8600.severity = silent
+
+[ClientAssertionValidatorTests.{cs}]
+dotnet_diagnostic.CS8601.severity = silent
+dotnet_diagnostic.CS8602.severity = silent
+dotnet_diagnostic.CS8620.severity = silent
+
+
+[ResourceController.{cs}]
+dotnet_diagnostic.S6932.severity = silent
+dotnet_diagnostic.S6934.severity = silent
+
+[ClientRegistrationResponse.{cs}]
+dotnet_diagnostic.S2094.severity = silent
+
+[ResourceController.{cs}]
+dotnet_diagnostic.S1135.severity = silent
+
+[*Controller.{cs}]
+dotnet_diagnostic.S6934.severity = silent
+dotnet_diagnostic.S6931.severity = silent
+
+[AesEncryptor.{cs}]
+dotnet_diagnostic.S3329.severity = silent
+
+[GetDataRecipientsFunction.{cs}]
+dotnet_diagnostic.S4830.severity = silent
+
+[CertificateValidator.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[ClientCertificateException.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[WebServerExtensions.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[ICertificateValidator.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[Pkce.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[JsonWebKey.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[JsonWebKeySet.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+
+[GetDataRecipients_IntegrationTestsHelper.{cs}]
+dotnet_diagnostic.SA1513.severity = silent
+dotnet_diagnostic.SA1028.severity = silent
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.SA1516.severity = silent
+dotnet_diagnostic.SA1508.severity = silent
+dotnet_diagnostic.SA1003.severity = silent
+dotnet_diagnostic.SA1137.severity = silent
+dotnet_diagnostic.SA1515.severity = silent
+
+[ClientRepository.{cs}]
+dotnet_diagnostic.S2139.severity = silent
+
+[SoftwareProductConfiguration.{cs}]
+dotnet_diagnostic.S1075.severity = silent
+
+[GrantRepository.{cs}]
+dotnet_diagnostic.S2139.severity = silent
+
+[US39327_CdrAuthServer_E2ETests.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+[US44264_CdrAuthServer_JARM_Authorise.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.S3459.severity = silent
+dotnet_diagnostic.SA1401.severity = silent
+dotnet_diagnostic.SA1307.severity = silent
+[US44264_CdrAuthServer_JARM_DCR.{cs}]
+dotnet_diagnostic.SA1601.severity = silent
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S4144.severity = silent
+dotnet_diagnostic.SA1115.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+dotnet_diagnostic.S3878.severity = silent
+[US44264_CdrAuthServer_JARM_OIDC.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S3459.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.S3878.severity = silent
+[US44264_CdrAuthServer_JARM_PAR.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.SA1114.severity = silent
+dotnet_diagnostic.S1135.severity = silent
+[US44264_CdrAuthServer_JARM_Authorise.{cs}]
+dotnet_diagnostic.S101.severity = silent
+[AuthorizationService.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+[BaseTest.{cs}]
+dotnet_diagnostic.SA1606.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+dotnet_diagnostic.SA1313.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+[ClientAssertionValidatorTests.{cs}]
+dotnet_diagnostic.SA1401.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+[ClientRegistrationValidatorTests.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.S1135.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+dotnet_diagnostic.S125.severity = silent
+[ConnectionStringCheck.{cs}]
+dotnet_diagnostic.S1135.severity = silent
+dotnet_diagnostic.SA1402.severity = silent
+[DatabaseSeeder.{cs}]
+dotnet_diagnostic.SA1117.severity = silent
+dotnet_diagnostic.S1172.severity = silent
+[DataHolderAccessToken.{cs}]
+dotnet_diagnostic.SA1402.severity = silent
+dotnet_diagnostic.SA1649.severity = silent
+[DataHolderCDRArrangementRevocationService.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+[DataHolderIntrospectionService.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+[DcrResponse.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+[IDataHolderCDRArrangementRevocationService.{cs}]
+dotnet_diagnostic.S101.severity = silent
+[JwtValidatorTests.{cs}]
+dotnet_diagnostic.SA1649.severity = silent
+dotnet_diagnostic.SA1306.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+[OpenIdConfiguration.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+[RequestObjectValidatorTests.{cs}]
+dotnet_diagnostic.SA1649.severity = silent
+[SkippableFactTestCase.{cs}]
+dotnet_diagnostic.S1133.severity = silent
+[SkippableTheoryTestCase.{cs}]
+dotnet_diagnostic.S1133.severity = silent
+[TokenRequestValidatorTests.{cs}]
+dotnet_diagnostic.SA1649.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1306.severity = silent
+[US12678_CdrAuthServer_Authorisation.{cs}]
+dotnet_diagnostic.SA1117.severity = silent
+dotnet_diagnostic.S2589.severity = silent
+dotnet_diagnostic.S1135.severity = silent
+[US12962_CdrAuthServer_OIDC_Configuration.{cs}]
+dotnet_diagnostic.SA1601.severity = silent
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S3878.severity = silent
+[US12963_CdrAuthServer_Token.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.SA1124.severity = silent
+dotnet_diagnostic.SA1413.severity = silent
+dotnet_diagnostic.S1135.severity = silent
+dotnet_diagnostic.S1481.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+[US12964_CDRAuthServer_OIDC_JWKS.{cs}]
+dotnet_diagnostic.SA1649.severity = silent
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S3459.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+[US12965_CdrAuthServer_UserInfo.{cs}]
+dotnet_diagnostic.S3459.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.S1172.severity = silent
+dotnet_diagnostic.S1144.severity = silent
+[US12966_CdrAuthServer_Introspection.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.S3459.severity = silent
+dotnet_diagnostic.SA1300.severity = silent
+dotnet_diagnostic.S1144.severity = silent
+[US12968_CdrAuthServer_PAR.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.S2589.severity = silent
+[US15221_US12969_US15584_CdrAuthServer_Registration_POST.{cs}]
+dotnet_diagnostic.S101.severity = silent
+[US15221_US12969_US15585_CdrAuthServer_Registration_PUT.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+[US15221_US12969_US15586_CdrAuthServer_Registration_GET.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+dotnet_diagnostic.SA1509.severity = silent
+dotnet_diagnostic.S1199.severity = silent
+dotnet_diagnostic.S1135.severity = silent
+[US15221_US12969_US15587_CdrAuthServer_Registration_DELETE.{cs}]
+dotnet_diagnostic.S101.severity = silent
+dotnet_diagnostic.SA1316.severity = silent
+dotnet_diagnostic.SA1117.severity = silent
+[US17652_CdrAuthServer_ArrangementRevocation.{cs}]
+dotnet_diagnostic.S4487.severity = silent
+dotnet_diagnostic.SA1509.severity = silent
+dotnet_diagnostic.S2699.severity = silent
+dotnet_diagnostic.S2589.severity = silent
+[US28391_GetDataRecipients.{cs}]
+dotnet_diagnostic.S1172.severity = silent
+dotnet_diagnostic.SA1312.severity = silent
+[US39327_CdrAuthServer_E2ETests.{cs}]
+dotnet_diagnostic.S2933.severity = silent
+dotnet_diagnostic.S1481.severity = silent
+[DisplayTestMethodNameAttribute.{cs}]
+dotnet_diagnostic.S3993.severity = silent
+[HttpHelperTests.{cs}]
+dotnet_diagnostic.SA1402.severity = silent
+dotnet_diagnostic.SA1601.severity = silent
+dotnet_diagnostic.S1144.severity = silent
+[ParValidatorTest.{cs}]
+dotnet_diagnostic.SA1300.severity = silent
+[SkippableFactAttribute.{cs}]
+dotnet_diagnostic.S3993.severity = silent
+[SkippableFactMessageBus.{cs}]
+dotnet_diagnostic.S3881.severity = silent
+[SkippableTheoryAttribute.{cs}]
+dotnet_diagnostic.S3993.severity = silent
+[StringExtensionsTests.{cs}]
+dotnet_diagnostic.S1186.severity = silent
diff --git a/Source/CdrAuthServer.API.Logger/CdrAuthServer.API.Logger.csproj b/Source/CdrAuthServer.API.Logger/CdrAuthServer.API.Logger.csproj
index 59e9d34..8de99f8 100644
--- a/Source/CdrAuthServer.API.Logger/CdrAuthServer.API.Logger.csproj
+++ b/Source/CdrAuthServer.API.Logger/CdrAuthServer.API.Logger.csproj
@@ -6,16 +6,27 @@
$(Version)
$(Version)
enable
- enable
+ enable
+ True
+
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/Source/CdrAuthServer.API.Logger/IRequestResponseLogger.cs b/Source/CdrAuthServer.API.Logger/IRequestResponseLogger.cs
index b9b488f..3c30a86 100644
--- a/Source/CdrAuthServer.API.Logger/IRequestResponseLogger.cs
+++ b/Source/CdrAuthServer.API.Logger/IRequestResponseLogger.cs
@@ -6,4 +6,4 @@ public interface IRequestResponseLogger
{
ILogger Log { get; }
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.API.Logger/LoggerExtensions.cs b/Source/CdrAuthServer.API.Logger/LoggerExtensions.cs
index 8fa3c2a..d4f0a13 100644
--- a/Source/CdrAuthServer.API.Logger/LoggerExtensions.cs
+++ b/Source/CdrAuthServer.API.Logger/LoggerExtensions.cs
@@ -10,4 +10,4 @@ public static IServiceCollection AddRequestResponseLogging(this IServiceCollecti
return services;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.API.Logger/RequestResponseLogger.cs b/Source/CdrAuthServer.API.Logger/RequestResponseLogger.cs
index 97b1aa8..d604013 100644
--- a/Source/CdrAuthServer.API.Logger/RequestResponseLogger.cs
+++ b/Source/CdrAuthServer.API.Logger/RequestResponseLogger.cs
@@ -1,33 +1,49 @@
namespace CdrAuthServer.API.Logger
{
- using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Core;
+ using Serilog.Settings.Configuration;
public class RequestResponseLogger : IRequestResponseLogger, IDisposable
{
private readonly Logger _logger;
- public ILogger Log { get { return _logger; } }
+
+ public ILogger Log
+ {
+ get { return _logger; }
+ }
public RequestResponseLogger(IConfiguration configuration)
{
- _logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration, sectionName: "SerilogRequestResponseLogger")
- .Enrich.WithProperty("RequestMethod", "")
- .Enrich.WithProperty("RequestBody", "")
- .Enrich.WithProperty("RequestHeaders", "")
- .Enrich.WithProperty("RequestPath", "")
- .Enrich.WithProperty("RequestQueryString", "")
- .Enrich.WithProperty("StatusCode", "")
- .Enrich.WithProperty("ElapsedTime", "")
- .Enrich.WithProperty("ResponseHeaders", "")
- .Enrich.WithProperty("ResponseBody", "")
- .Enrich.WithProperty("RequestHost", "")
- .Enrich.WithProperty("RequestIpAddress", "")
- .Enrich.WithProperty("ClientId", "")
- .Enrich.WithProperty("SoftwareId", "")
- .Enrich.WithProperty("FapiInteractionId", "")
+ var loggerConfiguration = new LoggerConfiguration();
+
+ // If the Serilog response loggins is disabled, do not configure it using the appsettings.
+ var isSerilogRequestResponseLoggerDisabled =
+ configuration.GetValue("SerilogRequestResponseLogger:IsDisabled", false);
+ if (isSerilogRequestResponseLoggerDisabled)
+ {
+ _logger = loggerConfiguration.CreateLogger();
+ return;
+ }
+
+ var options = new ConfigurationReaderOptions { SectionName = "SerilogRequestResponseLogger" };
+ _logger = loggerConfiguration
+ .ReadFrom.Configuration(configuration, options)
+ .Enrich.WithProperty("RequestMethod", string.Empty)
+ .Enrich.WithProperty("RequestBody", string.Empty)
+ .Enrich.WithProperty("RequestHeaders", string.Empty)
+ .Enrich.WithProperty("RequestPath", string.Empty)
+ .Enrich.WithProperty("RequestQueryString", string.Empty)
+ .Enrich.WithProperty("StatusCode", string.Empty)
+ .Enrich.WithProperty("ElapsedTime", string.Empty)
+ .Enrich.WithProperty("ResponseHeaders", string.Empty)
+ .Enrich.WithProperty("ResponseBody", string.Empty)
+ .Enrich.WithProperty("RequestHost", string.Empty)
+ .Enrich.WithProperty("RequestIpAddress", string.Empty)
+ .Enrich.WithProperty("ClientId", string.Empty)
+ .Enrich.WithProperty("SoftwareId", string.Empty)
+ .Enrich.WithProperty("FapiInteractionId", string.Empty)
.CreateLogger();
}
@@ -42,7 +58,7 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
Serilog.Log.CloseAndFlush();
- }
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.API.Logger/RequestResponseLoggingMiddleware.cs b/Source/CdrAuthServer.API.Logger/RequestResponseLoggingMiddleware.cs
index 63c5615..4213413 100644
--- a/Source/CdrAuthServer.API.Logger/RequestResponseLoggingMiddleware.cs
+++ b/Source/CdrAuthServer.API.Logger/RequestResponseLoggingMiddleware.cs
@@ -14,12 +14,16 @@ namespace CdrAuthServer.API.Logger
{
public class RequestResponseLoggingMiddleware
{
- const string httpSummaryMessageTemplate =
- "HTTP {RequestMethod} {RequestScheme:l}://{RequestHost:l}{RequestPathBase:l}{RequestPath:l} responded {StatusCode} in {ElapsedTime:0.0000} ms.";
+ private const string HttpSummaryMessageTemplate =
+ "HTTP {RequestMethod} {RequestScheme:l}://{RequestHost:l}{RequestPathBase:l}{RequestPath:l} responded {StatusCode} in {ElapsedTime:0.0000} ms.";
- const string httpSummaryExceptionMessageTemplate =
+ private const string HttpSummaryExceptionMessageTemplate =
"HTTP {RequestMethod} {RequestScheme:l}://{RequestHost:l}{RequestPathBase:l}{RequestPath:l} encountered following error {error}";
+ private readonly RecyclableMemoryStreamManager _recyclableMemoryStreamManager;
+ private readonly RequestDelegate _next;
+ private readonly ILogger _requestResponseLogger;
+ private readonly IConfiguration _configuration;
private string? _requestMethod;
private string? _requestBody;
private string? _requestHeaders;
@@ -36,20 +40,13 @@ public class RequestResponseLoggingMiddleware
private string? _requestPathBase;
private string? _clientId;
private string? _softwareId;
- private string? _fapiInteractionId;
-
-
- private readonly RecyclableMemoryStreamManager _recyclableMemoryStreamManager;
- readonly RequestDelegate _next;
- private readonly ILogger _requestResponseLogger;
- private readonly IConfiguration _configuration;
-
+ private string? _fapiInteractionId;
public RequestResponseLoggingMiddleware(RequestDelegate next, IRequestResponseLogger requestResponseLogger, IConfiguration configuration)
{
_requestResponseLogger = requestResponseLogger.Log.ForContext();
_next = next ?? throw new ArgumentNullException(nameof(next));
- _recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
+ _recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
_configuration = configuration;
}
@@ -87,15 +84,14 @@ private void LogWithContext()
if (!string.IsNullOrEmpty(_exceptionMessage))
{
- logger.Error(httpSummaryExceptionMessageTemplate, _requestMethod, _requestScheme, _requestHost, _requestPathBase, _requestPath, _exceptionMessage);
+ logger.Error(HttpSummaryExceptionMessageTemplate, _requestMethod, _requestScheme, _requestHost, _requestPathBase, _requestPath, _exceptionMessage);
}
else
{
- logger.Write(LogEventLevel.Information, httpSummaryMessageTemplate, _requestMethod, _requestScheme, _requestHost, _requestPathBase, _requestPath, _statusCode, _elapsedTime);
+ logger.Write(LogEventLevel.Information, HttpSummaryMessageTemplate, _requestMethod, _requestScheme, _requestHost, _requestPathBase, _requestPath, _statusCode, _elapsedTime);
}
}
-
private async Task ExtractRequestProperties(HttpContext context)
{
try
@@ -126,7 +122,7 @@ private async Task ExtractRequestProperties(HttpContext context)
}
}
- static class ClaimIdentifiers
+ private static class ClaimIdentifiers
{
public const string ClientId = "client_id";
public const string SoftwareId = "software_id";
@@ -139,7 +135,7 @@ private static void SetIdFromJwt(string jwt, string identifierType, ref string i
if (handler.CanReadToken(jwt))
{
var decodedJwt = handler.ReadJwtToken(jwt);
- var id = decodedJwt.Claims.FirstOrDefault(x => x.Type == identifierType)?.Value ?? "";
+ var id = decodedJwt.Claims.FirstOrDefault(x => x.Type == identifierType)?.Value ?? string.Empty;
idToSet = id;
}
@@ -149,14 +145,14 @@ private void ExtractIdFromRequest(HttpRequest request)
{
try
{
- //try fetching x-fapi-interaction-id. After fetching we don't return as we need other important ids.
+ // try fetching x-fapi-interaction-id. After fetching we don't return as we need other important ids.
_fapiInteractionId = string.Empty;
if (request.Headers.TryGetValue("x-fapi-interaction-id", out var interactionid))
{
_fapiInteractionId = interactionid;
}
- //try fetching from the JWT in the authorization header
+ // try fetching from the JWT in the authorization header
var authorization = request.Headers[HeaderNames.Authorization];
if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue) && string.IsNullOrEmpty(_clientId))
{
@@ -165,12 +161,12 @@ private void ExtractIdFromRequest(HttpRequest request)
if (scheme == JwtBearerDefaults.AuthenticationScheme && parameter != null)
{
- _clientId = String.Empty;
+ _clientId = string.Empty;
SetIdFromJwt(parameter, ClaimIdentifiers.ClientId, ref _clientId);
}
}
- //try fetching from the clientid in the body for connect/par
+ // try fetching from the clientid in the body for connect/par
if (!string.IsNullOrEmpty(_requestBody) && _requestBody.Contains("client_assertion=") && string.IsNullOrEmpty(_clientId))
{
var nameValueCollection = HttpUtility.ParseQueryString(_requestBody);
@@ -181,14 +177,13 @@ private void ExtractIdFromRequest(HttpRequest request)
if (assertion != null)
{
// in this case we set the iss to clientid
- _clientId = String.Empty;
+ _clientId = string.Empty;
SetIdFromJwt(assertion, ClaimIdentifiers.Iss, ref _clientId);
}
}
-
}
- //try fetching from the clientid in the body account/login, /consent, /token
+ // try fetching from the clientid in the body account/login, /consent, /token
if (!string.IsNullOrEmpty(_requestBody) && _requestBody.Contains(ClaimIdentifiers.ClientId) && string.IsNullOrEmpty(_clientId))
{
var decodedBody = HttpUtility.UrlDecode(_requestBody);
@@ -211,10 +206,9 @@ private void ExtractIdFromRequest(HttpRequest request)
}
}
-
if (request.ContentType == "application/jwt")
{
- //decode jwt sent to register
+ // decode jwt sent to register
var handler = new JwtSecurityTokenHandler();
if (handler.CanReadToken(_requestBody))
{
@@ -223,14 +217,14 @@ private void ExtractIdFromRequest(HttpRequest request)
if (softStatementValue != null)
{
- _softwareId = String.Empty;
+ _softwareId = string.Empty;
SetIdFromJwt(softStatementValue, ClaimIdentifiers.SoftwareId, ref _softwareId);
return;
}
}
}
- //try fetching from query string, this should be the last place to check for client id.
+ // try fetching from query string, this should be the last place to check for client id.
if (request.QueryString.Value?.Contains(ClaimIdentifiers.ClientId) == true && string.IsNullOrEmpty(_clientId))
{
var nameValueCollection = HttpUtility.ParseQueryString(request.QueryString.Value);
@@ -244,7 +238,6 @@ private void ExtractIdFromRequest(HttpRequest request)
{
_exceptionMessage = ex.Message;
}
-
}
private string ReadStreamInChunks(Stream stream)
@@ -261,7 +254,8 @@ private string ReadStreamInChunks(Stream stream)
{
readChunkLength = reader.ReadBlock(readChunk, 0, readChunkBufferLength);
textWriter.Write(readChunk, 0, readChunkLength);
- } while (readChunkLength > 0);
+ }
+ while (readChunkLength > 0);
return textWriter.ToString();
}
catch (Exception ex)
@@ -269,13 +263,11 @@ private string ReadStreamInChunks(Stream stream)
_exceptionMessage = ex.Message;
}
- return "";
+ return string.Empty;
}
-
private async Task ExtractResponseProperties(HttpContext httpContext)
{
-
var originalBodyStream = httpContext.Response.Body;
await using var responseBody = _recyclableMemoryStreamManager.GetStream();
httpContext.Response.Body = responseBody;
@@ -318,13 +310,13 @@ private string GetHost(HttpRequest request)
// 1. check if the X-Forwarded-Host header has been provided -> use that
// 2. If not, use the request.Host
string hostHeaderKey = _configuration.GetValue("SerilogRequestResponseLogger:HostNameHeaderKey") ?? "X-Forwarded-Host";
-
+
if (!request.Headers.TryGetValue(hostHeaderKey, out var keys))
{
return request.Host.ToString();
}
- return keys[0] ?? "";
+ return keys[0] ?? string.Empty;
}
private string? GetIpAddress(HttpContext context)
@@ -340,7 +332,7 @@ private string GetHost(HttpRequest request)
// the traffic traverses through. We get the first (and potentially only) ip address from the list as the client IP.
// We also remove any port numbers that may be included on the client IP.
return keys[0]?
- .Split(',')[0] // Get the first IP address in the list, in case there are multiple.
+ .Split(',')[0] // Get the first IP address in the list, in case there are multiple.
.Split(':')[0]; // Strip off the port number, in case it is attached to the IP address.
}
@@ -348,19 +340,18 @@ private string GetSourceContext()
{
// local containers have ports with requesthost e.g. mock-data-holder:8001
// test environment has mock-data-holder
-
if (string.IsNullOrEmpty(_requestHost))
{
return string.Empty;
}
-
+
if (_requestHost.Contains("mock-data-holder-energy"))
{
return "SB-DHE-ID";
}
if (_requestHost.Contains("mock-data-holder"))
- {
+ {
return "SB-DHB-ID";
}
diff --git a/Source/CdrAuthServer.Domain/CdrAuthServer.Domain.csproj b/Source/CdrAuthServer.Domain/CdrAuthServer.Domain.csproj
index 298509a..fe2de7a 100644
--- a/Source/CdrAuthServer.Domain/CdrAuthServer.Domain.csproj
+++ b/Source/CdrAuthServer.Domain/CdrAuthServer.Domain.csproj
@@ -19,7 +19,8 @@
-
+
+
diff --git a/Source/CdrAuthServer.Domain/Constants.cs b/Source/CdrAuthServer.Domain/Constants.cs
index c900b12..3bb4f80 100644
--- a/Source/CdrAuthServer.Domain/Constants.cs
+++ b/Source/CdrAuthServer.Domain/Constants.cs
@@ -105,8 +105,6 @@ public static class ClientMetadata
public const string ClientMetaDataResponseTypes = "response_types";
public const string ApplicationType = "application_type";
public const string IdTokenSignedResponseAlg = "id_token_signed_response_alg";
- public const string IdTokenEncryptedResponseAlg = "id_token_encrypted_response_alg";
- public const string IdTokenEncryptedResponseEnc = "id_token_encrypted_response_enc";
public const string RequestObjectSigningAlg = "request_object_signing_alg";
public const string SoftwareStatement = "software_statement";
public const string AuthorizationSignedResponseAlg = "authorization_signed_response_alg";
@@ -216,16 +214,11 @@ public static class GrantTypes
public const string RefreshToken = "refresh_token";
public const string AuthCode = "authorization_code";
public const string ClientCredentials = "client_credentials";
- public const string Hybrid = "hybrid";
public const string RequestUri = "request_uri";
}
public static class ResponseModes
{
- public const string FormPost = "form_post";
- public const string Fragment = "fragment";
- public const string FormPostJwt = "form_post.jwt";
- public const string FragmentJwt = "fragment.jwt";
public const string QueryJwt = "query.jwt";
public const string Jwt = "jwt";
}
@@ -233,14 +226,12 @@ public static class ResponseModes
public static class ResponseTypes
{
public const string AuthCode = "code";
- public const string Hybrid = "code id_token";
}
// The order of the response modes represents the precedence for each response type.
public static readonly ImmutableDictionary SupportedResponseModesForResponseType = new Dictionary
{
- { ResponseTypes.Hybrid, new string[] { ResponseModes.Fragment, ResponseModes.FormPost } },
- { ResponseTypes.AuthCode, new string[] { ResponseModes.QueryJwt, ResponseModes.FragmentJwt, ResponseModes.FormPostJwt, ResponseModes.Jwt } },
+ { ResponseTypes.AuthCode, new string[] { ResponseModes.Jwt } },
}.ToImmutableDictionary();
public static class ValidationRestrictions
diff --git a/Source/CdrAuthServer.Domain/Entities/Client.cs b/Source/CdrAuthServer.Domain/Entities/Client.cs
index c3def05..07a0b86 100644
--- a/Source/CdrAuthServer.Domain/Entities/Client.cs
+++ b/Source/CdrAuthServer.Domain/Entities/Client.cs
@@ -141,13 +141,13 @@ public class Client
/// Gets a JWE `alg` algorithm with which an id_token is to be encrypted.
///
[JsonProperty("id_token_encrypted_response_alg")]
- public string IdTokenEncryptedResponseAlg { get; set; } = string.Empty;
+ public string? IdTokenEncryptedResponseAlg { get; set; }
///
/// Gets a JWE `enc` algorithm with which an id_token is to be encrypted.
///
[JsonProperty("id_token_encrypted_response_enc")]
- public string IdTokenEncryptedResponseEnc { get; set; } = string.Empty;
+ public string? IdTokenEncryptedResponseEnc { get; set; }
///
/// Gets an algorithm which the ADR expects to sign the request object if a request object will be part of the authorization request sent to the Data Holder.
@@ -189,7 +189,7 @@ public class Client
/// Gets an algorithm with which an auth response is to be signed (JARM).
///
[JsonProperty("authorization_signed_response_alg")]
- public string? AuthorizationSignedResponseAlg { get; set; } = null;
+ public string? AuthorizationSignedResponseAlg { get; set; } = null;
///
/// Gets a JWE `alg` algorithm with which an auth response is to be encrypted (JARM).
@@ -203,4 +203,4 @@ public class Client
[JsonProperty("authorization_encrypted_response_enc")]
public string? AuthorizationEncryptedResponseEnc { get; set; } = null;
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.Domain/Entities/Grant.cs b/Source/CdrAuthServer.Domain/Entities/Grant.cs
index 2ac4f4b..b7ae5ef 100644
--- a/Source/CdrAuthServer.Domain/Entities/Grant.cs
+++ b/Source/CdrAuthServer.Domain/Entities/Grant.cs
@@ -19,5 +19,5 @@ public class Grant
public string Scope { get; set; } = string.Empty;
public virtual IDictionary Data { get; set; } = new Dictionary();
- }
+ }
}
diff --git a/Source/CdrAuthServer.Domain/Enums/CdsErrors.cs b/Source/CdrAuthServer.Domain/Enums/CdsErrors.cs
index a887334..dbae9ff 100644
--- a/Source/CdrAuthServer.Domain/Enums/CdsErrors.cs
+++ b/Source/CdrAuthServer.Domain/Enums/CdsErrors.cs
@@ -16,7 +16,7 @@ public enum CdsError
[CdrError(Constants.ErrorTitles.ServiceUnavailable, Constants.ErrorCodes.Cds.ServiceUnavailable)]
ServiceUnavailable,
- [CdrError(Constants.ErrorTitles.MissingRequiredField,Constants.ErrorCodes.Cds.MissingRequiredField)]
+ [CdrError(Constants.ErrorTitles.MissingRequiredField, Constants.ErrorCodes.Cds.MissingRequiredField)]
MissingRequiredField,
[CdrError(Constants.ErrorTitles.MissingRequiredHeader, Constants.ErrorCodes.Cds.MissingRequiredHeader)]
diff --git a/Source/CdrAuthServer.Domain/Models/ResponseErrorList.cs b/Source/CdrAuthServer.Domain/Models/ResponseErrorList.cs
index eb92aba..cd1ef52 100644
--- a/Source/CdrAuthServer.Domain/Models/ResponseErrorList.cs
+++ b/Source/CdrAuthServer.Domain/Models/ResponseErrorList.cs
@@ -11,7 +11,7 @@ public class ResponseErrorList
public bool HasErrors()
{
- return Errors != null && Errors.Count!=0;
+ return Errors != null && Errors.Count != 0;
}
public ResponseErrorList()
diff --git a/Source/CdrAuthServer.E2ETests/BaseTest.cs b/Source/CdrAuthServer.E2ETests/BaseTest.cs
index b72c4b2..8ffa65b 100644
--- a/Source/CdrAuthServer.E2ETests/BaseTest.cs
+++ b/Source/CdrAuthServer.E2ETests/BaseTest.cs
@@ -1,4 +1,4 @@
-#define TEST_DEBUG_MODE // Run Playwright in non-headless mode for debugging purposes (ie show a browser)
+#define TEST_DEBUG_MODE // Run Playwright in non-headless mode for debugging purposes (ie show a browser)
// In docker (Ubuntu container) Playwright will fail if running in non-headless mode, so we ensure TEST_DEBUG_MODE is undef'ed
#if !DEBUG
@@ -15,10 +15,11 @@ namespace CdrAuthServer.E2ETests
// Put all tests in same collection because we need them to run sequentially since some tests are mutating DB.
[Collection("E2ETests")]
[TestCaseOrderer("CdrAuthServer.E2ETests.XUnit.Orderers.AlphabeticalOrderer", "CdrAuthServer.E2ETests")]
- abstract public class BaseTest : SharedBaseTest
+ public abstract class BaseTest : SharedBaseTest
{
- protected BaseTest(ITestOutputHelperAccessor testOutputHelperAccessor, IConfiguration config) : base(testOutputHelperAccessor, config)
+ protected BaseTest(ITestOutputHelperAccessor testOutputHelperAccessor, IConfiguration config)
+ : base(testOutputHelperAccessor, config)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.E2ETests/CdrAuthServer.E2ETests.csproj b/Source/CdrAuthServer.E2ETests/CdrAuthServer.E2ETests.csproj
index 37c00b7..1e826cf 100644
--- a/Source/CdrAuthServer.E2ETests/CdrAuthServer.E2ETests.csproj
+++ b/Source/CdrAuthServer.E2ETests/CdrAuthServer.E2ETests.csproj
@@ -8,6 +8,7 @@
Debug;Release;Shared
enable
enable
+ True
@@ -29,7 +30,7 @@
-
+
@@ -40,6 +41,14 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Source/CdrAuthServer.E2ETests/Startup.cs b/Source/CdrAuthServer.E2ETests/Startup.cs
index 1aa9a0b..2208229 100644
--- a/Source/CdrAuthServer.E2ETests/Startup.cs
+++ b/Source/CdrAuthServer.E2ETests/Startup.cs
@@ -17,14 +17,14 @@ public Startup(IConfiguration configuration)
public static void ConfigureServices(IServiceCollection services)
{
- //Setup config
+ // Setup config
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true)
.Build();
- //Setting up logger early so we can catch any startup issues
+ // Setting up logger early so we can catch any startup issues
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration: configuration)
.CreateBootstrapLogger();
@@ -37,21 +37,23 @@ public static void ConfigureServices(IServiceCollection services)
opt.INDUSTRY = Industry.BANKING;
opt.SCOPE = ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Constants.Scopes.ScopeBanking;
- opt.DH_MTLS_GATEWAY_URL = configuration["URL:DH_MTLS_Gateway"]??string.Empty;
- opt.DH_TLS_AUTHSERVER_BASE_URL = configuration["URL:DH_TLS_AuthServer"]??string.Empty;
+ opt.DH_MTLS_GATEWAY_URL = configuration["URL:DH_MTLS_Gateway"] ?? string.Empty;
+ opt.DH_TLS_AUTHSERVER_BASE_URL = configuration["URL:DH_TLS_AuthServer"] ?? string.Empty;
opt.DH_TLS_PUBLIC_BASE_URL = configuration["URL:DH_TLS_Public"] ?? string.Empty;
opt.REGISTER_MTLS_URL = configuration["URL:Register_MTLS"] ?? string.Empty;
+
// Connection strings
opt.DATAHOLDER_CONNECTIONSTRING = configuration["ConnectionStrings:DataHolder"] ?? string.Empty;
opt.AUTHSERVER_CONNECTIONSTRING = configuration["ConnectionStrings:AuthServer"] ?? string.Empty;
opt.REGISTER_CONNECTIONSTRING = configuration["ConnectionStrings:Register"] ?? string.Empty;
+
// Seed-data offset
- opt.SEEDDATA_OFFSETDATES = (configuration["SeedData:OffsetDates"] == "true");
+ opt.SEEDDATA_OFFSETDATES = configuration["SeedData:OffsetDates"] == "true";
opt.MDH_INTEGRATION_TESTS_HOST = configuration["URL:MDH_INTEGRATION_TESTS_HOST"] ?? string.Empty;
opt.MDH_HOST = configuration["URL:MDH_HOST"] ?? string.Empty;
- opt.CDRAUTHSERVER_SECUREBASEURI = configuration["URL:CDRAuthServer_SecureBaseUri"] ?? string.Empty;
+ opt.CDRAUTHSERVER_SECUREBASEURI = configuration["URL:CDRAuthServer_SecureBaseUri"] ?? string.Empty;
// Playwright settings.
opt.RUNNING_IN_CONTAINER = Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER")?.ToUpper() == "TRUE";
@@ -62,9 +64,9 @@ public static void ConfigureServices(IServiceCollection services)
services.AddTestAutomationAuthServerSettings(opt =>
{
- opt.CDRAUTHSERVER_BASEURI = configuration["URL:CDRAuthServer_BaseUri"] ?? string.Empty; ;
+ opt.CDRAUTHSERVER_BASEURI = configuration["URL:CDRAuthServer_BaseUri"] ?? string.Empty;
opt.STANDALONE = configuration["Standalone"]!.ToUpper() == "TRUE";
- opt.XTLSCLIENTCERTTHUMBPRINT = configuration["XTlsClientCertThumbprint"]??string.Empty; ;
+ opt.XTLSCLIENTCERTTHUMBPRINT = configuration["XTlsClientCertThumbprint"] ?? string.Empty;
opt.XTLSADDITIONALCLIENTCERTTHUMBPRINT = configuration["XTlsAdditionalClientCertThumbprint"] ?? string.Empty;
opt.ACCESSTOKENLIFETIMESECONDS = Convert.ToInt32(configuration["AccessTokenLifetimeSeconds"]);
});
diff --git a/Source/CdrAuthServer.E2ETests/US39327_CdrAuthServer_E2ETests.cs b/Source/CdrAuthServer.E2ETests/US39327_CdrAuthServer_E2ETests.cs
index e52c91c..b3c21d6 100644
--- a/Source/CdrAuthServer.E2ETests/US39327_CdrAuthServer_E2ETests.cs
+++ b/Source/CdrAuthServer.E2ETests/US39327_CdrAuthServer_E2ETests.cs
@@ -1,4 +1,4 @@
-using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation;
+using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation;
using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums;
using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.AuthoriseExceptions;
using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions;
@@ -34,8 +34,7 @@ public US39327_CdrAuthServer_E2ETests(
IApiServiceDirector apiServiceDirector,
ITestOutputHelperAccessor testOutputHelperAccessor,
Microsoft.Extensions.Configuration.IConfiguration config)
- : base(testOutputHelperAccessor, config
- )
+ : base(testOutputHelperAccessor, config)
{
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
_authServerOptions = authServerOptions.Value ?? throw new ArgumentNullException(nameof(authServerOptions));
@@ -47,8 +46,8 @@ public US39327_CdrAuthServer_E2ETests(
_apiServiceDirector = apiServiceDirector ?? throw new ArgumentNullException(nameof(apiServiceDirector));
}
- PlaywrightDriver _playwrightDriver = new PlaywrightDriver();
- IBrowserContext? _browserContext;
+ private PlaywrightDriver _playwrightDriver = new PlaywrightDriver();
+ private IBrowserContext? _browserContext;
public const string CUSTOMERID_BANKING = "ksmith";
public const string DEFAULT_OPT = "000789";
@@ -62,59 +61,9 @@ public US39327_CdrAuthServer_E2ETests(
private readonly IDataHolderAccessTokenCache _dataHolderAccessTokenCache;
private readonly IApiServiceDirector _apiServiceDirector;
- [Theory]
- [InlineData(ResponseMode.FormPost)]
- public async Task AC01_Authorize_HybridFlow_ShouldRespondWith_AuthCodeAndIdToken(ResponseMode responseMode)
- {
- Log.Information("Running test with Params: {P1}={V1}.", nameof(responseMode), responseMode);
-
- // Arrange
- Uri authRedirect = await Authorise(
- ResponseType.CodeIdToken, // ie Hybrid flow
- responseMode,
- _options.SCOPE);
- var authRedirectLeftPart = authRedirect.GetLeftPart(UriPartial.Authority) + "/ui";
-
- _browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(AC01_Authorize_HybridFlow_ShouldRespondWith_AuthCodeAndIdToken)} - {responseMode}");
-
- var page = await _browserContext.NewPageAsync();
-
- await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
-
- // Username
- AuthenticateLoginPage authenticateLoginPage = new(page);
- await authenticateLoginPage.EnterCustomerId(CUSTOMERID_BANKING);
- await authenticateLoginPage.ClickContinue();
-
- // OTP
- OneTimePasswordPage oneTimePasswordPage = new(page);
- await oneTimePasswordPage.EnterOtp(DEFAULT_OPT);
- await oneTimePasswordPage.ClickContinue();
-
- // Select accounts
- SelectAccountsPage selectAccountsPage = new(page);
- await selectAccountsPage.SelectAccounts("Personal Loan");
- await selectAccountsPage.ClickContinue();
-
- // Confirmation - Click authorise and check callback response
- ConfirmAccountSharingPage confirmAccountSharingPage = new(page);
- (string? code, string? idtoken) = await HybridFlow_HandleCallback(responseMode: responseMode, page: page, setup: async (page) =>
- {
- await confirmAccountSharingPage.ClickAuthorise();
- });
-
- using (new AssertionScope(BaseTestAssertionStrategy))
- {
- code.Should().NotBeNullOrEmpty();
- idtoken.Should().NotBeNullOrEmpty();
- }
-
- }
-
[Fact]
public async Task AC01_Authorize_CodeFlow_ShouldRespondWith_AuthCodeAndIdToken()
{
-
// Arrange
Uri authRedirect = await Authorise(
ResponseType.Code, // ie Code flow
@@ -168,7 +117,6 @@ public async Task AC01_Authorize_CodeFlow_ShouldRespondWith_AuthCodeAndIdToken()
tokenResponse?.AccessToken.Should().NotBeNullOrEmpty();
tokenResponse?.IdToken.Should().NotBeNullOrEmpty();
tokenResponse?.RefreshToken.Should().NotBeNullOrEmpty();
-
}
}
@@ -180,7 +128,7 @@ public async Task ACX02_Cancel_Otp_And_Verify_Callback()
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX02_Cancel_Otp_And_Verify_Callback)}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -192,7 +140,6 @@ public async Task ACX02_Cancel_Otp_And_Verify_Callback()
// Assert
await AssertCancelCallback(async () => await oneTimePasswordPage.ClickCancel());
-
}
[Fact]
@@ -203,7 +150,7 @@ public async Task ACX03_Cancel_Select_Accounts_And_Verify_Callback()
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX03_Cancel_Select_Accounts_And_Verify_Callback)}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -219,7 +166,6 @@ public async Task ACX03_Cancel_Select_Accounts_And_Verify_Callback()
// Assert
await AssertCancelCallback(async () => await selectAccountsPage.ClickCancel());
-
}
[Fact]
@@ -230,7 +176,7 @@ public async Task ACX04_Deny_Account_Confirmation_And_Verify_Callback()
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX04_Deny_Account_Confirmation_And_Verify_Callback)}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -249,7 +195,6 @@ public async Task ACX04_Deny_Account_Confirmation_And_Verify_Callback()
// Assert
await AssertCancelCallback(async () => await confirmAccountSharingPage.ClickDeny());
-
}
[Theory]
@@ -260,11 +205,11 @@ public async Task ACX05_Invalid_Customer_Id(string testSuffix, string customerId
Log.Information("Running test with Params: {P1}={V1}, {P2}={V2}, {P3}={V3}.", nameof(testSuffix), testSuffix, nameof(customerIdToEnter), customerIdToEnter, nameof(expectedError), expectedError);
// Arrange
- Uri authRedirect = await Authorise(ResponseType.CodeIdToken, ResponseMode.FormPost, _options.SCOPE);
+ Uri authRedirect = await Authorise(ResponseType.Code, ResponseMode.Jwt, _options.SCOPE);
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX05_Invalid_Customer_Id)} - {testSuffix}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -277,7 +222,6 @@ public async Task ACX05_Invalid_Customer_Id(string testSuffix, string customerId
{
invalidCustomerIdMessageExists.Should().Be(true, $"Customer Id of '{customerIdToEnter}' was entered and expected '{expectedError}'.");
}
-
}
[Theory]
@@ -286,12 +230,13 @@ public async Task ACX05_Invalid_Customer_Id(string testSuffix, string customerId
public async Task ACX06_Invalid_One_Time_Password(string testSuffix, string otpToEnter, string expectedError)
{
Log.Information("Running test with Params: {P1}={V1}, {P2}={V2}, {P3}={V3}.", nameof(testSuffix), testSuffix, nameof(otpToEnter), otpToEnter, nameof(expectedError), expectedError);
+
// Arrange
- Uri authRedirect = await Authorise(ResponseType.CodeIdToken, ResponseMode.FormPost, _options.SCOPE);
+ Uri authRedirect = await Authorise(ResponseType.Code, ResponseMode.Jwt, _options.SCOPE);
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX06_Invalid_One_Time_Password)} - {testSuffix}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -308,18 +253,17 @@ public async Task ACX06_Invalid_One_Time_Password(string testSuffix, string otpT
{
invalidOptMessageExists.Should().Be(true, $"OTP of '{otpToEnter}' was entered and expected '{expectedError}'.");
}
-
}
[Fact]
public async Task ACX07_No_Accounts_Selected()
{
// Arrange
- Uri authRedirect = await Authorise(ResponseType.CodeIdToken, ResponseMode.FormPost, _options.SCOPE);
+ Uri authRedirect = await Authorise(ResponseType.Code, ResponseMode.Jwt, _options.SCOPE);
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX06_Invalid_One_Time_Password)}");
var page = await _browserContext.NewPageAsync();
- // Act
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -339,47 +283,82 @@ public async Task ACX07_No_Accounts_Selected()
{
noAccountSelectedErrorExists.Should().Be(true, $"No accounts were selected in the account selection form.");
}
-
}
// The test below aims to cover all Common, Banking and Energy scopes. Including the merging of Basic and Detailed clusters.
[Theory]
- //Common
- [InlineData("AC01-3AU.02.14 Common Basic with Profile", "openid profile common:customer.basic:read cdr:registration",
+
+ // Common
+ [InlineData(
+ "AC01-3AU.02.14 Common Basic with Profile",
+ "openid profile common:customer.basic:read cdr:registration",
new ClusterType[] { ClusterType.CommonName, ClusterType.CommonNameAndOccupation })]
- [InlineData("AC02-3AU.02.14 Common Basic with Detailed Common", "openid common:customer.basic:read common:customer.detail:read cdr:registration",
+ [InlineData(
+ "AC02-3AU.02.14 Common Basic with Detailed Common",
+ "openid common:customer.basic:read common:customer.detail:read cdr:registration",
new ClusterType[] { ClusterType.CommonNameAndOccupation, ClusterType.CommonContactDetails })]
- [InlineData("AC03-3AU.02.14 Common Detailed Common Only", "openid common:customer.detail:read cdr:registration",
+ [InlineData(
+ "AC03-3AU.02.14 Common Detailed Common Only",
+ "openid common:customer.detail:read cdr:registration",
new ClusterType[] { ClusterType.CommonNameOccupationAndContactDetails })]
- //Banking
- [InlineData("AC04-3AU.02.14 Bank Detailed with Bank Basic", "openid bank:accounts.detail:read bank:accounts.basic:read",
+
+ // Banking
+ [InlineData(
+ "AC04-3AU.02.14 Bank Detailed with Bank Basic",
+ "openid bank:accounts.detail:read bank:accounts.basic:read",
new ClusterType[] { ClusterType.BankAccountNameTypeAndBalance, ClusterType.BankAccountNumbersAndFeatures })]
- [InlineData("AC05-3AU.02.14 Bank Detailed Only", "openid bank:accounts.detail:read",
+ [InlineData(
+ "AC05-3AU.02.14 Bank Detailed Only",
+ "openid bank:accounts.detail:read",
new ClusterType[] { ClusterType.BankAccountBalanceAndDetails })]
- [InlineData("AC06-3AU.02.14 Bank Detailed with Bank Transations", "openid bank:accounts.detail:read bank:transactions:read cdr:registration",
- new ClusterType[] { ClusterType.BankAccountBalanceAndDetails,
- ClusterType.BankTransactionDetails})]
- [InlineData("AC07-3AU.02.14", "openid bank:regular_payments:read",
+ [InlineData(
+ "AC06-3AU.02.14 Bank Detailed with Bank Transations",
+ "openid bank:accounts.detail:read bank:transactions:read cdr:registration",
+ new ClusterType[]
+ {
+ ClusterType.BankAccountBalanceAndDetails,
+ ClusterType.BankTransactionDetails,
+ })]
+ [InlineData(
+ "AC07-3AU.02.14",
+ "openid bank:regular_payments:read",
new ClusterType[] { ClusterType.BankDirectDebitAndSheduledPayments })]
- [InlineData("AC08-3AU.02.14", "openid bank:payees:read",
+ [InlineData(
+ "AC08-3AU.02.14",
+ "openid bank:payees:read",
new ClusterType[] { ClusterType.BankSavedPayees })]
- [InlineData("AC09-3AU.02.14 all bank", "openid bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read",
- new ClusterType[] { ClusterType.BankAccountNameTypeAndBalance,
+ [InlineData(
+ "AC09-3AU.02.14 all bank",
+ "openid bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read",
+ new ClusterType[]
+ {
+ ClusterType.BankAccountNameTypeAndBalance,
ClusterType.BankAccountNumbersAndFeatures,
ClusterType.BankTransactionDetails,
ClusterType.BankDirectDebitAndSheduledPayments,
- ClusterType.BankSavedPayees})]
- //Energy
- [InlineData("AC10-3AU.02.14 Energy Basic with detailed", "openid energy:accounts.basic:read openid energy:accounts.detail:read",
+ ClusterType.BankSavedPayees,
+ })]
+
+ // Energy
+ [InlineData(
+ "AC10-3AU.02.14 Energy Basic with detailed",
+ "openid energy:accounts.basic:read openid energy:accounts.detail:read",
new ClusterType[] { ClusterType.EnergyAccountsAndPlans, ClusterType.EnergyAccountAndPlanDetailsWithBasicScope })]
- [InlineData("AC11-3AU.02.14 Energy Detailed Only", "openid energy:accounts.detail:read",
+ [InlineData(
+ "AC11-3AU.02.14 Energy Detailed Only",
+ "openid energy:accounts.detail:read",
new ClusterType[] { ClusterType.EnergyAccountAndPlanDetailsWithoutBasicScope })]
- [InlineData("AC12-3AU.02.14 Energy connection and meter", "openid energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read",
+ [InlineData(
+ "AC12-3AU.02.14 Energy connection and meter",
+ "openid energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read",
new ClusterType[] { ClusterType.EnergyElectricityConnection, ClusterType.EnergyElectricityMeter })]
- [InlineData("AC13-3AU.02.14 Energy Consessions-Payments-Billing",
+ [InlineData(
+ "AC13-3AU.02.14 Energy Consessions-Payments-Billing",
"openid energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read",
new ClusterType[] { ClusterType.EnergyConcessionsAndAssistance, ClusterType.EnergyPaymentPreferences, ClusterType.EnergyEnergyBillingPaymentsAndHistory })]
- [InlineData("AC14-3AU.02.14 Energy DER-Usage", "openid energy:electricity.der:read energy:electricity.usage:read",
+ [InlineData(
+ "AC14-3AU.02.14 Energy DER-Usage",
+ "openid energy:electricity.der:read energy:electricity.usage:read",
new ClusterType[] { ClusterType.EnergyEnergyGenerationAndStorage, ClusterType.EnergyElectricityUsage })]
public async Task ACX08_Confirmation_UI_Cluster_Verification(string testSuffix, string actualScope, ClusterType[] expectedClusters)
@@ -387,12 +366,11 @@ public async Task ACX08_Confirmation_UI_Cluster_Verification(string testSuffix,
Log.Information("Running test with Params: {P1}={V1}, {P2}={V2}, {P3}={V3}.", nameof(testSuffix), testSuffix, nameof(actualScope), actualScope, nameof(expectedClusters), expectedClusters);
// Arrange
- Uri authRedirect = await Authorise(ResponseType.CodeIdToken, ResponseMode.FormPost, scope: actualScope);
+ Uri authRedirect = await Authorise(ResponseType.Code, ResponseMode.Jwt, scope: actualScope);
_browserContext = await _playwrightDriver.NewBrowserContext($"{nameof(ACX08_Confirmation_UI_Cluster_Verification)} - {testSuffix}");
var page = await _browserContext.NewPageAsync();
- // Act
-
+ // Act
await page.GotoAsync(authRedirect.AbsoluteUri); // redirect user to Auth UI to login and consent to share accounts
AuthenticateLoginPage authenticateLoginPage = new(page);
@@ -410,7 +388,7 @@ public async Task ACX08_Confirmation_UI_Cluster_Verification(string testSuffix,
ConfirmAccountSharingPage confirmAccountSharingPage = new(page);
- //Assert
+ // Assert
foreach (ClusterType c in expectedClusters)
{
await VerifyCluster(c, confirmAccountSharingPage);
@@ -433,7 +411,7 @@ internal static async Task VerifyCluster(ClusterType clusterType, ConfirmAccount
// Remove newline chars from actual and expected to ensure consistency in results.
// When running in a docker container, the last element does not always have a newline delimiter.
- Assert.Equal(expectedDetail.Replace("\n", ""), actualClusterDetail.Replace("\n", ""));
+ Assert.Equal(expectedDetail.Replace("\n", string.Empty), actualClusterDetail.Replace("\n", string.Empty));
}
public enum ClusterType
@@ -458,7 +436,7 @@ public enum ClusterType
EnergyElectricityUsage,
CommonNameAndOccupation,
CommonContactDetails,
- CommonNameOccupationAndContactDetails
+ CommonNameOccupationAndContactDetails,
}
// Call authorise endpoint, should respond with a redirect to UI, return the redirect URI
@@ -491,62 +469,8 @@ private async Task Authorise(ResponseType responseType, ResponseMode respon
return response.Headers.Location ?? throw new NullReferenceException(nameof(response.Headers.Location.AbsoluteUri));
}
- delegate Task HybridFlow_HandleCallback_Setup(IPage page);
- private async Task<(string? code, string? idtoken)> HybridFlow_HandleCallback(ResponseMode responseMode, IPage page, HybridFlow_HandleCallback_Setup setup)
- {
- var callback = new DataRecipientConsentCallback(_options.SOFTWAREPRODUCT_REDIRECT_URI_FOR_INTEGRATION_TESTS);
- callback.Start();
- try
- {
- await setup(page);
-
- var callbackRequest = await callback.WaitForCallback();
- using (new AssertionScope(BaseTestAssertionStrategy))
- {
- switch (responseMode)
- {
- case ResponseMode.FormPost:
- {
- callbackRequest.Should().NotBeNull();
- callbackRequest?.received.Should().BeTrue();
- callbackRequest?.method.Should().Be(HttpMethod.Post);
- callbackRequest?.body.Should().NotBeNullOrEmpty();
-
- var body = QueryHelpers.ParseQuery(callbackRequest?.body);
- var code = body["code"];
- var id_token = body["id_token"];
-
- code.Should().NotBeNullOrEmpty();
- id_token.Should().NotBeNullOrEmpty();
-
- return (code, id_token);
- }
- case ResponseMode.Fragment:
- {
- callbackRequest.Should().NotBeNull();
- callbackRequest?.received.Should().BeTrue();
- callbackRequest?.method.Should().Be(HttpMethod.Get);
- throw new NotImplementedException("FIXME - MJS - check request URL fragment for authcode & idtoken");
- }
- case ResponseMode.Query:
- {
- callbackRequest.Should().NotBeNull();
- callbackRequest?.received.Should().BeTrue();
- callbackRequest?.method.Should().Be(HttpMethod.Get);
- throw new NotImplementedException("FIXME - MJS - check request URL query string for authcode & idtoken");
- }
- default:
- throw new NotSupportedException(nameof(responseMode));
- }
- }
- }
- finally
- {
- await callback.Stop();
- }
- }
+ private delegate Task CodeFlow_HandleCallback_Setup(IPage page);
- delegate Task CodeFlow_HandleCallback_Setup(IPage page);
private async Task CodeFlow_HandleCallback(IPage page, CodeFlow_HandleCallback_Setup setup)
{
var callback = new DataRecipientConsentCallback(_options.SOFTWAREPRODUCT_REDIRECT_URI_FOR_INTEGRATION_TESTS);
@@ -570,8 +494,7 @@ private async Task Authorise(ResponseType responseType, ResponseMode respon
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt);
jwt.Claim("code").Should().NotBeNull();
- return (jwt.Claim("code").Value);
-
+ return jwt.Claim("code").Value;
}
}
finally
@@ -580,10 +503,10 @@ private async Task Authorise(ResponseType responseType, ResponseMode respon
}
}
- delegate Task CancelAction();
+ private delegate Task CancelAction();
+
private async Task AssertCancelCallback(CancelAction cancelAction)
{
-
var expectedError = new UserCancelledException();
var callback = new DataRecipientConsentCallback(_options.SOFTWAREPRODUCT_REDIRECT_URI_FOR_INTEGRATION_TESTS);
@@ -605,10 +528,9 @@ private async Task AssertCancelCallback(CancelAction cancelAction)
var encodedJwt = queryValues["response"];
// Check claims of decode jwt
- var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt);
+ var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt);
jwt.Claim("error").Value.Should().Be(expectedError.Error);
jwt.Claim("error_description").Value.Should().Be(expectedError.ErrorDescription);
-
}
}
finally
@@ -616,7 +538,8 @@ private async Task AssertCancelCallback(CancelAction cancelAction)
await callback.Stop();
}
}
- public static (string expectedHeading, string expectedDetail) GetExpectedClusterDetail(ClusterType scopesType)
+
+ public static (string ExpectedHeading, string ExpectedDetail) GetExpectedClusterDetail(ClusterType scopesType)
{
switch (scopesType)
{
diff --git a/Source/CdrAuthServer.E2ETests/XUnit/Orderers/AlphabeticalOrderer.cs b/Source/CdrAuthServer.E2ETests/XUnit/Orderers/AlphabeticalOrderer.cs
index 9db967c..e46cdba 100644
--- a/Source/CdrAuthServer.E2ETests/XUnit/Orderers/AlphabeticalOrderer.cs
+++ b/Source/CdrAuthServer.E2ETests/XUnit/Orderers/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,9 @@ namespace CdrAuthServer.E2ETests.XUnit.Orderers
{
public class AlphabeticalOrderer : ITestCaseOrderer
{
- public IEnumerable OrderTestCases(IEnumerable testCases) where TTestCase : ITestCase =>
+ 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/CdrAuthServer.GetDataRecipients.IntegrationTests/BaseTest.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/BaseTest.cs
index 13fcf5d..b22ebd6 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/BaseTest.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/BaseTest.cs
@@ -1,63 +1,45 @@
-#undef DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
+#undef DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
#nullable enable
-using Microsoft.Extensions.Configuration;
using System;
+using System.Configuration;
using System.IO;
-using System.Reflection;
-using Xunit;
-using Xunit.Sdk;
-
using CdrAuthServer.GetDataRecipients.IntegrationTests.Fixtures;
-using System.Configuration;
+using Microsoft.Extensions.Configuration;
+using Xunit;
namespace CdrAuthServer.GetDataRecipients.IntegrationTests
{
- class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute
- {
- static int count = 0;
-
- public override void Before(MethodInfo methodUnderTest)
- {
- Console.WriteLine($"Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name}");
- }
-
- public override void After(MethodInfo methodUnderTest)
- {
- }
- }
-
// Put all tests in same collection because we need them to run sequentially since some tests are mutating DB.
[Collection("IntegrationTests")]
[TestCaseOrderer("CdrAuthServer.GetDataRecipients.IntegrationTests.XUnit.Orderers.AlphabeticalOrderer", "CdrAuthServer.GetDataRecipients.IntegrationTests")]
[DisplayTestMethodName]
- abstract public class BaseTest : IClassFixture
- {
+ public abstract class BaseTest : IClassFixture
+ {
public static string AZUREFUNCTIONS_URL => Configuration["URL:AZUREFUNCTIONS"]
?? throw new ConfigurationErrorsException($"{nameof(AZUREFUNCTIONS_URL)} - configuration setting not found");
- static public string CONNECTIONSTRING_REGISTER_RW =>
+ public static string CONNECTIONSTRING_REGISTER_RW =>
ConnectionStringCheck.Check(Configuration.GetConnectionString("Register_RW"));
- static public string CONNECTIONSTRING_AUTHSERVER_RW =>
+
+ public static string CONNECTIONSTRING_AUTHSERVER_RW =>
ConnectionStringCheck.Check(Configuration.GetConnectionString("CdrAuthServer_DB_RW"));
- static private IConfigurationRoot? configuration;
- static public IConfigurationRoot Configuration
+ private static IConfigurationRoot? configuration;
+
+ public static IConfigurationRoot Configuration
{
get
{
- if (configuration == null)
- {
- configuration = new ConfigurationBuilder()
+ configuration ??= new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true)
.Build();
- }
return configuration;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/CdrAuthServer.GetDataRecipients.IntegrationTests.csproj b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/CdrAuthServer.GetDataRecipients.IntegrationTests.csproj
index 6460646..ef33b24 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/CdrAuthServer.GetDataRecipients.IntegrationTests.csproj
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/CdrAuthServer.GetDataRecipients.IntegrationTests.csproj
@@ -4,7 +4,8 @@
$(Version)
$(Version)
$(Version)
- false
+ false
+ True
@@ -22,7 +23,16 @@
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/ConnectionStringCheck.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/ConnectionStringCheck.cs
index 36a8d43..55e4e5e 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/ConnectionStringCheck.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/ConnectionStringCheck.cs
@@ -1,24 +1,25 @@
-#nullable enable
+#nullable enable
using System;
-using Xunit;
-using FluentAssertions.Execution;
using FluentAssertions;
+using FluentAssertions.Execution;
+using Xunit;
namespace CdrAuthServer.GetDataRecipients.IntegrationTests
{
- static public class ConnectionStringCheck
+ public static class ConnectionStringCheck
{
internal const string PRODUCTION_SERVER = "sql-cdrsandbox-prod.database.windows.net";
// 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
- };
+ private static readonly string[] Blacklist =
+ [
+ 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)
@@ -30,17 +31,17 @@ static public string Check(string? connectionString)
}
}
- return connectionString ?? "";
+ return connectionString ?? string.Empty;
}
}
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
+ 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)]
+ [InlineData(PRODUCTION_SERVER_FOO)]
+ [InlineData(PRODUCTION_SERVER_FOO, true)]
public void WhenOnBlackList_ShouldThrowException(string connectionString, bool? uppercase = false)
{
if (uppercase == true)
@@ -77,9 +78,9 @@ public void WhenNotOnBlackList_ShouldNotThrowException(string? connectionString)
using (new AssertionScope())
{
act.Should().NotThrow();
- returnedConnectionString?.Should().Be(connectionString ?? "");
+ returnedConnectionString?.Should().Be(connectionString ?? string.Empty);
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DatabaseSeeder.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DatabaseSeeder.cs
index c167d04..447bc19 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DatabaseSeeder.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DatabaseSeeder.cs
@@ -1,16 +1,26 @@
-using System;
+using System;
using System.Threading.Tasks;
-using Microsoft.Data.SqlClient;
using Dapper;
+using Microsoft.Data.SqlClient;
#nullable enable
namespace CdrAuthServer.GetDataRecipients.IntegrationTests
{
- static public class DatabaseSeeder
+ public static class DatabaseSeeder
{
- private enum IndustryType { Banking, Energy, Telecommunications }
- private enum ParticipantType { DH, DR }
+ private enum IndustryType
+ {
+ Banking,
+ Energy,
+ Telecommunications,
+ }
+
+ private enum ParticipantType
+ {
+ DH,
+ DR,
+ }
private static int nextRegisterLegalEntityId = 0;
private static int nextRegisterParticipationId = 0;
@@ -21,12 +31,11 @@ private enum ParticipantType { DH, DR }
private static int nextAuthServerBrandId = 0;
private static int nextAuthServerSoftwareProductId = 0;
- static public async Task Execute(
+ public static async Task Execute(
int registerLegalEntityCount, int registerBrandCount, int registerSoftwareProductCount,
int authServerLegalEntityCount, int authServerBrandCount, int authServerSoftwareProductCount,
bool registerModified, // simulate change to register records
- bool authServerModified // simulate change to dataholder records
- )
+ bool authServerModified) // simulate change to dataholder records
{
// Database is purged so, reset next ids so that ids are consistent across tests
nextRegisterLegalEntityId = 0;
@@ -39,13 +48,13 @@ bool authServerModified // simulate change to dataholder records
// Seed Register
using var registerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
- registerConnection.Open();
+ await registerConnection.OpenAsync();
await RegisterPurge(registerConnection);
await RegisterInsert(registerConnection, registerLegalEntityCount, registerBrandCount, registerSoftwareProductCount, registerModified);
// Seed Software Products
using var authServerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_AUTHSERVER_RW);
- authServerConnection.Open();
+ await authServerConnection.OpenAsync();
await AuthServerPurge(authServerConnection);
await AuthServerInsert(authServerConnection, authServerLegalEntityCount, authServerBrandCount, authServerSoftwareProductCount, authServerModified);
}
@@ -64,8 +73,8 @@ private static async Task RegisterPurge(SqlConnection connection)
// Purge Auth Server database but leave standing data intact
private static async Task AuthServerPurge(SqlConnection connection)
- {
- await connection.ExecuteAsync("delete SoftwareProducts");
+ {
+ await connection.ExecuteAsync("delete SoftwareProducts");
}
private static async Task RegisterInsert(SqlConnection connection, int legalEntityCount, int brandCount, int softwareProductCount, bool modified)
@@ -75,28 +84,31 @@ static async Task Register_InsertLegalEntity(SqlConnection connection, Ind
var legalEntityId = new Guid($"00000000-0000-0000-0000-{++nextRegisterLegalEntityId:d012}");
string legalEntityName = $"LegalEntity_{legalEntityId}".ToString().Replace('-', '_');
-
- await connection.ExecuteScalarAsync(@"
+
+ await connection.ExecuteScalarAsync(
+ @"
insert into LegalEntity(LegalEntityId, LegalEntityName, LogoUri, AnzsicDivision, OrganisationTypeId, AccreditationLevelId, AccreditationNumber)
values(@LegalEntityId, @LegalEntityName, @LogoUri, @AnzsicDivision, @OrganisationTypeId, @AccreditationLevelId, @AccreditationNumber)",
new
{
- LegalEntityId = legalEntityId,
+ LegalEntityId = legalEntityId,
+
// MA
LegalEntityName = legalEntityName,
LogoUri = $"https://www.{legalEntityName}.com/logo.jpg",
-
+
AnzsicDivision = industryType switch
{
IndustryType.Banking => "6221",
IndustryType.Energy => "2640",
IndustryType.Telecommunications => "5801",
- _ => throw new NotSupportedException()
+ _ => throw new NotSupportedException(),
},
- OrganisationTypeId = "2", // company
- // LegalEntityStatusId = "1", // make it active by default
+ OrganisationTypeId = "2", // company
+
+ // LegalEntityStatusId = "1", // make it active by default
AccreditationLevelId = "1", // unrestricted
- AccreditationNumber = $"ABC{nextRegisterLegalEntityId:d012}"
+ AccreditationNumber = $"ABC{nextRegisterLegalEntityId:d012}",
});
return legalEntityId;
@@ -106,7 +118,8 @@ static async Task Register_InsertParticipation(SqlConnection connection, G
{
var participationId = new Guid($"00000000-0000-0000-0000-{++nextRegisterParticipationId:d012}");
- await connection.ExecuteScalarAsync(@"
+ await connection.ExecuteScalarAsync(
+ @"
insert into Participation(ParticipationId, LegalEntityId, ParticipationTypeId, IndustryId, StatusId)
values(@ParticipationId, @LegalEntityId,
(select ParticipationTypeId from ParticipationType where ParticipationTypeCode = @ParticipantTypeCode),
@@ -116,11 +129,12 @@ insert into Participation(ParticipationId, LegalEntityId, ParticipationTypeId, I
{
ParticipationId = participationId,
LegalEntityId = legalEntityId,
- ParticipantTypeCode = participantType.ToString(),
+ ParticipantTypeCode = participantType.ToString(),
+
// MA
ParticipationStatusCode = "ACTIVE",
- IndustryTypeCode = industryType.ToString()
+ IndustryTypeCode = industryType.ToString(),
});
return participationId;
@@ -132,7 +146,8 @@ static async Task Register_InsertBrand(SqlConnection connection, Guid part
string brandName = $"Brand_{brandId}".ToString().Replace('-', '_');
- await connection.ExecuteScalarAsync(@"
+ await connection.ExecuteScalarAsync(
+ @"
insert into Brand(BrandId, BrandName, LogoUri, BrandStatusId, ParticipationId, LastUpdated)
values(@BrandId, @BrandName, @LogoUri,
--(select BrandStatusId from BrandStatus where Upper(BrandStatusCode) = 'ACTIVE'),
@@ -141,14 +156,15 @@ insert into Brand(BrandId, BrandName, LogoUri, BrandStatusId, ParticipationId, L
@LastUpdated)",
new
{
- BrandId = brandId,
- // MA
+ BrandId = brandId,
+
+ // MA
BrandName = brandName,
LogoUri = $"https://www.{brandName}.com/logo.jpg",
StatusId = "1", // 1=active, 2=inactive
ParticipationId = participationId,
- LastUpdated = DateTime.UtcNow
+ LastUpdated = DateTime.UtcNow,
});
return brandId;
@@ -160,7 +176,8 @@ static async Task Register_InsertSoftwareProduct(SqlConnection connection,
string softwareProductName = $"SoftwareProduct_{softwareProductId}".ToString().Replace('-', '_');
- await connection.ExecuteScalarAsync(@"
+ await connection.ExecuteScalarAsync(
+ @"
insert into SoftwareProduct(
SoftwareProductId,
SoftwareProductName,
@@ -192,11 +209,12 @@ insert into SoftwareProduct(
@BrandId)",
new
{
- SoftwareProductId = softwareProductId,
+ SoftwareProductId = softwareProductId,
+
// MA
SoftwareProductName = $"{softwareProductName}",
SoftwareProductDescription = $"{softwareProductName} description",
- LogoUri = $"https://www.{softwareProductName}.com/logo.jpg",
+ LogoUri = $"https://www.{softwareProductName}.com/logo.jpg",
ClientUri = $"https://www.{softwareProductName}.com/client",
RecipientBaseUri = $"https://www.{softwareProductName}.com/recipientbase",
@@ -204,8 +222,8 @@ insert into SoftwareProduct(
RedirectUris = $"https://www.{softwareProductName}.com/redirect1,https://www.{softwareProductName}.com/redirect2",
JwksUri = $"https://www.{softwareProductName}.com/jwks",
Scope = "scope",
-
- //StatusId = modified ? "2" : "1", // 1=active, 2=inactive
+
+ // StatusId = modified ? "2" : "1", // 1=active, 2=inactive
StatusId = "1", // 1=active, 2=inactive
BrandId = brandId,
@@ -228,7 +246,7 @@ insert into SoftwareProduct(
// Insert software products
for (int isoftwareProductCount = 0; isoftwareProductCount < softwareProductCount; isoftwareProductCount++)
{
- var register_SoftwareProductId = await Register_InsertSoftwareProduct(connection, register_BrandId, modified);
+ _ = await Register_InsertSoftwareProduct(connection, register_BrandId, modified);
}
}
}
@@ -238,8 +256,8 @@ private static async Task AuthServerInsert(SqlConnection connection, int legalEn
{
static async Task AuthServer_InsertCDRSoftwareProduct(SqlConnection connection)
{
-
- await connection.ExecuteScalarAsync(@"
+ await connection.ExecuteScalarAsync(
+ @"
insert into SoftwareProducts(SoftwareProductId, SoftwareProductName, SoftwareProductDescription, LogoUri, Status,
LegalEntityId, LegalEntityName, LegalEntityStatus, BrandId, BrandName, BrandStatus )
values(@SoftwareProductId, @SoftwareProductName, @SoftwareProductDescription, @LogoUri, @Status,
@@ -258,38 +276,38 @@ insert into SoftwareProducts(SoftwareProductId, SoftwareProductName, SoftwarePro
BrandId = "cdr-register",
BrandName = "cdr-register",
- BrandStatus = "ACTIVE"
- }); ;
-
-
+ BrandStatus = "ACTIVE",
+ });
}
+
static async Task AuthServer_InsertSoftwareProducts(SqlConnection connection, Guid legalEntityId, Guid brandId, bool modified)
{
var softwareProductId = new Guid($"00000000-0000-0000-0000-{++nextAuthServerSoftwareProductId:d012}");
string softwareProductName = $"SoftwareProduct_{softwareProductId}".ToString().Replace('-', '_');
- await connection.ExecuteScalarAsync(@"
+ await connection.ExecuteScalarAsync(
+ @"
insert into SoftwareProducts(SoftwareProductId, SoftwareProductName, SoftwareProductDescription, LogoUri, Status,
LegalEntityId, LegalEntityName, LegalEntityStatus, BrandId, BrandName, BrandStatus )
values(@SoftwareProductId, @SoftwareProductName, @SoftwareProductDescription, @LogoUri, @Status,
@LegalEntityId, @LegalEntityName, @LegalEntityStatus, @BrandId, @BrandName, @BrandStatus)",
new
{
- SoftwareProductId = softwareProductId,
+ SoftwareProductId = softwareProductId,
SoftwareProductName = softwareProductName,
SoftwareProductDescription = $"{softwareProductName} description",
- LogoUri = $"https://www.{softwareProductName}.com/logo.jpg",
+ LogoUri = $"https://www.{softwareProductName}.com/logo.jpg",
Status = "ACTIVE",
-
- LegalEntityId = legalEntityId,
+
+ LegalEntityId = legalEntityId,
LegalEntityName = $"LegalEntity_{legalEntityId}".ToString().Replace('-', '_'),
LegalEntityStatus = "ACTIVE",
- BrandId = brandId,
+ BrandId = brandId,
BrandName = $"Brand_{brandId}".ToString().Replace('-', '_'),
- BrandStatus = "ACTIVE"
- }); ;
+ BrandStatus = "ACTIVE",
+ });
return softwareProductId;
}
@@ -297,14 +315,14 @@ insert into SoftwareProducts(SoftwareProductId, SoftwareProductName, SoftwarePro
await AuthServer_InsertCDRSoftwareProduct(connection);
for (int i = 1; i <= legalEntityCount; i++)
- {
+ {
var legalEntityId = new Guid($"00000000-0000-0000-0000-{++nextAuthServerLegalEntityId:d012}");
for (int i2 = 1; i2 <= brandCount; i2++)
- {
+ {
var brandId = new Guid($"00000000-0000-0000-0000-{++nextAuthServerBrandId:d012}");
for (int i3 = 1; i3 <= brandCount; i3++)
- {
- var softwareProductId = await AuthServer_InsertSoftwareProducts(connection, legalEntityId, brandId, modified);
+ {
+ _ = await AuthServer_InsertSoftwareProducts(connection, legalEntityId, brandId, modified);
}
}
}
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DisplayTestMethodNameAttribute.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DisplayTestMethodNameAttribute.cs
new file mode 100644
index 0000000..572f76b
--- /dev/null
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/DisplayTestMethodNameAttribute.cs
@@ -0,0 +1,29 @@
+#undef DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
+
+#nullable enable
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using CdrAuthServer.GetDataRecipients.IntegrationTests.Fixtures;
+using Microsoft.Extensions.Configuration;
+using Xunit;
+using Xunit.Sdk;
+
+namespace CdrAuthServer.GetDataRecipients.IntegrationTests
+{
+ internal class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute
+ {
+ private static int count = 0;
+
+ public override void Before(MethodInfo methodUnderTest)
+ {
+ Console.WriteLine($"Test #{++count} - {methodUnderTest.DeclaringType?.Name}.{methodUnderTest.Name}");
+ }
+
+ public override void After(MethodInfo methodUnderTest)
+ {
+ }
+ }
+}
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/Fixtures/TestFixture.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/Fixtures/TestFixture.cs
index de16c80..2112313 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/Fixtures/TestFixture.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/Fixtures/TestFixture.cs
@@ -15,4 +15,4 @@ public Task DisposeAsync()
return Task.CompletedTask;
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/US28391_GetDataRecipients.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/US28391_GetDataRecipients.cs
index eed9243..3351185 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/US28391_GetDataRecipients.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/US28391_GetDataRecipients.cs
@@ -1,15 +1,15 @@
-// #define DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
+// #define DEBUG_WRITE_EXPECTED_AND_ACTUAL_JSON
using System;
+using System.Net;
+using System.Net.Http;
using System.Threading.Tasks;
-using Microsoft.Data.SqlClient;
using Dapper;
-using Newtonsoft.Json;
-using Xunit;
using FluentAssertions;
using FluentAssertions.Execution;
-using System.Net.Http;
-using System.Net;
+using Microsoft.Data.SqlClient;
+using Newtonsoft.Json;
+using Xunit;
#nullable enable
@@ -34,16 +34,25 @@ private async Task ExecuteAzureFunction()
}
private async Task Test(
- int registerLegalEntityCount, int registerBrandCount, int registerSoftwareProductCount,
- int authServerLegalEntityCount, int authServerBrandCount, int authServerSoftwareProductCount,
- bool registerModified = false, bool authServerModified = false)
+ int registerLegalEntityCount,
+ int registerBrandCount,
+ int registerSoftwareProductCount,
+ int authServerLegalEntityCount,
+ int authServerBrandCount,
+ int authServerSoftwareProductCount,
+ bool registerModified = false,
+ bool authServerModified = false)
{
// Arrange
await DatabaseSeeder.Execute(
- registerLegalEntityCount, registerBrandCount, registerSoftwareProductCount,
- authServerLegalEntityCount, authServerBrandCount, authServerSoftwareProductCount,
- registerModified, authServerModified
- );
+ registerLegalEntityCount,
+ registerBrandCount,
+ registerSoftwareProductCount,
+ authServerLegalEntityCount,
+ authServerBrandCount,
+ authServerSoftwareProductCount,
+ registerModified,
+ authServerModified);
// Act
await ExecuteAzureFunction();
@@ -87,16 +96,15 @@ public async Task ACX01_WhenDataHolderChanged_ShouldSync()
await Test(1, 1, 1, 1, 1, 1, false, true);
}
-
-
- static private async Task Assert_RegisterAndDataHolderIsSynced()
+ private static async Task Assert_RegisterAndDataHolderIsSynced()
{
static async Task Assert_TableDataIsEqual(
- SqlConnection registerConnection, string registerSql,
- SqlConnection authServerConnection, string authServerSql,
+ SqlConnection registerConnection,
+ string registerSql,
+ SqlConnection authServerConnection,
+ string authServerSql,
string tableName)
{
-
var registerJson = JsonConvert.SerializeObject(await registerConnection.QueryAsync(registerSql));
var authServerJson = JsonConvert.SerializeObject(await authServerConnection.QueryAsync(authServerSql));
@@ -106,7 +114,6 @@ static async Task Assert_TableDataIsEqual(
File.WriteAllText($"c:/temp/actual_{tableName}.json", authServerJson);
#endif
authServerJson.Should().Be(registerJson);
-
}
const string REGISTER_LEGALENTITY_SQL = @"
@@ -158,16 +165,16 @@ from SoftwareProduct sp
where pt.ParticipationTypeCode = 'DR' -- hardly necessary since only DRs have software products anyway
order by SoftwareProductId";
- //Upper(Status) Status,
+ // Upper(Status) Status,
var AUTHSERVER_LEGALENTITY_SQL = "select LegalEntityId, LegalEntityName, LegalEntityStatus Status from SoftwareProducts where LegalEntityId != 'cdr-register' order by LegalEntityId ";
var AUTHSERVER_BRAND_SQL = "select BrandId, BrandName, BrandStatus Status, LegalEntityId from SoftwareProducts where BrandId != 'cdr-register' order by BrandId";
var AUTHSERVER_SOFTWAREPRODUCT_SQL = "select SoftwareProductId, SoftwareProductName, SoftwareProductDescription, LogoUri, Status from SoftwareProducts where SoftwareProductId != 'cdr-register' order by SoftwareProductId";
using var registerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
- registerConnection.Open();
+ await registerConnection.OpenAsync();
using var authServerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_AUTHSERVER_RW);
- authServerConnection.Open();
+ await authServerConnection.OpenAsync();
// Assert
await Assert_TableDataIsEqual(registerConnection, REGISTER_LEGALENTITY_SQL, authServerConnection, AUTHSERVER_LEGALENTITY_SQL, "LegalEntity");
diff --git a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/XUnit/AlphabeticalOrderer.cs b/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/XUnit/AlphabeticalOrderer.cs
index 40e5054..ff15fce 100644
--- a/Source/CdrAuthServer.GetDataRecipients.IntegrationTests/XUnit/AlphabeticalOrderer.cs
+++ b/Source/CdrAuthServer.GetDataRecipients.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,9 @@ namespace CdrAuthServer.GetDataRecipients.IntegrationTests.XUnit.Orderers
{
public class AlphabeticalOrderer : ITestCaseOrderer
{
- public IEnumerable OrderTestCases(IEnumerable testCases) where TTestCase : ITestCase =>
+ 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/CdrAuthServer.GetDataRecipients/CdrAuthServer.GetDataRecipients.csproj b/Source/CdrAuthServer.GetDataRecipients/CdrAuthServer.GetDataRecipients.csproj
index 65e5548..4d674a2 100644
--- a/Source/CdrAuthServer.GetDataRecipients/CdrAuthServer.GetDataRecipients.csproj
+++ b/Source/CdrAuthServer.GetDataRecipients/CdrAuthServer.GetDataRecipients.csproj
@@ -8,7 +8,8 @@
<_FunctionsSkipCleanOutput>true
Exe
/home/site/wwwroot
- Linux
+ Linux
+ True
@@ -26,6 +27,14 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CdrAuthServer.GetDataRecipients/GetDROptions.cs b/Source/CdrAuthServer.GetDataRecipients/GetDROptions.cs
index 4bb2980..9d4defa 100644
--- a/Source/CdrAuthServer.GetDataRecipients/GetDROptions.cs
+++ b/Source/CdrAuthServer.GetDataRecipients/GetDROptions.cs
@@ -3,18 +3,31 @@
public class GetDROptions
{
public string AzureWebJobsStorage { get; set; }
+
public string StorageConnectionString { get; set; }
- public string FUNCTIONS_WORKER_RUNTIME { get; set; }
+
+ public string FUNCTIONS_WORKER_RUNTIME { get; set; }
+
public string Register_CdrAuthServer_Logging_DB_ConnectionString { get; set; }
+
public string Register_CdrAuthServer_MetadataUpdate_Endpoint { get; set; }
+
public string Register_CdrAuthServer_Token_Endpoint { get; set; }
+
public string Register_CdrAuthServer_MetadataUpdate_XV { get; set; }
+
public string Register_CdrAuthServer_MetadataUpdate_XMINV { get; set; }
+
public string Register_Client_Id { get; set; }
+
public string Register_Client_Certificate { get; set; }
+
public string Register_Client_Certificate_Password { get; set; }
+
public string Register_Signing_Certificate { get; set; }
+
public string Register_Signing_Certificate_Password { get; set; }
+
public string Ignore_Server_Certificate_Errors { get; set; }
}
}
diff --git a/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients.cs b/Source/CdrAuthServer.GetDataRecipients/GetDataRecipientsFunction.cs
similarity index 76%
rename from Source/CdrAuthServer.GetDataRecipients/GetDataRecipients.cs
rename to Source/CdrAuthServer.GetDataRecipients/GetDataRecipientsFunction.cs
index dcfb4a5..4af8366 100644
--- a/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients.cs
+++ b/Source/CdrAuthServer.GetDataRecipients/GetDataRecipientsFunction.cs
@@ -1,4 +1,4 @@
-using CdrAuthServer.Infrastructure;
+using CdrAuthServer.Infrastructure;
using CdrAuthServer.Infrastructure.Extensions;
using CdrAuthServer.Infrastructure.Models;
using Microsoft.Azure.Functions.Worker;
@@ -23,14 +23,13 @@ public class GetDataRecipientsFunction
public GetDataRecipientsFunction(ILoggerFactory loggerFactory, IOptions options)
{
_logger = loggerFactory.CreateLogger();
- _drOptions =options.Value;
+ _drOptions = options.Value;
}
+
///
- /// Get Data Recipients Function
+ /// Get Data Recipients Function.
///
- /// Gets the Data Recipients from the Register and updates the local repository
-
-
+ /// Gets the Data Recipients from the Register and updates the local repository.
[Function("GetDataRecipients")]
public async Task Run([TimerTrigger("%Schedule%")] TimerInfo myTimer)
{
@@ -38,7 +37,6 @@ public async Task Run([TimerTrigger("%Schedule%")] TimerInfo myTimer)
try
{
-
// Updated names for the cdrauth server
var dataRecipientsEndpoint = _drOptions.Register_CdrAuthServer_MetadataUpdate_Endpoint;
var ignoreServerCertificateErrors = _drOptions.Ignore_Server_Certificate_Errors.Equals("true", StringComparison.OrdinalIgnoreCase);
@@ -55,7 +53,7 @@ public async Task Run([TimerTrigger("%Schedule%")] TimerInfo myTimer)
// Add token to the bear token call
// Auth Api should receive the call and authorize it before calling on
- //Loading client certificates from Base64 string
+ // Loading client certificates from Base64 string
X509Certificate2 clientCertificate = LoadCertificates(_logger, clientCert, clientCertPwd);
_logger.LogInformation("Client certificate loaded: {Thumbprint}", clientCertificate.Thumbprint);
@@ -66,7 +64,7 @@ public async Task Run([TimerTrigger("%Schedule%")] TimerInfo myTimer)
if (tokenResponse.IsSuccessful)
{
- // Send access token as bear token request to autherization server
+ // Send access token as bear token request to autherization server
(_, var respStatusCode) = await GetDataRecipients(dataRecipientsEndpoint, tokenResponse.Data.AccessToken, clientCertificate, _logger, ignoreServerCertificateErrors);
if (respStatusCode != System.Net.HttpStatusCode.OK)
{
@@ -84,26 +82,25 @@ public async Task Run([TimerTrigger("%Schedule%")] TimerInfo myTimer)
}
}
-
///
- /// Returns certificates
+ /// Returns certificates.
///
- ///
- ///
- ///
- ///
+ /// logger interface.
+ /// certificate name.
+ /// password for the certificate.
+ /// the loaded certificate.
private static X509Certificate2 LoadCertificates(ILogger log, string cert, string certPwd)
{
log.LogInformation("Loading the certificate...");
byte[] certBytes = Convert.FromBase64String(cert);
- X509Certificate2 certificate = new(certBytes, certPwd, X509KeyStorageFlags.MachineKeySet);
+ X509Certificate2 certificate = new (certBytes, certPwd, X509KeyStorageFlags.MachineKeySet);
return certificate;
}
///
- /// Get Access Token
+ /// Get Access Token.
///
- /// JWT
+ /// JWT.
private async Task> GetAccessToken(
string tokenEndpoint,
string clientId,
@@ -116,7 +113,7 @@ private static X509Certificate2 LoadCertificates(ILogger log, string cert, strin
var client = GetHttpClient(clientCertificate, ignoreServerCertificateErrors: ignoreServerCertificateErrors);
// Make the request to the token endpoint.
- log.LogInformation("Retrieving access_token from the AuthServer: {tokenEndpoint}", tokenEndpoint);
+ log.LogInformation("Retrieving access_token from the AuthServer: {TokenEndpoint}", tokenEndpoint);
try
{
@@ -132,12 +129,12 @@ private static X509Certificate2 LoadCertificates(ILogger log, string cert, strin
var tokenResponse = new Infrastructure.Models.Response()
{
- StatusCode = response.StatusCode
+ StatusCode = response.StatusCode,
};
if (response.IsSuccessStatusCode)
{
- log.LogInformation("AuthServer response: {statusCode} - {body}", tokenResponse.StatusCode, body);
+ log.LogInformation("AuthServer response: {StatusCode} - {Body}", tokenResponse.StatusCode, body);
tokenResponse.Data = JsonConvert.DeserializeObject(body);
}
else
@@ -148,7 +145,7 @@ private static X509Certificate2 LoadCertificates(ILogger log, string cert, strin
return tokenResponse;
}
- catch(Exception ex)
+ catch (Exception ex)
{
await InsertDBLog(_drOptions.Register_CdrAuthServer_Logging_DB_ConnectionString, "Error", "Exception", "GetAccessToken", ex);
log.LogError(ex, "Caught exception in GetAccessToken");
@@ -156,41 +153,41 @@ private static X509Certificate2 LoadCertificates(ILogger log, string cert, strin
return new Infrastructure.Models.Response()
{
- StatusCode = System.Net.HttpStatusCode.InternalServerError
+ StatusCode = System.Net.HttpStatusCode.InternalServerError,
};
}
-
///
- /// Get the list of Data Recipients from the Register
+ /// Get the list of Data Recipients from the Register.
///
- /// Raw data
+ /// Raw data.
private async Task<(string, System.Net.HttpStatusCode)> GetDataRecipients(
string dataRecipientsEndpoint,
string accessToken,
- X509Certificate2 clientCertificate,
+ X509Certificate2 clientCertificate,
ILogger log,
bool ignoreServerCertificateErrors = false)
{
- var client = GetHttpClient(clientCertificate:clientCertificate,
- accessToken:accessToken,
+ var client = GetHttpClient(
+ clientCertificate: clientCertificate,
+ accessToken: accessToken,
ignoreServerCertificateErrors: ignoreServerCertificateErrors);
- log.LogInformation("Retrieving data recipients from the Register: {dataRecipientsEndpoint}", dataRecipientsEndpoint);
+ log.LogInformation("Retrieving data recipients from the Register: {DataRecipientsEndpoint}", dataRecipientsEndpoint);
var payload = "{\"data\": {\"action\": \"REFRESH\"}}";
HttpContent content = new StringContent(payload, Encoding.UTF8, "application/json");
-
- var result = await client.PostAsync(dataRecipientsEndpoint, content);
- var data = result.Content.ReadAsStringAsync().Result;
- log.LogInformation("Register response: {statusCode} - {body}", result.StatusCode, data);
+
+ var result = await client.PostAsync(dataRecipientsEndpoint, content);
+ var data = await result.Content.ReadAsStringAsync();
+ log.LogInformation("Register response: {StatusCode} - {Body}", result.StatusCode, data);
return (data, result.StatusCode);
}
private HttpClient GetHttpClient(
X509Certificate2 clientCertificate = null,
- string accessToken = null,
+ string accessToken = null,
bool ignoreServerCertificateErrors = false)
{
var clientHandler = new HttpClientHandler();
@@ -210,7 +207,9 @@ private HttpClient GetHttpClient(
// If an access token has been provided then add to the Authorization header of the client.
if (!string.IsNullOrEmpty(accessToken))
+ {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
+ }
// Add the x-v header to the request from configurations
if (!string.IsNullOrEmpty(_drOptions.Register_CdrAuthServer_MetadataUpdate_XV))
@@ -226,18 +225,18 @@ private HttpClient GetHttpClient(
return client;
}
-
+
///
- /// Update the Log table
+ /// Update the Log table.
///
private static async Task InsertDBLog(string dbConnString, string msg, string lvl, string methodName, Exception exMsg = null, string entity = "")
{
- string exMessage = "";
+ string exMessage = string.Empty;
if (exMsg != null)
{
Exception innerException = exMsg;
- StringBuilder innerMsg = new();
+ StringBuilder innerMsg = new ();
int ctr = 0;
do
@@ -259,39 +258,47 @@ private static async Task InsertDBLog(string dbConnString, string msg, string lv
// Use the Exception message
if (innerMsg.Length == 0)
+ {
exMessage = exMsg.Message;
+ }
// Use the inner Exception message (includes the Exception message)
else
+ {
exMessage = innerMsg.ToString();
+ }
// Include the serialised entity for use with Exception message only
if (!string.IsNullOrEmpty(entity))
+ {
exMessage += "\r\nEntity: " + entity;
+ }
- exMessage = exMessage.Replace("'", "");
+ exMessage = exMessage.Replace("'", string.Empty);
}
- using (SqlConnection db = new(dbConnString))
- {
- db.Open();
- var cmdText = "";
+ using SqlConnection db = new (dbConnString);
+ await db.OpenAsync();
+ var cmdText = string.Empty;
- if (string.IsNullOrEmpty(exMessage))
- cmdText = $"INSERT INTO [LogEvents-DrService] ([Message], [Level], [TimeStamp], [ProcessName], [MethodName], [SourceContext]) VALUES (@msg,@lvl,GETUTCDATE(),@procName,@methodName,@srcContext)";
- else
- cmdText = $"INSERT INTO [LogEvents-DrService] ([Message], [Level], [TimeStamp], [Exception], [ProcessName], [MethodName], [SourceContext]) VALUES (@msg,@lvl,GETUTCDATE(), @exMessage,@procName,@methodName,@srcContext)";
-
- using var cmd = new SqlCommand(cmdText, db);
- cmd.Parameters.AddWithValue("@msg", msg);
- cmd.Parameters.AddWithValue("@lvl", lvl);
- cmd.Parameters.AddWithValue("@exMessage", exMessage);
- cmd.Parameters.AddWithValue("@procName", "Azure Function");
- cmd.Parameters.AddWithValue("@methodName", methodName);
- cmd.Parameters.AddWithValue("@srcContext", "CdrAuthServer.GetDataRecipients");
- await cmd.ExecuteNonQueryAsync();
- db.Close();
+ if (string.IsNullOrEmpty(exMessage))
+ {
+ cmdText = $"INSERT INTO [LogEvents-DrService] ([Message], [Level], [TimeStamp], [ProcessName], [MethodName], [SourceContext]) VALUES (@msg,@lvl,GETUTCDATE(),@procName,@methodName,@srcContext)";
}
+ else
+ {
+ cmdText = $"INSERT INTO [LogEvents-DrService] ([Message], [Level], [TimeStamp], [Exception], [ProcessName], [MethodName], [SourceContext]) VALUES (@msg,@lvl,GETUTCDATE(), @exMessage,@procName,@methodName,@srcContext)";
+ }
+
+ using var cmd = new SqlCommand(cmdText, db);
+ cmd.Parameters.AddWithValue("@msg", msg);
+ cmd.Parameters.AddWithValue("@lvl", lvl);
+ cmd.Parameters.AddWithValue("@exMessage", exMessage);
+ cmd.Parameters.AddWithValue("@procName", "Azure Function");
+ cmd.Parameters.AddWithValue("@methodName", methodName);
+ cmd.Parameters.AddWithValue("@srcContext", "CdrAuthServer.GetDataRecipients");
+ await cmd.ExecuteNonQueryAsync();
+ await db.CloseAsync();
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients_IntegrationTestsHelper.cs b/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients_IntegrationTestsHelper.cs
index b9ca383..c8db996 100644
--- a/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients_IntegrationTestsHelper.cs
+++ b/Source/CdrAuthServer.GetDataRecipients/GetDataRecipients_IntegrationTestsHelper.cs
@@ -1,5 +1,4 @@
-
-#if INTEGRATION_TESTS
+#if INTEGRATION_TESTS
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
@@ -37,4 +36,4 @@ public async Task INTEGRATIONTESTS_DATARECIPIENTS(
}
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Source/CdrAuthServer.GetDataRecipients/Program.cs b/Source/CdrAuthServer.GetDataRecipients/Program.cs
index f24fa9d..ddbdfb2 100644
--- a/Source/CdrAuthServer.GetDataRecipients/Program.cs
+++ b/Source/CdrAuthServer.GetDataRecipients/Program.cs
@@ -1,19 +1,21 @@
-using Microsoft.Extensions.Hosting;
+using System;
using System.IO;
using System.Reflection;
-using System;
+using CdrAuthServer.GetDataRecipients;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using CdrAuthServer.GetDataRecipients;
+using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureAppConfiguration((context, builder) =>
{
- var configuration = builder.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
- //while running on local machine via vs studio these are settings used
+ _ = builder.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
+
+ // while running on local machine via vs studio these are settings used
.AddJsonFile("local.settings.json", true, true)
- //while running docker these are config values used
+
+ // while running docker these are config values used
.AddJsonFile("appsettings.docker.json", true, true)
.AddEnvironmentVariables()
.AddCommandLine(Environment.GetCommandLineArgs())
@@ -35,4 +37,4 @@
})
.Build();
-host.Run();
\ No newline at end of file
+await host.RunAsync();
diff --git a/Source/CdrAuthServer.Infrastructure/Attributes/CheckXVAttribute.cs b/Source/CdrAuthServer.Infrastructure/Attributes/ReturnXVAttribute.cs
similarity index 99%
rename from Source/CdrAuthServer.Infrastructure/Attributes/CheckXVAttribute.cs
rename to Source/CdrAuthServer.Infrastructure/Attributes/ReturnXVAttribute.cs
index f3f6746..42bbc45 100644
--- a/Source/CdrAuthServer.Infrastructure/Attributes/CheckXVAttribute.cs
+++ b/Source/CdrAuthServer.Infrastructure/Attributes/ReturnXVAttribute.cs
@@ -3,7 +3,7 @@
namespace CdrAuthServer.Infrastructure.Attributes
{
///
- /// Checks the x-v header field is a supported version, if not then responds with BadRequest and appropriate ResponseErrorList
+ /// Checks the x-v header field is a supported version, if not then responds with BadRequest and appropriate ResponseErrorList.
///
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class ReturnXVAttribute : ActionFilterAttribute
@@ -23,4 +23,4 @@ public override void OnActionExecuted(ActionExecutedContext context)
base.OnActionExecuted(context);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/CdrAuthServer.Infrastructure/Authorisation/AuthServerAuthorisationPolicyAttribute.cs b/Source/CdrAuthServer.Infrastructure/Authorisation/AuthServerAuthorisationPolicyAttribute.cs
index 7da0631..9d47b24 100644
--- a/Source/CdrAuthServer.Infrastructure/Authorisation/AuthServerAuthorisationPolicyAttribute.cs
+++ b/Source/CdrAuthServer.Infrastructure/Authorisation/AuthServerAuthorisationPolicyAttribute.cs
@@ -13,6 +13,6 @@ public enum AuthServerAuthorisationPolicyAttribute
[AuthorisationPolicy("GetBankingAccounts", Scopes.ResourceApis.Banking.AccountsBasicRead, false, true, true)]
GetBankingAccounts,
[AuthorisationPolicy("AdminMetadataUpdate", Scopes.AdminMetadataUpdate, false, true, false)]
- AdminMetadataUpdate
+ AdminMetadataUpdate,
}
}
diff --git a/Source/CdrAuthServer.Infrastructure/Authorisation/AuthorisationPolicy.cs b/Source/CdrAuthServer.Infrastructure/Authorisation/AuthorisationPolicy.cs
index 01da057..460f2c0 100644
--- a/Source/CdrAuthServer.Infrastructure/Authorisation/AuthorisationPolicy.cs
+++ b/Source/CdrAuthServer.Infrastructure/Authorisation/AuthorisationPolicy.cs
@@ -1,7 +1,9 @@
namespace CdrAuthServer.Infrastructure.Authorisation
{
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
+#pragma warning disable S3376 // Attribute, EventArgs, and Exception type names should end with the type being extended
public class AuthorisationPolicy : Attribute
+#pragma warning restore S3376 // Attribute, EventArgs, and Exception type names should end with the type being extended
{
public AuthorisationPolicy(string name, string? scopeRequirement, bool hasMtlsRequirement, bool hasHolderOfKeyRequirement, bool hasAccessTokenRequirement)
{
@@ -13,9 +15,15 @@ public AuthorisationPolicy(string name, string? scopeRequirement, bool hasMtlsRe
}
public string Name { get; private set; }
+
public string? ScopeRequirement { get; private set; }
- public bool HasMtlsRequirement { get; private set; } //TODO: Currently not fully implemented in AuthServer. Implement in future to align with Mock Register
+
+#pragma warning disable S1135 // Track uses of "TODO" tags
+ public bool HasMtlsRequirement { get; private set; } // TODO: Currently not fully implemented in AuthServer. Implement in future to align with Mock Register
+#pragma warning restore S1135 // Track uses of "TODO" tags
+
public bool HasHolderOfKeyRequirement { get; private set; }
+
public bool HasAccessTokenRequirement { get; private set; }
}
}
diff --git a/Source/CdrAuthServer.Infrastructure/CdrAuthServer.Infrastructure.csproj b/Source/CdrAuthServer.Infrastructure/CdrAuthServer.Infrastructure.csproj
index 65ea3ee..3a9eab2 100644
--- a/Source/CdrAuthServer.Infrastructure/CdrAuthServer.Infrastructure.csproj
+++ b/Source/CdrAuthServer.Infrastructure/CdrAuthServer.Infrastructure.csproj
@@ -6,7 +6,8 @@
$(Version)
$(Version)
enable
- enable
+ enable
+ True
@@ -16,6 +17,14 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoadDetails.cs b/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoadDetails.cs
index 44edae8..d38ad68 100644
--- a/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoadDetails.cs
+++ b/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoadDetails.cs
@@ -5,14 +5,17 @@ public enum CertificateSource
Raw,
File,
Url,
- KeyVault
+ KeyVault,
}
public class CertificateLoadDetails
{
public CertificateSource Source { get; set; }
+
public string Content { get; set; } = string.Empty;
- public string Location { get; set; } = String.Empty;
- public string Password { get; set; } = String.Empty;
+
+ public string Location { get; set; } = string.Empty;
+
+ public string Password { get; set; } = string.Empty;
}
}
diff --git a/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoader.cs b/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoader.cs
index 8ec2f69..0c650e9 100644
--- a/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoader.cs
+++ b/Source/CdrAuthServer.Infrastructure/Certificates/CertificateLoader.cs
@@ -18,15 +18,15 @@ public async Task Load(CertificateLoadDetails loadDetails)
switch (loadDetails.Source)
{
case CertificateSource.File:
- return LoadCertificateFromBytes(File.ReadAllBytes(loadDetails.Location), loadDetails.Password);
+ return LoadCertificateFromBytes(await File.ReadAllBytesAsync(loadDetails.Location), loadDetails.Password);
case CertificateSource.Url:
- return LoadCertificateFromBytes((await DownloadData(loadDetails.Location)), loadDetails.Password);
+ return LoadCertificateFromBytes(await DownloadData(loadDetails.Location), loadDetails.Password);
case CertificateSource.Raw:
return LoadCertificateFromBytes(Convert.FromBase64String(loadDetails.Content), loadDetails.Password);
- case CertificateSource.KeyVault:
+ case CertificateSource.KeyVault:
throw new NotImplementedException();
default:
@@ -44,7 +44,7 @@ private static X509Certificate2 LoadCertificateFromBytes(byte[] certBytes, strin
return new X509Certificate2(certBytes, password, X509KeyStorageFlags.Exportable);
}
- private async static Task DownloadData(string url)
+ private static async Task DownloadData(string url)
{
using (var http = new HttpClient())
{
diff --git a/Source/CdrAuthServer.Infrastructure/Certificates/OcspRequester.cs b/Source/CdrAuthServer.Infrastructure/Certificates/OcspRequester.cs
index f1bd1a5..6081802 100644
--- a/Source/CdrAuthServer.Infrastructure/Certificates/OcspRequester.cs
+++ b/Source/CdrAuthServer.Infrastructure/Certificates/OcspRequester.cs
@@ -7,12 +7,11 @@
using Org.BouncyCastle.X509;
using System.Collections;
-
namespace CdrAuthServer.Infrastructure.Certificates
{
///
/// Online Certificate Status Protocol (OCSP) request builder class that is used to send a request
- /// to the defined OCSP responder defined in the certificates Authority Information Access (AIA) extension.
+ /// to the defined OCSP responder defined in the certificates Authority Information Access (AIA) extension.
///
public class OcspRequester
{
@@ -72,7 +71,7 @@ public async Task GetResult(string serialNumber)
_logger.LogInformation("OCSP Response revocation status = {RevokedStatus}", revokedStatus?.RevocationReason);
- return (revokedStatus == null ? OcspResult.Good : OcspResult.Revoked);
+ return revokedStatus == null ? OcspResult.Good : OcspResult.Revoked;
}
private BigInteger ConvertSerialNumber(string serialNumber)
@@ -87,7 +86,7 @@ private static byte[] BuildOcspRequest(BigInteger serialNumber, X509Certificate
CertificateID certId = new(CertificateID.HashSha1, cacert, serialNumber);
ocspRequestGenerator.AddRequest(certId);
- var derObjectIds = new List(); //Distinguished Encoding Rules (DER)
+ var derObjectIds = new List(); // Distinguished Encoding Rules (DER)
var extensionValues = new Hashtable();
Asn1OctetString asn1OctetString = new DerOctetString(BigInteger.ValueOf(DateTime.Now.Ticks).ToByteArray());
@@ -103,9 +102,9 @@ private static byte[] BuildOcspRequest(BigInteger serialNumber, X509Certificate
public static byte[] GetBytesFromPEM(string pem)
{
var base64 = pem
- .Replace(BEGIN_CERTIFICATE_MARKER, "")
- .Replace(END_CERTIFICATE_MARKER, "")
- .Replace(Environment.NewLine, "");
+ .Replace(BEGIN_CERTIFICATE_MARKER, string.Empty)
+ .Replace(END_CERTIFICATE_MARKER, string.Empty)
+ .Replace(Environment.NewLine, string.Empty);
return Convert.FromBase64String(base64);
}
diff --git a/Source/CdrAuthServer.Infrastructure/Constants.cs b/Source/CdrAuthServer.Infrastructure/Constants.cs
index f389cad..1c53bf1 100644
--- a/Source/CdrAuthServer.Infrastructure/Constants.cs
+++ b/Source/CdrAuthServer.Infrastructure/Constants.cs
@@ -19,11 +19,11 @@ public static class Scopes
{
public const string OpenId = "openid";
public const string Profile = "profile";
- public const string Registration = "cdr:registration"; //CDR_DYNAMIC_CLIENT_REGISTRATION
+ public const string Registration = "cdr:registration"; // CDR_DYNAMIC_CLIENT_REGISTRATION
public const string Common = "common:customer.basic:read common:customer.detail:read";
public const string Banking = "bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:payees:read bank:regular_payments:read";
public const string Energy = "energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.usage:read energy:electricity.der:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.paymentschedule:read energy:accounts.concessions:read energy:billing:read";
- public const string AdminMetadataUpdate = "admin:metadata:update"; //CDR_AUTHSERVER
+ public const string AdminMetadataUpdate = "admin:metadata:update"; // CDR_AUTHSERVER
public const string AdminMetricsRead = "admin:metrics.basic:read";
public const string BankingSectorScopes = $"{OpenId} {Profile} {Registration} {Common} {Banking}";
public const string AllSectorScopes = $"{BankingSectorScopes} {Energy}";
diff --git a/Source/CdrAuthServer.Infrastructure/Exceptions/ClientCertificateException.cs b/Source/CdrAuthServer.Infrastructure/Exceptions/ClientCertificateException.cs
index 61ad653..17188c2 100644
--- a/Source/CdrAuthServer.Infrastructure/Exceptions/ClientCertificateException.cs
+++ b/Source/CdrAuthServer.Infrastructure/Exceptions/ClientCertificateException.cs
@@ -2,8 +2,9 @@
{
public class ClientCertificateException : Exception
{
- public ClientCertificateException(string message) : base(message)
+ public ClientCertificateException(string message)
+ : base(message)
{
- }
+ }
}
}
diff --git a/Source/CdrAuthServer.Infrastructure/Extensions/AttributeExtensions.cs b/Source/CdrAuthServer.Infrastructure/Extensions/AttributeExtensions.cs
index 00b0190..9b10764 100644
--- a/Source/CdrAuthServer.Infrastructure/Extensions/AttributeExtensions.cs
+++ b/Source/CdrAuthServer.Infrastructure/Extensions/AttributeExtensions.cs
@@ -8,12 +8,13 @@ public static IEnumerable