Commit 8997c967 authored by matt@zope.com's avatar matt@zope.com

Document Template accelerations and additonal C Security Manager accelerations

from cAccessControl-review-branch.
parent a7131d9f
...@@ -89,6 +89,11 @@ Zope Changes ...@@ -89,6 +89,11 @@ Zope Changes
- API help topics can now document functions as well as classes. - API help topics can now document functions as well as classes.
- Security accelerations in c
- Accelerated C Document Template handling; Document Templates
can now do additional rendering in C, improving performance.
Bugs fixed Bugs fixed
- WebDAV: Zope escaped nested object properties derived from - WebDAV: Zope escaped nested object properties derived from
......
...@@ -148,6 +148,16 @@ Security issues ...@@ -148,6 +148,16 @@ Security issues
2.5+) 2.5+)
ZSP_OWNEROUS_SKIP
If set, will cause the Zope Security Policy to skip checks relating
to ownership, for servers on which ownership is not important.
ZSP_AUTHENTICATED_SKIP
If set, will cause the Zope Security Policy to skip checks relating
to authentication, for servers which serve only anonymous content.
DISALLOW_LOCAL_PRODUCTS DISALLOW_LOCAL_PRODUCTS
unknown unknown
......
...@@ -84,26 +84,42 @@ ...@@ -84,26 +84,42 @@
############################################################################## ##############################################################################
'''Add security system support to Document Templates '''Add security system support to Document Templates
$Id: DTML.py,v 1.7 2001/06/21 17:16:31 shane Exp $''' $Id: DTML.py,v 1.8 2001/10/26 16:07:50 matt Exp $'''
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
from DocumentTemplate import DT_Util from DocumentTemplate import DT_Util
import SecurityManagement, string, math, whrandom, random import SecurityManagement, string, math, whrandom, random
import DocumentTemplate.sequence import DocumentTemplate.sequence
from ZopeGuards import guarded_getattr, guarded_getitem, _marker from ZopeGuards import guarded_getattr, guarded_getitem
class RestrictedDTML: class RestrictedDTML:
''' '''
A mix-in for derivatives of DT_String.String that adds Zope security. A mix-in for derivatives of DT_String.String that adds Zope security.
''' '''
def guarded_getattr(self, ob, name, default=_marker): def guarded_getattr(self, *args): # ob, name [, default]
return guarded_getattr(ob, name, default) return guarded_getattr(*args)
def guarded_getitem(self, ob, index): def guarded_getitem(self, ob, index):
return guarded_getitem(ob, index) return guarded_getitem(ob, index)
try:
#raise ImportError
import os
if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
raise ImportError # :)
from cAccessControl import RestrictedDTMLMixin
except ImportError:
pass
else:
class RestrictedDTML(RestrictedDTMLMixin, RestrictedDTML):
'''
A mix-in for derivatives of DT_String.String that adds Zope security.
'''
# Allow access to unprotected attributes # Allow access to unprotected attributes
DT_Util.TemplateDict.__allow_access_to_unprotected_subobjects__=1 DT_Util.TemplateDict.__allow_access_to_unprotected_subobjects__=1
string.__allow_access_to_unprotected_subobjects__=1 string.__allow_access_to_unprotected_subobjects__=1
......
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''Objects that implement Permission-based roles. __doc__='''Objects that implement Permission-based roles.
$Id: PermissionRole.py,v 1.12 2001/10/19 15:12:25 shane Exp $''' $Id: PermissionRole.py,v 1.13 2001/10/26 16:07:50 matt Exp $'''
__version__='$Revision: 1.12 $'[11:-2] __version__='$Revision: 1.13 $'[11:-2]
_use_python_impl = 0 _use_python_impl = 0
import os import os
......
...@@ -85,8 +85,21 @@ ...@@ -85,8 +85,21 @@
__doc__='''short description __doc__='''short description
$Id: SecurityManagement.py,v 1.4 2001/07/02 16:29:55 evan Exp $''' $Id: SecurityManagement.py,v 1.5 2001/10/26 16:07:50 matt Exp $'''
__version__='$Revision: 1.4 $'[11:-2] __version__='$Revision: 1.5 $'[11:-2]
def getSecurityManager():
"""Get a security manager, for the current thread.
"""
thread_id=get_ident()
manager=_managers.get(thread_id, None)
if manager is None:
manager=SecurityManager(
thread_id,
SecurityContext(SpecialUsers.nobody))
_managers[thread_id]=manager
return manager
import SpecialUsers import SpecialUsers
from SecurityManager import SecurityManager from SecurityManager import SecurityManager
...@@ -110,19 +123,6 @@ def noSecurityManager(): ...@@ -110,19 +123,6 @@ def noSecurityManager():
except: pass except: pass
def getSecurityManager():
"""Get a security manager, for the current thread.
"""
thread_id=get_ident()
manager=_managers.get(thread_id, None)
if manager is None:
manager=SecurityManager(
thread_id,
SecurityContext(SpecialUsers.nobody))
_managers[thread_id]=manager
return manager
def setSecurityPolicy(aSecurityPolicy): def setSecurityPolicy(aSecurityPolicy):
"""Set the system default security policy. """Set the system default security policy.
......
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''short description __doc__='''short description
$Id: SecurityManager.py,v 1.7 2001/10/19 15:12:25 shane Exp $''' $Id: SecurityManager.py,v 1.8 2001/10/26 16:07:50 matt Exp $'''
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
import ZopeSecurityPolicy, os, string import ZopeSecurityPolicy, os, string
...@@ -95,7 +95,12 @@ _noroles = ZopeSecurityPolicy._noroles ...@@ -95,7 +95,12 @@ _noroles = ZopeSecurityPolicy._noroles
try: max_stack_size=string.atoi(os.environ.get('Z_MAX_STACK_SIZE','100')) try: max_stack_size=string.atoi(os.environ.get('Z_MAX_STACK_SIZE','100'))
except: max_stack_size=100 except: max_stack_size=100
_defaultPolicy=ZopeSecurityPolicy.ZopeSecurityPolicy() if os.environ.has_key("ZSP_OWNEROUS_SKIP"): ownerous=0
else: ownerous=1
if os.environ.has_key("ZSP_AUTHENTICATION_SKIP"): authenticated=0
else: authenticated=1
_defaultPolicy=ZopeSecurityPolicy.ZopeSecurityPolicy(ownerous=ownerous,
authenticated=authenticated)
def setSecurityPolicy(aSecurityPolicy): def setSecurityPolicy(aSecurityPolicy):
"""Set the system default security policy. """Set the system default security policy.
...@@ -107,6 +112,7 @@ def setSecurityPolicy(aSecurityPolicy): ...@@ -107,6 +112,7 @@ def setSecurityPolicy(aSecurityPolicy):
_defaultPolicy=aSecurityPolicy _defaultPolicy=aSecurityPolicy
return last return last
class SecurityManager: class SecurityManager:
"""A security manager provides methods for checking access and managing """A security manager provides methods for checking access and managing
executable context and policies executable context and policies
...@@ -120,7 +126,7 @@ class SecurityManager: ...@@ -120,7 +126,7 @@ class SecurityManager:
def __init__(self, thread_id, context): def __init__(self, thread_id, context):
self._thread_id=thread_id self._thread_id=thread_id
self._context=context self._context=context
self._policy=None self._policy=_defaultPolicy
def validate(self, accessed=None, container=None, name=None, value=None, def validate(self, accessed=None, container=None, name=None, value=None,
roles=_noroles): roles=_noroles):
...@@ -144,7 +150,6 @@ class SecurityManager: ...@@ -144,7 +150,6 @@ class SecurityManager:
all the values possible. all the values possible.
""" """
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy
if roles is _noroles: if roles is _noroles:
return policy.validate(accessed, container, name, value, return policy.validate(accessed, container, name, value,
self._context) self._context)
...@@ -153,7 +158,7 @@ class SecurityManager: ...@@ -153,7 +158,7 @@ class SecurityManager:
self._context, roles) self._context, roles)
def DTMLValidate(self, accessed=None, container=None, name=None, def DTMLValidate(self, accessed=None, container=None, name=None,
value=None,md=None): value=None, md=None):
"""Validate access. """Validate access.
* THIS EXISTS FOR DTML COMPATIBILITY * * THIS EXISTS FOR DTML COMPATIBILITY *
...@@ -177,7 +182,6 @@ class SecurityManager: ...@@ -177,7 +182,6 @@ class SecurityManager:
""" """
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy
return policy.validate(accessed, container, name, value, return policy.validate(accessed, container, name, value,
self._context) self._context)
...@@ -185,7 +189,6 @@ class SecurityManager: ...@@ -185,7 +189,6 @@ class SecurityManager:
"""Convenience for common case of simple value validation. """Convenience for common case of simple value validation.
""" """
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy
if roles is _noroles: if roles is _noroles:
return policy.validate(None, None, None, value, return policy.validate(None, None, None, value,
self._context) self._context)
...@@ -204,7 +207,6 @@ class SecurityManager: ...@@ -204,7 +207,6 @@ class SecurityManager:
object -- The object being accessed according to the permission object -- The object being accessed according to the permission
""" """
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy
return policy.checkPermission(permission, object, return policy.checkPermission(permission, object,
self._context) self._context)
...@@ -218,7 +220,10 @@ class SecurityManager: ...@@ -218,7 +220,10 @@ class SecurityManager:
raise SystemError, 'Excessive recursion' raise SystemError, 'Excessive recursion'
stack.append(anExecutableObject) stack.append(anExecutableObject)
p=getattr(anExecutableObject, '_customSecurityPolicy', None) p=getattr(anExecutableObject, '_customSecurityPolicy', None)
if p is not None: p=p() if p is not None:
p=p()
else:
p=_defaultPolicy
self._policy=p self._policy=p
def removeContext(self, anExecutableObject, def removeContext(self, anExecutableObject,
...@@ -245,10 +250,13 @@ class SecurityManager: ...@@ -245,10 +250,13 @@ class SecurityManager:
if stack: if stack:
top=stack[-1] top=stack[-1]
p=getattr(top, '_customSecurityPolicy', None) p=getattr(top, '_customSecurityPolicy', None)
if p is not None: p=p() if p is not None:
p=p()
else:
p=_defaultPolicy
self._policy=p self._policy=p
else: else:
self._policy=None self._policy=_defaultPolicy
def getUser(self): def getUser(self):
"""Get the current authenticated user""" """Get the current authenticated user"""
...@@ -260,3 +268,17 @@ class SecurityManager: ...@@ -260,3 +268,17 @@ class SecurityManager:
return len(self._context.stack) return len(self._context.stack)
try:
#raise ImportError
import os
if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
raise ImportError # :)
from cAccessControl import SecurityManager as cSecurityManager
except ImportError:
pass
else:
class SecurityManager(cSecurityManager, SecurityManager):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
from RestrictedPython.Guards import safe_builtins, _full_read_guard, \ from RestrictedPython.Guards import safe_builtins, _full_read_guard, \
full_write_guard full_write_guard
...@@ -98,10 +98,21 @@ _marker = [] # Create a new marker object. ...@@ -98,10 +98,21 @@ _marker = [] # Create a new marker object.
safe_builtins = safe_builtins.copy() safe_builtins = safe_builtins.copy()
safe_builtins.update(utility_builtins) safe_builtins.update(utility_builtins)
def aq_validate(inst, obj, name, v, validate): try:
#raise ImportError
import os
if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
raise ImportError # :)
from cAccessControl import aq_validate, guarded_getattr
except ImportError:
def aq_validate(inst, obj, name, v, validate):
return validate(inst, obj, name, v) return validate(inst, obj, name, v)
def guarded_getattr(inst, name, default=_marker):
def guarded_getattr(inst, name, default=_marker):
if name[:1] != '_': if name[:1] != '_':
# Try to get the attribute normally so that unusual # Try to get the attribute normally so that unusual
# exceptions are caught early. # exceptions are caught early.
...@@ -121,6 +132,7 @@ def guarded_getattr(inst, name, default=_marker): ...@@ -121,6 +132,7 @@ def guarded_getattr(inst, name, default=_marker):
if validate(inst, inst, name, v): if validate(inst, inst, name, v):
return v return v
raise Unauthorized, name raise Unauthorized, name
safe_builtins['getattr'] = guarded_getattr safe_builtins['getattr'] = guarded_getattr
def guarded_hasattr(object, name): def guarded_hasattr(object, name):
......
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''Define Zope\'s default security policy __doc__='''Define Zope\'s default security policy
$Id: ZopeSecurityPolicy.py,v 1.14 2001/10/19 15:12:25 shane Exp $''' $Id: ZopeSecurityPolicy.py,v 1.15 2001/10/26 16:07:50 matt Exp $'''
__version__='$Revision: 1.14 $'[11:-2] __version__='$Revision: 1.15 $'[11:-2]
_use_python_impl = 0 _use_python_impl = 0
...@@ -119,8 +119,32 @@ if _use_python_impl: ...@@ -119,8 +119,32 @@ if _use_python_impl:
class ZopeSecurityPolicy: class ZopeSecurityPolicy:
def __init__(self, ownerous=1): def __init__(self, ownerous=1, authenticated=1):
"""Create a Zope security policy.
Two optional keyword arguments may be provided:
ownerous -- Untrusted users can create code
(e.g. Python scripts or templates),
so check that code owners can access resources.
The argument must have a truth value.
The default is true.
authenticated -- Allow access to resources based on the
privaledges of the authenticated user.
The argument must have a truth value.
The default is true.
This (somewhat experimental) option can be set
to false on sites that allow only public
(unauthenticated) access. An anticipated
scenario is a ZEO configuration in which some
clients allow only public access and other
clients allow full management.
"""
self._ownerous=ownerous self._ownerous=ownerous
self._authenticated=authenticated
def validate(self, accessed, container, name, value, context, def validate(self, accessed, container, name, value, context,
roles=_noroles, None=None, type=type, IntType=type(0), roles=_noroles, None=None, type=type, IntType=type(0),
...@@ -239,7 +263,8 @@ if _use_python_impl: ...@@ -239,7 +263,8 @@ if _use_python_impl:
try: try:
if context.user.allowed(value, roles): return 1 if self._authenticated and context.user.allowed(value, roles):
return 1
except AttributeError: pass except AttributeError: pass
# We don't want someone to acquire if they can't get an unacquired! # We don't want someone to acquire if they can't get an unacquired!
...@@ -254,4 +279,3 @@ if _use_python_impl: ...@@ -254,4 +279,3 @@ if _use_python_impl:
if type(roles) is StringType: if type(roles) is StringType:
roles=[roles] roles=[roles]
return context.user.allowed(object, roles) return context.user.allowed(object, roles)
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. DAMAGE.
$Id: cAccessControl.c,v 1.11 2001/10/19 15:12:25 shane Exp $ $Id: cAccessControl.c,v 1.12 2001/10/26 16:07:50 matt Exp $
If you have questions regarding this software, If you have questions regarding this software,
contact: contact:
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "ExtensionClass.h" #include "ExtensionClass.h"
#include "Acquisition.h" #include "Acquisition.h"
...@@ -66,18 +67,24 @@ PyVar_Assign(PyObject **v, PyObject *e) ...@@ -66,18 +67,24 @@ PyVar_Assign(PyObject **v, PyObject *e)
#define OBJECT(o) ((PyObject *) (o)) #define OBJECT(o) ((PyObject *) (o))
static PyObject * static PyObject *
callmethod1(PyObject *self, PyObject *name, PyObject *arg) callfunction1(PyObject *function, PyObject *arg)
{ {
UNLESS(self = PyObject_GetAttr(self,name)) return NULL; PyObject *t, *r;
name = PyTuple_New(1); t = PyTuple_New(1);
if (name == NULL) { if (t == NULL)
Py_DECREF(self);
return NULL; return NULL;
}
Py_INCREF(arg); Py_INCREF(arg);
PyTuple_SET_ITEM(name, 0, arg); PyTuple_SET_ITEM(t, 0, arg);
ASSIGN(self, PyObject_CallObject(self, name)); r = PyObject_CallObject(function, t);
Py_DECREF(name); Py_DECREF(t);
return r;
}
static PyObject *
callmethod1(PyObject *self, PyObject *name, PyObject *arg)
{
UNLESS(self = PyObject_GetAttr(self,name)) return NULL;
ASSIGN(self, callfunction1(self, arg));
return self; return self;
} }
...@@ -97,6 +104,198 @@ callfunction2(PyObject *function, PyObject *arg0, PyObject *arg1) ...@@ -97,6 +104,198 @@ callfunction2(PyObject *function, PyObject *arg0, PyObject *arg1)
return r; return r;
} }
static PyObject *
callfunction3(PyObject *function,
PyObject *arg0, PyObject *arg1,
PyObject *arg2
)
{
PyObject *t, *r;
t = PyTuple_New(3);
if (t == NULL)
return NULL;
Py_INCREF(arg0);
Py_INCREF(arg1);
Py_INCREF(arg2);
PyTuple_SET_ITEM(t, 0, arg0);
PyTuple_SET_ITEM(t, 1, arg1);
PyTuple_SET_ITEM(t, 2, arg2);
r = PyObject_CallObject(function, t);
Py_DECREF(t);
return r;
}
static PyObject *
callfunction4(PyObject *function,
PyObject *arg0, PyObject *arg1,
PyObject *arg2, PyObject *arg3
)
{
PyObject *t, *r;
t = PyTuple_New(4);
if (t == NULL)
return NULL;
Py_INCREF(arg0);
Py_INCREF(arg1);
Py_INCREF(arg2);
Py_INCREF(arg3);
PyTuple_SET_ITEM(t, 0, arg0);
PyTuple_SET_ITEM(t, 1, arg1);
PyTuple_SET_ITEM(t, 2, arg2);
PyTuple_SET_ITEM(t, 3, arg3);
r = PyObject_CallObject(function, t);
Py_DECREF(t);
return r;
}
static PyObject *
callfunction5(PyObject *function,
PyObject *arg0, PyObject *arg1,
PyObject *arg2, PyObject *arg3, PyObject *arg4
)
{
PyObject *t, *r;
t = PyTuple_New(5);
if (t == NULL)
return NULL;
Py_INCREF(arg0);
Py_INCREF(arg1);
Py_INCREF(arg2);
Py_INCREF(arg3);
Py_INCREF(arg4);
PyTuple_SET_ITEM(t, 0, arg0);
PyTuple_SET_ITEM(t, 1, arg1);
PyTuple_SET_ITEM(t, 2, arg2);
PyTuple_SET_ITEM(t, 3, arg3);
PyTuple_SET_ITEM(t, 4, arg4);
r = PyObject_CallObject(function, t);
Py_DECREF(t);
return r;
}
static PyObject *
callfunction6(PyObject *function,
PyObject *arg0, PyObject *arg1,
PyObject *arg2, PyObject *arg3,
PyObject *arg4, PyObject *arg5
)
{
PyObject *t, *r;
t = PyTuple_New(6);
if (t == NULL)
return NULL;
Py_INCREF(arg0);
Py_INCREF(arg1);
Py_INCREF(arg2);
Py_INCREF(arg3);
Py_INCREF(arg4);
Py_INCREF(arg5);
PyTuple_SET_ITEM(t, 0, arg0);
PyTuple_SET_ITEM(t, 1, arg1);
PyTuple_SET_ITEM(t, 2, arg2);
PyTuple_SET_ITEM(t, 3, arg3);
PyTuple_SET_ITEM(t, 4, arg4);
PyTuple_SET_ITEM(t, 5, arg5);
r = PyObject_CallObject(function, t);
Py_DECREF(t);
return r;
}
static int
unpacktuple1(PyObject *args, char *name, int min, PyObject **a0)
{
int l;
l=PyTuple_Size(args);
if (l < 0) return -1;
if (l < min)
{
PyErr_Format(PyExc_TypeError, "expected %d arguments, got %d", min, l);
return -1;
}
if (l > 0) *a0=PyTuple_GET_ITEM(args, 0);
return 0;
}
static int
unpacktuple2(PyObject *args, char *name, int min,
PyObject **a0, PyObject **a1)
{
int l;
l=PyTuple_Size(args);
if (l < 0) return -1;
if (l < min)
{
PyErr_Format(PyExc_TypeError, "expected %d arguments, got %d", min, l);
return -1;
}
if (l > 0) *a0=PyTuple_GET_ITEM(args, 0);
if (l > 1) *a1=PyTuple_GET_ITEM(args, 1);
return 0;
}
static int
unpacktuple3(PyObject *args, char *name, int min,
PyObject **a0, PyObject **a1, PyObject **a2)
{
int l;
l=PyTuple_Size(args);
if (l < 0) return -1;
if (l < min)
{
PyErr_Format(PyExc_TypeError, "expected %d arguments, got %d", min, l);
return -1;
}
if (l > 0) *a0=PyTuple_GET_ITEM(args, 0);
if (l > 1) *a1=PyTuple_GET_ITEM(args, 1);
if (l > 2) *a2=PyTuple_GET_ITEM(args, 2);
return 0;
}
static int
unpacktuple5(PyObject *args, char *name, int min,
PyObject **a0, PyObject **a1, PyObject **a2,
PyObject **a3, PyObject **a4)
{
int l;
l=PyTuple_Size(args);
if (l < 0) return -1;
if (l < min)
{
PyErr_Format(PyExc_TypeError, "expected %d arguments, got %d", min, l);
return -1;
}
if (l > 0) *a0=PyTuple_GET_ITEM(args, 0);
if (l > 1) *a1=PyTuple_GET_ITEM(args, 1);
if (l > 2) *a2=PyTuple_GET_ITEM(args, 2);
if (l > 3) *a3=PyTuple_GET_ITEM(args, 3);
if (l > 4) *a4=PyTuple_GET_ITEM(args, 4);
return 0;
}
static int
unpacktuple6(PyObject *args, char *name, int min,
PyObject **a0, PyObject **a1, PyObject **a2,
PyObject **a3, PyObject **a4, PyObject **a5)
{
int l;
l=PyTuple_Size(args);
if (l < 0) return -1;
if (l < min)
{
PyErr_Format(PyExc_TypeError, "expected %d arguments, got %d", min, l);
return -1;
}
if (l > 0) *a0=PyTuple_GET_ITEM(args, 0);
if (l > 1) *a1=PyTuple_GET_ITEM(args, 1);
if (l > 2) *a2=PyTuple_GET_ITEM(args, 2);
if (l > 3) *a3=PyTuple_GET_ITEM(args, 3);
if (l > 4) *a4=PyTuple_GET_ITEM(args, 4);
if (l > 5) *a5=PyTuple_GET_ITEM(args, 5);
return 0;
}
/* /*
** Structures ** Structures
...@@ -106,6 +305,15 @@ typedef struct { ...@@ -106,6 +305,15 @@ typedef struct {
PyObject_HEAD PyObject_HEAD
} ZopeSecurityPolicy; } ZopeSecurityPolicy;
typedef struct {
PyObject_HEAD
PyObject *thread_id;
PyObject *context;
PyObject *policy;
PyObject *validate;
PyObject *checkPermission;
} SecurityManager;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
PyObject *__name__; PyObject *__name__;
...@@ -142,11 +350,26 @@ static PyObject *imPermissionRole_get(imPermissionRole *self, ...@@ -142,11 +350,26 @@ static PyObject *imPermissionRole_get(imPermissionRole *self,
static void imPermissionRole_dealloc(imPermissionRole *self); static void imPermissionRole_dealloc(imPermissionRole *self);
static PyObject *rolesForPermissionOn(PyObject *self, PyObject *args); static PyObject *rolesForPermissionOn(PyObject *self, PyObject *args);
static PyObject *module_guarded_getattr(PyObject *self, PyObject *args);
static PyObject *module_aq_validate(PyObject *self, PyObject *args);
static PyObject *c_rolesForPermissionOn(PyObject *self, PyObject *perm, static PyObject *c_rolesForPermissionOn(PyObject *self, PyObject *perm,
PyObject *object, PyObject *deflt); PyObject *object, PyObject *deflt);
static PyObject *permissionName(PyObject *name); static PyObject *permissionName(PyObject *name);
static PyObject *SecurityManager_validate(SecurityManager *self,
PyObject *args);
static PyObject *SecurityManager_validateValue(SecurityManager *self,
PyObject *args);
static PyObject *SecurityManager_DTMLValidate(SecurityManager *self,
PyObject *args);
static PyObject *SecurityManager_checkPermission(SecurityManager *self,
PyObject *args);
static void SecurityManager_dealloc(SecurityManager *self);
static PyObject *SecurityManager_getattro(SecurityManager *self,
PyObject *name);
static int SecurityManager_setattro(SecurityManager *self,
PyObject *name, PyObject *value);
/* /*
** Constants ** Constants
*/ */
...@@ -157,6 +380,16 @@ static PyMethodDef cAccessControl_methods[] = { ...@@ -157,6 +380,16 @@ static PyMethodDef cAccessControl_methods[] = {
METH_VARARGS, METH_VARARGS,
"" ""
}, },
{"guarded_getattr",
(PyCFunction)module_guarded_getattr,
METH_VARARGS,
""
},
{"aq_validate",
(PyCFunction)module_aq_validate,
METH_VARARGS,
""
},
{ NULL, NULL } { NULL, NULL }
}; };
...@@ -214,6 +447,70 @@ static PyExtensionClass ZopeSecurityPolicyType = { ...@@ -214,6 +447,70 @@ static PyExtensionClass ZopeSecurityPolicyType = {
}; };
static char SecurityManager__doc__[] = "ZopeSecurityPolicy C implementation";
static PyMethodDef SecurityManager_methods[] = {
{"validate",
(PyCFunction)SecurityManager_validate,
METH_VARARGS,
""
},
{"DTMLValidate",
(PyCFunction)SecurityManager_DTMLValidate,
METH_VARARGS,
""
},
{"validateValue",
(PyCFunction)SecurityManager_validateValue,
METH_VARARGS,
""
},
{"checkPermission",
(PyCFunction)SecurityManager_checkPermission,
METH_VARARGS,
""
},
{ NULL, NULL }
};
static PyExtensionClass SecurityManagerType = {
PyObject_HEAD_INIT(NULL) 0,
"SecurityManager", /* tp_name */
sizeof(SecurityManager), /* tp_basicsize */
0, /* tp_itemsize */
/* Standard methods */
(destructor) SecurityManager_dealloc,/* tp_dealloc */
NULL, /* tp_print */
NULL, /* tp_getattr */
NULL, /* tp_setattr */
NULL, /* tp_compare */
NULL, /* tp_repr */
/* Method suites */
NULL, /* tp_as_number */
NULL, /* tp_as_sequence*/
NULL, /* tp_as_mapping */
/* More standard ops */
NULL, /* tp_hash */
NULL, /* tp_call */
NULL, /* tp_str */
(getattrofunc)SecurityManager_getattro, /* tp_getattro */
(setattrofunc)SecurityManager_setattro, /* tp_setattro */
/* Reserved fields */
0, /* tp_xxx3 */
0, /* tp_xxx4 */
/* Docstring */
SecurityManager__doc__, /* tp_doc */
#ifdef COUNT_ALLOCS
0, /* tp_alloc */
0, /* tp_free */
0, /* tp_maxalloc */
NULL, /* tp_next */
#endif
METHOD_CHAIN(SecurityManager_methods), /* methods */
0, /* flags */
};
static char PermissionRole__doc__[] = "PermissionRole C implementation"; static char PermissionRole__doc__[] = "PermissionRole C implementation";
static PyMethodDef PermissionRole_methods[] = { static PyMethodDef PermissionRole_methods[] = {
...@@ -353,9 +650,15 @@ static PyObject *__of__ = NULL; ...@@ -353,9 +650,15 @@ static PyObject *__of__ = NULL;
static PyObject *__allow_access_to_unprotected_subobjects__ = NULL; static PyObject *__allow_access_to_unprotected_subobjects__ = NULL;
static PyObject *stack_str = NULL; static PyObject *stack_str = NULL;
static PyObject *user_str = NULL; static PyObject *user_str = NULL;
static PyObject *validate_str = NULL;
static PyObject *_proxy_roles_str = NULL; static PyObject *_proxy_roles_str = NULL;
static PyObject *allowed_str = NULL; static PyObject *allowed_str = NULL;
static PyObject *getOwner_str = NULL; static PyObject *getOwner_str = NULL;
static PyObject *checkPermission_str = NULL;
static PyObject *getSecurityManager = NULL;
static PyObject *aq_validate = NULL;
static int ownerous = 1;
static int authenticated = 1;
/* -------------------------------------------------------------- /* --------------------------------------------------------------
** ZopeSecurityPolicy Methods ** ZopeSecurityPolicy Methods
...@@ -383,14 +686,22 @@ ZopeSecurityPolicy_setup(void) { ...@@ -383,14 +686,22 @@ ZopeSecurityPolicy_setup(void) {
UNLESS (AnonymousTuple = Py_BuildValue("(s)", "Anonymous")) return -1; UNLESS (AnonymousTuple = Py_BuildValue("(s)", "Anonymous")) return -1;
UNLESS (stack_str = PyString_FromString("stack")) return -1; UNLESS (stack_str = PyString_FromString("stack")) return -1;
UNLESS (user_str = PyString_FromString("user")) return -1; UNLESS (user_str = PyString_FromString("user")) return -1;
UNLESS (validate_str = PyString_FromString("validate")) return -1;
UNLESS (_proxy_roles_str = PyString_FromString("_proxy_roles")) UNLESS (_proxy_roles_str = PyString_FromString("_proxy_roles"))
return -1; return -1;
UNLESS (allowed_str = PyString_FromString("allowed")) return -1; UNLESS (allowed_str = PyString_FromString("allowed")) return -1;
UNLESS (getOwner_str = PyString_FromString("getOwner")) return -1; UNLESS (getOwner_str = PyString_FromString("getOwner")) return -1;
UNLESS (checkPermission_str = PyString_FromString("checkPermission"))
return -1;
UNLESS (__allow_access_to_unprotected_subobjects__ = UNLESS (__allow_access_to_unprotected_subobjects__ =
PyString_FromString( PyString_FromString(
"__allow_access_to_unprotected_subobjects__")) "__allow_access_to_unprotected_subobjects__"))
return -1; return -1;
if (getenv("ZSP_OWNEROUS_SKIP") != NULL) ownerous = 0;
if (getenv("ZSP_AUTHENTICATED_SKIP") != NULL) authenticated = 0;
return 0; return 0;
} }
...@@ -438,8 +749,9 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -438,8 +749,9 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
**| roles=_noroles ... **| roles=_noroles ...
*/ */
if (!PyArg_ParseTuple(args, "OOOOO|O", &accessed, &container, if (unpacktuple6(args, "validate", 5, &accessed, &container,
&name, &value, &context, &roles)) return NULL; &name, &value, &context, &roles) < 0)
return NULL;
/*| # Provide special rules for acquisition attributes /*| # Provide special rules for acquisition attributes
**| if type(name) is StringType: **| if type(name) is StringType:
...@@ -704,6 +1016,8 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -704,6 +1016,8 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
eo = PySequence_GetItem(stack, -1); eo = PySequence_GetItem(stack, -1);
if (eo == NULL) goto err; if (eo == NULL) goto err;
if (ownerous) { /* Tabbing not adjusted for diff reasons*/
owner = PyObject_GetAttr(eo, getOwner_str); owner = PyObject_GetAttr(eo, getOwner_str);
if (owner) ASSIGN(owner, PyObject_CallObject(owner, NULL)); if (owner) ASSIGN(owner, PyObject_CallObject(owner, NULL));
if (owner ==NULL) if (owner ==NULL)
...@@ -735,6 +1049,8 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -735,6 +1049,8 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
} }
Py_DECREF(owner); Py_DECREF(owner);
} /* End of if ownerous */
/*| # Proxy roles, which are a lot safer now /*| # Proxy roles, which are a lot safer now
**| proxy_roles = getattr(eo, "_proxy_roles", None) **| proxy_roles = getattr(eo, "_proxy_roles", None)
**| if proxy_roles: **| if proxy_roles:
...@@ -805,6 +1121,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -805,6 +1121,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
**| if context.user.allowed(value, roles): return 1 **| if context.user.allowed(value, roles): return 1
**| except AttributeError: pass **| except AttributeError: pass
*/ */
if (authenticated) { /* Authentication skip for public only access */
user = PyObject_GetAttr(context, user_str); user = PyObject_GetAttr(context, user_str);
if (user) ASSIGN(user, PyObject_GetAttr(user, allowed_str)); if (user) ASSIGN(user, PyObject_GetAttr(user, allowed_str));
if (user == NULL) if (user == NULL)
...@@ -826,6 +1143,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -826,6 +1143,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
} }
Py_DECREF(user); Py_DECREF(user);
} }
} /* End of authentiction skip for public only access */
/*| # we don't want someone to acquire if they can't get an /*| # we don't want someone to acquire if they can't get an
**| # unacquired! **| # unacquired!
...@@ -869,7 +1187,8 @@ static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self, ...@@ -869,7 +1187,8 @@ static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self,
/*| def checkPermission(self, permission, object, context) /*| def checkPermission(self, permission, object, context)
*/ */
if (!PyArg_ParseTuple(args, "OOO", &permission, &object, &context)) if (unpacktuple3(args, "checkPermission", 3,
&permission, &object, &context) < 0)
return NULL; return NULL;
/*| roles = rolesForPermissionOn(permission, object) /*| roles = rolesForPermissionOn(permission, object)
...@@ -921,10 +1240,180 @@ static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self, ...@@ -921,10 +1240,180 @@ static PyObject *ZopeSecurityPolicy_checkPermission(PyObject *self,
static void ZopeSecurityPolicy_dealloc(ZopeSecurityPolicy *self) { static void ZopeSecurityPolicy_dealloc(ZopeSecurityPolicy *self) {
Py_DECREF(self->ob_type); /* Extensionclass init incref'd */ Py_DECREF(self->ob_type); /* Extensionclass init incref'd */
PyMem_DEL(self);
}
/* SecurityManager */
#define CHECK_SECURITY_MANAGER_STATE(self, R) \
UNLESS (self->policy) { \
PyErr_SetString(PyExc_AttributeError, "_policy"); return R; } \
UNLESS (self->context) { \
PyErr_SetString(PyExc_AttributeError, "_policy"); return R; }
#define GET_SECURITY_MANAGER_VALIDATE(self, R) \
if (self->validate == NULL && \
((self->validate = PyObject_GetAttr(self->policy, validate_str)) \
== NULL)) return R;
static PyObject *
SecurityManager_validate(SecurityManager *self, PyObject *args)
{
PyObject *accessed=Py_None, *container=Py_None, *name=Py_None,
*value=Py_None, *roles=NULL;
if (unpacktuple5(args, "validate", 0,
&accessed, &container, &name, &value, &roles) < 0)
return NULL;
CHECK_SECURITY_MANAGER_STATE(self, NULL);
GET_SECURITY_MANAGER_VALIDATE(self, NULL);
if (roles== NULL)
return callfunction5(self->validate,
accessed, container, name, value, self->context);
return callfunction6(self->validate,
accessed, container, name, value, self->context, roles);
}
static PyObject *
SecurityManager_validateValue(SecurityManager *self, PyObject *args)
{
PyObject *value=Py_None, *roles=NULL;
if (unpacktuple2(args, "validateValue", 1, &value, &roles) < 0) return NULL;
CHECK_SECURITY_MANAGER_STATE(self, NULL);
GET_SECURITY_MANAGER_VALIDATE(self, NULL);
if (roles==NULL)
return callfunction5(self->validate,
Py_None, Py_None, Py_None, value, self->context);
return callfunction6(self->validate,
Py_None, Py_None, Py_None, value, self->context, roles);
}
static PyObject *
SecurityManager_DTMLValidate(SecurityManager *self, PyObject *args)
{
PyObject *accessed=Py_None, *container=Py_None, *name=Py_None,
*value=Py_None, *md=NULL;
if (unpacktuple5(args, "DTMLValidate", 0,
&accessed, &container, &name, &value, &md) < 0)
return NULL;
CHECK_SECURITY_MANAGER_STATE(self, NULL);
GET_SECURITY_MANAGER_VALIDATE(self, NULL);
return callfunction5(self->validate,
accessed, container, name, value, self->context);
}
static PyObject *
SecurityManager_checkPermission(SecurityManager *self, PyObject *args)
{
PyObject *permission, *object;
if (unpacktuple2(args, "checkPermission", 2, &permission, &object) < 0)
return NULL;
CHECK_SECURITY_MANAGER_STATE(self, NULL);
if (self->checkPermission == NULL &&
((self->checkPermission = PyObject_GetAttr(self->policy,
checkPermission_str))
== NULL)) return NULL;
return callfunction3(self->checkPermission,
permission, object, self->context);
}
static void
SecurityManager_dealloc(SecurityManager *self)
{
Py_XDECREF(self->thread_id);
Py_XDECREF(self->context);
Py_XDECREF(self->policy);
Py_XDECREF(self->validate);
Py_XDECREF(self->checkPermission);
Py_DECREF(self->ob_type); /* Extensionclass init incref'd */
PyMem_DEL(self); PyMem_DEL(self);
} }
static PyObject *
SecurityManager_getattro(SecurityManager *self, PyObject *name)
{
if (PyString_Check(name) && PyString_AS_STRING(name)[0]=='_')
{
if (strcmp(PyString_AS_STRING(name), "_thread_id")==0
&& self->thread_id)
{
Py_INCREF(self->thread_id);
return self->thread_id;
}
else if (strcmp(PyString_AS_STRING(name), "_context")==0
&& self->context)
{
Py_INCREF(self->context);
return self->context;
}
else if (strcmp(PyString_AS_STRING(name), "_policy")==0
&& self->policy)
{
Py_INCREF(self->policy);
return self->policy;
}
}
return Py_FindAttr(OBJECT(self), name);
}
static int
SecurityManager_setattro(SecurityManager *self, PyObject *name, PyObject *v)
{
if (v && PyString_Check(name) && PyString_AS_STRING(name)[0]=='_')
{
if (strcmp(PyString_AS_STRING(name), "_thread_id")==0)
{
Py_INCREF(v);
ASSIGN(self->thread_id, v);
return 0;
}
else if (strcmp(PyString_AS_STRING(name), "_context")==0)
{
Py_INCREF(v);
ASSIGN(self->context, v);
return 0;
}
else if (strcmp(PyString_AS_STRING(name), "_policy")==0)
{
Py_INCREF(v);
ASSIGN(self->policy, v);
if (self->validate)
{
Py_DECREF(self->validate);
self->validate=0;
}
if (self->checkPermission)
{
Py_DECREF(self->checkPermission);
self->checkPermission=0;
}
return 0;
}
}
PyErr_SetObject(PyExc_AttributeError, name);
return -1;
}
/* /*
** PermissionRole_init ** PermissionRole_init
** **
...@@ -941,7 +1430,7 @@ static PyObject *PermissionRole_init(PermissionRole *self, PyObject *args) { ...@@ -941,7 +1430,7 @@ static PyObject *PermissionRole_init(PermissionRole *self, PyObject *args) {
**| self._d = default **| self._d = default
*/ */
if (!PyArg_ParseTuple(args, "O|O", &name, &deflt)) return NULL; if (unpacktuple2(args, "__init__", 1, &name, &deflt) < 0) return NULL;
if (deflt == NULL) deflt = defaultPermission; if (deflt == NULL) deflt = defaultPermission;
...@@ -972,7 +1461,7 @@ static PyObject *PermissionRole_of(PermissionRole *self, PyObject *args) { ...@@ -972,7 +1461,7 @@ static PyObject *PermissionRole_of(PermissionRole *self, PyObject *args) {
/*|def __of__(self, parent): /*|def __of__(self, parent):
*/ */
if (!PyArg_ParseTuple(args,"O", &parent)) return NULL; if (unpacktuple1(args,"__of__", 1, &parent) < 0) return NULL;
/*| r = imPermissionRole() /*| r = imPermissionRole()
*/ */
...@@ -1061,7 +1550,7 @@ static PyObject *imPermissionRole_of(imPermissionRole *self, PyObject *args) { ...@@ -1061,7 +1550,7 @@ static PyObject *imPermissionRole_of(imPermissionRole *self, PyObject *args) {
**| r = None **| r = None
*/ */
if (!PyArg_ParseTuple(args, "O", &parent)) return NULL; if (unpacktuple1(args, "__of__", 1, &parent) < 0) return NULL;
obj = parent; obj = parent;
Py_INCREF(obj); Py_INCREF(obj);
...@@ -1345,7 +1834,8 @@ static PyObject *rolesForPermissionOn(PyObject *self, PyObject *args) { ...@@ -1345,7 +1834,8 @@ static PyObject *rolesForPermissionOn(PyObject *self, PyObject *args) {
**| """Return the roles that have the permisson on the given object""" **| """Return the roles that have the permisson on the given object"""
*/ */
if (!PyArg_ParseTuple(args, "OO|O", &perm, &object, &deflt)) if (unpacktuple3(args, "rolesForPermissionOn", 2,
&perm, &object, &deflt) < 0)
return NULL; return NULL;
return c_rolesForPermissionOn(self, perm, object, deflt); return c_rolesForPermissionOn(self, perm, object, deflt);
} }
...@@ -1428,6 +1918,153 @@ static PyObject *permissionName(PyObject *name) { ...@@ -1428,6 +1918,153 @@ static PyObject *permissionName(PyObject *name) {
} }
/* def guarded_getattr(inst, name, default=_marker): */
static PyObject *
guarded_getattr(PyObject *inst, PyObject *name, PyObject *default_,
PyObject *validate)
{
PyObject *v=0, *t=0;
int i;
/* if name[:1] != '_': */
if (PyString_Check(name) && PyString_AS_STRING(name)[0] != '_')
{
/*
# Try to get the attribute normally so that unusual
# exceptions are caught early.
try: v = getattr(inst, name)
except AttributeError:
if default is not _marker:
return default
raise
*/
v=PyObject_GetAttr(inst, name);
if (v==NULL)
{
if (default_ && PyErr_Occurred() == PyExc_AttributeError)
{
PyErr_Clear();
Py_INCREF(default_);
return default_;
}
return NULL;
}
/*
if Containers(type(inst)):
# Simple type. Short circuit.
return v
*/
t=callfunction1(Containers, OBJECT(inst->ob_type));
if (t==NULL) goto err;
i=PyObject_IsTrue(t);
if (i < 0) goto err;
Py_DECREF(t);
if (i) return v;
/*
# Filter out the objects we can't access.
if hasattr(inst, 'aq_acquire'):
return inst.aq_acquire(name, aq_validate, validate)
*/
if (aq_isWrapper(inst))
{
ASSIGN(v, aq_Acquire(inst, name, aq_validate, validate, 1, NULL, 0));
return v;
}
/*
# Or just try to get the attribute directly.
if validate(inst, inst, name, v):
return v
*/
validate=callfunction4(validate, inst, inst, name, v);
if (validate==NULL) goto err;
i=PyObject_IsTrue(validate);
Py_DECREF(validate);
if (i < 0) goto err;
if (i > 0) return v;
unauthErr(name, v);
err:
Py_DECREF(v);
return NULL;
}
/* raise Unauthorized, name */
PyErr_SetObject(Unauthorized, name);
return NULL;
}
static PyObject *
module_guarded_getattr(PyObject *ignored, PyObject *args)
{
PyObject *inst, *name, *default_=0, *validate;
if (unpacktuple3(args, "guarded_getattr", 2, &inst, &name, &default_) < 0)
return NULL;
/*
validate = getSecurityManager().validate
*/
validate=PyObject_CallObject(getSecurityManager, NULL);
if (! validate) return NULL;
ASSIGN(validate, PyObject_GetAttr(validate, validate_str));
if (! validate) return NULL;
ASSIGN(validate, guarded_getattr(inst, name, default_, validate));
return validate;
}
/*
def aq_validate(inst, obj, name, v, validate):
return validate(inst, obj, name, v)
*/
static PyObject *
module_aq_validate(PyObject *ignored, PyObject *args)
{
PyObject *inst, *obj, *name, *v, *validate;
if (unpacktuple5(args, "validate", 0,
&inst, &obj, &name, &v, &validate) < 0) return NULL;
return callfunction4(validate, inst, obj, name, v);
}
static PyObject *
dtml_guarded_getattr(PyObject *self, PyObject *args)
{
PyObject *ob, *name, *default_=0, *validate;
if (unpacktuple3(args, "guarded_getattr", 2, &ob, &name, &default_) < 0)
return NULL;
UNLESS (validate = PyObject_GetAttr(self, validate_str))
{
/* This section is pure paranoia at this point. It was necessary
while debugging. */
PyErr_Clear();
validate=PyObject_CallObject(getSecurityManager, NULL);
if (! validate) return NULL;
ASSIGN(validate, PyObject_GetAttr(validate, validate_str));
if (! validate) return NULL;
}
ASSIGN(validate, guarded_getattr(ob, name, default_, validate));
return validate;
}
static struct PyMethodDef dtml_methods[] = {
{"guarded_getattr", (PyCFunction)dtml_guarded_getattr,
METH_VARARGS|METH_KEYWORDS, "" },
{NULL, NULL}
};
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
** Module initialization ** Module initialization
** ---------------------------------------------------------------- ** ----------------------------------------------------------------
...@@ -1438,7 +2075,11 @@ static PyObject *permissionName(PyObject *name) { ...@@ -1438,7 +2075,11 @@ static PyObject *permissionName(PyObject *name) {
void initcAccessControl(void) { void initcAccessControl(void) {
PyObject *module; PyObject *module;
PyObject *dict; PyObject *dict;
char *rev = "$Revision: 1.11 $"; char *rev = "$Revision: 1.12 $";
PURE_MIXIN_CLASS(RestrictedDTMLMixin,
"A mix-in for derivatives of DT_String.String "
"that adds Zope security."
, dtml_methods);
if (!ExtensionClassImported) return; if (!ExtensionClassImported) return;
...@@ -1455,41 +2096,38 @@ void initcAccessControl(void) { ...@@ -1455,41 +2096,38 @@ void initcAccessControl(void) {
module = Py_InitModule3("cAccessControl", module = Py_InitModule3("cAccessControl",
cAccessControl_methods, cAccessControl_methods,
"$Id: cAccessControl.c,v 1.11 2001/10/19 15:12:25 shane Exp $\n"); "$Id: cAccessControl.c,v 1.12 2001/10/26 16:07:50 matt Exp $\n");
aq_init(); /* For Python <= 2.1.1, aq_init() should be after aq_init(); /* For Python <= 2.1.1, aq_init() should be after
Py_InitModule(). */ Py_InitModule(). */
dict = PyModule_GetDict(module); dict = PyModule_GetDict(module);
ZopeSecurityPolicyType.ob_type = &PyType_Type;
PyDict_SetItemString(dict, "ZopeSecurityPolicyType",
OBJECT(&ZopeSecurityPolicyType));
PermissionRoleType.ob_type = &PyType_Type;
PyDict_SetItemString(dict, "PermissionRoleType",
OBJECT(&PermissionRoleType));
imPermissionRoleType.ob_type = &PyType_Type;
PyDict_SetItemString(dict, "imPermissionRoleType",
OBJECT(&imPermissionRoleType));
PyDict_SetItemString(dict, "__version__", PyDict_SetItemString(dict, "__version__",
PyString_FromStringAndSize(rev+11,strlen(rev+11)-2)); PyString_FromStringAndSize(rev+11,strlen(rev+11)-2));
PyDict_SetItemString(dict, "_what_not_even_god_should_do", PyDict_SetItemString(dict, "_what_not_even_god_should_do",
_what_not_even_god_should_do); _what_not_even_god_should_do);
PyExtensionClass_Export(dict, "RestrictedDTMLMixin",
RestrictedDTMLMixinType);
PyExtensionClass_Export(dict, "ZopeSecurityPolicy", PyExtensionClass_Export(dict, "ZopeSecurityPolicy",
ZopeSecurityPolicyType); ZopeSecurityPolicyType);
PyExtensionClass_Export(dict,"SecurityManager",
SecurityManagerType);
PyExtensionClass_Export(dict, "PermissionRole", PyExtensionClass_Export(dict, "PermissionRole",
PermissionRoleType); PermissionRoleType);
PyExtensionClass_Export(dict, "imPermissionRole", PyExtensionClass_Export(dict, "imPermissionRole",
imPermissionRoleType); imPermissionRoleType);
imPermissionRoleObj = PyDict_GetItemString(dict, "imPermissionRole"); imPermissionRoleObj = PyMapping_GetItemString(dict,
"imPermissionRole");
aq_validate = PyMapping_GetItemString(dict, "aq_validate");
/*| from SimpleObjectPolicies import Containers /*| from SimpleObjectPolicies import Containers
*/ */
...@@ -1507,6 +2145,14 @@ void initcAccessControl(void) { ...@@ -1507,6 +2145,14 @@ void initcAccessControl(void) {
Py_DECREF(module); Py_DECREF(module);
module = NULL; module = NULL;
/*| from AccessControl.SecurityManagement import getSecurityManager
*/
IMPORT(module, "AccessControl.SecurityManagement");
GETATTR(module, getSecurityManager);
Py_DECREF(module);
module = NULL;
/*| from zLOG import LOG, PROBLEM /*| from zLOG import LOG, PROBLEM
*/ */
......
...@@ -147,8 +147,8 @@ __doc__='''Conditional insertion ...@@ -147,8 +147,8 @@ __doc__='''Conditional insertion
variable is not reevaluated. variable is not reevaluated.
''' '''
__rcs_id__='$Id: DT_If.py,v 1.16 1999/03/10 00:15:07 klm Exp $' __rcs_id__='$Id: DT_If.py,v 1.17 2001/10/26 16:07:50 matt Exp $'
__version__='$Revision: 1.16 $'[11:-2] __version__='$Revision: 1.17 $'[11:-2]
from DT_Util import ParseError, parse_params, name_param, str from DT_Util import ParseError, parse_params, name_param, str
...@@ -192,7 +192,7 @@ class If: ...@@ -192,7 +192,7 @@ class If:
if elses is not None: sections.append(elses) if elses is not None: sections.append(elses)
self.simple_form=tuple(sections) self.simple_form=('i',)+tuple(sections)
class Unless: class Unless:
name='unless' name='unless'
...@@ -204,7 +204,7 @@ class Unless: ...@@ -204,7 +204,7 @@ class Unless:
name,expr=name_param(args,'unless',1) name,expr=name_param(args,'unless',1)
if expr is None: cond=name if expr is None: cond=name
else: cond=expr.eval else: cond=expr.eval
self.simple_form=(cond,None,section.blocks) self.simple_form=('i',cond,None,section.blocks)
class Else(Unless): class Else(Unless):
# The else tag is included for backward compatibility and is deprecated. # The else tag is included for backward compatibility and is deprecated.
......
...@@ -217,8 +217,8 @@ Evaluating expressions without rendering results ...@@ -217,8 +217,8 @@ Evaluating expressions without rendering results
''' # ' ''' # '
__rcs_id__='$Id: DT_Var.py,v 1.44 2001/10/02 14:23:32 shane Exp $' __rcs_id__='$Id: DT_Var.py,v 1.45 2001/10/26 16:07:50 matt Exp $'
__version__='$Revision: 1.44 $'[11:-2] __version__='$Revision: 1.45 $'[11:-2]
from DT_Util import parse_params, name_param, str from DT_Util import parse_params, name_param, str
import re, string, sys import re, string, sys
...@@ -254,7 +254,11 @@ class Var: ...@@ -254,7 +254,11 @@ class Var:
if len(args)==1 and fmt=='s': if len(args)==1 and fmt=='s':
if expr is None: expr=name if expr is None: expr=name
else: expr=expr.eval else: expr=expr.eval
self.simple_form=expr, self.simple_form=('v', expr)
elif len(args)==2 and fmt=='s' and args.has_key('html_quote'):
if expr is None: expr=name
else: expr=expr.eval
self.simple_form=('v', expr, 'h')
def render(self, md): def render(self, md):
args=self.args args=self.args
...@@ -353,7 +357,7 @@ class Call: ...@@ -353,7 +357,7 @@ class Call:
name, expr = name_param(args,'call',1) name, expr = name_param(args,'call',1)
if expr is None: expr=name if expr is None: expr=name
else: expr=expr.eval else: expr=expr.eval
self.simple_form=expr,None self.simple_form=('i', expr, None)
def url_quote(v, name='(Unknown name)', md={}): def url_quote(v, name='(Unknown name)', md={}):
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
****************************************************************************/ ****************************************************************************/
static char cDocumentTemplate_module_documentation[] = static char cDocumentTemplate_module_documentation[] =
"" ""
"\n$Id: cDocumentTemplate.c,v 1.39 2001/06/21 19:08:59 shane Exp $" "\n$Id: cDocumentTemplate.c,v 1.40 2001/10/26 16:07:50 matt Exp $"
; ;
#include "ExtensionClass.h" #include "ExtensionClass.h"
...@@ -94,7 +94,7 @@ static PyObject *py___call__, *py___roles__, *py_AUTHENTICATED_USER; ...@@ -94,7 +94,7 @@ static PyObject *py___call__, *py___roles__, *py_AUTHENTICATED_USER;
static PyObject *py_hasRole, *py__proxy_roles, *py_Unauthorized; static PyObject *py_hasRole, *py__proxy_roles, *py_Unauthorized;
static PyObject *py_Unauthorized_fmt, *py_guarded_getattr; static PyObject *py_Unauthorized_fmt, *py_guarded_getattr;
static PyObject *py__push, *py__pop, *py_aq_base, *py_renderNS; static PyObject *py__push, *py__pop, *py_aq_base, *py_renderNS;
static PyObject *py___class__; static PyObject *py___class__, *html_quote;
/* ----------------------------------------------------- */ /* ----------------------------------------------------- */
...@@ -398,13 +398,29 @@ static PyObject * ...@@ -398,13 +398,29 @@ static PyObject *
MM_cget(MM *self, PyObject *key, int call) MM_cget(MM *self, PyObject *key, int call)
{ {
long i; long i;
PyObject *e, *rr, *tb; PyObject *e, *rr;
UNLESS(-1 != (i=PyList_Size(self->data))) return NULL; UNLESS(-1 != (i=PyList_Size(self->data))) return NULL;
while (--i >= 0) while (--i >= 0)
{ {
e=PyList_GetItem(self->data,i); e=PyList_GET_ITEM(self->data,i);
if ((e=PyObject_GetItem(e,key))) if (PyDict_Check(e))
{
e=PyDict_GetItem(e, key);
Py_XINCREF(e);
}
else
{
UNLESS (e=PyObject_GetItem(e,key))
{
if (PyErr_Occurred() == PyExc_KeyError)
PyErr_Clear();
else
return NULL;
}
}
if (e)
{ {
if (!call) return e; if (!call) return e;
...@@ -437,17 +453,8 @@ MM_cget(MM *self, PyObject *key, int call) ...@@ -437,17 +453,8 @@ MM_cget(MM *self, PyObject *key, int call)
} }
return e; return e;
} }
PyErr_Fetch(&e, &rr, &tb);
if (e != PyExc_KeyError)
{
PyErr_Restore(e,rr,tb);
return NULL;
}
Py_XDECREF(e);
Py_XDECREF(rr);
Py_XDECREF(tb);
} }
PyErr_SetObject(PyExc_KeyError,key); PyErr_SetObject(PyExc_KeyError, key);
return NULL; return NULL;
} }
...@@ -726,7 +733,7 @@ static int ...@@ -726,7 +733,7 @@ static int
render_blocks_(PyObject *blocks, PyObject *rendered, render_blocks_(PyObject *blocks, PyObject *rendered,
PyObject *md, PyObject *mda) PyObject *md, PyObject *mda)
{ {
PyObject *block; PyObject *block, *t;
int l, i, k=0, append; int l, i, k=0, append;
if ((l=PyList_Size(blocks)) < 0) return -1; if ((l=PyList_Size(blocks)) < 0) return -1;
...@@ -735,27 +742,48 @@ render_blocks_(PyObject *blocks, PyObject *rendered, ...@@ -735,27 +742,48 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
block=PyList_GET_ITEM(((PyListObject*)blocks), i); block=PyList_GET_ITEM(((PyListObject*)blocks), i);
append=1; append=1;
if (PyTuple_Check(block)) if (PyTuple_Check(block)
&& PyTuple_GET_SIZE(block) > 1
&& PyTuple_GET_ITEM(block, 0)
&& PyString_Check(PyTuple_GET_ITEM(block, 0)))
{
switch (PyString_AS_STRING(PyTuple_GET_ITEM(block, 0))[0])
{ {
int bs; case 'v': /* var */
t=PyTuple_GET_ITEM(block,1);
bs=((PyTupleObject*)block)->ob_size; if (t == NULL) return -1;
if (bs==1) if (PyString_Check(t)) t=PyObject_GetItem(md, t);
else t=PyObject_CallObject(t, mda);
if (t == NULL || (! PyString_Check(t)))
{ {
/* Simple var */ if (t) ASSIGN(t, PyObject_Str(t));
block=PyTuple_GET_ITEM(block,0); UNLESS(t) return -1;
if (PyString_Check(block)) block=PyObject_GetItem(md,block);
else block=PyObject_CallObject(block,mda);
if (block) ASSIGN(block, PyObject_Str(block));
UNLESS(block) return -1;
} }
else
if (PyString_Check(t)
&& PyTuple_GET_SIZE(block) == 3) /* html_quote */
{
if (strchr(PyString_AS_STRING(t), '&')
&& strchr(PyString_AS_STRING(t), '<')
&& strchr(PyString_AS_STRING(t), '>')
&& strchr(PyString_AS_STRING(t), '"')
)
ASSIGN(t, PyObject_CallFunction(html_quote, "O", t));
if (t == NULL) return -1;
}
block = t;
break;
case 'i': /* if */
{ {
/* if */ int icond, m, bs;
int icond, m;
PyObject *cond, *n, *cache; PyObject *cond, *n, *cache;
bs = PyTuple_GET_SIZE(block) - 1; /* subtract code */
UNLESS(cache=PyDict_New()) return -1; UNLESS(cache=PyDict_New()) return -1;
cond=PyObject_GetAttr(md,py__push); cond=PyObject_GetAttr(md,py__push);
if (cond) ASSIGN(cond, PyObject_CallFunction(cond,"O",cache)); if (cond) ASSIGN(cond, PyObject_CallFunction(cond,"O",cache));
...@@ -767,7 +795,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered, ...@@ -767,7 +795,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
m=bs-1; m=bs-1;
for (icond=0; icond < m; icond += 2) for (icond=0; icond < m; icond += 2)
{ {
cond=PyTuple_GET_ITEM(block,icond); cond=PyTuple_GET_ITEM(block,icond+1);
if (PyString_Check(cond)) if (PyString_Check(cond))
{ {
/* We have to be careful to handle key errors here */ /* We have to be careful to handle key errors here */
...@@ -804,7 +832,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered, ...@@ -804,7 +832,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
if (PyObject_IsTrue(cond)) if (PyObject_IsTrue(cond))
{ {
Py_DECREF(cond); Py_DECREF(cond);
block=PyTuple_GET_ITEM(block,icond+1); block=PyTuple_GET_ITEM(block,icond+1+1);
if (block!=Py_None && if (block!=Py_None &&
render_blocks_(block, rendered, md, mda) < 0) render_blocks_(block, rendered, md, mda) < 0)
return if_finally(md,1); return if_finally(md,1);
...@@ -815,7 +843,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered, ...@@ -815,7 +843,7 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
} }
if (icond==m) if (icond==m)
{ {
block=PyTuple_GET_ITEM(block,icond); block=PyTuple_GET_ITEM(block,icond+1);
if (block!=Py_None && if (block!=Py_None &&
render_blocks_(block, rendered, md, mda) < 0) render_blocks_(block, rendered, md, mda) < 0)
return if_finally(md,1); return if_finally(md,1);
...@@ -823,6 +851,13 @@ render_blocks_(PyObject *blocks, PyObject *rendered, ...@@ -823,6 +851,13 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
if (if_finally(md,0) == -2) return -1; if (if_finally(md,0) == -2) return -1;
} }
break;
default:
PyErr_Format(PyExc_ValueError,
"Invalid DTML command code, %s",
PyString_AS_STRING(PyTuple_GET_ITEM(block, 0)));
return -1;
}
} }
else if (PyString_Check(block)) else if (PyString_Check(block))
{ {
...@@ -904,10 +939,14 @@ void ...@@ -904,10 +939,14 @@ void
initcDocumentTemplate(void) initcDocumentTemplate(void)
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.39 $"; char *rev="$Revision: 1.40 $";
DictInstanceType.ob_type=&PyType_Type; DictInstanceType.ob_type=&PyType_Type;
UNLESS (html_quote = PyImport_ImportModule("html_quote")) return;
ASSIGN(html_quote, PyObject_GetAttrString(html_quote, "html_quote"));
UNLESS (html_quote) return;
UNLESS(py_isDocTemp=PyString_FromString("isDocTemp")) return; UNLESS(py_isDocTemp=PyString_FromString("isDocTemp")) return;
UNLESS(py_renderNS=PyString_FromString("__render_with_namespace__")) return; UNLESS(py_renderNS=PyString_FromString("__render_with_namespace__")) return;
UNLESS(py_blocks=PyString_FromString("blocks")) return; UNLESS(py_blocks=PyString_FromString("blocks")) return;
...@@ -946,6 +985,4 @@ initcDocumentTemplate(void) ...@@ -946,6 +985,4 @@ initcDocumentTemplate(void)
PyDict_SetItemString(d, "__version__", PyDict_SetItemString(d, "__version__",
PyString_FromStringAndSize(rev+11,strlen(rev+11)-2)); PyString_FromStringAndSize(rev+11,strlen(rev+11)-2));
if (PyErr_Occurred())
Py_FatalError("can't initialize module cDocumentTemplate");
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment