Let users delete their accounts

This commit is contained in:
Mouse Reeve 2021-06-14 10:44:25 -07:00
parent 7ae64c2a68
commit 8cd6712db3
7 changed files with 71 additions and 30 deletions

View file

@ -150,6 +150,12 @@ class LimitedEditUserForm(CustomForm):
help_texts = {f: None for f in fields}
class DeleteUserForm(CustomForm):
class Meta:
model = models.User
fields = ["password"]
class UserGroupForm(CustomForm):
class Meta:
model = models.User

View file

@ -1,27 +0,0 @@
{% extends 'preferences/layout.html' %}
{% load i18n %}
{% block title %}{% trans "Delete Account" %}{% endblock %}
{% block header %}
{% trans "Delete Account" %}
{% endblock %}
{% block panel %}
{% if form.non_field_errors %}
<p class="notification is-danger">{{ form.non_field_errors }}</p>
{% endif %}
<div class="block">
<h2 class="title is-4">{% trans "Permanently delete account" %}</h2>
<p class="help">{% trans "Deleting your account cannot be undone. The username will not be available to register in the future." %}</p>
<form name="delete-account" action="/delete-account" method="post">
<div class="field">
<label class="label" for="id_password">{% trans "Confirm password" %}</label>
<input class="input" type="password" name="password" id="id_password">
</div>
<button type="submit" class="is-danger">Delete</button>
</form>
</div>
{% endblock %}

View file

@ -0,0 +1,30 @@
{% extends 'preferences/layout.html' %}
{% load i18n %}
{% block title %}{% trans "Delete Account" %}{% endblock %}
{% block header %}
{% trans "Delete Account" %}
{% endblock %}
{% block panel %}
<div class="block">
<h2 class="title is-4">{% trans "Permanently delete account" %}</h2>
<p class="notification is-danger is-light">
{% trans "Deleting your account cannot be undone. The username will not be available to register in the future." %}
</p>
<form name="delete-user" action="{% url 'prefs-delete' %}" method="post">
{% csrf_token %}
<div class="field">
<label class="label" for="id_password">{% trans "Confirm password:" %}</label>
<input class="input {% if form.password.errors %}is-danger{% endif %}" type="password" name="password" id="id_password" required>
{% for error in form.password.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<button type="submit" class="button is-danger">{% trans "Delete Account" %}</button>
</form>
</div>
{% endblock %}

View file

@ -69,3 +69,4 @@
</div>
<div class="block"><button class="button is-primary" type="submit">{% trans "Save" %}</button></div>
</form>
{% endblock %}

View file

@ -253,7 +253,7 @@ urlpatterns = [
views.ChangePassword.as_view(),
name="prefs-password",
),
re_path(r"^preferences/delete/?$", views.DeleteAccount.as_view(), name="prefs-delete"),
re_path(r"^preferences/delete/?$", views.DeleteUser.as_view(), name="prefs-delete"),
re_path(r"^preferences/block/?$", views.Block.as_view(), name="prefs-block"),
re_path(r"^block/(?P<user_id>\d+)/?$", views.Block.as_view()),
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),

View file

@ -6,7 +6,7 @@ from .block import Block, unblock
from .books import Book, EditBook, ConfirmEditBook, Editions
from .books import upload_cover, add_description, switch_edition, resolve_book
from .directory import Directory
from .edit_user import EditUser
from .edit_user import EditUser, DeleteUser
from .federation import Federation, FederatedServer
from .federation import AddFederatedServer, ImportServerBlocklist
from .federation import block_server, unblock_server

View file

@ -3,6 +3,7 @@ from io import BytesIO
from uuid import uuid4
from PIL import Image
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.core.files.base import ContentFile
from django.shortcuts import redirect
@ -10,7 +11,7 @@ from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from bookwyrm import forms
from bookwyrm import forms, models
# pylint: disable=no-self-use
@ -38,6 +39,36 @@ class EditUser(View):
return redirect(user.local_path)
# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
class DeleteUser(View):
"""delete user view"""
def get(self, request):
"""delete page for a user"""
data = {
"form": forms.DeleteUserForm(),
"user": request.user,
}
return TemplateResponse(request, "preferences/delete_user.html", data)
def post(self, request):
"""les get fancy with images"""
form = forms.DeleteUserForm(request.POST, instance=request.user)
form.is_valid()
# idk why but I couldn't get check_password to work on request.user
user = models.User.objects.get(id=request.user.id)
if form.is_valid() and user.check_password(form.cleaned_data["password"]):
request.user.delete()
logout(request)
return redirect("/")
form.errors["password"] = ["Invalid password"]
data = {"form": form, "user": request.user}
return TemplateResponse(request, "preferences/delete_user.html", data)
def save_user_form(form):
"""special handling for the user form"""
user = form.save(commit=False)