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 )