summaryrefslogtreecommitdiff
path: root/Services
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
parent76e4bf609c3d196bd20619188a317fca66f4a04a (diff)
Separated HBPrincipal into IPrincipal and LocalPrincipal
Diffstat (limited to 'Services')
-rw-r--r--Services/PrincipalProvider.cs24
-rw-r--r--Services/SecurityService.cs54
-rw-r--r--Services/UserService.cs13
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));
}