Add links to resend mail confirmations

This commit is contained in:
Yohann D'ANELLO 2020-04-05 09:48:23 +02:00
parent fbc25240e6
commit 3516b1fa04
9 changed files with 51 additions and 16 deletions

View File

@ -12,7 +12,7 @@ from django.urls import reverse, reverse_lazy
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode from django.utils.http import urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from registration.tokens import account_activation_token from registration.tokens import email_validation_token
from note.models import MembershipTransaction from note.models import MembershipTransaction
@ -73,13 +73,13 @@ class Profile(models.Model):
def send_email_validation_link(self): def send_email_validation_link(self):
subject = "Activate your Note Kfet account" subject = "Activate your Note Kfet account"
message = loader.render_to_string('registration/account_activation_email.html', message = loader.render_to_string('registration/email_validation_email.html',
{ {
'user': self.user, 'user': self.user,
'domain': "nk20.ynerant.fr", 'domain': "nk20.ynerant.fr",
'site_name': "La Note Kfet", 'site_name': "La Note Kfet",
'protocol': 'https', 'protocol': 'https',
'token': account_activation_token.make_token(self.user), 'token': email_validation_token.make_token(self.user),
'uid': urlsafe_base64_encode(force_bytes(self.user.pk)).decode('UTF-8'), 'uid': urlsafe_base64_encode(force_bytes(self.user.pk)).decode('UTF-8'),
}) })
self.user.email_user(subject, message) self.user.email_user(subject, message)

View File

@ -27,4 +27,4 @@ class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
return str(user.pk) + str(user.profile.email_confirmed) + str(login_timestamp) + str(timestamp) return str(user.pk) + str(user.profile.email_confirmed) + str(login_timestamp) + str(timestamp)
account_activation_token = AccountActivationTokenGenerator() email_validation_token = AccountActivationTokenGenerator()

View File

@ -8,8 +8,10 @@ from . import views
app_name = 'registration' app_name = 'registration'
urlpatterns = [ urlpatterns = [
path('signup/', views.UserCreateView.as_view(), name="signup"), path('signup/', views.UserCreateView.as_view(), name="signup"),
path('validate_email/sent/', views.UserActivationEmailSentView.as_view(), name='account_activation_sent'), path('validate_email/sent/', views.UserValidationEmailSentView.as_view(), name='email_validation_sent'),
path('validate_email/<uidb64>/<token>/', views.UserActivateView.as_view(), name='account_activation'), path('validate_email/resend/<int:pk>/', views.UserResendValidationEmailView.as_view(),
name='email_validation_resend'),
path('validate_email/<uidb64>/<token>/', views.UserValidateView.as_view(), name='email_validation'),
path('validate_user/', views.FutureUserListView.as_view(), name="future_user_list"), path('validate_user/', views.FutureUserListView.as_view(), name="future_user_list"),
path('validate_user/<int:pk>/', views.FutureUserDetailView.as_view(), name="future_user_detail"), path('validate_user/<int:pk>/', views.FutureUserDetailView.as_view(), name="future_user_detail"),
path('validate_user/<int:pk>/invalidate/', views.FutureUserInvalidateView.as_view(), name="future_user_invalidate"), path('validate_user/<int:pk>/invalidate/', views.FutureUserInvalidateView.as_view(), name="future_user_invalidate"),

View File

@ -16,14 +16,14 @@ from django.views.generic import CreateView, TemplateView, DetailView, FormView
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from member.forms import ProfileForm from member.forms import ProfileForm
from member.models import Membership, Club from member.models import Membership, Club
from note.models import SpecialTransaction from note.models import SpecialTransaction, Transaction
from note.templatetags.pretty_money import pretty_money from note.templatetags.pretty_money import pretty_money
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin from permission.views import ProtectQuerysetMixin
from .forms import SignUpForm, ValidationForm from .forms import SignUpForm, ValidationForm
from .tables import FutureUserTable from .tables import FutureUserTable
from .tokens import account_activation_token from .tokens import email_validation_token
class UserCreateView(CreateView): class UserCreateView(CreateView):
@ -32,7 +32,7 @@ class UserCreateView(CreateView):
""" """
form_class = SignUpForm form_class = SignUpForm
success_url = reverse_lazy('registration:account_activation_sent') success_url = reverse_lazy('registration:email_validation_sent')
template_name = 'registration/signup.html' template_name = 'registration/signup.html'
second_form = ProfileForm second_form = ProfileForm
@ -66,9 +66,9 @@ class UserCreateView(CreateView):
return super().form_valid(form) return super().form_valid(form)
class UserActivateView(TemplateView): class UserValidateView(LoginRequiredMixin, ProtectQuerysetMixin, TemplateView):
title = _("Account Activation") title = _("Account Activation")
template_name = 'registration/account_activation_complete.html' template_name = 'registration/email_validation_complete.html'
@method_decorator(csrf_protect) @method_decorator(csrf_protect)
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
@ -84,7 +84,7 @@ class UserActivateView(TemplateView):
user = self.get_user(kwargs['uidb64']) user = self.get_user(kwargs['uidb64'])
token = kwargs['token'] token = kwargs['token']
if user is not None and account_activation_token.check_token(user, token): if user is not None and email_validation_token.check_token(user, token):
self.validlink = True self.validlink = True
user.is_active = True user.is_active = True
user.profile.email_confirmed = True user.profile.email_confirmed = True
@ -116,11 +116,26 @@ class UserActivateView(TemplateView):
return context return context
class UserActivationEmailSentView(TemplateView): class UserValidationEmailSentView(LoginRequiredMixin, ProtectQuerysetMixin, TemplateView):
template_name = 'registration/account_activation_email_sent.html' template_name = 'registration/email_validation_email_sent.html'
title = _('Account activation email sent') title = _('Account activation email sent')
class UserResendValidationEmailView(LoginRequiredMixin, ProtectQuerysetMixin, DetailView):
model = User
def get_queryset(self, **kwargs):
return super().get_queryset(**kwargs).filter(profile__email_confirmed=False)
def get(self, request, *args, **kwargs):
user = self.get_object()
user.profile.send_email_validation_link()
url = 'member:user_detail' if user.profile.registration_valid else 'registration:future_user_detail'
return redirect(url, user.id)
class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
""" """
Affiche la liste des utilisateurs, avec une fonction de recherche statique Affiche la liste des utilisateurs, avec une fonction de recherche statique

View File

@ -1,5 +1,14 @@
{% load render_table from django_tables2 %} {% load render_table from django_tables2 %}
{% load i18n %} {% load i18n %}
{% load perms %}
{% if not object.profile.email_confirmed and "member.change_profile_email_confirmed"|has_perm:object.profile %}
<div class="alert alert-warning">
{% trans "This user doesn't have confirmed his/her e-mail address." %}
<a href="{% url "registration:email_validation_resend" pk=object.pk %}">{% trans "Click here to resend a validation link." %}</a>
</div>
{% endif %}
<div class="accordion shadow" id="accordionProfile"> <div class="accordion shadow" id="accordionProfile">
<div class="card"> <div class="card">
<div class="card-header position-relative" id="clubListHeading"> <div class="card-header position-relative" id="clubListHeading">

View File

@ -2,7 +2,7 @@ Hi {{ user.username }},
Welcome to {{ site_name }}. Please click on the link below to confirm your registration. Welcome to {{ site_name }}. Please click on the link below to confirm your registration.
{{ protocol }}://{{ domain }}{% url 'registration:account_activation' uidb64=uid token=token %} {{ protocol }}://{{ domain }}{% url 'registration:email_validation' uidb64=uid token=token %}
This link is only valid for a couple of days, after that you will need to contact us to validate your email. This link is only valid for a couple of days, after that you will need to contact us to validate your email.

View File

@ -2,7 +2,7 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load pretty_money %} {% load perms %}
{% block content %} {% block content %}
<div class="card bg-light shadow"> <div class="card bg-light shadow">
@ -20,6 +20,15 @@
<dt class="col-xl-6">{% trans 'email'|capfirst %}</dt> <dt class="col-xl-6">{% trans 'email'|capfirst %}</dt>
<dd class="col-xl-6"><a href="mailto:{{ object.email }}">{{ object.email }}</a></dd> <dd class="col-xl-6"><a href="mailto:{{ object.email }}">{{ object.email }}</a></dd>
{% if not object.profile.email_confirmed and "member.change_profile_email_confirmed"|has_perm:object.profile %}
<dd class="col-xl-12">
<div class="alert alert-warning">
{% trans "This user doesn't have confirmed his/her e-mail address." %}
<a href="{% url "registration:email_validation_resend" pk=object.pk %}">{% trans "Click here to resend a validation link." %}</a>
</div>
</dd>
{% endif %}
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt> <dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6"> <dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}"> <a class="small" href="{% url 'password_change' %}">