snapshot: preserve upload hardening phase
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
from django import forms
|
||||
from pathlib import Path
|
||||
from datetime import timedelta
|
||||
from django.contrib.auth import authenticate, get_user_model, password_validation
|
||||
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm, PasswordResetForm, SetPasswordForm
|
||||
@@ -12,6 +11,13 @@ from .form_builder import apply_form_field_config
|
||||
from .models import EmployeeProfile, FormOption, OffboardingRequest, OnboardingRequest, PortalBranding, PortalCompanyConfig, PortalTrialConfig, UserProfile, WorkflowConfig
|
||||
from .roles import ROLE_ADMIN, ROLE_GROUP_NAMES, ROLE_IT_STAFF, ROLE_LABELS, ROLE_PLATFORM_OWNER, ROLE_STAFF, ROLE_SUPER_ADMIN, assign_user_role, user_has_capability
|
||||
from .totp import normalize_recovery_code, normalize_totp_token, verify_totp_token
|
||||
from .upload_validation import (
|
||||
validate_avatar_upload,
|
||||
validate_favicon_upload,
|
||||
validate_logo_upload,
|
||||
validate_pdf_upload,
|
||||
validate_signature_upload,
|
||||
)
|
||||
|
||||
|
||||
YES_NO_CHOICES = [('', '--'), ('ja', 'Ja'), ('nein', 'Nein')]
|
||||
@@ -233,10 +239,7 @@ class AccountAvatarForm(forms.ModelForm):
|
||||
|
||||
def clean_avatar_image(self):
|
||||
avatar = self.cleaned_data.get('avatar_image')
|
||||
if not avatar:
|
||||
return avatar
|
||||
if getattr(avatar, 'size', 0) > 5 * 1024 * 1024:
|
||||
raise forms.ValidationError(_('Das Profilbild darf maximal 5 MB groß sein.'))
|
||||
validate_avatar_upload(avatar)
|
||||
return avatar
|
||||
|
||||
|
||||
@@ -565,26 +568,17 @@ class PortalBrandingForm(forms.ModelForm):
|
||||
|
||||
def clean_logo_image(self):
|
||||
logo = self.cleaned_data.get('logo_image')
|
||||
if not logo:
|
||||
return logo
|
||||
if getattr(logo, 'size', 0) > 5 * 1024 * 1024:
|
||||
raise forms.ValidationError(_('Das Logo darf maximal 5 MB groß sein.'))
|
||||
validate_logo_upload(logo)
|
||||
return logo
|
||||
|
||||
def clean_pdf_letterhead(self):
|
||||
letterhead = self.cleaned_data.get('pdf_letterhead')
|
||||
if not letterhead:
|
||||
return letterhead
|
||||
if getattr(letterhead, 'size', 0) > 10 * 1024 * 1024:
|
||||
raise forms.ValidationError(_('Der PDF-Briefkopf darf maximal 10 MB groß sein.'))
|
||||
validate_pdf_upload(letterhead)
|
||||
return letterhead
|
||||
|
||||
def clean_favicon_image(self):
|
||||
favicon = self.cleaned_data.get('favicon_image')
|
||||
if not favicon:
|
||||
return favicon
|
||||
if getattr(favicon, 'size', 0) > 2 * 1024 * 1024:
|
||||
raise forms.ValidationError(_('Das Favicon darf maximal 2 MB groß sein.'))
|
||||
validate_favicon_upload(favicon)
|
||||
return favicon
|
||||
|
||||
|
||||
@@ -832,36 +826,7 @@ class OnboardingRequestForm(forms.ModelForm):
|
||||
|
||||
def clean_signature_image(self):
|
||||
image = self.cleaned_data.get('signature_image')
|
||||
if not image:
|
||||
return image
|
||||
max_size = 4 * 1024 * 1024 # 4 MB
|
||||
if image.size > max_size:
|
||||
raise forms.ValidationError('Die Signatur-Datei ist zu groß (max. 4 MB).')
|
||||
content_type = (getattr(image, 'content_type', '') or '').lower().strip()
|
||||
extension = Path(getattr(image, 'name', '')).suffix.lower()
|
||||
allowed_content_types = {
|
||||
'image/png',
|
||||
'image/x-png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/pjpeg',
|
||||
}
|
||||
allowed_extensions = {'.png', '.jpg', '.jpeg'}
|
||||
if content_type and not content_type.startswith('image/'):
|
||||
raise forms.ValidationError('Bitte eine PNG- oder JPG-Datei hochladen.')
|
||||
if content_type and content_type not in allowed_content_types and extension not in allowed_extensions:
|
||||
raise forms.ValidationError('Bitte eine PNG- oder JPG-Datei hochladen.')
|
||||
if not content_type and extension not in allowed_extensions:
|
||||
raise forms.ValidationError('Bitte eine PNG- oder JPG-Datei hochladen.')
|
||||
try:
|
||||
header = image.read(16)
|
||||
image.seek(0)
|
||||
except Exception:
|
||||
raise forms.ValidationError('Die Signatur-Datei konnte nicht gelesen werden.')
|
||||
is_png = header.startswith(b'\x89PNG\r\n\x1a\n')
|
||||
is_jpeg = header.startswith(b'\xff\xd8\xff')
|
||||
if not (is_png or is_jpeg):
|
||||
raise forms.ValidationError('Die Signatur-Datei ist kein gültiges PNG/JPG-Bild.')
|
||||
validate_signature_upload(image)
|
||||
return image
|
||||
|
||||
def clean(self):
|
||||
|
||||
Reference in New Issue
Block a user