From c5ff0b57a12b605a5ae5ae8a92ce7a4e8eaec77a Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Fri, 29 Sep 2023 16:20:23 +1000 Subject: Separated HBPrincipal into IPrincipal and LocalPrincipal --- Services/SecurityService.cs | 54 ++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) (limited to 'Services/SecurityService.cs') diff --git a/Services/SecurityService.cs b/Services/SecurityService.cs index 8c97c7b..48f2d3e 100644 --- a/Services/SecurityService.cs +++ b/Services/SecurityService.cs @@ -7,21 +7,23 @@ namespace HyperBooru.Services; public class SecurityService { private IDbContextFactory dbFactory; - private MemoryCache principalCache; - private MemoryCache aclCache; + private MemoryCache membershipCache; + private MemoryCache aclCache; - public SecurityService(IDbContextFactory dbFactory) { - this.dbFactory = dbFactory; + IPrincipalProvider principalProvider; + + public SecurityService( + IDbContextFactory dbFactory, + IPrincipalProvider principalProvider) { + + this.dbFactory = dbFactory; + this.principalProvider = principalProvider; // TODO: preload the principal cache - principalCache = new() { - MaxItems = 10_000, + membershipCache = new() { + MaxItems = 1000, MaxAge = TimeSpan.FromMinutes(10), DataSource = (SidStruct sid) => { - using var db = dbFactory.CreateDbContext(); - return db.Principals - .Include(p => p.MemberOf) - .FirstOrDefault(p => p.Sid.SidStruct.Equals(sid)); } }; @@ -39,7 +41,7 @@ public class SecurityService { public IEnumerable Filter( IEnumerable objects, - Principal principal, + IPrincipal principal, ulong permissions) { foreach(var obj in objects) { @@ -51,7 +53,7 @@ public class SecurityService { public IEnumerable Filter( IEnumerable objects, - Principal principal, + IPrincipal principal, T permissions) where T : Enum => Filter(objects, principal, permissions); @@ -62,14 +64,14 @@ public class SecurityService { /// /// ACL to resolve (returns a bitmask consisting of all 1's if this field is null) /// - private ulong GetPermissions(Acl? acl, Principal principal) { + private ulong GetPermissions(Acl? acl, IPrincipal principal) { if(acl is null) return ulong.MaxValue; ulong permissions = 0; var principals = GetGroupMemberShip(principal) - .Cast() + .Cast() .Concat(new[] { principal }) .Select(p => p.Sid) .ToArray(); @@ -91,28 +93,4 @@ public class SecurityService { return permissions; } - - /// - /// Recursively get all groups of which the specified principal - /// is a member, including implicit memberships. - /// - private List GetGroupMemberShip(Principal principal) { - var groups = principal.MemberOf.ToList(); - - while(true) { - var toAdd = groups - .SelectMany(g => g.MemberOf) - .Select(g => g.Sid.SidStruct) - .Where(sid => !groups.Select(g => g.Sid.SidStruct).Contains(sid)) - .ToArray(); - - if(toAdd.Count() == 0) - break; - - foreach(var sid in toAdd) - groups.Add((Group) principalCache[sid]); - } - - return groups; - } } -- cgit v1.3