Ajout de la gestion de l'activation des comptes utilisateur par e-mail, des validations pour les pseudos existants, et configuration par défaut de l'e-mail backend.
This commit is contained in:
parent
ca0211e841
commit
fc4939577a
5 changed files with 74 additions and 4 deletions
|
|
@ -203,3 +203,6 @@ def get_git_version():
|
|||
return "Version inconnue (Fichier manquant)"
|
||||
|
||||
GIT_VERSION = get_git_version()
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
DEFAULT_FROM_EMAIL = 'noreply@partirdezero.local'
|
||||
|
|
@ -27,7 +27,15 @@ class UserRegistrationForm(forms.Form):
|
|||
password2 = cleaned_data.get("password2")
|
||||
|
||||
if password1 and password2 and password1 != password2:
|
||||
raise forms.ValidationError("Passwords do not match")
|
||||
raise forms.ValidationError("Les mots de passe ne correspondent pas.")
|
||||
|
||||
return cleaned_data
|
||||
|
||||
def clean_username(self):
|
||||
username = self.cleaned_data.get('username')
|
||||
if username and User.objects.filter(username__iexact=username).exists():
|
||||
raise forms.ValidationError("Ce pseudo est déjà pris. Veuillez en choisir un autre.")
|
||||
return username
|
||||
|
||||
class UserLoginForm(forms.Form):
|
||||
username = forms.CharField(
|
||||
|
|
|
|||
4
users/tokens.py
Normal file
4
users/tokens.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||
|
||||
# Générateur de tokens pour l'activation de compte
|
||||
activation_token = PasswordResetTokenGenerator()
|
||||
|
|
@ -7,6 +7,8 @@ urlpatterns = [
|
|||
path('', views.register, name='register'),
|
||||
path('login/', views.login, name='login'),
|
||||
path('logout/', views.logout, name='logout'),
|
||||
# Activation de compte par lien tokenisé
|
||||
path('activate/<uidb64>/<token>/', views.activate, name='activate'),
|
||||
path('profile/view/<int:user_id>/', views.another_profile, name='another_profile'),
|
||||
path('complete-profile/', views.complete_profile, name='complete_profile'),
|
||||
path('profile/', views.profile, name='profile'),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ from django.contrib.auth.models import User
|
|||
from courses.models import Course
|
||||
from .forms import UserRegistrationForm, UserLoginForm, UserUpdateForm, ProfileUpdateForm, CompleteProfileForm
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.mail import send_mail
|
||||
from django.urls import reverse
|
||||
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||||
from django.utils.encoding import force_bytes
|
||||
from .tokens import activation_token
|
||||
|
||||
def register(request):
|
||||
# Si l'utilisateur est deja connecté, on le redirige vers la page de profil
|
||||
|
|
@ -13,13 +18,36 @@ def register(request):
|
|||
if request.method == 'POST':
|
||||
form = UserRegistrationForm(request.POST)
|
||||
if form.is_valid():
|
||||
# Crée un utilisateur inactif en attente d'activation par e‑mail
|
||||
user = User.objects.create_user(
|
||||
username=form.cleaned_data['username'],
|
||||
email=form.cleaned_data['email'],
|
||||
password=form.cleaned_data['password1']
|
||||
)
|
||||
auth_login(request, user)
|
||||
return redirect('profile')
|
||||
user.is_active = False
|
||||
user.save()
|
||||
|
||||
# Envoi du lien d'activation par e‑mail
|
||||
uid = urlsafe_base64_encode(force_bytes(user.pk))
|
||||
token = activation_token.make_token(user)
|
||||
activation_link = request.build_absolute_uri(
|
||||
reverse('activate', kwargs={'uidb64': uid, 'token': token})
|
||||
)
|
||||
subject = 'Active ton compte sur partirdezero'
|
||||
message = (
|
||||
'Bienvenue !\n\n'
|
||||
'Pour activer ton compte, clique sur le lien suivant (valide pendant une durée limitée) :\n'
|
||||
f'{activation_link}\n\n'
|
||||
"Si tu n'es pas à l'origine de cette inscription, ignore ce message."
|
||||
)
|
||||
try:
|
||||
send_mail(subject, message, None, [user.email], fail_silently=True)
|
||||
except Exception:
|
||||
# Même si l'envoi échoue, on n'interrompt pas le flux; un admin vérifiera la config e‑mail
|
||||
pass
|
||||
|
||||
messages.success(request, "Inscription réussie. Vérifie ta boîte mail pour activer ton compte.")
|
||||
return redirect('login')
|
||||
else:
|
||||
form = UserRegistrationForm()
|
||||
return render(request, 'users/register.html', {'form': form})
|
||||
|
|
@ -32,8 +60,15 @@ def login(request):
|
|||
password = form.cleaned_data['password']
|
||||
user = authenticate(request, username=username, password=password)
|
||||
if user is not None:
|
||||
if not user.is_active:
|
||||
messages.error(request, "Votre compte n'est pas encore activé. Consultez l'e‑mail d'activation envoyé." )
|
||||
return render(request, 'users/login.html', {'form': form})
|
||||
auth_login(request, user)
|
||||
return redirect('profile')
|
||||
else:
|
||||
# Identifiants invalides: avertir l'utilisateur
|
||||
messages.error(request, "Nom d'utilisateur ou mot de passe incorrect.")
|
||||
return render(request, 'users/login.html', {'form': form})
|
||||
else:
|
||||
form = UserLoginForm()
|
||||
return render(request, 'users/login.html', {'form': form})
|
||||
|
|
@ -106,3 +141,21 @@ def create_post(request):
|
|||
def another_profile(request, user_id):
|
||||
user = User.objects.get(id=user_id)
|
||||
return render(request, 'users/another_profile.html', {'user': user})
|
||||
|
||||
# Activation de compte via lien tokenisé
|
||||
def activate(request, uidb64, token):
|
||||
try:
|
||||
uid = urlsafe_base64_decode(uidb64).decode()
|
||||
user = User.objects.get(pk=uid)
|
||||
except Exception:
|
||||
user = None
|
||||
|
||||
if user and activation_token.check_token(user, token):
|
||||
if not user.is_active:
|
||||
user.is_active = True
|
||||
user.save()
|
||||
messages.success(request, 'Votre compte a été activé. Vous pouvez maintenant vous connecter.')
|
||||
return redirect('login')
|
||||
|
||||
messages.error(request, "Lien d'activation invalide ou expiré. Demandez un nouveau lien ou inscrivez‑vous à nouveau.")
|
||||
return redirect('register')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue