feature: No user management endpoints (create, update, deactivate)
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user