Files
vigilcare-records/VigilCareRecordsAPI/Services/UserDirectoryService.cs
T

96 lines
3.2 KiB
C#

using Microsoft.EntityFrameworkCore;
public class UserDirectoryService : IUserDirectoryService
{
private readonly AppDbContext _db;
public UserDirectoryService(AppDbContext db) => _db = db;
public async Task<IReadOnlyList<UserSummaryResponse>> ListByRoleAsync(UserRole? role)
{
var query = _db.Users.AsNoTracking().Where(u => u.IsActive);
if (role.HasValue)
query = query.Where(u => u.Role == role.Value);
return await query
.OrderBy(u => u.FullName)
.Select(u => new UserSummaryResponse(
u.Id,
u.Username,
u.FullName,
u.Role.ToDbString()))
.ToListAsync();
}
public async Task<UserSummaryResponse> CreateAsync(CreateUserRequest request)
{
var exists = await _db.Users.AnyAsync(u => u.Username == request.Username);
if (exists)
throw new ConflictException(
$"Username '{request.Username}' is already taken.",
"USERNAME_TAKEN");
var user = new User
{
Id = Guid.NewGuid(),
Username = request.Username,
PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.Password),
FullName = request.FullName,
Role = UserRoleExtensions.FromDbString(request.Role),
IsActive = true,
CreatedAt = DateTimeOffset.UtcNow
};
_db.Users.Add(user);
await _db.SaveChangesAsync();
return new UserSummaryResponse(user.Id, user.Username, user.FullName, user.Role.ToDbString());
}
public async Task<UserSummaryResponse> UpdateAsync(Guid userId, UpdateUserRequest request)
{
var user = await _db.Users.FindAsync(userId);
if (user is null)
throw new NotFoundException("User not found.", "USER_NOT_FOUND");
if (request.FullName is not null)
user.FullName = request.FullName;
if (request.Role is not null)
user.Role = UserRoleExtensions.FromDbString(request.Role);
if (request.IsActive.HasValue)
user.IsActive = request.IsActive.Value;
await _db.SaveChangesAsync();
return new UserSummaryResponse(user.Id, user.Username, user.FullName, user.Role.ToDbString());
}
public async Task ResetPasswordAsync(Guid userId, string newPassword)
{
var user = await _db.Users.FindAsync(userId);
if (user is null)
throw new NotFoundException("User not found.", "USER_NOT_FOUND");
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
await _db.SaveChangesAsync();
}
public async Task ChangePasswordAsync(Guid userId, string currentPassword, string newPassword)
{
var user = await _db.Users.FindAsync(userId);
if (user is null)
throw new NotFoundException("User not found.", "USER_NOT_FOUND");
if (!BCrypt.Net.BCrypt.Verify(currentPassword, user.PasswordHash))
throw new ValidationException(
"Current password is incorrect.",
"INVALID_PASSWORD");
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
await _db.SaveChangesAsync();
}
}