diff --git a/src/c3nav/mapdata/models/report.py b/src/c3nav/mapdata/models/report.py index 04226d14..b9eacb4f 100644 --- a/src/c3nav/mapdata/models/report.py +++ b/src/c3nav/mapdata/models/report.py @@ -31,7 +31,7 @@ class Report(models.Model): ) created = models.DateTimeField(auto_now_add=True, verbose_name=_('created')) category = models.CharField(max_length=20, db_index=True, choices=CATEGORIES, verbose_name=_('category')) - author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author')) + author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL, verbose_name=_('author')) open = models.BooleanField(default=True, verbose_name=_('open')) last_update = models.DateTimeField(auto_now=True, verbose_name=_('last_update')) title = models.CharField(max_length=100, default='', verbose_name=_('title'), diff --git a/src/c3nav/site/forms.py b/src/c3nav/site/forms.py index d95f21b4..2e1bfa7e 100644 --- a/src/c3nav/site/forms.py +++ b/src/c3nav/site/forms.py @@ -3,7 +3,7 @@ from datetime import timedelta from operator import attrgetter from django.db import transaction -from django.forms import Form, IntegerField, ModelChoiceField, ModelForm +from django.forms import Form, IntegerField, ModelChoiceField, ModelForm, BooleanField from django.utils import timezone from django.utils.crypto import get_random_string from django.utils.translation import gettext_lazy as _ @@ -20,6 +20,10 @@ class ReportIssueForm(I18nModelFormMixin, ModelForm): fields = ['title', 'description'] +class DeleteAccountForm(Form): + confirm = BooleanField(label=_('Yes, i really want to delete my account.'), required=True) + + class ReportMissingLocationForm(I18nModelFormMixin, ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/src/c3nav/site/templates/site/account.html b/src/c3nav/site/templates/site/account.html index 12ea4588..cbcc6aab 100644 --- a/src/c3nav/site/templates/site/account.html +++ b/src/c3nav/site/templates/site/account.html @@ -51,7 +51,7 @@

{% trans 'Log out' %} - {% trans 'Change password' %} + {% trans 'Manage account' %}

{% endblock %} diff --git a/src/c3nav/site/templates/site/account_form.html b/src/c3nav/site/templates/site/account_form.html index 4f69c273..e7756562 100644 --- a/src/c3nav/site/templates/site/account_form.html +++ b/src/c3nav/site/templates/site/account_form.html @@ -5,6 +5,7 @@

{{ title }}

+ {% if form_description %}

{{ form_description }}

{% endif %} {% include 'site/fragment_messages.html' %} diff --git a/src/c3nav/site/templates/site/account_manage.html b/src/c3nav/site/templates/site/account_manage.html new file mode 100644 index 00000000..994a17e6 --- /dev/null +++ b/src/c3nav/site/templates/site/account_manage.html @@ -0,0 +1,26 @@ +{% extends 'site/base.html' %} +{% load i18n %} + +{% block content %} +
+

{% trans 'Manage your Account' %}

+ + {% include 'site/fragment_messages.html' %} + +

+ {% with username=request.user.username %} + {% blocktrans %}You are logged in as {{ username }}.{% endblocktrans %} + {% endwith %} +

+
+

+ {% trans 'Change password' %} +

+

+ {% trans 'Delete account' %} +

+

+ {% trans 'Log out' %} +

+
+{% endblock %} diff --git a/src/c3nav/site/urls.py b/src/c3nav/site/urls.py index 2e11c147..d7e17020 100644 --- a/src/c3nav/site/urls.py +++ b/src/c3nav/site/urls.py @@ -6,7 +6,7 @@ from c3nav.site.converters import AtPositionConverter, CoordinatesConverter, IsE from c3nav.site.views import (about_view, access_redeem_view, account_view, api_secret_create, api_secret_list, change_password_view, choose_language, login_view, logout_view, map_index, position_create, position_detail, position_list, position_set, qr_code, register_view, - report_create, report_detail, report_list) + report_create, report_detail, report_list, delete_account_view, account_manage) register_converter(LocationConverter, 'loc') register_converter(CoordinatesConverter, 'coords') @@ -41,7 +41,9 @@ urlpatterns = [ path('logout', logout_view, name='site.logout'), path('register', register_view, name='site.register'), path('account/', account_view, name='site.account'), - path('account/change_password', change_password_view, name='site.account.change_password'), + path('account/manage/', account_manage, name='site.account.manage'), + path('account/change_password/', change_password_view, name='site.account.change_password'), + path('account/delete/', delete_account_view, name='site.account.delete'), path('access/', access_redeem_view, name='site.access.redeem'), path('lang/', choose_language, name='site.language'), path('about/', about_view, name='site.about'), diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index 1e39f826..b31274c7 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -38,7 +38,7 @@ from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_l from c3nav.mapdata.utils.user import can_access_editor, get_user_data from c3nav.mapdata.views import set_tile_access_cookie from c3nav.routing.models import RouteOptions -from c3nav.site.forms import APISecretForm, PositionForm, PositionSetForm, ReportUpdateForm +from c3nav.site.forms import APISecretForm, PositionForm, PositionSetForm, ReportUpdateForm, DeleteAccountForm from c3nav.site.models import Announcement, SiteUpdate @@ -308,6 +308,27 @@ def change_password_view(request): }) +@never_cache +@login_required(login_url='site.login') +def delete_account_view(request): + if request.method == 'POST': + form = DeleteAccountForm(data=request.POST) + if form.is_valid(): + request.user.delete() + messages.success(request, _('Account successfully deleted.')) + return redirect('site.account') + else: + form = DeleteAccountForm() + + return render(request, 'site/account_form.html', { + 'title': _('Delete account'), + 'form_description': _("Click the button below to instantly delete your account and all associated data. " + "This process can't be reversed."), + 'back_url': reverse('site.account'), + 'form': form, + }) + + @never_cache @login_required(login_url='site.login') def account_view(request): @@ -316,6 +337,12 @@ def account_view(request): }) +@never_cache +@login_required(login_url='site.login') +def account_manage(request): + return render(request, 'site/account_manage.html', {}) + + @never_cache def access_redeem_view(request, token): with transaction.atomic():