mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 07:02:10 +01:00 
			
		
		
		
	Upload all authorizations
This commit is contained in:
		@@ -1,7 +1,6 @@
 | 
			
		||||
# Copyright (C) 2020 by Animath
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
from address.forms import AddressField
 | 
			
		||||
from address.widgets import AddressWidget
 | 
			
		||||
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.contrib.auth.forms import UserCreationForm
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
@@ -69,7 +68,8 @@ class StudentRegistrationForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = StudentRegistration
 | 
			
		||||
        fields = ('team', 'student_class', 'birth_date', 'address', 'phone_number',
 | 
			
		||||
                  'school', 'give_contact_to_animath', 'email_confirmed',)
 | 
			
		||||
                  'school', 'responsible_name', 'responsible_phone', 'responsible_email',
 | 
			
		||||
                  'give_contact_to_animath', 'email_confirmed',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PhotoAuthorizationForm(forms.ModelForm):
 | 
			
		||||
@@ -94,6 +94,50 @@ class PhotoAuthorizationForm(forms.ModelForm):
 | 
			
		||||
        fields = ('photo_authorization',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HealthSheetForm(forms.ModelForm):
 | 
			
		||||
    """
 | 
			
		||||
    Form to send a health sheet.
 | 
			
		||||
    """
 | 
			
		||||
    def clean_health_sheet(self):
 | 
			
		||||
        if "health_sheet" in self.files:
 | 
			
		||||
            file = self.files["health_sheet"]
 | 
			
		||||
            if file.size > 2e6:
 | 
			
		||||
                raise ValidationError(_("The uploaded file size must be under 2 Mo."))
 | 
			
		||||
            if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
 | 
			
		||||
                raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
 | 
			
		||||
            return self.cleaned_data["health_sheet"]
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.fields["health_sheet"].widget = FileInput()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = StudentRegistration
 | 
			
		||||
        fields = ('health_sheet',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ParentalAuthorizationForm(forms.ModelForm):
 | 
			
		||||
    """
 | 
			
		||||
    Form to send a parental authorization.
 | 
			
		||||
    """
 | 
			
		||||
    def clean_parental_authorization(self):
 | 
			
		||||
        if "parental_authorization" in self.files:
 | 
			
		||||
            file = self.files["parental_authorization"]
 | 
			
		||||
            if file.size > 2e6:
 | 
			
		||||
                raise ValidationError(_("The uploaded file size must be under 2 Mo."))
 | 
			
		||||
            if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
 | 
			
		||||
                raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
 | 
			
		||||
            return self.cleaned_data["parental_authorization"]
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.fields["parental_authorization"].widget = FileInput()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = StudentRegistration
 | 
			
		||||
        fields = ('parental_authorization',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CoachRegistrationForm(forms.ModelForm):
 | 
			
		||||
    """
 | 
			
		||||
    A coach can tell its professional activity.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
# Copyright (C) 2020 by Animath
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from datetime import date
 | 
			
		||||
 | 
			
		||||
from address.models import AddressField
 | 
			
		||||
from django.contrib.sites.models import Site
 | 
			
		||||
from django.db import models
 | 
			
		||||
@@ -73,7 +75,7 @@ class Registration(PolymorphicModel):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def participates(self):
 | 
			
		||||
        return isinstance(self, StudentRegistration) or isinstance(self, CoachRegistration)
 | 
			
		||||
        return isinstance(self, ParticipantRegistration)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_admin(self):
 | 
			
		||||
@@ -119,7 +121,7 @@ class ParticipantRegistration(Registration):
 | 
			
		||||
 | 
			
		||||
    birth_date = models.DateField(
 | 
			
		||||
        verbose_name=_("birth date"),
 | 
			
		||||
        default=timezone.now,
 | 
			
		||||
        default=date.today,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    address = AddressField(
 | 
			
		||||
@@ -147,6 +149,10 @@ class ParticipantRegistration(Registration):
 | 
			
		||||
        default="",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def under_18(self):
 | 
			
		||||
        return (timezone.now().date() - self.birth_date).days < 18 * 365.24
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def type(self):  # pragma: no cover
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
 | 
			
		||||
{% load i18n static crispy_forms_filters %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <a class="btn btn-info" href="{% url "registration:user_detail" pk=object.user.pk %}"><i class="fas fa-arrow-left"></i> {% trans "Back to the user detail" %}</a>
 | 
			
		||||
    <hr>
 | 
			
		||||
    <form method="post" enctype="multipart/form-data">
 | 
			
		||||
        <div id="form-content">
 | 
			
		||||
            <div class="alert alert-info">
 | 
			
		||||
                {% trans "Health sheet template:" %}
 | 
			
		||||
                <a class="alert-link" href="{% static "Fiche_sanitaire.pdf" %}">{% trans "Download" %}</a>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {{ form|crispy }}
 | 
			
		||||
        </div>
 | 
			
		||||
        <button class="btn btn-success" type="submit">{% trans "Upload" %}</button>
 | 
			
		||||
    </form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
 | 
			
		||||
{% load i18n static crispy_forms_filters %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <a class="btn btn-info" href="{% url "registration:user_detail" pk=object.user.pk %}"><i class="fas fa-arrow-left"></i> {% trans "Back to the user detail" %}</a>
 | 
			
		||||
    <hr>
 | 
			
		||||
    <form method="post" enctype="multipart/form-data">
 | 
			
		||||
        <div id="form-content">
 | 
			
		||||
            <div class="alert alert-info">
 | 
			
		||||
                {% trans "Authorzation template:" %}
 | 
			
		||||
                <a class="alert-link" href="{% static "Autorisation_parentale.tex" %}">{% trans "Download" %}</a>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {{ form|crispy }}
 | 
			
		||||
        </div>
 | 
			
		||||
        <button class="btn btn-success" type="submit">{% trans "Upload" %}</button>
 | 
			
		||||
    </form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -9,8 +9,8 @@
 | 
			
		||||
        <div id="form-content">
 | 
			
		||||
            <div class="alert alert-info">
 | 
			
		||||
                {% trans "Authorzation templates:" %}
 | 
			
		||||
                <a class="alert-link" href="{% static "Autorisation de droit à l'image - majeur.pdf" %}">{% trans "Adult" %}</a> —
 | 
			
		||||
                <a class="alert-link" href="{% static "Autorisation de droit à l'image - mineur.pdf" %}">{% trans "Child" %}</a>
 | 
			
		||||
                <a class="alert-link" href="{% static "Autorisation_droit_image_majeur.tex" %}">{% trans "Adult" %}</a> —
 | 
			
		||||
                <a class="alert-link" href="{% static "Autorisation_droit_image_mineur.tex" %}">{% trans "Child" %}</a>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {{ form|crispy }}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
            <dd class="col-sm-6"><a href="mailto:{{ user_object.email }}">{{ user_object.email }}</a>
 | 
			
		||||
                {% if not user_object.registration.email_confirmed %} (<em>{% trans "Not confirmed" %}, <a href="{% url "registration:email_validation_resend" pk=user_object.pk %}">{% trans "resend the validation link" %}</a></em>){% endif %}</dd>
 | 
			
		||||
 | 
			
		||||
            {% if user_object.registration.participates or True %}
 | 
			
		||||
            {% if user_object.registration.participates %}
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Team:" %}</dt>
 | 
			
		||||
                {% trans "any" as any %}
 | 
			
		||||
                <dd class="col-sm-6">
 | 
			
		||||
@@ -29,14 +29,15 @@
 | 
			
		||||
                        {{ user_object.registration.team|default:any }}
 | 
			
		||||
                    </a>
 | 
			
		||||
                </dd>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 | 
			
		||||
            {% if user_object.registration.studentregistration %}
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Student class:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.get_student_class_display }}</dd>
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Birth date:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.birth_date }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "School:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.school }}</dd>
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Address:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.address }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Phone number:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.phone_number }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Photo authorization:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">
 | 
			
		||||
@@ -47,6 +48,47 @@
 | 
			
		||||
                        <button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Health sheet:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">
 | 
			
		||||
                    {% if user_object.registration.health_sheet %}
 | 
			
		||||
                        <a href="{{ user_object.registration.health_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    {% if user_object.pk == user.pk %}
 | 
			
		||||
                        <button class="btn btn-primary" data-toggle="modal" data-target="#uploadHealthSheetModal">{% trans "Replace" %}</button>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </dd>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 | 
			
		||||
            {% if user_object.registration.studentregistration %}
 | 
			
		||||
                {% if user_object.registration.under_18 %}
 | 
			
		||||
                    <dt class="col-sm-6 text-right">{% trans "Parental authorization:" %}</dt>
 | 
			
		||||
                    <dd class="col-sm-6">
 | 
			
		||||
                        {% if user_object.registration.parental_authorization %}
 | 
			
		||||
                            <a href="{{ user_object.registration.parental_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                        {% if user_object.pk == user.pk %}
 | 
			
		||||
                            <button class="btn btn-primary" data-toggle="modal" data-target="#uploadParentalAuthorizationModal">{% trans "Replace" %}</button>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                    </dd>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Student class:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.get_student_class_display }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "School:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.school }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Responsible name:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.responsible_name }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Responsible phone number:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.responsible_phone }}</dd>
 | 
			
		||||
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Responsible email address:" %}</dt>
 | 
			
		||||
                {% with user_object.registration.responsible_email as email %}
 | 
			
		||||
                    <dd class="col-sm-6"><a href="mailto:{{ email }}">{{ email }}</a></dd>
 | 
			
		||||
                {% endwith %}
 | 
			
		||||
            {% elif user_object.registration.coachregistration %}
 | 
			
		||||
                <dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
 | 
			
		||||
                <dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd>
 | 
			
		||||
@@ -78,6 +120,16 @@
 | 
			
		||||
    {% trans "Upload" as modal_button %}
 | 
			
		||||
    {% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk as modal_action %}
 | 
			
		||||
    {% include "base_modal.html" with modal_id="uploadPhotoAuthorization" modal_enctype="multipart/form-data" %}
 | 
			
		||||
 | 
			
		||||
    {% trans "Upload health sheet" as modal_title %}
 | 
			
		||||
    {% trans "Upload" as modal_button %}
 | 
			
		||||
    {% url "registration:upload_user_health_sheet" pk=user_object.registration.pk as modal_action %}
 | 
			
		||||
    {% include "base_modal.html" with modal_id="uploadHealthSheet" modal_enctype="multipart/form-data" %}
 | 
			
		||||
 | 
			
		||||
    {% trans "Upload parental authorization" as modal_title %}
 | 
			
		||||
    {% trans "Upload" as modal_button %}
 | 
			
		||||
    {% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %}
 | 
			
		||||
    {% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block extrajavascript %}
 | 
			
		||||
@@ -93,6 +145,16 @@
 | 
			
		||||
                if (!modalBody.html().trim())
 | 
			
		||||
                    modalBody.load("{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk %} #form-content");
 | 
			
		||||
            });
 | 
			
		||||
            $('button[data-target="#uploadHealthSheetModal"]').click(function() {
 | 
			
		||||
                let modalBody = $("#uploadHealthSheetModal div.modal-body");
 | 
			
		||||
                if (!modalBody.html().trim())
 | 
			
		||||
                    modalBody.load("{% url "registration:upload_user_health_sheet" pk=user_object.registration.pk %} #form-content");
 | 
			
		||||
            });
 | 
			
		||||
            $('button[data-target="#uploadParentalAuthorizationModal"]').click(function() {
 | 
			
		||||
                let modalBody = $("#uploadParentalAuthorizationModal div.modal-body");
 | 
			
		||||
                if (!modalBody.html().trim())
 | 
			
		||||
                    modalBody.load("{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %} #form-content");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -268,37 +268,38 @@ class TestRegistration(TestCase):
 | 
			
		||||
        """
 | 
			
		||||
        Try to upload a photo authorization.
 | 
			
		||||
        """
 | 
			
		||||
        response = self.client.get(reverse("registration:upload_user_photo_authorization",
 | 
			
		||||
                                           args=(self.student.registration.pk,)))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
        for auth_type in ["photo_authorization", "health_sheet", "parental_authorization"]:
 | 
			
		||||
            response = self.client.get(reverse("registration:upload_user_photo_authorization",
 | 
			
		||||
                                               args=(self.student.registration.pk,)))
 | 
			
		||||
            self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
        # README is not a valid PDF file
 | 
			
		||||
        response = self.client.post(reverse("registration:upload_user_photo_authorization",
 | 
			
		||||
                                            args=(self.student.registration.pk,)), data=dict(
 | 
			
		||||
            photo_authorization=open("README.md", "rb"),
 | 
			
		||||
        ))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
            # README is not a valid PDF file
 | 
			
		||||
            response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
 | 
			
		||||
                                                args=(self.student.registration.pk,)), data={
 | 
			
		||||
                auth_type: open("README.md", "rb"),
 | 
			
		||||
            })
 | 
			
		||||
            self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
        # Don't send too large files
 | 
			
		||||
        response = self.client.post(reverse("registration:upload_user_photo_authorization",
 | 
			
		||||
                                            args=(self.student.registration.pk,)), data=dict(
 | 
			
		||||
            photo_authorization=SimpleUploadedFile("file.pdf", content=int(0).to_bytes(2000001, "big"),
 | 
			
		||||
                                                   content_type="application/pdf"),
 | 
			
		||||
        ))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
            # Don't send too large files
 | 
			
		||||
            response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
 | 
			
		||||
                                                args=(self.student.registration.pk,)), data={
 | 
			
		||||
                auth_type: SimpleUploadedFile("file.pdf", content=int(0).to_bytes(2000001, "big"),
 | 
			
		||||
                                              content_type="application/pdf"),
 | 
			
		||||
            })
 | 
			
		||||
            self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
        response = self.client.post(reverse("registration:upload_user_photo_authorization",
 | 
			
		||||
                                            args=(self.student.registration.pk,)), data=dict(
 | 
			
		||||
            photo_authorization=open("tfjm/static/Fiche_sanitaire.pdf", "rb"),
 | 
			
		||||
        ))
 | 
			
		||||
        self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200)
 | 
			
		||||
            response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
 | 
			
		||||
                                                args=(self.student.registration.pk,)), data={
 | 
			
		||||
                auth_type: open("tfjm/static/Fiche_sanitaire.pdf", "rb"),
 | 
			
		||||
            })
 | 
			
		||||
            self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200)
 | 
			
		||||
 | 
			
		||||
        self.student.registration.refresh_from_db()
 | 
			
		||||
        self.assertTrue(self.student.registration.photo_authorization)
 | 
			
		||||
            self.student.registration.refresh_from_db()
 | 
			
		||||
            self.assertTrue(getattr(self.student.registration, auth_type))
 | 
			
		||||
 | 
			
		||||
        response = self.client.get(reverse("photo_authorization",
 | 
			
		||||
                                           args=(self.student.registration.photo_authorization.name.split('/')[-1],)))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
            response = self.client.get(reverse(
 | 
			
		||||
                auth_type, args=(self.student.registration.photo_authorization.name.split('/')[-1],)))
 | 
			
		||||
            self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
        from participation.models import Team
 | 
			
		||||
        team = Team.objects.create(name="Test", trigram="TES")
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,8 @@
 | 
			
		||||
from django.urls import path
 | 
			
		||||
 | 
			
		||||
from .views import MyAccountDetailView, ResetAdminView, SignupView, UserDetailView, UserImpersonateView, \
 | 
			
		||||
    UserListView, UserResendValidationEmailView, UserUpdateView, UserUploadPhotoAuthorizationView, UserValidateView, \
 | 
			
		||||
    UserListView, UserResendValidationEmailView, UserUpdateView, UserUploadHealthSheetView, \
 | 
			
		||||
    UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, UserValidateView, \
 | 
			
		||||
    UserValidationEmailSentView
 | 
			
		||||
 | 
			
		||||
app_name = "registration"
 | 
			
		||||
@@ -20,6 +21,10 @@ urlpatterns = [
 | 
			
		||||
    path("user/<int:pk>/update/", UserUpdateView.as_view(), name="update_user"),
 | 
			
		||||
    path("user/<int:pk>/upload-photo-authorization/", UserUploadPhotoAuthorizationView.as_view(),
 | 
			
		||||
         name="upload_user_photo_authorization"),
 | 
			
		||||
    path("user/<int:pk>/upload-health_sheet/", UserUploadHealthSheetView.as_view(),
 | 
			
		||||
         name="upload_user_health_sheet"),
 | 
			
		||||
    path("user/<int:pk>/upload-parental-authorization/", UserUploadParentalAuthorizationView.as_view(),
 | 
			
		||||
         name="upload_user_parental_authorization"),
 | 
			
		||||
    path("user/<int:pk>/impersonate/", UserImpersonateView.as_view(), name="user_impersonate"),
 | 
			
		||||
    path("user/list/", UserListView.as_view(), name="user_list"),
 | 
			
		||||
    path("reset-admin/", ResetAdminView.as_view(), name="reset_admin"),
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,10 @@ from django.views.generic import CreateView, DetailView, RedirectView, TemplateV
 | 
			
		||||
from django_tables2 import SingleTableView
 | 
			
		||||
from magic import Magic
 | 
			
		||||
from tfjm.tokens import email_validation_token
 | 
			
		||||
from tfjm.views import AdminMixin
 | 
			
		||||
from tfjm.views import AdminMixin, UserMixin
 | 
			
		||||
 | 
			
		||||
from .forms import CoachRegistrationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm
 | 
			
		||||
from .forms import CoachRegistrationForm, HealthSheetForm, ParentalAuthorizationForm, PhotoAuthorizationForm,\
 | 
			
		||||
    SignupForm, StudentRegistrationForm, UserForm
 | 
			
		||||
from .models import Registration, StudentRegistration
 | 
			
		||||
from .tables import RegistrationTable
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +151,7 @@ class MyAccountDetailView(LoginRequiredMixin, RedirectView):
 | 
			
		||||
        return reverse_lazy("registration:user_detail", args=(self.request.user.pk,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserDetailView(LoginRequiredMixin, DetailView):
 | 
			
		||||
class UserDetailView(UserMixin, DetailView):
 | 
			
		||||
    """
 | 
			
		||||
    Display the detail about a user.
 | 
			
		||||
    """
 | 
			
		||||
@@ -159,15 +160,6 @@ class UserDetailView(LoginRequiredMixin, DetailView):
 | 
			
		||||
    context_object_name = "user_object"
 | 
			
		||||
    template_name = "registration/user_detail.html"
 | 
			
		||||
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        user = request.user
 | 
			
		||||
        if not user.is_authenticated:
 | 
			
		||||
            return self.handle_no_permission()
 | 
			
		||||
        # Only an admin or the concerned user can see the information
 | 
			
		||||
        if not user.registration.is_admin and user.pk != kwargs["pk"]:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context["title"] = _("Detail of user {user}").format(user=str(self.object.registration))
 | 
			
		||||
@@ -183,7 +175,7 @@ class UserListView(AdminMixin, SingleTableView):
 | 
			
		||||
    template_name = "registration/user_list.html"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserUpdateView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
class UserUpdateView(UserMixin, UpdateView):
 | 
			
		||||
    """
 | 
			
		||||
    Update the detail about a user and its registration.
 | 
			
		||||
    """
 | 
			
		||||
@@ -191,12 +183,6 @@ class UserUpdateView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
    form_class = UserForm
 | 
			
		||||
    template_name = "registration/update_user.html"
 | 
			
		||||
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        user = request.user
 | 
			
		||||
        if not user.registration.is_admin and user.pk != kwargs["pk"]:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        user = self.get_object()
 | 
			
		||||
@@ -229,7 +215,7 @@ class UserUpdateView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
        return reverse_lazy("registration:user_detail", args=(self.object.pk,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
class UserUploadPhotoAuthorizationView(UserMixin, UpdateView):
 | 
			
		||||
    """
 | 
			
		||||
    A participant can send its photo authorization.
 | 
			
		||||
    """
 | 
			
		||||
@@ -238,12 +224,6 @@ class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
    template_name = "registration/upload_photo_authorization.html"
 | 
			
		||||
    extra_context = dict(title=_("Upload photo authorization"))
 | 
			
		||||
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        user = request.user
 | 
			
		||||
        if not user.registration.is_admin and user.registration.pk != kwargs["pk"]:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    @transaction.atomic
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        old_instance = StudentRegistration.objects.get(pk=self.object.pk)
 | 
			
		||||
@@ -255,6 +235,46 @@ class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
 | 
			
		||||
        return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserUploadHealthSheetView(UserMixin, UpdateView):
 | 
			
		||||
    """
 | 
			
		||||
    A participant can send its health sheet.
 | 
			
		||||
    """
 | 
			
		||||
    model = StudentRegistration
 | 
			
		||||
    form_class = HealthSheetForm
 | 
			
		||||
    template_name = "registration/upload_health_sheet.html"
 | 
			
		||||
    extra_context = dict(title=_("Upload health sheet"))
 | 
			
		||||
 | 
			
		||||
    @transaction.atomic
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        old_instance = StudentRegistration.objects.get(pk=self.object.pk)
 | 
			
		||||
        if old_instance.health_sheet:
 | 
			
		||||
            old_instance.health_sheet.delete()
 | 
			
		||||
        return super().form_valid(form)
 | 
			
		||||
 | 
			
		||||
    def get_success_url(self):
 | 
			
		||||
        return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserUploadParentalAuthorizationView(UserMixin, UpdateView):
 | 
			
		||||
    """
 | 
			
		||||
    A participant can send its parental authorization.
 | 
			
		||||
    """
 | 
			
		||||
    model = StudentRegistration
 | 
			
		||||
    form_class = ParentalAuthorizationForm
 | 
			
		||||
    template_name = "registration/upload_parental_authorization.html"
 | 
			
		||||
    extra_context = dict(title=_("Upload parental authorization"))
 | 
			
		||||
 | 
			
		||||
    @transaction.atomic
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        old_instance = StudentRegistration.objects.get(pk=self.object.pk)
 | 
			
		||||
        if old_instance.parental_authorization:
 | 
			
		||||
            old_instance.parental_authorization.delete()
 | 
			
		||||
        return super().form_valid(form)
 | 
			
		||||
 | 
			
		||||
    def get_success_url(self):
 | 
			
		||||
        return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PhotoAuthorizationView(LoginRequiredMixin, View):
 | 
			
		||||
    """
 | 
			
		||||
    Display the sent photo authorization.
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,15 @@ from haystack.generic_views import SearchView
 | 
			
		||||
 | 
			
		||||
class AdminMixin(LoginRequiredMixin):
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        if not request.user.registration.is_admin:
 | 
			
		||||
        if request.user.is_authenticated and not request.user.registration.is_admin:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserMixin(LoginRequiredMixin):
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        user = request.user
 | 
			
		||||
        if user.is_authenticated and not user.registration.is_admin and user.registration.pk != kwargs["pk"]:
 | 
			
		||||
            raise PermissionDenied
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user