Better photo authorization upload

This commit is contained in:
Yohann D'ANELLO 2020-09-27 12:36:37 +02:00
parent c84d4151bb
commit 9ef35217d3
7 changed files with 79 additions and 40 deletions

View File

@ -4,7 +4,7 @@ ENV PYTHONUNBUFFERED 1
ENV DJANGO_ALLOW_ASYNC_UNSAFE 1
# Install LaTeX requirements
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev libmagic
RUN apk add --no-cache bash

View File

@ -2,6 +2,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.forms import FileInput
from django.utils.translation import gettext_lazy as _
from .models import AdminRegistration, CoachRegistration, StudentRegistration
@ -52,6 +53,10 @@ class PhotoAuthorizationForm(forms.ModelForm):
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)
self.fields["photo_authorization"].widget = FileInput()
class Meta:
model = StudentRegistration
fields = ('photo_authorization',)

View File

@ -1,3 +1,5 @@
from django.core.exceptions import ValidationError
from corres2math.tokens import email_validation_token
from django.contrib.sites.models import Site
from django.db import models
@ -68,7 +70,7 @@ class Registration(PolymorphicModel):
def get_random_filename(instance, filename):
return get_random_string(64)
return "authorization/photo/" + get_random_string(64)
class StudentRegistration(Registration):

View File

@ -1,3 +1,10 @@
import mimetypes
import os
from django.http import Http404, HttpResponse, FileResponse
from django.views.generic.base import View
from magic import Magic
from corres2math.tokens import email_validation_token
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
@ -164,5 +171,26 @@ class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
form_class = PhotoAuthorizationForm
template_name = "registration/upload_photo_authorization.html"
@transaction.atomic
def form_valid(self, form):
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
if old_instance.photo_authorization:
old_instance.photo_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):
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/photo/{filename}"
if not os.path.exists(path):
raise Http404
student = StudentRegistration.objects.get(photo_authorization__endswith=filename)
mime = Magic(mime=True)
mime_type = mime.from_file(path)
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
true_file_name = _("Photo authorization of {student}.{ext}").format(student=str(student), ext=ext)
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)

View File

@ -18,8 +18,7 @@ from django.contrib import admin
from django.urls import path, include
from django.views.defaults import bad_request, permission_denied, page_not_found, server_error
from django.views.generic import TemplateView
from corres2math import settings
from registration.views import PhotoAuthorizationView
urlpatterns = [
path('', TemplateView.as_view(template_name="index.html"), name='index'),
@ -32,12 +31,11 @@ urlpatterns = [
path('participation/', include('participation.urls')),
path('registration/', include('registration.urls')),
path('media/authorization/photo/<str:filename>/', PhotoAuthorizationView.as_view(), name='photo_authorization'),
path('', include('eastereggs.urls')),
]
# FIXME Protect files
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler400 = bad_request
handler403 = permission_denied
handler404 = page_not_found

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Corres2math\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-27 11:18+0200\n"
"POT-Creation-Date: 2020-09-27 12:35+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"
@ -38,7 +38,7 @@ msgstr "Fermer"
msgid "Logs"
msgstr "Logs"
#: apps/logs/models.py:22 apps/registration/models.py:16
#: apps/logs/models.py:22 apps/registration/models.py:18
msgid "user"
msgstr "utilisateur"
@ -141,7 +141,7 @@ msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:45 apps/participation/models.py:56
#: apps/registration/models.py:81 apps/registration/models.py:127
#: apps/registration/models.py:83 apps/registration/models.py:129
msgid "team"
msgstr "équipe"
@ -302,104 +302,104 @@ msgstr "Vous n'êtes pas dans une équipe."
msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
#: apps/registration/forms.py:12
#: apps/registration/forms.py:13
msgid "role"
msgstr "rôle"
#: apps/registration/forms.py:14
#: apps/registration/forms.py:15
msgid "participant"
msgstr "participant"
#: apps/registration/forms.py:15 apps/registration/models.py:136
#: apps/registration/forms.py:16 apps/registration/models.py:138
msgid "coach"
msgstr "encadrant"
#: apps/registration/forms.py:52
#: apps/registration/forms.py:53
msgid "The uploaded file must be a PDF, PNG of JPEG file."
msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG."
#: apps/registration/models.py:21
#: apps/registration/models.py:23
msgid "Grant Animath to contact me in the future about other actions"
msgstr ""
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
#: apps/registration/models.py:26
#: apps/registration/models.py:28
msgid "email confirmed"
msgstr "email confirmé"
#: apps/registration/models.py:30
#: apps/registration/models.py:32
msgid "Activate your Correspondances account"
msgstr "Activez votre compte des Correspondances"
#: apps/registration/models.py:66
#: apps/registration/models.py:68
msgid "registration"
msgstr "inscription"
#: apps/registration/models.py:67
#: apps/registration/models.py:69
msgid "registrations"
msgstr "inscriptions"
#: apps/registration/models.py:86
#: apps/registration/models.py:88
msgid "12th grade"
msgstr "Terminale"
#: apps/registration/models.py:87
#: apps/registration/models.py:89
msgid "11th grade"
msgstr "Première"
#: apps/registration/models.py:88
#: apps/registration/models.py:90
msgid "10th grade or lower"
msgstr "Seconde ou inférieur"
#: apps/registration/models.py:90
#: apps/registration/models.py:92
msgid "student class"
msgstr "classe"
#: apps/registration/models.py:95
#: apps/registration/models.py:97
msgid "school"
msgstr "école"
#: apps/registration/models.py:100
#: apps/registration/models.py:102
msgid "photo authorization"
msgstr "autorisation de droit à l'image"
#: apps/registration/models.py:108
#: apps/registration/models.py:110
msgid "student"
msgstr "étudiant"
#: apps/registration/models.py:116
#: apps/registration/models.py:118
msgid "student registration"
msgstr "inscription d'élève"
#: apps/registration/models.py:117
#: apps/registration/models.py:119
msgid "student registrations"
msgstr "inscriptions d'élève"
#: apps/registration/models.py:131
#: apps/registration/models.py:133
msgid "professional activity"
msgstr "activité professionnelle"
#: apps/registration/models.py:144
#: apps/registration/models.py:146
msgid "coach registration"
msgstr "inscription d'encadrant"
#: apps/registration/models.py:145
#: apps/registration/models.py:147
msgid "coach registrations"
msgstr "inscriptions d'encadrants"
#: apps/registration/models.py:150
#: apps/registration/models.py:152
msgid "role of the administrator"
msgstr "rôle de l'administrateur"
#: apps/registration/models.py:155
#: apps/registration/models.py:157
msgid "admin"
msgstr "admin"
#: apps/registration/models.py:163
#: apps/registration/models.py:165
msgid "admin registration"
msgstr "inscription d'administrateur"
#: apps/registration/models.py:164
#: apps/registration/models.py:166
msgid "admin registrations"
msgstr "inscriptions d'administrateur"
@ -635,26 +635,31 @@ msgstr "Modifier l'utilisateur"
msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/views.py:56
#: apps/registration/views.py:63
msgid "Email validation"
msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:58
#: apps/registration/views.py:65
msgid "Validate email"
msgstr "Valider l'adresse mail"
#: apps/registration/views.py:97
#: apps/registration/views.py:104
msgid "Email validation unsuccessful"
msgstr "Échec de la validation de l'adresse mail"
#: apps/registration/views.py:108
#: apps/registration/views.py:115
msgid "Email validation email sent"
msgstr "Mail de confirmation de l'adresse mail envoyé"
#: apps/registration/views.py:116
#: apps/registration/views.py:123
msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail"
#: apps/registration/views.py:195
#, python-brace-format
msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: corres2math/settings.py:150
msgid "English"
msgstr "Anglais"

View File

@ -9,4 +9,5 @@ django-tables2
djangorestframework
django-rest-polymorphic
ptpython
python-magic
gunicorn