[Zope-Checkins] CVS: Zope3/lib/python/Zope/Security - ISecurityContext.py:1.1.2.1 ISecurityManagement.py:1.1.2.1 ISecurityManager.py:1.1.2.1 ISecurityPolicy.py:1.1.2.1 SecurityContext.py:1.1.2.1 SecurityManagement.py:1.1.2.1 SecurityManager.py:1.1.2.1 SimpleSecurityPolicies.py:1.1.2.1 Checker.py:1.1.2.10
Jim Fulton
jim@zope.com
Sat, 27 Apr 2002 12:58:56 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/Security
In directory cvs.zope.org:/tmp/cvs-serv26931/lib/python/Zope/Security
Modified Files:
Tag: SecurityProxy-branch
Checker.py
Added Files:
Tag: SecurityProxy-branch
ISecurityContext.py ISecurityManagement.py ISecurityManager.py
ISecurityPolicy.py SecurityContext.py SecurityManagement.py
SecurityManager.py SimpleSecurityPolicies.py
Log Message:
Moved security management modules to Zope.Security.
Added like_unto attribute to protect class so you can say that a class
has the same protections as another class::
<security:protectClass name=".RootFolder." like_unto=".Folder." />
Added some additional calls to removeAllProxies in some component
lookup code while debugging integration of new security model.
Added protections for BTree types.
=== Added File Zope3/lib/python/Zope/Security/ISecurityContext.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.
#
##############################################################################
from Interface import Interface
from Interface.Attribute import Attribute
class ISecurityContext( Interface ):
"""
Capture transient request-specific security information.
"""
Attribute( 'stack'
, 'A stack of elements, each either be an ExecutableObject'
'or a tuple consisting of an ExecutableObject and a'
'custom SecurityPolicy.'
)
Attribute( 'principal'
, 'The AUTHENTICATED_USER for the request.'
)
=== Added File Zope3/lib/python/Zope/Security/ISecurityManagement.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.
#
##############################################################################
from Interface import Interface
class ISecurityManagementSetup( Interface ):
"""
Infrastructure (including tests, etc.) calls these things to
tweak the security manager.
"""
def newSecurityManager( user ):
"""
Install a new SecurityManager, using user. Return the
old SecurityManager, if any, or None.
"""
def replaceSecurityManager( old_manager ):
"""
Replace the SecurityManager with 'old_manager', which
must implement ISecurityManager.
"""
def noSecurityManager():
"""
Clear any existing SecurityManager.
"""
class ISecurityManagement( Interface ):
"""
"Public" SM API.
"""
def getSecurityManager():
"""
Get a SecurityManager (create if needed).
"""
def setSecurityPolicy( aSecurityPolicy ):
"""
Set the system default security policy.
This method should only be caused by system startup code.
It should never, for example, be called during a web request.
"""
=== Added File Zope3/lib/python/Zope/Security/ISecurityManager.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.
#
##############################################################################
from Interface import Interface
# XXX This interface has too muct Zope application dependence. This
# needs to be refactored somehow.
class ISecurityManager( Interface ):
"""
A security manager provides methods for checking access and managing
executable context and policies.
"""
def getPrincipal():
"""
Return the authenticated principal.
This is equivalent to something like::
REQUEST['AUTHENTICATED_USER']
but is a bit cleaner, especially if 'REQUEST' isn't handy.
"""
def checkPermission( permission, object ):
"""
Check whether the security context allows the given
permission on the given object. Return a boolean value.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
def pushExecutable( anExecutableObject ):
"""
Push an ExecutableObject onto the manager's stack, and
activate it's custom security policy, if any.
"""
def popExecutable( anExecutableObject ):
"""
Pop the topmost ExecutableObject from the stack, deactivating
any custom security policy it might have installed.
"""
def calledByExecutable():
"""
Return a boolean indicating whether the current request has
invoked any IExecutableObjects.
This can be used to determine if an object was called
(more or less) directly from a URL, or if it was called by
through-the-web provided code.
"""
=== Added File Zope3/lib/python/Zope/Security/ISecurityPolicy.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.
#
##############################################################################
from Interface import Interface
class ISecurityPolicy( Interface ):
def checkPermission( permission
, object
, context
):
"""
Check whether the security context allows the given permission on
the given object, returning a boolean value.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
context -- A SecurityContext, which provides access to information
shuch as the context stack and AUTHENTICATED_USER.
"""
=== Added File Zope3/lib/python/Zope/Security/SecurityContext.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.
#
##############################################################################
""" Default ISecurityContext impl """
from ISecurityContext import ISecurityContext
class SecurityContext:
"""
Capture transient request-specific security information.
Attribute( 'stack'
, 'A stack of elements, each either be an ExecutableObject'
'or a tuple consisting of an ExecutableObject and a'
'custom SecurityPolicy.'
)
Attribute( 'user'
, 'The AUTHENTICATED_USER for the request.'
)
"""
def __init__( self, user ):
self.stack = []
self.user = user
self.objectCache = {}
=== Added File Zope3/lib/python/Zope/Security/SecurityManagement.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.
#
##############################################################################
""" Default ISecurityManagement implementation """
from ISecurityManagement import ISecurityManagement, ISecurityManagementSetup
from SecurityManager import SecurityManager
from SecurityManager import setSecurityPolicy as _setSecurityPolicy
from SecurityContext import SecurityContext
__implements__ = ( ISecurityManagement, ISecurityManagementSetup )
try:
import thread
except:
get_ident=lambda: 0
else:
get_ident=thread.get_ident
_managers={}
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_managers.clear)
#
# ISecurityManagementSetup implementation
#
def newSecurityManager( user ):
"""
Install a new SecurityManager, using user. Return the
old SecurityManager, if any, or None.
"""
return replaceSecurityManager( SecurityManager( SecurityContext( user ) ) )
def replaceSecurityManager( old_manager ):
"""
Replace the SecurityManager with 'old_manager', which
must implement ISecurityManager.
"""
thread_id = get_ident()
old = _managers.get( thread_id, None )
_managers[ thread_id ] = old_manager
return old
def noSecurityManager():
"""
Clear any existing SecurityManager.
"""
try:
del _managers[ get_ident() ]
except KeyError:
pass
#
# ISecurityManagement implementation
#
def getSecurityManager():
"""
Get a SecurityManager (create if needed).
"""
thread_id = get_ident()
manager=_managers.get( thread_id, None )
if manager is None:
newSecurityManager( None )
manager=_managers.get( thread_id, None )
return manager
def setSecurityPolicy( aSecurityPolicy ):
"""
Set the system default security policy, and return the previous
value.
This method should only be caused by system startup code.
It should never, for example, be called during a web request.
"""
return _setSecurityPolicy( aSecurityPolicy )
=== Added File Zope3/lib/python/Zope/Security/SecurityManager.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.
#
##############################################################################
""" Default ISecurityManager implementation """
import os
from SimpleSecurityPolicies import ParanoidSecurityPolicy
MAX_STACK_SIZE = 100
_defaultPolicy = ParanoidSecurityPolicy()
def _clear():
global _defaultPolicy
_defaultPolicy = ParanoidSecurityPolicy()
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
def setSecurityPolicy( aSecurityPolicy ):
"""
Set the system default security policy.
This method should only be caused by system startup code. It should
never, for example, be called during a web request.
"""
global _defaultPolicy
last, _defaultPolicy = _defaultPolicy, aSecurityPolicy
return last
from ISecurityManager import ISecurityManager
class SecurityManager:
"""
A security manager provides methods for checking access and managing
executable context and policies.
"""
__implements__ = ISecurityManager
def __init__( self, context ):
self._context = context
self._policy = None
def _getPolicy( self ):
"""
Find current policy, or default.
"""
policy = self._policy
if policy is None:
policy = _defaultPolicy
return policy
#
# ISecurityManager implementation
#
def getPrincipal( self ):
"""
Return the authenticated user.
This is equivalent to something like::
REQUEST['AUTHENTICATED_USER']
but is a bit cleaner, especially if 'REQUEST' isn't handy.
"""
return self._context.user
def checkPermission( self, permission, object ):
"""
Check whether the security context allows the given
permission on the given object. Return a boolean value.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
return self._getPolicy().checkPermission( permission, object
, self._context )
def pushExecutable( self, anExecutableObject ):
"""
Push an ExecutableObject onto the manager's stack, and
activate it's custom security policy, if any.
"""
stack=self._context.stack
if len( stack ) >= MAX_STACK_SIZE:
raise SystemError, 'Excessive recursion'
stack.append( anExecutableObject )
p = getattr( anExecutableObject, '_customSecurityPolicy', None )
if p is not None:
p = p()
self._policy = p
def popExecutable( self, anExecutableObject ):
"""
Pop the topmost ExecutableObject from the stack, deactivating
any custom security policy it might have installed.
"""
stack=self._context.stack
if not stack:
return
top = stack[-1]
if top is anExecutableObject:
del stack[-1]
else:
indexes = range(len(stack))
indexes.reverse()
for i in indexes:
top=stack[i]
if top is anExecutableObject:
del stack[i:]
break
else:
return
if stack:
top = stack[-1]
p = getattr( top, '_customSecurityPolicy', None )
if p is not None:
p=p()
self._policy=p
else:
self._policy=None
def calledByExecutable( self ):
"""
Return a boolean indicating whether the current request has
invoked any IExecutableObjects.
This can be used to determine if an object was called
(more or less) directly from a URL, or if it was called by
through-the-web provided code.
"""
return len( self._context.stack )
=== Added File Zope3/lib/python/Zope/Security/SimpleSecurityPolicies.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.
#
##############################################################################
""" Simple ISecurityPolicy implementations."""
from ISecurityPolicy import ISecurityPolicy
from Zope.Exceptions import Unauthorized
class ParanoidSecurityPolicy:
"""
Deny all access.
"""
__implements__ = ISecurityPolicy
def checkPermission( sel, permission, object, context ):
if (context.user is None # no user
and not context.stack # no untrusted code
):
return 1 # Nobody not to trust!
return 0
class PermissiveSecurityPolicy:
"""
Allow all access
"""
__implements__ = ISecurityPolicy
def checkPermission( self, permission, object, context ):
return 1
=== Zope3/lib/python/Zope/Security/Checker.py 1.1.2.9 => 1.1.2.10 ===
-from Zope.Exceptions import Unauthorized, Forbidden, DuplicationError
+from Zope.Exceptions \
+ import Unauthorized, ForbiddenAttribute, Forbidden, DuplicationError
from Interface.IInterface import IInterface
from _Proxy import _Proxy as Proxy
from types import InstanceType, ClassType, FunctionType, MethodType, ModuleType
from ISecurityProxyFactory import ISecurityProxyFactory
-# XXX SecurityManagement needs to move out of App
-from Zope.App.Security.SecurityManagement import getSecurityManager
+from Zope.Security.SecurityManagement import getSecurityManager
# Marker for public attributes
CheckerPublic = object()
@@ -86,7 +86,7 @@
elif name in _always_available:
return
- raise Forbidden(name)
+ raise ForbiddenAttribute(name)
def proxy(self, value):
'See Zope.Security.IChecker.IChecker'
@@ -254,9 +254,14 @@
}
_default_checkers = {
- dict: NamesChecker(['__getitem__', 'get', 'has_key', '__len__',
- 'keys', 'values', 'items']),
- list: NamesChecker(['__getitem__', 'index', 'count', '__len__']),
+ dict: NamesChecker(['__getitem__', '__len__', '__iter__',
+ 'get', 'has_key', '__copy__',
+ 'keys', 'values', 'items',
+ 'iterkeys', 'iteritems', 'itervalues', '__contains__',
+ ]),
+ list: NamesChecker(['__getitem__', '__len__', '__iter__',
+ 'index', 'count']),
+
# YAGNI: () a rock
tuple: NamesChecker(['__getitem__', '__len__']),
InstanceType: _instanceChecker,