Commit 211bf8a8 authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: Ensure that Permissions on Developer can be updated later (through Filesystem).

In aed4f303, Permissions were set in ComponentTool __init__ and it could not be
modified later on because it is set directly in the ZODB. Moreover, Permissions
could be modified after execution by modifying attributes.
parent 290d1dcb
...@@ -62,32 +62,34 @@ class ComponentTool(BaseTool): ...@@ -62,32 +62,34 @@ class ComponentTool(BaseTool):
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
def __init__(self, *args, **kwargs): @classmethod
def _applyAllStaticSecurity(cls):
""" """
Except 'Access *', 'View*' and 'WebDAV' permissions (Acquired) and 'Reset Apply static security on portal_components to ensure that nobody can
dynamic classes' (Manager, required to reset Components), everything change Permissions, only 'ghost' Developer Role has Permissions to
requires Developer Role. add/modify/delete Components. Also, make these permissions read-only
thanks to 'property'.
Another solution would be to load it from XML as it was previously done,
but from a security point of view, it's better to forbid everything and cls is erp5.portal_type.Component Tool and not this class as this function
allows only some. is called on Portal Type class when loading Componet Tool Portal Type
class
XXX-arnau: Really all 'Access *' and 'View*'? nothing else?
""" """
obj = BaseTool.__init__(self, *args, **kwargs) # XXX-Cosmetic: From Zope >= 2.13, getPermissions() can be used instead of
for permission_tuple in self.ac_inherited_permissions(1): # protected _registeredPermissions module attribute
name = permission_tuple[0] from AccessControl.Permission import _registeredPermissions, pname
value = permission_tuple[1] for permission_name in _registeredPermissions:
if name == 'Reset dynamic classes': if permission_name == 'Reset dynamic classes':
p = Permission(name, value, self) permission_function = lambda self: ('Manager',)
p.setRoles(('Manager',)) elif permission_name in ('Change permissions', 'Define permissions'):
elif not (name.startswith('Access ') or permission_function = lambda self: ()
name.startswith('View') or elif not (permission_name.startswith('Access ') or
name.startswith('WebDAV')): permission_name.startswith('View') or
p = Permission(name, value, self) permission_name.startswith('WebDAV')):
p.setRoles(('Developer',)) permission_function = lambda self: ('Developer',)
else:
return obj continue
setattr(cls, pname(permission_name), property(permission_function))
def _isBootstrapRequired(self): def _isBootstrapRequired(self):
""" """
......
...@@ -193,9 +193,17 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder): ...@@ -193,9 +193,17 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder):
pmc_init_of(subclass) pmc_init_of(subclass)
def setupSecurity(cls): def setupSecurity(cls):
apply_security_function = getattr(cls, '_applyAllStaticSecurity', None)
if apply_security_function:
apply_security_function()
# note that after this call the 'security' attribute will be gone. # note that after this call the 'security' attribute will be gone.
InitializeClass(cls) InitializeClass(cls)
for subclass in PortalTypeMetaClass.getSubclassList(cls): for subclass in PortalTypeMetaClass.getSubclassList(cls):
apply_security_function = getattr(cls, '_applyAllStaticSecurity', None)
if apply_security_function:
apply_security_function()
InitializeClass(subclass) InitializeClass(subclass)
def restoreGhostState(cls): def restoreGhostState(cls):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment