diff options
| author | Jake Mannens <jake@asger.xyz> | 2023-09-29 16:20:23 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2023-09-29 16:28:00 +1000 |
| commit | c5ff0b57a12b605a5ae5ae8a92ce7a4e8eaec77a (patch) | |
| tree | a59c3ef10b277a7733a274f107472dc8f00cfc9a /Services | |
| parent | 76e4bf609c3d196bd20619188a317fca66f4a04a (diff) | |
Separated HBPrincipal into IPrincipal and LocalPrincipal
Diffstat (limited to 'Services')
| -rw-r--r-- | Services/PrincipalProvider.cs | 24 | ||||
| -rw-r--r-- | Services/SecurityService.cs | 54 | ||||
| -rw-r--r-- | Services/UserService.cs | 13 |
3 files changed, 29 insertions, 62 deletions
diff --git a/Services/PrincipalProvider.cs b/Services/PrincipalProvider.cs index 6991c64..0c35007 100644 --- a/Services/PrincipalProvider.cs +++ b/Services/PrincipalProvider.cs @@ -1,23 +1,23 @@ namespace HyperBooru.Services; public interface IPrincipalProvider { - public Principal? GetPrincipal(string name); - public User? GetUser(string name); - public Group? GetGroup(string name); + public IPrincipal? GetPrincipal(string name); + public IUser? GetUser(string name); + public IGroup? GetGroup(string name); - public Group[] GetGroups(Principal principal); - public Group[] GetGroups(Principal principal, bool recurse); + public IGroup[] GetGroups(IPrincipal principal); + public IGroup[] GetGroups(IPrincipal principal, bool recurse); - public bool ValidatePassword(User user, string password); + public bool ValidatePassword(IUser user, string password); } public abstract class PrincipalProvider : IPrincipalProvider { - public abstract Principal? GetPrincipal(string name); - public abstract User? GetUser(string name); - public abstract Group? GetGroup(string name); + public abstract IPrincipal? GetPrincipal(string name); + public abstract IUser? GetUser(string name); + public abstract IGroup? GetGroup(string name); - public Group[] GetGroups(Principal principal) => GetGroups(principal, false); - public abstract Group[] GetGroups(Principal principal, bool recurse); + public IGroup[] GetGroups(IPrincipal principal) => GetGroups(principal, false); + public abstract IGroup[] GetGroups(IPrincipal principal, bool recurse); - public abstract bool ValidatePassword(User user, string password); + public abstract bool ValidatePassword(IUser user, string password); } 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<HBContext> dbFactory; - private MemoryCache<SidStruct, Principal> principalCache; - private MemoryCache<int, Acl> aclCache; + private MemoryCache<SidStruct, IGroup[]> membershipCache; + private MemoryCache<int, Acl> aclCache; - public SecurityService(IDbContextFactory<HBContext> dbFactory) { - this.dbFactory = dbFactory; + IPrincipalProvider principalProvider; + + public SecurityService( + IDbContextFactory<HBContext> 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<HBObject> Filter( IEnumerable<HBObject> objects, - Principal principal, + IPrincipal principal, ulong permissions) { foreach(var obj in objects) { @@ -51,7 +53,7 @@ public class SecurityService { public IEnumerable<HBObject> Filter<T>( IEnumerable<HBObject> objects, - Principal principal, + IPrincipal principal, T permissions) where T : Enum => Filter(objects, principal, permissions); @@ -62,14 +64,14 @@ public class SecurityService { /// <param name="acl"> /// ACL to resolve (returns a bitmask consisting of all 1's if this field is null) /// </param> - 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<Principal>() + .Cast<IPrincipal>() .Concat(new[] { principal }) .Select(p => p.Sid) .ToArray(); @@ -91,28 +93,4 @@ public class SecurityService { return permissions; } - - /// <summary> - /// Recursively get all groups of which the specified principal - /// is a member, including implicit memberships. - /// </summary> - private List<Group> 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; - } } diff --git a/Services/UserService.cs b/Services/UserService.cs index c333c4f..d2abea3 100644 --- a/Services/UserService.cs +++ b/Services/UserService.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Cryptography.KeyDerivation; - -namespace HyperBooru.Services; +namespace HyperBooru.Services; public interface IUserService { public bool ShowNsfw { get; set; } @@ -20,13 +18,4 @@ public class UserService : IUserService { public event EventHandler<bool> ShowNsfwChanged; private bool showNsfw = false; - - public static string HashPassword(string password) => - Convert.ToBase64String( - KeyDerivation.Pbkdf2( - password, - Array.Empty<byte>(), - KeyDerivationPrf.HMACSHA512, - 100_000, - 512 / 8)); } |
