Skip to content

Commit

Permalink
chore(summary): Add key vault and fusion sql token support (#666)
Browse files Browse the repository at this point in the history
- [x] New feature
- [ ] Bug fix
- [ ] High impact

**Description of work:**
<!--- Please give a description of the work --->


[AB#55619](https://statoil-proview.visualstudio.com/787035c2-8cf2-4d73-a83e-bb0e6d937eec/_workitems/edit/55619)

This adds the keyvault support and azure sql token support. I've tested
connecting to the Summary CI database which works.


**Testing:**
- [ ] Can be tested
- [ ] Automatic tests created / updated
- [x] Local tests are passing

<!--- Please give a description of how this can be tested --->


**Checklist:**
- [ ] Considered automated tests
- [ ] Considered updating specification / documentation
- [x] Considered work items 
- [x] Considered security
- [x] Performed developer testing
- [x] Checklist finalized / ready for review

<!--- Other comments --->
  • Loading branch information
Jonathanio123 authored Aug 22, 2024
1 parent 1008b27 commit 9bc94fd
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
30 changes: 30 additions & 0 deletions src/Fusion.Summary.Api/ConfigurationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Azure.Identity;

namespace Fusion.Summary.Api;

public static class ConfigurationExtensions
{
public static void AddKeyVault(this WebApplicationBuilder builder)
{
var configuration = builder.Configuration;
var clientId = configuration["AzureAd:ClientId"];
var tenantId = configuration["AzureAd:TenantId"];
var clientSecret = configuration["AzureAd:ClientSecret"];
var keyVaultUrl = configuration["KEYVAULT_URL"];

if (string.IsNullOrWhiteSpace(keyVaultUrl))
{
Console.WriteLine("Skipping key vault as url is null, empty or whitespace.");
return;
}

if (string.IsNullOrWhiteSpace(clientSecret))
{
Console.WriteLine("Skipping key vault as clientSecret is null, empty or whitespace.");
return;
}

var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
configuration.AddAzureKeyVault(new Uri(keyVaultUrl), credential);
}
}
19 changes: 19 additions & 0 deletions src/Fusion.Summary.Api/Database/SqlTokenProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Fusion.Infrastructure.Database;
using Fusion.Integration.Configuration;

namespace Fusion.Summary.Api.Database;

public class SqlTokenProvider : ISqlTokenProvider
{
private readonly IFusionTokenProvider fusionTokenProvider;

public SqlTokenProvider(IFusionTokenProvider fusionTokenProvider)
{
this.fusionTokenProvider = fusionTokenProvider;
}

public Task<string> GetAccessTokenAsync()
{
return fusionTokenProvider.GetApplicationTokenAsync("https://database.windows.net/");
}
}
1 change: 1 addition & 0 deletions src/Fusion.Summary.Api/Fusion.Summary.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<PackageReference Include="Fusion.AspNetCore" Version="8.0.4"/>
<PackageReference Include="Fusion.AspNetCore.FluentAuthorization" Version="8.0.0" />
<PackageReference Include="Fusion.AspNetCore.Versioning" Version="8.1.0"/>
<PackageReference Include="Fusion.Infrastructure.Database" Version="8.0.5"/>
<PackageReference Include="Fusion.Integration" Version="8.0.0" />
<PackageReference Include="Fusion.Integration.Authorization" Version="8.0.0" />
<PackageReference Include="MediatR" Version="12.3.0" />
Expand Down
26 changes: 18 additions & 8 deletions src/Fusion.Summary.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using FluentValidation.AspNetCore;
using Fusion.AspNetCore.Versioning;
using Fusion.Resources.Api.Middleware;
using Fusion.Summary.Api;
using Fusion.Summary.Api.Database;
using Fusion.Summary.Api.Middleware;
using Microsoft.AspNetCore.Authentication.JwtBearer;
Expand All @@ -13,24 +14,30 @@

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
.AddJsonFile("/app/secrets/appsettings.secrets.yaml", optional: true)
.AddJsonFile("/app/static/config/env.json", optional: true, reloadOnChange: true);
if (Environment.GetEnvironmentVariable("INTEGRATION_TEST_RUN") != "true")
{
builder.Configuration
.AddJsonFile("/app/secrets/appsettings.secrets.yaml", optional: true)
.AddJsonFile("/app/config/appsettings.json", optional: true); // to be able to override settings by using a config map in kubernetes

builder.AddKeyVault();
}

var azureAdClientId = builder.Configuration["AzureAd:ClientId"];
var azureAdClientSecret = builder.Configuration["AzureAd:ClientSecret"];
var certThumbprint = builder.Configuration["Config:CertThumbprint"];
var environment = builder.Configuration["Environment"];
var fusionEnvironment = builder.Configuration["FUSION_ENVIRONMENT"];
var databaseConnectionString = builder.Configuration.GetConnectionString(nameof(SummaryDbContext));
var databaseConnectionString = builder.Configuration.GetConnectionString(nameof(SummaryDbContext))!;

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHealthChecks()
.AddCheck("liveness", () => HealthCheckResult.Healthy())
.AddCheck("db", () => HealthCheckResult.Healthy(), tags: ["ready"]);
// TODO: Add a real health check, when database is added
// TODO: Add a real health check, when database is added in deployment pipelines and PR pipelines
// .AddDbContextCheck<DatabaseContext>("db", tags: new[] { "ready" });


builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
Expand All @@ -54,17 +61,20 @@
builder.Services.AddFusionIntegration(f =>
{
f.AddFusionAuthorization();
f.UseServiceInformation("Fusion.Summary.Api", "Dev");
f.UseServiceInformation("Fusion.Summary.Api", environment);
f.UseDefaultEndpointResolver(fusionEnvironment ?? "ci");
f.UseDefaultTokenProvider(opts =>
{
opts.ClientId = azureAdClientId ?? throw new InvalidOperationException("Missing AzureAd:ClientId");
opts.ClientSecret = azureAdClientSecret;
opts.CertificateThumbprint = certThumbprint;
});
});

builder.Services.AddApplicationInsightsTelemetry();
builder.Services.AddDbContext<SummaryDbContext>(options => options.UseSqlServer(databaseConnectionString));
builder.Services.AddSqlDbContext<SummaryDbContext>(databaseConnectionString, enablePullRequestEnv: false)
.AddSqlTokenProvider<SqlTokenProvider>()
.AddAccessTokenSupport();
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
builder.Services.AddFluentValidationAutoValidation().AddValidatorsFromAssembly(typeof(Program).Assembly);

Expand Down

0 comments on commit 9bc94fd

Please sign in to comment.