diff --git a/AsbCloudWebApi/Middlewares/PermissionsMiddlware.cs b/AsbCloudWebApi/Middlewares/PermissionsMiddlware.cs new file mode 100644 index 00000000..38d5f420 --- /dev/null +++ b/AsbCloudWebApi/Middlewares/PermissionsMiddlware.cs @@ -0,0 +1,56 @@ +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Middlewares +{ + public class PermissionsMiddlware + { + private readonly RequestDelegate next; + + public PermissionsMiddlware(RequestDelegate next) + { + this.next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + var endpoint = context.GetEndpoint(); + var permission = endpoint?.Metadata.GetMetadata(); + if (permission is null) + { + await next(context); + return; + } + + var idUser = context.User.GetUserId(); + if (idUser is null) + { + await context.ForbidAsync(); + return; + } + + var permissionName = permission.Name; + if (string.IsNullOrEmpty(permissionName)) + permissionName = endpoint.Metadata + .GetMetadata() + ?.ControllerName + .ToLower(); + + var permissionMask = permission.Mask; + var userService = context.RequestServices.GetRequiredService(); + var isAuthorized = userService.HasPermission((int)idUser, permissionName, permissionMask); + + if(isAuthorized) + await next?.Invoke(context); + else + await context.ForbidAsync(); + } + } +} diff --git a/AsbCloudWebApi/PermissionAttribute.cs b/AsbCloudWebApi/PermissionAttribute.cs new file mode 100644 index 00000000..819da218 --- /dev/null +++ b/AsbCloudWebApi/PermissionAttribute.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; + +namespace AsbCloudWebApi +{ + public static class CommonMasks + { + public const int Get = 1; + public const int Edit = 1 << 1; + public const int Delete = 1 << 15; + public const int Any = -1; + public const int Bit_00 = 1; + public const int Bit_01 = 1 << 1; + public const int Bit_02 = 1 << 2; + public const int Bit_03 = 1 << 3; + public const int Bit_04 = 1 << 4; + public const int Bit_05 = 1 << 5; + public const int Bit_06 = 1 << 6; + public const int Bit_07 = 1 << 7; + public const int Bit_08 = 1 << 8; + public const int Bit_09 = 1 << 9; + public const int Bit_10 = 1 << 10; + public const int Bit_11 = 1 << 11; + public const int Bit_12 = 1 << 12; + public const int Bit_13 = 1 << 13; + public const int Bit_14 = 1 << 14; + public const int Bit_15 = 1 << 15; + public const int Bit_16 = 1 << 16; + public const int Bit_17 = 1 << 17; + public const int Bit_18 = 1 << 18; + public const int Bit_19 = 1 << 19; + public const int Bit_20 = 1 << 20; + public const int Bit_21 = 1 << 21; + public const int Bit_22 = 1 << 22; + public const int Bit_23 = 1 << 23; + public const int Bit_24 = 1 << 24; + public const int Bit_25 = 1 << 25; + public const int Bit_26 = 1 << 26; + public const int Bit_27 = 1 << 27; + public const int Bit_28 = 1 << 28; + public const int Bit_29 = 1 << 29; + public const int Bit_30 = 1 << 30; + public const int Bit_31 = 1 << 31; + } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class PermissionAttribute : Attribute + { + public static SortedSet Registered { get; } = new SortedSet(); + + public string Name { get; set; } + public int Mask { get; set; } + + /// + /// Проверка наличия у пользователя разрешения. + /// + /// Имя разрешения (default = controllerName) + /// Маска проверки по "И" (default = Any(-1)) + public PermissionAttribute(string name = default, int mask = -1) + { + Name = name; + Mask = mask; + Registered.Add(name); + } + } +} diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index 37572326..6828163f 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -81,6 +81,7 @@ namespace AsbCloudWebApi app.UseAuthentication(); app.UseAuthorization(); + app.UseMiddleware(); app.UseMiddleware(); app.UseMiddleware();