Commit a5651b7c authored by Jim Fulton's avatar Jim Fulton

Changed the mechanism for getting object roles, based on a suggestion

by Dieter Maurer.  This was to allow storing class-defined permission
requirements for class-defined attributes in classes totally
independently from the values being protected.
parent bf3537c7
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
__doc__='''Define Zope\'s default security policy __doc__='''Define Zope\'s default security policy
$Id: ZopeSecurityPolicy.py,v 1.24 2003/10/24 01:21:48 chrism Exp $''' $Id: ZopeSecurityPolicy.py,v 1.25 2003/11/28 16:44:06 jim Exp $'''
__version__='$Revision: 1.24 $'[11:-2] __version__='$Revision: 1.25 $'[11:-2]
_use_python_impl = 0 _use_python_impl = 0
...@@ -31,7 +31,7 @@ else: ...@@ -31,7 +31,7 @@ else:
_use_python_impl = 1 _use_python_impl = 1
if _use_python_impl: if 1 or _use_python_impl:
from types import StringType, UnicodeType from types import StringType, UnicodeType
...@@ -44,6 +44,32 @@ if _use_python_impl: ...@@ -44,6 +44,32 @@ if _use_python_impl:
from PermissionRole import _what_not_even_god_should_do, \ from PermissionRole import _what_not_even_god_should_do, \
rolesForPermissionOn rolesForPermissionOn
tuple_or_list = tuple, list
def getRoles(container, name, value, default):
roles = getattr(value, '__roles__', _noroles)
if roles is _noroles:
if not name or not isinstance(name, basestring):
return default
cls = getattr(container, '__class__', None)
if cls is None:
return default
roles = getattr(cls, name+'__roles__', _noroles)
if roles is _noroles:
return default
value = container
if roles is None or isinstance(roles, tuple_or_list):
return roles
rolesForPermissionOn = getattr(roles, 'rolesForPermissionOn', None)
if rolesForPermissionOn is not None:
roles = rolesForPermissionOn(value)
return roles
class ZopeSecurityPolicy: class ZopeSecurityPolicy:
...@@ -93,7 +119,7 @@ if _use_python_impl: ...@@ -93,7 +119,7 @@ if _use_python_impl:
# If roles weren't passed in, we'll try to get them from the object # If roles weren't passed in, we'll try to get them from the object
if roles is _noroles: if roles is _noroles:
roles=getattr(value, '__roles__', _noroles) roles = getRoles(container, name, value, _noroles)
############################################################ ############################################################
# We still might not have any roles # We still might not have any roles
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
"""Tests of ZopeSecurityPolicy """Tests of ZopeSecurityPolicy
""" """
__rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.7 2003/10/24 01:21:49 chrism Exp $' __rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.8 2003/11/28 16:44:07 jim Exp $'
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
import os, sys, unittest import os, sys, unittest
...@@ -44,6 +44,9 @@ class PublicMethod (Method): ...@@ -44,6 +44,9 @@ class PublicMethod (Method):
def getOwner(self): def getOwner(self):
return None return None
def __call__(*args, **kw):
return args, kw
__roles__ = None __roles__ = None
...@@ -267,9 +270,156 @@ class ZopeSecurityPolicyTests (unittest.TestCase): ...@@ -267,9 +270,156 @@ class ZopeSecurityPolicyTests (unittest.TestCase):
self.fail('Policy accepted bad __roles__') self.fail('Policy accepted bad __roles__')
def test_getRoles():
"""
>>> from AccessControl.ZopeSecurityPolicy import getRoles
>>> class C:
... x = 'CRole'
>>> class V:
... x = 'VRole'
>>> c = C()
>>> c.v = V()
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'inabox', c.v, 42)
42
>>> c.v.__roles__ = ['spam', 'eggs']
>>> getRoles(c, None, c.v, 42)
['spam', 'eggs']
>>> getRoles(c, 'withafox', c.v, 42)
['spam', 'eggs']
>>> del c.v.__roles__
>>> V.__roles__ = ('Manager', )
>>> getRoles(c, None, c.v, 42)
('Manager',)
>>> getRoles(c, 'withafox', c.v, 42)
('Manager',)
>>> del V.__roles__
>>> c.foo__roles__ = ('Foo', )
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
42
>>> C.foo__roles__ = ('Editor', )
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
('Editor',)
>>> del C.foo__roles__
>>> class ComputedRoles:
... def __init__(self, roles):
... self.roles = roles
... def rolesForPermissionOn(self, ob):
... return [ob.x] + self.roles
>>> c.v.__roles__ = ComputedRoles(['Member'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
>>> c.foo__roles__ = ComputedRoles(['Admin'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
>>> del c.v.__roles__
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
42
>>> C.foo__roles__ = ComputedRoles(['Guest'])
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
['CRole', 'Guest']
>>> V.__roles__ = ComputedRoles(['Member'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
"""
def test_zsp_gets_right_roles_for_methods():
"""
>>> zsp = ZopeSecurityPolicy()
>>> from ExtensionClass import Base
>>> class C(Base):
... def foo(self):
... pass
... foo__roles__ = ['greeneggs', 'ham']
... def bar(self):
... pass
>>> class User:
... def __init__(self, roles):
... self.roles = roles
... def allowed(self, value, roles):
... for role in roles:
... if role in self.roles:
... return True
... return False
>>> class Context:
... stack = ()
... def __init__(self, user):
... self.user = user
>>> c = C()
>>> bool(zsp.validate(c, c, 'foo', c.foo, Context(User(['greeneggs']))))
True
>>> zsp.validate(c, c, 'foo', c.foo, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'foo' in this context
>>> c.__roles__ = ['spam']
>>> zsp.validate(c, c, 'foo', c.foo, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'foo' in this context
>>> zsp.validate(c, c, 'bar', c.bar, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'bar' in this context
>>> c.__allow_access_to_unprotected_subobjects__ = 1
>>> bool(zsp.validate(c, c, 'bar', c.bar, Context(User(['spam']))))
True
"""
from doctest import DocTestSuite
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ZopeSecurityPolicyTests, 'test')) suite.addTest(unittest.makeSuite(ZopeSecurityPolicyTests, 'test'))
suite.addTest(DocTestSuite())
return suite return suite
def main(): def main():
......
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