Corp/backend/eusrr_backend/protected_media.py
Игорь Надеин 4f6244ab1f
Some checks failed
Deploy production / deploy (push) Failing after 2s
Fix CORP runtime errors and harden deployment and media access
2026-09-10 16:40:08 +03:00

53 lines
1.7 KiB
Python

"""Storage-backed private media responses; callers MUST authorize the resource."""
import mimetypes
from pathlib import Path
from urllib.parse import quote
from django.conf import settings
from django.http import FileResponse, Http404, HttpResponse
from django.utils.http import content_disposition_header
def protected_file_response(
attachment,
*,
filename,
storage_directory,
internal_prefix,
use_x_accel=False,
as_attachment=True,
):
local_path = None
if use_x_accel:
try:
local_path = attachment.path
except NotImplementedError:
pass
if local_path is not None:
try:
root = (Path(settings.MEDIA_ROOT) / storage_directory).resolve(strict=True)
path = Path(local_path).resolve(strict=True)
relative = path.relative_to(root)
if not path.is_file():
raise ValueError("not a file")
except (OSError, ValueError) as exc:
raise Http404("Файл недоступен") from exc
response = HttpResponse(
content_type=mimetypes.guess_type(filename)[0] or "application/octet-stream"
)
response["X-Accel-Redirect"] = internal_prefix + quote(
relative.as_posix(), safe="/"
)
response["Content-Disposition"] = content_disposition_header(
as_attachment, filename
)
else:
response = FileResponse(
attachment.open("rb"), as_attachment=as_attachment, filename=filename
)
response["Cache-Control"] = "private, no-store"
response["X-Content-Type-Options"] = "nosniff"
response["Content-Security-Policy"] = "sandbox"
return response