Validate screenshot MIME and filename metadata
This commit is contained in:
@@ -182,7 +182,7 @@ def add_screenshot(report_id: UUID, db: Db, screenshot: UploadFile = File()) ->
|
||||
raise HTTPException(status_code=409, detail="screenshot already uploaded")
|
||||
raw = screenshot.file.read(settings.screenshot_max_bytes + 1)
|
||||
try:
|
||||
report.screenshot_key = upload_screenshot(raw)
|
||||
report.screenshot_key = upload_screenshot(raw, filename=screenshot.filename, content_type=screenshot.content_type)
|
||||
except ScreenshotError as exc:
|
||||
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
||||
db.commit()
|
||||
|
||||
+10
-1
@@ -17,6 +17,14 @@ class ScreenshotError(ValueError):
|
||||
|
||||
|
||||
ALLOWED_FORMATS = {"JPEG": ("jpg", "image/jpeg"), "PNG": ("png", "image/png"), "WEBP": ("webp", "image/webp")}
|
||||
ALLOWED_UPLOADS = {"image/jpeg": {".jpg", ".jpeg"}, "image/png": {".png"}, "image/webp": {".webp"}}
|
||||
|
||||
|
||||
def validate_upload_metadata(filename: str | None, content_type: str | None) -> None:
|
||||
mime = (content_type or "").lower()
|
||||
suffix = f".{(filename or '').rsplit('.', 1)[-1].lower()}" if "." in (filename or "") else ""
|
||||
if mime not in ALLOWED_UPLOADS or suffix not in ALLOWED_UPLOADS[mime]:
|
||||
raise ScreenshotError("filename extension and MIME type must match JPEG, PNG or WebP")
|
||||
|
||||
|
||||
@lru_cache
|
||||
@@ -50,7 +58,8 @@ def prepare_image(raw: bytes) -> tuple[bytes, str, str]:
|
||||
raise ScreenshotError("file is not a valid image") from exc
|
||||
|
||||
|
||||
def upload_screenshot(raw: bytes) -> str:
|
||||
def upload_screenshot(raw: bytes, *, filename: str | None = None, content_type: str | None = None) -> str:
|
||||
validate_upload_metadata(filename, content_type)
|
||||
body, extension, mime = prepare_image(raw)
|
||||
key = f"reports/{uuid.uuid4()}.{extension}"
|
||||
s3 = client()
|
||||
|
||||
Reference in New Issue
Block a user