Allow deletion of admins
This commit is contained in:
@@ -19,8 +19,9 @@ public class AdminController(
|
|||||||
DeleteUserHandler deleteUserHandler,
|
DeleteUserHandler deleteUserHandler,
|
||||||
MakeAdminHandler makeAdminHandler) : ControllerBase
|
MakeAdminHandler makeAdminHandler) : ControllerBase
|
||||||
{
|
{
|
||||||
private bool IsAdmin =>
|
private bool IsAdmin => User.FindFirstValue("isAdmin") == "true";
|
||||||
User.FindFirstValue("isAdmin") == "true";
|
private Guid RequesterId => Guid.Parse(User.FindFirstValue(System.Security.Claims.ClaimTypes.NameIdentifier)
|
||||||
|
?? User.FindFirstValue("sub")!);
|
||||||
|
|
||||||
[HttpGet("users")]
|
[HttpGet("users")]
|
||||||
public async Task<IActionResult> GetAllUsers(CancellationToken ct)
|
public async Task<IActionResult> GetAllUsers(CancellationToken ct)
|
||||||
@@ -62,7 +63,7 @@ public class AdminController(
|
|||||||
public async Task<IActionResult> DeleteUser(Guid id, CancellationToken ct)
|
public async Task<IActionResult> DeleteUser(Guid id, CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (!IsAdmin) return Forbid();
|
if (!IsAdmin) return Forbid();
|
||||||
var result = await deleteUserHandler.HandleAsync(new DeleteUserCommand(id), ct);
|
var result = await deleteUserHandler.HandleAsync(new DeleteUserCommand(RequesterId, id), ct);
|
||||||
if (!result.IsSuccess)
|
if (!result.IsSuccess)
|
||||||
return BadRequest(new ProblemDetails { Detail = result.Error });
|
return BadRequest(new ProblemDetails { Detail = result.Error });
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
namespace Randall.Application.Admin.DeleteUser;
|
namespace Randall.Application.Admin.DeleteUser;
|
||||||
|
|
||||||
public record DeleteUserCommand(Guid UserId);
|
public record DeleteUserCommand(Guid RequesterId, Guid UserId);
|
||||||
|
|||||||
@@ -11,8 +11,15 @@ public class DeleteUserHandler(IUserRepository userRepository)
|
|||||||
if (user is null)
|
if (user is null)
|
||||||
return Result.Failure("User not found.");
|
return Result.Failure("User not found.");
|
||||||
|
|
||||||
|
if (user.Id == command.RequesterId)
|
||||||
|
return Result.Failure("You cannot delete your own account.");
|
||||||
|
|
||||||
if (user.IsAdmin)
|
if (user.IsAdmin)
|
||||||
return Result.Failure("Admin users cannot be deleted.");
|
{
|
||||||
|
var adminCount = await userRepository.CountAdminsAsync(ct);
|
||||||
|
if (adminCount <= 1)
|
||||||
|
return Result.Failure("Cannot delete the last admin account.");
|
||||||
|
}
|
||||||
|
|
||||||
userRepository.Delete(user);
|
userRepository.Delete(user);
|
||||||
await userRepository.SaveChangesAsync(ct);
|
await userRepository.SaveChangesAsync(ct);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public interface IUserRepository
|
|||||||
Task<bool> ExistsByEmailAsync(string email, CancellationToken ct = default);
|
Task<bool> ExistsByEmailAsync(string email, CancellationToken ct = default);
|
||||||
Task<List<User>> GetPendingAsync(CancellationToken ct = default);
|
Task<List<User>> GetPendingAsync(CancellationToken ct = default);
|
||||||
Task<List<User>> GetAllAsync(CancellationToken ct = default);
|
Task<List<User>> GetAllAsync(CancellationToken ct = default);
|
||||||
|
Task<int> CountAdminsAsync(CancellationToken ct = default);
|
||||||
Task<List<User>> GetAllNonAdminAsync(CancellationToken ct = default);
|
Task<List<User>> GetAllNonAdminAsync(CancellationToken ct = default);
|
||||||
Task AddAsync(User user, CancellationToken ct = default);
|
Task AddAsync(User user, CancellationToken ct = default);
|
||||||
void Delete(User user);
|
void Delete(User user);
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ public class UserRepository(AppDbContext context) : IUserRepository
|
|||||||
public Task<List<User>> GetAllAsync(CancellationToken ct = default) =>
|
public Task<List<User>> GetAllAsync(CancellationToken ct = default) =>
|
||||||
context.Users.OrderBy(u => u.Name).ToListAsync(ct);
|
context.Users.OrderBy(u => u.Name).ToListAsync(ct);
|
||||||
|
|
||||||
|
public Task<int> CountAdminsAsync(CancellationToken ct = default) =>
|
||||||
|
context.Users.CountAsync(u => u.IsAdmin);
|
||||||
|
|
||||||
public Task<List<User>> GetAllNonAdminAsync(CancellationToken ct = default) =>
|
public Task<List<User>> GetAllNonAdminAsync(CancellationToken ct = default) =>
|
||||||
context.Users.Where(u => !u.IsAdmin).OrderBy(u => u.Name).ToListAsync(ct);
|
context.Users.Where(u => !u.IsAdmin).OrderBy(u => u.Name).ToListAsync(ct);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user