[Zodb-checkins] SVN: ZODB/branches/patricks-blob-dir-perm/src/ZODB/ preserve legacy behavior if explicit blob dir permissions are not

Patrick Strawderman cvs-admin at zope.org
Wed Oct 17 14:47:56 UTC 2012


Log message for revision 128024:
  preserve legacy behavior if explicit blob dir permissions are not
  specified, add tests.
  

Changed:
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/FileStorage/FileStorage.py
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/blob.py
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/component.xml
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/config.py
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testFileStorage.py
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testMVCCMappingStorage.py
  U   ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testblob.py

-=-
Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/FileStorage/FileStorage.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/FileStorage/FileStorage.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/FileStorage/FileStorage.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -107,7 +107,7 @@
 
     def __init__(self, file_name, create=False, read_only=False, stop=None,
                  quota=None, pack_gc=True, pack_keep_old=True, packer=None,
-                 blob_dir=None):
+                 blob_dir=None, blob_dir_permissions=None):
 
         if read_only:
             self._is_read_only = True
@@ -210,7 +210,7 @@
             if create and os.path.exists(self.blob_dir):
                 ZODB.blob.remove_committed_dir(self.blob_dir)
 
-            self._blob_init(blob_dir)
+            self._blob_init(blob_dir, permissions=blob_dir_permissions)
             zope.interface.alsoProvides(self,
                                         ZODB.interfaces.IBlobStorageRestoreable)
         else:

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/blob.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/blob.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/blob.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -20,6 +20,7 @@
 import binascii
 import logging
 import os
+import os.path
 import re
 import shutil
 import stat
@@ -322,7 +323,8 @@
     # with blobs and storages needn't indirect through this if they
     # want to perform blob storage differently.
 
-    blob_dir_permissions = 0700
+    default_blob_dir_permissions = 0700
+    blob_dir_permissions = None
 
     def __init__(self, base_dir, layout_name='automatic', permissions=None):
         self.base_dir = os.path.abspath(base_dir) + os.path.sep
@@ -340,11 +342,21 @@
             self.blob_dir_permissions = permissions
 
     def makedirs(self, path):
-        umask = os.umask(0)
-        try:
-            os.makedirs(path, self.blob_dir_permissions)
-        finally:
-            os.umask(umask)
+        if self.blob_dir_permissions:
+            dirs = [path]
+            head, tail = os.path.split(path)
+            if not tail:
+                head, tail = os.path.split(head)
+            while head and tail and not os.path.exists(head):
+                dirs.append(head)
+                head, tail = os.path.split(head)
+            os.makedirs(path)
+            for path in dirs:
+                os.chmod(path, self.blob_dir_permissions)
+        else:
+            # we preserve legacy behavior here when explicit blob
+            # dir permissions are not specified.
+            os.makedirs(path, self.default_blob_dir_permissions)
 
     def create(self):
         if not os.path.exists(self.base_dir):
@@ -370,12 +382,11 @@
                     (self.layout_name, self.base_dir, layout))
 
     def isSecure(self, path):
-        """Ensure that (POSIX) path mode bits for others is 0."""
-        # XXX
-        return (os.stat(path).st_mode & stat.S_IRWXO) == 0
+        """Ensure that (POSIX) path mode bits are 0700."""
+        return (os.stat(path).st_mode & 077) == 0
 
     def checkSecure(self):
-        if not self.isSecure(self.base_dir):
+        if not (self.blob_dir_permissions or self.isSecure(self.base_dir)):
             log('Blob dir %s has insecure mode setting' % self.base_dir,
                 level=logging.WARNING)
 
@@ -705,11 +716,12 @@
     """
 
 
-    def __init__(self, base_directory, storage, layout='automatic'):
+    def __init__(self, base_directory, storage, layout='automatic',
+        permissions=None):
         assert not ZODB.interfaces.IBlobStorage.providedBy(storage)
         self.__storage = storage
 
-        self._blob_init(base_directory, layout)
+        self._blob_init(base_directory, layout, permissions=permissions)
         try:
             supportsUndo = storage.supportsUndo
         except AttributeError:

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/component.xml
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/component.xml	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/component.xml	2012-10-17 14:47:52 UTC (rev 128024)
@@ -23,6 +23,13 @@
         use a BlobStorage to provide blob support.)
       </description>
     </key>
+    <key name="blob-dir-permissions" required="no" datatype="string">
+      <description>
+        The octal representation of the permissions that should be
+        applied to any sub-directories created in the blob dir,
+        and the blob dir itself on initial creation.
+      </description>
+    </key>
     <key name="create" datatype="boolean">
       <description>
         Flag that indicates whether the storage should be truncated if

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/config.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/config.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/config.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -169,7 +169,7 @@
                 options['packer'] = getattr(m, name)
 
         for name in ('blob_dir', 'create', 'read_only', 'quota', 'pack_gc',
-                     'pack_keep_old'):
+                     'pack_keep_old', 'blob_dir_permissions'):
             v = getattr(config, name, self)
             if v is not self:
                 options[name] = v

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testFileStorage.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testFileStorage.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testFileStorage.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -676,16 +676,18 @@
         tearDown=zope.testing.setupstack.tearDown))
     suite.addTest(ZODB.tests.testblob.storage_reusable_suite(
         'BlobFileStorage',
-        lambda name, blob_dir:
-        ZODB.FileStorage.FileStorage('%s.fs' % name, blob_dir=blob_dir),
+        lambda name, blob_dir, permissions=None:
+        ZODB.FileStorage.FileStorage('%s.fs' % name, blob_dir=blob_dir,
+            blob_dir_permissions=permissions),
         test_blob_storage_recovery=True,
         test_packing=True,
         ))
     suite.addTest(ZODB.tests.testblob.storage_reusable_suite(
         'BlobFileHexStorage',
-        lambda name, blob_dir:
+        lambda name, blob_dir, permissions=None:
         ZODB.tests.hexstorage.HexStorage(
-            ZODB.FileStorage.FileStorage('%s.fs' % name, blob_dir=blob_dir)),
+            ZODB.FileStorage.FileStorage('%s.fs' % name, blob_dir=blob_dir,
+                blob_dir_permissions=permissions)),
         test_blob_storage_recovery=True,
         test_packing=True,
         ))

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testMVCCMappingStorage.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testMVCCMappingStorage.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testMVCCMappingStorage.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -122,8 +122,8 @@
             self.assert_(r2['gamma']['delta'] == 'yes')
         finally:
             db.close()
-    
 
+
 class MVCCMappingStorageTests(
     StorageTestBase.StorageTestBase,
     BasicStorage.BasicStorage,
@@ -168,9 +168,9 @@
         self._storage.tpc_begin(t)
         self.assertEqual(self._storage._tid, 'zzzzzzzz')
 
-def create_blob_storage(name, blob_dir):
+def create_blob_storage(name, blob_dir, permissions=None):
     s = MVCCMappingStorage(name)
-    return ZODB.blob.BlobStorage(blob_dir, s)
+    return ZODB.blob.BlobStorage(blob_dir, s, permissions=permissions)
 
 def test_suite():
     suite = unittest.makeSuite(MVCCMappingStorageTests, 'check')

Modified: ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testblob.py
===================================================================
--- ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testblob.py	2012-10-16 19:52:10 UTC (rev 128023)
+++ ZODB/branches/patricks-blob-dir-perm/src/ZODB/tests/testblob.py	2012-10-17 14:47:52 UTC (rev 128024)
@@ -446,9 +446,41 @@
     >>> blob_storage.fshelper.isSecure(tmp_dir)
     False
 
+    >>> blob_storage.close()
+
+    Blob dir permissions can also be specified explicitly.
+
+    >>> blob_storage = create_storage(blob_dir="blahbs", permissions=0770)
+    >>> os.path.isdir("blahbs")
+    True
+    >>> oct(os.stat("blahbs").st_mode)
+    '040770'
+
+    >>> path = blob_storage.fshelper.getPathForOID(0x0, create=True)
+    >>> oct(os.stat(path).st_mode)
+    '040770'
+
+    When explicit blob dir permissions are specified, the `checkSecure`
+    method doesn't not log a warning.
+
+    >>> import zope.testing.loggingsupport
+    >>> handler = zope.testing.loggingsupport.InstalledHandler("ZODB.blob")
+    >>> blob_storage.fshelper.blob_dir_permissions = None
+    >>> blob_storage.fshelper.checkSecure()
+    >>> print handler # doctest: +ELLIPSIS
+    ZODB.blob WARNING
+      (...) Blob dir ...blahbs... has insecure mode setting
+
+    >>> handler.clear()
+    >>> blob_storage.fshelper.blob_dir_permissions = 0770
+    >>> blob_storage.fshelper.checkSecure()
+    >>> print handler
+    <BLANKLINE>
+
     Clean up:
 
     >>> blob_storage.close()
+    >>> handler.uninstall()
 
     """
 
@@ -591,7 +623,7 @@
     >>> conn2.root.b.open().read()
     '2'
     >>> tm2.commit()
-    >>> tm1.commit()  # doctest: +IGNORE_EXCEPTION_DETAIL
+    >>> tm1.commit()  #doctest: +IGNORE_EXCEPTION_DETAIL
     Traceback (most recent call last):
         ...
     ConflictError: database conflict error...
@@ -651,10 +683,11 @@
 def setUpBlobAdaptedFileStorage(test):
     setUp(test)
 
-    def create_storage(name='data', blob_dir=None):
+    def create_storage(name='data', blob_dir=None, permissions=None):
         if blob_dir is None:
             blob_dir = '%s.bobs' % name
-        return ZODB.blob.BlobStorage(blob_dir, FileStorage('%s.fs' % name))
+        return ZODB.blob.BlobStorage(blob_dir, FileStorage('%s.fs' % name),
+            permissions=permissions)
 
     test.globs['create_storage'] = create_storage
 
@@ -667,13 +700,12 @@
 
     Pass a factory taking a name and a blob directory name.
     """
-
     def setup(test):
         setUp(test)
-        def create_storage(name='data', blob_dir=None):
+        def create_storage(name='data', blob_dir=None, permissions=None):
             if blob_dir is None:
                 blob_dir = '%s.bobs' % name
-            return factory(name, blob_dir)
+            return factory(name, blob_dir, permissions=permissions)
 
         test.globs['create_storage'] = create_storage
 
@@ -697,10 +729,10 @@
             ]),
         ))
 
-    def create_storage(self, name='data', blob_dir=None):
+    def create_storage(self, name='data', blob_dir=None, permissions=None):
         if blob_dir is None:
             blob_dir = '%s.bobs' % name
-        return factory(name, blob_dir)
+        return factory(name, blob_dir, permissions=permissions)
 
     def add_test_based_on_test_class(class_):
         new_class = class_.__class__(
@@ -742,8 +774,9 @@
         ))
     suite.addTest(storage_reusable_suite(
         'BlobAdaptedFileStorage',
-        lambda name, blob_dir:
-        ZODB.blob.BlobStorage(blob_dir, FileStorage('%s.fs' % name)),
+        lambda name, blob_dir, permissions=None:
+        ZODB.blob.BlobStorage(blob_dir, FileStorage('%s.fs' % name),
+            permissions=permissions),
         test_blob_storage_recovery=True,
         test_packing=True,
         ))



More information about the Zodb-checkins mailing list