Mizuki/Services/UserService.cs
2025-01-15 21:13:51 +01:00

98 lines
No EOL
2.8 KiB
C#

using Isopoh.Cryptography.Argon2;
using Microsoft.EntityFrameworkCore;
using Mizuki.Database;
using Mizuki.Database.Models;
namespace Mizuki.Services;
/// <summary>
/// The user service.
/// </summary>
/// <param name="dbContext">The Mizuki database context.</param>
public class UserService(
MizukiDbContext dbContext)
{
/// <summary>
/// Check if a user with the given username exists.
/// </summary>
/// <param name="username">The username.</param>
/// <returns>Whether they exist.</returns>
public async Task<bool> UsernameTaken(
string username)
{
return await dbContext.Users
.AnyAsync(u => u.Username == username);
}
/// <summary>
/// Gets a user with the given username.
/// </summary>
/// <param name="username">The username.</param>
/// <returns>The user model.</returns>
public async Task<User> GetUserForUsername(
string username)
{
return await dbContext.Users
.FirstAsync(u => u.Username == username);
}
/// <summary>
/// Check if the password is valid for the given user.
/// </summary>
/// <param name="username">The user's name.</param>
/// <param name="password">The password.</param>
/// <returns>Whether it's valid.</returns>
public async Task<bool> CheckPasswordForUser(
string username,
string password)
{
var user = await dbContext.Users
.FirstOrDefaultAsync(u => u.Username == username);
if (user is null)
return false;
return Argon2.Verify(user.PasswordHash, password);
}
/// <summary>
/// Creates a user with the given username and password.
/// </summary>
/// <param name="username">The username.</param>
/// <param name="password">The password.</param>
/// <returns>Whether the user was created.</returns>
public async Task<User?> CreateUser(
string username,
string password)
{
if (await UsernameTaken(username))
return null;
var hash = Argon2.Hash(password);
var userModel = new User
{
Id = Guid.NewGuid(),
Username = username,
PasswordHash = hash
};
await dbContext.Users.AddAsync(userModel);
await dbContext.SaveChangesAsync();
return userModel;
}
/// <summary>
/// Updates the password for a given user.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="newPassword">The new password.</param>
public async Task UpdatePasswordFor(
User user,
string newPassword)
{
user.PasswordHash = Argon2.Hash(newPassword);
dbContext.Users.Update(user);
await dbContext.SaveChangesAsync();
}
}