From f10497bac3a5d1d12b340f983429b16046e8dce8 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sun, 5 Apr 2020 06:40:03 +0200 Subject: [PATCH] List pending users --- apps/member/forms.py | 2 +- apps/member/models.py | 7 ++++- apps/member/views.py | 2 +- apps/note/signals.py | 11 +++---- apps/registration/tables.py | 23 +++++++++++++++ apps/{member => registration}/tokens.py | 0 apps/registration/urls.py | 5 ++-- apps/registration/views.py | 29 +++++++++++++++++-- templates/base.html | 7 +++++ templates/registration/future_user_list.html | 22 ++++++++++++++ .../{member => registration}/signup.html | 0 11 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 apps/registration/tables.py rename apps/{member => registration}/tokens.py (100%) create mode 100644 templates/registration/future_user_list.html rename templates/{member => registration}/signup.html (100%) diff --git a/apps/member/forms.py b/apps/member/forms.py index 5b20fd15..70ffcf5e 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -26,7 +26,7 @@ class ProfileForm(forms.ModelForm): class Meta: model = Profile fields = '__all__' - exclude = ('user', 'email_confirmed', ) + exclude = ('user', 'email_confirmed', 'registration_valid', ) class ClubForm(forms.ModelForm): diff --git a/apps/member/models.py b/apps/member/models.py index 294643af..46051fe1 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -12,7 +12,7 @@ from django.urls import reverse, reverse_lazy from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from django.utils.translation import gettext_lazy as _ -from member.tokens import account_activation_token +from registration.tokens import account_activation_token from note.models import MembershipTransaction @@ -53,6 +53,11 @@ class Profile(models.Model): default=False, ) + registration_valid = models.BooleanField( + verbose_name=_("registration valid"), + default=False, + ) + email_confirmed = models.BooleanField( verbose_name=_("email confirmed"), default=False, diff --git a/apps/member/views.py b/apps/member/views.py index ac5dd59e..29b16222 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -139,7 +139,7 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): template_name = 'member/user_list.html' def get_queryset(self, **kwargs): - qs = super().get_queryset() + qs = super().get_queryset().filter(profile__registration_valid=True) if "search" in self.request.GET: pattern = self.request.GET["search"] diff --git a/apps/note/signals.py b/apps/note/signals.py index e62115b3..78312682 100644 --- a/apps/note/signals.py +++ b/apps/note/signals.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later -def save_user_note(instance, created, raw, **_kwargs): +def save_user_note(instance, raw, **_kwargs): """ Hook to create and save a note when an user is updated """ @@ -10,10 +10,11 @@ def save_user_note(instance, created, raw, **_kwargs): # When provisionning data, do not try to autocreate return - if created: - from .models import NoteUser - NoteUser.objects.create(user=instance) - instance.note.save() + if instance.profile.registration_valid and instance.is_active: + # Create note only when the registration is validated + from note.models import NoteUser + NoteUser.objects.get_or_create(user=instance) + instance.note.save() def save_club_note(instance, created, raw, **_kwargs): diff --git a/apps/registration/tables.py b/apps/registration/tables.py new file mode 100644 index 00000000..7fd7537f --- /dev/null +++ b/apps/registration/tables.py @@ -0,0 +1,23 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +import django_tables2 as tables +from django.contrib.auth.models import User + + +class FutureUserTable(tables.Table): + phone_number = tables.Column(accessor='profile.phone_number') + + section = tables.Column(accessor='profile.section') + + class Meta: + attrs = { + 'class': 'table table-condensed table-striped table-hover' + } + template_name = 'django_tables2/bootstrap4.html' + fields = ('last_name', 'first_name', 'username', 'email', ) + model = User + row_attrs = { + 'class': 'table-row', + 'data-href': lambda record: record.pk + } diff --git a/apps/member/tokens.py b/apps/registration/tokens.py similarity index 100% rename from apps/member/tokens.py rename to apps/registration/tokens.py diff --git a/apps/registration/urls.py b/apps/registration/urls.py index e752922c..ce2977dc 100644 --- a/apps/registration/urls.py +++ b/apps/registration/urls.py @@ -8,6 +8,7 @@ from . import views app_name = 'registration' urlpatterns = [ path('signup/', views.UserCreateView.as_view(), name="signup"), - path('accounts/activate/sent', views.UserActivationEmailSentView.as_view(), name='account_activation_sent'), - path('accounts/activate//', views.UserActivateView.as_view(), name='account_activation'), + path('validate_email/sent', views.UserActivationEmailSentView.as_view(), name='account_activation_sent'), + path('validate_email//', views.UserActivateView.as_view(), name='account_activation'), + path('validate_user/', views.FutureUserListView.as_view(), name="future_user_list"), ] diff --git a/apps/registration/views.py b/apps/registration/views.py index f4a26c3b..543f2fb9 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django.conf import settings +from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.shortcuts import resolve_url @@ -11,10 +12,13 @@ from django.utils.http import urlsafe_base64_decode from django.utils.translation import gettext_lazy as _ from django.views.decorators.csrf import csrf_protect from django.views.generic import CreateView, TemplateView +from django_tables2 import SingleTableView from member.forms import ProfileForm -from member.tokens import account_activation_token +from permission.views import ProtectQuerysetMixin from .forms import SignUpForm +from .tables import FutureUserTable +from .tokens import account_activation_token class UserCreateView(CreateView): @@ -23,8 +27,8 @@ class UserCreateView(CreateView): """ form_class = SignUpForm - success_url = reverse_lazy('member:login') - template_name = 'member/signup.html' + success_url = reverse_lazy('registration:account_activation_sent') + template_name = 'registration/signup.html' second_form = ProfileForm def get_context_data(self, **kwargs): @@ -108,3 +112,22 @@ class UserActivationEmailSentView(TemplateView): template_name = 'registration/account_activation_email_sent.html' title = _('Account activation email sent') + +class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): + """ + Affiche la liste des utilisateurs, avec une fonction de recherche statique + """ + model = User + table_class = FutureUserTable + template_name = 'registration/future_user_list.html' + + def get_queryset(self, **kwargs): + return super().get_queryset().filter(profile__registration_valid=False) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context["title"] = _("Unregistered users") + + return context + diff --git a/templates/base.html b/templates/base.html index 8e16a419..3c2c637f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -94,6 +94,13 @@ SPDX-License-Identifier: GPL-3.0-or-later {% trans 'Clubs' %} {% endif %} + {% if "member.change_profile_registration_valid"|has_perm:user %} + + {% endif %} {% if "activity.activity"|not_empty_model_list %}