forked from CGM_Public/pretix_original
102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
import logging
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile
|
|
from django.utils.translation import gettext_lazy as _
|
|
from pretix.control.forms import ClearableBasenameFileInput
|
|
from django.core.files import File
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def validate_rsa_privkey(value: File):
|
|
value = value.read().strip()
|
|
if isinstance(value, bytes):
|
|
value = value.decode()
|
|
if not value:
|
|
return
|
|
if not re.match(r"^-----BEGIN( (RSA |ENCRYPTED )?PRIVATE KEY-----).*-----END\1$", value, re.DOTALL):
|
|
raise ValidationError(
|
|
_(
|
|
"This does not look like an RSA private key in PEM format (it misses the correct begin or end signifiers)"
|
|
),
|
|
)
|
|
|
|
|
|
class CertificateFileField(forms.FileField):
|
|
widget = ClearableBasenameFileInput
|
|
|
|
def clean(self, value, *args, **kwargs):
|
|
value = super().clean(value, *args, **kwargs)
|
|
if isinstance(value, UploadedFile):
|
|
value.open("rb")
|
|
value.seek(0)
|
|
content = value.read()
|
|
if (
|
|
content.startswith(b"-----BEGIN CERTIFICATE-----")
|
|
and b"-----BEGIN CERTIFICATE-----" in content
|
|
):
|
|
return SimpleUploadedFile("cert.pem", content, "text/plain")
|
|
|
|
openssl_cmd = [
|
|
"openssl",
|
|
"x509",
|
|
"-inform",
|
|
"DER",
|
|
"-outform",
|
|
"PEM",
|
|
]
|
|
process = subprocess.Popen(
|
|
openssl_cmd,
|
|
stderr=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stdin=subprocess.PIPE,
|
|
)
|
|
process.stdin.write(content)
|
|
pem, error = process.communicate()
|
|
if process.returncode != 0:
|
|
logger.info("Trying to convert a DER to PEM failed: {}".format(error))
|
|
raise ValidationError(
|
|
_(
|
|
"This does not look like a X509 certificate in either PEM or DER format"
|
|
),
|
|
)
|
|
|
|
return SimpleUploadedFile("cert.pem", pem, "text/plain")
|
|
return value
|
|
|
|
|
|
class PNGImageField(forms.FileField):
|
|
widget = ClearableBasenameFileInput
|
|
|
|
def clean(self, value, *args, **kwargs):
|
|
value = super().clean(value, *args, **kwargs)
|
|
if isinstance(value, UploadedFile):
|
|
try:
|
|
from PIL import Image
|
|
except ImportError:
|
|
return value
|
|
|
|
value.open("rb")
|
|
value.seek(0)
|
|
try:
|
|
with (
|
|
Image.open(value, formats=settings.PILLOW_FORMATS_IMAGE) as im,
|
|
tempfile.NamedTemporaryFile("rb", suffix=".png") as tmpfile,
|
|
):
|
|
im.save(tmpfile.name)
|
|
tmpfile.seek(0)
|
|
return SimpleUploadedFile(
|
|
"picture.png", tmpfile.read(), "image png"
|
|
)
|
|
except IOError:
|
|
logger.exception("Could not convert image to PNG.")
|
|
raise ValidationError(
|
|
_("The file you uploaded could not be converted to PNG format.")
|
|
)
|
|
|
|
return value
|