From da18a5d836a2c6abfa76c4887af481fd91710554 Mon Sep 17 00:00:00 2001 From: Raz Date: Wed, 20 Nov 2024 12:36:15 +0100 Subject: [PATCH] improve registration --- tournaments/forms.py | 38 +++++++++++++++ tournaments/templates/registration/login.html | 5 ++ .../registration/password_reset_complete.html | 19 ++++++++ .../registration/password_reset_confirm.html | 29 ++++++++++++ .../registration/password_reset_done.html | 20 ++++++++ .../registration/password_reset_email.html | 11 +++++ .../registration/password_reset_form.html | 25 ++++++++++ tournaments/urls.py | 4 ++ tournaments/views.py | 46 ++++++++++++++++++- 9 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 tournaments/templates/registration/password_reset_complete.html create mode 100644 tournaments/templates/registration/password_reset_confirm.html create mode 100644 tournaments/templates/registration/password_reset_done.html create mode 100644 tournaments/templates/registration/password_reset_email.html create mode 100644 tournaments/templates/registration/password_reset_form.html diff --git a/tournaments/forms.py b/tournaments/forms.py index 34d2a36..adc0063 100644 --- a/tournaments/forms.py +++ b/tournaments/forms.py @@ -115,3 +115,41 @@ class AddPlayerForm(forms.Form): # Return the cleaned data with any modifications applied return cleaned_data + +from django.contrib.auth.forms import PasswordResetForm +from django.core.mail import send_mail +from django.template.loader import render_to_string +from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode +from django.contrib.auth.tokens import default_token_generator +from django.contrib.sites.shortcuts import get_current_site +from django.utils.encoding import force_bytes + +class CustomPasswordResetForm(PasswordResetForm): + def save(self, *args, **kwargs): + """ + Override the save method to send a custom email. + """ + email = self.cleaned_data["email"] + users = self.get_users(email) + + for user in users: + # Generate the token for password reset + token = default_token_generator.make_token(user) + uid = urlsafe_base64_encode(force_bytes(user.pk)) + + # Prepare the context for the email template + context = { + "email": user.email, + "domain": get_current_site(self.request).domain, + "site_name": "Padel Club", + "uid": uid, + "token": token, + "protocol": "http", # Use 'https' in production + } + + # Render the email content from the template + subject = "Réinitialisation du mot de passe" + message = render_to_string("registration/password_reset_email.html", context) + + # Send the email + send_mail(subject, message, None, [user.email]) diff --git a/tournaments/templates/registration/login.html b/tournaments/templates/registration/login.html index ab2e224..ddd1521 100644 --- a/tournaments/templates/registration/login.html +++ b/tournaments/templates/registration/login.html @@ -20,6 +20,11 @@ + +

+ Mot de passe oublié ? +

+

Pas encore de compte ? Créer le tout de suite !

diff --git a/tournaments/templates/registration/password_reset_complete.html b/tournaments/templates/registration/password_reset_complete.html new file mode 100644 index 0000000..a701c7b --- /dev/null +++ b/tournaments/templates/registration/password_reset_complete.html @@ -0,0 +1,19 @@ +{% extends 'tournaments/base.html' %} +{% block head_title %} Réinitialisation terminée {% endblock %} +{% block first_title %} Padel Club {% endblock %} +{% block second_title %} Réinitialisation terminée {% endblock %} + +{% block content %} +
+
+
+

+ Votre mot de passe a été réinitialisé avec succès. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe. +

+

+ Se connecter +

+
+
+
+{% endblock %} diff --git a/tournaments/templates/registration/password_reset_confirm.html b/tournaments/templates/registration/password_reset_confirm.html new file mode 100644 index 0000000..cb0dc0a --- /dev/null +++ b/tournaments/templates/registration/password_reset_confirm.html @@ -0,0 +1,29 @@ +{% extends 'tournaments/base.html' %} +{% block head_title %} Nouveau mot de passe {% endblock %} +{% block first_title %} Padel Club {% endblock %} +{% block second_title %} Nouveau mot de passe {% endblock %} + +{% block content %} +
+
+
+
+ {% csrf_token %} + + + + + + + +
+

+ Retour à la connexion +

+
+ {% for message in messages %} +
{{ message }}
+ {% endfor %} +
+
+{% endblock %} diff --git a/tournaments/templates/registration/password_reset_done.html b/tournaments/templates/registration/password_reset_done.html new file mode 100644 index 0000000..bfc7035 --- /dev/null +++ b/tournaments/templates/registration/password_reset_done.html @@ -0,0 +1,20 @@ +{% extends 'tournaments/base.html' %} +{% block head_title %} Demande envoyée {% endblock %} +{% block first_title %} Padel Club {% endblock %} +{% block second_title %} Demande envoyée {% endblock %} + +{% block content %} +
+
+
+

+ Un e-mail contenant un lien pour réinitialiser votre mot de passe a été envoyé à votre adresse. + Veuillez vérifier votre boîte de réception. +

+

+ Retour à la connexion +

+
+
+
+{% endblock %} diff --git a/tournaments/templates/registration/password_reset_email.html b/tournaments/templates/registration/password_reset_email.html new file mode 100644 index 0000000..8a2c323 --- /dev/null +++ b/tournaments/templates/registration/password_reset_email.html @@ -0,0 +1,11 @@ +{% autoescape off %} +Bonjour, + +Vous avez demandé une réinitialisation de votre mot de passe. Veuillez cliquer sur le lien suivant pour en choisir un nouveau : + +http://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} + +Si vous n'avez pas fait cette demande, vous pouvez ignorer ce message. + +A tout de suite sur Padel Club ! +{% endautoescape %} diff --git a/tournaments/templates/registration/password_reset_form.html b/tournaments/templates/registration/password_reset_form.html new file mode 100644 index 0000000..318f44d --- /dev/null +++ b/tournaments/templates/registration/password_reset_form.html @@ -0,0 +1,25 @@ +{% extends 'tournaments/base.html' %} +{% block head_title %} Réinitialisation du mot de passe {% endblock %} +{% block first_title %} Padel Club {% endblock %} +{% block second_title %} Réinitialisation du mot de passe {% endblock %} + +{% block content %} +
+
+
+
+ {% csrf_token %} + + + +
+

+ Retour à la connexion +

+
+ {% for message in messages %} +
{{ message }}
+ {% endfor %} +
+
+{% endblock %} diff --git a/tournaments/urls.py b/tournaments/urls.py index 59fc932..6afde58 100644 --- a/tournaments/urls.py +++ b/tournaments/urls.py @@ -4,6 +4,7 @@ from django.urls import include, path from . import views urlpatterns = [ + path('reset///', views.CustomPasswordResetConfirmView.as_view(), name='password_reset_confirm'), path("", views.index, name="index"), path("tournaments/", views.tournaments, name="tournaments"), path("clubs/", views.clubs, name="clubs"), @@ -45,5 +46,8 @@ urlpatterns = [ path('profile/', views.profile, name='profile'), # URL pattern for signup path('tournaments//register/', views.register_tournament, name='register_tournament'), path('tournaments//unregister/', views.unregister_tournament, name='unregister_tournament'), + path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'), + path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'), + path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'), ] diff --git a/tournaments/views.py b/tournaments/views.py index 4079d20..bdc47fe 100644 --- a/tournaments/views.py +++ b/tournaments/views.py @@ -52,6 +52,15 @@ from django.template.loader import render_to_string from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.utils.encoding import force_bytes +from django.contrib.auth.forms import SetPasswordForm +from django.contrib.auth.views import PasswordResetConfirmView +from django.urls import reverse_lazy +from django.shortcuts import render +from django.utils.http import urlsafe_base64_decode +from django.contrib.auth.tokens import default_token_generator +from django.contrib.auth.models import User +from django.http import Http404 + def index(request): club_id = request.GET.get('club') @@ -687,9 +696,10 @@ def register_tournament(request, tournament_id): # Check if the team registration form is valid and finalize the registration elif 'register_team' in request.POST and team_form.is_valid(): + registration_date = timezone.now().replace(microsecond=0) team_registration = TeamRegistration.objects.create( tournament=tournament, - registration_date=timezone.now() + registration_date=registration_date ) stripped_license = None @@ -836,3 +846,37 @@ def validate_license_id(licence_id, tournament): # If all checks pass, return True (you can add further logic here if needed) return False + +class CustomPasswordResetConfirmView(PasswordResetConfirmView): + template_name = 'registration/password_reset_confirm.html' # Custom template + + def get_context_data(self, **kwargs): + """ + Modify the context to provide custom data to the template. + """ + context = super().get_context_data(**kwargs) + context['custom_message'] = "Veuillez entrer un nouveau mot de passe." + return context + + def form_valid(self, form): + """ + Custom behavior when the password reset form is valid. + """ + # Call the parent method to save the new password + response = super().form_valid(form) + + # Additional actions (e.g., logging or sending notifications) can be added here + # You can add custom logic after password reset + + return response + + def get_user(self, uidb64): + """ + Override this method to decode the uid and return the corresponding user. + """ + try: + uid = urlsafe_base64_decode(uidb64).decode() + user = User.objects.get(pk=uid) + return user + except (TypeError, ValueError, User.DoesNotExist): + raise Http404("User not found")