1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2024-11-26 18:37:12 +00:00

Invalidate registrations, fix profile creation

This commit is contained in:
Yohann D'ANELLO 2020-04-05 08:01:51 +02:00
parent f10497bac3
commit b1cd46bf7d
8 changed files with 121 additions and 21 deletions

View File

@ -10,7 +10,7 @@ def save_user_profile(instance, created, raw, **_kwargs):
# When provisionning data, do not try to autocreate # When provisionning data, do not try to autocreate
return return
if created: if created and instance.is_active:
from .models import Profile from .models import Profile
Profile.objects.get_or_create(user=instance) Profile.objects.get_or_create(user=instance)
instance.profile.save() instance.profile.save()

View File

@ -102,11 +102,8 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
return super().form_valid(form) return super().form_valid(form)
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
if kwargs: url = 'member:user_detail' if self.object.profile.registration_valid else 'registration:future_user_detail'
return reverse_lazy('member:user_detail', return reverse_lazy(url, args=(self.object.id,))
kwargs={'pk': kwargs['id']})
else:
return reverse_lazy('member:user_detail', args=(self.object.id,))
class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
@ -117,6 +114,12 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
context_object_name = "user_object" context_object_name = "user_object"
template_name = "member/profile_detail.html" 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): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
user = context['user_object'] user = context['user_object']

View File

@ -8,7 +8,9 @@ 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.UserActivationEmailSentView.as_view(), name='account_activation_sent'),
path('validate_email/<uidb64>/<token>', views.UserActivateView.as_view(), name='account_activation'), path('validate_email/<uidb64>/<token>/', views.UserActivateView.as_view(), name='account_activation'),
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>/invalidate/', views.FutureUserInvalidateView.as_view(), name="future_user_invalidate"),
] ]

View File

@ -5,15 +5,18 @@ from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError 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.urls import reverse_lazy
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.http import urlsafe_base64_decode from django.utils.http import urlsafe_base64_decode
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.decorators.csrf import csrf_protect 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 django_tables2 import SingleTableView
from member.forms import ProfileForm from member.forms import ProfileForm
from member.models import Profile
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin from permission.views import ProtectQuerysetMixin
from .forms import SignUpForm 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 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. 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(): if not profile_form.is_valid():
return self.form_invalid(form) return self.form_invalid(form)
user = form.save(commit=False) user = form.save(commit=False)
user.is_active = 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.save()
user.profile.save() user.refresh_from_db()
profile.user = user
profile.save()
user.profile.send_email_validation_link() user.profile.send_email_validation_link()
@ -86,7 +93,6 @@ class UserActivateView(TemplateView):
return self.render_to_response(self.get_context_data()) return self.render_to_response(self.get_context_data())
def get_user(self, uidb64): def get_user(self, uidb64):
print(uidb64)
try: try:
# urlsafe_base64_decode() decodes to bytestring # urlsafe_base64_decode() decodes to bytestring
uid = urlsafe_base64_decode(uidb64).decode() uid = urlsafe_base64_decode(uidb64).decode()
@ -131,3 +137,32 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
return context 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')

View File

@ -53,7 +53,7 @@ ProductFormSet = forms.inlineformset_factory(
class ProductFormSetHelper(FormHelper): class ProductFormSetHelper(FormHelper):
""" """
Specify some template informations for the product form. Specify some template information for the product form.
""" """
def __init__(self, form=None): def __init__(self, form=None):

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 '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. This link is only valid for a couple of days, after that you will need to contact us to validate your email.

View File

@ -0,0 +1,54 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load pretty_money %}
{% block content %}
<div class="card bg-light shadow">
<div class="card-header text-center" >
<h4> {% trans "Account #" %} {{ object.pk }}</h4>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
<dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
<dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.username }}</dd>
<dt class="col-xl-6">{% trans 'email'|capfirst %}</dt>
<dd class="col-xl-6"><a href="mailto:{{ object.email }}">{{ object.email }}</a></dd>
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}">
{% trans 'Change password' %}
</a>
</dd>
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.section }}</dd>
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.address }}</dd>
<dt class="col-xl-6">{% trans 'phone number'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.phone_number }}</dd>
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.paid|yesno }}</dd>
</dl>
{% if object.pk == user.pk %}
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
{% endif %}
</div>
<div class="card-footer text-center">
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
<a class="btn btn-danger btn-sm" href="{% url 'registration:future_user_invalidate' object.pk %}">{% trans 'Delete registration' %}</a>
</div>
</div>
{% endblock %}

View File

@ -4,13 +4,19 @@
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<div id="user_table"> <a href="{% url 'registration:signup' %}"><button class="btn btn-primary btn-block">{% trans "New user" %}</button></a>
{% render_table table %}
</div>
<hr> <hr>
<a href="{% url 'registration:signup' %}"><button class="btn btn-primary btn-block">{% trans "New user" %}</button></a> {% if table.data %}
<div id="user_table">
{% render_table table %}
</div>
{% else %}
<div class="alert alert-warning">
{% trans "There is no pending user." %}
</div>
{% endif %}
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block extrajavascript %}