From 51a43989695c9dae1645387a5b893b3d00420f0c Mon Sep 17 00:00:00 2001 From: Jonas Winkler Date: Sat, 7 Nov 2020 23:25:50 +0100 Subject: [PATCH] updated document upload form --- src/documents/forms.py | 89 +++++++++--------------------------------- 1 file changed, 18 insertions(+), 71 deletions(-) diff --git a/src/documents/forms.py b/src/documents/forms.py index 3cdef448e..e6c7bbf41 100644 --- a/src/documents/forms.py +++ b/src/documents/forms.py @@ -1,4 +1,3 @@ -import magic import os from datetime import datetime @@ -6,77 +5,25 @@ from time import mktime from django import forms from django.conf import settings - -from .models import Document, Correspondent +from pathvalidate import validate_filename, ValidationError class UploadForm(forms.Form): - TYPE_LOOKUP = { - "application/pdf": Document.TYPE_PDF, - "image/png": Document.TYPE_PNG, - "image/jpeg": Document.TYPE_JPG, - "image/gif": Document.TYPE_GIF, - "image/tiff": Document.TYPE_TIF, - } - - correspondent = forms.CharField( - max_length=Correspondent._meta.get_field("name").max_length, - required=False - ) - title = forms.CharField( - max_length=Document._meta.get_field("title").max_length, - required=False - ) document = forms.FileField() - def __init__(self, *args, **kwargs): - forms.Form.__init__(self, *args, **kwargs) - self._file_type = None - - def clean_correspondent(self): - """ - I suppose it might look cleaner to use .get_or_create() here, but that - would also allow someone to fill up the db with bogus correspondents - before all validation was met. - """ - - corresp = self.cleaned_data.get("correspondent") - - if not corresp: - return None - - if not Correspondent.SAFE_REGEX.match(corresp) or " - " in corresp: - raise forms.ValidationError( - "That correspondent name is suspicious.") - - return corresp - - def clean_title(self): - - title = self.cleaned_data.get("title") - - if not title: - return None - - if not Correspondent.SAFE_REGEX.match(title) or " - " in title: - raise forms.ValidationError("That title is suspicious.") - - return title - def clean_document(self): + try: + validate_filename(self.cleaned_data.get("document").name) + except ValidationError: + raise forms.ValidationError("That filename is suspicious.") + return self.cleaned_data.get("document") - document = self.cleaned_data.get("document").read() - - with magic.Magic(flags=magic.MAGIC_MIME_TYPE) as m: - file_type = m.id_buffer(document) - - if file_type not in self.TYPE_LOOKUP: - raise forms.ValidationError("The file type is invalid.") - - self._file_type = self.TYPE_LOOKUP[file_type] - - return document + def get_filename(self, i=None): + return os.path.join( + settings.CONSUMPTION_DIR, + "{}_{}".format(str(i), self.cleaned_data.get("document").name) if i else self.cleaned_data.get("document").name + ) def save(self): """ @@ -85,15 +32,15 @@ class UploadForm(forms.Form): form do that as well. Think of it as a poor-man's queue server. """ - correspondent = self.cleaned_data.get("correspondent") - title = self.cleaned_data.get("title") - document = self.cleaned_data.get("document") + document = self.cleaned_data.get("document").read() t = int(mktime(datetime.now().timetuple())) - file_name = os.path.join( - settings.CONSUMPTION_DIR, - "{} - {}.{}".format(correspondent, title, self._file_type) - ) + + file_name = self.get_filename() + i = 0 + while os.path.exists(file_name): + i += 1 + file_name = self.get_filename(i) with open(file_name, "wb") as f: f.write(document)