mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-03 17:08:47 +01:00 
			
		
		
		
	Add links to resend mail confirmations
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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' %}">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user