summaryrefslogtreecommitdiff
path: root/Services/SecurityService.cs
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2023-09-29 16:20:23 +1000
committerJake Mannens <jake@asger.xyz>2023-09-29 16:28:00 +1000
commitc5ff0b57a12b605a5ae5ae8a92ce7a4e8eaec77a (patch)
treea59c3ef10b277a7733a274f107472dc8f00cfc9a /Services/SecurityService.cs
parent76e4bf609c3d196bd20619188a317fca66f4a04a (diff)
Separated HBPrincipal into IPrincipal and LocalPrincipal
Diffstat (limited to 'Services/SecurityService.cs')
-rw-r--r--Services/SecurityService.cs54
1 files changed, 16 insertions, 38 deletions
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;
- }
}