Files
customerTicket/apps/attachments/delivery.py
T

35 lines
1.5 KiB
Python

import base64
import hashlib
import time
from urllib.parse import quote, urlencode
from django.conf import settings
from django.http import HttpResponseRedirect
def signed_media_redirect(relative_path, *, download=False, lifetime=300):
"""Create an Nginx secure_link URL after Django has authorized the request."""
safe_path = quote(str(relative_path).replace("\\", "/").lstrip("/"), safe="/")
uri = f"/protected-media/{safe_path}"
expires = int(time.time()) + lifetime
source = f"{expires}{uri} {settings.MEDIA_SIGNING_SECRET}".encode()
digest = hashlib.md5(source, usedforsecurity=False).digest()
signature = base64.urlsafe_b64encode(digest).rstrip(b"=").decode()
query = {"md5": signature, "expires": expires}
if download:
query["download"] = "1"
return HttpResponseRedirect(f"{uri}?{urlencode(query)}")
def attachment_response(attachment, *, download=False):
"""Deliver authorized bytes; confidential responses never use bearer URLs."""
import mimetypes
from django.http import FileResponse
if settings.USE_NGINX_MEDIA and not attachment.relative_path.startswith("dispatch-responses/"):
return signed_media_redirect(attachment.relative_path, download=download)
content_type = attachment.mime_type or mimetypes.guess_type(attachment.original_name)[0] or "application/octet-stream"
response = FileResponse(attachment.file.open("rb"), content_type=content_type,
as_attachment=download, filename=attachment.original_name)
response["X-Content-Type-Options"] = "nosniff"
return response