194 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // ***********************************************************************
 | |
| // <copyright file="SwaggerExtensions.cs">
 | |
| //     AgileWebs
 | |
| // </copyright>
 | |
| // ***********************************************************************
 | |
| 
 | |
| 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
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Extension methods for configuring Swagger documentation and UI.
 | |
|     /// </summary>
 | |
|     public static class SwaggerExtensions
 | |
|     {
 | |
|         private static readonly string? environment = Environment.GetEnvironmentVariable(EnvironmentVariables.Stage);
 | |
|         /// <summary>
 | |
|         /// Adds Swagger services to the specified <see cref="IServiceCollection"/>.
 | |
|         /// </summary>
 | |
|         /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
 | |
|         public static void AddSwagger(this IServiceCollection services, IConfiguration configuration, string DocumentationFile, AuthSettings authSettings)
 | |
|         {
 | |
|             services.AddEndpointsApiExplorer();
 | |
|             services.AddSwaggerGen(configuration, DocumentationFile, authSettings);
 | |
|             services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Configures Swagger generation with OAuth2 security and XML comments.
 | |
|         /// </summary>
 | |
|         /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
 | |
|         /// <param name="configuration">The <see cref="IConfiguration"/> containing Swagger and OAuth2 configuration settings.</param>
 | |
|         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<string, string>
 | |
|                                 {
 | |
|                                 { 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<string>()
 | |
|                     }
 | |
|                     });
 | |
| 
 | |
|                     var filePath = Path.Combine(AppContext.BaseDirectory, DocumentationFile);
 | |
|                     c.IncludeXmlComments(filePath);
 | |
|                     c.SchemaFilter<EnumSchemaFilter>();
 | |
|                 });
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Configures Swagger and Swagger UI for the application.
 | |
|         /// </summary>
 | |
|         /// <param name="app">The <see cref="WebApplication"/> instance.</param>
 | |
|         /// <param name="configuration">The <see cref="IConfiguration"/> containing Swagger configuration settings.</param>
 | |
|         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);
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Configures Swagger UI for the application with OAuth2 settings.
 | |
|         /// </summary>
 | |
|         /// <param name="app">The <see cref="WebApplication"/> instance.</param>
 | |
|         /// <param name="configuration">The <see cref="IConfiguration"/> containing Swagger UI and OAuth2 configuration settings.</param>
 | |
|         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(" ");
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Adds API versioning and API explorer to the application.
 | |
|         /// </summary>
 | |
|         /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
 | |
|         /// <returns>The modified <see cref="IServiceCollection"/> instance.</returns>
 | |
|         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;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Configures Swagger generation options.
 | |
|     /// </summary>
 | |
|     public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) : IConfigureOptions<SwaggerGenOptions>
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Configures SwaggerGen options.
 | |
|         /// </summary>
 | |
|         /// <param name="options">The SwaggerGen options to configure.</param>
 | |
|         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<DateOnly>(() => new OpenApiSchema
 | |
|             {
 | |
|                 Type = "string",
 | |
|                 Format = "date",
 | |
|                 Example = new OpenApiString(DateOnly.MinValue.ToString())
 | |
|             });
 | |
| 
 | |
|             // Customize schema IDs for Swagger
 | |
|             options.CustomSchemaIds(type => type.ToString().Replace("+", "."));
 | |
|         }
 | |
|     }
 | |
| }
 | 
