|
|
|
@ -8,6 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
|
from django.core.exceptions import PermissionDenied, ValidationError
|
|
|
|
|
from django.db import transaction
|
|
|
|
|
from django.db.models import Q
|
|
|
|
|
from django.http import FileResponse, Http404
|
|
|
|
|
from django.shortcuts import redirect, resolve_url
|
|
|
|
|
from django.urls import reverse_lazy
|
|
|
|
@ -17,9 +18,9 @@ from django.views.generic import CreateView, DetailView, RedirectView, TemplateV
|
|
|
|
|
from django_tables2 import SingleTableView
|
|
|
|
|
from magic import Magic
|
|
|
|
|
|
|
|
|
|
from participation.models import Solution, Synthesis
|
|
|
|
|
from participation.models import Solution, Synthesis, Passage
|
|
|
|
|
from tfjm.tokens import email_validation_token
|
|
|
|
|
from tfjm.views import AdminMixin, UserMixin
|
|
|
|
|
from tfjm.views import AdminMixin, UserMixin, VolunteerMixin
|
|
|
|
|
|
|
|
|
|
from .forms import AddOrganizerForm, AdminRegistrationForm, CoachRegistrationForm, HealthSheetForm, \
|
|
|
|
|
ParentalAuthorizationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \
|
|
|
|
@ -67,6 +68,7 @@ class SignupView(CreateView):
|
|
|
|
|
registration = registration_form.instance
|
|
|
|
|
registration.user = form.instance
|
|
|
|
|
registration.save()
|
|
|
|
|
registration.send_email_validation_link()
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
@ -74,7 +76,7 @@ class SignupView(CreateView):
|
|
|
|
|
return reverse_lazy("registration:email_validation_sent")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AddOrganizerView(AdminMixin, CreateView):
|
|
|
|
|
class AddOrganizerView(VolunteerMixin, CreateView):
|
|
|
|
|
model = User
|
|
|
|
|
form_class = AddOrganizerForm
|
|
|
|
|
template_name = "registration/add_organizer.html"
|
|
|
|
@ -89,6 +91,10 @@ class AddOrganizerView(AdminMixin, CreateView):
|
|
|
|
|
del context["volunteer_registration_form"].fields["email_confirmed"]
|
|
|
|
|
del context["admin_registration_form"].fields["email_confirmed"]
|
|
|
|
|
|
|
|
|
|
if not self.request.user.registration.is_admin:
|
|
|
|
|
del context["form"].fields["type"]
|
|
|
|
|
del context["admin_registration_form"]
|
|
|
|
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@ -107,6 +113,7 @@ class AddOrganizerView(AdminMixin, CreateView):
|
|
|
|
|
registration = registration_form.instance
|
|
|
|
|
registration.user = form.instance
|
|
|
|
|
registration.save()
|
|
|
|
|
registration.send_email_validation_link()
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
@ -114,7 +121,6 @@ class AddOrganizerView(AdminMixin, CreateView):
|
|
|
|
|
return reverse_lazy("registration:email_validation_sent")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserValidateView(TemplateView):
|
|
|
|
|
"""
|
|
|
|
|
A view to validate the email address.
|
|
|
|
@ -204,6 +210,19 @@ class UserDetailView(UserMixin, DetailView):
|
|
|
|
|
context_object_name = "user_object"
|
|
|
|
|
template_name = "registration/user_detail.html"
|
|
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
|
me = request.user
|
|
|
|
|
if not me.is_authenticated:
|
|
|
|
|
return self.handle_no_permission()
|
|
|
|
|
user = self.get_object()
|
|
|
|
|
if user == me or me.registration.is_admin or me.registration.is_volunteer \
|
|
|
|
|
and user.registration.participates and user.registration.team \
|
|
|
|
|
and user.registration.team.participation.tournament in user.registration.organized_tournaments.all() \
|
|
|
|
|
or user.registration.is_volunteer and me.registration.is_volunteer \
|
|
|
|
|
and me.registration.interesting_tournaments.intersection(user.registration.intersting_tournaments):
|
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
|
context["title"] = _("Detail of user {user}").format(user=str(self.object.registration))
|
|
|
|
@ -227,6 +246,12 @@ class UserUpdateView(UserMixin, UpdateView):
|
|
|
|
|
form_class = UserForm
|
|
|
|
|
template_name = "registration/update_user.html"
|
|
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
|
if not self.request.user.is_authenticated or \
|
|
|
|
|
not self.request.user.registration.is_admin and self.request.user != self.get_object():
|
|
|
|
|
return self.handle_no_permission()
|
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
|
user = self.get_object()
|
|
|
|
@ -268,6 +293,12 @@ class UserUploadPhotoAuthorizationView(UserMixin, UpdateView):
|
|
|
|
|
template_name = "registration/upload_photo_authorization.html"
|
|
|
|
|
extra_context = dict(title=_("Upload photo authorization"))
|
|
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
|
if not self.request.user.is_authenticated or \
|
|
|
|
|
not self.request.user.registration.is_admin and self.request.user != self.get_object().user:
|
|
|
|
|
return self.handle_no_permission()
|
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
|
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
|
|
|
|
@ -288,6 +319,12 @@ class UserUploadHealthSheetView(UserMixin, UpdateView):
|
|
|
|
|
template_name = "registration/upload_health_sheet.html"
|
|
|
|
|
extra_context = dict(title=_("Upload health sheet"))
|
|
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
|
if not self.request.user.is_authenticated or \
|
|
|
|
|
not self.request.user.registration.is_admin and self.request.user != self.get_object().user:
|
|
|
|
|
return self.handle_no_permission()
|
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
|
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
|
|
|
|
@ -308,6 +345,12 @@ class UserUploadParentalAuthorizationView(UserMixin, UpdateView):
|
|
|
|
|
template_name = "registration/upload_parental_authorization.html"
|
|
|
|
|
extra_context = dict(title=_("Upload parental authorization"))
|
|
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
|
if not self.request.user.is_authenticated or \
|
|
|
|
|
not self.request.user.registration.is_admin and self.request.user != self.get_object().user:
|
|
|
|
|
return self.handle_no_permission()
|
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
|
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
|
|
|
|
@ -330,7 +373,8 @@ class PhotoAuthorizationView(LoginRequiredMixin, View):
|
|
|
|
|
raise Http404
|
|
|
|
|
student = ParticipantRegistration.objects.get(photo_authorization__endswith=filename)
|
|
|
|
|
user = request.user
|
|
|
|
|
if not user.registration.is_admin and user.pk != student.user.pk:
|
|
|
|
|
if not (student.user == user or user.registration.is_admin or user.registration.is_volunteer and student.team
|
|
|
|
|
and student.team.participation.tournament in user.registration.organized_tournaments.all()):
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
# Guess mime type of the file
|
|
|
|
|
mime = Magic(mime=True)
|
|
|
|
@ -352,7 +396,8 @@ class HealthSheetView(LoginRequiredMixin, View):
|
|
|
|
|
raise Http404
|
|
|
|
|
student = ParticipantRegistration.objects.get(health_sheet__endswith=filename)
|
|
|
|
|
user = request.user
|
|
|
|
|
if not user.registration.is_admin and user.pk != student.user.pk:
|
|
|
|
|
if not (student.user == user or user.registration.is_admin or user.registration.is_volunteer and student.team
|
|
|
|
|
and student.team.participation.tournament in user.registration.organized_tournaments.all()):
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
# Guess mime type of the file
|
|
|
|
|
mime = Magic(mime=True)
|
|
|
|
@ -374,7 +419,8 @@ class ParentalAuthorizationView(LoginRequiredMixin, View):
|
|
|
|
|
raise Http404
|
|
|
|
|
student = StudentRegistration.objects.get(parental_authorization__endswith=filename)
|
|
|
|
|
user = request.user
|
|
|
|
|
if not user.registration.is_admin and user.pk != student.user.pk:
|
|
|
|
|
if not (student.user == user or user.registration.is_admin or user.registration.is_volunteer and student.team
|
|
|
|
|
and student.team.participation.tournament in user.registration.organized_tournaments.all()):
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
# Guess mime type of the file
|
|
|
|
|
mime = Magic(mime=True)
|
|
|
|
@ -395,10 +441,19 @@ class SolutionView(LoginRequiredMixin, View):
|
|
|
|
|
if not os.path.exists(path):
|
|
|
|
|
raise Http404
|
|
|
|
|
solution = Solution.objects.get(file__endswith=filename)
|
|
|
|
|
# user = request.user
|
|
|
|
|
# if False:
|
|
|
|
|
# FIXME Check ACL
|
|
|
|
|
# raise PermissionDenied
|
|
|
|
|
user = request.user
|
|
|
|
|
if not (user.registration.is_admin or user.registration.is_volunteer
|
|
|
|
|
and Passage.objects.filter(Q(pool__juries=user.registration)
|
|
|
|
|
| Q(pool__tournament__in=user.registration.organized_tournaments.all()),
|
|
|
|
|
defender=solution.participation,
|
|
|
|
|
solution_number=solution.problem).exists()
|
|
|
|
|
or user.registration.participates and user.registration.team
|
|
|
|
|
and Passage.objects.filter(Q(defender=user.registration.team.participation)
|
|
|
|
|
| Q(opponent=user.registration.team.participation)
|
|
|
|
|
| Q(reporter=user.registration.team.participation),
|
|
|
|
|
defender=solution.participation,
|
|
|
|
|
solution_number=solution.problem).exists()):
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
# Guess mime type of the file
|
|
|
|
|
mime = Magic(mime=True)
|
|
|
|
|
mime_type = mime.from_file(path)
|
|
|
|
@ -417,17 +472,19 @@ class SynthesisView(LoginRequiredMixin, View):
|
|
|
|
|
path = f"media/syntheses/{filename}"
|
|
|
|
|
if not os.path.exists(path):
|
|
|
|
|
raise Http404
|
|
|
|
|
solution = Synthesis.objects.get(file__endswith=filename)
|
|
|
|
|
# user = request.user
|
|
|
|
|
# if False:
|
|
|
|
|
# FIXME Check ACL
|
|
|
|
|
# raise PermissionDenied
|
|
|
|
|
synthesis = Synthesis.objects.get(file__endswith=filename)
|
|
|
|
|
user = request.user
|
|
|
|
|
if not (user.registration.is_admin or user.registration.is_volunteer
|
|
|
|
|
and (user.registration in synthesis.passage.pool.juries.all()
|
|
|
|
|
or user.registration in synthesis.passage.pool.tournament.organizers.all())
|
|
|
|
|
or user.registration.participates and user.registration.team == synthesis.participation.team):
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
# Guess mime type of the file
|
|
|
|
|
mime = Magic(mime=True)
|
|
|
|
|
mime_type = mime.from_file(path)
|
|
|
|
|
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
|
|
|
|
# Replace file name
|
|
|
|
|
true_file_name = str(solution) + f".{ext}"
|
|
|
|
|
true_file_name = str(synthesis) + f".{ext}"
|
|
|
|
|
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|