[Zope-Checkins] CVS: Zope2 - PermissionRole.py:1.10 ZopeSecurityPolicy.py:1.12 cAccessControl.c:1.8
Matthew T. Kromer
matt@digicool.com
Tue, 3 Jul 2001 15:37:53 -0400 (EDT)
Update of /cvs-repository/Zope2/lib/python/AccessControl
In directory korak.digicool.com:/tmp/cvs-serv3012
Modified Files:
PermissionRole.py ZopeSecurityPolicy.py cAccessControl.c
Log Message:
Accelerated to go with Acquisition C api
--- Updated File PermissionRole.py in package Zope2 --
--- PermissionRole.py 2000/12/05 18:49:42 1.9
+++ PermissionRole.py 2001/07/03 19:37:52 1.10
@@ -88,120 +88,11 @@
$Id$'''
__version__='$Revision$'[11:-2]
-import sys
-
-from ExtensionClass import Base
-
-import string
-
-name_trans=filter(lambda c, an=string.letters+string.digits+'_': c not in an,
- map(chr,range(256)))
-name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans))
-
-def rolesForPermissionOn(perm, object, default=('Manager',)):
- """Return the roles that have the given permission on the given object
- """
- im=imPermissionRole()
- im._p='_'+string.translate(perm, name_trans)+"_Permission"
- im._d=default
- return im.__of__(object)
-
-
-class PermissionRole(Base):
- """Implement permission-based roles.
-
- Under normal circumstances, our __of__ method will be
- called with an unwrapped object. The result will then be called
- with a wrapped object, if the original object was wrapped.
- To deal with this, we have to create an intermediate object.
-
- """
-
- def __init__(self, name, default=('Manager',)):
- self.__name__=name
- self._p='_'+string.translate(name,name_trans)+"_Permission"
- self._d=default
-
- def __of__(self, parent, None=None, getattr=getattr):
- r=imPermissionRole()
- r._p=self._p
- r._pa=parent
- r._d=self._d
- p=getattr(parent, 'aq_inner', None)
- if p is not None:
- return r.__of__(p)
- else:
- return r
-
-
-# This is used when a permission maps explicitly to no permission.
-_what_not_even_god_should_do=[]
-
-class imPermissionRole(Base):
- """Implement permission-based roles
- """
-
- def __of__(self, parent,tt=type(()),st=type(''),getattr=getattr,None=None):
- obj=parent
- n=self._p
- r=None
- while 1:
- if hasattr(obj,n):
- roles=getattr(obj, n)
-
- if roles is None: return 'Anonymous',
-
- t=type(roles)
-
- if t is tt:
- # If we get a tuple, then we don't acquire
- if r is None: return roles
- return r+list(roles)
-
- if t is st:
- # We found roles set to a name. Start over
- # with the new permission name. If the permission
- # name is '', then treat as private!
- if roles:
- if roles != n:
- n=roles
- # If we find a name that is the same as the
- # current name, we just ignore it.
- roles=None
- else:
- return _what_not_even_god_should_do
-
- elif roles:
- if r is None: r=list(roles)
- else: r=r+list(roles)
-
- obj=getattr(obj, 'aq_inner', None)
- if obj is None: break
- obj=obj.aq_parent
-
- if r is None: r=self._d
-
- return r
-
- # The following methods are needed in the unlikely case that an unwrapped
- # object is accessed:
- def __getitem__(self, i):
- try:
- v=self._v
- except:
- v=self._v=self.__of__(self._pa)
- del self._pa
-
- return v[i]
-
- def __len__(self):
- try:
- v=self._v
- except:
- v=self._v=self.__of__(self._pa)
- del self._pa
-
- return len(v)
+import cAccessControl
+rolesForPermissionOn=cAccessControl.rolesForPermissionOn
+PermissionRole=cAccessControl.PermissionRole
+imPermisionRole=cAccessControl.imPermissionRole
+_what_not_even_god_should_do= cAccessControl._what_not_even_god_should_do
##############################################################################
# Test functions:
--- Updated File ZopeSecurityPolicy.py in package Zope2 --
--- ZopeSecurityPolicy.py 2001/06/07 22:36:43 1.11
+++ ZopeSecurityPolicy.py 2001/07/03 19:37:52 1.12
@@ -1,253 +1,9 @@
-##############################################################################
-#
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-#
-# Copyright (c) Digital Creations. All rights reserved.
-#
-# This license has been certified as Open Source(tm).
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# 1. Redistributions in source code must retain the above copyright
-# notice, this list of conditions, and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions, and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# 3. Digital Creations requests that attribution be given to Zope
-# in any manner possible. Zope includes a "Powered by Zope"
-# button that is installed by default. While it is not a license
-# violation to remove this button, it is requested that the
-# attribution remain. A significant investment has been put
-# into Zope, and this effort will continue if the Zope community
-# continues to grow. This is one way to assure that growth.
-#
-# 4. All advertising materials and documentation mentioning
-# features derived from or use of this software must display
-# the following acknowledgement:
-#
-# "This product includes software developed by Digital Creations
-# for use in the Z Object Publishing Environment
-# (http://www.zope.org/)."
-#
-# In the event that the product being advertised includes an
-# intact Zope distribution (with copyright and license included)
-# then this clause is waived.
-#
-# 5. Names associated with Zope or Digital Creations must not be used to
-# endorse or promote products derived from this software without
-# prior written permission from Digital Creations.
-#
-# 6. Modified redistributions of any form whatsoever must retain
-# the following acknowledgment:
-#
-# "This product includes software developed by Digital Creations
-# for use in the Z Object Publishing Environment
-# (http://www.zope.org/)."
-#
-# Intact (re-)distributions of any official Zope release do not
-# require an external acknowledgement.
-#
-# 7. Modifications are encouraged but must be packaged separately as
-# patches to official Zope releases. Distributions that do not
-# clearly separate the patches from the original work must be clearly
-# labeled as unofficial distributions. Modifications which do not
-# carry the name Zope may be packaged in any form, as long as they
-# conform to all of the clauses above.
-#
-#
-# Disclaimer
-#
-# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-#
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations. Specific
-# attributions are listed in the accompanying credits file.
-#
-##############################################################################
-__doc__='''Define Zope\'s default security policy
+#
+from SimpleObjectPolicies import _noroles
-$Id$'''
-__version__='$Revision$'[11:-2]
+import cAccessControl
-from types import StringType
+ZopeSecurityPolicy = cAccessControl.ZopeSecurityPolicy
-import SimpleObjectPolicies
-from AccessControl import Unauthorized
-_noroles=SimpleObjectPolicies._noroles
-from zLOG import LOG, PROBLEM
-from Acquisition import aq_base
-from PermissionRole import _what_not_even_god_should_do, rolesForPermissionOn
-
-
-class ZopeSecurityPolicy:
-
- def validate(self, accessed, container, name, value, context,
- roles=_noroles, None=None, type=type, IntType=type(0),
- DictType=type({}), getattr=getattr, _noroles=_noroles,
- StringType=type(''),
- Containers=SimpleObjectPolicies.Containers,
- valid_aq_=('aq_parent','aq_explicit')):
-
-
- ############################################################
- # Provide special rules for the acquisition attributes
- if type(name) is StringType:
- if name[:3]=='aq_' and name not in valid_aq_:
- return 0
-
- containerbase = aq_base(container)
- accessedbase=getattr(accessed, 'aq_base', container)
-
- ############################################################
- # If roles weren't passed in, we'll try to get them from the object
-
- if roles is _noroles:
- roles=getattr(value, '__roles__', _noroles)
-
- ############################################################
- # We still might not have any roles
-
- if roles is _noroles:
-
- ############################################################
- # We have an object without roles and we didn't get a list
- # of roles passed in. Presumably, the value is some simple
- # object like a string or a list. We'll try to get roles
- # from its container.
- if container is None: return 0 # Bail if no container
-
- roles=getattr(container, '__roles__', _noroles)
- if roles is _noroles:
- aq=getattr(container, 'aq_acquire', None)
- if aq is None:
- roles=_noroles
- if containerbase is not accessedbase: return 0
- else:
- # Try to acquire roles
- try: roles=aq('__roles__')
- except AttributeError:
- roles=_noroles
- if containerbase is not accessedbase: return 0
-
- # We need to make sure that we are allowed to
- # get unprotected attributes from the container. We are
- # allowed for certain simple containers and if the
- # container says we can. Simple containers
- # may also impose name restrictions.
- p=Containers(type(container), None)
- if p is None:
- p=getattr(container,
- '__allow_access_to_unprotected_subobjects__', None)
-
- if p is not None:
- tp=type(p)
- if tp is not IntType:
- if tp is DictType:
- p=p.get(name, None)
- else:
- p=p(name, value)
-
- if not p:
- if (containerbase is accessedbase):
- raise Unauthorized, cleanupName(name, value)
- else:
- return 0
-
- if roles is _noroles: return 1
-
- # We are going to need a security-aware object to pass
- # to allowed(). We'll use the container.
- value=container
-
- # Short-circuit tests if we can:
- try:
- if roles is None or 'Anonymous' in roles: return 1
- except TypeError:
- # 'roles' isn't a sequence
- LOG('Zope Security Policy', PROBLEM, "'%s' passed as roles"
- " during validation of '%s' is not a sequence." % (
- `roles`, name))
- raise
-
- # Check executable security
- stack=context.stack
- if stack:
- eo=stack[-1]
-
- # If the executable had an owner, can it execute?
- owner=eo.getOwner()
- if (owner is not None) and not owner.allowed(value, roles):
- # We don't want someone to acquire if they can't
- # get an unacquired!
- if accessedbase is containerbase:
- raise Unauthorized, (
- 'You are not authorized to access <em>%s</em>.' \
- % cleanupName(name, value))
- return 0
-
- # Proxy roles, which are a lot safer now.
- proxy_roles=getattr(eo, '_proxy_roles', None)
- if proxy_roles:
- for r in proxy_roles:
- if r in roles: return 1
-
- # Proxy roles actually limit access!
- if accessedbase is containerbase:
- raise Unauthorized, (
- 'You are not authorized to access <em>%s</em>.' \
- % cleanupName(name, value))
-
- return 0
-
-
- try:
- if context.user.allowed(value, roles): return 1
- except AttributeError: pass
-
- # We don't want someone to acquire if they can't get an unacquired!
- if accessedbase is containerbase:
- raise Unauthorized, (
- 'You are not authorized to access <em>%s</em>.' \
- % cleanupName(name, value))
-
- return 0
-
- def checkPermission(self, permission, object, context):
- roles=rolesForPermissionOn(permission, object)
- if type(roles) is StringType:
- roles=[roles]
- return context.user.allowed(object, roles)
-
-
-def cleanupName(name, value):
- # If name is not available, tries to get it from the value.
- _name = name
- if _name is None and value is not None:
- try: _name = value.id
- except:
- try: _name = value.__name__
- except: pass
- if callable(_name):
- try: _name = _name()
- except: pass
- return _name
--- Updated File cAccessControl.c in package Zope2 --
--- cAccessControl.c 2001/07/03 12:52:56 1.7
+++ cAccessControl.c 2001/07/03 19:37:52 1.8
@@ -51,6 +51,7 @@
#include <stdio.h>
#include "ExtensionClass.h"
+#include "Acquisition.h"
#define OBJECT(o) ((PyObject *) (o))
@@ -339,7 +340,6 @@
*/
static PyObject *Containers = NULL;
-static PyObject *aq_base = NULL;
static PyObject *_noroles = NULL;
static PyObject *Unauthorized = NULL;
static PyObject *LOG = NULL;
@@ -348,6 +348,7 @@
static PyObject *Anonymous = NULL;
static PyObject *imPermissionRoleObj = NULL;
static PyObject *defaultPermission = NULL;
+static PyObject *__roles__ = NULL;
/* --------------------------------------------------------------
** ZopeSecurityPolicy Methods
@@ -392,16 +393,9 @@
Py_DECREF(module);
module = NULL;
- /*| from Acquisition import aq_base
- */
-
- IMPORT(module,"Acquisition");
- GETATTR(module, aq_base);
- Py_DECREF(module);
- module = NULL;
-
defaultPermission = Py_BuildValue("(s)", "Manager");
_what_not_even_god_should_do = Py_BuildValue("[]");
+ __roles__ = PyString_FromString("__roles__");
return 1;
@@ -662,12 +656,12 @@
**| accessedbase = getattr(accessed, 'aq_base', container)
*/
- containerbase = PyObject_CallFunction(aq_base, "O", container);
+ containerbase = aq_base(container);
if (containerbase == NULL) goto err;
- accessedbase = PyObject_GetAttrString(accessed, "aq_base");
- if (accessedbase == NULL) {
- PyErr_Clear();
+ if (aq_isWrapper(accessed))
+ accessedbase = aq_base(accessed);
+ else {
Py_INCREF(container);
accessedbase = container;
}
@@ -695,7 +689,7 @@
if (roles == NULL || roles == _noroles) {
Py_XDECREF(roles);
- roles = PyObject_GetAttrString(value, "__roles__");
+ roles = PyObject_GetAttr(value, __roles__);
if (roles == NULL) {
PyErr_Clear();
Py_INCREF(_noroles);
@@ -739,7 +733,7 @@
Py_XDECREF(roles);
- roles = PyObject_GetAttrString(container, "__roles__");
+ roles = PyObject_GetAttr(container, __roles__);
if (roles == NULL) {
PyErr_Clear();
Py_INCREF(_noroles);
@@ -747,11 +741,7 @@
}
if (roles == _noroles) {
- PyObject *aq;
-
- aq = PyObject_GetAttrString(container, "aq_acquire");
- if (aq == NULL) {
- PyErr_Clear();
+ if (aq_isWrapper(container) != 1) {
Py_DECREF(roles);
if (containerbase != accessedbase) {
rval = PyInt_FromLong(0);
@@ -762,10 +752,7 @@
roles = _noroles;
} else {
Py_DECREF(roles);
- roles = PyObject_CallFunction(aq, "s",
- "__roles__");
- Py_DECREF(aq);
- aq = NULL;
+ roles = aq_acquire(container, __roles__);
if (roles == NULL) {
/* XXX not JUST AttributeError*/
/* XXX should we clear the error? */
@@ -1289,9 +1276,9 @@
**| return r
*/
- _p = PyObject_GetAttrString(parent, "aq_inner");
- if (_p) {
+ if (aq_isWrapper(parent)) {
+ _p = aq_inner(parent);
result = PyObject_CallMethod(OBJECT(r),"__of__","O", _p);
Py_DECREF(_p);
/* Dont need goto */
@@ -1503,13 +1490,15 @@
**| obj = obj.aq_parent
*/
- tobj = PyObject_GetAttrString(obj, "aq_inner");
+ if (aq_isWrapper(obj) <= 0) break;
+ tobj = aq_inner(obj);
if (tobj == NULL) break;
Py_DECREF(obj);
obj = tobj;
if (obj == Py_None) break;
- tobj = PyObject_GetAttrString(obj, "aq_parent");
+ if (aq_isWrapper(obj) <= 0) break;
+ tobj = aq_parent(obj);
if (tobj == NULL) goto err;
Py_DECREF(obj);
obj = tobj;
@@ -1777,6 +1766,8 @@
char *rev = "$Revision$";
if (!ExtensionClassImported) return;
+
+ aq_init();
ZopeSecurityPolicyType.tp_getattro =
(getattrofunc) PyExtensionClassCAPI->getattro;