1
0
mirror of https://gitlab.com/animath/si/plateforme-corres2math.git synced 2025-07-06 08:43:53 +02:00

Merge branch 'improvements' into 'master'

Improvements, bug fixes

See merge request animath/si/plateforme-corres2math!8
This commit is contained in:
Yohann D'ANELLO
2020-12-22 20:36:57 +00:00
14 changed files with 183 additions and 69 deletions

View File

@ -13,7 +13,9 @@ Bonjour {{ user.registration }},
L'équipe « {{ team.name }} » ({{ team.trigram }}) vient de demander à valider son équipe pour participer
au {{ team.participation.get_problem_display }} des Correspondances des Jeunes Mathématicien·ne·s.
Vous pouvez décider d'accepter ou de refuser l'équipe en vous rendant sur la page de l'équipe :
<a href="{% url "participation:team_detail" pk=team.pk %}">{% url "participation:team_detail" pk=team.pk %}</a>
<a href="https://{{ domain }}{% url "participation:team_detail" pk=team.pk %}">
https://{{ domain }}{% url "participation:team_detail" pk=team.pk %}
</a>
</p>
<p>

View File

@ -3,7 +3,7 @@ Bonjour {{ user.registration }},
L'équipe « {{ team.name }} » ({{ team.trigram }}) vient de demander à valider son équipe pour participer
au {{ team.participation.get_problem_display }} des Correspondances des Jeunes Mathématicien·ne·s.
Vous pouvez décider d'accepter ou de refuser l'équipe en vous rendant sur la page de l'équipe :
{% url "participation:team_detail" pk=team.pk %}
https://{{ domain }}{% url "participation:team_detail" pk=team.pk %}
Cordialement,

View File

@ -669,7 +669,7 @@ class TestStudentParticipation(TestCase):
def test_forbidden_access(self):
"""
Load personnal pages and ensure that these are protected.
Load personal pages and ensure that these are protected.
"""
self.user.registration.team = self.team
self.user.registration.save()

View File

@ -5,6 +5,7 @@ from corres2math.lists import get_sympa_client
from corres2math.matrix import Matrix
from corres2math.views import AdminMixin
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.sites.models import Site
from django.core.exceptions import PermissionDenied
from django.core.mail import send_mail
from django.db import transaction
@ -38,6 +39,8 @@ class CreateTeamView(LoginRequiredMixin, CreateView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
registration = user.registration
if not registration.participates:
raise PermissionDenied(_("You don't participate, so you can't create a team."))
@ -84,6 +87,8 @@ class JoinTeamView(LoginRequiredMixin, FormView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
registration = user.registration
if not registration.participates:
raise PermissionDenied(_("You don't participate, so you can't create a team."))
@ -208,7 +213,7 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
self.object.participation.save()
for admin in AdminRegistration.objects.all():
mail_context = dict(user=admin.user, team=self.object)
mail_context = dict(user=admin.user, team=self.object, domain=Site.objects.first().domain)
mail_plain = render_to_string("participation/mails/request_validation.txt", mail_context)
mail_html = render_to_string("participation/mails/request_validation.html", mail_context)
admin.user.email_user("[Corres2math] Validation d'équipe", mail_plain, html_message=mail_html)
@ -264,6 +269,8 @@ class TeamUpdateView(LoginRequiredMixin, UpdateView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
if user.registration.is_admin or user.registration.participates and \
user.registration.team and \
user.registration.team.pk == kwargs["pk"]:
@ -298,6 +305,8 @@ class TeamAuthorizationsView(LoginRequiredMixin, DetailView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
if user.registration.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
@ -376,6 +385,8 @@ class ParticipationDetailView(LoginRequiredMixin, DetailView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
if not self.get_object().valid:
raise PermissionDenied(_("The team is not validated yet."))
if user.registration.is_admin or user.registration.participates \
@ -500,6 +511,8 @@ class UploadVideoView(LoginRequiredMixin, UpdateView):
def dispatch(self, request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
return super().handle_no_permission()
if user.registration.is_admin or user.registration.participates \
and user.registration.team.participation.pk == self.get_object().participation.pk:
return super().dispatch(request, *args, **kwargs)

View File

@ -72,10 +72,13 @@ class PhotoAuthorizationForm(forms.ModelForm):
Form to send a photo authorization.
"""
def clean_photo_authorization(self):
file = self.files["photo_authorization"]
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["photo_authorization"]
if "photo_authorization" in self.files:
file = self.files["photo_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["photo_authorization"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@ -19,7 +19,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
</p>
{% else %}
<p>
{% trans "The link was invalid. The token may have expired. Please send us an email to activate your account." %}
{% if user.is_authenticated and user.registration.email_confirmed %}
{% trans "The link was invalid. The token may have expired, or your account is already activated. However, your account seems to be already valid." %}
{% else %}
{% trans "The link was invalid. The token may have expired, or your account is already activated. Please send us an email to activate your account." %}
{% endif %}
</p>
{% endif %}
</div>

View File

@ -5,13 +5,14 @@ from corres2math.tokens import email_validation_token
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.management import call_command
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from participation.models import Phase
from participation.models import Phase, Team
from .models import AdminRegistration, CoachRegistration, StudentRegistration
@ -35,6 +36,24 @@ class TestIndexPage(TestCase):
response = self.client.get(reverse("registration:user_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("registration:user_detail", args=(1,)))
Team.objects.create()
response = self.client.get(reverse("participation:team_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:team_detail", args=(1,)))
response = self.client.get(reverse("participation:update_team", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:update_team", args=(1,)))
response = self.client.get(reverse("participation:create_team"))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:create_team"))
response = self.client.get(reverse("participation:join_team"))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:join_team"))
response = self.client.get(reverse("participation:team_authorizations", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next="
+ reverse("participation:team_authorizations", args=(1,)))
response = self.client.get(reverse("participation:participation_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next="
+ reverse("participation:participation_detail", args=(1,)))
response = self.client.get(reverse("participation:upload_video", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:upload_video", args=(1,)))
class TestRegistration(TestCase):
def setUp(self) -> None:
@ -268,6 +287,14 @@ class TestRegistration(TestCase):
))
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)
response = self.client.post(reverse("registration:upload_user_photo_authorization",
args=(self.student.registration.pk,)), data=dict(
photo_authorization=open("corres2math/static/Autorisation de droit à l'image - majeur.pdf", "rb"),

View File

@ -1,7 +1,5 @@
import os
from django_tables2 import SingleTableView
from corres2math.tokens import email_validation_token
from corres2math.views import AdminMixin
from django.conf import settings
@ -15,11 +13,12 @@ from django.urls import reverse_lazy
from django.utils.http import urlsafe_base64_decode
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View
from django_tables2 import SingleTableView
from magic import Magic
from participation.models import Phase
from .forms import CoachRegistrationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm
from .models import StudentRegistration, Registration
from .models import Registration, StudentRegistration
from .tables import RegistrationTable