From 7a729ea8d69b5cea16d7ba4a03748cd8a4caf871 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 2 Dec 2020 14:59:57 -0700 Subject: Move OpenApiSecurityScheme to OperationFilter --- .../Filters/SecurityRequirementsOperationFilter.cs | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Jellyfin.Server/Filters/SecurityRequirementsOperationFilter.cs (limited to 'Jellyfin.Server/Filters') diff --git a/Jellyfin.Server/Filters/SecurityRequirementsOperationFilter.cs b/Jellyfin.Server/Filters/SecurityRequirementsOperationFilter.cs new file mode 100644 index 000000000..802662ce2 --- /dev/null +++ b/Jellyfin.Server/Filters/SecurityRequirementsOperationFilter.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Jellyfin.Api.Constants; +using Microsoft.AspNetCore.Authorization; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Jellyfin.Server.Filters +{ + /// + /// Security requirement operation filter. + /// + public class SecurityRequirementsOperationFilter : IOperationFilter + { + /// + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + var requiredScopes = new List(); + + // Add all method scopes. + foreach (var attribute in context.MethodInfo.GetCustomAttributes(true)) + { + if (attribute is AuthorizeAttribute authorizeAttribute + && authorizeAttribute.Policy != null + && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal)) + { + requiredScopes.Add(authorizeAttribute.Policy); + } + } + + // Add controller scopes if any. + var controllerAttributes = context.MethodInfo.DeclaringType?.GetCustomAttributes(true); + if (controllerAttributes != null) + { + foreach (var attribute in controllerAttributes) + { + if (attribute is AuthorizeAttribute authorizeAttribute + && authorizeAttribute.Policy != null + && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal)) + { + requiredScopes.Add(authorizeAttribute.Policy); + } + } + } + + if (requiredScopes.Count != 0) + { + if (!operation.Responses.ContainsKey("401")) + { + operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" }); + } + + if (!operation.Responses.ContainsKey("403")) + { + operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" }); + } + + var scheme = new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = AuthenticationSchemes.CustomAuthentication + } + }; + + operation.Security = new List + { + new OpenApiSecurityRequirement + { + [scheme] = requiredScopes + } + }; + } + } + } +} \ No newline at end of file -- cgit v1.2.3