From 40d457b2ca31bd386d229a5b69af1abbbed854ad Mon Sep 17 00:00:00 2001 From: Matt Hoffmeister Date: Tue, 15 Feb 2022 08:45:56 -0600 Subject: [PATCH] Add GCP Secret Manager --- .gcp/asaph-dev.json | 12 +++ Asaph.Bootstrapper/Asaph.Bootstrapper.csproj | 2 +- .../Asaph.Core.UnitTests.csproj | 8 +- Asaph.Core/Asaph.Core.csproj | 4 +- .../AggregateSongDirectorRepositoryTests.cs | 4 +- ...aph.Infrastructure.IntegrationTests.csproj | 4 +- .../AzureAdb2cSongDirectorRepositoryTests.cs | 2 +- .../DynamoDBSongDirectorRepositoryTests.cs | 4 +- .../Asaph.Infrastructure.csproj | 8 +- .../Asaph.WebApi.IntegrationTests.csproj | 4 +- .../Asaph.WebApi.UnitTests.csproj | 4 +- Asaph.WebApi/Asaph.WebApi.csproj | 5 +- Asaph.WebApi/Dockerfile | 12 +-- ...GcpSecretManagerConfigurationExtensions.cs | 25 +++++ .../GcpSecretManagerConfigurationProvider.cs | 98 +++++++++++++++++++ .../GcpSecretManagerConfigurationSource.cs | 29 ++++++ Asaph.WebApi/Program.cs | 4 + Asaph.WebApi/appsettings.Development.json | 11 ++- Asaph.WebApi/appsettings.json | 3 +- 19 files changed, 209 insertions(+), 34 deletions(-) create mode 100644 .gcp/asaph-dev.json create mode 100644 Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationExtensions.cs create mode 100644 Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationProvider.cs create mode 100644 Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationSource.cs diff --git a/.gcp/asaph-dev.json b/.gcp/asaph-dev.json new file mode 100644 index 0000000..061f98e --- /dev/null +++ b/.gcp/asaph-dev.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "asaph-dev", + "private_key_id": "8233a3f09f026303d76949bbafa14f61d924e14e", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDbForo+GnsGJqk\nRrdTGcDgsGJu2SULEyu303gRFBtvHjSWddBpYyvIXGOdT+ph/0T3KcytFKmI9Y2M\n4um97+55IgV0SBKb1W6s0Eejl2ofxoGPjRHcIdTtokHmr+WPpYFV/7+xha0Rf4Z3\n2QmBk7UfmN/awXb7MxTKGC4b2ZFlcwINdXXQIf0i8D474uhpNYbeTEQ4kR29WshW\nGSApFy4frbdEjUl0u06JWcfI0EMCPMzD1GbOQFtb6HnU0lD//U0Ett5H3npMbWY+\n4Nya/qGSB+gmeQGrVu/kVQhZowuYh6pReCPGBcj8Wy4DKI510IL/875g4x6I40Ju\nXHvNhS7ZAgMBAAECggEAA6Up+OfvlNOj+KLxXrSWMCbYvGqbryxJrrlNM7UkVhwo\nJW8ex8iBBfuWvLTqFWjsRzoVNoJnGU92MQ3ldBkpD2Lj7FddCxkcY+VJpXMmrnip\ncMkye6y+Bv++hCdEQbhjOoCsbWu0wXT5uJMn3iJzAdLG7RpvvFlq0yH4qNLDeu7/\n2H5dYLKEtIs20GxLXRXmlAk8UtmuOkL3ThejLemEO9U5DExOIzQ9lkD4OhRDdI9L\nrY2Q7XgJnkjZN0Fln/Xq2p56v34mZ+5HRcCc6mtSDXZbmZX8LZ/Pk0a/BP8ZvkW3\nRnL6jTxO5aqma9KnSO4M1OT5e/vqO/fZ748Tci62wQKBgQDynX1GEWP6LgxkF9Ox\ns1GY/ZFWPfk8Fj3wWgRC5uIjYI0JoFOps69Uij3n2AxJypInIM5so4zIKWus7k64\nrWoHGQnQKiCLbuHRpa2N4EeUYhjUIwoAmi0pVlIlGfzs6N8Lab7/bfzqj9D5Vgq+\ngLl/RWa3NNBnhkmKmLeepu5JjQKBgQDnLMYplFGvaJtQ7cz2hwOP42dDyvrMQTim\nJsb+4/IMrwI7dwSmcWpz3sRUzPbjbLzPUlgJOzDgyRqv85yObMo1FB691EfpTkPV\nA4i0ARerJhIjnaNeIVF/9eUMcRyOHglcYLbXSXbmmaEZbNEz+dj+58RwsLjKkitl\nVO/ZqY6ZfQKBgQCbKAzNmqGNhZV3DaXcpwkwBjnEJa4Wt0K1S1weTPmiFkUcOuRG\nSxt9vUsJ0ilJp7sAOwLIh2+pMpQh6+V8RarhDyovbkGR6j+Qi5wKd7xPMM0gHahv\n6imnngS6pXwTJno+GkqDoBt3BrJmQphsbHY05nViBOyiyEaP1ErZs3gAoQKBgGEH\nLuk2wo4/9qiiFtwGUR1skeQnZtqiKVe7gNxs6iQetG4nB0Gg6tBVWMxK9vj/o8PU\nyPSe7mX6ooPlWPmCeeCLYFfGqKQo4Fmg0RjUOI3yPbzLJk2U6HMvzwJI23Ze7wjh\n4vw7bnddVfuo66nIHSboOlAeLIGBlktCuiT+gMa1AoGAB4R6o4Y+Ue+i173G6AbC\nsTODEpXOnBNlgt+RQ9900qc1sBU7518QSJQOe645a4+BIIQ6WwUZgPRoN2qr1Eec\nmazXdT+xDFi8OjhlF1j/RZsp6f5bMVuQkAqadPgtN7NjA7xyE/YFTSu1OMYseyXn\ngfDA5SUUy6LKPDfEclZkidA=\n-----END PRIVATE KEY-----\n", + "client_email": "secret-accessor@asaph-dev.iam.gserviceaccount.com", + "client_id": "117527350958472163100", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/secret-accessor%40asaph-dev.iam.gserviceaccount.com" +} diff --git a/Asaph.Bootstrapper/Asaph.Bootstrapper.csproj b/Asaph.Bootstrapper/Asaph.Bootstrapper.csproj index f2c5502..ec595cd 100644 --- a/Asaph.Bootstrapper/Asaph.Bootstrapper.csproj +++ b/Asaph.Bootstrapper/Asaph.Bootstrapper.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Asaph.Core.UnitTests/Asaph.Core.UnitTests.csproj b/Asaph.Core.UnitTests/Asaph.Core.UnitTests.csproj index 65da637..7447ba4 100644 --- a/Asaph.Core.UnitTests/Asaph.Core.UnitTests.csproj +++ b/Asaph.Core.UnitTests/Asaph.Core.UnitTests.csproj @@ -11,11 +11,11 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -28,7 +28,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Asaph.Core/Asaph.Core.csproj b/Asaph.Core/Asaph.Core.csproj index 9253605..dcd85ea 100644 --- a/Asaph.Core/Asaph.Core.csproj +++ b/Asaph.Core/Asaph.Core.csproj @@ -7,8 +7,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Asaph.Infrastructure.IntegrationTests/AggregateSongDirectorRepositoryTests.cs b/Asaph.Infrastructure.IntegrationTests/AggregateSongDirectorRepositoryTests.cs index dd5aac8..2bb2283 100644 --- a/Asaph.Infrastructure.IntegrationTests/AggregateSongDirectorRepositoryTests.cs +++ b/Asaph.Infrastructure.IntegrationTests/AggregateSongDirectorRepositoryTests.cs @@ -114,13 +114,13 @@ public static async Task TryFindPropertyById_Rank_ReturnsExpectedRankName( /// /// Tests getting all song directors. - /// + /// /// AWS region system name. /// Indicates whether to use Dynamo DB local. /// Expected song director count. /// The async operation. [Theory] - [InlineData("us-east-2", true, 1)] + [InlineData("us-east-2", false, 1)] public static async Task TryGetAllAsync( string awsRegionSystemName, bool useDynamoDBLocal, diff --git a/Asaph.Infrastructure.IntegrationTests/Asaph.Infrastructure.IntegrationTests.csproj b/Asaph.Infrastructure.IntegrationTests/Asaph.Infrastructure.IntegrationTests.csproj index 7e2e0ae..85348c2 100644 --- a/Asaph.Infrastructure.IntegrationTests/Asaph.Infrastructure.IntegrationTests.csproj +++ b/Asaph.Infrastructure.IntegrationTests/Asaph.Infrastructure.IntegrationTests.csproj @@ -13,7 +13,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -26,7 +26,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Asaph.Infrastructure.IntegrationTests/AzureAdb2cSongDirectorRepositoryTests.cs b/Asaph.Infrastructure.IntegrationTests/AzureAdb2cSongDirectorRepositoryTests.cs index 57bd583..d6e3e87 100644 --- a/Asaph.Infrastructure.IntegrationTests/AzureAdb2cSongDirectorRepositoryTests.cs +++ b/Asaph.Infrastructure.IntegrationTests/AzureAdb2cSongDirectorRepositoryTests.cs @@ -91,7 +91,7 @@ public static async Task TryFindPropertyById_Rank_ReturnsExpectedRankName( /// Expected song director count. /// The async operation. [Theory] - [InlineData(2)] + [InlineData(1)] public static async Task TryGetAllAsync_ExistingSongDirectors_ReturnsExpectedCount( int expectedSongDirectorDataModelCount) { diff --git a/Asaph.Infrastructure.IntegrationTests/DynamoDBSongDirectorRepositoryTests.cs b/Asaph.Infrastructure.IntegrationTests/DynamoDBSongDirectorRepositoryTests.cs index 71a7a70..9c0d638 100644 --- a/Asaph.Infrastructure.IntegrationTests/DynamoDBSongDirectorRepositoryTests.cs +++ b/Asaph.Infrastructure.IntegrationTests/DynamoDBSongDirectorRepositoryTests.cs @@ -34,7 +34,7 @@ public class DynamoDBSongDirectorRepositoryTests /// Is active indicator to add. /// The async operation. [Theory] - [InlineData("us-east-2", true, "d7a068f8-461d-42f2-a561-5ea2f843c2b3", true)] + [InlineData("us-east-2", false, "d7a068f8-461d-42f2-a561-5ea2f843c2b3", true)] public static async Task TryAddAsync_ValidSongDirector_Succeeds( string awsRegionSystemName, bool useDynamoDBLocal, string songDirectorId, bool isActive) { @@ -95,7 +95,7 @@ public static async Task TryFindPropertyByIdAsync_Rank_ReturnsFailedResult( /// Expected song director count. /// The async operation. [Theory] - [InlineData("us-east-2", true, 2)] + [InlineData("us-east-2", false, 1)] public static async Task TryGetAllAsync( string awsRegionSystemName, bool useDynamoDBLocal, diff --git a/Asaph.Infrastructure/Asaph.Infrastructure.csproj b/Asaph.Infrastructure/Asaph.Infrastructure.csproj index c6cb616..e226fc6 100644 --- a/Asaph.Infrastructure/Asaph.Infrastructure.csproj +++ b/Asaph.Infrastructure/Asaph.Infrastructure.csproj @@ -6,12 +6,12 @@ - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Asaph.WebApi.IntegrationTests/Asaph.WebApi.IntegrationTests.csproj b/Asaph.WebApi.IntegrationTests/Asaph.WebApi.IntegrationTests.csproj index c60be04..1d07168 100644 --- a/Asaph.WebApi.IntegrationTests/Asaph.WebApi.IntegrationTests.csproj +++ b/Asaph.WebApi.IntegrationTests/Asaph.WebApi.IntegrationTests.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -21,7 +21,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Asaph.WebApi.UnitTests/Asaph.WebApi.UnitTests.csproj b/Asaph.WebApi.UnitTests/Asaph.WebApi.UnitTests.csproj index a418399..117079e 100644 --- a/Asaph.WebApi.UnitTests/Asaph.WebApi.UnitTests.csproj +++ b/Asaph.WebApi.UnitTests/Asaph.WebApi.UnitTests.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -21,7 +21,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Asaph.WebApi/Asaph.WebApi.csproj b/Asaph.WebApi/Asaph.WebApi.csproj index 6cbe5b7..4c05476 100644 --- a/Asaph.WebApi/Asaph.WebApi.csproj +++ b/Asaph.WebApi/Asaph.WebApi.csproj @@ -9,11 +9,12 @@ + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Asaph.WebApi/Dockerfile b/Asaph.WebApi/Dockerfile index 4561835..8b7d866 100644 --- a/Asaph.WebApi/Dockerfile +++ b/Asaph.WebApi/Dockerfile @@ -7,16 +7,16 @@ EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src -COPY ["Asaph.WebApi.Next/Asaph.WebApi.Next.csproj", "Asaph.WebApi.Next/"] -RUN dotnet restore "Asaph.WebApi.Next/Asaph.WebApi.Next.csproj" +COPY ["Asaph.WebApi/Asaph.WebApi.csproj", "Asaph.WebApi/"] +RUN dotnet restore "Asaph.WebApi/Asaph.WebApi.csproj" COPY . . -WORKDIR "/src/Asaph.WebApi.Next" -RUN dotnet build "Asaph.WebApi.Next.csproj" -c Release -o /app/build +WORKDIR "/src/Asaph.WebApi" +RUN dotnet build "Asaph.WebApi.csproj" -c Release -o /app/build FROM build AS publish -RUN dotnet publish "Asaph.WebApi.Next.csproj" -c Release -o /app/publish +RUN dotnet publish "Asaph.WebApi.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "Asaph.WebApi.Next.dll"] \ No newline at end of file +ENTRYPOINT ["dotnet", "Asaph.WebApi.dll"] \ No newline at end of file diff --git a/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationExtensions.cs b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationExtensions.cs new file mode 100644 index 0000000..1cf360b --- /dev/null +++ b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationExtensions.cs @@ -0,0 +1,25 @@ +namespace Asaph.WebApi.GcpSecretManagerConfigurationProvider; + +/// +/// Provides extensions for adding GCP Secret Manager secrets to configuration. +/// +public static class GcpSecretManagerConfigurationExtensions +{ + /// + /// Adds GCP Secret Manager as a configuration source. + /// + /// Configuration builder. + /// Configuration. "Gcp" is the assumed section. + /// The updated configuration builder. + public static IConfigurationBuilder AddGcpSecretManager( + this IConfigurationBuilder builder, IConfiguration configuration) + { + string? projectId = configuration["Gcp:ProjectId"]; + string? secretManagerCredentialsPath = configuration["Gcp:SecretManagerCredentialsPath"]; + + builder.Add(new GcpSecretManagerConfigurationSource( + projectId, secretManagerCredentialsPath)); + + return builder; + } +} diff --git a/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationProvider.cs b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationProvider.cs new file mode 100644 index 0000000..af0ea04 --- /dev/null +++ b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationProvider.cs @@ -0,0 +1,98 @@ +using Google.Api.Gax; +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; + +namespace Asaph.WebApi.GcpSecretManagerConfigurationProvider; + +/// +/// Configuration provider for GCP Secret Manager. +/// +public class GcpSecretManagerConfigurationProvider : ConfigurationProvider +{ + private readonly SecretManagerServiceClient _client; + private readonly string _projectId; + + /// + /// Initializes a new instance of the class. + /// + /// GCP project id. + /// Secret Manager credentials path. + public GcpSecretManagerConfigurationProvider( + string? projectId, string? secretManagerCredentialsPath) + { + if (projectId != null && secretManagerCredentialsPath != null) + { + SecretManagerServiceClientBuilder secretManagerServiceClientBuilder = new(); + secretManagerServiceClientBuilder.CredentialsPath = secretManagerCredentialsPath; + _client = secretManagerServiceClientBuilder.Build(); + } + else + { + _client = SecretManagerServiceClient.Create(); + } + + _projectId = string.IsNullOrWhiteSpace(projectId) ? GetGcpProjectId() : projectId; + } + + /// + public override void Load() + { + IEnumerable? secretNames = _client + .ListSecrets(new ProjectName(_projectId))? + .Select(i => i.SecretName); + + if (secretNames?.Any() == false) + return; + + foreach (SecretName secretName in secretNames!) + { + try + { + SecretVersionName secretVersionName = new( + secretName.ProjectId, secretName.SecretId, "latest"); + + AccessSecretVersionResponse secretVersion = _client + .AccessSecretVersion(secretVersionName); + + Set( + NormalizeDelimiter(secretName.SecretId), + secretVersion.Payload.Data.ToStringUtf8()); + } + catch (Grpc.Core.RpcException) + { + // Ignore. This might happen if the secret has no versions available. + } + } + } + + /// + /// Gets the GCP project id from the execution platform. + /// + /// Project id. + /// + /// Thrown if GCP execution platform information couldn't be retrieved. This is most likely due + /// to the service not running on GCP (e.g. local testing.) + /// + private static string GetGcpProjectId() + { + string? projectId = Platform.Instance()?.ProjectId; + + if (projectId == null) + { + throw new InvalidOperationException( + "Could not retrieve GCP project id for GcpSecretManagerProvider."); + } + + return projectId; + } + + /// + /// Normalizes the "__" (double underscore) key delimeter. + /// + /// Key. + /// The normalized key. + private static string NormalizeDelimiter(string key) + { + return key.Replace("__", ConfigurationPath.KeyDelimiter); + } +} \ No newline at end of file diff --git a/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationSource.cs b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationSource.cs new file mode 100644 index 0000000..ef162c9 --- /dev/null +++ b/Asaph.WebApi/GcpSecretManagerConfigurationProvider/GcpSecretManagerConfigurationSource.cs @@ -0,0 +1,29 @@ +namespace Asaph.WebApi.GcpSecretManagerConfigurationProvider; + +/// +/// GCP Secret Manager configurtion source. +/// +public class GcpSecretManagerConfigurationSource : IConfigurationSource +{ + // Project id + private readonly string? _projectId; + + // Secret Manager credentials path + private readonly string? _secretManagerCredentialsPath; + + /// + /// Initializes a new instance of the class. + /// + /// Project id. + /// Secret Manager credentials path. + public GcpSecretManagerConfigurationSource( + string? projectId, string? secretManagerCredentialsPath) + { + _projectId = projectId; + _secretManagerCredentialsPath = secretManagerCredentialsPath; + } + + /// + public IConfigurationProvider Build(IConfigurationBuilder builder) => + new GcpSecretManagerConfigurationProvider(_projectId, _secretManagerCredentialsPath); +} \ No newline at end of file diff --git a/Asaph.WebApi/Program.cs b/Asaph.WebApi/Program.cs index efe6826..c61ca99 100644 --- a/Asaph.WebApi/Program.cs +++ b/Asaph.WebApi/Program.cs @@ -2,6 +2,7 @@ using Asaph.Core.UseCases; using Asaph.Core.UseCases.AddSongDirector; using Asaph.Core.UseCases.GetSongDirectors; +using Asaph.WebApi.GcpSecretManagerConfigurationProvider; using Microsoft.AspNetCore.Authorization; using Microsoft.Identity.Web; using Microsoft.OpenApi; @@ -10,7 +11,10 @@ WebApplicationBuilder? builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddGcpSecretManager(builder.Configuration); + string baseUri = builder.Configuration["BaseUri"]; + string hydraContextUri = builder.Configuration["HydraContextUri"]; string songDirectorsBaseUri = @$"{baseUri.TrimEnd('/')}/song-directors/"; diff --git a/Asaph.WebApi/appsettings.Development.json b/Asaph.WebApi/appsettings.Development.json index 457a019..8dcdc32 100644 --- a/Asaph.WebApi/appsettings.Development.json +++ b/Asaph.WebApi/appsettings.Development.json @@ -4,8 +4,9 @@ "AuthorizationUrlTemplate": "{0}/{1}/{2}/oauth2/v2.0/authorize", "ClientId": "272f1cc2-c536-4457-92c9-a874e0730cba", "Domain": "asaphworshipdev.onmicrosoft.com", - "ExtensionsAppClientId": "653d67fe-4996-4cd6-8808-b876d7120cf1", + "ExtensionsAppClientId": "653d67fe49964cd68808b876d7120cf1", "Instance": "https://asaphworshipdev.b2clogin.com", + "ResetPasswordPolicyId": "B2C_1_password_reset", "SignUpSignInPolicyId": "B2C_1_sign_in", "TenantId": "2f5b9ffe-c33e-413d-bc8a-41bf11d5df1d", "TokenUrlTemplate": "{0}/{1}/{2}/oauth2/v2.0/token" @@ -15,7 +16,11 @@ "DynamoDB": { "AwsRegionSystemName": "us-east-2", "DynamoDBLocalUrl": "http://localhost:8000", - "UseDynamoDBLocal": true + "UseDynamoDBLocal": false + }, + "Gcp": { + "ProjectId": "asaph-dev", + "SecretManagerCredentialsPath": "C:\\Source\\mjhoffmeister\\Asaph\\.gcp\\asaph-dev.json" }, "HydraContextUri": "http://www.w3.org/ns/hydra/context.jsonld", "Logging": { @@ -25,7 +30,7 @@ } }, "SwaggerUI": { - "ClientId": "31f5643f-e3ec-40f6-bcaf-4868249ca09c", + "ClientId": "ae2ac300-d3bc-462a-8b30-ae78d71137d9", "Scopes": { "Provides API access.": "https://asaphworshipdev.onmicrosoft.com/asaph-worship-api/API.Access" } diff --git a/Asaph.WebApi/appsettings.json b/Asaph.WebApi/appsettings.json index d55e84d..2a30f88 100644 --- a/Asaph.WebApi/appsettings.json +++ b/Asaph.WebApi/appsettings.json @@ -6,6 +6,7 @@ "Domain": "asaphworship.onmicrosoft.com", "ExtensionsAppClientId": "d4a9cc89e8f6434796aa3acf40fe8331", "Instance": "https://asaphworship.b2clogin.com", + "ResetPasswordPolicyId": "B2C_1_password_reset", "SignUpSignInPolicyId": "B2C_1_sign_in", "TenantId": "2a4b3225-e8d4-46b7-af80-a3f5b27044ef", "TokenUrlTemplate": "{0}/{1}/{2}/oauth2/v2.0/token" @@ -15,7 +16,7 @@ "DynamoDB": { "AwsRegionSystemName": "us-east-2", "DynamoDBLocalUrl": "http://localhost:8000", - "UseDynamoDBLocal": true + "UseDynamoDBLocal": false }, "HydraContextUri": "http://www.w3.org/ns/hydra/context.jsonld", "Logging": {