Skip to content
Snippets Groups Projects
Commit 611a1017 authored by Dorian Lesbre's avatar Dorian Lesbre
Browse files

Added change password options

parent 35f1b0af
No related branches found
No related tags found
No related merge requests found
from django import forms
from django.contrib.auth import authenticate, password_validation
from django.contrib.auth.forms import UserCreationForm
from django.utils.safestring import mark_safe
from accounts.models import EmailUser
def password_criterions_html():
"""Wraps password criterions into nice html used by other forms"""
def wrap_str(s, tagopen, tagclose=None):
if not tagclose:
tagclose = tagopen
return "<{}>{}</{}>".format(tagopen, s, tagclose)
criterions = password_validation.password_validators_help_texts()
criterions_html = wrap_str(
"\n".join(map(lambda crit: wrap_str(crit, "li"), criterions)),
'ul class="helptext"',
"ul",
)
return mark_safe(criterions_html)
class FormRenderMixin:
""" A mixin that can be included in any form to make it render to html as we want
......@@ -163,6 +178,57 @@ class UpdateAccountForm(FormRenderMixin, forms.ModelForm):
user.username = email
if email_changed:
user.email_confirmed = False
user.is_active = False
if commit:
user.save()
return user
class UpdatePasswordForm(FormRenderMixin, forms.Form):
""" Form to update one's password """
current_password = forms.CharField(
widget=forms.PasswordInput, label="Mot de passe actuel",
)
password = forms.CharField(
widget=forms.PasswordInput,
help_text=password_criterions_html(),
label="Nouveau mot de passe",
)
password_confirm = forms.CharField(
widget=forms.PasswordInput, label="Nouveau mot de passe (confirmation)",
)
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
super().__init__(*args, **kwargs)
def clean_current_password(self):
""" Check current password correctness """
cur_password = self.cleaned_data["current_password"]
if authenticate(username=self.user.email, password=cur_password) != self.user:
raise forms.ValidationError("Votre mot de passe actuel est incorrect.")
return cur_password
def clean_password(self):
""" Check password strength """
password = self.cleaned_data["password"]
password_validation.validate_password(password)
return password
def clean_password_confirm(self):
""" Check that both passwords match """
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_confirm = cleaned_data.get("password_confirm")
if not password:
return None
if password != password_confirm:
raise forms.ValidationError(
"Les deux mots de passe ne sont pas identiques."
)
return cleaned_data
def apply(self):
""" Apply the password change, assuming validation was already passed """
self.user.set_password(self.cleaned_data["password"])
self.user.save()
{% autoescape off %}
Bonjour {{ user.first_name }} {{ user.last_name }},
Veuillez suivre le lien ci dessous pour valider votre compte :
Veuillez suivre le lien ci-dessous pour valider votre compte :
http://{{ domain }}{% url 'accounts:activate' uidb64=uid token=token %}
{% endautoescape %}
{% autoescape off %}
Bonjour {{ user.first_name }} {{ user.last_name }},
Veuillez suivre le lien ci dessous pour valider le changement d'adresse email :
http://{{ domain }}{% url 'accounts:activate' uidb64=uid token=token %}
{% endautoescape %}
......@@ -16,8 +16,6 @@
<p><a href="{% url 'accounts:update' %}">Modifier mes informations</a></p>
<p><a href="TODO">Changer mom mot de passe</a></p>
<p><a class="button" href="{% url 'accounts:logout' %}">Déconnexion</a></p>
{% endblock %}
\ No newline at end of file
......@@ -5,7 +5,16 @@
<form method="post" action="{% url 'accounts:update' %}">
{% csrf_token %}
{{ form.as_html }}
{{ update_form.as_html }}
<br>
<input type="submit" value="Valider">
</form>
<h2>Changer mon mot de passe</h2>
<form method="post" action="{% url 'accounts:change_password' %}">
{% csrf_token %}
{{ password_form.as_html }}
<br>
<input type="submit" value="Valider">
</form>
......
......@@ -10,5 +10,6 @@ urlpatterns = [
path("profile/", views.ProfileView.as_view(), name="profile"),
path("create/", views.CreateAccountView.as_view(), name="create"),
path("update/", views.UpdateAccountView.as_view(), name="update"),
path("change_password/", views.UpdatePasswordView.as_view(), name="change_password"),
path('activate/<uidb64>/<token>/', views.ActivateAccountView.as_view(), name='activate'),
]
......@@ -8,14 +8,26 @@ from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.urls import reverse
from django.template.loader import render_to_string
from django.views.generic import RedirectView, TemplateView, UpdateView, View
from django.views.generic import FormView, RedirectView, TemplateView, UpdateView, View
from django.shortcuts import render, redirect
from accounts.forms import CreateAccountForm, UpdateAccountForm
from accounts.forms import CreateAccountForm, UpdateAccountForm, UpdatePasswordForm
from accounts.models import EmailUser
from accounts.tokens import email_token_generator
from site_settings.models import SiteSettings
def send_validation_email(request, user, subject, template):
"""Send a validation email to user"""
current_site = get_current_site(request)
message = render_to_string(template, {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': email_token_generator.make_token(user),
})
user.email_user(subject, message)
class LoginView(DjangoLoginView):
"""Vue pour se connecter"""
template_name = "login.html"
......@@ -71,15 +83,7 @@ class CreateAccountView(View):
user.email_confirmed = False
user.save()
current_site = get_current_site(request)
subject = 'Activation de votre compte Interludes'
message = render_to_string('activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': email_token_generator.make_token(user),
})
user.email_user(subject, message)
send_validation_email(request, user, "Activer votre compte Interludes", "activation_email.html")
messages.info(request, 'Un lien vous a été envoyé par mail. Utilisez le pour finaliser la création de compte.')
......@@ -127,18 +131,50 @@ class UpdateAccountView(LoginRequiredMixin, UpdateView):
def get_object(self):
return self.request.user
# def get_context_data(self, **kwargs):
# context = super().get_context_data(**kwargs)
# context["change_password_form"] = registration_forms.UpdatePasswordForm(
# user=self.request.user
# )
# return context
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["update_form"] = context["form"]
context["password_form"] = UpdatePasswordForm(
user=self.request.user
)
return context
def get_success_url(self):
# if not self.request.user.email_confirmed:
if not self.request.user.email_confirmed:
send_validation_email(
self.request, self.request.user,
"Valider le changement d'email de votre compte Interludes",
"change_email.html"
)
messages.info(self.request, 'Un lien vous a été envoyé par mail. Utilisez le pour valider la mise à jour.')
# return reverse("registration:email_confirmation_needed")
return reverse("accounts:profile")
def form_valid(self, form):
messages.success(self.request, "Informations personnelles mises à jour")
return super().form_valid(form)
class UpdatePasswordView(LoginRequiredMixin, FormView):
""" Change a user's password """
template_name = "update.html"
form_class = UpdatePasswordForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["password_form"] = context["form"]
context["update_form"] = UpdateAccountForm(instance=self.request.user)
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user
return kwargs
def form_valid(self, form):
form.apply()
messages.success(self.request, "Mot de passe mis à jour")
return redirect("accounts:profile")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment