From e278b0950cc06ecf43cd339865d2366ffe1679df Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Tue, 26 Feb 2019 12:58:02 +0100 Subject: [PATCH 1/3] Fix #93 -- Always use POSIX style S3 keys --- s3file/forms.py | 12 ++++++------ tests/test_forms.py | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/s3file/forms.py b/s3file/forms.py index e0e9d99..2506d0c 100644 --- a/s3file/forms.py +++ b/s3file/forms.py @@ -1,5 +1,5 @@ import logging -import os +import pathlib import uuid from django.conf import settings @@ -13,7 +13,7 @@ class S3FileInputMixin: """FileInput that uses JavaScript to directly upload to Amazon S3.""" needs_multipart_form = False - upload_path = getattr(settings, 'S3FILE_UPLOAD_PATH', os.path.join('tmp', 's3file')) + upload_path = getattr(settings, 'S3FILE_UPLOAD_PATH', pathlib.PurePosixPath('tmp', 's3file')) expires = settings.SESSION_COOKIE_AGE @property @@ -29,7 +29,7 @@ def build_attrs(self, *args, **kwargs): accept = attrs.get('accept') response = self.client.generate_presigned_post( - self.bucket_name, os.path.join(self.upload_folder, '${filename}'), + self.bucket_name, str(pathlib.PurePosixPath(self.upload_folder, '${filename}')), Conditions=self.get_conditions(accept), ExpiresIn=self.expires, ) @@ -50,7 +50,7 @@ def build_attrs(self, *args, **kwargs): def get_conditions(self, accept): conditions = [ {"bucket": self.bucket_name}, - ["starts-with", "$key", self.upload_folder], + ["starts-with", "$key", str(self.upload_folder)], {"success_action_status": "201"}, ] if accept and ',' not in accept: @@ -66,10 +66,10 @@ def get_conditions(self, accept): @cached_property def upload_folder(self): - return os.path.join( + return str(pathlib.PurePosixPath( self.upload_path, uuid.uuid4().hex, - ) + )) # S3 uses POSIX paths class Media: js = ( diff --git a/tests/test_forms.py b/tests/test_forms.py index c1b2041..781e827 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -165,3 +165,7 @@ def test_file_insert_submit_value(self, driver, live_server, upload_file, freeze def test_media(self): assert ClearableFileInput().media._js == ['s3file/js/s3file.js'] + + def test_upload_folder(self): + assert ClearableFileInput().upload_folder.startswith('tmp/s3file/') + assert len(ClearableFileInput().upload_folder) == 43 From 3c07bf875dd9d74b084df06bf7ec76370c6d52d2 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Tue, 26 Feb 2019 13:00:59 +0100 Subject: [PATCH 2/3] Fix deprecation warnings in test setup --- tests/conftest.py | 2 +- tests/testapp/settings.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index c5fe447..83e6c6a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,7 +14,7 @@ def driver(): chrome_options.add_argument('headless') chrome_options.add_argument('window-size=1200x800') try: - b = webdriver.Chrome(chrome_options=chrome_options) + b = webdriver.Chrome(options=chrome_options) except WebDriverException as e: pytest.skip(force_text(e)) else: diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index 8a17763..4b62f80 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -52,3 +52,4 @@ AWS_STORAGE_BUCKET_NAME = 'test-bucket' AWS_S3_REGION_NAME = 'eu-central-1' AWS_S3_SIGNATURE_VERSION = 's3v4' +AWS_DEFAULT_ACL = None From e13f7d65bd00259b29a39dc2507682a528a4d828 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Tue, 26 Feb 2019 13:02:06 +0100 Subject: [PATCH 3/3] Switch to shorter base64 coded UUID in S3 key --- s3file/forms.py | 5 ++++- tests/test_forms.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/s3file/forms.py b/s3file/forms.py index 2506d0c..9c29e45 100644 --- a/s3file/forms.py +++ b/s3file/forms.py @@ -1,3 +1,4 @@ +import base64 import logging import pathlib import uuid @@ -68,7 +69,9 @@ def get_conditions(self, accept): def upload_folder(self): return str(pathlib.PurePosixPath( self.upload_path, - uuid.uuid4().hex, + base64.urlsafe_b64encode( + uuid.uuid4().bytes + ).decode('utf-8').rstrip('=\n'), )) # S3 uses POSIX paths class Media: diff --git a/tests/test_forms.py b/tests/test_forms.py index 781e827..2ad8780 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -168,4 +168,4 @@ def test_media(self): def test_upload_folder(self): assert ClearableFileInput().upload_folder.startswith('tmp/s3file/') - assert len(ClearableFileInput().upload_folder) == 43 + assert len(ClearableFileInput().upload_folder) == 33