diff --git a/apps/participation/views.py b/apps/participation/views.py
index a79c8f1..7d4da87 100644
--- a/apps/participation/views.py
+++ b/apps/participation/views.py
@@ -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,))
diff --git a/apps/registration/models.py b/apps/registration/models.py
index f7abe84..5c3535a 100644
--- a/apps/registration/models.py
+++ b/apps/registration/models.py
@@ -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}"
diff --git a/apps/registration/templates/registration/user_detail.html b/apps/registration/templates/registration/user_detail.html
index 9ed7bb3..38c5519 100644
--- a/apps/registration/templates/registration/user_detail.html
+++ b/apps/registration/templates/registration/user_detail.html
@@ -21,6 +21,16 @@
{{ user_object.email }}
{% if not user_object.registration.email_confirmed %} ({% trans "Not confirmed" %}, {% trans "resend the validation link" %}){% endif %}
+ {% if user_object.registration.participates or True %}
+ {% trans "Team:" %}
+ {% trans "any" as any %}
+
+
+ {{ user_object.registration.team|default:any }}
+
+
+ {% endif %}
+
{% if user_object.registration.studentregistration %}
{% trans "Student class:" %}
{{ user_object.registration.get_student_class_display }}
@@ -32,7 +42,10 @@
{% if user_object.registration.photo_authorization %}
{% trans "Download" %}
- {% endif %}
+ {% endif %}
+ {% if user_object.pk == user.pk %}
+
+ {% endif %}
{% elif user_object.registration.coachregistration %}
{% trans "Profesional activity:" %}
@@ -46,9 +59,11 @@
{{ user_object.registration.give_contact_to_animath|yesno }}
-
+ {% if user.pk == user_object.pk or user.registration.is_admin %}
+
+ {% endif %}
{% trans "Update user" as modal_title %}
diff --git a/apps/registration/views.py b/apps/registration/views.py
index 0b8a2d6..7b4819a 100644
--- a/apps/registration/views.py
+++ b/apps/registration/views.py
@@ -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")
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 39c561a..9e1cf6d 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -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 \n"
"Language-Team: LANGUAGE \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}"