from types import SimpleNamespace import pytest from django.core.files.base import ContentFile from django.http import Http404 from api.v1.documents.media_delivery import document_file_response def test_nginx_response_is_internal_escaped_and_does_not_read_file(settings, tmp_path): settings.MEDIA_ROOT = tmp_path settings.DOCUMENTS_USE_X_ACCEL_REDIRECT = True path = tmp_path / "documents" / "public" / "контракт #1.pdf" path.parent.mkdir(parents=True) path.write_bytes(b"private document") response = document_file_response(SimpleNamespace(path=path), filename=path.name) assert response["X-Accel-Redirect"].startswith("/_protected_documents/public/%") assert "%20%231.pdf" in response["X-Accel-Redirect"] assert response.content == b"" assert response["Cache-Control"] == "private, no-store" assert response["Content-Type"] == "application/pdf" def test_nginx_response_rejects_outside_paths_and_missing_files(settings, tmp_path): settings.MEDIA_ROOT = tmp_path settings.DOCUMENTS_USE_X_ACCEL_REDIRECT = True (tmp_path / "documents").mkdir() outside = tmp_path / "private.env" outside.write_bytes(b"not document data") for path in ( outside, tmp_path / "documents" / "missing.pdf", tmp_path / "documents", ): with pytest.raises(Http404): document_file_response(SimpleNamespace(path=path), filename="file.pdf") def test_nginx_response_rejects_symlink_escape(settings, tmp_path): settings.MEDIA_ROOT = tmp_path settings.DOCUMENTS_USE_X_ACCEL_REDIRECT = True (tmp_path / "documents").mkdir() outside = tmp_path / "private.env" outside.write_bytes(b"not document data") link = tmp_path / "documents" / "link.pdf" try: link.symlink_to(outside) except OSError: pytest.skip("Creating symlinks is unavailable on this host") with pytest.raises(Http404): document_file_response(SimpleNamespace(path=link), filename="file.pdf") @pytest.mark.parametrize("accelerated", [True, False]) @pytest.mark.django_db def test_document_file_response_supports_nonlocal_storage(settings, accelerated): settings.DOCUMENTS_USE_X_ACCEL_REDIRECT = accelerated class RemoteFile: @property def path(self): raise NotImplementedError def open(self, mode): return ContentFile(b"authorized remote content", name="document.pdf") response = document_file_response(RemoteFile(), filename="document.pdf") assert "X-Accel-Redirect" not in response assert b"".join(response.streaming_content) == b"authorized remote content" response.close()