fix lot of stuff around forms and password reset

timetoconfirm
Raz 8 months ago
parent d9a696d82e
commit 9c456a9357
  1. 14
      tournaments/custom_views.py
  2. 13
      tournaments/services/tournament_registration.py
  3. 48
      tournaments/templates/profile.html
  4. 47
      tournaments/templates/register_tournament.html
  5. 4
      tournaments/templates/registration/login.html
  6. 4
      tournaments/templates/registration/password_reset_complete.html
  7. 18
      tournaments/templates/registration/password_reset_confirm.html
  8. 4
      tournaments/templates/registration/password_reset_done.html
  9. 17
      tournaments/templates/registration/password_reset_form.html
  10. 23
      tournaments/templates/registration/signup.html
  11. 9
      tournaments/templates/tournaments/tournament_info.html
  12. 12
      tournaments/urls.py
  13. 53
      tournaments/views.py

@ -10,12 +10,20 @@ class CustomLoginView(auth_views.LoginView):
def get_success_url(self):
# First check the 'next' parameter which has higher priority
next_url = self.request.POST.get('next') or self.request.GET.get('next')
# Check if the next URL is a password reset page and avoid that redirect
if next_url and next_url.strip():
# Avoid redirecting to password reset pages after login
if 'reset' in next_url or 'password_reset' in next_url:
# Redirect to profile or index instead
return reverse('profile')
return next_url
# Then check if we have a stored referrer URL
referrer = self.request.session.get('login_referrer')
if referrer:
# Avoid redirecting to password reset pages from stored referrer
if 'reset' not in referrer and 'password_reset' not in referrer:
# Clear the stored referrer to prevent reuse
del self.request.session['login_referrer']
return referrer
@ -24,5 +32,11 @@ class CustomLoginView(auth_views.LoginView):
return reverse('index')
def get(self, request, *args, **kwargs):
# Clear any potential password reset session data
keys_to_clear = [key for key in request.session.keys()
if 'reset' in key or 'password' in key]
for key in keys_to_clear:
del request.session[key]
messages.get_messages(request).used = True
return super().get(request, *args, **kwargs)

@ -48,6 +48,13 @@ class TournamentRegistrationService:
if not self.context['add_player_form'].is_valid():
return
# Clear existing messages if the form is valid
from django.contrib.messages import get_messages
storage = get_messages(self.request)
# Iterate through the storage to clear it
for _ in storage:
pass
player_data = self.context['add_player_form'].cleaned_data
licence_id = player_data.get('licence_id', '').upper()
@ -112,6 +119,12 @@ class TournamentRegistrationService:
self.context['registration_successful'] = True
def handle_get_request(self):
from django.contrib.messages import get_messages
storage = get_messages(self.request)
# Iterate through the storage to clear it
for _ in storage:
pass
self.context['add_player_form'] = AddPlayerForm()
self.context['team_form'] = self.initialize_team_form()
self.initialize_session_data()

@ -20,16 +20,34 @@
{% load static %}
{% load tz %}
{% if form.errors or password_change_form.errors %}
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<label class="title">Mes informations</label>
{% if form.non_field_errors %}
<div class="alert">
{% for error in form.non_field_errors %}
<p>{{ error }}</p>
<div>
{% for field in form %}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert">{{ field.label }} : {{ error }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
<div>
{% for field in password_change_form %}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert">{{ field.label }} : {{ error }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endif %}
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<label class="title">Mes informations</label>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
@ -40,25 +58,7 @@
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<label class="title">Mot de passe</label>
{% if password_change_form.errors %}
<div class="alert">
{% for field, errors in password_change_form.errors.items %}
{% for error in errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{% endif %}
{% if password_change_form.non_field_errors %}
<div class="alert">
{% for error in password_change_form.non_field_errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
<form method="post" action="{% url 'password_change' %}">
<form method="post" action="{% url 'custom_password_change' %}">
{% csrf_token %}
{{ password_change_form.as_p }}
<button type="submit" class="rounded-button">Modifier le mot de passe</button>

@ -28,20 +28,27 @@
{% else %}
{% if team_form.errors %}
<div class="alert alert-error">
{% if team_form.non_field_errors %}
{% for error in team_form.non_field_errors %}
<p>{{ error }}</p>
{% endfor %}
{% endif %}
<div>
{% for field in team_form %}
{% if field.errors %}
{% for error in field.errors %}
<p>{{ error }}</p>
<div class="alert">{{ field.label }} : {{ error }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if messages %}
<div class="messages">
{% for message in messages %}
<div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
<form method="post">
{% csrf_token %}
@ -52,6 +59,12 @@
Informations de contact
</div>
</p>
{% if team_form.non_field_errors %}
{% for error in team_form.non_field_errors %}
<p>{{ error }}</p>
{% endfor %}
{% endif %}
{{ team_form.as_p }} <!-- Render team registration form fields here -->
</div>
@ -124,24 +137,6 @@
{% endif %}
{% endif %}
<div class="margin10">
{% if add_player_form.errors %}
<div class="alert alert-error">
{% if add_player_form.non_field_errors %}
{% for error in add_player_form.non_field_errors %}
<p>{{ error }}</p>
{% endfor %}
{% endif %}
{% for field in add_player_form %}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{% endif %}
</div>
<button type="submit" name="add_player" class="rounded-button">
{% if add_player_form.user_without_licence %}
Confirmer

@ -11,7 +11,7 @@
<div class="grid-x">
<div class="bubble">
<div class="cell medium-6 large-6 my-block">
{% if form.errors %}
{% if form.non_field_errors %}
<div class="alert alert-error">
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
@ -28,7 +28,9 @@
{% endif %}
<form method="post" action="{% url 'custom-login' %}">
{% csrf_token %}
{% if request.GET.next and 'reset' not in request.GET.next and 'password_reset' not in request.GET.next %}
<input type="hidden" name="next" value="{{ request.GET.next }}">
{% endif %}
<label for="username">Identifiant ou e-mail </label>
<input type="text" name="username" id="username" required>

@ -10,9 +10,9 @@
<p>
Votre mot de passe a été réinitialisé avec succès. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe.
</p>
<p>
<div class="topmargin20">
<a href="{% url 'login' %}" class="rounded-button">Se connecter</a>
</p>
</div>
</div>
</div>
</div>

@ -7,17 +7,6 @@
<div class="grid-x">
<div class="bubble">
<div class="cell medium-6 large-6 my-block">
{% if form.errors %}
<div class="alert">
{% for field, errors in form.errors.items %}
{% for error in errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<!-- Add non-field errors (if any) -->
{% if form.non_field_errors %}
<div class="alert">
{% for error in form.non_field_errors %}
@ -35,13 +24,10 @@
<button type="submit" class="rounded-button">Réinitialiser le mot de passe</button>
</form>
<p>
<div class="topmargin20">
<a href="{% url 'login' %}" class="styled-link">Retour à la connexion</a>
</p>
</div>
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

@ -11,9 +11,9 @@
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.
</p>
<p>
<div class="topmargin20">
<a href="{% url 'login' %}" class="styled-link">Retour à la connexion</a>
</p>
</div>
</div>
</div>
</div>

@ -7,16 +7,6 @@
<div class="grid-x">
<div class="bubble">
<div class="cell medium-6 large-6 my-block">
{% if form.errors %}
<div class="alert">
{% for field, errors in form.errors.items %}
{% for error in errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<!-- Add non-field errors (if any) -->
{% if form.non_field_errors %}
<div class="alert">
@ -31,13 +21,10 @@
<input type="email" name="email" id="email" required>
<button type="submit" class="rounded-button">Envoyer le lien de réinitialisation</button>
</form>
<p>
<div class="topmargin20">
<a href="{% url 'login' %}" class="styled-link">Retour à la connexion</a>
</p>
</div>
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

@ -8,20 +8,25 @@
{% load static %}
{% load tz %}
<div class="grid-x">
<div class="bubble">
<div class="cell medium-6 large-6 my-block">
<div class="grid">
{% if form.errors %}
<div class="alert">
{% for field, errors in form.errors.items %}
{% for error in errors %}
<p>{{ error }}</p>
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<div>
{% for field in form %}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert">{{ field.label }} : {{ error }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- Add non-field errors (if any) -->
<div class="cell medium-6 large-6 my-block">
<div class="bubble">
{% if form.non_field_errors %}
<div class="alert">
{% for error in form.non_field_errors %}
@ -36,7 +41,7 @@
<button type="submit" class="rounded-button">Créer votre compte</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

@ -47,12 +47,6 @@
{% if tournament.is_unregistration_possible %}
<p>
<div class="margin10">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
</div>
<a href="{% url 'unregister_tournament' tournament.id %}"
class="rounded-button destructive-button"
onclick="return confirm('Êtes-vous sûr de vouloir vous désinscrire ?');">
@ -164,9 +158,6 @@
</p>
{% endif %}
{% else %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
<p>
<div>
<a href="{% url 'login' %}?next={{ request.path }}" class="styled-link">Connectez-vous !</a>

@ -55,13 +55,7 @@ urlpatterns = [
path('utils/xls-to-csv/', views.xls_to_csv, name='xls-to-csv'),
path('mail-test/', views.simple_form_view, name='mail-test'),
path('login/', CustomLoginView.as_view(), name='custom-login'),
path('password_change/',
auth_views.PasswordChangeView.as_view(
success_url='/profile/', # Redirect back to profile after success
form_class=CustomPasswordChangeForm
),
name='password_change'
),
path('custom_password_change/', views.custom_password_change, name='custom_password_change'),
path('logout/', views.custom_logout, name='custom_logout'),
path('signup/', views.signup, name='signup'), # URL pattern for signup
# path('profile/', views.profile, name='profile'), # URL pattern for signup
@ -70,7 +64,9 @@ urlpatterns = [
path('tournaments/<str:tournament_id>/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'),
path('reset/done/',
views.CustomPasswordResetCompleteView.as_view(),
name='password_reset_complete'),
path('profile/', views.ProfileUpdateView.as_view(), name='profile'),
path('admin/tournament-import/', views.tournament_import_view, name='tournament_import'),
path('admin/status/', views.status_page, name='status_page'),

@ -2,6 +2,11 @@
import os
import csv
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.views import PasswordResetCompleteView
from django.shortcuts import redirect
from django.contrib.auth import login
from django.contrib.auth import get_user_model
from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse, HttpResponse
from django.utils.encoding import force_str
@ -818,6 +823,54 @@ class CustomPasswordResetConfirmView(PasswordResetConfirmView):
except (TypeError, ValueError, User.DoesNotExist):
raise Http404("User not found")
class CustomPasswordResetCompleteView(PasswordResetCompleteView):
template_name = 'registration/password_reset_complete.html'
def get(self, request, *args, **kwargs):
# Get the user from the session
username = request.session.get('reset_username')
if username:
try:
# Get the user
User = get_user_model()
user = User.objects.get(username=username)
# Log the user in
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
# Clean up the session
if 'reset_username' in request.session:
del request.session['reset_username']
# Redirect to the profile page
return redirect('profile')
except User.DoesNotExist:
pass
# If no username in session or user not found, proceed with normal view
return super().get(request, *args, **kwargs)
@login_required
def custom_password_change(request):
if request.method == 'POST':
form = CustomPasswordChangeForm(user=request.user, data=request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important to keep user logged in
messages.success(request, 'Votre mot de passe a été mis à jour avec succès!')
return redirect('profile')
else:
# Form is invalid, show errors
profile_form = ProfileUpdateForm(instance=request.user)
return render(request, 'profile.html', {
'form': profile_form,
'password_change_form': form
})
# If not POST, redirect to profile page
return redirect('profile')
@login_required
def my_tournaments(request):
user = request.user

Loading…
Cancel
Save