Protect some pages

This commit is contained in:
Yohann D'ANELLO 2020-09-27 16:35:31 +02:00
parent 56193dbecf
commit 88c4a6b218
5 changed files with 136 additions and 65 deletions

View File

@ -15,18 +15,20 @@ class CreateTeamView(LoginRequiredMixin, CreateView):
extra_context = dict(title=_("Create team"))
template_name = "participation/create_team.html"
@transaction.atomic
def form_valid(self, form):
user = self.request.user
def dispatch(self, request, *args, **kwargs):
user = request.user
registration = user.registration
if not registration.participates:
form.add_error(None, _("You don't participate, so you can't create a team."))
return self.form_invalid(form)
raise PermissionDenied(_("You don't participate, so you can't create a team."))
elif registration.team:
form.add_error(None, _("You are already in a team."))
return self.form_invalid(form)
raise PermissionDenied(_("You are already in a team."))
return super().dispatch(request, *args, **kwargs)
@transaction.atomic
def form_valid(self, form):
ret = super().form_valid(form)
user = self.request.user
registration = user.registration
registration.team = form.instance
registration.save()
return ret
@ -41,19 +43,21 @@ class JoinTeamView(LoginRequiredMixin, FormView):
extra_context = dict(title=_("Join team"))
template_name = "participation/create_team.html"
@transaction.atomic
def form_valid(self, form):
user = self.request.user
def dispatch(self, request, *args, **kwargs):
user = request.user
registration = user.registration
if not registration.participates:
form.add_error(None, _("You don't participate, so you can't create a team."))
return self.form_invalid(form)
raise PermissionDenied(_("You don't participate, so you can't create a team."))
elif registration.team:
form.add_error(None, _("You are already in a team."))
return self.form_invalid(form)
raise PermissionDenied(_("You are already in a team."))
return super().dispatch(request, *args, **kwargs)
@transaction.atomic
def form_valid(self, form):
self.object = form.instance
ret = super().form_valid(form)
user = self.request.user
registration = user.registration
registration.team = form.instance
registration.save()
return ret
@ -76,12 +80,24 @@ class MyTeamDetailView(LoginRequiredMixin, RedirectView):
class TeamDetailView(LoginRequiredMixin, DetailView):
model = Team
def dispatch(self, request, *args, **kwargs):
user = request.user
if user.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
class TeamUpdateView(LoginRequiredMixin, UpdateView):
model = Team
form_class = TeamForm
template_name = "participation/update_team.html"
def dispatch(self, request, *args, **kwargs):
user = request.user
if user.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["participation_form"] = ParticipationForm(data=self.request.POST or None,
@ -115,11 +131,24 @@ class MyParticipationDetailView(LoginRequiredMixin, RedirectView):
class ParticipationDetailView(LoginRequiredMixin, DetailView):
model = Participation
def dispatch(self, request, *args, **kwargs):
user = request.user
if user.is_admin or user.registration.participates and user.registration.team.participation.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
class UploadVideoView(LoginRequiredMixin, UpdateView):
model = Video
form_class = UploadVideoForm
template_name = "participation/upload_video.html"
def dispatch(self, request, *args, **kwargs):
user = request.user
if user.is_admin or user.registration.participates\
and user.registration.team.participation.pk == self.object.participation.pk:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
def get_success_url(self):
return reverse_lazy("participation:participation_detail", args=(self.object.participation.pk,))

View File

@ -59,6 +59,10 @@ class Registration(PolymorphicModel):
def participates(self):
return isinstance(self, StudentRegistration) or isinstance(self, CoachRegistration)
@property
def is_admin(self):
return isinstance(self, AdminRegistration) or self.user.is_superuser
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}"

View File

@ -21,6 +21,16 @@
<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 %}
<dt class="col-sm-6 text-right">{% trans "Team:" %}</dt>
{% trans "any" as any %}
<dd class="col-sm-6">
<a href="{% if user_object.registration.team %}{% url "participation:team_detail" pk=user_object.registration.team.pk %}{% else %}#{% endif %}">
{{ 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>
@ -32,7 +42,10 @@
<dd class="col-sm-6">
{% if user_object.registration.photo_authorization %}
<a href="{{ user_object.registration.photo_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} <button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
{% endif %}
{% if user_object.pk == user.pk %}
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
{% endif %}
</dd>
{% elif user_object.registration.coachregistration %}
<dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
@ -46,9 +59,11 @@
<dd class="col-sm-6">{{ user_object.registration.give_contact_to_animath|yesno }}</dd>
</dl>
</div>
<div class="card-footer text-center">
<button class="btn btn-primary" data-toggle="modal" data-target="#updateUserModal">{% trans "Update" %}</button>
</div>
{% if user.pk == user_object.pk or user.registration.is_admin %}
<div class="card-footer text-center">
<button class="btn btn-primary" data-toggle="modal" data-target="#updateUserModal">{% trans "Update" %}</button>
</div>
{% endif %}
</div>
{% trans "Update user" as modal_title %}

View File

@ -4,7 +4,7 @@ from corres2math.tokens import email_validation_token
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.core.exceptions import ValidationError, PermissionDenied
from django.db import transaction
from django.http import FileResponse, Http404
from django.shortcuts import redirect, resolve_url
@ -135,12 +135,24 @@ 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.registration.is_admin and user.pk != kwargs["pk"]:
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
class UserUpdateView(LoginRequiredMixin, UpdateView):
model = User
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()
@ -168,6 +180,12 @@ class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
form_class = PhotoAuthorizationForm
template_name = "registration/upload_photo_authorization.html"
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)
@ -186,6 +204,9 @@ class PhotoAuthorizationView(LoginRequiredMixin, View):
if not os.path.exists(path):
raise Http404
student = StudentRegistration.objects.get(photo_authorization__endswith=filename)
user = request.user
if not user.registration.is_admin and user.pk != student.user.pk:
raise PermissionDenied
mime = Magic(mime=True)
mime_type = mime.from_file(path)
ext = mime_type.split("/")[1].replace("jpeg", "jpg")

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Corres2math\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-27 14:31+0200\n"
"POT-Creation-Date: 2020-09-27 16:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -141,7 +141,7 @@ msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:48 apps/participation/models.py:59
#: apps/registration/models.py:81 apps/registration/models.py:127
#: apps/registration/models.py:85 apps/registration/models.py:131
msgid "team"
msgstr "équipe"
@ -225,42 +225,40 @@ msgstr "Rejoindre"
#: apps/participation/templates/participation/participation_detail.html:6
#: apps/participation/templates/participation/team_detail.html:6
#: apps/registration/templates/registration/user_detail.html:6
#: apps/registration/templates/registration/user_detail.html:26
msgid "any"
msgstr "aucun"
#: apps/participation/templates/participation/participation_detail.html:11
#: apps/participation/templates/participation/participation_detail.html:27
#, fuzzy
#| msgid "participation"
#: apps/participation/templates/participation/participation_detail.html:9
msgid "Participation of team"
msgstr "participation"
msgstr "Participation de l'équipe"
#: apps/participation/templates/participation/participation_detail.html:15
#: apps/participation/templates/participation/participation_detail.html:13
#: apps/participation/templates/participation/team_detail.html:29
msgid "Chosen problem:"
msgstr "Problème choisi :"
#: apps/participation/templates/participation/participation_detail.html:30
#: apps/participation/templates/participation/participation_detail.html:19
msgid "No video sent"
msgstr "Pas de vidéo envoyée"
#: apps/participation/templates/participation/participation_detail.html:31
#: apps/participation/templates/participation/participation_detail.html:20
msgid "Video link:"
msgstr "Lien de la vidéo :"
#: apps/participation/templates/participation/participation_detail.html:32
#: apps/participation/templates/participation/participation_detail.html:46
#: apps/participation/templates/participation/participation_detail.html:23
#: apps/participation/templates/participation/participation_detail.html:38
#: apps/participation/templates/participation/upload_video.html:11
#: apps/registration/templates/registration/upload_photo_authorization.html:18
#: apps/registration/templates/registration/user_detail.html:60
#: apps/registration/templates/registration/user_detail.html:72
msgid "Upload"
msgstr "Téléverser"
#: apps/participation/templates/participation/participation_detail.html:37
#: apps/participation/templates/participation/participation_detail.html:30
msgid "This video platform is not supported yet."
msgstr "La plateforme de cette vidéo n'est pas encore supportée."
#: apps/participation/templates/participation/participation_detail.html:45
#: apps/participation/templates/participation/participation_detail.html:37
msgid "Upload video"
msgstr "Envoyer la vidéo"
@ -300,8 +298,8 @@ msgstr "Pas encore envoyée"
#: apps/participation/templates/participation/team_detail.html:53
#: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/update_user.html:12
#: apps/registration/templates/registration/user_detail.html:50
#: apps/registration/templates/registration/user_detail.html:55
#: apps/registration/templates/registration/user_detail.html:61
#: apps/registration/templates/registration/user_detail.html:67
msgid "Update"
msgstr "Modifier"
@ -343,7 +341,7 @@ msgstr "rôle"
msgid "participant"
msgstr "participant"
#: apps/registration/forms.py:16 apps/registration/models.py:136
#: apps/registration/forms.py:16 apps/registration/models.py:140
msgid "coach"
msgstr "encadrant"
@ -364,75 +362,75 @@ msgstr "email confirmé"
msgid "Activate your Correspondances account"
msgstr "Activez votre compte des Correspondances"
#: apps/registration/models.py:66
#: apps/registration/models.py:70
msgid "registration"
msgstr "inscription"
#: apps/registration/models.py:67
#: apps/registration/models.py:71
msgid "registrations"
msgstr "inscriptions"
#: apps/registration/models.py:86
#: apps/registration/models.py:90
msgid "12th grade"
msgstr "Terminale"
#: apps/registration/models.py:87
#: apps/registration/models.py:91
msgid "11th grade"
msgstr "Première"
#: apps/registration/models.py:88
#: apps/registration/models.py:92
msgid "10th grade or lower"
msgstr "Seconde ou inférieur"
#: apps/registration/models.py:90
#: apps/registration/models.py:94
msgid "student class"
msgstr "classe"
#: apps/registration/models.py:95
#: apps/registration/models.py:99
msgid "school"
msgstr "école"
#: apps/registration/models.py:100
#: apps/registration/models.py:104
msgid "photo authorization"
msgstr "autorisation de droit à l'image"
#: apps/registration/models.py:108
#: apps/registration/models.py:112
msgid "student"
msgstr "étudiant"
#: apps/registration/models.py:116
#: apps/registration/models.py:120
msgid "student registration"
msgstr "inscription d'élève"
#: apps/registration/models.py:117
#: apps/registration/models.py:121
msgid "student registrations"
msgstr "inscriptions d'élève"
#: apps/registration/models.py:131
#: apps/registration/models.py:135
msgid "professional activity"
msgstr "activité professionnelle"
#: apps/registration/models.py:144
#: apps/registration/models.py:148
msgid "coach registration"
msgstr "inscription d'encadrant"
#: apps/registration/models.py:145
#: apps/registration/models.py:149
msgid "coach registrations"
msgstr "inscriptions d'encadrants"
#: apps/registration/models.py:150
#: apps/registration/models.py:154
msgid "role of the administrator"
msgstr "rôle de l'administrateur"
#: apps/registration/models.py:155
#: apps/registration/models.py:159
msgid "admin"
msgstr "admin"
#: apps/registration/models.py:163
#: apps/registration/models.py:167
msgid "admin registration"
msgstr "inscription d'administrateur"
#: apps/registration/models.py:164
#: apps/registration/models.py:168
msgid "admin registrations"
msgstr "inscriptions d'administrateur"
@ -624,42 +622,46 @@ msgid "resend the validation link"
msgstr "Renvoyer le lien de validation"
#: apps/registration/templates/registration/user_detail.html:25
msgid "Team:"
msgstr "Équipe :"
#: apps/registration/templates/registration/user_detail.html:35
msgid "Student class:"
msgstr "Classe :"
#: apps/registration/templates/registration/user_detail.html:28
#: apps/registration/templates/registration/user_detail.html:38
msgid "School:"
msgstr "École :"
#: apps/registration/templates/registration/user_detail.html:31
#: apps/registration/templates/registration/user_detail.html:41
msgid "Photo authorization:"
msgstr "Autorisation de droit à l'image"
#: apps/registration/templates/registration/user_detail.html:34
#: apps/registration/templates/registration/user_detail.html:44
msgid "Download"
msgstr "Télécharger"
#: apps/registration/templates/registration/user_detail.html:35
#: apps/registration/templates/registration/user_detail.html:45
msgid "Replace"
msgstr "Remplacer"
#: apps/registration/templates/registration/user_detail.html:38
#: apps/registration/templates/registration/user_detail.html:48
msgid "Profesional activity:"
msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:41
#: apps/registration/templates/registration/user_detail.html:51
msgid "Role:"
msgstr "Rôle :"
#: apps/registration/templates/registration/user_detail.html:45
#: apps/registration/templates/registration/user_detail.html:55
msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :"
#: apps/registration/templates/registration/user_detail.html:54
#: apps/registration/templates/registration/user_detail.html:66
msgid "Update user"
msgstr "Modifier l'utilisateur"
#: apps/registration/templates/registration/user_detail.html:59
#: apps/registration/templates/registration/user_detail.html:71
msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image"
@ -683,7 +685,7 @@ msgstr "Mail de confirmation de l'adresse mail envoyé"
msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail"
#: apps/registration/views.py:192
#: apps/registration/views.py:198
#, python-brace-format
msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}"