From 4b7b24d8928ce29f4b33d39aa60b54bced6fa97d Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Fri, 29 Dec 2017 10:36:55 +0000 Subject: [PATCH] [server] Start building user/rbac system. --- Nibriboard/Nibriboard.csproj | 8 ++++ Nibriboard/Userspace/RbacPermission.cs | 33 ++++++++++++++++ Nibriboard/Userspace/RbacRole.cs | 32 ++++++++++++++++ Nibriboard/Userspace/User.cs | 51 +++++++++++++++++++++++++ Nibriboard/Userspace/UserManager.cs | 53 ++++++++++++++++++++++++++ Nibriboard/packages.config | 1 + 6 files changed, 178 insertions(+) create mode 100644 Nibriboard/Userspace/RbacPermission.cs create mode 100644 Nibriboard/Userspace/RbacRole.cs create mode 100644 Nibriboard/Userspace/User.cs create mode 100644 Nibriboard/Userspace/UserManager.cs diff --git a/Nibriboard/Nibriboard.csproj b/Nibriboard/Nibriboard.csproj index fbbcc54..9a0b52d 100644 --- a/Nibriboard/Nibriboard.csproj +++ b/Nibriboard/Nibriboard.csproj @@ -54,6 +54,9 @@ ..\packages\GlidingSquirrel.0.6.1-alpha\lib\net462\GlidingSquirrel.dll + + ..\packages\SimpleHashing.Net.1.0.1\lib\SimpleHashing.Net.dll + @@ -145,6 +148,10 @@ + + + + @@ -169,6 +176,7 @@ + diff --git a/Nibriboard/Userspace/RbacPermission.cs b/Nibriboard/Userspace/RbacPermission.cs new file mode 100644 index 0000000..cb5b7d9 --- /dev/null +++ b/Nibriboard/Userspace/RbacPermission.cs @@ -0,0 +1,33 @@ +using System; + +namespace Nibriboard.Userspace +{ + public class RbacPermission + { + public readonly string Name; + public readonly string Description; + + public RbacPermission(string inName, string inDescription) + { + Name = inName; + Description = inDescription; + } + + public override bool Equals(object obj) + { + RbacPermission otherPermission = obj as RbacPermission; + if (obj == null) + return false; + return Name == otherPermission.Name; + } + public override int GetHashCode() + { + return ToString().GetHashCode(); + } + public override string ToString() + { + return $"[RbacPermission -> {Name}: {Description}]"; + } + } + +} diff --git a/Nibriboard/Userspace/RbacRole.cs b/Nibriboard/Userspace/RbacRole.cs new file mode 100644 index 0000000..c2bbb97 --- /dev/null +++ b/Nibriboard/Userspace/RbacRole.cs @@ -0,0 +1,32 @@ +using System; +using System.Linq; +using System.Collections.Generic; + +namespace Nibriboard.Userspace +{ + public class RbacRole + { + public readonly string Name; + + public readonly List SubRoles = new List(); + public readonly List Permissions = new List(); + + public RbacRole() + { + } + public RbacRole(string inRoleName, List inPermissions) : this(inRoleName, inPermissions, new List()) + { + } + public RbacRole(string inRoleName, List inPermissions, List inSubRoles) + { + Name = inRoleName; + Permissions = inPermissions; + SubRoles = inSubRoles; + } + + public bool HasPermission(RbacPermission permission) + { + return Permissions.Contains(permission) || SubRoles.Any((RbacRole obj) => obj.HasPermission(permission)); + } + } +} diff --git a/Nibriboard/Userspace/User.cs b/Nibriboard/Userspace/User.cs new file mode 100644 index 0000000..5beef87 --- /dev/null +++ b/Nibriboard/Userspace/User.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using SimpleHashing.Net; + +namespace Nibriboard.Userspace +{ + public class User + { + private static ISimpleHash passwordHasher = new SimpleHash(); + + public DateTime CreationTime { get; set; } + public string Username { get; set; } + public string HashedPassword { get; set; } + + public List Roles { get; set; } + + public User() + { + } + + /// + /// Updates this user's password. + /// + /// The new (unhashed) password. + public void SetPassword(string newPassword) + { + HashedPassword = passwordHasher.Compute(newPassword); + } + /// + /// Checks whether a specified (unhashed) password matches + /// + /// The password to check. + /// Whether the specified password matches the stored password or not. + public bool CheckPassword(string providedPassword) + { + return passwordHasher.Verify(providedPassword, HashedPassword); + } + + /// + /// Recursively works out whether this user has the specified permission. + /// + /// The permission to search for. + /// Whether this user has the specified permission through one of their roles or not. + public bool HasPermission(RbacPermission permission) + { + return Roles.Any((RbacRole role) => role.HasPermission(permission)); + } + } +} diff --git a/Nibriboard/Userspace/UserManager.cs b/Nibriboard/Userspace/UserManager.cs new file mode 100644 index 0000000..876cfe5 --- /dev/null +++ b/Nibriboard/Userspace/UserManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace Nibriboard.Userspace +{ + public class UserManager + { + public List Users { get; private set; } = new List(); + public List Permissions { get; private set; } = new List(); + public List Roles { get; private set; } = new List(); + + public UserManager() + { + Permissions.AddRange(new RbacPermission[] { + new RbacPermission("view-public-plane", "View public planes"), + new RbacPermission("view-own-plane", "View your own planes."), + new RbacPermission("view-any-plane", "View anyone's planes."), + new RbacPermission("create-plane", "Create a new plane."), + new RbacPermission("delete-own-plane", "Delete a plane."), + new RbacPermission("delete-any-plane", "Delete a plane."), + new RbacPermission("manage-own-plane-members", "Manage the users allowed to access one of your planes."), + new RbacPermission("manage-any-plane-members", "Manage the users allowed to access one any plane.") + }); + Roles.Add(new RbacRole("Guest", new List() { + GetPermission("view-public-plane") + })); + Roles.Add(new RbacRole("Member", new List() { + GetPermission("view-own-plane"), + GetPermission("create-plane"), + GetPermission("delete-own-plane"), + GetPermission("manage-own-plane-members") + }, new List() { + GetRole("Guest") + })); + Roles.Add(new RbacRole("Root", new List() { + GetPermission("view-any-plane"), + GetPermission("delete-any-plane"), + GetPermission("manage-any-plane-members") + }, new List() { + GetRole("Member") + })); + } + + public RbacPermission GetPermission(string permissionName) + { + return Permissions.Find((RbacPermission permission) => permission.Name == permissionName); + } + public RbacRole GetRole(string roleName) + { + return Roles.Find((RbacRole role) => role.Name == roleName); + } + } +} diff --git a/Nibriboard/packages.config b/Nibriboard/packages.config index 60ff3fc..4019e74 100644 --- a/Nibriboard/packages.config +++ b/Nibriboard/packages.config @@ -5,5 +5,6 @@ + \ No newline at end of file