| | | 1 | | using ArturRios.Configuration.Loaders; |
| | | 2 | | using ArturRios.Configuration.Providers; |
| | | 3 | | using Microsoft.AspNetCore.Authentication.JwtBearer; |
| | | 4 | | using Microsoft.AspNetCore.Builder; |
| | | 5 | | using Microsoft.Extensions.Configuration; |
| | | 6 | | using Microsoft.Extensions.DependencyInjection; |
| | | 7 | | using Microsoft.Extensions.DependencyInjection.Extensions; |
| | | 8 | | using Microsoft.Extensions.Logging; |
| | | 9 | | using Microsoft.OpenApi; |
| | | 10 | | using Swashbuckle.AspNetCore.SwaggerGen; |
| | | 11 | | |
| | | 12 | | namespace ArturRios.Util.WebApi.Configuration; |
| | | 13 | | |
| | | 14 | | /// <summary>Builder-side steps of the standard web API setup. <see cref="WebApiStartup"/> runs them in order, and each |
| | | 15 | | /// one can be used on its own with a plain <see cref="WebApplicationBuilder"/>.</summary> |
| | | 16 | | public static class WebApplicationBuilderExtensions |
| | | 17 | | { |
| | | 18 | | /// <param name="builder">The application builder.</param> |
| | | 19 | | extension(WebApplicationBuilder builder) |
| | | 20 | | { |
| | | 21 | | /// <summary>Loads <c>appsettings</c> and/or the environment file according to <paramref name="parameters"/>, an |
| | | 22 | | /// registers <paramref name="parameters"/>, the <see cref="ConfigurationLoader"/>, <see cref="SettingsProvider" |
| | | 23 | | /// (always, since <c>AuthenticationMiddleware</c> depends on it) and <see cref="EnvironmentProvider"/> (when th |
| | | 24 | | /// environment file is loaded) as services.</summary> |
| | | 25 | | /// <param name="parameters">The startup parameters deciding which sources are loaded.</param> |
| | | 26 | | /// <returns>The same <paramref name="builder"/> instance, for chaining.</returns> |
| | | 27 | | public WebApplicationBuilder LoadConfiguration(WebApiParameters parameters) |
| | | 28 | | { |
| | 20 | 29 | | ArgumentNullException.ThrowIfNull(parameters); |
| | | 30 | | |
| | 20 | 31 | | var environmentName = builder.Environment.EnvironmentName; |
| | | 32 | | |
| | 20 | 33 | | builder.Services.TryAddSingleton(parameters); |
| | 20 | 34 | | builder.Services.TryAddSingleton(sp => new ConfigurationLoader(builder.Configuration, environmentName, null, |
| | 20 | 35 | | sp.GetRequiredService<ILogger<ConfigurationLoader>>())); |
| | 20 | 36 | | builder.Services.TryAddSingleton<SettingsProvider>(); |
| | | 37 | | |
| | 40 | 38 | | using var loggerFactory = LoggerFactory.Create(logging => logging.AddConsole()); |
| | | 39 | | |
| | 20 | 40 | | var configurationLoader = new ConfigurationLoader(builder.Configuration, environmentName, null, |
| | 20 | 41 | | loggerFactory.CreateLogger<ConfigurationLoader>()); |
| | | 42 | | |
| | 20 | 43 | | if (parameters.UseAppSettings) |
| | | 44 | | { |
| | 0 | 45 | | configurationLoader.LoadAppSettings(); |
| | | 46 | | } |
| | | 47 | | |
| | 20 | 48 | | if (parameters.UseEnvFile) |
| | | 49 | | { |
| | 0 | 50 | | configurationLoader.LoadEnvironment(); |
| | | 51 | | |
| | 0 | 52 | | builder.Services.TryAddSingleton<EnvironmentProvider>(); |
| | | 53 | | } |
| | | 54 | | |
| | 20 | 55 | | return builder; |
| | | 56 | | } |
| | | 57 | | |
| | | 58 | | /// <summary>Registers the Swagger generator when Swagger is allowed in the current environment (see |
| | | 59 | | /// <see cref="WebApiParameters.IsSwaggerAllowed"/>), and marks it enabled under |
| | | 60 | | /// <see cref="AppSettingsKeys.SwaggerEnabled"/> so <c>AuthenticationMiddleware</c> lets <c>/swagger</c> through |
| | | 61 | | /// Pair it with <see cref="ApplicationBuilderExtensions.UseWebApiSwagger"/>, which serves whatever was register |
| | | 62 | | /// <param name="parameters">The startup parameters gating Swagger by environment.</param> |
| | | 63 | | /// <param name="configure">Optional callback to configure the allowed environments, JWT security and generator. |
| | | 64 | | /// <returns>The same <paramref name="builder"/> instance, for chaining.</returns> |
| | | 65 | | public WebApplicationBuilder AddWebApiSwagger(WebApiParameters parameters, Action<WebApiSwaggerOptions>? configu |
| | | 66 | | { |
| | 0 | 67 | | var options = new WebApiSwaggerOptions(); |
| | 0 | 68 | | configure?.Invoke(options); |
| | | 69 | | |
| | 0 | 70 | | return builder.AddWebApiSwaggerWith(parameters, options); |
| | | 71 | | } |
| | | 72 | | |
| | | 73 | | internal WebApplicationBuilder AddWebApiSwaggerWith(WebApiParameters parameters, WebApiSwaggerOptions options) |
| | | 74 | | { |
| | 20 | 75 | | ArgumentNullException.ThrowIfNull(parameters); |
| | | 76 | | |
| | 20 | 77 | | if (!parameters.IsSwaggerAllowed(builder.Environment.EnvironmentName, options.AllowedEnvironments)) |
| | | 78 | | { |
| | 16 | 79 | | return builder; |
| | | 80 | | } |
| | | 81 | | |
| | 4 | 82 | | builder.Configuration.AddInMemoryCollection( |
| | 4 | 83 | | new Dictionary<string, string?> { [AppSettingsKeys.SwaggerEnabled] = "true" }); |
| | | 84 | | |
| | 4 | 85 | | builder.Services.AddSwaggerGen(generator => |
| | 4 | 86 | | { |
| | 3 | 87 | | options.ConfigureGenerator?.Invoke(generator); |
| | 4 | 88 | | |
| | 3 | 89 | | if (options.JwtAuthentication) |
| | 4 | 90 | | { |
| | 0 | 91 | | AddJwtSecurity(generator); |
| | 4 | 92 | | } |
| | 7 | 93 | | }); |
| | | 94 | | |
| | 4 | 95 | | return builder; |
| | | 96 | | } |
| | | 97 | | } |
| | | 98 | | |
| | | 99 | | private static void AddJwtSecurity(SwaggerGenOptions options) |
| | | 100 | | { |
| | 0 | 101 | | var jwtSecurityScheme = new OpenApiSecurityScheme |
| | 0 | 102 | | { |
| | 0 | 103 | | BearerFormat = "JWT", |
| | 0 | 104 | | Name = "JWT Authentication", |
| | 0 | 105 | | In = ParameterLocation.Header, |
| | 0 | 106 | | Type = SecuritySchemeType.Http, |
| | 0 | 107 | | Scheme = JwtBearerDefaults.AuthenticationScheme, |
| | 0 | 108 | | Description = |
| | 0 | 109 | | "After getting a token from the Authentication route, put **_ONLY_** your JWT Bearer token on textbox be |
| | 0 | 110 | | }; |
| | | 111 | | |
| | 0 | 112 | | var jwtRequirement = new OpenApiSecurityRequirement |
| | 0 | 113 | | { |
| | 0 | 114 | | { new OpenApiSecuritySchemeReference(JwtBearerDefaults.AuthenticationScheme), [] } |
| | 0 | 115 | | }; |
| | | 116 | | |
| | 0 | 117 | | options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, jwtSecurityScheme); |
| | 0 | 118 | | options.AddSecurityRequirement(_ => jwtRequirement); |
| | 0 | 119 | | } |
| | | 120 | | } |