From 42bfb8a80625690d570e3a385d86ca6f96ca2208 Mon Sep 17 00:00:00 2001 From: warrenchen Date: Wed, 17 Jun 2026 17:18:49 +0900 Subject: [PATCH] feat(media): Add media proxy view for serving files securely --- innovedus_cms/mysite/settings/base.py | 2 ++ innovedus_cms/mysite/urls.py | 2 ++ innovedus_cms/mysite/views.py | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 innovedus_cms/mysite/views.py diff --git a/innovedus_cms/mysite/settings/base.py b/innovedus_cms/mysite/settings/base.py index a7d563c..39b40ca 100644 --- a/innovedus_cms/mysite/settings/base.py +++ b/innovedus_cms/mysite/settings/base.py @@ -263,9 +263,11 @@ STORAGES = { "secret_key": os.environ.get("AWS_SECRET_ACCESS_KEY"), "bucket_name": os.environ.get("AWS_STORAGE_BUCKET_NAME"), "region_name": os.environ.get("AWS_S3_REGION_NAME", default="us-east-1"), + "endpoint_url": env_optional("AWS_S3_ENDPOINT_URL"), "default_acl": env_optional("AWS_S3_DEFAULT_ACL"), "querystring_auth": env_bool("AWS_S3_QUERYSTRING_AUTH", default=True), "custom_domain": env_optional("AWS_S3_CUSTOM_DOMAIN"), + "url_protocol": os.environ.get("AWS_S3_URL_PROTOCOL", "https:"), }, }, "staticfiles": { diff --git a/innovedus_cms/mysite/urls.py b/innovedus_cms/mysite/urls.py index f060942..7c07c75 100644 --- a/innovedus_cms/mysite/urls.py +++ b/innovedus_cms/mysite/urls.py @@ -9,11 +9,13 @@ from wagtail.documents import urls as wagtaildocs_urls from search import views as search_views from home import views as home_views from base import views as base_views +from mysite import views as mysite_views urlpatterns = [ path("django-admin/", admin.site.urls), path("admin/", include(wagtailadmin_urls)), path("documents/", include(wagtaildocs_urls)), + path("media/", mysite_views.media_proxy, name="media_proxy"), path("health", base_views.health_check, name="health_check"), # use so Unicode tag slugs (e.g. 台北美食) still resolve path("tags//", home_views.hashtag_search, name="hashtag_search"), diff --git a/innovedus_cms/mysite/views.py b/innovedus_cms/mysite/views.py new file mode 100644 index 0000000..33cb9b4 --- /dev/null +++ b/innovedus_cms/mysite/views.py @@ -0,0 +1,25 @@ +import mimetypes +import posixpath + +from django.core.exceptions import SuspiciousFileOperation +from django.core.files.storage import default_storage +from django.http import FileResponse, Http404 + + +def media_proxy(request, path): + normalized_path = posixpath.normpath(path).lstrip("/") + if ( + not normalized_path + or normalized_path == "." + or normalized_path.startswith("../") + or path.startswith("/") + ): + raise SuspiciousFileOperation("Invalid media path") + + try: + file_obj = default_storage.open(normalized_path, "rb") + except FileNotFoundError as exc: + raise Http404("Media file not found") from exc + + content_type, _ = mimetypes.guess_type(normalized_path) + return FileResponse(file_obj, content_type=content_type)