Loading django/core/files/storage.py +4 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,10 @@ class FileSystemStorage(Storage): else: # This fun binary flag incantation makes os.open throw an # OSError if the file already exists before we open it. fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) flags = (os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) # The current umask value is masked out by os.open! fd = os.open(full_path, flags, 0o666) try: locks.lock(fd, locks.LOCK_EX) _file = None Loading docs/releases/1.5.txt +5 −0 Original line number Diff line number Diff line Loading @@ -333,6 +333,11 @@ Miscellaneous function at :func:`django.utils.text.slugify`. Similarly, ``remove_tags`` is available at :func:`django.utils.html.remove_tags`. * Uploaded files are no longer created as executable by default. If you need them to be executeable change :setting:`FILE_UPLOAD_PERMISSIONS` to your needs. The new default value is `0666` (octal) and the current umask value is first masked out. Features deprecated in 1.5 ========================== Loading tests/regressiontests/file_storage/tests.py +13 −4 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals import errno import os import shutil import sys import tempfile import time from datetime import datetime, timedelta Loading @@ -23,6 +24,7 @@ from django.core.files.uploadedfile import UploadedFile from django.test import SimpleTestCase from django.utils import six from django.utils import unittest from django.test.utils import override_settings from ..servers.tests import LiveServerBase # Try to import PIL in either of the two ways it can end up installed. Loading Loading @@ -433,22 +435,29 @@ class FileSaveRaceConditionTest(unittest.TestCase): self.storage.delete('conflict') self.storage.delete('conflict_1') @unittest.skipIf(sys.platform.startswith('win'), "Windows only partially supports umasks and chmod.") class FileStoragePermissions(unittest.TestCase): def setUp(self): self.old_perms = settings.FILE_UPLOAD_PERMISSIONS settings.FILE_UPLOAD_PERMISSIONS = 0o666 self.umask = 0o027 self.old_umask = os.umask(self.umask) self.storage_dir = tempfile.mkdtemp() self.storage = FileSystemStorage(self.storage_dir) def tearDown(self): settings.FILE_UPLOAD_PERMISSIONS = self.old_perms shutil.rmtree(self.storage_dir) os.umask(self.old_umask) @override_settings(FILE_UPLOAD_PERMISSIONS=0o654) def test_file_upload_permissions(self): name = self.storage.save("the_file", ContentFile("data")) actual_mode = os.stat(self.storage.path(name))[0] & 0o777 self.assertEqual(actual_mode, 0o666) self.assertEqual(actual_mode, 0o654) @override_settings(FILE_UPLOAD_PERMISSIONS=None) def test_file_upload_default_permissions(self): fname = self.storage.save("some_file", ContentFile("data")) mode = os.stat(self.storage.path(fname))[0] & 0o777 self.assertEqual(mode, 0o666 & ~self.umask) class FileStoragePathParsing(unittest.TestCase): def setUp(self): Loading Loading
django/core/files/storage.py +4 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,10 @@ class FileSystemStorage(Storage): else: # This fun binary flag incantation makes os.open throw an # OSError if the file already exists before we open it. fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) flags = (os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) # The current umask value is masked out by os.open! fd = os.open(full_path, flags, 0o666) try: locks.lock(fd, locks.LOCK_EX) _file = None Loading
docs/releases/1.5.txt +5 −0 Original line number Diff line number Diff line Loading @@ -333,6 +333,11 @@ Miscellaneous function at :func:`django.utils.text.slugify`. Similarly, ``remove_tags`` is available at :func:`django.utils.html.remove_tags`. * Uploaded files are no longer created as executable by default. If you need them to be executeable change :setting:`FILE_UPLOAD_PERMISSIONS` to your needs. The new default value is `0666` (octal) and the current umask value is first masked out. Features deprecated in 1.5 ========================== Loading
tests/regressiontests/file_storage/tests.py +13 −4 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals import errno import os import shutil import sys import tempfile import time from datetime import datetime, timedelta Loading @@ -23,6 +24,7 @@ from django.core.files.uploadedfile import UploadedFile from django.test import SimpleTestCase from django.utils import six from django.utils import unittest from django.test.utils import override_settings from ..servers.tests import LiveServerBase # Try to import PIL in either of the two ways it can end up installed. Loading Loading @@ -433,22 +435,29 @@ class FileSaveRaceConditionTest(unittest.TestCase): self.storage.delete('conflict') self.storage.delete('conflict_1') @unittest.skipIf(sys.platform.startswith('win'), "Windows only partially supports umasks and chmod.") class FileStoragePermissions(unittest.TestCase): def setUp(self): self.old_perms = settings.FILE_UPLOAD_PERMISSIONS settings.FILE_UPLOAD_PERMISSIONS = 0o666 self.umask = 0o027 self.old_umask = os.umask(self.umask) self.storage_dir = tempfile.mkdtemp() self.storage = FileSystemStorage(self.storage_dir) def tearDown(self): settings.FILE_UPLOAD_PERMISSIONS = self.old_perms shutil.rmtree(self.storage_dir) os.umask(self.old_umask) @override_settings(FILE_UPLOAD_PERMISSIONS=0o654) def test_file_upload_permissions(self): name = self.storage.save("the_file", ContentFile("data")) actual_mode = os.stat(self.storage.path(name))[0] & 0o777 self.assertEqual(actual_mode, 0o666) self.assertEqual(actual_mode, 0o654) @override_settings(FILE_UPLOAD_PERMISSIONS=None) def test_file_upload_default_permissions(self): fname = self.storage.save("some_file", ContentFile("data")) mode = os.stat(self.storage.path(fname))[0] & 0o777 self.assertEqual(mode, 0o666 & ~self.umask) class FileStoragePathParsing(unittest.TestCase): def setUp(self): Loading