diff --git a/MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs b/MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs index b6acc87..b5b492a 100644 --- a/MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs +++ b/MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs @@ -45,7 +45,7 @@ public async Task Mediator_Send_RequestHandled() { this.AddTestRegistrations(services, hostingEnvironment.Object); s.ConfigureContainer(services); - Startup.Container.AssertConfigurationIsValid(AssertMode.Full); + //Startup.Container.AssertConfigurationIsValid(AssertMode.Full); List errors = new(); IMediator mediator = Startup.Container.GetService(); diff --git a/MessagingService.IntegrationTests/SMS/SendSMS.feature b/MessagingService.IntegrationTests/SMS/SendSMS.feature index e5a6861..b026685 100644 --- a/MessagingService.IntegrationTests/SMS/SendSMS.feature +++ b/MessagingService.IntegrationTests/SMS/SendSMS.feature @@ -8,7 +8,7 @@ Background: | messagingService | Messaging REST Scope | A scope for Messaging REST | Given the following api resources exist - | ResourceName | DisplayName | Secret | Scopes | UserClaims | + | Name | DisplayName | Secret | Scopes | UserClaims | | messagingService | Messaging REST | Secret1 | messagingService | | Given the following clients exist diff --git a/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs b/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs index 9c4119e..cac611a 100644 --- a/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs +++ b/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs @@ -113,53 +113,53 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa { #line 4 #line hidden - global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] { "Name", "DisplayName", "Description"}); - table6.AddRow(new string[] { + table1.AddRow(new string[] { "messagingService", "Messaging REST Scope", "A scope for Messaging REST"}); #line 6 - await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table6, "Given "); + await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table1, "Given "); #line hidden - global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { - "ResourceName", + global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { + "Name", "DisplayName", "Secret", "Scopes", "UserClaims"}); - table7.AddRow(new string[] { + table2.AddRow(new string[] { "messagingService", "Messaging REST", "Secret1", "messagingService", ""}); #line 10 - await testRunner.GivenAsync("the following api resources exist", ((string)(null)), table7, "Given "); + await testRunner.GivenAsync("the following api resources exist", ((string)(null)), table2, "Given "); #line hidden - global::Reqnroll.Table table8 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { "ClientId", "ClientName", "Secret", "Scopes", "GrantTypes"}); - table8.AddRow(new string[] { + table3.AddRow(new string[] { "serviceClient", "Service Client", "Secret1", "messagingService", "client_credentials"}); #line 14 - await testRunner.GivenAsync("the following clients exist", ((string)(null)), table8, "Given "); + await testRunner.GivenAsync("the following clients exist", ((string)(null)), table3, "Given "); #line hidden - global::Reqnroll.Table table9 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { "ClientId"}); - table9.AddRow(new string[] { + table4.AddRow(new string[] { "serviceClient"}); #line 18 - await testRunner.GivenAsync("I have a token to access the messaging service resource", ((string)(null)), table9, "Given "); + await testRunner.GivenAsync("I have a token to access the messaging service resource", ((string)(null)), table4, "Given "); #line hidden } @@ -193,16 +193,16 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa #line 4 await this.FeatureBackgroundAsync(); #line hidden - global::Reqnroll.Table table10 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { "Sender", "Destination", "Message"}); - table10.AddRow(new string[] { + table5.AddRow(new string[] { "TestSender", "07777777771", "TestSMSMessage"}); #line 24 - await testRunner.GivenAsync("I send the following SMS Messages", ((string)(null)), table10, "Given "); + await testRunner.GivenAsync("I send the following SMS Messages", ((string)(null)), table5, "Given "); #line hidden } await this.ScenarioCleanupAsync(); diff --git a/MessagingService.Testing/TestData.cs b/MessagingService.Testing/TestData.cs index a0586d4..917d371 100644 --- a/MessagingService.Testing/TestData.cs +++ b/MessagingService.Testing/TestData.cs @@ -341,6 +341,7 @@ public static Dictionary GetStandardMemoryConfiguration() configuration.Add("AppSettings:SMSProxy", "UnitTest"); configuration.Add("ConnectionStrings:HealthCheck", "HeathCheckConnString"); configuration.Add("SecurityConfiguration:Authority", "https://127.0.0.1"); + configuration.Add("SecurityConfiguration:ApiName", "messagingService"); configuration.Add("EventStoreSettings:ConnectionString", "esdb://127.0.0.1:2113"); configuration.Add("EventStoreSettings:ConnectionName", "UnitTestConnection"); configuration.Add("EventStoreSettings:UserName", "admin"); diff --git a/MessagingService.Tests/General/BootstrapperTests.cs b/MessagingService.Tests/General/BootstrapperTests.cs deleted file mode 100644 index 03846a0..0000000 --- a/MessagingService.Tests/General/BootstrapperTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Microsoft.AspNetCore.Mvc.Infrastructure; -using Microsoft.AspNetCore.Routing; -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using Microsoft.AspNetCore.Routing.Patterns; - -namespace MessagingService.Tests.General -{ - using Lamar; - using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Mvc.Abstractions; - using Microsoft.AspNetCore.Mvc.ApiExplorer; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Hosting; - using Microsoft.Extensions.Options; - using Moq; - using System.Diagnostics; - using System.Linq; - using Testing; - using Xunit; - - [Collection("TestCollection")] - public class BootstrapperTests - { - #region Methods - - [Fact] - public void VerifyBootstrapperIsValid() - { - Mock hostingEnvironment = new(); - hostingEnvironment.Setup(he => he.EnvironmentName).Returns("Development"); - hostingEnvironment.Setup(he => he.ContentRootPath).Returns("/home"); - hostingEnvironment.Setup(he => he.ApplicationName).Returns("Test Application"); - - ServiceRegistry services = new(); - Startup s = new(hostingEnvironment.Object); - Startup.Configuration = this.SetupMemoryConfiguration(); - - this.AddTestRegistrations(services, hostingEnvironment.Object); - s.ConfigureContainer(services); - Startup.Container.AssertConfigurationIsValid(AssertMode.Full); - } - - private IConfigurationRoot SetupMemoryConfiguration(){ - Dictionary configuration = TestData.GetStandardMemoryConfiguration(); - - IConfigurationBuilder builder = new ConfigurationBuilder(); - - builder.AddInMemoryCollection(configuration); - - return builder.Build(); - } - - /// - /// Adds the test registrations. - /// - /// The services. - /// The hosting environment. - private void AddTestRegistrations(IServiceCollection services, - IWebHostEnvironment hostingEnvironment) - { - services.AddLogging(); - DiagnosticListener diagnosticSource = new(hostingEnvironment.ApplicationName); - services.AddSingleton(diagnosticSource); - services.AddSingleton(diagnosticSource); - services.AddSingleton(hostingEnvironment); - services.AddSingleton(hostingEnvironment); - services.AddSingleton(Startup.Configuration); - } - - #endregion - } -} diff --git a/MessagingService.Tests/MessagingService.Tests.csproj b/MessagingService.Tests/MessagingService.Tests.csproj index 6a447e5..05d1428 100644 --- a/MessagingService.Tests/MessagingService.Tests.csproj +++ b/MessagingService.Tests/MessagingService.Tests.csproj @@ -29,4 +29,8 @@ + + + + diff --git a/MessagingService/Bootstrapper/MiddlewareRegistry.cs b/MessagingService/Bootstrapper/MiddlewareRegistry.cs index f1daab1..f374403 100644 --- a/MessagingService/Bootstrapper/MiddlewareRegistry.cs +++ b/MessagingService/Bootstrapper/MiddlewareRegistry.cs @@ -1,6 +1,8 @@ using KurrentDB.Client; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi; +using OpenIddict.Client; using Shared.Authorisation; namespace MessagingService.Bootstrapper @@ -51,30 +53,51 @@ public MiddlewareRegistry() { } private void ConfigureAuthentication() { - this.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(options => - { - options.BackchannelHttpHandler = new HttpClientHandler - { - ServerCertificateCustomValidationCallback = - (message, certificate, chain, sslPolicyErrors) => true - }; - options.Authority = GetSecurityConfigSetting("Authority"); - options.Audience = GetSecurityConfigSetting("ApiName"); + //this.AddAuthentication(options => + // { + // options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + // options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + // options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + // }) + // .AddJwtBearer(options => + // { + // options.BackchannelHttpHandler = new HttpClientHandler + // { + // ServerCertificateCustomValidationCallback = + // (message, certificate, chain, sslPolicyErrors) => true + // }; + // options.Authority = GetSecurityConfigSetting("Authority"); + // options.Audience = GetSecurityConfigSetting("ApiName"); + + // options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() + // { + // ValidateAudience = false, + // ValidAudience = GetSecurityConfigSetting("ApiName"), + // ValidIssuer = GetSecurityConfigSetting("Authority"), + // }; + // options.IncludeErrorDetails = true; + // }); + this.AddOpenIddict() + // Register the OpenIddict client components. + .AddClient(options => { + // Allow grant_type=client_credentials to be negotiated. + options.AllowClientCredentialsFlow(); + + // Disable token storage, which is not necessary for non-interactive flows like + // grant_type=password, grant_type=client_credentials or grant_type=refresh_token. + options.DisableTokenStorage(); + + // Register the System.Net.Http integration and use the identity of the current + // assembly as a more specific user agent, which can be useful when dealing with + // providers that use the user agent as a way to throttle requests (e.g Reddit). + options.UseSystemNetHttp().SetProductInformation(typeof(Program).Assembly); + + // Add a client registration matching the client application definition in the server project. + options.AddRegistration(new OpenIddictClientRegistration { Issuer = new Uri(GetSecurityConfigSetting("Authority"), UriKind.Absolute), ClientId = GetSecurityConfigSetting("ApiName") }); - options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() - { - ValidateAudience = false, - ValidAudience = GetSecurityConfigSetting("ApiName"), - ValidIssuer = GetSecurityConfigSetting("Authority"), - }; - options.IncludeErrorDetails = true; }); + + this.AddClientCredentialsOnlyPolicy(); this.AddClientCredentialsHandler(); diff --git a/MessagingService/MessagingService.csproj b/MessagingService/MessagingService.csproj index 4f3e52c..3929b05 100644 --- a/MessagingService/MessagingService.csproj +++ b/MessagingService/MessagingService.csproj @@ -10,6 +10,7 @@ + @@ -18,6 +19,7 @@ +