Pārlūkot izejas kodu

Fixed #8454: added a FILE_UPLOAD_PERMISSIONS setting to control the permissoin of files uploaded by the built-in file storage system. Thanks, dcwatson.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8640 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Jacob Kaplan-Moss 16 gadi atpakaļ
vecāks
revīzija
ff420b4364

+ 4 - 0
django/conf/global_settings.py

@@ -252,6 +252,10 @@ FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440 # i.e. 2.5 MB
 # (i.e. "/tmp" on *nix systems).
 FILE_UPLOAD_TEMP_DIR = None
 
+# The numeric mode to set newly-uploaded files to. The value should be a mode
+# you'd pass directly to os.chmod; see http://docs.python.org/lib/os-file-dir.html.
+FILE_UPLOAD_PERMISSIONS = None
+
 # Default formatting for date objects. See all available format strings here:
 # http://www.djangoproject.com/documentation/templates/#now
 DATE_FORMAT = 'N j, Y'

+ 4 - 1
django/core/files/storage.py

@@ -172,7 +172,10 @@ class FileSystemStorage(Storage):
             else:
                 # OK, the file save worked. Break out of the loop.
                 break
-                
+        
+        if settings.FILE_UPLOAD_PERMISSIONS is not None:
+            os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)
+        
         return name
 
     def delete(self, name):

+ 34 - 0
docs/ref/settings.txt

@@ -453,6 +453,8 @@ Default: ``'utf-8'``
 The character encoding used to decode any files read from disk. This includes
 template files and initial SQL data files.
 
+.. setting:: FILE_UPLOAD_HANDLERS
+
 FILE_UPLOAD_HANDLERS
 --------------------
 
@@ -465,6 +467,8 @@ Default::
 
 A tuple of handlers to use for uploading. See :ref:`topics-files` for details.
 
+.. setting:: FILE_UPLOAD_MAX_MEMORY_SIZE
+
 FILE_UPLOAD_MAX_MEMORY_SIZE
 ---------------------------
 
@@ -475,6 +479,8 @@ Default: ``2621440`` (i.e. 2.5 MB).
 The maximum size (in bytes) that an upload will be before it gets streamed to
 the file system. See :ref:`topics-files` for details.
 
+.. setting:: FILE_UPLOAD_TEMP_DIR
+
 FILE_UPLOAD_TEMP_DIR
 --------------------
 
@@ -488,6 +494,34 @@ example, this will default to '/tmp' on \*nix-style operating systems.
 
 See :ref:`topics-files` for details.
 
+.. setting:: FILE_UPLOAD_PERMISSIONS
+
+FILE_UPLOAD_PERMISSIONS
+-----------------------
+
+Default: ``None``
+
+The numeric mode (i.e. ``0644``) to set newly uploaded files to. For
+more information about what these modes mean, see the `documentation for
+os.chmod`_
+
+If this isn't given or is ``None``, you'll get operating-system
+dependent behavior. On most platforms, temporary files will have a mode
+of ``0600``, and files saved from memory will be saved using the
+system's standard umask.
+
+.. warning::
+
+    **Always prefix the mode with a 0.**
+    
+    If you're not familiar with file modes, please note that the leading
+    ``0`` is very important: it indicates an octal number, which is the
+    way that modes must be specified. If you try to use ``644``, you'll
+    get totally incorrect behavior.
+    
+
+.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html 
+
 .. setting:: FIXTURE_DIRS
 
 FIXTURE_DIRS

+ 33 - 13
docs/topics/http/file-uploads.txt

@@ -122,25 +122,43 @@ Changing upload handler behavior
 
 Three settings control Django's file upload behavior:
 
-    ``FILE_UPLOAD_MAX_MEMORY_SIZE``
-        The maximum size, in bytes, for files that will be uploaded
-        into memory. Files larger than ``FILE_UPLOAD_MAX_MEMORY_SIZE``
-        will be streamed to disk.
+    :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`
+        The maximum size, in bytes, for files that will be uploaded into memory.
+        Files larger than :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` will be
+        streamed to disk.
 
         Defaults to 2.5 megabytes.
 
-    ``FILE_UPLOAD_TEMP_DIR``
-        The directory where uploaded files larger than ``FILE_UPLOAD_TEMP_DIR``
-        will be stored.
+    :setting:`FILE_UPLOAD_TEMP_DIR`
+        The directory where uploaded files larger than
+        :setting:`FILE_UPLOAD_TEMP_DIR` will be stored.
 
         Defaults to your system's standard temporary directory (i.e. ``/tmp`` on
         most Unix-like systems).
-
-    ``FILE_UPLOAD_HANDLERS``
-        The actual handlers for uploaded files. Changing this setting
-        allows complete customization -- even replacement -- of
-        Django's upload process. See `upload handlers`_, below,
-        for details.
+        
+    :setting:`FILE_UPLOAD_PERMISSIONS`
+        The numeric mode (i.e. ``0644``) to set newly uploaded files to. For
+        more information about what these modes mean, see the `documentation for
+        os.chmod`_
+        
+        If this isn't given or is ``None``, you'll get operating-system
+        dependent behavior. On most platforms, temporary files will have a mode
+        of ``0600``, and files saved from memory will be saved using the
+        system's standard umask.
+        
+        .. warning::
+        
+            If you're not familiar with file modes, please note that the leading
+            ``0`` is very important: it indicates an octal number, which is the
+            way that modes must be specified. If you try to use ``644``, you'll
+            get totally incorrect behavior.
+            
+            **Always prefix the mode with a ``0``.**
+
+    :setting:`FILE_UPLOAD_HANDLERS`
+        The actual handlers for uploaded files. Changing this setting allows
+        complete customization -- even replacement -- of Django's upload
+        process. See `upload handlers`_, below, for details.
 
         Defaults to::
 
@@ -150,6 +168,8 @@ Three settings control Django's file upload behavior:
         Which means "try to upload to memory first, then fall back to temporary
         files."
 
+.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html 
+
 ``UploadedFile`` objects
 ========================
 

+ 14 - 1
tests/regressiontests/file_storage/tests.py

@@ -86,9 +86,10 @@ u'custom_storage.2'
 # Tests for a race condition on file saving (#4948).
 # This is written in such a way that it'll always pass on platforms 
 # without threading.
-
+import os
 import time
 from unittest import TestCase
+from django.conf import settings
 from django.core.files.base import ContentFile
 from models import temp_storage
 try:
@@ -117,3 +118,15 @@ class FileSaveRaceConditionTest(TestCase):
         temp_storage.delete('conflict')
         temp_storage.delete('conflict_')
 
+class FileStoragePermissions(TestCase):
+    def setUp(self):
+        self.old_perms = settings.FILE_UPLOAD_PERMISSIONS
+        settings.FILE_UPLOAD_PERMISSIONS = 0666
+        
+    def test_file_upload_permissions(self):
+        name = temp_storage.save("the_file", ContentFile("data"))
+        actual_mode = os.stat(temp_storage.path(name))[0] & 0777
+        self.assertEqual(actual_mode, 0666)
+        
+    def tearDown(self):
+        settings.FILE_UPLOAD_PERMISSIONS = self.old_perms