Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Enforce access control on snapshot files and folders.
  • Loading branch information
mauritsvanrees committed Mar 1, 2021
1 parent 835c1ac commit 7003195
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGES.rst
Expand Up @@ -4,7 +4,7 @@ Changelog
2.1.1 (unreleased)
------------------

- Enforce access control on setup tool log files
- Enforce access control on setup tool log files and snapshot files and folders.
(`#101 <https://github.com/zopefoundation/Products.GenericSetup/issues/101>`_)


Expand Down
11 changes: 9 additions & 2 deletions src/Products/GenericSetup/context.py
Expand Up @@ -26,6 +26,7 @@
import six

from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import view
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Implicit
from Acquisition import aq_base
Expand Down Expand Up @@ -499,6 +500,10 @@ def writeDataFile(self, filename, text, content_type, subdir=None):
# MISSING: switch on content_type
ob = self._createObjectByType(filename, text, content_type)
folder._setObject(str(filename), ob) # No Unicode IDs!
# Tighten the View permission on the new object.
# Only the owner and Manager users may view the log.
# file_ob = self._getOb(name)
ob.manage_permission(view, ('Manager', 'Owner'), 0)

@security.protected(ManagePortal)
def getSnapshotURL(self):
Expand Down Expand Up @@ -559,8 +564,10 @@ def _ensureSnapshotsFolder(self, subdir=None):
if element not in current.objectIds():
# No Unicode IDs!
current._setObject(str(element), Folder(element))

current = current._getOb(element)
current = current._getOb(element)
current.manage_permission(view, ('Manager', 'Owner'), 0)
else:
current = current._getOb(element)

return current

Expand Down
24 changes: 19 additions & 5 deletions src/Products/GenericSetup/tests/test_tool.py
Expand Up @@ -473,6 +473,15 @@ def test_runAllImportStepsFromProfile_sorted_default_purge(self):
logged = [x for x in tool.objectIds('File') if x.startswith(prefix)]
self.assertEqual(len(logged), 1)

def check_restricted_access(self, obj):
# For most objects that we create, we do not want ordinary users to
# see it, also not when they have View permission on a higher level.
rop_info = obj.rolesOfPermission(view)
allowed_roles = sorted([x['name'] for x in rop_info
if x['selected']])
self.assertEqual(allowed_roles, ['Manager', 'Owner'])
self.assertFalse(obj.acquiredRolesAreUsedBy(view))

def test_runAllImportStepsFromProfile_unicode_id_creates_reports(self):

TITLE = 'original title'
Expand All @@ -497,11 +506,7 @@ def test_runAllImportStepsFromProfile_unicode_id_creates_reports(self):
logged = [x for x in tool.objectIds('File')]
for file_id in logged:
file_ob = tool._getOb(file_id)
rop_info = file_ob.rolesOfPermission(view)
allowed_roles = sorted([x['name'] for x in rop_info
if x['selected']])
self.assertEqual(allowed_roles, ['Manager', 'Owner'])
self.assertFalse(file_ob.acquiredRolesAreUsedBy(view))
self.check_restricted_access(file_ob)

def test_runAllImportStepsFromProfile_sorted_explicit_purge(self):

Expand Down Expand Up @@ -1101,6 +1106,15 @@ def normalize_xml(xml):
self.assertEqual(info['id'], 'default')
self.assertEqual(info['title'], 'default')

# Check access restriction on snapshot files and folders
self.check_restricted_access(tool.snapshots)
self.check_restricted_access(snapshot)
for obj in snapshot.objectValues():
self.check_restricted_access(obj)
if hasattr(aq_base(obj), 'objectValues'):
for child in obj.objectValues():
self.check_restricted_access(child)

def test_applyContext(self):
from ..tool import EXPORT_STEPS_XML
from ..tool import IMPORT_STEPS_XML
Expand Down

0 comments on commit 7003195

Please sign in to comment.