Create models and Clean Arch boilerplate

This commit is contained in:
danial23 2025-05-19 16:13:58 -04:00
parent 3926db5446
commit 872dc1e263
Signed by: danial23
SSH key fingerprint: SHA256:IJ8VP0j2WMUVweTYnzUUnEjNgPnGx+mAt+RhqWZ01bU
21 changed files with 576 additions and 27 deletions

View file

@ -0,0 +1,33 @@
namespace CSR.Domain.Entities;
public record Role
{
public int Id { get; private set; }
public string Name { get; private set; }
private Role(int id, string name)
{
Id = id;
Name = name;
}
internal static Role LoadExisting(int id, string name)
{
return new Role(id, name);
}
public static Role Admin
{
get
{
return new Role(1, "Admin");
}
}
public static Role User
{
get
{
return new Role(2, "User");
}
}
}

173
CSR.Domain/Entities/User.cs Normal file
View file

@ -0,0 +1,173 @@
namespace CSR.Domain.Entities;
using System.Net.Mail;
using CSR.Domain.Interfaces;
public class User
{
public int Id { get; private set; }
public string Username { get; private set; }
public string Email { get; private set; }
public string PasswordHash { get; private set; }
public int RoleId { get; private set; }
public Role Role { get; private set; }
private User(int id, string username, string email, string passwordHash, int roleId, Role role)
{
Id = id;
Username = username;
Email = email;
PasswordHash = passwordHash;
RoleId = roleId;
Role = role;
}
// This role is used when a new user is created
public static readonly Role DefaultRole = Role.User;
internal static User LoadExisting(int id, string username, string email, string passwordHash, int roleId, Role role)
{
return new User(id, username, email, passwordHash, roleId, role);
}
public (bool Success, IEnumerable<string>? Errors) UpdatePassword(string password, IPasswordHasher passwordHasher, User requestingUser)
{
if (requestingUser.Id != Id || requestingUser.Role.Name != "Admin")
{
throw new UnauthorizedAccessException("Only admins or the same user can update passwords.");
}
var validityCheck = IsValidPassword(password);
if (validityCheck.IsValid)
{
PasswordHash = passwordHasher.HashPassword(password);
}
return validityCheck;
}
public bool VerifyPasswordAgainstHash(string providedPassword, IPasswordHasher passwordHasher, User requestingUser)
{
if (requestingUser.Id != Id || requestingUser.Role.Name != "Admin")
{
throw new UnauthorizedAccessException("Only admins or the same user can verify passwords.");
}
return passwordHasher.VerifyHashedPassword(PasswordHash, providedPassword);
}
public static (bool IsValid, IEnumerable<string>? Errors) IsValidPassword(string password)
{
var Errors = new List<string>();
if (password.Length < 8 || password.Length > 32)
{
Errors.Add("Password must be between 8 and 32 characters long.");
}
if (!password.Any(char.IsUpper))
{
Errors.Add("Password must contain at least one uppercase letter.");
}
if (!password.Any(char.IsLower))
{
Errors.Add("Password must contain at least one lowercase letter.");
}
if (!password.Any(char.IsDigit))
{
Errors.Add("Password must contain at least one digit.");
}
if (Errors.Count > 0)
{
return (false, Errors);
}
return (true, null);
}
public (bool Success, IEnumerable<string>? Errors) UpdateEmail(string email, User requestingUser)
{
if (requestingUser.Id != Id || requestingUser.Role.Name != "Admin")
{
throw new UnauthorizedAccessException("Only admins or the same user can update email.");
}
if (IsValidEmail(email))
{
Email = email;
return (true, null);
}
return (false, new List<string> { "Invalid email format." });
}
public static bool IsValidEmail(string email)
{
try
{
var mailAddress = new MailAddress(email);
return true;
}
catch (FormatException)
{
return false;
}
}
public (bool Success, IEnumerable<string>? Errors) UpdateUsername(string username, User requestingUser)
{
if (requestingUser.Id != Id || requestingUser.Role.Name != "Admin")
{
throw new UnauthorizedAccessException("Only admins can update username.");
}
var validityCheck = IsValidUsername(username);
if (validityCheck.IsValid)
{
Username = username;
}
return validityCheck;
}
public static (bool IsValid, IEnumerable<string>? Errors) IsValidUsername(string username)
{
var Errors = new List<string>();
if (!username.All(char.IsLetterOrDigit))
{
Errors.Add("Username must be alphanumeric.");
}
if (string.IsNullOrWhiteSpace(username) || username.Length < 3)
{
Errors.Add("Username must be at least 3 characters long.");
}
if (username.Length > 32)
{
Errors.Add("Username must be less than 32 characters long.");
}
if (Errors.Count > 0)
{
return (false, Errors);
}
return (true, null);
}
public void UpdateRole(Role role, User requestingUser)
{
if (requestingUser.Role.Name != "Admin")
{
throw new UnauthorizedAccessException("Only admins can assign roles.");
}
Role = role;
RoleId = role.Id;
}
}