From b1cd46bf7de7533078ba34b59072fac05950d7cc Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sun, 5 Apr 2020 08:01:51 +0200 Subject: [PATCH] Invalidate registrations, fix profile creation --- apps/member/signals.py | 4 +- apps/member/views.py | 13 +++-- apps/registration/urls.py | 6 ++- apps/registration/views.py | 47 +++++++++++++--- apps/treasury/forms.py | 2 +- .../account_activation_email.html | 2 +- .../registration/future_profile_detail.html | 54 +++++++++++++++++++ templates/registration/future_user_list.html | 14 +++-- 8 files changed, 121 insertions(+), 21 deletions(-) create mode 100644 templates/registration/future_profile_detail.html diff --git a/apps/member/signals.py b/apps/member/signals.py index 2b03e3ce..fbb66c1f 100644 --- a/apps/member/signals.py +++ b/apps/member/signals.py @@ -10,7 +10,7 @@ def save_user_profile(instance, created, raw, **_kwargs): # When provisionning data, do not try to autocreate return - if created: + if created and instance.is_active: from .models import Profile Profile.objects.get_or_create(user=instance) - instance.profile.save() + instance.profile.save() diff --git a/apps/member/views.py b/apps/member/views.py index 29b16222..ed5826ef 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -102,11 +102,8 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): return super().form_valid(form) def get_success_url(self, **kwargs): - if kwargs: - return reverse_lazy('member:user_detail', - kwargs={'pk': kwargs['id']}) - else: - return reverse_lazy('member:user_detail', args=(self.object.id,)) + url = 'member:user_detail' if self.object.profile.registration_valid else 'registration:future_user_detail' + return reverse_lazy(url, args=(self.object.id,)) class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): @@ -117,6 +114,12 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): context_object_name = "user_object" template_name = "member/profile_detail.html" + def get_queryset(self, **kwargs): + """ + We can't display information of a not registered user. + """ + return super().get_queryset().filter(profile__registration_valid=True) + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = context['user_object'] diff --git a/apps/registration/urls.py b/apps/registration/urls.py index ce2977dc..ae9b2fca 100644 --- a/apps/registration/urls.py +++ b/apps/registration/urls.py @@ -8,7 +8,9 @@ from . import views app_name = 'registration' urlpatterns = [ path('signup/', views.UserCreateView.as_view(), name="signup"), - path('validate_email/sent', views.UserActivationEmailSentView.as_view(), name='account_activation_sent'), - path('validate_email//', 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"), + path('validate_user//', views.FutureUserDetailView.as_view(), name="future_user_detail"), + path('validate_user//invalidate/', views.FutureUserInvalidateView.as_view(), name="future_user_invalidate"), ] diff --git a/apps/registration/views.py b/apps/registration/views.py index 543f2fb9..7f06f92f 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -5,15 +5,18 @@ 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 +from django.shortcuts import resolve_url, redirect from django.urls import reverse_lazy from django.utils.decorators import method_decorator from django.utils.http import urlsafe_base64_decode from django.utils.translation import gettext_lazy as _ +from django.views import View from django.views.decorators.csrf import csrf_protect -from django.views.generic import CreateView, TemplateView +from django.views.generic import CreateView, TemplateView, DetailView from django_tables2 import SingleTableView from member.forms import ProfileForm +from member.models import Profile +from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin from .forms import SignUpForm @@ -42,15 +45,19 @@ class UserCreateView(CreateView): If the form is valid, then the user is created with is_active set to False so that the user cannot log in until the email has been validated. """ - profile_form = ProfileForm(self.request.POST) + profile_form = ProfileForm(data=self.request.POST) if not profile_form.is_valid(): return self.form_invalid(form) user = form.save(commit=False) user.is_active = False - user.profile = profile_form.save(commit=False) + profile_form.instance.user = user + profile = profile_form.save(commit=False) + user.profile = profile user.save() - user.profile.save() + user.refresh_from_db() + profile.user = user + profile.save() user.profile.send_email_validation_link() @@ -86,7 +93,6 @@ class UserActivateView(TemplateView): return self.render_to_response(self.get_context_data()) def get_user(self, uidb64): - print(uidb64) try: # urlsafe_base64_decode() decodes to bytestring uid = urlsafe_base64_decode(uidb64).decode() @@ -131,3 +137,32 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi return context + +class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): + """ + Affiche les informations sur un utilisateur, sa note, ses clubs... + """ + model = User + context_object_name = "user_object" + template_name = "registration/future_profile_detail.html" + + def get_queryset(self, **kwargs): + """ + We only display information of a not registered user. + """ + return super().get_queryset().filter(profile__registration_valid=False) + + +class FutureUserInvalidateView(ProtectQuerysetMixin, LoginRequiredMixin, View): + """ + Affiche les informations sur un utilisateur, sa note, ses clubs... + """ + + def dispatch(self, request, *args, **kwargs): + user = User.objects.filter(profile__registration_valid=False)\ + .filter(PermissionBackend.filter_queryset(request.user, User, "change", "is_valid"))\ + .get(pk=self.kwargs["pk"]) + + user.delete() + + return redirect('registration:future_user_list') diff --git a/apps/treasury/forms.py b/apps/treasury/forms.py index ad479e14..b09a46c7 100644 --- a/apps/treasury/forms.py +++ b/apps/treasury/forms.py @@ -53,7 +53,7 @@ ProductFormSet = forms.inlineformset_factory( class ProductFormSetHelper(FormHelper): """ - Specify some template informations for the product form. + Specify some template information for the product form. """ def __init__(self, form=None): diff --git a/templates/registration/account_activation_email.html b/templates/registration/account_activation_email.html index e8f2032d..252b83c7 100644 --- a/templates/registration/account_activation_email.html +++ b/templates/registration/account_activation_email.html @@ -2,7 +2,7 @@ Hi {{ user.username }}, Welcome to {{ site_name }}. Please click on the link below to confirm your registration. -{{ protocol }}://{{ domain }}{% url 'member:account_activation' uidb64=uid token=token %} +{{ protocol }}://{{ domain }}{% url 'registration:account_activation' 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. diff --git a/templates/registration/future_profile_detail.html b/templates/registration/future_profile_detail.html new file mode 100644 index 00000000..9b7449e2 --- /dev/null +++ b/templates/registration/future_profile_detail.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} +{% load static %} +{% load i18n %} +{% load render_table from django_tables2 %} +{% load pretty_money %} + +{% block content %} + +
+
+

{% trans "Account #" %} {{ object.pk }}

+
+
+
+
{% trans 'name'|capfirst %}, {% trans 'first name' %}
+
{{ object.last_name }} {{ object.first_name }}
+ +
{% trans 'username'|capfirst %}
+
{{ object.username }}
+ +
{% trans 'email'|capfirst %}
+
{{ object.email }}
+ +
{% trans 'password'|capfirst %}
+
+ + {% trans 'Change password' %} + +
+ +
{% trans 'section'|capfirst %}
+
{{ object.profile.section }}
+ +
{% trans 'address'|capfirst %}
+
{{ object.profile.address }}
+ +
{% trans 'phone number'|capfirst %}
+
{{ object.profile.phone_number }}
+ +
{% trans 'paid'|capfirst %}
+
{{ object.profile.paid|yesno }}
+
+ + {% if object.pk == user.pk %} + {% trans 'Manage auth token' %} + {% endif %} +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/registration/future_user_list.html b/templates/registration/future_user_list.html index e500ee19..490fe2ab 100644 --- a/templates/registration/future_user_list.html +++ b/templates/registration/future_user_list.html @@ -4,13 +4,19 @@ {% load i18n %} {% block content %} -
- {% render_table table %} -
+
- + {% if table.data %} +
+ {% render_table table %} +
+ {% else %} +
+ {% trans "There is no pending user." %} +
+ {% endif %} {% endblock %} {% block extrajavascript %}