[Zope-Checkins] CVS: Zope3/lib/python/Zope/Security - Checker.py:1.1.4.1 IChecker.py:1.1.4.1 ISecurityContext.py:1.1.4.1 ISecurityManagement.py:1.1.4.1 ISecurityManager.py:1.1.4.1 ISecurityPolicy.py:1.1.4.1 ISecurityProxyFactory.py:1.1.4.1 Proxy.py:1.1.4.1 RestrictedInterpreter.py:1.1.4.1 SecurityContext.py:1.1.4.1 SecurityManagement.py:1.1.4.1 SecurityManager.py:1.1.4.1 SimpleSecurityPolicies.py:1.1.4.1 _Proxy.c:1.1.4.1 __init__.py:1.1.4.1 setup.py:1.1.4.1
Jim Fulton
jim@zope.com
Sun, 28 Apr 2002 13:16:50 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/Security
In directory cvs.zope.org:/tmp/cvs-serv17050/lib/python/Zope/Security
Added Files:
Tag: Zope-3x-branch
Checker.py IChecker.py ISecurityContext.py
ISecurityManagement.py ISecurityManager.py ISecurityPolicy.py
ISecurityProxyFactory.py Proxy.py RestrictedInterpreter.py
SecurityContext.py SecurityManagement.py SecurityManager.py
SimpleSecurityPolicies.py _Proxy.c __init__.py setup.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/Security/Checker.py ===
from Zope.Security.IChecker import IChecker
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
from Zope.Security.SecurityManagement import getSecurityManager
# Marker for public attributes
CheckerPublic = object()
def ProxyFactory(object, checker=None):
"""Factory function that creats a proxy for an object
The proxy checker is looked up if not provided.
"""
if checker is None:
checker = selectChecker(object)
if checker is None:
return object
else:
# Maybe someone passed us a proxy and a checker
if type(object) is Proxy:
# XXX should we keep the existing proxy or create a new one.
return object
return Proxy(object, checker)
ProxyFactory.__implements__ = ISecurityProxyFactory
class Checker:
__implements__ = IChecker
def __init__(self, permission_func):
"""Create a checker
A callable must be provided for computing permissions for
names. The callable will be called with attribute names and
must return a permission id, None, or the special marker,
CheckerPublic. If None is returned, then access to the name is
forbidden. If CheckerPublic is returned, then access will be
granted without checking a permission.
"""
self.__permission_func = permission_func
def getPermission_func(self):
return self.__permission_func
def permission_id(self, name):
"""Return the result of calling the permission func
"""
return self.__permission_func(name)
############################################################
# Implementation methods for interface
# Zope.Security.IChecker.
def check_getattr(self, object, name):
'See Zope.Security.IChecker.IChecker'
self.check(object, name)
def check_setattr(self, object, name):
'See Zope.Security.IChecker.IChecker'
# YAGNI
raise Forbidden("Can't set attributes in untrusted code.")
def check(self, object, name):
'See Zope.Security.IChecker.IChecker'
# We have the information we need already
permission = self.__permission_func(name)
if permission:
if permission is CheckerPublic:
return # Public
manager = getSecurityManager()
if manager.checkPermission(permission, object):
return
else:
raise Unauthorized(name=name)
elif name in _always_available:
return
raise ForbiddenAttribute(name)
def proxy(self, value):
'See Zope.Security.IChecker.IChecker'
# Now we need to create a proxy
checker = selectChecker(value)
if checker is None:
return value
return Proxy(value, checker)
#
############################################################
def NamesChecker(names=(), permission_id=CheckerPublic, **__kw__):
"""Return a checker that grants access to a set of names.
A sequence of names is given as the first argument. If a second
argument, permission_id, is given, it is the permission required
to access the names. Additional names and persmission ids can be
supplied as keyword arguments.
"""
data = {}
data.update(__kw__)
for name in names:
if data.get(name, permission_id) is not permission_id:
raise DuplicationError(name)
data[name] = permission_id
return Checker(data.get)
def MultiChecker(specs):
"""Create a checker from a sequence of specifications
A specification is:
- A two-tuple with:
o a sequence of names or an interface
o a permission id
All the names in the sequence of names or the interface are
protected by the permission.
- A dictionoid (having anitems method), with items that are
name/permission-id pairs.
"""
data = {}
for spec in specs:
if type(spec) is tuple:
names, permission_id = spec
if IInterface.isImplementedBy(names):
names = names.names(1)
for name in names:
if data.get(name, permission_id) is not permission_id:
raise DuplicationError(name)
data[name] = permission_id
else:
for name, permission_id in spec.items():
if data.get(name, permission_id) is not permission_id:
raise DuplicationError(name)
data[name] = permission_id
return Checker(data.get)
def NonPrivateChecker(permission_id = CheckerPublic):
def check(name, permission_id=permission_id):
if name.startswith('_'):
return None
return permission_id
return Checker(check)
def selectChecker(object):
"""Get a checker for the given object
The appropriate checker is returned or None is returned. If the
return value is None, then object should not be wrapped in a proxy.
"""
checker = _getChecker(type(object), _defaultChecker)
if checker is NoProxy:
return None
while not isinstance(checker, Checker):
checker = checker(object)
if checker is NoProxy:
return None
return checker
def getCheckerForInstancesOf(class_):
return _checkers.get(class_)
def defineChecker(type_, checker):
"""Define a checker for a given type of object
The checker can be a Checker, or a function that, when called with
an object, returns a Checker.
"""
if type_ in _checkers:
raise DuplicationError(type_)
_checkers[type_] = checker
NoProxy = object()
# _checkers is a mapping.
#
# - Keys are types
#
# - Values are
#
# o None => rock
# o a Checker
# o a function returning None or a Checker
#
_checkers = {}
_getChecker = _checkers.get
_defaultChecker = Checker({}.get)
def _instanceChecker(inst):
checker = _checkers.get(inst.__class__, _defaultChecker)
if checker is _defaultChecker and isinstance(inst, Exception):
return NoProxy # XXX we should be more careful
return checker
def _classChecker(class_):
checker = _checkers.get(class_, _typeChecker)
if checker is _typeChecker and issubclass(class_, Exception):
return NoProxy # XXX we should be more careful
return checker
def _moduleChecker(module):
return _checkers.get(module, _typeChecker)
_always_available = ['__lt__', '__le__', '__eq__',
'__gt__', '__ge__', '__ne__',
'__hash__', '__nonzero__',
'__class__', '__implements__',
]
_callableChecker = NamesChecker(['__str__', '__repr__', '__name__',
'__call__'])
_typeChecker = NamesChecker(['__str__', '__repr__', '__name__', '__module__'])
BasicTypes = {
int: NoProxy,
float: NoProxy,
long: NoProxy,
complex: NoProxy,
type(None): NoProxy,
str: NoProxy,
unicode: NoProxy,
type(not 1): NoProxy, # Boolean, if available :)
}
_default_checkers = {
dict: NamesChecker(['__getitem__', '__len__', '__iter__',
'get', 'has_key', '__copy__',
'keys', 'values', 'items',
'iterkeys', 'iteritems', 'itervalues', '__contains__',
]),
list: NamesChecker(['__getitem__', '__getslice__', '__len__', '__iter__',
'__contains__', 'index', 'count']),
# YAGNI: () a rock
tuple: NamesChecker(['__getitem__', '__getslice__',
'__contains__', '__len__', '__iter__']),
InstanceType: _instanceChecker,
Proxy: NoProxy,
ClassType: _classChecker,
FunctionType: _callableChecker,
MethodType: _callableChecker,
type: _typeChecker,
ModuleType: _moduleChecker,
type(iter([])): NamesChecker(['next']),
}
def _clear():
_checkers.clear()
_checkers.update(_default_checkers)
_checkers.update(BasicTypes)
_clear()
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
=== Added File Zope3/lib/python/Zope/Security/IChecker.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.
#
##############################################################################
"""
$Id: IChecker.py,v 1.1.4.1 2002/04/28 17:16:49 jim Exp $
"""
from Interface import Interface
class IChecker(Interface):
"""Security-proxy plugin objects that implement low-level checks
The checker is responsible for creating proxies for
operation return values, via the proxy method.
There are check_getattr() and check_setattr() methods for checking
getattr and setattr, and a check() method for all other operations.
The check methods may raise errors. They return no value.
Example (for __getitem__):
checker.check(ob, "__getitem__")
return checker.proxy(ob[key])
"""
def check_getattr(ob, name):
"""Check whether attribute access is allowed.
"""
def check_setattr(ob, name):
"""Check whether attribute assignment is allowed.
"""
def check(ob, operation):
"""Check whether operation is allowed.
The operation name is the Python special method name,
e.g. "__getitem__".
"""
def proxy(value):
"""Return a security proxy for the value.
"""
=== 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/ISecurityProxyFactory.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.
#
##############################################################################
"""
$Id: ISecurityProxyFactory.py,v 1.1.4.1 2002/04/28 17:16:49 jim Exp $
"""
from Interface import Interface
class ISecurityProxyFactory(Interface):
def __call__(object, checker=None):
"""Create a security proxy
If a checker is given, then use it, otherwise, try to figure
out a checker.
If the object is already a security proxy, then it will be
returned.
"""
=== Added File Zope3/lib/python/Zope/Security/Proxy.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.
#
##############################################################################
"""
$Id: Proxy.py,v 1.1.4.1 2002/04/28 17:16:49 jim Exp $
"""
from _Proxy import getObject, getChecker
from _Proxy import _Proxy as Proxy
from Checker import ProxyFactory
=== Added File Zope3/lib/python/Zope/Security/RestrictedInterpreter.py ===
import sys
from Zope.Security.Proxy import ProxyFactory
class RestrictedInterpreter:
ok_builtin_modules = ('audioop', 'array', 'binascii',
'cmath', 'errno', 'imageop',
'marshal', 'math', 'md5', 'operator',
'parser', 'regex', 'pcre', 'rotor', 'select',
'sha', '_sre', 'strop', 'struct', 'time')
ok_sys_names = ('ps1', 'ps2', 'copyright', 'version',
'platform', 'exit', 'maxint')
nok_builtin_names = ('open', 'file', 'reload', '__import__')
def __init__(self, checker):
self.checker = checker
self.builtins = {}
self.globals = {'__builtins__' : self.builtins}
self.create_builtins()
def ri_exec(self, code):
# what is the type of code?
exec code in self.globals
def create_builtins(self):
import __builtin__
for k, v in __builtin__.__dict__.iteritems():
if k not in self.nok_builtin_names:
self.builtins[k] = ProxyFactory(v, self.checker)
self.builtins['__import__'] = ProxyFactory(self.ri_import)
def ri_import(self, name, globals, locals, fromlist):
# XXX handle fromlist
return sys.modules[name]
=== 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
=== Added File Zope3/lib/python/Zope/Security/_Proxy.c === (690/790 lines abridged)
/*
* Security proxy.
*/
#include <Python.h>
typedef struct {
PyObject_HEAD
PyObject *proxy_object;
PyObject *proxy_checker;
} ProxyObject;
#define Proxy_Check(proxy) \
PyObject_TypeCheck(proxy, &ProxyType)
#define Proxy_GetObject(proxy) \
(((ProxyObject *)proxy)->proxy_object)
#define Proxy_GetChecker(proxy) \
(((ProxyObject *)proxy)->proxy_checker)
staticforward PyTypeObject ProxyType;
/*
* Machinery to call the checker.
*/
typedef PyObject *(*function1)(PyObject *);
static int
check(PyObject *checker, char *opname, PyObject *object)
{
PyObject *checked;
checked = PyObject_CallMethod(checker, "check", "(Os)",
object, opname);
if (checked == NULL)
return 0;
Py_DECREF(checked);
return 1;
}
static int
checkattr(PyObject *checker, char *check_method,
PyObject *object, PyObject *name)
{
PyObject *checked;
[-=- -=- -=- 690 lines omitted -=- -=- -=-]
PyErr_SetString(PyExc_TypeError,
"getObject argument must be a _Proxy");
return NULL;
}
result = Proxy_GetObject(arg);
Py_INCREF(result);
return result;
}
static PyObject *
module_getChecker(PyObject *self, PyObject *arg)
{
PyObject *result;
if (!Proxy_Check(arg)) {
PyErr_SetString(PyExc_TypeError,
"getChecker argument must be a _Proxy");
return NULL;
}
result = Proxy_GetChecker(arg);
Py_INCREF(result);
return result;
}
static PyMethodDef
module_functions[] = {
{"getObject", module_getObject, METH_O, "get object from proxy"},
{"getChecker", module_getChecker, METH_O, "get checker from proxy"},
{NULL}
};
static char
module___doc__[] = "Security proxy implementation.";
void
init_Proxy(void)
{
PyObject *m;
ProxyType.ob_type = &PyType_Type;
if (PyType_Ready(&ProxyType) < 0)
return;
m = Py_InitModule3("_Proxy", module_functions, module___doc__);
if (m == NULL)
return;
Py_INCREF(&ProxyType);
PyModule_AddObject(m, "_Proxy", (PyObject *)&ProxyType);
}
=== Added File Zope3/lib/python/Zope/Security/__init__.py ===
=== Added File Zope3/lib/python/Zope/Security/setup.py ===
#! /usr/bin/env python
##############################################################################
#
# 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 distutils.core import setup, Extension
setup(name="_Proxy", version = "0.1",
ext_modules=[Extension("_Proxy", ["_Proxy.c"])])