feature: No user management endpoints (create, update, deactivate)

This commit is contained in:
voltsrage
2026-06-27 15:45:01 +08:00
parent 5a2e95c984
commit 299e6e1453
13 changed files with 684 additions and 4 deletions
@@ -1,4 +1,8 @@
public interface IUserDirectoryService
{
Task<IReadOnlyList<UserSummaryResponse>> ListByRoleAsync(UserRole? role);
Task<UserSummaryResponse> CreateAsync(CreateUserRequest request);
Task<UserSummaryResponse> UpdateAsync(Guid userId, UpdateUserRequest request);
Task ResetPasswordAsync(Guid userId, string newPassword);
Task ChangePasswordAsync(Guid userId, string currentPassword, string newPassword);
}
@@ -22,4 +22,74 @@ public class UserDirectoryService : IUserDirectoryService
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();
}
}