// *********************************************************************** // // AgileWebs // // *********************************************************************** using Asp.Versioning.ApiExplorer; using Core.Cerberos.Adapters.Common.Constants; using Core.Cerberos.Adapters.Extensions; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; namespace Core.Cerberos.Adapters.Extensions { /// /// Extension methods for configuring Swagger documentation and UI. /// public static class SwaggerExtensions { private static readonly string? environment = Environment.GetEnvironmentVariable(EnvironmentVariables.Stage); /// /// Adds Swagger services to the specified . /// /// The to add the services to. public static void AddSwagger(this IServiceCollection services, IConfiguration configuration, string DocumentationFile, AuthSettings authSettings) { services.AddEndpointsApiExplorer(); services.AddSwaggerGen(configuration, DocumentationFile, authSettings); services.AddTransient, ConfigureSwaggerOptions>(); } /// /// Configures Swagger generation with OAuth2 security and XML comments. /// /// The to add the services to. /// The containing Swagger and OAuth2 configuration settings. public static void AddSwaggerGen(this IServiceCollection services, IConfiguration configuration, string DocumentationFile, AuthSettings authSettings) { services.AddSwaggerGen(c => { c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Description = "OAuth2.0 Authorization Code flow", Name = "oauth2.0", Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { AuthorizationCode = new OpenApiOAuthFlow { AuthorizationUrl = new Uri(authSettings.HeathCerberosAppAuthorizationUrl ?? string.Empty), TokenUrl = new Uri(authSettings.HeathCerberosAppTokenUrl ?? string.Empty), Scopes = new Dictionary { { authSettings.HeathCerberosAppScope ?? string.Empty, "Access API as User" } } } } }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } }, new[] { authSettings.HeathCerberosAppScope } } }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty() } }); var filePath = Path.Combine(AppContext.BaseDirectory, DocumentationFile); c.IncludeXmlComments(filePath); c.SchemaFilter(); }); } /// /// Configures Swagger and Swagger UI for the application. /// /// The instance. /// The containing Swagger configuration settings. public static void ConfigureSwagger(this WebApplication app, IConfiguration configuration) { app.UseSwagger(); app.UseSwaggerUI(options => { foreach (var version in app.DescribeApiVersions().Select(version => version.GroupName)) options.SwaggerEndpoint($"/swagger/{version}/swagger.json", version); options.DisplayRequestDuration(); options.EnableTryItOutByDefault(); options.DocExpansion(DocExpansion.None); }); } /// /// Configures Swagger UI for the application with OAuth2 settings. /// /// The instance. /// The containing Swagger UI and OAuth2 configuration settings. public static void UseSwaggerUI(this WebApplication app, IConfiguration configuration, AuthSettings authSettings) { app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "Custom Auth API with Azure AD v1"); options.OAuthClientId(authSettings.HeathCerberosAppClientId); options.OAuthUsePkce(); options.OAuthScopeSeparator(" "); }); } /// /// Adds API versioning and API explorer to the application. /// /// The to add the services to. /// The modified instance. public static IServiceCollection AddVersioning(this IServiceCollection services, IConfiguration configuration) { services.AddApiVersioning(options => options.ReportApiVersions = true) .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; }); return services; } } /// /// Configures Swagger generation options. /// public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) : IConfigureOptions { /// /// Configures SwaggerGen options. /// /// The SwaggerGen options to configure. public void Configure(SwaggerGenOptions options) { foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerDoc(description.GroupName, new OpenApiInfo { Title = AppDomain.CurrentDomain.FriendlyName, Version = description.ApiVersion.ToString() }); } // Map DateOnly type to Swagger schema options.MapType(() => new OpenApiSchema { Type = "string", Format = "date", Example = new OpenApiString(DateOnly.MinValue.ToString()) }); // Customize schema IDs for Swagger options.CustomSchemaIds(type => type.ToString().Replace("+", ".")); } } }