using System; using Kyoo.Abstractions.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; namespace Kyoo.Abstractions.Models.Permissions { /// /// Specify one part of a permissions needed for the API (the kind or the type). /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] public class PartialPermissionAttribute : Attribute, IFilterFactory { /// /// The needed permission type. /// public string Type { get; } /// /// The needed permission kind. /// public Kind Kind { get; } /// /// Ask a permission to run an action. /// /// /// With this attribute, you can only specify a type or a kind. /// To have a valid permission attribute, you must specify the kind and the permission using two attributes. /// Those attributes can be dispatched at different places (one on the class, one on the method for example). /// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will /// lead to unspecified behaviors. /// /// /// The type of the action /// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)). /// public PartialPermissionAttribute(string type) { if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase)) type = type[..^3]; Type = type.ToLower(); } /// /// Ask a permission to run an action. /// /// /// With this attribute, you can only specify a type or a kind. /// To have a valid permission attribute, you must specify the kind and the permission using two attributes. /// Those attributes can be dispatched at different places (one on the class, one on the method for example). /// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will /// lead to unspecified behaviors. /// /// The kind of permission needed. public PartialPermissionAttribute(Kind permission) { Kind = permission; } /// public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { return serviceProvider.GetRequiredService().Create(this); } /// public bool IsReusable => true; } }