Commit 89b1075e authored by Shane Hathaway's avatar Shane Hathaway

- Merged cAccessControl-review-branch.

- Made some corrections to the DTML tests, which aren't currently working
in testrunner but work when run directly. ??
parent 9f506076
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,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: Acquisition.h,v 1.1 2001/07/03 19:38:20 matt Exp $ $Id: Acquisition.h,v 1.2 2001/10/19 15:12:24 shane Exp $
If you have questions regarding this software, If you have questions regarding this software,
contact: contact:
...@@ -79,10 +79,8 @@ static ACQUISITIONCAPI *AcquisitionCAPI = NULL; ...@@ -79,10 +79,8 @@ static ACQUISITIONCAPI *AcquisitionCAPI = NULL;
#define aq_init() { \ #define aq_init() { \
PyObject *module; \ PyObject *module; \
PyObject *api; \ PyObject *api; \
if ((module = PyImport_ImportModule("Acquisition")) == NULL) \ if (! (module = PyImport_ImportModule("Acquisition"))) return; \
Py_FatalError("Acquisition CAPI failed to load Acquisition"); \ if (! (api = PyObject_GetAttrString(module,"AcquisitionCAPI"))) return; \
if ((api = PyObject_GetAttrString(module,"AcquisitionCAPI")) \
== NULL) Py_FatalError("Acquisition CAPI failed to load AcquistionCAPI"); \
Py_DECREF(module); \ Py_DECREF(module); \
AcquisitionCAPI = PyCObject_AsVoidPtr(api); \ AcquisitionCAPI = PyCObject_AsVoidPtr(api); \
Py_DECREF(api); \ Py_DECREF(api); \
......
...@@ -85,19 +85,139 @@ ...@@ -85,19 +85,139 @@
__doc__='''Objects that implement Permission-based roles. __doc__='''Objects that implement Permission-based roles.
$Id: PermissionRole.py,v 1.11 2001/10/17 22:01:43 tseaver Exp $''' $Id: PermissionRole.py,v 1.12 2001/10/19 15:12:25 shane Exp $'''
__version__='$Revision: 1.11 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
if 0: # cAccessControl is not working _use_python_impl = 0
import cAccessControl import os
rolesForPermissionOn=cAccessControl.rolesForPermissionOn if os.environ.get("ZOPE_SECURITY_POLICY", None) == "PYTHON":
PermissionRole=cAccessControl.PermissionRole _use_python_impl = 1
imPermissionRole=cAccessControl.imPermissionRole
_what_not_even_god_should_do= cAccessControl._what_not_even_god_should_do
else: else:
import pPermissionRole try:
from pPermissionRole import rolesForPermissionOn, PermissionRole # C Optimization:
from pPermissionRole import imPermissionRole, _what_not_even_god_should_do from cAccessControl import rolesForPermissionOn, \
PermissionRole, imPermissionRole, _what_not_even_god_should_do
except ImportError:
# Fall back to Python implementation.
_use_python_impl = 1
if _use_python_impl:
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)
############################################################################## ##############################################################################
# Test functions: # Test functions:
......
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''short description __doc__='''short description
$Id: SecurityManager.py,v 1.6 2001/10/01 21:03:15 matt Exp $''' $Id: SecurityManager.py,v 1.7 2001/10/19 15:12:25 shane Exp $'''
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
import ZopeSecurityPolicy, os, string import ZopeSecurityPolicy, os, string
...@@ -145,6 +145,10 @@ class SecurityManager: ...@@ -145,6 +145,10 @@ class SecurityManager:
""" """
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy if policy is None: policy=_defaultPolicy
if roles is _noroles:
return policy.validate(accessed, container, name, value,
self._context)
else:
return policy.validate(accessed, container, name, value, return policy.validate(accessed, container, name, value,
self._context, roles) self._context, roles)
...@@ -175,13 +179,17 @@ class SecurityManager: ...@@ -175,13 +179,17 @@ class SecurityManager:
policy=self._policy policy=self._policy
if policy is None: policy=_defaultPolicy if policy is None: policy=_defaultPolicy
return policy.validate(accessed, container, name, value, return policy.validate(accessed, container, name, value,
self._context, _noroles) self._context)
def validateValue(self, value, roles=_noroles): def validateValue(self, value, roles=_noroles):
"""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 policy is None: policy=_defaultPolicy
if roles is _noroles:
return policy.validate(None, None, None, value,
self._context)
else:
return policy.validate(None, None, None, value, return policy.validate(None, None, None, value,
self._context, roles) self._context, roles)
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
############################################################################## ##############################################################################
"""Access control package""" """Access control package"""
__version__='$Revision: 1.159 $'[11:-2] __version__='$Revision: 1.160 $'[11:-2]
import Globals, socket, SpecialUsers,re import Globals, socket, SpecialUsers,re
import os import os
...@@ -98,7 +98,8 @@ from App.ImageFile import ImageFile ...@@ -98,7 +98,8 @@ from App.ImageFile import ImageFile
from Role import RoleManager, DEFAULTMAXLISTUSERS from Role import RoleManager, DEFAULTMAXLISTUSERS
from PermissionRole import _what_not_even_god_should_do, rolesForPermissionOn from PermissionRole import _what_not_even_god_should_do, rolesForPermissionOn
import AuthEncoding import AuthEncoding
from AccessControl import getSecurityManager, Unauthorized from AccessControl import getSecurityManager
from zExceptions import Unauthorized
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.ZopeSecurityPolicy import _noroles from AccessControl.ZopeSecurityPolicy import _noroles
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[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
...@@ -91,8 +91,7 @@ from RestrictedPython.Utilities import utility_builtins ...@@ -91,8 +91,7 @@ from RestrictedPython.Utilities import utility_builtins
from SecurityManagement import getSecurityManager from SecurityManagement import getSecurityManager
from SecurityInfo import secureModule from SecurityInfo import secureModule
from SimpleObjectPolicies import Containers from SimpleObjectPolicies import Containers
from zExceptions import Unauthorized
Unauthorized = 'Unauthorized'
_marker = [] # Create a new marker object. _marker = [] # Create a new marker object.
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
# #
############################################################################## ##############################################################################
Unauthorized = 'Unauthorized' from unauthorized import Unauthorized
import DTML import DTML
del DTML del DTML
......
This diff is collapsed.
#
from SimpleObjectPolicies import _noroles
import cAccessControl
ZopeSecurityPolicy = cAccessControl.ZopeSecurityPolicy
...@@ -82,69 +82,25 @@ ...@@ -82,69 +82,25 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__doc__='''Objects that implement Permission-based roles. """Access control exceptions
"""
import zExceptions
$Id: cPermissionRole.py,v 1.1 2001/08/08 15:57:49 matt Exp $''' class Unauthorized(zExceptions.Unauthorized):
__version__='$Revision: 1.1 $'[11:-2]
import cAccessControl def getValueName(self):
rolesForPermissionOn=cAccessControl.rolesForPermissionOn v=self.value
PermissionRole=cAccessControl.PermissionRole n=getattr(v, 'getId', v)
imPermisionRole=cAccessControl.imPermissionRole if n is v: n=getattr(v, 'id', v)
_what_not_even_god_should_do= cAccessControl._what_not_even_god_should_do if n is v: n=getattr(v, '__name__', v)
if n is not v:
if callable(n):
try: n = n()
except TypeError: pass
return n
############################################################################## c = getattr(v, '__class__', type(v))
# Test functions: c = getattr(c, '__name__', 'object')
# return "a particular %s" % c
def main():
# The "main" program for this module
import sys
sys.path.append('/projects/_/ExtensionClass')
from Acquisition import Implicit
class I(Implicit):
x__roles__=PermissionRole('x')
y__roles__=PermissionRole('y')
z__roles__=PermissionRole('z')
def x(self): pass
def y(self): pass
def z(self): pass
a=I()
a.b=I()
a.b.c=I()
a.q=I()
a.q._x_Permission=('foo',)
a._y_Permission=('bar',)
a._z_Permission=('zee',)
a.b.c._y_Permission=('Manage',)
a.b._z_Permission=['also']
print a.x.__roles__, list(a.x.__roles__)
print a.b.x.__roles__
print a.b.c.x.__roles__
print a.q.x.__roles__
print a.b.q.x.__roles__
print a.b.c.q.x.__roles__
print
print a.y.__roles__, list(a.y.__roles__)
print a.b.y.__roles__
print a.b.c.y.__roles__
print a.q.y.__roles__
print a.b.q.y.__roles__
print a.b.c.q.y.__roles__
print
print a.z.__roles__, list(a.z.__roles__)
print a.b.z.__roles__
print a.b.c.z.__roles__
print a.q.z.__roles__
print a.b.q.z.__roles__
print a.b.c.q.z.__roles__
print
...@@ -85,15 +85,15 @@ ...@@ -85,15 +85,15 @@
"""Standard management interface support """Standard management interface support
$Id: Management.py,v 1.50 2001/09/04 16:50:48 shane Exp $""" $Id: Management.py,v 1.51 2001/10/19 15:12:25 shane Exp $"""
__version__='$Revision: 1.50 $'[11:-2] __version__='$Revision: 1.51 $'[11:-2]
import sys, Globals, ExtensionClass, urllib import sys, Globals, ExtensionClass, urllib
from Dialogs import MessageDialog from Dialogs import MessageDialog
from Globals import DTMLFile, HTMLFile from Globals import DTMLFile, HTMLFile
from string import split, join, find from string import split, join, find
from AccessControl import getSecurityManager from AccessControl import getSecurityManager, Unauthorized
class Tabs(ExtensionClass.Base): class Tabs(ExtensionClass.Base):
"""Mix-in provides management folder tab support.""" """Mix-in provides management folder tab support."""
...@@ -145,8 +145,8 @@ class Tabs(ExtensionClass.Base): ...@@ -145,8 +145,8 @@ class Tabs(ExtensionClass.Base):
m=options[0]['action'] m=options[0]['action']
if m=='manage_workspace': raise TypeError if m=='manage_workspace': raise TypeError
except: except:
raise 'Unauthorized', ( raise Unauthorized, (
'You are not authorized to view this object.<p>') 'You are not authorized to view this object.')
if find(m,'/'): if find(m,'/'):
raise 'Redirect', ( raise 'Redirect', (
......
...@@ -118,6 +118,7 @@ from Permission import PermissionManager ...@@ -118,6 +118,7 @@ from Permission import PermissionManager
import ZClasses, ZClasses.ZClass import ZClasses, ZClasses.ZClass
from HelpSys.HelpSys import ProductHelp from HelpSys.HelpSys import ProductHelp
import RefreshFuncs import RefreshFuncs
from AccessControl import Unauthorized
class ProductFolder(Folder): class ProductFolder(Folder):
...@@ -447,7 +448,7 @@ class Product(Folder, PermissionManager): ...@@ -447,7 +448,7 @@ class Product(Folder, PermissionManager):
Attempts to perform a refresh operation. Attempts to perform a refresh operation.
''' '''
if self._readRefreshTxt() is None: if self._readRefreshTxt() is None:
raise 'Unauthorized', 'refresh.txt not found' raise Unauthorized, 'refresh.txt not found'
message = None message = None
if RefreshFuncs.performFullRefresh(self._p_jar, self.id): if RefreshFuncs.performFullRefresh(self._p_jar, self.id):
from ZODB import Connection from ZODB import Connection
...@@ -463,7 +464,7 @@ class Product(Folder, PermissionManager): ...@@ -463,7 +464,7 @@ class Product(Folder, PermissionManager):
Changes the auto refresh flag for this product. Changes the auto refresh flag for this product.
''' '''
if self._readRefreshTxt() is None: if self._readRefreshTxt() is None:
raise 'Unauthorized', 'refresh.txt not created' raise Unauthorized, 'refresh.txt not created'
RefreshFuncs.enableAutoRefresh(self._p_jar, self.id, enable) RefreshFuncs.enableAutoRefresh(self._p_jar, self.id, enable)
if enable: if enable:
message = 'Enabled auto refresh.' message = 'Enabled auto refresh.'
...@@ -477,7 +478,7 @@ class Product(Folder, PermissionManager): ...@@ -477,7 +478,7 @@ class Product(Folder, PermissionManager):
Selects which products to refresh simultaneously. Selects which products to refresh simultaneously.
''' '''
if self._readRefreshTxt() is None: if self._readRefreshTxt() is None:
raise 'Unauthorized', 'refresh.txt not created' raise Unauthorized, 'refresh.txt not created'
RefreshFuncs.setDependentProducts(self._p_jar, self.id, selections) RefreshFuncs.setDependentProducts(self._p_jar, self.id, selections)
if REQUEST is not None: if REQUEST is not None:
return self.manage_refresh(REQUEST) return self.manage_refresh(REQUEST)
......
...@@ -82,8 +82,8 @@ ...@@ -82,8 +82,8 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
'''$Id: DT_Util.py,v 1.83 2001/09/04 13:46:43 evan Exp $''' '''$Id: DT_Util.py,v 1.84 2001/10/19 15:12:26 shane Exp $'''
__version__='$Revision: 1.83 $'[11:-2] __version__='$Revision: 1.84 $'[11:-2]
import re, os import re, os
from html_quote import html_quote # for import by other modules, dont remove! from html_quote import html_quote # for import by other modules, dont remove!
...@@ -98,7 +98,7 @@ LIMITED_BUILTINS = 1 ...@@ -98,7 +98,7 @@ LIMITED_BUILTINS = 1
str=__builtins__['str'] # Waaaaa, waaaaaaaa needed for pickling waaaaa str=__builtins__['str'] # Waaaaa, waaaaaaaa needed for pickling waaaaa
ParseError='Document Template Parse Error' ParseError='Document Template Parse Error'
ValidationError='Unauthorized' from zExceptions import Unauthorized as ValidationError
def int_param(params,md,name,default=0, st=type('')): def int_param(params,md,name,default=0, st=type('')):
try: v=params[name] try: v=params[name]
......
...@@ -85,19 +85,16 @@ ...@@ -85,19 +85,16 @@
"""Document Template Tests """Document Template Tests
""" """
__rcs_id__='$Id: testDTML.py,v 1.6 2001/07/02 16:30:46 shane Exp $' __rcs_id__='$Id: testDTML.py,v 1.7 2001/10/19 15:12:26 shane Exp $'
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
import sys, os import sys, os
import unittest import unittest
if __name__=='__main__': if __name__=='__main__':
sys.path.append(os.path.join(os.pardir, os.pardir))
here = os.curdir here = os.curdir
else: else:
from DocumentTemplate import tests here = os.path.split(__file__)[0]
from App.Common import package_home
here = package_home(tests.__dict__)
def read_file(name): def read_file(name):
f = open(os.path.join(here, name), 'rb') f = open(os.path.join(here, name), 'rb')
...@@ -122,7 +119,7 @@ class DTMLTests (unittest.TestCase): ...@@ -122,7 +119,7 @@ class DTMLTests (unittest.TestCase):
doc_class = HTML doc_class = HTML
def checkBatchingEtc(self): def testBatchingEtc(self):
def item(key,**kw): return (key,kw) def item(key,**kw): return (key,kw)
def item2(key,**kw): return kw def item2(key,**kw): return kw
...@@ -239,7 +236,7 @@ class DTMLTests (unittest.TestCase): ...@@ -239,7 +236,7 @@ class DTMLTests (unittest.TestCase):
expected = read_file('dealers.out') expected = read_file('dealers.out')
assert res == expected, res assert res == expected, res
def checkSequenceSummaries(self): def testSequenceSummaries(self):
def d(**kw): return kw def d(**kw): return kw
data=(d(name='jim', age=38), data=(d(name='jim', age=38),
# d(name='kak', age=40), # d(name='kak', age=40),
...@@ -274,7 +271,7 @@ class DTMLTests (unittest.TestCase): ...@@ -274,7 +271,7 @@ class DTMLTests (unittest.TestCase):
'median=5 mean=12.5 s.d.=17') 'median=5 mean=12.5 s.d.=17')
assert res == expected, res assert res == expected, res
def checkDTMLDateFormatting(self): def testDTMLDateFormatting(self):
import DateTime import DateTime
html = self.doc_class( html = self.doc_class(
"<dtml-var name capitalize spacify> is " "<dtml-var name capitalize spacify> is "
...@@ -285,13 +282,13 @@ class DTMLTests (unittest.TestCase): ...@@ -285,13 +282,13 @@ class DTMLTests (unittest.TestCase):
expected = 'Christmas day is 1995/12/25' expected = 'Christmas day is 1995/12/25'
assert res == expected, res assert res == expected, res
def checkSimpleString(self): def testSimpleString(self):
dt = String('%(name)s') dt = String('%(name)s')
res = dt(name='Chris') res = dt(name='Chris')
expected = 'Chris' expected = 'Chris'
assert res == expected, res assert res == expected, res
def checkStringDateFormatting(self): def testStringDateFormatting(self):
import DateTime import DateTime
html = String("%(name capitalize spacify)s is " html = String("%(name capitalize spacify)s is "
"%(date fmt=year)s/%(date fmt=month)s/%(date fmt=day)s") "%(date fmt=year)s/%(date fmt=month)s/%(date fmt=day)s")
...@@ -300,7 +297,7 @@ class DTMLTests (unittest.TestCase): ...@@ -300,7 +297,7 @@ class DTMLTests (unittest.TestCase):
expected = 'The date is 2001/4/27' expected = 'The date is 2001/4/27'
assert res == expected, res assert res == expected, res
def checkSequence1(self): def testSequence1(self):
html=self.doc_class( html=self.doc_class(
'<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item> ' '<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item> '
'</dtml-in sequence-item></dtml-in spam>') '</dtml-in sequence-item></dtml-in spam>')
...@@ -308,7 +305,7 @@ class DTMLTests (unittest.TestCase): ...@@ -308,7 +305,7 @@ class DTMLTests (unittest.TestCase):
res = html(spam=[[1,2,3],[4,5,6]]) res = html(spam=[[1,2,3],[4,5,6]])
assert res == expected, res assert res == expected, res
def checkSequence2(self): def testSequence2(self):
html=self.doc_class( html=self.doc_class(
'<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item>-' '<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item>-'
'</dtml-in sequence-item></dtml-in spam>') '</dtml-in sequence-item></dtml-in spam>')
...@@ -316,14 +313,14 @@ class DTMLTests (unittest.TestCase): ...@@ -316,14 +313,14 @@ class DTMLTests (unittest.TestCase):
res = html(spam=[[1,2,3],[4,5,6]]) res = html(spam=[[1,2,3],[4,5,6]])
assert res == expected, res assert res == expected, res
def checkNull(self): def testNull(self):
html=self.doc_class('<dtml-var spam fmt="$%.2f bobs your uncle" ' html=self.doc_class('<dtml-var spam fmt="$%.2f bobs your uncle" '
'null="spam%eggs!|">') 'null="spam%eggs!|">')
expected = '$42.00 bobs your unclespam%eggs!|' expected = '$42.00 bobs your unclespam%eggs!|'
res = html(spam=42) + html(spam=None) res = html(spam=42) + html(spam=None)
assert res == expected, res assert res == expected, res
def check_fmt(self): def test_fmt(self):
html=self.doc_class( html=self.doc_class(
""" """
<dtml-var spam> <dtml-var spam>
...@@ -369,7 +366,7 @@ foo bar ...@@ -369,7 +366,7 @@ foo bar
spam='<a href="spam">\nfoo bar') spam='<a href="spam">\nfoo bar')
assert res == expected, res assert res == expected, res
def checkPropogatedError(self): def testPropogatedError(self):
class foo: class foo:
def __len__(self): return 9 def __len__(self): return 9
...@@ -408,7 +405,7 @@ foo bar ...@@ -408,7 +405,7 @@ foo bar
else: else:
assert 0, 'Puke error not propogated' assert 0, 'Puke error not propogated'
def checkRenderCallable(self): def testRenderCallable(self):
"Test automatic rendering of callable objects" "Test automatic rendering of callable objects"
class C (Base): class C (Base):
__allow_access_to_unprotected_subobjects__ = 1 __allow_access_to_unprotected_subobjects__ = 1
...@@ -433,7 +430,7 @@ foo bar ...@@ -433,7 +430,7 @@ foo bar
<dtml-var expr="_.render(i.h2)">''')(i=C()) <dtml-var expr="_.render(i.h2)">''')(i=C())
assert res == expected, res assert res == expected, res
def checkWith(self): def testWith(self):
class person: class person:
__allow_access_to_unprotected_subobjects__ = 1 __allow_access_to_unprotected_subobjects__ = 1
name='Jim' name='Jim'
...@@ -448,7 +445,7 @@ foo bar ...@@ -448,7 +445,7 @@ foo bar
'cm.</dtml-with>')(person=person) 'cm.</dtml-with>')(person=person)
assert res == expected, res assert res == expected, res
def checkRaise(self): def testRaise(self):
try: try:
res = self.doc_class( res = self.doc_class(
"<dtml-raise IndexError>success!</dtml-raise>")() "<dtml-raise IndexError>success!</dtml-raise>")()
...@@ -457,7 +454,7 @@ foo bar ...@@ -457,7 +454,7 @@ foo bar
assert str(res) == 'success!', `res` assert str(res) == 'success!', `res`
def checkBasicHTMLIn(self): def testBasicHTMLIn(self):
data=( data=(
d(name='jim', age=39), d(name='jim', age=39),
d(name='kak', age=29), d(name='kak', age=29),
...@@ -481,7 +478,7 @@ foo bar ...@@ -481,7 +478,7 @@ foo bar
result = self.doc_class(html)(data=data) result = self.doc_class(html)(data=data)
assert result == expected, result assert result == expected, result
def checkBasicHTMLIn2(self): def testBasicHTMLIn2(self):
xxx=(D(name=1), D(name=2), D(name=3)) xxx=(D(name=1), D(name=2), D(name=3))
html = """ html = """
<!--#in xxx--> <!--#in xxx-->
...@@ -496,7 +493,7 @@ foo bar ...@@ -496,7 +493,7 @@ foo bar
result = self.doc_class(html)(xxx=xxx) result = self.doc_class(html)(xxx=xxx)
assert result == expected, result assert result == expected, result
def checkBasicHTMLIn3(self): def testBasicHTMLIn3(self):
ns = {'prop_ids': ('title', 'id'), 'title': 'good', 'id': 'times'} ns = {'prop_ids': ('title', 'id'), 'title': 'good', 'id': 'times'}
html = """:<dtml-in prop_ids><dtml-var sequence-item>=<dtml-var html = """:<dtml-in prop_ids><dtml-var sequence-item>=<dtml-var
expr="_[_['sequence-item']]">:</dtml-in>""" expr="_[_['sequence-item']]">:</dtml-in>"""
...@@ -505,7 +502,7 @@ foo bar ...@@ -505,7 +502,7 @@ foo bar
assert result == expected, result assert result == expected, result
def checkHTMLInElse(self): def testHTMLInElse(self):
xxx=(D(name=1), D(name=2), D(name=3)) xxx=(D(name=1), D(name=2), D(name=3))
html=""" html="""
<!--#in data mapping--> <!--#in data mapping-->
...@@ -524,7 +521,7 @@ foo bar ...@@ -524,7 +521,7 @@ foo bar
result = self.doc_class(html)(xxx=xxx, data={}) result = self.doc_class(html)(xxx=xxx, data={})
assert result == expected, result assert result == expected, result
def checkBasicStringIn(self): def testBasicStringIn(self):
data=( data=(
d(name='jim', age=39), d(name='jim', age=39),
d(name='kak', age=29), d(name='kak', age=29),
...@@ -548,22 +545,12 @@ foo bar ...@@ -548,22 +545,12 @@ foo bar
assert expected == result, result assert expected == result, result
def test_suite(): def test_suite():
return unittest.makeSuite(DTMLTests, 'check') suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( DTMLTests ) )
return suite
def main(): def main():
alltests = test_suite() unittest.TextTestRunner().run(test_suite())
runner = unittest.TextTestRunner()
runner.run(alltests)
def debug(): if __name__ == '__main__':
test_suite().debug()
def pdebug():
import pdb
pdb.run('debug()')
if __name__=='__main__':
if len(sys.argv) > 1:
globals()[sys.argv[1]]()
else:
main() main()
...@@ -84,9 +84,9 @@ ...@@ -84,9 +84,9 @@
############################################################################## ##############################################################################
__doc__="""Cacheable object and cache management base classes. __doc__="""Cacheable object and cache management base classes.
$Id: Cache.py,v 1.6 2001/02/08 15:24:16 shane Exp $""" $Id: Cache.py,v 1.7 2001/10/19 15:12:26 shane Exp $"""
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
import time, sys import time, sys
from string import join from string import join
...@@ -96,6 +96,7 @@ from Acquisition import aq_get, aq_acquire, aq_inner, aq_parent, aq_base ...@@ -96,6 +96,7 @@ from Acquisition import aq_get, aq_acquire, aq_inner, aq_parent, aq_base
from zLOG import LOG, WARNING from zLOG import LOG, WARNING
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl.Role import _isBeingUsedAsAMethod from AccessControl.Role import _isBeingUsedAsAMethod
from AccessControl import Unauthorized
ZCM_MANAGERS = '__ZCacheManager_ids__' ZCM_MANAGERS = '__ZCacheManager_ids__'
...@@ -585,7 +586,7 @@ class CacheManager: ...@@ -585,7 +586,7 @@ class CacheManager:
path = key[10:] path = key[10:]
ob = parent.restrictedTraverse(path) ob = parent.restrictedTraverse(path)
if not sm.checkPermission('Change cache settings', ob): if not sm.checkPermission('Change cache settings', ob):
raise 'Unauthorized' raise Unauthorized
if not isCacheable(ob): if not isCacheable(ob):
# Not a cacheable object. # Not a cacheable object.
continue continue
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
# #
############################################################################## ##############################################################################
__doc__="""Copy interface""" __doc__="""Copy interface"""
__version__='$Revision: 1.74 $'[11:-2] __version__='$Revision: 1.75 $'[11:-2]
import sys, string, Globals, Moniker, tempfile, ExtensionClass import sys, string, Globals, Moniker, tempfile, ExtensionClass
from marshal import loads, dumps from marshal import loads, dumps
...@@ -410,9 +410,9 @@ class CopyContainer(ExtensionClass.Base): ...@@ -410,9 +410,9 @@ class CopyContainer(ExtensionClass.Base):
except: parent=None except: parent=None
if getSecurityManager().validate(None, parent, None, object): if getSecurityManager().validate(None, parent, None, object):
return return
raise 'Unauthorized', absattr(object.id) raise Unauthorized, absattr(object.id)
else: else:
raise 'Unauthorized', mt_permission raise Unauthorized(permission=mt_permission)
# #
# XXX: Ancient cruft, left here in true co-dependent fashion # XXX: Ancient cruft, left here in true co-dependent fashion
# to keep from breaking old products which don't put # to keep from breaking old products which don't put
...@@ -434,9 +434,9 @@ class CopyContainer(ExtensionClass.Base): ...@@ -434,9 +434,9 @@ class CopyContainer(ExtensionClass.Base):
except: parent=None except: parent=None
if getSecurityManager().validate(None, parent, None, object): if getSecurityManager().validate(None, parent, None, object):
return return
raise 'Unauthorized', absattr(object.id) raise Unauthorized, absattr(object.id)
else: else:
raise 'Unauthorized', method_name raise Unauthorized, method_name
raise CopyError, MessageDialog( raise CopyError, MessageDialog(
title='Not Supported', title='Not Supported',
......
...@@ -87,13 +87,14 @@ ...@@ -87,13 +87,14 @@
Folders are the basic container objects and are analogous to directories. Folders are the basic container objects and are analogous to directories.
$Id: Folder.py,v 1.95 2001/10/15 14:38:13 evan Exp $""" $Id: Folder.py,v 1.96 2001/10/19 15:12:26 shane Exp $"""
__version__='$Revision: 1.95 $'[11:-2] __version__='$Revision: 1.96 $'[11:-2]
import Globals, SimpleItem, ObjectManager, PropertyManager import Globals, SimpleItem, ObjectManager, PropertyManager
import AccessControl.Role, webdav.Collection, FindSupport import AccessControl.Role, webdav.Collection, FindSupport
from webdav.WriteLockInterface import WriteLockInterface from webdav.WriteLockInterface import WriteLockInterface
from AccessControl import Unauthorized
from Globals import DTMLFile from Globals import DTMLFile
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
...@@ -121,14 +122,14 @@ def manage_addFolder(self, id, title='', ...@@ -121,14 +122,14 @@ def manage_addFolder(self, id, title='',
if createUserF: if createUserF:
if not checkPermission('Add User Folders', ob): if not checkPermission('Add User Folders', ob):
raise 'Unauthorized', ( raise Unauthorized, (
'You are not authorized to add User Folders.' 'You are not authorized to add User Folders.'
) )
ob.manage_addUserFolder() ob.manage_addUserFolder()
if createPublic: if createPublic:
if not checkPermission('Add Page Templates', ob): if not checkPermission('Add Page Templates', ob):
raise 'Unauthorized', ( raise Unauthorized, (
'You are not authorized to add Page Templates.' 'You are not authorized to add Page Templates.'
) )
ob.manage_addProduct['PageTemplates'].manage_addPageTemplate( ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
......
...@@ -84,12 +84,13 @@ ...@@ -84,12 +84,13 @@
############################################################################## ##############################################################################
'''This module implements a mix-in for traversable objects. '''This module implements a mix-in for traversable objects.
$Id: Traversable.py,v 1.11 2001/09/11 14:31:25 evan Exp $''' $Id: Traversable.py,v 1.12 2001/10/19 15:12:26 shane Exp $'''
__version__='$Revision: 1.11 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
from Acquisition import Acquired, aq_inner, aq_parent, aq_base from Acquisition import Acquired, aq_inner, aq_parent, aq_base
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl import Unauthorized
from string import split, join from string import split, join
from urllib import quote from urllib import quote
...@@ -165,7 +166,7 @@ class Traversable: ...@@ -165,7 +166,7 @@ class Traversable:
pop() pop()
self=self.getPhysicalRoot() self=self.getPhysicalRoot()
if (restricted and not securityManager.validateValue(self)): if (restricted and not securityManager.validateValue(self)):
raise 'Unauthorized', name raise Unauthorized, name
try: try:
object = self object = self
...@@ -181,7 +182,7 @@ class Traversable: ...@@ -181,7 +182,7 @@ class Traversable:
if o is not M: if o is not M:
if (restricted and not securityManager.validate( if (restricted and not securityManager.validate(
object, object,name, o)): object, object,name, o)):
raise 'Unauthorized', name raise Unauthorized, name
object=o object=o
continue continue
...@@ -198,7 +199,7 @@ class Traversable: ...@@ -198,7 +199,7 @@ class Traversable:
container = object container = object
if (not securityManager.validate(object, if (not securityManager.validate(object,
container, name, o)): container, name, o)):
raise 'Unauthorized', name raise Unauthorized, name
else: else:
o=get(object, name, M) o=get(object, name, M)
...@@ -209,17 +210,17 @@ class Traversable: ...@@ -209,17 +210,17 @@ class Traversable:
# value wasn't acquired # value wasn't acquired
if not securityManager.validate( if not securityManager.validate(
object, object, name, o): object, object, name, o):
raise 'Unauthorized', name raise Unauthorized, name
else: else:
if not securityManager.validate( if not securityManager.validate(
object, N, name, o): object, N, name, o):
raise 'Unauthorized', name raise Unauthorized, name
else: else:
o=object[name] o=object[name]
if (restricted and not securityManager.validate( if (restricted and not securityManager.validate(
object, object, N, o)): object, object, N, o)):
raise 'Unauthorized', name raise Unauthorized, name
object=o object=o
......
...@@ -84,12 +84,13 @@ ...@@ -84,12 +84,13 @@
############################################################################## ##############################################################################
'''CGI Response Output formatter '''CGI Response Output formatter
$Id: BaseResponse.py,v 1.8 2001/04/26 14:40:07 andreas Exp $''' $Id: BaseResponse.py,v 1.9 2001/10/19 15:12:27 shane Exp $'''
__version__='$Revision: 1.8 $'[11:-2] __version__='$Revision: 1.9 $'[11:-2]
import string, types, sys import string, types, sys
from string import find, rfind, lower, upper, strip, split, join, translate from string import find, rfind, lower, upper, strip, split, join, translate
from types import StringType, InstanceType from types import StringType, InstanceType
from zExceptions import Unauthorized
class BaseResponse: class BaseResponse:
"""Base Response Class """Base Response Class
...@@ -226,4 +227,4 @@ class BaseResponse: ...@@ -226,4 +227,4 @@ class BaseResponse:
Make sure to generate an appropriate challenge, as appropriate. Make sure to generate an appropriate challenge, as appropriate.
""" """
raise 'Unauthorized' raise Unauthorized
...@@ -84,13 +84,14 @@ ...@@ -84,13 +84,14 @@
############################################################################## ##############################################################################
'''CGI Response Output formatter '''CGI Response Output formatter
$Id: HTTPResponse.py,v 1.48 2001/08/07 18:36:48 evan Exp $''' $Id: HTTPResponse.py,v 1.49 2001/10/19 15:12:27 shane Exp $'''
__version__='$Revision: 1.48 $'[11:-2] __version__='$Revision: 1.49 $'[11:-2]
import string, types, sys, re import string, types, sys, re
from string import find, rfind, lower, upper, strip, split, join, translate from string import find, rfind, lower, upper, strip, split, join, translate
from types import StringType, InstanceType, LongType from types import StringType, InstanceType, LongType
from BaseResponse import BaseResponse from BaseResponse import BaseResponse
from zExceptions import Unauthorized
nl2sp=string.maketrans('\n',' ') nl2sp=string.maketrans('\n',' ')
...@@ -578,7 +579,7 @@ class HTTPResponse(BaseResponse): ...@@ -578,7 +579,7 @@ class HTTPResponse(BaseResponse):
m=m+'<p>\nUsername and password are not correct.' m=m+'<p>\nUsername and password are not correct.'
else: else:
m=m+'<p>\nNo Authorization header found.' m=m+'<p>\nNo Authorization header found.'
raise 'Unauthorized', m raise Unauthorized, m
def exception(self, fatal=0, info=None, def exception(self, fatal=0, info=None,
absuri_match=re.compile(r'\w+://[\w\.]+').match, absuri_match=re.compile(r'\w+://[\w\.]+').match,
...@@ -588,7 +589,11 @@ class HTTPResponse(BaseResponse): ...@@ -588,7 +589,11 @@ class HTTPResponse(BaseResponse):
if type(info) is type(()) and len(info)==3: t,v,tb = info if type(info) is type(()) and len(info)==3: t,v,tb = info
else: t,v,tb = sys.exc_info() else: t,v,tb = sys.exc_info()
if str(t)=='Unauthorized': self._unauthorized() if t=='Unauthorized' or t == Unauthorized or (
isinstance(t, types.ClassType) and issubclass(t, Unauthorized)
):
t = 'Unauthorized'
self._unauthorized()
stb=tb stb=tb
......
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
"""WebDAV support - null resource objects.""" """WebDAV support - null resource objects."""
__version__='$Revision: 1.32 $'[11:-2] __version__='$Revision: 1.33 $'[11:-2]
import sys, os, string, mimetypes, Globals, davcmds import sys, os, string, mimetypes, Globals, davcmds
import Acquisition, OFS.content_types import Acquisition, OFS.content_types
...@@ -96,6 +96,7 @@ from Resource import Resource ...@@ -96,6 +96,7 @@ from Resource import Resource
from Globals import Persistent, DTMLFile from Globals import Persistent, DTMLFile
from WriteLockInterface import WriteLockInterface from WriteLockInterface import WriteLockInterface
import OFS.SimpleItem import OFS.SimpleItem
from zExceptions import Unauthorized
class NullResource(Persistent, Acquisition.Implicit, Resource): class NullResource(Persistent, Acquisition.Implicit, Resource):
"""Null resources are used to handle HTTP method calls on """Null resources are used to handle HTTP method calls on
...@@ -179,8 +180,8 @@ class NullResource(Persistent, Acquisition.Implicit, Resource): ...@@ -179,8 +180,8 @@ class NullResource(Persistent, Acquisition.Implicit, Resource):
# check the clipboard. # check the clipboard.
try: try:
parent._verifyObjectPaste(ob.__of__(parent), 0) parent._verifyObjectPaste(ob.__of__(parent), 0)
except 'Unauthorized': except Unauthorized:
raise 'Unauthorized', sys.exc_info()[1] raise
except: except:
raise 'Forbidden', sys.exc_info()[1] raise 'Forbidden', sys.exc_info()[1]
...@@ -429,8 +430,8 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__): ...@@ -429,8 +430,8 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__):
# Verify that the user can create this type of object # Verify that the user can create this type of object
try: try:
parent._verifyObjectPaste(ob.__of__(parent), 0) parent._verifyObjectPaste(ob.__of__(parent), 0)
except 'Unauthorized': except Unauthorized:
raise 'Unauthorized', sys.exc_info()[1] raise
except: except:
raise 'Forbidden', sys.exc_info()[1] raise 'Forbidden', sys.exc_info()[1]
......
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
"""WebDAV support - resource objects.""" """WebDAV support - resource objects."""
__version__='$Revision: 1.47 $'[11:-2] __version__='$Revision: 1.48 $'[11:-2]
import sys, os, string, mimetypes, davcmds, ExtensionClass, Lockable import sys, os, string, mimetypes, davcmds, ExtensionClass, Lockable
from common import absattr, aq_base, urlfix, rfc1123_date, tokenFinder, urlbase from common import absattr, aq_base, urlfix, rfc1123_date, tokenFinder, urlbase
...@@ -95,6 +95,7 @@ from AccessControl import getSecurityManager ...@@ -95,6 +95,7 @@ from AccessControl import getSecurityManager
from WriteLockInterface import WriteLockInterface from WriteLockInterface import WriteLockInterface
import Globals, time import Globals, time
from ZPublisher.HTTPRangeSupport import HTTPRangeInterface from ZPublisher.HTTPRangeSupport import HTTPRangeInterface
from zExceptions import Unauthorized
class Resource(ExtensionClass.Base, Lockable.LockableItem): class Resource(ExtensionClass.Base, Lockable.LockableItem):
"""The Resource mixin class provides basic WebDAV support for """The Resource mixin class provides basic WebDAV support for
...@@ -155,7 +156,7 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -155,7 +156,7 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
method) method)
except: pass except: pass
raise 'Unauthorized', msg raise Unauthorized, msg
def dav__simpleifhandler(self, request, response, method='PUT', def dav__simpleifhandler(self, request, response, method='PUT',
col=0, url=None, refresh=0): col=0, url=None, refresh=0):
...@@ -394,8 +395,8 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -394,8 +395,8 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
try: parent._checkId(name, allow_dup=1) try: parent._checkId(name, allow_dup=1)
except: raise 'Forbidden', sys.exc_info()[1] except: raise 'Forbidden', sys.exc_info()[1]
try: parent._verifyObjectPaste(self) try: parent._verifyObjectPaste(self)
except 'Unauthorized': except Unauthorized:
raise 'Unauthorized', sys.exc_info()[1] raise
except: raise 'Forbidden', sys.exc_info()[1] except: raise 'Forbidden', sys.exc_info()[1]
# Now check locks. The If header on a copy only cares about the # Now check locks. The If header on a copy only cares about the
...@@ -483,8 +484,7 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -483,8 +484,7 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
except: except:
raise 'Forbidden', sys.exc_info()[1] raise 'Forbidden', sys.exc_info()[1]
try: parent._verifyObjectPaste(self) try: parent._verifyObjectPaste(self)
except 'Unauthorized': except Unauthorized: raise
raise 'Unauthorized', sys.exc_info()[1]
except: raise 'Forbidden', sys.exc_info()[1] except: raise 'Forbidden', sys.exc_info()[1]
# Now check locks. Since we're affecting the resource that we're # Now check locks. Since we're affecting the resource that we're
......
...@@ -82,172 +82,12 @@ ...@@ -82,172 +82,12 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__doc__='''Define Zope\'s default security policy """General exceptions that wish they were standard exceptions
These exceptions are so general purpose that they don't belong in Zope
application-specific packages.
$Id: pZopeSecurityPolicy.py,v 1.1 2001/08/08 15:57:49 matt Exp $''' $Id: __init__.py,v 1.2 2001/10/19 15:12:28 shane Exp $
__version__='$Revision: 1.1 $'[11:-2] """
from types import StringType from unauthorized import Unauthorized
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
...@@ -82,178 +82,57 @@ ...@@ -82,178 +82,57 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__doc__='''Objects that implement Permission-based roles. """
$Id: unauthorized.py,v 1.2 2001/10/19 15:12:28 shane Exp $
"""
$Id: pPermissionRole.py,v 1.1 2001/08/08 15:57:49 matt Exp $'''
__version__='$Revision: 1.1 $'[11:-2] class Unauthorized(Exception):
"""Some user wasn't allowed to access a resource"""
import sys
def __init__(self, message=None, value=None, needed=None, name=None, **kw):
from ExtensionClass import Base """Possible signatures:
import string Unauthorized()
Unauthorized(message) # Note that message includes a space
name_trans=filter(lambda c, an=string.letters+string.digits+'_': c not in an, Unauthorized(name)
map(chr,range(256))) Unauthorized(name, value)
name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans)) Unauthorized(name, value, needed)
Unauthorized(message, value, needed, name)
def rolesForPermissionOn(perm, object, default=('Manager',)):
"""Return the roles that have the given permission on the given object Where needed is a mapping objects with items represnting requirements
(e.g. {'permission': 'add spam'}). Any extra keyword arguments
provides are added to needed.
""" """
im=imPermissionRole() if name is None and message is not None and len(message.split()) <= 1:
im._p='_'+string.translate(perm, name_trans)+"_Permission" # First arg is a name, not a message
im._d=default name=message
return im.__of__(object) message=None
self.name=name
class PermissionRole(Base): self.message=message
"""Implement permission-based roles. self.value=value
Under normal circumstances, our __of__ method will be if kw:
called with an unwrapped object. The result will then be called if needed: needed.update(kw)
with a wrapped object, if the original object was wrapped. else: needed=kw
To deal with this, we have to create an intermediate object.
self.needed=needed
"""
def __str__(self):
def __init__(self, name, default=('Manager',)): if self.message is not None: return self.message
self.__name__=name if self.name is not None:
self._p='_'+string.translate(name,name_trans)+"_Permission" return ("You are not allowed to access %s in this context"
self._d=default % self.name)
elif self.value is not None:
def __of__(self, parent, None=None, getattr=getattr): return ("You are not allowed to access %s in this context"
r=imPermissionRole() % self.getValueName(self.value))
r._p=self._p
r._pa=parent
r._d=self._d def getValueName(self):
p=getattr(parent, 'aq_inner', None) v=self.value
if p is not None: vname=getattr(v, '__name__', None)
return r.__of__(p) if vname: return vname
else: c = getattr(v, '__class__', type(v))
return r c = getattr(c, '__name__', 'object')
return "a particular %s" % c
# 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)
##############################################################################
# Test functions:
#
def main():
# The "main" program for this module
import sys
sys.path.append('/projects/_/ExtensionClass')
from Acquisition import Implicit
class I(Implicit):
x__roles__=PermissionRole('x')
y__roles__=PermissionRole('y')
z__roles__=PermissionRole('z')
def x(self): pass
def y(self): pass
def z(self): pass
a=I()
a.b=I()
a.b.c=I()
a.q=I()
a.q._x_Permission=('foo',)
a._y_Permission=('bar',)
a._z_Permission=('zee',)
a.b.c._y_Permission=('Manage',)
a.b._z_Permission=['also']
print a.x.__roles__, list(a.x.__roles__)
print a.b.x.__roles__
print a.b.c.x.__roles__
print a.q.x.__roles__
print a.b.q.x.__roles__
print a.b.c.q.x.__roles__
print
print a.y.__roles__, list(a.y.__roles__)
print a.b.y.__roles__
print a.b.c.y.__roles__
print a.q.y.__roles__
print a.b.q.y.__roles__
print a.b.c.q.y.__roles__
print
print a.z.__roles__, list(a.z.__roles__)
print a.b.z.__roles__
print a.b.c.z.__roles__
print a.q.z.__roles__
print a.b.q.z.__roles__
print a.b.c.q.z.__roles__
print
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