summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2023-07-07 17:45:51 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2023-07-07 17:51:04 +0200
commit939bb82df4a993502d39bfb852b348547746cafa (patch)
tree324e5c416b8fa34d82012a4f74e28bac2cb132f2
parent1c299abec0ed2a562572ee2c4bdaf85d0c451148 (diff)
downloadIshtar-939bb82df4a993502d39bfb852b348547746cafa.tar.bz2
Ishtar-939bb82df4a993502d39bfb852b348547746cafa.zip
✨ enable password recovering by email
-rw-r--r--changelog/en/changelog_2022-06-15.md6
-rw-r--r--changelog/fr/changelog_2023-01-25.md6
-rw-r--r--ishtar_common/templates/registration/password_reset_confirm.html49
-rw-r--r--ishtar_common/templates/registration/password_reset_email.html2
-rw-r--r--ishtar_common/urls_registration.py6
-rw-r--r--ishtar_common/views.py42
6 files changed, 79 insertions, 32 deletions
diff --git a/changelog/en/changelog_2022-06-15.md b/changelog/en/changelog_2022-06-15.md
index 4333237a0..d9004ce38 100644
--- a/changelog/en/changelog_2022-06-15.md
+++ b/changelog/en/changelog_2022-06-15.md
@@ -3,8 +3,10 @@ v4.0.54 - 2099-12-31
### Features/improvements ###
- wizards: automatic scroll on field when navigating with TAB key
-- update password form: improve layout - redirect to start page
-- open registration form: disabled by default - improve layout
+- improve layout: update password form, open registration form
+- update password form: redirect to start page
+- open registration form: disabled by default
+- reset email form
v4.0.53 - 2023-07-06
diff --git a/changelog/fr/changelog_2023-01-25.md b/changelog/fr/changelog_2023-01-25.md
index 2a68aaecd..04554b387 100644
--- a/changelog/fr/changelog_2023-01-25.md
+++ b/changelog/fr/changelog_2023-01-25.md
@@ -3,8 +3,10 @@ v4.0.54 - 2099-12-31
### Fonctionnalités/améliorations ###
- `wizards` : défilement automatique sur le champ lorsque l'on navigue avec la touche TAB
-- formulaire de mise à jour mot de passe : amélioration de la mise en page - redirection vers la page d'accueil
-- formulaire d'inscription ouvert : désactivé par défaut - amélioration de la mise en page
+- amlioration de mise en page : formulaires de mise à jour de mot de passe et d'inscription
+- formulaire de mise à jour mot de passe : redirection vers la page d'accueil
+- formulaire d'inscription ouvert : désactivé par défaut
+- formulaire de réinitialisation de mot de passe par courriel
v4.0.53 - 2023-07-06
--------------------
diff --git a/ishtar_common/templates/registration/password_reset_confirm.html b/ishtar_common/templates/registration/password_reset_confirm.html
index b0e2cc142..6129d259b 100644
--- a/ishtar_common/templates/registration/password_reset_confirm.html
+++ b/ishtar_common/templates/registration/password_reset_confirm.html
@@ -3,19 +3,42 @@
{% block content %}
-{% if validlink %}
-<div class='form'>
-<form method="post" action=".">{% csrf_token %}
- <table>
- {{ form.as_table }}
- <tr><td colspan='2'><input type="submit" value="{% trans 'Submit' %}" /></td></tr>
- </table>
-</form>
-</div>
-{% else %}
-<div class='info'>
-<p>{% trans "Password reset failed" %}</p>
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-lg-4 col-md-6 col-sm-10">
+ <h3 class="text-center">{{page_title}}</h3>
+ {% if validlink %}
+ <form method="post" action=".">{% csrf_token %}
+ {% if form.non_field_errors %}
+ <div class="form-group row">
+ {% for error in form.non_field_errors %}
+ <div class="form-group has-errors text-danger small">
+ {{error}}
+ </div>
+ {% endfor %}
+ </div>
+ {% endif %}
+ {% with force_large_col=True %}
+ {% for field in form %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endfor %}
+ {% endwith %}
+
+ <div class="row justify-content-center">
+ <div class="col-4">
+ <button type="submit" class="btn btn-primary">{% trans 'Validate' %}</button>
+ </div>
+ </div>
+ </form>
+ {% else %}
+ <div class='info'>
+ <p>{% trans "Password reset failed" %}</p>
+ </div>
+ {% endif %}
+ </div>
+ </div>
</div>
-{% endif %}
+
+
{% endblock %}
diff --git a/ishtar_common/templates/registration/password_reset_email.html b/ishtar_common/templates/registration/password_reset_email.html
index 05612cf58..ad81d141b 100644
--- a/ishtar_common/templates/registration/password_reset_email.html
+++ b/ishtar_common/templates/registration/password_reset_email.html
@@ -1,5 +1,5 @@
{% load i18n %}
{% blocktrans %}Reset password at {{ site_name }}{% endblocktrans %}:
{% block reset_link %}
-{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid, token=token %}
+{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
diff --git a/ishtar_common/urls_registration.py b/ishtar_common/urls_registration.py
index fc8d2c53c..556bf6f95 100644
--- a/ishtar_common/urls_registration.py
+++ b/ishtar_common/urls_registration.py
@@ -42,11 +42,7 @@ urlpatterns = [
path('accounts/logout/', views.LogoutView.as_view(), name='logout'),
path('accounts/password_change/', views.PasswordChangeView.as_view(),
name='password_change'),
- path('accounts/password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),
- path('accounts/password_reset/done/', auth_views.PasswordResetDoneView.as_view(),
- name='password_reset_done'),
+ path('accounts/password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
path('accounts/reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
- path('accounts/reset/done/', auth_views.PasswordResetCompleteView.as_view(),
- name='password_reset_complete'),
] \ No newline at end of file
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 38fd80689..2a60bfd6a 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -38,10 +38,7 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
-from django.contrib.auth.views import redirect_to_login, LoginView as AuthLoginView, \
- PasswordChangeView as AuthPasswordChangeView, \
- PasswordResetConfirmView as AuthPasswordResetConfirmView, \
- LogoutView as AuthLogoutView
+from django.contrib.auth import views as auth_view
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.cache import cache
@@ -179,7 +176,7 @@ def index(request):
return render(request, "index.html", dct)
-class LoginView(AuthLoginView):
+class LoginView(auth_view.LoginView):
form_class = forms.AuthenticationForm
def get_context_data(self, **kwargs):
@@ -188,7 +185,7 @@ class LoginView(AuthLoginView):
return context
-class LogoutView(AuthLogoutView):
+class LogoutView(auth_view.LogoutView):
def get(self, request, *args, **kwargs):
# clear cache
keys = []
@@ -210,7 +207,7 @@ def update_password_last_update(user):
cache.set(key, False, settings.CACHE_TIMEOUT)
-class PasswordChangeView(AuthPasswordChangeView):
+class PasswordChangeView(auth_view.PasswordChangeView):
form_class = forms.PasswordChangeForm
success_url = reverse_lazy('start')
template_name = 'registration/form.html'
@@ -227,10 +224,19 @@ class PasswordChangeView(AuthPasswordChangeView):
return context
-class PasswordResetConfirmView(AuthPasswordResetConfirmView):
+class PasswordResetConfirmView(auth_view.PasswordResetConfirmView):
+ form_class = forms.SetPasswordForm
+ success_url = reverse_lazy('login')
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context["page_title"] = _("Password reset")
+ return context
+
def form_valid(self, form):
returned = super().form_valid(form)
update_password_last_update(form.user)
+ messages.add_message(self.request, messages.INFO, _("Password changed"))
return returned
@@ -247,6 +253,24 @@ class RegistrationView(registration_views.RegistrationView):
raise NotImplementedError
+class PasswordResetView(auth_view.PasswordResetView):
+ template_name = 'registration/form.html'
+ success_url = reverse_lazy('start')
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context["page_title"] = _("Reset password")
+ return context
+
+ def form_valid(self, form):
+ returned = super().form_valid(form)
+ messages.add_message(
+ self.request, messages.INFO,
+ _("Email with password reset instructions has been sent.")
+ )
+ return returned
+
+
person_search_wizard = wizards.PersonSearch.as_view(
[("general-person_search", forms.PersonFormSelection)],
label=_("Person search"),
@@ -2753,7 +2777,7 @@ class DisplayItemView(IshtarMixin, TemplateView):
def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated:
- return redirect_to_login(reverse("display-item", kwargs=kwargs))
+ return auth_view.redirect_to_login(reverse("display-item", kwargs=kwargs))
return super(DisplayItemView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, *args, **kwargs):