Sorry if these have already been fixed in 2.3.1, I haven't had time to
upgrade yet.

I fixed a small bug in SecurityInfo that made
SecurityInfo.setPermissionDefault() impossible to use:

191c191
>         self.roles[permission_name] = rdict.keys()
---
<         self.roles[permission_name] = rdict

    def setPermissionDefault(self, permission_name, roles):
        """Declare default roles for a permission"""
        rdict = {}
        for role in roles:
            rdict[role] = 1
        if self.roles.get(permission_name, rdict) != rdict:
            LOG('SecurityInfo', WARNING, 'Conflicting default role'
                'declarations for permission "%s"' % permission_name)
            self._warnings = 1
        self.roles[permission_name] = rdict.keys()

My other problem was that I wanted to setup some default permissions
that are used programatically in my product (i.e. they aren't used to
protect any specific methods, but the methods themselves check for the
permission.)  A small change to ClassSecurityInfo.apply() allows you to
call SecurityInfo.setPermissionDefault() to create new permissions, even
if they aren't attached to any methods:

239a240,242
>         for permission_name in self.roles.keys():
>             if not ac_permissions.has_key(permission_name):
>                 ac_permissions[permission_name] = ()

    def apply(self, classobj):
        """Apply security information to the given class object."""

        dict = classobj.__dict__

        # Check the class for an existing __ac_permissions__ and
        # incorporate that if present to support older classes or
        # classes that haven't fully switched to using SecurityInfo.
        if dict.has_key('__ac_permissions__'):
            for item in dict['__ac_permissions__']:
                permission_name = item[0]
                self._setaccess(item[1], permission_name)
                if len(item) > 2:
                    self.setDefaultRoles(permission_name, item[2])

        # Set __roles__ for attributes declared public or private.
        # Collect protected attribute names in ac_permissions.
        ac_permissions = {}
        for name, access in self.names.items():
            if access in (ACCESS_PRIVATE, ACCESS_PUBLIC, ACCESS_NONE):
                dict['%s__roles__' % name] = access
            else:
                if not ac_permissions.has_key(access):
                    ac_permissions[access] = []
                ac_permissions[access].append(name)

        # Now transform our nested dict structure into the nested tuple
        # structure expected of __ac_permissions__ attributes and set
        # it on the class object.
        getRoles = self.roles.get
        __ac_permissions__ = []
        for permission_name in self.roles.keys():
            if not ac_permissions.has_key(permission_name):
                ac_permissions[permission_name] = ()
        permissions = ac_permissions.items()
        permissions.sort()
        for permission_name, names in permissions:
            roles = getRoles(permission_name, ())
            if len(roles):
                entry = (permission_name, tuple(names), tuple(roles))
            else:
                entry = (permission_name, tuple(names))
            __ac_permissions__.append(entry)
        dict['__ac_permissions__'] = tuple(__ac_permissions__)

        # Take care of default attribute access policy
        access = getattr(self, 'access', _marker)
        if access is not _marker:
            dict['__allow_access_to_unprotected_subobjects__'] = access

        if getattr(self, '_warnings', None):
            LOG('SecurityInfo', WARNING, 'Class "%s" had conflicting '
                'security declarations' % classobj.__name__)



-Randy

_______________________________________________
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists -
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )

Reply via email to