summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2023-09-29 05:01:45 +1000
committerJake Mannens <jake@asger.xyz>2023-09-29 05:33:04 +1000
commit76e4bf609c3d196bd20619188a317fca66f4a04a (patch)
tree8d6544efc82782f2417f39f31fd05aa76e68316e
parentbedcb6b176130fc2c6bd4657c8af4d407b64c970 (diff)
Separated Principal and LocalPrincipal types
-rw-r--r--HBContext.cs14
-rw-r--r--LocalPrincipal.cs49
-rw-r--r--Principal.cs13
-rw-r--r--PrincipalProviders/LocalPrincipalProvider.cs49
-rw-r--r--Services/PrincipalProvider.cs22
-rw-r--r--Services/SecurityService.cs14
6 files changed, 135 insertions, 26 deletions
diff --git a/HBContext.cs b/HBContext.cs
index 2bb477e..2d44bc5 100644
--- a/HBContext.cs
+++ b/HBContext.cs
@@ -24,11 +24,11 @@ public class HBContext : DbContext {
public DbSet<OcrData> OcrData { get; set; }
// Security-related tables
- public DbSet<HBPrincipal> Principals { get; set; }
- public DbSet<User> Users { get; set; }
- public DbSet<Group> Groups { get; set; }
- public DbSet<Acl> Acls { get; set; }
- public DbSet<AclRule> AclRules { get; set; }
+ public DbSet<LocalPrincipal> Principals { get; set; }
+ public DbSet<LocalUser> Users { get; set; }
+ public DbSet<LocalGroup> Groups { get; set; }
+ public DbSet<Acl> Acls { get; set; }
+ public DbSet<AclRule> AclRules { get; set; }
private IConfigService config;
@@ -50,7 +50,7 @@ public class HBContext : DbContext {
modelBuilder.Entity<Tag>().ToTable("Tags");
modelBuilder.Entity<Media>().ToTable("Media");
modelBuilder.Entity<UploadedFile>().ToTable("UploadedFiles");
- modelBuilder.Entity<HBPrincipal>().ToTable("SecurityPrincipals");
+ modelBuilder.Entity<Principal>().ToTable("SecurityPrincipals");
// Seed internal tag definitions
// These should NEVER change
@@ -70,7 +70,7 @@ public class HBContext : DbContext {
});
// Seed initial admin user
- modelBuilder.Entity<User>().HasData(new User[] {
+ modelBuilder.Entity<LocalUser>().HasData(new LocalUser[] {
new() {
ObjectId = (int) HBObjectId.AdminUser,
Guid = HBObjectGuid.AdminUser,
diff --git a/LocalPrincipal.cs b/LocalPrincipal.cs
new file mode 100644
index 0000000..28a2721
--- /dev/null
+++ b/LocalPrincipal.cs
@@ -0,0 +1,49 @@
+namespace HyperBooru;
+
+public class LocalPrincipal : HBObject {
+ public string Name { get; set; }
+ public SecurityIdentifier Sid { get; set; }
+ public List<LocalGroup> MemberOf { get; set; }
+
+ public static implicit operator Principal(LocalPrincipal principal) =>
+ new() {
+ Name = principal.Name,
+ Sid = principal.Sid,
+ };
+
+ public static implicit operator LocalPrincipal(Principal principal) =>
+ new() {
+ Name = principal.Name,
+ Sid = principal.Sid
+ };
+}
+
+public class LocalUser : LocalPrincipal {
+ public string PasswordHash { get; set; }
+
+ public static implicit operator User(LocalUser user) =>
+ new() {
+ Name = user.Name,
+ Sid = user.Sid,
+ };
+
+ public static implicit operator LocalUser(User user) =>
+ new() {
+ Name = user.Name,
+ Sid = user.Sid
+ };
+}
+
+public class LocalGroup : LocalPrincipal {
+ public static implicit operator Group(LocalGroup group) =>
+ new() {
+ Name = group.Name,
+ Sid = group.Sid,
+ };
+
+ public static implicit operator LocalGroup(Group group) =>
+ new() {
+ Name = group.Name,
+ Sid = group.Sid
+ };
+}
diff --git a/Principal.cs b/Principal.cs
index 553fbec..677f926 100644
--- a/Principal.cs
+++ b/Principal.cs
@@ -4,14 +4,11 @@ using System.Security.Principal;
namespace HyperBooru;
[Index(nameof(Name))]
-public class HBPrincipal : HBObject {
- public string Name { get; set; }
- public SecurityIdentifier Sid { get; set; }
- public List<Group> MemberOf { get; set; }
+public class Principal {
+ public string Name { get; set; }
+ public SecurityIdentifier Sid { get; set; }
}
-public class User : HBPrincipal {
- public string PasswordHash { get; set; }
-}
+public class User : Principal {}
-public class Group : HBPrincipal {} \ No newline at end of file
+public class Group : Principal {} \ No newline at end of file
diff --git a/PrincipalProviders/LocalPrincipalProvider.cs b/PrincipalProviders/LocalPrincipalProvider.cs
new file mode 100644
index 0000000..7bee800
--- /dev/null
+++ b/PrincipalProviders/LocalPrincipalProvider.cs
@@ -0,0 +1,49 @@
+using HyperBooru.Services;
+using Microsoft.EntityFrameworkCore;
+
+namespace HyperBooru.PrincipalProviders;
+
+public class LocalPrincipalProvider : PrincipalProvider {
+ private IDbContextFactory<HBContext> dbFactory;
+
+ public LocalPrincipalProvider(IDbContextFactory<HBContext> dbFactory) =>
+ this.dbFactory = dbFactory;
+
+ public override Principal? GetPrincipal(string name) {
+ using var db = dbFactory.CreateDbContext();
+
+ LocalPrincipal? principal = db.Principals.FirstOrDefault(p => p.Name == name);
+ if(principal is null)
+ return null;
+
+ return principal;
+ }
+
+ public override User? GetUser(string name) {
+ using var db = dbFactory.CreateDbContext();
+
+ LocalUser? user = db.Users.FirstOrDefault(p => p.Name == name);
+ if(user is null)
+ return null;
+
+ return user;
+ }
+
+ public override Group? GetGroup(string name) {
+ using var db = dbFactory.CreateDbContext();
+
+ LocalGroup? group = db.Groups.FirstOrDefault(p => p.Name == name);
+ if(group is null)
+ return null;
+
+ return group;
+ }
+
+ public override Group[] GetGroups(Principal principal, bool recurse) {
+ throw new NotImplementedException();
+ }
+
+ public override bool ValidatePassword(User principal, string password) {
+ throw new NotImplementedException();
+ }
+}
diff --git a/Services/PrincipalProvider.cs b/Services/PrincipalProvider.cs
index e75c6c7..6991c64 100644
--- a/Services/PrincipalProvider.cs
+++ b/Services/PrincipalProvider.cs
@@ -1,9 +1,23 @@
namespace HyperBooru.Services;
-public abstract class PrincipalProvider {
- public abstract bool ValidatePassword(HBPrincipal principal, string password);
+public interface IPrincipalProvider {
+ public Principal? GetPrincipal(string name);
+ public User? GetUser(string name);
+ public Group? GetGroup(string name);
- public abstract HBPrincipal GetPrincipal(string username);
+ public Group[] GetGroups(Principal principal);
+ public Group[] GetGroups(Principal principal, bool recurse);
- public abstract Group[] GetAllGroups(HBPrincipal principal);
+ public bool ValidatePassword(User 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 Group[] GetGroups(Principal principal) => GetGroups(principal, false);
+ public abstract Group[] GetGroups(Principal principal, bool recurse);
+
+ public abstract bool ValidatePassword(User user, string password);
}
diff --git a/Services/SecurityService.cs b/Services/SecurityService.cs
index f1444c1..8c97c7b 100644
--- a/Services/SecurityService.cs
+++ b/Services/SecurityService.cs
@@ -7,8 +7,8 @@ namespace HyperBooru.Services;
public class SecurityService {
private IDbContextFactory<HBContext> dbFactory;
- private MemoryCache<SidStruct, HBPrincipal> principalCache;
- private MemoryCache<int, Acl> aclCache;
+ private MemoryCache<SidStruct, Principal> principalCache;
+ private MemoryCache<int, Acl> aclCache;
public SecurityService(IDbContextFactory<HBContext> dbFactory) {
this.dbFactory = dbFactory;
@@ -39,7 +39,7 @@ public class SecurityService {
public IEnumerable<HBObject> Filter(
IEnumerable<HBObject> objects,
- HBPrincipal principal,
+ Principal principal,
ulong permissions) {
foreach(var obj in objects) {
@@ -51,7 +51,7 @@ public class SecurityService {
public IEnumerable<HBObject> Filter<T>(
IEnumerable<HBObject> objects,
- HBPrincipal principal,
+ Principal principal,
T permissions) where T : Enum =>
Filter(objects, principal, permissions);
@@ -62,14 +62,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, HBPrincipal principal) {
+ private ulong GetPermissions(Acl? acl, Principal principal) {
if(acl is null)
return ulong.MaxValue;
ulong permissions = 0;
var principals = GetGroupMemberShip(principal)
- .Cast<HBPrincipal>()
+ .Cast<Principal>()
.Concat(new[] { principal })
.Select(p => p.Sid)
.ToArray();
@@ -96,7 +96,7 @@ public class SecurityService {
/// Recursively get all groups of which the specified principal
/// is a member, including implicit memberships.
/// </summary>
- private List<Group> GetGroupMemberShip(HBPrincipal principal) {
+ private List<Group> GetGroupMemberShip(Principal principal) {
var groups = principal.MemberOf.ToList();
while(true) {