From eb8cde421b565331008d8719e335ee5b4b00d391 Mon Sep 17 00:00:00 2001 From: eduardo Date: Tue, 24 Oct 2023 10:23:16 -0300 Subject: [PATCH] feat: Add CORS configuration --- .../workflows/azure-functions-app-dotnet.yml | 55 ++++++++++++++ .../azure-functions-app-dotnet.yml.stop | 52 -------------- .../workflows/azure-webapps-dotnet-core.yml | 2 + src/Infrastructure/IoC/InfrastructureDI.cs | 28 +------- src/Infrastructure/IoC/Utils/DotEnvSecrets.cs | 72 ++++--------------- src/Infrastructure/WebAPI/Startup.cs | 33 ++++++++- src/Infrastructure/WebAPI/appsettings.json | 1 - src/Infrastructure/WebFunctions/Program.cs | 4 +- 8 files changed, 105 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/azure-functions-app-dotnet.yml delete mode 100644 .github/workflows/azure-functions-app-dotnet.yml.stop diff --git a/.github/workflows/azure-functions-app-dotnet.yml b/.github/workflows/azure-functions-app-dotnet.yml new file mode 100644 index 00000000..051ad179 --- /dev/null +++ b/.github/workflows/azure-functions-app-dotnet.yml @@ -0,0 +1,55 @@ +name: Deploy WebFunctions to Azure + +on: + push: + branches: ["main"] + +env: + AZURE_FUNCTIONAPP_NAME: "GPIC-Stg-WebFunctions" # set this to your function app name on Azure + AZURE_FUNCTIONAPP_PACKAGE_PATH: "src" # set this to the path to your function app project, defaults to the repository root + DOTNET_VERSION: "7.0" # set this to the dotnet version to use (e.g. '2.1.x', '3.1.x', '5.0.x') + +jobs: + build-and-deploy: + runs-on: ubuntu-latest # For Linux, use ubuntu-latest + environment: dev + steps: + - name: "Checkout GitHub Action" + uses: actions/checkout@v3 + + - name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment + uses: actions/setup-dotnet@v3 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: "Resolve Project Dependencies Using Dotnet" + shell: bash # For Linux, use bash + run: | + pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' + dotnet build --configuration Release --output ./output + popd + + - name: Create env + run: | + echo "AZURE_BLOB_STORAGE_CONNECTION_STRING=${{ secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING }} + AZURE_BLOB_STORAGE_CONTAINER_NAME=${{ secrets.AZURE_BLOB_STORAGE_CONTAINER_NAME }} + POSTGRES_CONNECTION_STRING=${{ secrets.POSTGRES_CONNECTION_STRING }} + FRONTEND_URL=${{ secrets.FRONTEND_URL }} + ALLOW_ORIGINS=${{ secrets.ALLOW_ORIGINS }} + JWT_AUDIENCE=${{ secrets.JWT_AUDIENCE }} + JWT_EXPIRE_IN=${{ secrets.JWT_EXPIRE_IN }} + JWT_ISSUER=${{ secrets.JWT_ISSUER }} + JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }} + SEQ_API_KEY=${{ secrets.SEQ_API_KEY }} + SEQ_URL=${{ secrets.SEQ_URL }} + SMTP_EMAIL_PASSWORD=${{ secrets.SMTP_EMAIL_PASSWORD }} + SMTP_EMAIL_USERNAME=${{ secrets.SMTP_EMAIL_USERNAME }} + EXECUTE_MIGRATION=${{ secrets.EXECUTE_MIGRATION }}" > src/Infrastructure/WebAPI/.env + + - name: "Run Azure Functions Action" + uses: Azure/functions-action@v1 + id: fa + with: + app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} + package: "${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output" + publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }} # Remove publish-profile to use Azure RBAC diff --git a/.github/workflows/azure-functions-app-dotnet.yml.stop b/.github/workflows/azure-functions-app-dotnet.yml.stop deleted file mode 100644 index 5a4fb3f3..00000000 --- a/.github/workflows/azure-functions-app-dotnet.yml.stop +++ /dev/null @@ -1,52 +0,0 @@ -# name: Deploy WebFunctions to Azure - -# on: -# push: -# branches: ["development"] - -# env: -# AZURE_FUNCTIONAPP_NAME: 'GPIC-Staging-WebFunctions' # set this to your function app name on Azure -# AZURE_FUNCTIONAPP_PACKAGE_PATH: 'src' # set this to the path to your function app project, defaults to the repository root -# DOTNET_VERSION: '7.0' # set this to the dotnet version to use (e.g. '2.1.x', '3.1.x', '5.0.x') - -# jobs: -# build-and-deploy: -# runs-on: ubuntu-latest # For Linux, use ubuntu-latest -# environment: dev -# steps: -# - name: 'Checkout GitHub Action' -# uses: actions/checkout@v3 - -# - name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment -# uses: actions/setup-dotnet@v3 -# with: -# dotnet-version: ${{ env.DOTNET_VERSION }} - -# - name: 'Resolve Project Dependencies Using Dotnet' -# shell: bash # For Linux, use bash -# run: | -# pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' -# dotnet build --configuration Release --output ./output -# popd - -# - name: Create env -# run: | -# echo "AZURE_BLOB_STORAGE_CONNECTION_STRING=${{ secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING }} -# AZURE_BLOB_STORAGE_CONTAINER_NAME=${{ secrets.AZURE_BLOB_STORAGE_CONTAINER_NAME }} -# POSTGRES_CONNECTION_STRING=${{ secrets.POSTGRES_CONNECTION_STRING }} -# JWT_AUDIENCE=${{ secrets.JWT_AUDIENCE }} -# JWT_EXPIRE_IN=${{ secrets.JWT_EXPIRE_IN }} -# JWT_ISSUER=${{ secrets.JWT_ISSUER }} -# JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }} -# SEQ_API_KEY=${{ secrets.SEQ_API_KEY }} -# SEQ_URL=${{ secrets.SEQ_URL }} -# SMTP_EMAIL_PASSWORD=${{ secrets.SMTP_EMAIL_PASSWORD }} -# SMTP_EMAIL_USERNAME=${{ secrets.SMTP_EMAIL_USERNAME }}" > src/Infrastructure/WebFunctions/.env - -# - name: 'Run Azure Functions Action' -# uses: Azure/functions-action@v1 -# id: fa -# with: -# app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} -# package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output' -# publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }} # Remove publish-profile to use Azure RBAC diff --git a/.github/workflows/azure-webapps-dotnet-core.yml b/.github/workflows/azure-webapps-dotnet-core.yml index d9b87f79..41e246c6 100644 --- a/.github/workflows/azure-webapps-dotnet-core.yml +++ b/.github/workflows/azure-webapps-dotnet-core.yml @@ -42,6 +42,8 @@ jobs: echo "AZURE_BLOB_STORAGE_CONNECTION_STRING=${{ secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING }} AZURE_BLOB_STORAGE_CONTAINER_NAME=${{ secrets.AZURE_BLOB_STORAGE_CONTAINER_NAME }} POSTGRES_CONNECTION_STRING=${{ secrets.POSTGRES_CONNECTION_STRING }} + FRONTEND_URL=${{ secrets.FRONTEND_URL }} + ALLOW_ORIGINS=${{ secrets.ALLOW_ORIGINS }} JWT_AUDIENCE=${{ secrets.JWT_AUDIENCE }} JWT_EXPIRE_IN=${{ secrets.JWT_EXPIRE_IN }} JWT_ISSUER=${{ secrets.JWT_ISSUER }} diff --git a/src/Infrastructure/IoC/InfrastructureDI.cs b/src/Infrastructure/IoC/InfrastructureDI.cs index b4e19211..c7de4e2f 100644 --- a/src/Infrastructure/IoC/InfrastructureDI.cs +++ b/src/Infrastructure/IoC/InfrastructureDI.cs @@ -11,11 +11,11 @@ namespace Infrastructure.IoC { public static class InfrastructureDI { - public static IServiceCollection AddInfrastructure(this IServiceCollection services, HostBuilderContext? hostContext = null) + public static IServiceCollection AddInfrastructure(this IServiceCollection services, ref IConfiguration? configuration, HostBuilderContext? hostContext = null) { #region AppSettings e DotEnv // Define valores das propriedades de configuração - IConfiguration configuration = SettingsConfiguration.GetConfiguration(hostContext); + configuration = SettingsConfiguration.GetConfiguration(hostContext); services.AddSingleton(configuration); // Carrega informações de ambiente (.env) @@ -35,30 +35,6 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi }); #endregion Serviço de Log - #region CORS - // TODO: Definir política de CORS - services.AddCors(options => - { - options.AddDefaultPolicy( - policy => - { - policy.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader(); - }); - }); - #endregion CORS - - #region Rate Limit - services.AddMemoryCache(); - services.AddInMemoryRateLimiting(); - services.Configure(configuration.GetSection("IpRateLimiting")); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - #endregion Rate Limit - return services; } } diff --git a/src/Infrastructure/IoC/Utils/DotEnvSecrets.cs b/src/Infrastructure/IoC/Utils/DotEnvSecrets.cs index 7d536db0..38aaab23 100644 --- a/src/Infrastructure/IoC/Utils/DotEnvSecrets.cs +++ b/src/Infrastructure/IoC/Utils/DotEnvSecrets.cs @@ -13,66 +13,18 @@ public DotEnvSecrets() _ = DotNetEnv.Env.Load(Path.Combine(basePath!, ".env")); } - public string GetFrontEndUrl() - { - return DotNetEnv.Env.GetString("FRONTEND_URL"); - } - - public string GetSeqUrl() - { - return DotNetEnv.Env.GetString("SEQ_URL"); - } - - public string GetSeqApiKey() - { - return DotNetEnv.Env.GetString("SEQ_API_KEY"); - } - - public string GetBlobStorageConnectionString() - { - return DotNetEnv.Env.GetString("AZURE_BLOB_STORAGE_CONNECTION_STRING"); - } - - public string GetBlobStorageContainerName() - { - return DotNetEnv.Env.GetString("AZURE_BLOB_STORAGE_CONTAINER_NAME"); - } - - public string GetDatabaseConnectionString() - { - return DotNetEnv.Env.GetString("POSTGRES_CONNECTION_STRING"); - } - - public string GetSmtpUserName() - { - return DotNetEnv.Env.GetString("SMTP_EMAIL_USERNAME"); - } - - public string GetSmtpUserPassword() - { - return DotNetEnv.Env.GetString("SMTP_EMAIL_PASSWORD"); - } - - public string GetJwtSecret() - { - return DotNetEnv.Env.GetString("JWT_SECRET_KEY"); - } - - public string GetJwtIssuer() - { - return DotNetEnv.Env.GetString("JWT_ISSUER"); - } - - public string GetJwtAudience() - { - return DotNetEnv.Env.GetString("JWT_AUDIENCE"); - } - - public string GetJwtExpirationTime() - { - return DotNetEnv.Env.GetString("JWT_EXPIRE_IN"); - } - + public string GetFrontEndUrl() => DotNetEnv.Env.GetString("FRONTEND_URL"); + public string GetSeqUrl() => DotNetEnv.Env.GetString("SEQ_URL"); + public string GetSeqApiKey() => DotNetEnv.Env.GetString("SEQ_API_KEY"); + public string GetBlobStorageConnectionString() => DotNetEnv.Env.GetString("AZURE_BLOB_STORAGE_CONNECTION_STRING"); + public string GetBlobStorageContainerName() => DotNetEnv.Env.GetString("AZURE_BLOB_STORAGE_CONTAINER_NAME"); + public string GetDatabaseConnectionString() => DotNetEnv.Env.GetString("POSTGRES_CONNECTION_STRING"); + public string GetSmtpUserName() => DotNetEnv.Env.GetString("SMTP_EMAIL_USERNAME"); + public string GetSmtpUserPassword() => DotNetEnv.Env.GetString("SMTP_EMAIL_PASSWORD"); + public string GetJwtSecret() => DotNetEnv.Env.GetString("JWT_SECRET_KEY"); + public string GetJwtIssuer() => DotNetEnv.Env.GetString("JWT_ISSUER"); + public string GetJwtAudience() => DotNetEnv.Env.GetString("JWT_AUDIENCE"); + public string GetJwtExpirationTime() => DotNetEnv.Env.GetString("JWT_EXPIRE_IN"); public bool ExecuteMigration() { try diff --git a/src/Infrastructure/WebAPI/Startup.cs b/src/Infrastructure/WebAPI/Startup.cs index 8900a94e..c4b39f1b 100644 --- a/src/Infrastructure/WebAPI/Startup.cs +++ b/src/Infrastructure/WebAPI/Startup.cs @@ -9,6 +9,9 @@ namespace WebAPI /// public class Startup { + private const string CORS_POLICY_NAME = "_allowSpecificOrigins"; + private IConfiguration? _configuration; + /// /// Realiza a configuração dos serviços de injeção de dependência. /// @@ -19,7 +22,7 @@ public void ConfigureServices(IServiceCollection services) services.AddControllers(); // Realiza comunicação com os demais Projetos. - services.AddInfrastructure(); + services.AddInfrastructure(ref _configuration); services.AddPersistence(); services.AddExternalServices(); services.AddApplication(); @@ -32,6 +35,32 @@ public void ConfigureServices(IServiceCollection services) // Permite que rotas sejam acessíveis em lowercase services.AddRouting(options => options.LowercaseUrls = true); + + #region CORS + // Definição de política de CORS + services.AddCors(options => + { + options.AddPolicy(name: CORS_POLICY_NAME, + policy => + { + // Busca os valores de ALLOW_ORIGINS do arquivo .env + policy.WithOrigins( + origins: Environment.GetEnvironmentVariable("ALLOW_ORIGINS").Split(',')!) + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); + #endregion CORS + + #region Rate Limit + services.AddMemoryCache(); + services.AddInMemoryRateLimiting(); + services.Configure(_configuration.GetSection("IpRateLimiting")); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + #endregion Rate Limit } /// @@ -66,7 +95,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseHttpsRedirection(); // Enable CORS - app.UseCors(); + app.UseCors(CORS_POLICY_NAME); // Enable routing for incoming requests app.UseRouting(); diff --git a/src/Infrastructure/WebAPI/appsettings.json b/src/Infrastructure/WebAPI/appsettings.json index d38d6351..68b88538 100644 --- a/src/Infrastructure/WebAPI/appsettings.json +++ b/src/Infrastructure/WebAPI/appsettings.json @@ -1,5 +1,4 @@ { - "SiteUrl": "https://localhost:5001", "Serilog": { "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"], "MinimumLevel": { diff --git a/src/Infrastructure/WebFunctions/Program.cs b/src/Infrastructure/WebFunctions/Program.cs index b4b6026d..cd8517ec 100644 --- a/src/Infrastructure/WebFunctions/Program.cs +++ b/src/Infrastructure/WebFunctions/Program.cs @@ -1,11 +1,13 @@ using Microsoft.Extensions.Hosting; using Infrastructure.IoC; +using Microsoft.Extensions.Configuration; var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices((hostContext, services) => { - services.AddInfrastructure(hostContext); + IConfiguration? configuration = null; + services.AddInfrastructure(ref configuration, hostContext); services.AddPersistence(); services.AddExternalServices(); services.AddApplication();