diff --git a/BTCPayServer.Client/BTCPayServerClient.Users.cs b/BTCPayServer.Client/BTCPayServerClient.Users.cs index d3d3e50df..08063878b 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Users.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Users.cs @@ -21,11 +21,15 @@ namespace BTCPayServer.Client return await HandleResponse(response); } - public virtual async Task DeleteUser(string userId, CancellationToken token = default) + public virtual async Task DeleteUser(string userId, CancellationToken token = default) { var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}", null, HttpMethod.Delete), token); await HandleResponse(response); - return response; + } + + public virtual async Task DeleteCurrentUser(CancellationToken token = default) + { + await DeleteUser("me", token); } } } diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index 5be327869..acd0d84d2 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -131,22 +131,39 @@ namespace BTCPayServer.Tests [Trait("Integration", "Integration")] public async Task CanDeleteUsersViaApi() { - using (var tester = ServerTester.Create(newDb: true)) - { - await tester.StartAsync(); - var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri); - // Should not be authorized to perform this action - await AssertHttpError(401, - async () => await unauthClient.DeleteUser("lol user id")); + using var tester = ServerTester.Create(newDb: true); + await tester.StartAsync(); + var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri); + // Should not be authorized to perform this action + await AssertHttpError(401, + async () => await unauthClient.DeleteUser("lol user id")); - var user = tester.NewAccount(); - user.GrantAccess(); - await user.MakeAdmin(); - var adminClient = await user.CreateClient(Policies.Unrestricted); - // Should 404 if user doesn't exist - await AssertHttpError(404, - async () => await adminClient.DeleteUser("lol user id")); - } + var user = tester.NewAccount(); + await user.GrantAccessAsync(); + await user.MakeAdmin(); + var adminClient = await user.CreateClient(Policies.Unrestricted); + + //can't delete if the only admin + await AssertHttpError(403, + async () => await adminClient.DeleteCurrentUser()); + + // Should 404 if user doesn't exist + await AssertHttpError(404, + async () => await adminClient.DeleteUser("lol user id")); + + user = tester.NewAccount(); + await user.GrantAccessAsync(); + var badClient = await user.CreateClient(Policies.CanCreateInvoice); + + await AssertHttpError(403, + async () => await badClient.DeleteCurrentUser()); + + var goodClient = await user.CreateClient(Policies.CanDeleteUser, Policies.CanViewProfile); + await goodClient.DeleteCurrentUser(); + await AssertHttpError(404, + async () => await adminClient.DeleteUser(user.UserId)); + + tester.Stores.Remove(user.StoreId); } [Fact(Timeout = TestTimeout)] diff --git a/BTCPayServer/Controllers/GreenField/UsersController.cs b/BTCPayServer/Controllers/GreenField/UsersController.cs index c4d2d526d..fe5c2478a 100644 --- a/BTCPayServer/Controllers/GreenField/UsersController.cs +++ b/BTCPayServer/Controllers/GreenField/UsersController.cs @@ -37,9 +37,6 @@ namespace BTCPayServer.Controllers.GreenField private readonly BTCPayServerOptions _options; private readonly IAuthorizationService _authorizationService; private readonly CssThemeManager _themeManager; - private readonly FileService _fileService; - private readonly StoredFileRepository _storedFileRepository; - private readonly StoreRepository _storeRepository; private readonly UserService _userService; public UsersController(UserManager userManager, @@ -51,9 +48,6 @@ namespace BTCPayServer.Controllers.GreenField BTCPayServerOptions options, IAuthorizationService authorizationService, CssThemeManager themeManager, - FileService fileService, - StoredFileRepository storedFileRepository, - StoreRepository storeRepository, UserService userService) { _userManager = userManager; @@ -65,9 +59,6 @@ namespace BTCPayServer.Controllers.GreenField _options = options; _authorizationService = authorizationService; _themeManager = themeManager; - _fileService = fileService; - _storedFileRepository = storedFileRepository; - _storeRepository = storeRepository; _userService = userService; } @@ -83,15 +74,7 @@ namespace BTCPayServer.Controllers.GreenField [HttpDelete("~/api/v1/users/me")] public async Task DeleteCurrentUser() { - // Don't want to allow the user to delete themselves if they are the only admin - if (await IsUserTheOnlyOneAdmin()) { - return Forbid(AuthenticationSchemes.GreenfieldBasic); - } - - var user = await _userManager.GetUserAsync(User); - await _userService.DeleteUserAndAssociatedData(user); - - return Ok(); + return await DeleteUser(_userManager.GetUserId(User)); } [AllowAnonymous]