2017-12-29 10:36:55 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2017-12-29 14:52:26 +00:00
|
|
|
|
using System.Runtime.Serialization;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Newtonsoft.Json.Converters;
|
2017-12-29 10:36:55 +00:00
|
|
|
|
using SimpleHashing.Net;
|
|
|
|
|
|
|
|
|
|
namespace Nibriboard.Userspace
|
|
|
|
|
{
|
2017-12-29 14:52:26 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates new <see cref="User" /> class instances for Newtonsoft.json.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class UserCreationConverter : CustomCreationConverter<User>
|
|
|
|
|
{
|
|
|
|
|
private UserManager userManager;
|
|
|
|
|
public UserCreationConverter(UserManager inUserManager)
|
|
|
|
|
{
|
|
|
|
|
userManager = inUserManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override User Create(Type objectType)
|
|
|
|
|
{
|
|
|
|
|
return new User(userManager);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a single Nibriboard user.
|
|
|
|
|
/// </summary>
|
2018-01-09 19:50:06 +00:00
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
2017-12-29 10:36:55 +00:00
|
|
|
|
public class User
|
|
|
|
|
{
|
|
|
|
|
private static ISimpleHash passwordHasher = new SimpleHash();
|
|
|
|
|
|
2017-12-29 14:52:26 +00:00
|
|
|
|
private UserManager userManager;
|
|
|
|
|
|
2018-01-09 19:50:06 +00:00
|
|
|
|
[JsonProperty]
|
2017-12-29 10:36:55 +00:00
|
|
|
|
public DateTime CreationTime { get; set; }
|
2018-01-09 19:50:06 +00:00
|
|
|
|
[JsonProperty]
|
2017-12-29 10:36:55 +00:00
|
|
|
|
public string Username { get; set; }
|
2018-01-09 19:50:06 +00:00
|
|
|
|
[JsonProperty]
|
2017-12-29 10:36:55 +00:00
|
|
|
|
public string HashedPassword { get; set; }
|
|
|
|
|
|
2017-12-29 14:52:26 +00:00
|
|
|
|
[JsonIgnore]
|
2017-12-30 12:31:00 +00:00
|
|
|
|
public List<RbacRole> Roles { get; set; } = new List<RbacRole>();
|
2017-12-29 10:36:55 +00:00
|
|
|
|
|
2018-01-10 17:52:16 +00:00
|
|
|
|
[JsonProperty]
|
|
|
|
|
public List<string> RawRoles = new List<string>();
|
2017-12-29 14:52:26 +00:00
|
|
|
|
public List<string> RolesText {
|
|
|
|
|
get {
|
|
|
|
|
return new List<string>(Roles.Select((RbacRole role) => role.Name));
|
|
|
|
|
}
|
|
|
|
|
set {
|
2018-01-10 11:53:29 +00:00
|
|
|
|
RawRoles = value;
|
2017-12-29 14:52:26 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public User(UserManager inUserManager)
|
2017-12-29 10:36:55 +00:00
|
|
|
|
{
|
2017-12-29 14:52:26 +00:00
|
|
|
|
userManager = inUserManager;
|
2017-12-29 10:36:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Updates this user's password.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newPassword">The new (unhashed) password.</param>
|
|
|
|
|
public void SetPassword(string newPassword)
|
|
|
|
|
{
|
|
|
|
|
HashedPassword = passwordHasher.Compute(newPassword);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks whether a specified (unhashed) password matches
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="providedPassword">The password to check.</param>
|
|
|
|
|
/// <returns>Whether the specified password matches the stored password or not.</returns>
|
|
|
|
|
public bool CheckPassword(string providedPassword)
|
|
|
|
|
{
|
|
|
|
|
return passwordHasher.Verify(providedPassword, HashedPassword);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Recursively works out whether this user has the specified permission.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="permission">The permission to search for.</param>
|
|
|
|
|
/// <returns>Whether this user has the specified permission through one of their roles or not.</returns>
|
|
|
|
|
public bool HasPermission(RbacPermission permission)
|
|
|
|
|
{
|
|
|
|
|
return Roles.Any((RbacRole role) => role.HasPermission(permission));
|
|
|
|
|
}
|
2017-12-29 14:52:26 +00:00
|
|
|
|
|
2017-12-30 12:31:00 +00:00
|
|
|
|
public bool HasRole(RbacRole targetRole)
|
|
|
|
|
{
|
|
|
|
|
return Roles.Any((RbacRole role) => role.HasRole(targetRole));
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-10 17:52:16 +00:00
|
|
|
|
[OnSerializing]
|
|
|
|
|
internal void OnSerializing(StreamingContext context)
|
|
|
|
|
{
|
|
|
|
|
// Update the textual list of roles just before serialisation
|
|
|
|
|
RawRoles = RolesText;
|
|
|
|
|
}
|
2017-12-29 14:52:26 +00:00
|
|
|
|
[OnDeserialized]
|
|
|
|
|
internal void OnDeserialized(StreamingContext context)
|
|
|
|
|
{
|
2018-01-10 17:52:16 +00:00
|
|
|
|
// Resolve the list of text roles to a list of RbacRole objects after deserialisation
|
2018-01-10 11:53:29 +00:00
|
|
|
|
Roles = new List<RbacRole>(userManager.ResolveRoles(RawRoles));
|
2017-12-29 14:52:26 +00:00
|
|
|
|
}
|
2017-12-29 10:36:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|