Commit 5fc71985 authored by Boxiang Sun's avatar Boxiang Sun

apply 3.0.12 implementation with some Pyston change

parent 97bc7e89
Changelog
=========
2.13.14 (2015-12-21)
--------------------
For changes before verison 3.0, see ``HISTORY.txt``.
3.0.12 (2015-12-21)
-------------------
- Avoid acquiring ``access`` from module wrapped by
``SecurityInfo._ModuleSecurityInfo``. See:
https://github.com/zopefoundation/AccessControl/issues/12
2.13.13 (2013-07-16)
--------------------
- LP #1169923: ensure initialization of shared ``ImplPython`` state
(used by ``ImplC``) when using the "C" security policy. Thanks to
Arnaud Fontaine for the patch.
2.13.12 (2012-10-31)
--------------------
3.0.11 (2014-11-02)
-------------------
- LP #1071067: Use a stronger random number generator and a constant time
comparison function.
- Harden test fix for machines that do not define `localhost`.
2.13.11 (2012-10-21)
--------------------
3.0.10 (2014-11-02)
-------------------
- LP #966101: Recognize special ``zope2.Private`` permission in ZCML
role directive.
- Test fix for machines that do not define `localhost`.
2.13.10 (2012-09-09)
--------------------
3.0.9 (2014-08-08)
------------------
- LP #1047318: Tighten import restrictions for restricted code.
- GitHub #6: Do not pass SecurityInfo instance itself to declarePublic/declarePrivate
when using the public/private decorator. This fixes ``Conflicting security declarations``
warnings on Zope startup.
2.13.9 (2012-08-23)
-------------------
- LP #1248529: Leave existing security manager in place inside
``RoleManager.manage_getUserRolesAndPermissions``.
- Fix a bug in ZopeSecurityPolicy.py. Global variable ``rolesForPermissionOn``
could be overridden if ``__role__`` had custom ``rolesForPermissionOn``.
3.0.8 (2013-07-16)
------------------
2.13.8 (2012-06-22)
-------------------
- LP #1169923: ensure initialization of shared ``ImplPython`` state
(used by ``ImplC``) when using the "C" security policy. Thanks to
Arnaud Fontaine for the patch.
- Add Anonymous as a default role for Public permission.
3.0.7 (2013-05-14)
------------------
2.13.7 (2011-12-12)
-------------------
- Remove long-deprecated 'Shared' roles support (pre-dates Zope, never
used by Zope itself)
- Exclude compiled ``.so`` and ``.dll`` files from source distributions.
- Prevent infinite loop when looking up local roles in an acquisition chain
with cycles.
2.13.6 (2011-12-12)
-------------------
3.0.6 (2012-10-31)
------------------
- Added ``manifest.in`` to ensure the inclusion of the ``include`` directory
into the release.
- LP #1071067: Use a stronger random number generator and a constant time
comparison function.
2.13.5 (2011-12-12)
-------------------
3.0.5 (2012-10-21)
------------------
- Apply changes made available in ``Products.Zope_Hotfix_20111024`` and make
them more robust.
- LP #966101: Recognize special `zope2.Private` permission in ZCML
role directive.
2.13.4 (2011-01-11)
-------------------
3.0.4 (2012-09-09)
------------------
- Return the created user in ``_doAddUser``.
- LP #1047318: Tighten import restrictions for restricted code.
- Added ``IUser`` interface.
3.0.3 (2012-08-23)
------------------
- LP #659968: Added support for ``level`` argument to the ``__import__``
function as introduced in Python 2.5. Currently only ``level = -1`` is
supported.
- Fix a bug in ZopeSecurityPolicy.py. Global variable `rolesForPermissionOn`
could be overridden if `__role__` had custom rolesForPermissionOn.
2.13.3 (2010-08-28)
-------------------
3.0.2 (2012-06-22)
------------------
- Added a ``role`` subdirective for the ``permission`` ZCML directive. If any
roles are specified, they will override the default set of default roles
(Manager).
- Add Anonymous as a default role for Public permission.
2.13.2 (2010-07-16)
-------------------
3.0.1 (2012-05-24)
------------------
- Added ``override_existing_protection`` parameter to the protectName helper.
- Fix tests under Python 2.6.
2.13.1 (2010-06-19)
-------------------
3.0 (2012-05-12)
----------------
- Restore security declarations for deprecated ``sets`` module.
- Added decorators for public, private and protected security declarations.
2.13.0 (2010-06-19)
-------------------
- Update tests to take advantage of automatic test suite discovery.
- Released as separate package.
Pre 3.0 Changelog
=================
2.13.12 (2012-10-31)
--------------------
- LP #1071067: Use a stronger random number generator and a constant time
comparison function.
2.13.11 (2012-10-21)
--------------------
- LP #966101: Recognize special `zope2.Private` permission in ZCML
role directive.
2.13.10 (2012-09-09)
--------------------
- LP #1047318: Tighten import restrictions for restricted code.
2.13.9 (2012-08-23)
-------------------
- Fix a bug in ZopeSecurityPolicy.py. Global variable `rolesForPermissionOn`
could be overridden if `__role__` had custom rolesForPermissionOn.
2.13.8 (2012-06-22)
-------------------
- Add Anonymous as a default role for Public permission.
2.13.7 (2011-12-12)
-------------------
- Exclude compiled `.so` and `.dll` files from source distributions.
2.13.6 (2011-12-12)
-------------------
- Added `manifest.in` to ensure the inclusion of the `include` directory into
the release.
2.13.5 (2011-12-12)
-------------------
- Apply changes made available in `Products.Zope_Hotfix_20111024` and make them
more robust.
2.13.4 (2011-01-11)
-------------------
- Return the created user in _doAddUser.
- Added IUser interface.
- LP #659968: Added support for level argument to the ``__import__`` function
as introduced in Python 2.5. Currently only level=-1 is supported.
2.13.3 (2010-08-28)
-------------------
- Added a ``role`` subdirective for the ``permission`` ZCML directive. If any
roles are specified, they will override the default set of default roles
(Manager).
2.13.2 (2010-07-16)
-------------------
- Added ``override_existing_protection`` parameter to the protectName helper.
2.13.1 (2010-06-19)
-------------------
- Restore security declarations for deprecated ``sets`` module.
2.13.0 (2010-06-19)
-------------------
- Released as separate package.
include *.txt
include *.rst
recursive-include include *
recursive-include src/AccessControl *
......
This diff is collapsed.
[buildout]
develop = .
parts = interpreter test
parts = interpreter test coverage
[interpreter]
recipe = zc.recipe.egg
......@@ -10,3 +10,8 @@ eggs = AccessControl
[test]
recipe = zc.recipe.testrunner
eggs = AccessControl
[coverage]
recipe = zc.recipe.testrunner
eggs = AccessControl
defaults = ['--coverage', '../../coverage', '-v', '--auto-progress']
......@@ -212,7 +212,7 @@ static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) 0, # NAME, \
(PyMethod_Check((M)) ? ((PyMethodObject*)(M))->im_self : NULL)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
in the context of its container. */
#define has__of__(O) (PyObject_TypeCheck((O)->ob_type, ECExtensionClassType) \
&& (O)->ob_type->tp_descr_get != NULL)
......
......@@ -27,6 +27,19 @@ setup(name='AccessControl',
packages=find_packages('src'),
package_dir={'': 'src'},
classifiers=[
"Development Status :: 6 - Mature",
"Environment :: Web Environment",
"Framework :: Zope2",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2 :: Only",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: Pyston",
],
ext_modules=[Extension(
name='AccessControl.cAccessControl',
include_dirs=['include', 'src'],
......@@ -37,6 +50,8 @@ setup(name='AccessControl',
install_requires=[
'Acquisition',
'DateTime', # optional dependency of RestrictedPython
# Pyston change: Pyston will use pure Python implementation.
# So the version of ExtenstionClass is not important.
'ExtensionClass',
'Persistence',
'Record',
......
......@@ -93,7 +93,8 @@ _policy_names = {
# start with the default, mostly because we need something for the tests
setImplementation("C")
# Pyston change: use Python implementation by default
setImplementation("Python")
# allow the implementation to change from the default
_implementation_set = 0
......@@ -51,16 +51,16 @@ Persistent.__class_init__ = InitializeClass
LOG = getLogger('SecurityInfo')
# Security constants - these are imported into the AccessControl
# namespace and can be referenced as AccessControl.PUBLIC etc.
ACCESS_NONE = _what_not_even_god_should_do
ACCESS_NONE = _what_not_even_god_should_do
ACCESS_PRIVATE = ()
ACCESS_PUBLIC = None
ACCESS_PUBLIC = None
_marker = []
class SecurityInfo(Implicit):
"""Encapsulate security information."""
......@@ -71,6 +71,7 @@ class SecurityInfo(Implicit):
def __init__(self):
self.names = {}
self.roles = {}
self._unused_protected_decorators = set()
def _setaccess(self, names, access):
for name in names:
......@@ -79,37 +80,67 @@ class SecurityInfo(Implicit):
self._warnings = 1
self.names[name] = access
declarePublic__roles__=ACCESS_PRIVATE
declarePublic__roles__ = ACCESS_PRIVATE
def declarePublic(self, name, *names):
"""Declare names to be publicly accessible."""
self._setaccess((name,) + names, ACCESS_PUBLIC)
declarePrivate__roles__=ACCESS_PRIVATE
declarePrivate__roles__ = ACCESS_PRIVATE
def declarePrivate(self, name, *names):
"""Declare names to be inaccessible to restricted code."""
self._setaccess((name,) + names, ACCESS_PRIVATE)
declareProtected__roles__=ACCESS_PRIVATE
declareProtected__roles__ = ACCESS_PRIVATE
def declareProtected(self, permission_name, name, *names):
"""Declare names to be associated with a permission."""
self._setaccess((name,) + names, permission_name)
declareObjectPublic__roles__=ACCESS_PRIVATE
declareObjectPublic__roles__ = ACCESS_PRIVATE
def declareObjectPublic(self):
"""Declare the object to be publicly accessible."""
self._setaccess(('',), ACCESS_PUBLIC)
declareObjectPrivate__roles__=ACCESS_PRIVATE
declareObjectPrivate__roles__ = ACCESS_PRIVATE
def declareObjectPrivate(self):
"""Declare the object to be inaccessible to restricted code."""
self._setaccess(('',), ACCESS_PRIVATE)
declareObjectProtected__roles__=ACCESS_PRIVATE
declareObjectProtected__roles__ = ACCESS_PRIVATE
def declareObjectProtected(self, permission_name):
"""Declare the object to be associated with a permission."""
self._setaccess(('',), permission_name)
setPermissionDefault__roles__=ACCESS_PRIVATE
public__roles__ = ACCESS_PRIVATE
def public(self, func):
"""Decorate a function to be publicly accessible."""
self.declarePublic(func.__name__)
return func
private__roles__ = ACCESS_PRIVATE
def private(self, func):
"""Decorate a function to be inaccessible to restricted code."""
self.declarePrivate(func.__name__)
return func
protected__roles__ = ACCESS_PRIVATE
def protected(self, permission_name):
"""Return a decorator to associate a function with a permission."""
# the decorator returned is remembered in a set and will
# remove itself upon call. self.apply will check for an empty
# set and raise an AssertionError otherwise.
key = "'%s':%s" % (permission_name, id(lambda x: x))
def decor(func):
self.declareProtected(permission_name, func.__name__)
self._unused_protected_decorators.remove(key)
return func
# make sure our key algo creates unique-enough keys
if key in self._unused_protected_decorators:
raise KeyError("Duplicate key: %s" % (key,))
self._unused_protected_decorators.add(key)
return decor
setPermissionDefault__roles__ = ACCESS_PRIVATE
def setPermissionDefault(self, permission_name, roles):
"""Declare default roles for a permission"""
rdict = {}
......@@ -121,7 +152,7 @@ class SecurityInfo(Implicit):
self._warnings = 1
self.roles[permission_name] = rdict
setDefaultAccess__roles__=ACCESS_PRIVATE
setDefaultAccess__roles__ = ACCESS_PRIVATE
def setDefaultAccess(self, access):
"""Declare default attribute access policy.
......@@ -135,7 +166,7 @@ class SecurityInfo(Implicit):
elif access == 'deny':
access = 0
else:
raise ValueError, "'allow' or 'deny' expected"
raise ValueError("'allow' or 'deny' expected")
self.access = access
......@@ -148,13 +179,19 @@ class ClassSecurityInfo(SecurityInfo):
def apply(self, classobj):
"""Apply security information to the given class object."""
dict = classobj.__dict__
# make sure all decorators handed out by security.protected were used
if self._unused_protected_decorators:
msg = "Class '%r' has %d non-decorator security.protected calls!"
raise AssertionError(msg % (classobj,
len(self._unused_protected_decorators)))
cdict = classobj.__dict__
# Check the class for an existing __ac_permissions__ and
# incorporate that if present to support older classes or
# classes that haven't fully switched to using SecurityInfo.
if dict.has_key('__ac_permissions__'):
for item in dict['__ac_permissions__']:
if '__ac_permissions__' in cdict:
for item in cdict['__ac_permissions__']:
permission_name = item[0]
self._setaccess(item[1], permission_name)
if len(item) > 2:
......@@ -167,7 +204,7 @@ class ClassSecurityInfo(SecurityInfo):
if access in (ACCESS_PRIVATE, ACCESS_PUBLIC, ACCESS_NONE):
setattr(classobj, '%s__roles__' % name, access)
else:
if not ac_permissions.has_key(access):
if access not in ac_permissions:
ac_permissions[access] = []
ac_permissions[access].append(name)
......@@ -201,6 +238,7 @@ class ClassSecurityInfo(SecurityInfo):
LOG.warn('Class "%s" had conflicting '
'security declarations' % classobj.__name__)
class ClassSecurityInformation(ClassSecurityInfo):
# Default policy is disallow
access = 0
......@@ -208,6 +246,7 @@ class ClassSecurityInformation(ClassSecurityInfo):
_moduleSecurity = {}
_appliedModuleSecurity = {}
def secureModule(mname, *imp):
modsec = _moduleSecurity.get(mname, None)
if modsec is None:
......@@ -223,6 +262,7 @@ def secureModule(mname, *imp):
_appliedModuleSecurity[mname] = modsec
return module
def ModuleSecurityInfo(module_name=None):
if module_name is not None:
modsec = _moduleSecurity.get(module_name, None)
......@@ -246,10 +286,11 @@ def ModuleSecurityInfo(module_name=None):
# leading to the module
modname = module_name[dot + 1:]
pmodsec = ModuleSecurityInfo(module_name[:dot])
if not pmodsec.names.has_key(modname):
if modname not in pmodsec.names:
pmodsec.declarePublic(modname)
return _ModuleSecurityInfo(module_name)
class _ModuleSecurityInfo(SecurityInfo):
"""Encapsulate security information for modules."""
......@@ -284,23 +325,24 @@ class _ModuleSecurityInfo(SecurityInfo):
LOG.warn('Module "%s" had conflicting '
'security declarations' % dict['__name__'])
declareProtected__roles__=ACCESS_PRIVATE
declareProtected__roles__ = ACCESS_PRIVATE
def declareProtected(self, permission_name, *names):
"""Cannot declare module names protected."""
pass
declareObjectProtected__roles__=ACCESS_PRIVATE
declareObjectProtected__roles__ = ACCESS_PRIVATE
def declareObjectProtected(self, permission_name):
"""Cannot declare module protected."""
pass
setDefaultRoles__roles__=ACCESS_PRIVATE
setDefaultRoles__roles__ = ACCESS_PRIVATE
def setDefaultRoles(self, permission_name, roles):
"""Cannot set default roles for permissions in a module."""
pass
# Handy little utility functions
def allow_module(module_name):
"""Allow a module and all its contents to be used from a
restricted Script. The argument module_name may be a simple
......@@ -312,6 +354,7 @@ def allow_module(module_name):
ModuleSecurityInfo(module_name[:dot]).setDefaultAccess(1)
dot = module_name.find('.', dot + 1)
def allow_class(Class):
"""Allow a class and all of its methods to be used from a
restricted Script. The argument Class must be a class."""
......
......@@ -13,7 +13,7 @@
"""Place to find special users
This is needed to avoid a circular import problem. The 'real' values
are stored here by the AccessControl.User module as part of it's
are stored here by the AccessControl.User module as part of its
initialization.
"""
......
......@@ -894,7 +894,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
/*| # 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 it's container
**| # We'll try to get roles from its container
**|
**| if container is None: raise Unauthorized(name, value)
*/
......
......@@ -158,7 +158,6 @@ class RoleManager(Base, RoleManager):
else:
current = current.__parent__
newSecurityManager(None, userObj) # necessary?
userObj = userObj.__of__(uf)
d = {'user_defined_in': '/' + uf.absolute_url(1)}
......
......@@ -10,24 +10,39 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
""" Unit tests for ClassSecurityInfo.
"""
import unittest
class ClassSecurityInfoTests(unittest.TestCase):
def _getTargetClass(self):
from AccessControl.SecurityInfo import ClassSecurityInfo
return ClassSecurityInfo
def test_SetPermissionDefault(self):
def assertRaises(self, excClass, callableObj, *args, **kwargs):
"""Fail unless an exception of class excClass is thrown
by callableObj when invoked with arguments args and keyword
arguments kwargs. If a different type of exception is
thrown, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
unexpected exception.
Return the raised exception object, if it matches the expected type.
"""
try:
callableObj(*args, **kwargs)
except excClass as e:
return e
else:
if getattr(excClass,'__name__', None) is not None:
excName = excClass.__name__
else:
excName = str(excClass)
raise self.failureException("%s not raised" % excName)
def test_SetPermissionDefault(self):
# Test setting default roles for permissions.
from AccessControl.class_init import InitializeClass
from ExtensionClass import Base
......@@ -38,22 +53,39 @@ class ClassSecurityInfoTests(unittest.TestCase):
"""Test class
"""
__ac_roles__ = ('Role A', 'Role B', 'Role C')
meta_type = "Test"
security = ClassSecurityInfo()
security.setPermissionDefault('Make food', ('Chef',))
security.setPermissionDefault(
'Test permission',
('Manager', 'Role A', 'Role B', 'Role C')
)
security.declareProtected('Test permission', 'foo')
def foo(self, REQUEST=None):
security.declarePublic('public')
def public(self, REQUEST=None):
""" """
security.declarePrivate('private')
def private(self, REQUEST=None):
""" """
security.declareProtected('Test permission', 'protected')
def protected(self, REQUEST=None):
""" """
# same with decorators
@security.public
def public_new(self, REQUEST=None):
""" """
@security.private
def private_new(self, REQUEST=None):
""" """
@security.protected('Test permission')
def protected_new(self, REQUEST=None):
""" """
pass
# Do class initialization.
InitializeClass(Test)
......@@ -62,7 +94,24 @@ class ClassSecurityInfoTests(unittest.TestCase):
# correctly. Note that this uses carnal knowledge of the internal
# structures used to store this information!
object = Test()
imPermissionRole = [r for r in object.foo__roles__
self.assertEqual(object.public__roles__, None)
self.assertEqual(object.private__roles__, ())
imPermissionRole = [r for r in object.protected__roles__
if not r.endswith('_Permission')]
self.failUnless(len(imPermissionRole) == 4)
for item in ('Manager', 'Role A', 'Role B', 'Role C'):
self.failUnless(item in imPermissionRole)
# functions exist, i.e. decorators returned them
self.assertEqual(object.public_new.__name__, 'public_new')
self.assertEqual(object.private_new.__name__, 'private_new')
self.assertEqual(object.protected_new.__name__, 'protected_new')
# roles for functions have been set via decorators
self.assertEqual(object.public_new__roles__, None)
self.assertEqual(object.private_new__roles__, ())
imPermissionRole = [r for r in object.protected_new__roles__
if not r.endswith('_Permission')]
self.failUnless(len(imPermissionRole) == 4)
......@@ -74,11 +123,61 @@ class ClassSecurityInfoTests(unittest.TestCase):
self.assertEquals([t for t in Test.__ac_permissions__ if not t[1]],
[('Make food', (), ('Chef',))])
def test_EnsureProtectedDecoCall(self):
from AccessControl.class_init import InitializeClass
from ExtensionClass import Base
ClassSecurityInfo = self._getTargetClass()
class Test(Base):
"""Test class
"""
meta_type = "Test"
security = ClassSecurityInfo()
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ClassSecurityInfoTests))
return suite
security.protected('Test permission 1')
def unprotected1(self, REQUEST=None):
""" """
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
security.protected('Test permission 2')
def unprotected2(self, REQUEST=None):
""" """
@security.protected('Test permission 3')
def protected(self, REQUEST=None):
""" """
# Do class initialization.
exc = self.assertRaises(AssertionError,
InitializeClass, Test)
self.assertTrue('has 2 non-decorator' in str(exc))
def test_aq_context_in_decorators(self):
from Acquisition import Implicit
info = self._getTargetClass()
class A(Implicit):
security = info()
a = 1
@security.public
def public(self):
return self.a
@security.private
def private(self):
# make sure the acquisition context is still intact
return self.b
class B(Implicit):
security = info()
b = 2
a = A()
b = B()
a = a.__of__(b)
self.assertEqual(a.b, 2)
self.assertEqual(a.public(), 1)
self.assertEqual(a.private(), 2)
......@@ -62,6 +62,3 @@ class AccessControlImplementationTest(unittest.TestCase):
def test_suite():
return unittest.makeSuite(AccessControlImplementationTest)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")
......@@ -84,7 +84,3 @@ class ModuleSecurityTests(unittest.TestCase):
def test_level_nondefault(self):
self.assertUnauth('AccessControl.tests.public_module', (), level=1)
def test_suite():
return unittest.makeSuite(ModuleSecurityTests)
......@@ -290,10 +290,3 @@ class OwnershipChangeTests(unittest.TestCase):
self.assertEquals( self.root.parent.child.grandchild._owner
, previous_grandchild_owner
)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(OwnedTests),
unittest.makeSuite(OwnershipChangeTests),
))
......@@ -78,15 +78,3 @@ class PasswordDigestTests (unittest.TestCase):
# Sanity check
pw = 'my-password'
assert AuthEncoding.pw_validate(pw, pw)
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( PasswordDigestTests ) )
return suite
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
......@@ -9,9 +9,3 @@ class TestRoleManager(unittest.TestCase):
from zope.interface.verify import verifyClass
verifyClass(IPermissionMappingSupport, RoleManager)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestRoleManager),
))
......@@ -114,14 +114,3 @@ class PermissionRoleTests (unittest.TestCase):
self.failUnless(getattr(a, '_d') == ('Manager',))
self.failUnless(getattr(a, '__name__') == 'a')
self.failUnless(getattr(a, '_p') == '_a_Permission')
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(PermissionRoleTests))
return suite
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
import unittest
def _makeRootAndUser():
from AccessControl.rolemanager import RoleManager
from Acquisition import Implicit, Explicit
class DummyContext(Implicit, RoleManager):
__roles__ = ('Manager',)
class DummyUser(Explicit):
def getRoles(self):
return ('Manager',)
def getRolesInContext(self, context):
return ('Manager',)
def has_permission(self, permission, context):
return True
class DummyAclUsers(Explicit):
def getUser(self, user_id):
user = DummyUser()
return user.__of__(self)
def absolute_url(self, relative=0):
return 'acl_users'
class DummyRoot(Explicit):
acl_users = DummyAclUsers()
root = DummyRoot()
root.acl_users = DummyAclUsers()
root.context1 = DummyContext()
root.context2 = DummyContext()
user = DummyUser().__of__(root.acl_users)
return root, user
class TestRoleManager(unittest.TestCase):
def tearDown(self):
from AccessControl.SecurityManagement import noSecurityManager
noSecurityManager()
def test_interfaces(self):
from AccessControl.interfaces import IRoleManager
from AccessControl.rolemanager import RoleManager
......@@ -10,8 +55,12 @@ class TestRoleManager(unittest.TestCase):
verifyClass(IRoleManager, RoleManager)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestRoleManager),
))
def test_manage_getUserRolesAndPermissions(self):
from AccessControl.ImplPython import verifyAcquisitionContext
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
root, user = _makeRootAndUser()
newSecurityManager(None, user)
root.context1.manage_getUserRolesAndPermissions('dummy_user')
user = getSecurityManager().getUser()
self.assertTrue(verifyAcquisitionContext(user, root.context2, ()))
......@@ -262,10 +262,6 @@ class C_SecurityManagerTests(SecurityManagerTestBase,
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( PythonSecurityManagerTests ) )
suite.addTest( unittest.makeSuite( C_SecurityManagerTests ) )
suite.addTest(unittest.makeSuite(PythonSecurityManagerTests))
suite.addTest(unittest.makeSuite(C_SecurityManagerTests))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
......@@ -438,6 +438,7 @@ def test_register_permission_with_non_default_roles():
>>> tearDown()
"""
def test_suite():
import doctest
return doctest.DocTestSuite(optionflags=doctest.ELLIPSIS)
......@@ -857,9 +857,9 @@ protected_inplacevar allows inplce ops on sets:
[2, 7, 8, 9]
>>> sorted(s)
[2, 7, 8, 9]
"""
def test_suite():
suite = unittest.TestSuite([
doctest.DocTestSuite(),
......@@ -874,7 +874,3 @@ def test_suite():
):
suite.addTest(unittest.makeSuite(cls))
return suite
if __name__ == '__main__':
unittest.main()
......@@ -11,6 +11,7 @@
#
##############################################################################
from doctest import DocTestSuite
import sys
import thread
import unittest
......@@ -635,10 +636,8 @@ def test_zsp_gets_right_roles_for_methods():
>>> c.__allow_access_to_unprotected_subobjects__ = 1
>>> bool(zsp.validate(c, c, 'bar', c.bar, Context(User(['spam']))))
True
"""
from doctest import DocTestSuite
class GetRolesWithMultiThreadTest(unittest.TestCase):
......
......@@ -14,18 +14,16 @@
from zope.interface import implements
from zope.publisher.interfaces.browser import IBrowserRequest
class DummyRequest:
implements(IBrowserRequest)
def __init__(self, method):
self.method = method
def test_suite():
from doctest import DocFileSuite
return DocFileSuite('../requestmethod.txt',
globs=dict(GET=DummyRequest('GET'),
POST=DummyRequest('POST')))
if __name__ == '__main__':
import unittest
unittest.main(defaultTest='test_suite')
......@@ -60,7 +60,3 @@ class SafeIterTestCase(unittest.TestCase):
self.assertEqual(self.checks, [(contid, 1),
(contid, 2),
(contid, 3)])
def test_suite():
return unittest.makeSuite(SafeIterTestCase)
......@@ -151,9 +151,3 @@ class TestTaintedString(unittest.TestCase):
def testQuoted(self):
self.assertEquals(self.tainted.quoted(), self.quoted)
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestTaintedString))
return suite
......@@ -168,9 +168,3 @@ class UserFolderTests(unittest.TestCase):
self.assertEqual(user.__, ENCRYPTED)
self.failUnless(uf._isPasswordEncrypted(user.__))
self.failUnless(pw_validate(user.__, PASSWORD))
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(UserFolderTests))
return suite
This diff is collapsed.
......@@ -55,7 +55,7 @@ class BasicUser(Implicit):
# functionality that we cant anticipate from the base scaffolding.
def __allow_access_to_unprotected_subobjects__(self, name, value=None):
deny_names=('name', '__', 'roles', 'domains', '_getPassword',
'authenticate', '_shared_roles')
'authenticate')
if name in deny_names:
return 0
return 1
......@@ -128,29 +128,6 @@ class BasicUser(Implicit):
return result and domainSpecMatch(domains, request)
return result
def _shared_roles(self, parent):
r=[]
while 1:
if hasattr(parent, '__roles__'):
roles = parent.__roles__
if roles is None:
return 'Anonymous',
if 'Shared' in roles:
roles=list(roles)
roles.remove('Shared')
r = r + roles
else:
try:
return r + list(roles)
except:
return r
if getattr(parent, '__parent__', None) is not None:
while hasattr(parent.aq_self, 'aq_self'):
parent = parent.aq_self
parent = aq_parent(parent)
else:
return r
def _check_context(self, object):
# Check that 'object' exists in the acquisition context of
# the parent of the acl_users object containing this user,
......@@ -188,14 +165,6 @@ class BasicUser(Implicit):
if self._check_context(object):
return 1
# Check for ancient role data up front, convert if found.
# This should almost never happen, and should probably be
# deprecated at some point.
if 'Shared' in object_roles:
object_roles = self._shared_roles(object)
if object_roles is None or 'Anonymous' in object_roles:
return 1
# Check for a role match with the normal roles given to
# the user, then with local roles only if necessary. We
# want to avoid as much overhead as possible.
......@@ -211,6 +180,7 @@ class BasicUser(Implicit):
# we can incur only the overhead required to find a match.
inner_obj = getattr(object, 'aq_inner', object)
userid = self.getId()
parents = set()
while 1:
local_roles = getattr(inner_obj, '__ac_local_roles__', None)
if local_roles:
......@@ -226,16 +196,19 @@ class BasicUser(Implicit):
inner = getattr(inner_obj, 'aq_inner', inner_obj)
parent = getattr(inner, '__parent__', None)
if parent is not None:
if parent in parents:
break
parents.add(parent)
inner_obj = parent
continue
if hasattr(inner_obj, 'im_self'):
inner_obj=inner_obj.im_self
inner_obj=getattr(inner_obj, 'aq_inner', inner_obj)
inner_obj = inner_obj.im_self
inner_obj = getattr(inner_obj, 'aq_inner', inner_obj)
continue
break
return None
domains=[]
domains = []
def has_role(self, roles, object=None):
"""Check if the user has at least one role from a list of roles.
......@@ -459,14 +432,18 @@ def domainSpecMatch(spec, request):
if not host:
try:
host=socket.gethostbyaddr(addr)[0]
except:
host = socket.gethostbyaddr(addr)[0]
except Exception:
pass
if not addr:
try:
addr=socket.gethostbyname(host)
except:
pass
addr = socket.gethostbyname(host)
except Exception:
# always define localhost, even if the underlying system
# doesn't know about it, this fixes tests on travis
if host == 'localhost':
addr = '127.0.0.1'
_host = host.split('.')
_addr = addr.split('.')
......
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