Add custom permission to object programmatically

Hi everyone,

is it possible to simply add a custom permission to an object programmatically?
Or do I have to hack it into __ac_permissions__?

Thanks in advance
Ramon

I ended now up using this solution:


def manage_permission(obj, permission, roles, acquire=0):
    """Manage the permission of an object
       or adds the permission on the fly when it is not found.
    """
    try:
        obj.manage_permission(permission, roles=roles, acquire=acquire)
    except ValueError:
        # NOTE: There seems to be no API to programmatically add an unmanaged
        #       permission to an object, so that the only way that worked is the
        #       one below...
        perms = list(obj.__ac_permissions__)
        entry = (permission, tuple())
        perms.append(entry)
        obj.__ac_permissions__ = perms
        obj.manage_permission(permission, roles=roles, acquire=acquire)
    obj.reindexObjectSecurity()

I would be grateful if someone shows me a more elegant way to solve this.

>>> from zope.component.hooks import setSite
>>> setSite(site)
>>> from zope.security.interfaces import IPermission
>>> from zope.security.permission import Permission
>>> x = Permission('x')
>>> from zope.security.permission import Permission
>>> x = Permission('x')
>>> from zope.component import provideUtility
>>> provideUtility(x, IPermission, 'x')
>>> site.manage_permission('x', roles=['Member'], acquire=False)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 8, in manage_permission
  File "/home/casa/yuri/plone6/es6/buildout.coredev/plips/eggs/AccessControl-5.2-py3.9-linux-x86_64.egg/AccessControl/requestmethod.py", line 89, in _curried
    return callable(*args, **kw)
  File "/home/casa/yuri/plone6/es6/buildout.coredev/src/Zope/src/OFS/role.py", line 98, in manage_permission
    BaseRoleManager.manage_permission(
  File "/home/casa/yuri/plone6/es6/buildout.coredev/plips/eggs/AccessControl-5.2-py3.9-linux-x86_64.egg/AccessControl/rolemanager.py", line 222, in manage_permission
    raise ValueError(
ValueError: The permission <em>x</em> is invalid.
>>> from AccessControl.Permission import addPermission
>>> addPermission('x')
>>> site.manage_permission('x', roles=['Member'], acquire=False)
>>> allp = site.ac_inherited_permissions(1)
>>> for perm in sorted(allp):
...  print(perm)
[...]

('plone.restapi: Use REST API', (), ('Manager',))
('x', (), ('Manager',))


I've found this way, but still don't understand why 'x' is not added to the 'Member' role. I'm missing the glue between zope.security.permission.Permission and AccessControl.Permission.Permission.