Allow User to delete own account (#2949)

* Allow User to delete own account

* Add User delete e2e test

* fix test

* Apply suggestions from code review

Co-authored-by: d11n <mail@dennisreimann.de>

Co-authored-by: d11n <mail@dennisreimann.de>
This commit is contained in:
Andrew Camilleri
2021-10-09 05:18:37 +02:00
committed by GitHub
parent 4321cbf41a
commit 54539001f1
4 changed files with 53 additions and 5 deletions

View File

@@ -206,6 +206,15 @@ namespace BTCPayServer.Tests
// We should be logged in now
s.Driver.FindElement(By.Id("mainNav"));
//let's test delete user quickly while we're at it
s.GoToProfile();
s.Driver.FindElement(By.Id("danger-zone-expander")).Click();
s.Driver.FindElement(By.Id("delete-user")).Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
Assert.Contains("/login", s.Driver.Url);
}
}

View File

@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Data;
using BTCPayServer.Fido2;
using BTCPayServer.Models;
using BTCPayServer.Models.ManageViewModels;
using BTCPayServer.Security.GreenField;
using BTCPayServer.Services;
@@ -19,6 +20,7 @@ using Microsoft.Extensions.Logging;
namespace BTCPayServer.Controllers
{
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[Route("[controller]/[action]")]
public partial class ManageController : Controller
@@ -33,6 +35,7 @@ namespace BTCPayServer.Controllers
private readonly IAuthorizationService _authorizationService;
private readonly Fido2Service _fido2Service;
private readonly LinkGenerator _linkGenerator;
private readonly UserService _userService;
readonly StoreRepository _StoreRepository;
public ManageController(
@@ -41,14 +44,13 @@ namespace BTCPayServer.Controllers
EmailSenderFactory emailSenderFactory,
ILogger<ManageController> logger,
UrlEncoder urlEncoder,
BTCPayWalletProvider walletProvider,
StoreRepository storeRepository,
IWebHostEnvironment env,
BTCPayServerEnvironment btcPayServerEnvironment,
APIKeyRepository apiKeyRepository,
IAuthorizationService authorizationService,
Fido2Service fido2Service,
LinkGenerator linkGenerator
LinkGenerator linkGenerator,
UserService userService
)
{
_userManager = userManager;
@@ -61,6 +63,7 @@ namespace BTCPayServer.Controllers
_authorizationService = authorizationService;
_fido2Service = fido2Service;
_linkGenerator = linkGenerator;
_userService = userService;
_StoreRepository = storeRepository;
}
@@ -238,6 +241,30 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(SetPassword));
}
[HttpGet()]
public IActionResult DeleteUser()
{
return View("Confirm", new ConfirmModel("Delete account", "Your account will be permanently deleted. This action will also delete all stores, invoices, apps and data associated with your account.", "Delete")
{
ActionUrl = "DeleteUserPost"
});
}
[HttpPost()]
public async Task<IActionResult> DeleteUserPost()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
await _userService.DeleteUserAndAssociatedData(user);
TempData[WellKnownTempData.SuccessMessage] = "Account successfully deleted.";
await _signInManager.SignOutAsync();
return RedirectToAction(nameof(AccountController.Login), "Account");
}
#region Helpers

View File

@@ -8,7 +8,7 @@ namespace BTCPayServer.Models
public ConfirmModel() {}
public ConfirmModel(string title, string desc, string action = null, string buttonClass = ButtonClassDefault)
public ConfirmModel(string title, string desc, string action = null, string buttonClass = ButtonClassDefault, string actionUrl = null)
{
Title = title;
Description = desc;
@@ -19,6 +19,8 @@ namespace BTCPayServer.Models
{
DescriptionHtml = true;
}
ActionUrl = actionUrl;
}
public string Title { get; set; }

View File

@@ -36,8 +36,18 @@
</div>
</div>
<button type="submit" id="save" class="btn btn-primary">Save</button>
<h4 class="mt-5 mb-3">Other actions</h4>
<button id="danger-zone-expander" class="btn btn-link text-secondary mb-3 p-0" type="button" data-bs-toggle="collapse" data-bs-target="#danger-zone">
See more actions
</button>
<div id="danger-zone" class="collapse">
<a id="delete-user" class="btn btn-outline-danger mb-5" asp-action="DeleteUser" data-confirm-input="DELETE" data-bs-toggle="modal" data-bs-target="#ConfirmModal" data-action="DeleteUserPost" data-description="This action will also delete all stores, invoices, apps and data associated with the user.">Delete your user.</a>
</div>
</form>
<partial name="_Confirm"
model="@(new ConfirmModel("Delete user", "The user will be permanently deleted. This action will also delete all stores, invoices, apps and data associated with your user.", "Delete", actionUrl:"DeleteUserPost"))"/>
@section PageFootContent {
<partial name="_ValidationScriptsPartial" />
<partial name="_ValidationScriptsPartial"/>
}