[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - _protections.py:1.1.4.1 ZopeSecurityPolicy.py:1.1.2.25 __init__.py:1.1.2.5 metaConfigure.py:1.1.2.26 protectClass.py:1.1.2.13 publicClass.py:1.1.2.9 security-meta.zcml:1.1.2.3 security.zcml:1.1.2.5 ISecurityContext.py:NONE ISecurityManagement.py:NONE ISecurityManager.py:NONE ISecurityPolicy.py:NONE SecurityContext.py:NONE SecurityManagement.py:NONE SecurityManager.py:NONE SimpleSecurityPolicies.py:NONE
Jim Fulton
jim@zope.com
Sun, 28 Apr 2002 13:17:11 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv17050/lib/python/Zope/App/Security
Modified Files:
Tag: Zope-3x-branch
ZopeSecurityPolicy.py __init__.py metaConfigure.py
protectClass.py publicClass.py security-meta.zcml
security.zcml
Added Files:
Tag: Zope-3x-branch
_protections.py
Removed Files:
Tag: Zope-3x-branch
ISecurityContext.py ISecurityManagement.py ISecurityManager.py
ISecurityPolicy.py SecurityContext.py SecurityManagement.py
SecurityManager.py SimpleSecurityPolicies.py
Log Message:
HOTYB: Merged SecurityProxy-branch into main branch.
All tests pass and folders can be listed and added through the web.
It is likely that most other things don't work and will need to be
fixed. The reason is that many accesses that should have been checked
before are now being checked and additional checks and thinking about
permissions and security settings are needed.
I'm in the process of drafting a paper for the wiki that describes the
changes in more detail.
=== Added File Zope3/lib/python/Zope/App/Security/_protections.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Register protection information for some standard low-level types
Revision information:
$Id: _protections.py,v 1.1.4.1 2002/04/28 17:16:40 jim Exp $
"""
def protect():
from Zope.Security.Checker import \
defineChecker, getCheckerForInstancesOf, NamesChecker
import Persistence.BTrees
def _protect(which):
__import__('Persistence.BTrees.%sBTree' % which)
module = getattr(Persistence.BTrees, "%sBTree" % which)
defineChecker(getattr(module, '%sBTree' % which),
getCheckerForInstancesOf(dict))
defineChecker(getattr(module, '%sBucket' % which),
getCheckerForInstancesOf(dict))
defineChecker(getattr(module, '%sSet' % which),
NamesChecker(['__getitem__', '__len__', 'has_key',
'__repr__', '__str__',
'keys', 'maxKey', 'minKey']
)
)
defineChecker(getattr(module, '%sTreeSet' % which),
NamesChecker(['__len__', 'has_key',
'__repr__', '__str__',
'keys', 'maxKey', 'minKey']
)
)
items = getattr(module, '%sBTree' % which)().keys()
defineChecker(type(items),
getCheckerForInstancesOf(tuple))
for which in 'OO', 'II', 'OI', 'IO':
_protect(which)
=== Zope3/lib/python/Zope/App/Security/ZopeSecurityPolicy.py 1.1.2.24 => 1.1.2.25 ===
from Zope.ComponentArchitecture import getAdapter
-from Zope.ContextWrapper.ContainmentIterator import ContainmentIterator
-
+from Zope.Proxy.ContextWrapper import ContainmentIterator
from Zope.Exceptions import Unauthorized, Forbidden
-
from Zope.App.Security.IRolePermissionManager import IRolePermissionManager
from Zope.App.Security.IPrincipalPermissionManager \
import IPrincipalPermissionManager
@@ -39,9 +37,6 @@
from types import StringType, StringTypes, TupleType, ListType, IntType, MethodType, NoneType
-# XXX: hack alert
-from Zope.ContextWrapper import getbaseobject
-
getPermissionsForPrincipal = \
principalPermissionManager.getPermissionsForPrincipal
getPermissionsForRole = rolePermissionManager.getPermissionsForRole
@@ -75,48 +70,6 @@
self._ownerous=ownerous
self._authenticated=authenticated
- #
- # ISecurityPolicy implementation.
- #
- def validate( self
- , name
- , value
- , context
- ):
-
- try: permission=value.__permission__
- except AttributeError:
- # XXX: allow some simple types to get ZMI working
- # is this the right thing to do?
- # Also, respect the attribute
- # __allow_access_to_unprotected_subobjects__
- # as used in TALES iterators and other places
- # Also, respect __aatus__ for accessing methods of objects
- # (un)protected by it.
- # This is still a hack, and still incomplete, and just here
- # to get the ZMI working.
-
-
- unwrapped_value = getbaseobject(value)
- if (isinstance(unwrapped_value, (ListType, TupleType, StringTypes, IntType, NoneType))
- or
- getattr(value,'__allow_access_to_unprotected_subobjects__',0)):
- permission = 'Zope.Public'
- elif (isinstance(unwrapped_value, MethodType) and
- getattr(value.im_self,
- '__allow_access_to_unprotected_subobjects__',
- 0)):
- permission = 'Zope.Public'
- else:
- raise Forbidden(name, value, 'No permission set')
-
- if permission == 'Zope.Public': # XXX need unit test for this
- return
-
- if self.checkPermission(permission, value, context):
- return
- raise Unauthorized(permission, name, value)
-
def checkPermission( self, permission, object, context ):
# XXX We aren't really handling multiple principals yet
@@ -191,51 +144,6 @@
return 1 # Allow on global role
return 0 # Deny by default
-
-# for p in principals.keys():
-# if permission in getPermissionsForPrincipal(p):
-# del principals[p]
-# else:
-# for r in getRolesForPrincipal(p):
-# if permission in getPermissionsForRole(r):
-# del principals[p]
-# if r in roles:
-# return 1
-# return not principals
-
- #
- # Helper methods
- #
- def _allowName( self, name ):
- """
- Is 'name' ever allowed to be retrieved under this policy?
- """
- return name and isinstance(name, StringType) and name.strip()
-
- def _findPermission( self, value ):
- """
- Find the permission which guards the accessed object.
- """
- return getattr( value, '__permission__', None )
-
- def _listRolesFor( self, permission, object ):
- """
- Crawl the context of 'object' and return an accumulated
- list of all roles which have 'permission'.
-
- Note that we don't (yet) use 'object' to search for
- placeful permission-role bindings.
- """
- role_set = {}
-
- # Add "global" roles for permission here
- for role in getRolesForPermission( permission ):
- role_set[ role ] = 1
-
- roles = role_set.keys()
- roles.sort()
-
- return tuple( roles )
zopeSecurityPolicy=ZopeSecurityPolicy()
=== Zope3/lib/python/Zope/App/Security/__init__.py 1.1.2.4 => 1.1.2.5 ===
##############################################################################
""" Zope Security Architecture """
+
+# Register some standard types
+import _protections
+_protections.protect()
+del _protections
=== Zope3/lib/python/Zope/App/Security/metaConfigure.py 1.1.2.25 => 1.1.2.26 ===
from PermissionRegistry import permissionRegistry as perm_reg
from RoleRegistry import roleRegistry as role_reg
-from SecurityManager import setSecurityPolicy
+from Zope.Security.SecurityManager import setSecurityPolicy
from PrincipalRegistry import principalRegistry
from RolePermissionManager import rolePermissionManager as role_perm_mgr
from PrincipalPermissionManager import principalPermissionManager \
=== Zope3/lib/python/Zope/App/Security/protectClass.py 1.1.2.12 => 1.1.2.13 ===
#
##############################################################################
-"""Create the protection declarations object.
-
-Protection declarations are assert as part of the configuration process to map
-permissions to objects, ie to specific classes, class instances, and methods.
-\(Method permissions apply to both the class and class instance manifestations
-of the methods.)
-
-When the declarations are expressed as a simple (ie, empty) tag, they are
-applied to both the class and the instances of the class. When the tags have
-subtags, then the instances are not inherently affected - the subtag directive
-"instances" can then be used. [XXX this needs to be fleshed out.]
-
-Invalid protection declarations raise ProtectionDeclarationException
-instances."""
+"""Make assertions about permissions needed to access class instances attributes
+"""
from Interface.Method import Method
from Exceptions import UndefinedPermissionError
@@ -32,26 +20,29 @@
from Zope.Configuration.ConfigurationDirectiveInterfaces \
import INonEmptyDirective
+from Zope.Configuration.Action import Action
+
+from Zope.Security.Checker import defineChecker, getCheckerForInstancesOf
+from Zope.Security.Checker import Checker, CheckerPublic
class ProtectionDeclarationException(Exception):
"""Security-protection-specific exceptions."""
pass
-
class protectClass:
__class_implements__ = INonEmptyDirective
def __init__(self, _context, name, permission_id=None, interface=None,
- methods=None):
+ names=None, like_unto=None):
self.__class = _context.resolve(name)
self.__name = name
self.__permission_id = permission_id
+ self.__like_unto = like_unto
self.__context = _context
- self.__r = self.protect(_context, permission_id, interface, methods)
- # So subsequent simple-declaration-style self() calls process instances
- self.__empty = 1
+ self.__r = self.protect(_context, permission_id, interface, names,
+ like_unto)
# ._getPermission() is handy for subclassing with different permission
# policy, eg publicClass.
@@ -68,65 +59,57 @@
return permission_id
def protect(self, _context, permission_id=None, interface=None,
- methods=None):
+ names=None, like_unto=None):
"Protect a specific aspect"
- self.__empty = 0
+ r = []
+
+ if like_unto:
+ self.__protectLikeUnto(like_unto, r)
- if not (interface or methods):
- return []
+ if not (interface or names):
+ return r
+
permission_id = self._getPermission(permission_id)
- r = []
if interface:
self.__protectByInterface(interface, permission_id, r)
- if methods:
- self.__protectMethods(methods, permission_id, r)
+ if names:
+ self.__protectNames(names, permission_id, r)
return r
- def instances(self, _context, permission_id=None):
- "Protect instances of the class, as opposed to methods"
- self.__empty = 0
-
- permission_id = self._getPermission(permission_id)
- r=[]
- self.__instances(permission_id, r)
- return r
-
- def __instances(self, permission_id, r):
- "Protect instances of the class, as opposed to methods"
- permission_id = self._getPermission(permission_id)
- r.append((
- ('protectInstances', self.__class),
- protectInstancesOfClass, (self.__class, permission_id,)))
-
- def __protectMethod(self, method, permission_id, r):
- "Set a permission on a particular method."
+ def __protectName(self, name, permission_id, r):
+ "Set a permission on a particular name."
r.append((
- ('protectMethod', self.__class, method),
- protectMethod, (self.__class, method, permission_id)))
-
- def __protectMethods(self, methods, permission_id, r):
- "Set a permission on a bunch of methods."
- for method in methods.split(","):
- self.__protectMethod(method.strip(), permission_id, r)
+ ('protectName', self.__class, name),
+ protectName, (self.__class, name, permission_id)))
+ def __protectNames(self, names, permission_id, r):
+ "Set a permission on a bunch of names."
+ for name in names.split(","):
+ self.__protectName(name.strip(), permission_id, r)
def __protectByInterface(self, interface, permission_id, r):
- "Set a permission on methods in an interface."
+ "Set a permission on names in an interface."
interface = self.__context.resolve(interface)
for n, d in interface.namesAndDescriptions(1):
- if isinstance(d, Method):
- self.__protectMethod(n, permission_id, r)
+ self.__protectName(n, permission_id, r)
+
+ def __protectLikeUnto(self, like_unto, r):
+ "Set a permission on names in an interface."
+ like_unto = self.__context.resolve(like_unto)
+ r.append(
+ Action(discriminator=('protectLikeUnto', self.__class, object()),
+ callable=protectLikeUnto,
+ args=(self.__class, like_unto),
+ )
+ )
def __call__(self):
"Handle empty/simple declaration."
- r = self.__r
- if self.__empty:
- self.__instances(self.__permission_id, r)
- return r
+ return self.__r
def _checkPermission(permission_id):
"""Check to make sure that the permission is valid.
@@ -135,58 +118,38 @@
if not permissionRegistry.definedPermission(permission_id):
raise UndefinedPermissionError(permission_id)
+def protectName(class_, name, permission_id):
+ "Set a permission on a particular name."
+ checker = getCheckerForInstancesOf(class_)
+ if checker is None:
+ checker = Checker({}.get)
+ defineChecker(class_, checker)
+
+ if permission_id == 'Zope.Public':
+ # Translate public permission to CheckerPublic
+ permission_id = CheckerPublic
+
+ # OK, so it's a hack.
+ protections = checker.getPermission_func().__self__
+ protections[name] = permission_id
-def protectInstancesOfClass(class_, permission_id):
- _checkPermission(permission_id)
- class_.__permission__ = permission_id
-
-def protectMethod(class_, method, permission_id):
- "Set a permission on a particular method."
- _checkPermission(permission_id)
-
- m = getattr(class_, method)
-
- d = class_.__dict__
- if not d.has_key(method):
- # Hm, we inherit the method. Dang, we need to insert a stub
-
- # Make sure we have new style class:
- if not issubclass(class_, object):
- raise TypeError(
- "Can only protected inherited methods of new "
- "style classes", class_)
-
- f = Protected(class_, method, permission_id)
- setattr(class_, method, f)
+def protectLikeUnto(class_, like_unto):
+ """Use the protections from like_unto for class_
+ """
+
+ unto_checker = getCheckerForInstancesOf(like_unto)
+ if unto_checker is None:
return
-
- try:
- setattr(m, "__permission__", permission_id)
- except (AttributeError, TypeError):
- if hasattr(m, "im_func"):
- setattr(m.im_func, "__permission__", permission_id)
- else:
- raise ProtectionDeclarationException(
- "Couldn't assign permission to method %s of class %s"
- % (m, class_.__name__))
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Hack!!!!!!!!!!
-
-class Protected(object):
-
- def __init__(self, *args):
- self.__args = args # class_, method, permission_id
-
- def __get__(self, instance, type=None):
- return ProtectedMethod(self.__args, instance)
+ # OK, so it's a hack.
+ unto_protections = unto_checker.getPermission_func().__self__
-class ProtectedMethod(object):
-
- def __init__(self, args, instance):
- class_, method, self.__permission__ = args
- m = getattr(super(class_, instance), method)
- self.__m = self.__call__ = m
-
- def __call__(self, *args, **kw):
- return self.__m(*args, **kw)
+ checker = getCheckerForInstancesOf(class_)
+ if checker is None:
+ checker = Checker({}.get)
+ defineChecker(class_, checker)
+
+ # OK, so it's a hack.
+ protections = checker.getPermission_func().__self__
+ for name in unto_protections:
+ protections[name] = unto_protections[name]
=== Zope3/lib/python/Zope/App/Security/publicClass.py 1.1.2.8 => 1.1.2.9 ===
def __init__(self, _context, name, permission_id=None, interface=None,
- methods=None):
+ names=None):
self._getPermission(permission_id) # Prohibit explicit permission!
protectClass.__init__(self, _context, name,
permission_id=PublicPermission,
- interface=interface, methods=methods)
+ interface=interface, names=names)
def _getPermission(self, permission_id=None):
if permission_id not in [None, PublicPermission]:
=== Zope3/lib/python/Zope/App/Security/security-meta.zcml 1.1.2.2 => 1.1.2.3 ===
<subdirective name="protect"
attributes="permission_id, interface, methods" />
- <subdirective name="instances" attributes="permission_id" />
</directive>
<directive name="publicClass" attributes="name, interface, methods"
handler="Zope.App.Security.publicClass." />
=== Zope3/lib/python/Zope/App/Security/security.zcml 1.1.2.4 => 1.1.2.5 ===
<security:protectClass name="Zope.App.Security.RolePermissionView."
permission_id="Zope.Security"
- methods="index, roles, permissions, permissionRoles, action,
+ names="index, roles, permissions, permissionRoles, action,
manage_permissionForm, update_permission,
manage_roleForm, update_role, permissionForID" />
<security:protectClass
name="Zope.App.Security.RolePermissionView.PermissionRoles."
permission_id="Zope.Security"
- methods="roles, rolesInfo"
+ names="roles, rolesInfo"
interface="Zope.App.Security.IRegisteredObject." />
@@ -55,7 +55,7 @@
<security:protectClass name="Zope.App.Security.PrincipalPermissionView."
permission_id="Zope.Security"
- methods="index, get_principal, unsetPermissions, denyPermissions,
+ names="index, get_principal, unsetPermissions, denyPermissions,
grantPermissions, getUnsetPermissionsForPrincipal,
getPermissionsForPrincipal" />
=== Removed File Zope3/lib/python/Zope/App/Security/ISecurityContext.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/ISecurityManagement.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/ISecurityManager.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/ISecurityPolicy.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/SecurityContext.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/SecurityManagement.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/SecurityManager.py ===
=== Removed File Zope3/lib/python/Zope/App/Security/SimpleSecurityPolicies.py ===