From 1e4221fbf2a76f5a8a6a920399af508a07c2db77 Mon Sep 17 00:00:00 2001 From: Jens Kleineheismann Date: Thu, 8 Mar 2018 15:36:29 +0100 Subject: [PATCH] Added 'Forgot Password' function. --- TODO.txt | 1 - dav_events/emails.py | 7 ++-- dav_events/forms/auth.py | 12 +++++++ .../templates/dav_events/auth/login_form.html | 1 + .../dav_events/auth/reset_password_form.html | 35 +++++++++++++++++++ dav_events/urls.py | 1 + dav_events/views/auth.py | 26 +++++++++++++- 7 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 dav_events/templates/dav_events/auth/reset_password_form.html diff --git a/TODO.txt b/TODO.txt index 2a2f6c0..950da2f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,7 +2,6 @@ - Copy Event - Tourenreferent managed Gruppen der Subreferenten - Placeholder von forms in config/app_config -- Passwort vergessen Funktion - Besserer Zurück-Button in Formulare - uhrzeitfelder ohne widget diff --git a/dav_events/emails.py b/dav_events/emails.py index be51ef9..5b74fa0 100644 --- a/dav_events/emails.py +++ b/dav_events/emails.py @@ -64,8 +64,6 @@ class AbstractMail(object): raise NotImplementedError() def send(self): - if not app_config.settings.enable_email_notifications: - return None subject = self._get_subject() body = self._get_body() sender = self._sender @@ -94,6 +92,11 @@ class AbstractEventMail(AbstractMail): context.update(self._event.get_template_context()) return context + def send(self): + if not app_config.settings.enable_email_notifications: + return None + return super(AbstractMail, self).send() + class NewEventMail(AbstractEventMail): _template_name = 'dav_events/emails/new_event.txt' diff --git a/dav_events/forms/auth.py b/dav_events/forms/auth.py index 7349756..826d43c 100644 --- a/dav_events/forms/auth.py +++ b/dav_events/forms/auth.py @@ -62,3 +62,15 @@ class SetPasswordForm(forms.Form): if commit: self.user.save() return self.user + + +class ResetPasswordForm(forms.Form): + username = auth_forms.UsernameField( + max_length=254, + label=_(u'E-Mail-Adresse'), + widget=forms.TextInput(attrs={'autofocus': True}), + ) + + def clean_username(self): + username = self.cleaned_data.get('username') + return username.lower() diff --git a/dav_events/templates/dav_events/auth/login_form.html b/dav_events/templates/dav_events/auth/login_form.html index c311bd2..248a462 100644 --- a/dav_events/templates/dav_events/auth/login_form.html +++ b/dav_events/templates/dav_events/auth/login_form.html @@ -15,6 +15,7 @@
{% csrf_token %} {% bootstrap_form form %} + {% buttons %} + + {% bootstrap_icon 'remove' %}  + {% trans 'Abbrechen' %} + + {% endbuttons %} +
+ + +
+   +
+ +{% endblock page-container %} diff --git a/dav_events/urls.py b/dav_events/urls.py index da59b0c..7813f74 100644 --- a/dav_events/urls.py +++ b/dav_events/urls.py @@ -7,6 +7,7 @@ urlpatterns = [ url(r'^user/login$', views.auth.LoginView.as_view(), name='login'), url(r'^user/logout$', views.auth.LogoutView.as_view(), name='logout'), url(r'^user/password$', views.auth.SetPasswordView.as_view(), name='set_password'), + url(r'^user/password/reset$', views.auth.ResetPasswordView.as_view(), name='reset_password'), url(r'^events$', views.events.EventListView.as_view(), name='event_list'), url(r'^events/create$', views.events.EventCreateView.as_view(), name='event_create'), url(r'^events/export$', views.events.EventListExportView.as_view(), name='event_list_export'), diff --git a/dav_events/views/auth.py b/dav_events/views/auth.py index 335e18a..728e1da 100644 --- a/dav_events/views/auth.py +++ b/dav_events/views/auth.py @@ -1,8 +1,9 @@ import logging from django.contrib import messages -from django.contrib.auth import views as auth_views +from django.contrib.auth import views as auth_views, get_user_model from django.urls import reverse_lazy from django.utils.translation import ugettext as _ +from django.views import generic from .. import emails from .. import forms @@ -46,3 +47,26 @@ class SetPasswordView(auth_views.PasswordChangeView): email = emails.PasswordSetEmail(self.request.user, form.cleaned_data['new_password']) email.send() return r + + +class ResetPasswordView(generic.FormView): + form_class = forms.auth.ResetPasswordForm + template_name = 'dav_events/auth/reset_password_form.html' + success_url = reverse_lazy('dav_events:login') + + def form_valid(self, form): + username = form.cleaned_data.get('username') + user_model = get_user_model() + try: + user = user_model.objects.get(username=username) + random_password = user_model.objects.make_random_password(length=12) + user.set_password(random_password) + user.save() + email = emails.PasswordSetEmail(user, random_password) + email.send() + messages.success(self.request, _(u'Neues Passwort versendet.')) + logger.info('Password reset for user \'%s\'', username) + except user_model.DoesNotExist: + logger.warning('Password reset for unknown user \'%s\'', username) + + return super(ResetPasswordView, self).form_valid(form)