Swagger: Handling PermissionsAttribute for the swagger's document

This commit is contained in:
Zoe Roux 2021-09-29 21:24:56 +02:00
parent 4791736019
commit cb6ea80adb
2 changed files with 98 additions and 1 deletions

View File

@ -0,0 +1,80 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Kyoo.Abstractions.Models.Permissions;
using NSwag;
using NSwag.Generation.Processors;
using NSwag.Generation.Processors.Contexts;
namespace Kyoo.Swagger
{
/// <summary>
/// An operation processor that adds permissions information from the <see cref="PermissionAttribute"/> and the
/// <see cref="PartialPermissionAttribute"/>.
/// </summary>
public class OperationPermissionProcessor : IOperationProcessor
{
/// <inheritdoc />
public bool Process(OperationProcessorContext context)
{
context.OperationDescription.Operation.Security ??= new List<OpenApiSecurityRequirement>();
OpenApiSecurityRequirement perms = context.MethodInfo.GetCustomAttributes<PermissionAttribute>()
.Aggregate(new OpenApiSecurityRequirement(), (agg, cur) =>
{
ICollection<string> permissions = _GetPermissionsList(agg, cur.Group);
permissions.Add($"{cur.Type}.{cur.Kind.ToString().ToLower()}");
agg[cur.Group.ToString()] = permissions;
return agg;
});
PartialPermissionAttribute controller = context.ControllerType
.GetCustomAttribute<PartialPermissionAttribute>();
if (controller != null)
{
perms = context.MethodInfo.GetCustomAttributes<PartialPermissionAttribute>()
.Aggregate(perms, (agg, cur) =>
{
Group group = controller.Group != Group.Overall
? controller.Group
: cur.Group;
string type = controller.Type ?? cur.Type;
Kind kind = controller.Type == null
? controller.Kind
: cur.Kind;
ICollection<string> permissions = _GetPermissionsList(agg, group);
permissions.Add($"{type}.{kind.ToString().ToLower()}");
agg[group.ToString()] = permissions;
return agg;
});
}
context.OperationDescription.Operation.Security.Add(perms);
return true;
}
private ICollection<string> _GetPermissionsList(OpenApiSecurityRequirement security, Group group)
{
return security.TryGetValue(group.ToString(), out IEnumerable<string> perms)
? perms.ToList()
: new List<string>();
}
}
}

View File

@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models.Permissions;
using Kyoo.Abstractions.Models.Utils;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
@ -27,6 +28,7 @@ using NJsonSchema;
using NJsonSchema.Generation.TypeMappers;
using NSwag;
using NSwag.Generation.AspNetCore;
using NSwag.Generation.Processors.Security;
using static Kyoo.Abstractions.Models.Utils.Constants;
namespace Kyoo.Swagger
@ -104,9 +106,24 @@ namespace Kyoo.Swagger
},
AuthorizationUrl = "https://localhost:44333/core/connect/authorize",
TokenUrl = "https://localhost:44333/core/connect/token"
},
}
}
});
document.OperationProcessors.Add(new OperationPermissionProcessor());
document.DocumentProcessors.Add(new SecurityDefinitionAppender(Group.Overall.ToString(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.ApiKey,
Name = "Authorization",
In = OpenApiSecurityApiKeyLocation.Header,
Description = "Type into the textbox: Bearer {your JWT token}. You can get a JWT token from /Authorization/Authenticate."
}));
document.DocumentProcessors.Add(new SecurityDefinitionAppender(Group.Admin.ToString(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.ApiKey,
Name = "Authorization",
In = OpenApiSecurityApiKeyLocation.Header,
Description = "Type into the textbox: Bearer {your JWT token}. You can get a JWT token from /Authorization/Authenticate."
}));
});
}