diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index fb04188..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.github/.DS_Store b/.github/.DS_Store deleted file mode 100644 index 36b372c..0000000 Binary files a/.github/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index c786620..3c2a2d3 100644 --- a/.gitignore +++ b/.gitignore @@ -397,5 +397,5 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml -.DS_Store .idea/ +.DS_Store diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index c45eada..0000000 Binary files a/src/.DS_Store and /dev/null differ diff --git a/src/OpenApi.Extensions/Extensions/OpenApiOptionsExtensions.cs b/src/OpenApi.Extensions/Extensions/OpenApiOptionsExtensions.cs index fcf64f2..67f8ecb 100644 --- a/src/OpenApi.Extensions/Extensions/OpenApiOptionsExtensions.cs +++ b/src/OpenApi.Extensions/Extensions/OpenApiOptionsExtensions.cs @@ -7,7 +7,9 @@ using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; +using OpenApi.Extensions.Options; using OpenApi.Extensions.Transformers; +using OpenApi.Extensions.Transformers.Documents; using OpenApi.Extensions.Transformers.Operations; namespace OpenApi.Extensions.Extensions; @@ -29,6 +31,21 @@ public static OpenApiOptions AddDescription(this OpenApiOptions options, string return options; } + /// + /// Adds a document transformer to configure OAuth2 Implicit Flow. + /// + /// The OpenAPI options to configure. + /// + /// The updated instance. + public static OpenApiOptions AddOAuth2ImplicitFlow(this OpenApiOptions options, Action configure) + { + var opt = new ImplicitFlowOptions(); + configure(opt); + + options.AddDocumentTransformer(new OAuth2ImplicitFlowDocumentTransformation(opt.SecurityScheme, opt.TokenEndpoint, opt.AuthorizationEndpoint, opt.Description, opt.Scopes)); + return options; + } + /// /// Adds the given status code and description to all operations /// @@ -489,13 +506,6 @@ private static string FormatJson(T obj, JsonSerializerOptions? jsonSerializer return formatToJson; } - private static bool ShouldTransform(OpenApiSchemaTransformerContext context) - { - var jsonType = context.JsonTypeInfo.Type; - var type = Nullable.GetUnderlyingType(jsonType) ?? jsonType; - return type == typeof(T); - } - private static string GetTypeName() { if (typeof(T) == typeof(string)) @@ -505,4 +515,11 @@ private static string GetTypeName() return typeof(T).Name; } + + private static bool ShouldTransform(OpenApiSchemaTransformerContext context) + { + var jsonType = context.JsonTypeInfo.Type; + var type = Nullable.GetUnderlyingType(jsonType) ?? jsonType; + return type == typeof(T); + } } diff --git a/src/OpenApi.Extensions/Options/ImplicitFlowOptions.cs b/src/OpenApi.Extensions/Options/ImplicitFlowOptions.cs new file mode 100644 index 0000000..0b04890 --- /dev/null +++ b/src/OpenApi.Extensions/Options/ImplicitFlowOptions.cs @@ -0,0 +1,10 @@ +namespace OpenApi.Extensions.Options; + +public class ImplicitFlowOptions +{ + public string AuthorizationEndpoint { get; set; } = null!; + public string Description { get; set; } = null!; + public string[] Scopes { get; set; } = []; + public string SecurityScheme { get; set; } = null!; + public string TokenEndpoint { get; set; } = null!; +} diff --git a/src/OpenApi.Extensions/Transformers/Documents/OAuth2ImplicitFlowDocumentTransformation.cs b/src/OpenApi.Extensions/Transformers/Documents/OAuth2ImplicitFlowDocumentTransformation.cs new file mode 100644 index 0000000..df7a31f --- /dev/null +++ b/src/OpenApi.Extensions/Transformers/Documents/OAuth2ImplicitFlowDocumentTransformation.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.OpenApi; +using Microsoft.OpenApi.Models; + +namespace OpenApi.Extensions.Transformers.Documents; + +public class OAuth2ImplicitFlowDocumentTransformation : IOpenApiDocumentTransformer +{ + private readonly string _authorizationEndpoint; + private readonly string _description; + private readonly string[] _scopes; + private readonly string _securityScheme; + private readonly string _tokenEndpoint; + + public OAuth2ImplicitFlowDocumentTransformation(string securityScheme, + string tokenEndpoint, + string authorizationEndpoint, + string description, + params string[] scopes) + { + _securityScheme = securityScheme; + _tokenEndpoint = tokenEndpoint; + _authorizationEndpoint = authorizationEndpoint; + _description = description; + _scopes = scopes; + } + + public Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) + { + document.Components ??= new OpenApiComponents(); + document.Components.SecuritySchemes[_securityScheme] = + new OpenApiSecurityScheme + { + Type = SecuritySchemeType.OAuth2, + Description = _description, + Flows = new OpenApiOAuthFlows + { + Implicit = new OpenApiOAuthFlow + { + AuthorizationUrl = new Uri(_authorizationEndpoint), + TokenUrl = new Uri(_tokenEndpoint), + Scopes = _scopes.ToDictionary( + s => s, + s => s) + } + } + }; + + document.SecurityRequirements.Add( + new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType + .SecurityScheme, + Id = _securityScheme, + } + }, + _scopes + } + }); + + return Task.CompletedTask; + } +} diff --git a/src/OpenApi.NodaTime/.DS_Store b/src/OpenApi.NodaTime/.DS_Store deleted file mode 100644 index fb928a8..0000000 Binary files a/src/OpenApi.NodaTime/.DS_Store and /dev/null differ