forked from GithubBackups/healthchecks
Update the "Close Account" function to use confirmation codes
This commit is contained in:
parent
48750ee668
commit
9401bc3987
@ -7,6 +7,21 @@ from hc.test import BaseTestCase
|
||||
|
||||
|
||||
class CloseAccountTestCase(BaseTestCase):
|
||||
def test_it_requires_sudo_mode(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
|
||||
r = self.client.get("/accounts/close/")
|
||||
self.assertContains(r, "We have sent a confirmation code")
|
||||
|
||||
def test_it_shows_confirmation_form(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
self.set_sudo_flag()
|
||||
|
||||
r = self.client.get("/accounts/close/")
|
||||
self.assertContains(r, "Close Account?")
|
||||
self.assertContains(r, "1 project")
|
||||
self.assertContains(r, "0 checks")
|
||||
|
||||
@patch("hc.payments.models.braintree")
|
||||
def test_it_works(self, mock_braintree):
|
||||
Check.objects.create(project=self.project, tags="foo a-B_1 baz@")
|
||||
@ -15,8 +30,11 @@ class CloseAccountTestCase(BaseTestCase):
|
||||
)
|
||||
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
r = self.client.post("/accounts/close/")
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.set_sudo_flag()
|
||||
|
||||
payload = {"confirmation": "alice@example.org"}
|
||||
r = self.client.post("/accounts/close/", payload)
|
||||
self.assertRedirects(r, "/")
|
||||
|
||||
# Alice should be gone
|
||||
alices = User.objects.filter(username="alice")
|
||||
@ -31,10 +49,26 @@ class CloseAccountTestCase(BaseTestCase):
|
||||
# Subscription should be gone
|
||||
self.assertFalse(Subscription.objects.exists())
|
||||
|
||||
def test_it_requires_confirmation(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
self.set_sudo_flag()
|
||||
|
||||
payload = {"confirmation": "incorrect"}
|
||||
r = self.client.post("/accounts/close/", payload)
|
||||
self.assertContains(r, "Close Account?")
|
||||
self.assertContains(r, "has-error")
|
||||
|
||||
# Alice should be still present
|
||||
self.alice.refresh_from_db()
|
||||
self.profile.refresh_from_db()
|
||||
|
||||
def test_partner_removal_works(self):
|
||||
self.client.login(username="bob@example.org", password="password")
|
||||
r = self.client.post("/accounts/close/")
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.set_sudo_flag()
|
||||
|
||||
payload = {"confirmation": "bob@example.org"}
|
||||
r = self.client.post("/accounts/close/", payload)
|
||||
self.assertRedirects(r, "/")
|
||||
|
||||
# Alice should be still present
|
||||
self.alice.refresh_from_db()
|
||||
@ -43,8 +77,3 @@ class CloseAccountTestCase(BaseTestCase):
|
||||
# Bob should be gone
|
||||
bobs = User.objects.filter(username="bob")
|
||||
self.assertFalse(bobs.exists())
|
||||
|
||||
def test_it_rejects_get(self):
|
||||
self.client.login(username="bob@example.org", password="password")
|
||||
r = self.client.get("/accounts/close/")
|
||||
self.assertEqual(r.status_code, 405)
|
||||
|
@ -540,22 +540,29 @@ def unsubscribe_reports(request, signed_username):
|
||||
return render(request, "accounts/unsubscribed.html")
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@require_sudo_mode
|
||||
def close(request):
|
||||
user = request.user
|
||||
|
||||
# Cancel their subscription:
|
||||
sub = Subscription.objects.filter(user=user).first()
|
||||
if sub:
|
||||
sub.cancel()
|
||||
if request.method == "POST":
|
||||
if request.POST.get("confirmation") == request.user.email:
|
||||
# Cancel their subscription:
|
||||
sub = Subscription.objects.filter(user=user).first()
|
||||
if sub:
|
||||
sub.cancel()
|
||||
|
||||
user.delete()
|
||||
# Deleting user also deletes its profile, checks, channels etc.
|
||||
user.delete()
|
||||
|
||||
# Deleting user also deletes its profile, checks, channels etc.
|
||||
request.session.flush()
|
||||
return redirect("hc-index")
|
||||
|
||||
request.session.flush()
|
||||
return redirect("hc-index")
|
||||
ctx = {}
|
||||
if "confirmation" in request.POST:
|
||||
ctx["wrong_confirmation"] = True
|
||||
|
||||
return render(request, "accounts/close_account.html", ctx)
|
||||
|
||||
|
||||
@require_POST
|
||||
|
50
templates/accounts/close_account.html
Normal file
50
templates/accounts/close_account.html
Normal file
@ -0,0 +1,50 @@
|
||||
{% extends "base.html" %}
|
||||
{% load compress static hc_extras %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<form class="col-sm-6 col-sm-offset-3" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body settings-block">
|
||||
<h2>Close Account?</h2>
|
||||
<p></p>
|
||||
|
||||
<p>
|
||||
You are about to close your {% site_name %} account. This
|
||||
operation will permanently remove:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>{{ request.user.project_set.count }} project{{ request.user.project_set.count|pluralize }}</li>
|
||||
<li>{{ request.profile.num_checks_used }} check{{ request.profile.num_checks_used|pluralize }}</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
To confirm, please type your account's email address
|
||||
(<code>{{ request.user.email }}</code>) below:
|
||||
</p>
|
||||
|
||||
<div class="form-group {% if wrong_confirmation%}has-error{% endif %}">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
name="confirmation"
|
||||
placeholder="type your email address to confirm" />
|
||||
</div>
|
||||
|
||||
<div class="text-right">
|
||||
<a
|
||||
href="{% url 'hc-profile' %}"
|
||||
class="btn btn-default">Cancel</a>
|
||||
<button
|
||||
type="submit"
|
||||
name="close_account"
|
||||
class="btn btn-danger">Close Account</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -193,45 +193,18 @@
|
||||
<div class="panel-body settings-block">
|
||||
{% csrf_token %}
|
||||
<h2>Close Account</h2>
|
||||
<a
|
||||
id="close-account"
|
||||
href="#"
|
||||
class="btn btn-default pull-right"
|
||||
data-toggle="modal"
|
||||
data-target="#close-account-modal">Close Account</a>
|
||||
This will permanently remove your {{ site_name }} account
|
||||
<p>This will permanently remove your {{ site_name }} account.</p>
|
||||
<div class="text-right">
|
||||
<a
|
||||
id="close-account"
|
||||
href="{% url 'hc-close' %}"
|
||||
class="btn btn-default">Close Account</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="close-account-modal" class="modal">
|
||||
<div class="modal-dialog">
|
||||
<form method="post" action="{% url 'hc-close' %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4>Close Account?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p></p>
|
||||
<p>You are about to permanently remove
|
||||
the account <strong>{{ request.user.email }}</strong> and all
|
||||
of its associated projects, checks and integrations. Are you sure?
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger">Close Account</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="leave-project-modal" class="modal">
|
||||
<div class="modal-dialog">
|
||||
<form id="leave-project-form" method="post">
|
||||
|
Loading…
x
Reference in New Issue
Block a user