From dc0149560c8a71e8d44ee87f08abca25e32417af Mon Sep 17 00:00:00 2001 From: Johannes Erwerle Date: Fri, 2 Oct 2026 20:32:37 +0200 Subject: [PATCH] Added form for users to delete their accounts. Closes #10 --- community_backup/tests/test_models.py | 36 ++++++++++++++++++++ community_backup/webui/forms.py | 4 +++ community_backup/webui/templates/base.html | 1 + community_backup/webui/templates/delete.html | 22 ++++++++++++ community_backup/webui/urls.py | 1 + community_backup/webui/views.py | 13 ++++++- 6 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 community_backup/webui/templates/delete.html diff --git a/community_backup/tests/test_models.py b/community_backup/tests/test_models.py index 74e2aa4..abde7ca 100644 --- a/community_backup/tests/test_models.py +++ b/community_backup/tests/test_models.py @@ -2,6 +2,7 @@ from django.test import TestCase from django.contrib.auth.models import User from django.core.exceptions import ValidationError from webui.models import BorgRepository +from django.test import Client class BorgRepositoryTestCase(TestCase): @@ -52,3 +53,38 @@ class BorgRepositoryTestCase(TestCase): user=user, ) repo.full_clean() + + +class UserDeleteTestCase(TestCase): + def test_user_delete(self): + password = "12345" + user = User.objects.create_user(username="deleteme", password=password) + + self.assertEqual( + BorgRepository.objects.filter(name="test_repo_for_deletion").count(), 0 + ) + + # create a repository + BorgRepository.objects.create( + name="test_repo_for_deletion", + key="ssh-ed25519 lkjasdlkjaslkdjaslkjd", + user=user, + ) + + # create a session for the user + c = Client() + + # log in + self.assertTrue(c.login(username=user.username, password=password)) + + # delete the account + + response = c.post("/delete/", {"confirm": "on"}, follow=True) + self.assertEqual(response.status_code, 200) + + # check that there is nothing left of the user + self.assertEqual(User.objects.filter(username="deleteme").count(), 0) + + self.assertEqual( + BorgRepository.objects.filter(name="test_repo_for_deletion").count(), 0 + ) diff --git a/community_backup/webui/forms.py b/community_backup/webui/forms.py index 3ac0cb0..0ca3ffe 100644 --- a/community_backup/webui/forms.py +++ b/community_backup/webui/forms.py @@ -38,3 +38,7 @@ class RegisterUserForm(UserCreationForm): class Meta(UserCreationForm.Meta): fields = ("username", "email") + + +class DeleteUserForm(forms.Form): + confirm = forms.BooleanField(label="I want to delete my account") diff --git a/community_backup/webui/templates/base.html b/community_backup/webui/templates/base.html index 341f6ce..766acf7 100644 --- a/community_backup/webui/templates/base.html +++ b/community_backup/webui/templates/base.html @@ -58,6 +58,7 @@ Change Password + Delete Account {% if user.is_staff %} Admin diff --git a/community_backup/webui/templates/delete.html b/community_backup/webui/templates/delete.html new file mode 100644 index 0000000..ffd0506 --- /dev/null +++ b/community_backup/webui/templates/delete.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} +{% load crispy_forms_tags %} + +{% block content %} + +{% if next %} + {% if user.is_authenticated %} +

Your account doesn't have access to this page. To proceed, + please login with an account that has access.

+ {% else %} +

Please login to see this page.

+ {% endif %} +{% endif %} + +
+ {% csrf_token %} + {{ form|crispy }} + + +
+ +{% endblock %} diff --git a/community_backup/webui/urls.py b/community_backup/webui/urls.py index 0bcf271..7ba5f31 100644 --- a/community_backup/webui/urls.py +++ b/community_backup/webui/urls.py @@ -17,5 +17,6 @@ urlpatterns = [ name="borg_delete", ), path("register/", views.RegisterUserView.as_view(), name="register"), + path("delete/", views.DeleteUserView.as_view(), name="delete"), path("imprint/", views.ImprintView.as_view(), name="imprint"), ] diff --git a/community_backup/webui/views.py b/community_backup/webui/views.py index 249f861..663cd31 100644 --- a/community_backup/webui/views.py +++ b/community_backup/webui/views.py @@ -12,7 +12,7 @@ from django.core.exceptions import ValidationError import markdown2 from .models import BorgRepository, Voucher -from .forms import BorgRepositoryForm, RegisterUserForm +from .forms import BorgRepositoryForm, RegisterUserForm, DeleteUserForm class UserOwnsRepositoryMixin(UserPassesTestMixin): @@ -70,6 +70,17 @@ class RegisterUserView(FormView): return super().form_valid(form) +class DeleteUserView(LoginRequiredMixin, FormView): + template_name = "delete.html" + form_class = DeleteUserForm + success_url = "/" + + def form_valid(self, form): + user = self.request.user + user.delete() + return super().form_valid(form) + + class BorgRepositoryCreateView(LoginRequiredMixin, CreateView): model = BorgRepository success_url = "/borg/"