delete account feature

This commit is contained in:
Laura Klünder 2023-12-18 11:14:13 +01:00
parent a2d6012369
commit 6a5097a0b6
7 changed files with 66 additions and 6 deletions

View file

@ -31,7 +31,7 @@ class Report(models.Model):
) )
created = models.DateTimeField(auto_now_add=True, verbose_name=_('created')) created = models.DateTimeField(auto_now_add=True, verbose_name=_('created'))
category = models.CharField(max_length=20, db_index=True, choices=CATEGORIES, verbose_name=_('category')) 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')) open = models.BooleanField(default=True, verbose_name=_('open'))
last_update = models.DateTimeField(auto_now=True, verbose_name=_('last_update')) last_update = models.DateTimeField(auto_now=True, verbose_name=_('last_update'))
title = models.CharField(max_length=100, default='', verbose_name=_('title'), title = models.CharField(max_length=100, default='', verbose_name=_('title'),

View file

@ -3,7 +3,7 @@ from datetime import timedelta
from operator import attrgetter from operator import attrgetter
from django.db import transaction 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 import timezone
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -20,6 +20,10 @@ class ReportIssueForm(I18nModelFormMixin, ModelForm):
fields = ['title', 'description'] fields = ['title', 'description']
class DeleteAccountForm(Form):
confirm = BooleanField(label=_('Yes, i really want to delete my account.'), required=True)
class ReportMissingLocationForm(I18nModelFormMixin, ModelForm): class ReportMissingLocationForm(I18nModelFormMixin, ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View file

@ -51,7 +51,7 @@
<hr> <hr>
<p> <p>
<a class="button" href="{% url 'site.logout' %}">{% trans 'Log out' %}</a> <a class="button" href="{% url 'site.logout' %}">{% trans 'Log out' %}</a>
<a class="button" href="{% url 'site.account.change_password' %}">{% trans 'Change password' %}</a> <a class="button" href="{% url 'site.account.manage' %}">{% trans 'Manage account' %}</a>
</p> </p>
</main> </main>
{% endblock %} {% endblock %}

View file

@ -5,6 +5,7 @@
<main class="account"> <main class="account">
<div class="narrow"> <div class="narrow">
<h2>{{ title }}</h2> <h2>{{ title }}</h2>
{% if form_description %}<p>{{ form_description }}</p>{% endif %}
{% include 'site/fragment_messages.html' %} {% include 'site/fragment_messages.html' %}

View file

@ -0,0 +1,26 @@
{% extends 'site/base.html' %}
{% load i18n %}
{% block content %}
<main class="account">
<h2>{% trans 'Manage your Account' %}</h2>
{% include 'site/fragment_messages.html' %}
<p>
{% with username=request.user.username %}
{% blocktrans %}You are logged in as <strong>{{ username }}</strong>.{% endblocktrans %}
{% endwith %}
</p>
<hr>
<p>
<a class="button" href="{% url 'site.account.change_password' %}">{% trans 'Change password' %}</a>
</p>
<p>
<a class="button" href="{% url 'site.account.delete' %}">{% trans 'Delete account' %}</a>
</p>
<p>
<a class="button" href="{% url 'site.logout' %}">{% trans 'Log out' %}</a>
</p>
</main>
{% endblock %}

View file

@ -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, 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, change_password_view, choose_language, login_view, logout_view, map_index,
position_create, position_detail, position_list, position_set, qr_code, register_view, 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(LocationConverter, 'loc')
register_converter(CoordinatesConverter, 'coords') register_converter(CoordinatesConverter, 'coords')
@ -41,7 +41,9 @@ urlpatterns = [
path('logout', logout_view, name='site.logout'), path('logout', logout_view, name='site.logout'),
path('register', register_view, name='site.register'), path('register', register_view, name='site.register'),
path('account/', account_view, name='site.account'), 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/<str:token>', access_redeem_view, name='site.access.redeem'), path('access/<str:token>', access_redeem_view, name='site.access.redeem'),
path('lang/', choose_language, name='site.language'), path('lang/', choose_language, name='site.language'),
path('about/', about_view, name='site.about'), path('about/', about_view, name='site.about'),

View file

@ -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.utils.user import can_access_editor, get_user_data
from c3nav.mapdata.views import set_tile_access_cookie from c3nav.mapdata.views import set_tile_access_cookie
from c3nav.routing.models import RouteOptions 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 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 @never_cache
@login_required(login_url='site.login') @login_required(login_url='site.login')
def account_view(request): 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 @never_cache
def access_redeem_view(request, token): def access_redeem_view(request, token):
with transaction.atomic(): with transaction.atomic():