From df48e8861474dc7461fb2576697cb96c38b15e76 Mon Sep 17 00:00:00 2001 From: Karolis2011 Date: Tue, 25 Jan 2022 21:11:24 +0200 Subject: [PATCH] Clean up --- KTUSAPS/Auth/AdminAuthorizationHandler.cs | 38 --- KTUSAPS/Auth/MyIssueRequirement.cs | 8 + KTUSAPS/Auth/SaPsAuthorizationHandler.cs | 117 +++++++ KTUSAPS/ClientApp/src/components/NavMenu.vue | 4 +- KTUSAPS/Controllers/GlueController.cs | 303 ------------------- KTUSAPS/Controllers/IssuesController.cs | 33 +- KTUSAPS/Models/RequestScope.cs | 8 + KTUSAPS/Startup.cs | 12 +- 8 files changed, 165 insertions(+), 358 deletions(-) delete mode 100644 KTUSAPS/Auth/AdminAuthorizationHandler.cs create mode 100644 KTUSAPS/Auth/MyIssueRequirement.cs create mode 100644 KTUSAPS/Auth/SaPsAuthorizationHandler.cs delete mode 100644 KTUSAPS/Controllers/GlueController.cs create mode 100644 KTUSAPS/Models/RequestScope.cs diff --git a/KTUSAPS/Auth/AdminAuthorizationHandler.cs b/KTUSAPS/Auth/AdminAuthorizationHandler.cs deleted file mode 100644 index a3b7002..0000000 --- a/KTUSAPS/Auth/AdminAuthorizationHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using KTUSAPS.Data; -using Microsoft.AspNetCore.Authorization; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace KTUSAPS.Auth -{ - public class AdminAuthorizationHandler : AuthorizationHandler - { - private readonly IServiceProvider serviceProvider; - public AdminAuthorizationHandler(IServiceProvider serviceProvider) - { - this.serviceProvider = serviceProvider; - } - - protected async override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdminRequirement requirement) - { - var idclaim = context.User.Claims.Where(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").FirstOrDefault(); - if(idclaim == default) - { - context.Fail(); - return; - } - using var scope = serviceProvider.CreateScope(); - var dataContext = scope.ServiceProvider.GetRequiredService(); - var admin = await dataContext.Admins.Where(a => a.UserId == idclaim.Value).FirstOrDefaultAsync(); - if (admin != default) - { - context.Succeed(requirement); - return; - } - context.Fail(); - } - } -} diff --git a/KTUSAPS/Auth/MyIssueRequirement.cs b/KTUSAPS/Auth/MyIssueRequirement.cs new file mode 100644 index 0000000..fc1c027 --- /dev/null +++ b/KTUSAPS/Auth/MyIssueRequirement.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Authorization; + +namespace KTUSAPS.Auth +{ + public class MyIssueRequirement : IAuthorizationRequirement + { + } +} diff --git a/KTUSAPS/Auth/SaPsAuthorizationHandler.cs b/KTUSAPS/Auth/SaPsAuthorizationHandler.cs new file mode 100644 index 0000000..809deda --- /dev/null +++ b/KTUSAPS/Auth/SaPsAuthorizationHandler.cs @@ -0,0 +1,117 @@ +using KTUSAPS.Data; +using KTUSAPS.Data.Model; +using KTUSAPS.Extensions; +using Microsoft.AspNetCore.Authorization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace KTUSAPS.Auth +{ + public class SaPsAuthorizationHandler : IAuthorizationHandler + { + private readonly IServiceProvider serviceProvider; + public SaPsAuthorizationHandler(IServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + } + + public async Task HandleAsync(AuthorizationHandlerContext context) + { + var cache = new AuthProcessingCache(context.User, serviceProvider); + foreach (var requirement in context.Requirements) + { + if (requirement is AdminRequirement adminRequirement) + await HandleRequirementAsync(context, adminRequirement, cache); + if (requirement is MyIssueRequirement myIssueRequirement) + await HandleRequirementAsync(context, myIssueRequirement, cache); + } + } + + private async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyIssueRequirement myIssueRequirement, AuthProcessingCache cache) + { + if(context.Resource is not Issue issue) + throw new Exception($"'{nameof(MyIssueRequirement)}' must be issued with resource of type '{nameof(Issue)}'"); + + if(issue.UserID == context.User.GetUserId()) + { + context.Succeed(myIssueRequirement); + return; + } + + if(await cache.DetermineIsAdminAsync()) + { + context.Succeed(myIssueRequirement); + return; + } + } + + private async Task HandleRequirementAsync(AuthorizationHandlerContext context, AdminRequirement adminRequirement, AuthProcessingCache cache) + { + if(await cache.DetermineIsAdminAsync()) + { + context.Succeed(adminRequirement); + return; + } + context.Fail(); + } + + + private class AuthProcessingCache + { + private readonly ClaimsPrincipal _user; + private readonly IServiceProvider _serviceProvider; + + private bool? isAdmin; + public bool IsAdmin => determineIsAdminCached(); + + public AuthProcessingCache(ClaimsPrincipal user, IServiceProvider serviceProvider) { + _user = user; + _serviceProvider = serviceProvider; + } + + private bool determineIsAdminCached() + { + if (isAdmin == null) + isAdmin = determineIsAdmin(); + return isAdmin.Value; + } + + private bool determineIsAdmin() + { + var objectId = _user.GetObjectId(); + if (objectId == default) + return false; + using var scope = _serviceProvider.CreateScope(); + var dataContext = scope.ServiceProvider.GetRequiredService(); + var admin = dataContext.Admins.Where(a => a.UserId == objectId).FirstOrDefault(); + if (admin != default) + return true; + return false; + } + + private async ValueTask determineIsAdminAsync() + { + var idclaim = _user.Claims.Where(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").FirstOrDefault(); + if (idclaim == default) + return false; + using var scope = _serviceProvider.CreateScope(); + var dataContext = scope.ServiceProvider.GetRequiredService(); + var admin = await dataContext.Admins.Where(a => a.UserId == idclaim.Value).FirstOrDefaultAsync(); + if (admin != default) + return true; + return false; + } + + public async ValueTask DetermineIsAdminAsync() + { + if (isAdmin == null) + isAdmin = await determineIsAdminAsync(); + return isAdmin.Value; + } + } + } +} diff --git a/KTUSAPS/ClientApp/src/components/NavMenu.vue b/KTUSAPS/ClientApp/src/components/NavMenu.vue index 5f22888..d9df1ed 100644 --- a/KTUSAPS/ClientApp/src/components/NavMenu.vue +++ b/KTUSAPS/ClientApp/src/components/NavMenu.vue @@ -47,9 +47,9 @@ >Pateiktos problemos - +