2024-08-17 16:38:40 +02:00
|
|
|
|
using Asp.Versioning;
|
|
|
|
|
|
using FluentValidation;
|
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
|
using Microsoft.Extensions.Options;
|
2025-06-12 19:12:38 +02:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.Reflection;
|
2025-06-12 18:22:37 +02:00
|
|
|
|
using Vegasco.Server.Api.Authentication;
|
|
|
|
|
|
using Vegasco.Server.Api.Common;
|
|
|
|
|
|
using Vegasco.Server.Api.Persistence;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
2025-06-12 18:22:37 +02:00
|
|
|
|
namespace Vegasco.Server.Api.Common;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
|
|
|
|
|
public static class DependencyInjectionExtensions
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-06-12 18:22:37 +02:00
|
|
|
|
/// Adds all the Api related services to the Dependency Injection container.
|
2024-08-17 16:38:40 +02:00
|
|
|
|
/// </summary>
|
2025-06-12 17:43:22 +02:00
|
|
|
|
/// <param name="builder"></param>
|
2025-06-12 18:22:37 +02:00
|
|
|
|
public static void AddApiServices(this IHostApplicationBuilder builder)
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
2025-07-22 20:19:57 +02:00
|
|
|
|
builder.AddBuilderServices();
|
|
|
|
|
|
|
2024-12-28 17:01:18 +01:00
|
|
|
|
builder.Services
|
2024-08-17 16:38:40 +02:00
|
|
|
|
.AddMiscellaneousServices()
|
2025-06-12 17:43:22 +02:00
|
|
|
|
.AddCustomOpenApi()
|
2024-08-17 16:38:40 +02:00
|
|
|
|
.AddApiVersioning()
|
2024-12-28 17:01:18 +01:00
|
|
|
|
.AddAuthenticationAndAuthorization(builder.Environment);
|
|
|
|
|
|
|
|
|
|
|
|
builder.AddDbContext();
|
2024-08-17 16:38:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-22 20:19:57 +02:00
|
|
|
|
private static IHostApplicationBuilder AddBuilderServices(this IHostApplicationBuilder builder)
|
|
|
|
|
|
{
|
2025-07-22 21:13:18 +02:00
|
|
|
|
string? seqHost = builder.Configuration.GetConnectionString("seq");
|
|
|
|
|
|
if (!string.IsNullOrEmpty(seqHost))
|
|
|
|
|
|
{
|
2025-09-21 10:50:08 +02:00
|
|
|
|
builder.AddSeqEndpoint("seq", o =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var apiKey = builder.Configuration.GetValue<string>("seq-api-key");
|
|
|
|
|
|
if (!string.IsNullOrEmpty(apiKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
o.ApiKey = apiKey;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-07-22 21:13:18 +02:00
|
|
|
|
}
|
2025-07-22 20:19:57 +02:00
|
|
|
|
|
|
|
|
|
|
return builder;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
private static IServiceCollection AddMiscellaneousServices(this IServiceCollection services)
|
|
|
|
|
|
{
|
2025-06-13 19:39:37 +02:00
|
|
|
|
services.AddSingleton(() =>
|
2025-06-12 19:18:17 +02:00
|
|
|
|
{
|
2025-06-13 19:39:37 +02:00
|
|
|
|
string assemblyName = Assembly.GetExecutingAssembly()
|
|
|
|
|
|
.GetName()
|
|
|
|
|
|
.Name ?? "Vegasco.Server.Api";
|
2025-06-12 19:18:17 +02:00
|
|
|
|
return new ActivitySource(assemblyName);
|
|
|
|
|
|
});
|
2025-06-12 19:12:38 +02:00
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
services.AddResponseCompression();
|
|
|
|
|
|
|
|
|
|
|
|
services.AddValidatorsFromAssemblies(
|
|
|
|
|
|
[
|
2025-06-12 18:22:37 +02:00
|
|
|
|
typeof(IApiMarker).Assembly
|
2024-08-17 16:38:40 +02:00
|
|
|
|
], ServiceLifetime.Singleton);
|
|
|
|
|
|
|
|
|
|
|
|
services.AddHealthChecks();
|
|
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
services.AddHttpContextAccessor();
|
|
|
|
|
|
|
2024-08-24 13:43:43 +02:00
|
|
|
|
services.AddHostedService<ApplyMigrationsService>();
|
2025-06-15 09:36:52 +02:00
|
|
|
|
|
2025-06-13 19:39:37 +02:00
|
|
|
|
services.AddRequestLocalization(o =>
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] cultures =
|
|
|
|
|
|
[
|
|
|
|
|
|
"en-US",
|
|
|
|
|
|
"en",
|
|
|
|
|
|
"de-DE",
|
|
|
|
|
|
"de"
|
|
|
|
|
|
];
|
2025-06-15 09:36:52 +02:00
|
|
|
|
|
2025-06-13 19:39:37 +02:00
|
|
|
|
o.SetDefaultCulture(cultures[0])
|
|
|
|
|
|
.AddSupportedCultures(cultures)
|
|
|
|
|
|
.AddSupportedUICultures(cultures);
|
|
|
|
|
|
});
|
2024-08-24 13:43:43 +02:00
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
return services;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 17:43:22 +02:00
|
|
|
|
private static IServiceCollection AddCustomOpenApi(this IServiceCollection services)
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
|
|
|
|
|
services.AddEndpointsApiExplorer();
|
2025-06-12 17:43:22 +02:00
|
|
|
|
services.AddOpenApi(o =>
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
2025-06-12 17:43:22 +02:00
|
|
|
|
o.CreateSchemaReferenceId = jsonTypeInfo =>
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
2025-06-12 17:43:22 +02:00
|
|
|
|
if (string.IsNullOrEmpty(jsonTypeInfo.Type.FullName))
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
2025-06-12 17:43:22 +02:00
|
|
|
|
return jsonTypeInfo.Type.Name;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-12 17:43:22 +02:00
|
|
|
|
string? fullClassName = jsonTypeInfo.Type.FullName;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
2025-06-12 17:43:22 +02:00
|
|
|
|
if (!string.IsNullOrEmpty(jsonTypeInfo.Type.Namespace))
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
|
|
|
|
|
fullClassName = fullClassName
|
2025-06-12 17:43:22 +02:00
|
|
|
|
.Replace(jsonTypeInfo.Type.Namespace, "")
|
2024-08-17 16:38:40 +02:00
|
|
|
|
.TrimStart('.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-25 13:14:32 +02:00
|
|
|
|
fullClassName = fullClassName.Replace('+', '_');
|
2024-08-17 16:38:40 +02:00
|
|
|
|
return fullClassName;
|
2025-06-12 17:43:22 +02:00
|
|
|
|
};
|
2024-08-17 16:38:40 +02:00
|
|
|
|
});
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static IServiceCollection AddApiVersioning(this IServiceCollection services)
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddApiVersioning(o =>
|
|
|
|
|
|
{
|
|
|
|
|
|
o.DefaultApiVersion = new ApiVersion(1);
|
|
|
|
|
|
o.ApiVersionReader = new UrlSegmentApiVersionReader();
|
|
|
|
|
|
o.ReportApiVersions = true;
|
|
|
|
|
|
})
|
|
|
|
|
|
.AddApiExplorer(o =>
|
|
|
|
|
|
{
|
|
|
|
|
|
o.GroupNameFormat = "'v'V";
|
|
|
|
|
|
o.SubstituteApiVersionInUrl = true;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-17 16:38:41 +02:00
|
|
|
|
private static IServiceCollection AddAuthenticationAndAuthorization(this IServiceCollection services, IHostEnvironment environment)
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
|
|
|
|
|
services.AddOptions<JwtOptions>()
|
|
|
|
|
|
.BindConfiguration(JwtOptions.SectionName)
|
|
|
|
|
|
.ValidateFluently()
|
|
|
|
|
|
.ValidateOnStart();
|
|
|
|
|
|
|
2025-06-24 19:28:55 +02:00
|
|
|
|
IOptions<JwtOptions> jwtOptions = services.BuildServiceProvider().GetRequiredService<IOptions<JwtOptions>>();
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
|
|
|
|
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
|
|
|
|
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
|
|
|
|
|
|
{
|
2024-08-17 16:38:40 +02:00
|
|
|
|
o.MetadataAddress = jwtOptions.Value.MetadataUrl;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
o.TokenValidationParameters.ValidAudience = jwtOptions.Value.ValidAudience;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
o.TokenValidationParameters.ValidateAudience = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(jwtOptions.Value.NameClaimType))
|
|
|
|
|
|
{
|
|
|
|
|
|
o.TokenValidationParameters.NameClaimType = jwtOptions.Value.NameClaimType;
|
|
|
|
|
|
}
|
2024-08-17 16:38:41 +02:00
|
|
|
|
|
|
|
|
|
|
o.RequireHttpsMetadata = !jwtOptions.Value.AllowHttpMetadataUrl && !environment.IsDevelopment();
|
2024-08-17 16:38:40 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
services.AddAuthorizationBuilder()
|
|
|
|
|
|
.AddPolicy(Constants.Authorization.RequireAuthenticatedUserPolicy, p => p
|
|
|
|
|
|
.RequireAuthenticatedUser()
|
|
|
|
|
|
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme));
|
|
|
|
|
|
|
2024-08-17 16:38:40 +02:00
|
|
|
|
services.AddScoped<UserAccessor>();
|
|
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-28 17:01:18 +01:00
|
|
|
|
private static IHostApplicationBuilder AddDbContext(this IHostApplicationBuilder builder)
|
2024-08-17 16:38:40 +02:00
|
|
|
|
{
|
2025-06-12 18:22:37 +02:00
|
|
|
|
builder.AddNpgsqlDbContext<ApplicationDbContext>(AppHost.Shared.Constants.Database.Name);
|
2024-12-28 17:01:18 +01:00
|
|
|
|
return builder;
|
2024-08-17 16:38:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|