diff --git a/azure/template.json b/azure/template.json index ef0246df7c..5e44d2f969 100644 --- a/azure/template.json +++ b/azure/template.json @@ -106,6 +106,10 @@ "type": "securestring", "defaultValue": "" }, + "DataProtectionKeysDatabase": { + "type": "string", + "defaultValue": "" + }, "ApprenticeshipProgrammesApiBaseUrl": { "type": "string", "defaultValue": "" @@ -191,6 +195,7 @@ "CobrowsingSnippetKey": "" } }, + "FaaConfiguration": { "type": "secureObject", "defaultValue": { @@ -621,7 +626,15 @@ { "name": "ZenDesk:CobrowsingSnippetKey", "value": "[parameters('ZenDesk').CobrowsingSnippetKey]" - } + }, + { + "name": "RedisConnectionSettings:RedisConnectionString", + "value": "[parameters('StorageRedisConnectionString')]" + }, + { + "name": "RedisConnectionSettings:DataProtectionKeysDatabase", + "value": "[parameters('DataProtectionKeysDatabase')]" + } ] } }, @@ -633,11 +646,6 @@ "connectionString": "[parameters('LoggingRedisConnectionString')]", "type": "Custom" }, - { - "name": "StorageRedis", - "connectionString": "[parameters('StorageRedisConnectionString')]", - "type": "Custom" - }, { "name": "MongoDb", "connectionString": "[concat('mongodb://', variables('CosmosDbName'), ':', reference(variables('CosmosDbName')).outputs.PrimaryMasterKey.value,'@', variables('CosmosDbName'), '.documents.azure.com:10255/?ssl=true&replicaSet=globaldb')]", @@ -791,7 +799,15 @@ { "name": "FaaConfiguration:StorageConnectionString", "value": "[parameters('FaaConfiguration').StorageConnectionString]" - } + }, + { + "name": "RedisConnectionSettings:RedisConnectionString", + "value": "[parameters('StorageRedisConnectionString')]" + }, + { + "name": "RedisConnectionSettings:DataProtectionKeysDatabase", + "value": "[parameters('DataProtectionKeysDatabase')]" + } ] } }, @@ -803,11 +819,6 @@ "connectionString": "[parameters('LoggingRedisConnectionString')]", "type": "Custom" }, - { - "name": "StorageRedis", - "connectionString": "[parameters('StorageRedisConnectionString')]", - "type": "Custom" - }, { "name": "MongoDb", "connectionString": "[concat('mongodb://', variables('CosmosDbName'), ':', reference(variables('CosmosDbName')).outputs.PrimaryMasterKey.value,'@', variables('CosmosDbName'), '.documents.azure.com:10255/?ssl=true&replicaSet=globaldb')]", @@ -1029,7 +1040,15 @@ { "name": "ProviderRelationshipsApiConfiguration:Tenant", "value": "[parameters('ProviderRelationshipsApiConfiguration').Tenant]" - } + }, + { + "name": "RedisConnectionSettings:RedisConnectionString", + "value": "[parameters('StorageRedisConnectionString')]" + }, + { + "name": "RedisConnectionSettings:DataProtectionKeysDatabase", + "value": "[parameters('DataProtectionKeysDatabase')]" + } ] } }, @@ -1041,11 +1060,6 @@ "connectionString": "[parameters('LoggingRedisConnectionString')]", "type": "Custom" }, - { - "name": "StorageRedis", - "connectionString": "[parameters('StorageRedisConnectionString')]", - "type": "Custom" - }, { "name": "MongoDb", "connectionString": "[concat('mongodb://', variables('CosmosDbName'), ':', reference(variables('CosmosDbName')).outputs.PrimaryMasterKey.value,'@', variables('CosmosDbName'), '.documents.azure.com:10255/?ssl=true&replicaSet=globaldb')]", diff --git a/src/Communication/Communication.Core/Communication.Core.csproj b/src/Communication/Communication.Core/Communication.Core.csproj index 70efc6c51c..ea7112a222 100644 --- a/src/Communication/Communication.Core/Communication.Core.csproj +++ b/src/Communication/Communication.Core/Communication.Core.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/Communication/Communication.Types/Communication.Types.csproj b/src/Communication/Communication.Types/Communication.Types.csproj index c42e90e706..77926608eb 100644 --- a/src/Communication/Communication.Types/Communication.Types.csproj +++ b/src/Communication/Communication.Types/Communication.Types.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/Employer/Employer.Web/Employer.Web.csproj b/src/Employer/Employer.Web/Employer.Web.csproj index 8d5866a0af..bdaf5de30a 100644 --- a/src/Employer/Employer.Web/Employer.Web.csproj +++ b/src/Employer/Employer.Web/Employer.Web.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Employer/Employer.Web/Startup.ConfigureServices.cs b/src/Employer/Employer.Web/Startup.ConfigureServices.cs index 40212ee7c7..e1665366b8 100644 --- a/src/Employer/Employer.Web/Startup.ConfigureServices.cs +++ b/src/Employer/Employer.Web/Startup.ConfigureServices.cs @@ -1,4 +1,5 @@ using Esfa.Recruit.Employer.Web.Configuration; +using Esfa.Recruit.Shared.Web.Extensions; using Esfa.Recruit.Shared.Web.FeatureToggle; using Esfa.Recruit.Vacancies.Client.Infrastructure.Client; using Microsoft.AspNetCore.Hosting; @@ -57,7 +58,9 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthenticationService(_authConfig, sp.GetService(), sp.GetService(), sp.GetService()); services.AddAuthorizationService(); - } + } + + services.AddDataProtection(_configuration, _hostingEnvironment, applicationName: "das-employer-recruit-web"); } } } diff --git a/src/Employer/Employer.Web/appsettings.Development.json b/src/Employer/Employer.Web/appsettings.Development.json index 6688fba79b..edc57e0e0a 100644 --- a/src/Employer/Employer.Web/appsettings.Development.json +++ b/src/Employer/Employer.Web/appsettings.Development.json @@ -25,9 +25,12 @@ "Features": { "SetNotificationPreferences": true }, + "RedisConnectionSettings": { + "RedisConnectionString": "localhost:6379", + "DataProtectionKeysDatabase": "abc123" + }, "ConnectionStrings": { "Redis": "localhost:6379", - "StorageRedis": "localhost:6379", "MongoDb": "mongodb://dbadmin:changeme@localhost:27017/admin/?ssl=false&authMechanism=SCRAM-SHA-1", "QueueStorage": "UseDevelopmentStorage=true", "TableStorage": "UseDevelopmentStorage=true" diff --git a/src/Employer/Employer.Web/appsettings.json b/src/Employer/Employer.Web/appsettings.json index 028796bdd5..c6cf1eae67 100644 --- a/src/Employer/Employer.Web/appsettings.json +++ b/src/Employer/Employer.Web/appsettings.json @@ -39,11 +39,15 @@ "FindProviderUrl": "https://findapprenticeshiptraining.apprenticeships.education.gov.uk/provider/search", "CommitmentsSiteUrl": "https://manage-apprenticeships.service.gov.uk/", "NationalMinimumWageRates": "https://www.gov.uk/national-minimum-wage-rates", - "EmployerFavouritesUrl": "https://test-employerfavourites.apprenticeships.education.gov.uk" + "EmployerFavouritesUrl": "https://test-employerfavourites.apprenticeships.education.gov.uk" }, "Features": { "SetNotificationPreferences": false }, + "RedisConnectionSettings": { + "RedisConnectionString": "", + "DataProtectionKeysDatabase": "" + }, "ManageApprenticeshipsRoutes": { "ManageApprenticeshipSiteAccountsHomeRoute": "/accounts/{0}/teams", "ManageApprenticeshipSiteHelpRoute": "/service/help", @@ -78,7 +82,6 @@ }, "ConnectionStrings": { "Redis": "", - "StorageRedis": "", "MongoDb": "", "QueueStorage": "", "TableStorage": "" diff --git a/src/Employer/IntegrationTests/IntegrationTests.csproj b/src/Employer/IntegrationTests/IntegrationTests.csproj index ef852dd225..6305dc272c 100644 --- a/src/Employer/IntegrationTests/IntegrationTests.csproj +++ b/src/Employer/IntegrationTests/IntegrationTests.csproj @@ -1,6 +1,6 @@ - netcoreapp2.1 + netcoreapp2.2 false Esfa.Recruit.Employer.IntegrationTests diff --git a/src/Provider/Provider.Web/Provider.Web.csproj b/src/Provider/Provider.Web/Provider.Web.csproj index a2b2e1847c..99b48cbc26 100644 --- a/src/Provider/Provider.Web/Provider.Web.csproj +++ b/src/Provider/Provider.Web/Provider.Web.csproj @@ -1,6 +1,6 @@  - netcoreapp2.1 + netcoreapp2.2 recruit-provider-web Esfa.Recruit.Provider.Web @@ -17,7 +17,7 @@ - + diff --git a/src/Provider/Provider.Web/Startup.ConfigureServices.cs b/src/Provider/Provider.Web/Startup.ConfigureServices.cs index 16bca1f93b..7608ce2419 100644 --- a/src/Provider/Provider.Web/Startup.ConfigureServices.cs +++ b/src/Provider/Provider.Web/Startup.ConfigureServices.cs @@ -1,4 +1,5 @@ using Esfa.Recruit.Provider.Web.Configuration; +using Esfa.Recruit.Shared.Web.Extensions; using Esfa.Recruit.Vacancies.Client.Infrastructure.Client; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Razor; @@ -43,6 +44,7 @@ public void ConfigureServices(IServiceCollection services) }); services.AddMvcService(_hostingEnvironment, _loggerFactory); + services.AddDataProtection(_configuration, _hostingEnvironment, applicationName: "das-provider-recruit-web"); services.AddApplicationInsightsTelemetry(_configuration); diff --git a/src/Provider/Provider.Web/appsettings.Development.json b/src/Provider/Provider.Web/appsettings.Development.json index 8d422b6333..6e26154f1d 100644 --- a/src/Provider/Provider.Web/appsettings.Development.json +++ b/src/Provider/Provider.Web/appsettings.Development.json @@ -30,5 +30,9 @@ "QueueStorage": "UseDevelopmentStorage=true", "TableStorage": "UseDevelopmentStorage=true" }, - "UseTableStorageQueryStore": false + "UseTableStorageQueryStore": false, + "RedisConnectionSettings": { + "RedisConnectionString": "localhost:6379", + "DataProtectionKeysDatabase": "abc123" + } } diff --git a/src/Provider/Provider.Web/appsettings.json b/src/Provider/Provider.Web/appsettings.json index af954c6282..4dd285fc8e 100644 --- a/src/Provider/Provider.Web/appsettings.json +++ b/src/Provider/Provider.Web/appsettings.json @@ -69,7 +69,6 @@ }, "ConnectionStrings": { "Redis": "", - "StorageRedis": "", "MongoDb": "", "QueueStorage": "", "TableStorage": "" @@ -93,5 +92,9 @@ "ClientId": "", "ClientSecret": "", "ApiBaseUrl": "" + }, + "RedisConnectionSettings": { + "RedisConnectionString": "", + "DataProtectionKeysDatabase": "" } } diff --git a/src/Provider/UnitTests/UnitTests.csproj b/src/Provider/UnitTests/UnitTests.csproj index b4c1f6c2b1..4f354fb8f7 100644 --- a/src/Provider/UnitTests/UnitTests.csproj +++ b/src/Provider/UnitTests/UnitTests.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp2.2 false diff --git a/src/QA/QA.Web/QA.Web.csproj b/src/QA/QA.Web/QA.Web.csproj index 607c323440..ef51fced43 100644 --- a/src/QA/QA.Web/QA.Web.csproj +++ b/src/QA/QA.Web/QA.Web.csproj @@ -1,6 +1,6 @@  - netcoreapp2.1 + netcoreapp2.2 recruit-qa-web Esfa.Recruit.Qa.Web @@ -10,11 +10,11 @@ - - - - - + + + + + diff --git a/src/QA/QA.Web/Startup.ConfigureServices.cs b/src/QA/QA.Web/Startup.ConfigureServices.cs index b17db99a2f..9bd44903d2 100644 --- a/src/QA/QA.Web/Startup.ConfigureServices.cs +++ b/src/QA/QA.Web/Startup.ConfigureServices.cs @@ -7,11 +7,13 @@ using Esfa.Recruit.QA.Web.Filters; using Esfa.Recruit.QA.Web.Orchestrators; using Esfa.Recruit.Shared.Web.Configuration; +using Esfa.Recruit.Shared.Web.Extensions; using Esfa.Recruit.Shared.Web.Mappers; using Esfa.Recruit.Shared.Web.RuleTemplates; using Esfa.Recruit.Shared.Web.Services; using Esfa.Recruit.Vacancies.Client.Application.Configuration; using Esfa.Recruit.Vacancies.Client.Ioc; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.Configuration; @@ -23,15 +25,17 @@ namespace Esfa.Recruit.Qa.Web public partial class Startup { private readonly IConfiguration _configuration; + private readonly IHostingEnvironment _hostingEnvironment; private readonly AuthenticationConfiguration _authenticationConfig; private readonly AuthorizationConfiguration _legacyAuthorizationConfig; private readonly AuthorizationConfiguration _authorizationConfig; private readonly ExternalLinksConfiguration _externalLinks; private readonly ILoggerFactory _loggerFactory; - public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) + public Startup(IConfiguration configuration, IHostingEnvironment env, ILoggerFactory loggerFactory) { _configuration = configuration; + _hostingEnvironment = env; _authenticationConfig = _configuration.GetSection("Authentication").Get(); _legacyAuthorizationConfig = _configuration.GetSection("LegacyAuthorization").Get(); _authorizationConfig = _configuration.GetSection("Authorization").Get(); @@ -54,6 +58,7 @@ public void ConfigureServices(IServiceCollection services) }); services.AddMvcService(_loggerFactory); + services.AddDataProtection(_configuration, _hostingEnvironment, applicationName: "das-qa-recruit-web"); services.AddAntiforgery( options => diff --git a/src/QA/QA.Web/appsettings.Development.json b/src/QA/QA.Web/appsettings.Development.json index 24ff105d1a..0f4dfe1f49 100644 --- a/src/QA/QA.Web/appsettings.Development.json +++ b/src/QA/QA.Web/appsettings.Development.json @@ -17,13 +17,16 @@ "Slack": { "FindAnApprenticeshipDetailPrefixUrl": "https://www.findapprenticeship.service.gov.uk/apprenticeship/" }, + "RedisConnectionSettings": { + "RedisConnectionString": "localhost:6379", + "DataProtectionKeysDatabase": "abc123" + }, "ConnectionStrings": { "Redis": "localhost:6379", - "StorageRedis": "localhost:6379", "MongoDb": "mongodb://dbadmin:changeme@localhost:27017/admin/?ssl=false&authMechanism=SCRAM-SHA-1", "QueueStorage": "UseDevelopmentStorage=true", "TableStorage": "UseDevelopmentStorage=true", - "CommunicationsStorage": "UseDevelopmentStorage=true", + "CommunicationsStorage": "UseDevelopmentStorage=true" }, "ExternalLinks": { "StaffIdamsUrl": "https://adfs.preprod.skillsfunding.service.gov.uk" diff --git a/src/QA/QA.Web/appsettings.json b/src/QA/QA.Web/appsettings.json index 7f2841b99a..59fbb3fbdb 100644 --- a/src/QA/QA.Web/appsettings.json +++ b/src/QA/QA.Web/appsettings.json @@ -16,7 +16,6 @@ }, "ConnectionStrings": { "Redis": "", - "StorageRedis": "", "MongoDb": "", "QueueStorage": "", "TableStorage": "", @@ -52,5 +51,9 @@ "UseTableStorageQueryStore": false, "FaaConfiguration": { "StorageConnectionString": "" + }, + "RedisConnectionSettings": { + "RedisConnectionString": "", + "DataProtectionKeysDatabase": "" } } diff --git a/src/QA/UnitTests/UnitTests.csproj b/src/QA/UnitTests/UnitTests.csproj index 3a247cbc49..8795c44b98 100644 --- a/src/QA/UnitTests/UnitTests.csproj +++ b/src/QA/UnitTests/UnitTests.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp2.2 false diff --git a/src/Shared/Recruit.Shared.Web/Configuration/RedisConnectionSettings.cs b/src/Shared/Recruit.Shared.Web/Configuration/RedisConnectionSettings.cs new file mode 100644 index 0000000000..005f7807a7 --- /dev/null +++ b/src/Shared/Recruit.Shared.Web/Configuration/RedisConnectionSettings.cs @@ -0,0 +1,8 @@ +namespace Esfa.Recruit.Shared.Web.Configuration +{ + public class RedisConnectionSettings + { + public string RedisConnectionString { get; set; } + public string DataProtectionKeysDatabase { get; set; } + } +} diff --git a/src/Shared/Recruit.Shared.Web/Extensions/DataProtectionStartupExtensions.cs b/src/Shared/Recruit.Shared.Web/Extensions/DataProtectionStartupExtensions.cs new file mode 100644 index 0000000000..0a81bce6e8 --- /dev/null +++ b/src/Shared/Recruit.Shared.Web/Extensions/DataProtectionStartupExtensions.cs @@ -0,0 +1,36 @@ +using Esfa.Recruit.Shared.Web.Configuration; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; + +namespace Esfa.Recruit.Shared.Web.Extensions +{ + public static class DataProtectionStartupExtensions + { + public static IServiceCollection AddDataProtection(this IServiceCollection services, IConfiguration configuration, IHostingEnvironment environment, string applicationName) + { + if (!environment.IsDevelopment()) + { + var redisConfiguration = configuration.GetSection("RedisConnectionSettings") + .Get(); + + if (redisConfiguration != null) + { + var redisConnectionString = redisConfiguration.RedisConnectionString; + var dataProtectionKeysDatabase = redisConfiguration.DataProtectionKeysDatabase; + + var redis = ConnectionMultiplexer + .Connect($"{redisConnectionString},{dataProtectionKeysDatabase}"); + + services.AddDataProtection() + .SetApplicationName(applicationName) + .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys"); + } + } + + return services; + } + } +} diff --git a/src/Shared/Recruit.Shared.Web/Recruit.Shared.Web.csproj b/src/Shared/Recruit.Shared.Web/Recruit.Shared.Web.csproj index 28920856f9..21662a18c6 100644 --- a/src/Shared/Recruit.Shared.Web/Recruit.Shared.Web.csproj +++ b/src/Shared/Recruit.Shared.Web/Recruit.Shared.Web.csproj @@ -8,7 +8,9 @@ - + + +