Commit 1c5572b9 authored by Tres Seaver's avatar Tres Seaver

- Port new Owned API + tests from 2.6 branch.

parent e04ad274
...@@ -10,21 +10,18 @@ ...@@ -10,21 +10,18 @@
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################## ##############################################################################
__doc__='''Support for owned objects """Support for owned objects
$Id: Owned.py,v 1.21 2004/01/27 16:59:23 tseaver Exp $
$Id: Owned.py,v 1.20 2003/11/28 16:45:32 jim Exp $''' """
__version__='$Revision: 1.20 $'[11:-2]
import Globals, urlparse, SpecialUsers, ExtensionClass import Globals, urlparse, SpecialUsers, ExtensionClass
from AccessControl import getSecurityManager, Unauthorized from AccessControl import getSecurityManager, Unauthorized
from Acquisition import aq_get, aq_parent, aq_base from Acquisition import aq_get, aq_parent, aq_base
UnownableOwner=[] UnownableOwner=[]
def ownableFilter(self, def ownableFilter(self):
aq_get=aq_get, _owner = aq_get(self, '_owner', None, 1)
UnownableOwner=UnownableOwner):
_owner=aq_get(self, '_owner', None, 1)
return _owner is not UnownableOwner return _owner is not UnownableOwner
# Marker to use as a getattr default. # Marker to use as a getattr default.
...@@ -52,8 +49,11 @@ class Owned(ExtensionClass.Base): ...@@ -52,8 +49,11 @@ class Owned(ExtensionClass.Base):
def owner_info(self): def owner_info(self):
"""Get ownership info for display """Get ownership info for display
""" """
owner=self.getOwner(1) owner=self.getOwnerTuple()
if owner is None or owner is UnownableOwner: return owner
if owner is None or owner is UnownableOwner:
return owner
d={'path': '/'.join(owner[0]), 'id': owner[1], d={'path': '/'.join(owner[0]), 'id': owner[1],
'explicit': hasattr(self, '_owner'), 'explicit': hasattr(self, '_owner'),
'userCanChangeOwnershipType': 'userCanChangeOwnershipType':
...@@ -62,43 +62,71 @@ class Owned(ExtensionClass.Base): ...@@ -62,43 +62,71 @@ class Owned(ExtensionClass.Base):
return d return d
getOwner__roles__=() getOwner__roles__=()
def getOwner(self, info=0, def getOwner(self, info=0):
aq_get=aq_get,
UnownableOwner=UnownableOwner,
getSecurityManager=getSecurityManager,
):
"""Get the owner """Get the owner
If a true argument is provided, then only the owner path and id are If a true argument is provided, then only the owner path and id are
returned. Otherwise, the owner object is returned. returned. Otherwise, the owner object is returned.
""" """
owner=aq_get(self, '_owner', None, 1) if info:
if info or (owner is None): return owner import warnings
warnings.warn('Owned.getOwner(1) is deprecated; '
'please use getOwnerTuple() instead.',
DeprecationWarning)
return self.getOwnerTuple()
return aq_base(self.getWrappedOwner()) # ugh, backward compat.
getOwnerTuple__roles__=()
def getOwnerTuple(self):
"""Return a tuple, (userdb_path, user_id) for the owner.
o Ownership can be acquired, but only from the containment path.
o If unowned, return None.
"""
return aq_get(self, '_owner', None, 1)
getWrappedOwner__roles__=()
def getWrappedOwner(self):
"""Get the owner, modestly wrapped in the user folder.
o If the object is not owned, return None.
o If the owner's user database doesn't exist, return Nobody.
o If the owner ID does not exist in the user database, return Nobody.
"""
owner = self.getOwnerTuple()
if owner is None:
return None
if owner is UnownableOwner: return None udb_path, oid = owner
udb, oid = owner root = self.getPhysicalRoot()
udb = root.unrestrictedTraverse(udb_path, None)
root=self.getPhysicalRoot()
udb=root.unrestrictedTraverse(udb, None)
if udb is None: if udb is None:
user = SpecialUsers.nobody return SpecialUsers.nobody
else:
user = udb.getUserById(oid, None) user = udb.getUserById(oid, None)
if user is None: user = SpecialUsers.nobody
return user if user is None:
return SpecialUsers.nobody
return user.__of__(udb)
changeOwnership__roles__=() changeOwnership__roles__=()
def changeOwnership(self, user, recursive=0, def changeOwnership(self, user, recursive=0):
aq_get=aq_get,
):
"""Change the ownership to the given user. If 'recursive' is """Change the ownership to the given user. If 'recursive' is
true then also take ownership of all sub-objects, otherwise true then also take ownership of all sub-objects, otherwise
sub-objects retain their ownership information.""" sub-objects retain their ownership information."""
new=ownerInfo(user) new=ownerInfo(user)
if new is None: return # Special user! if new is None: return # Special user!
old=aq_get(self, '_owner', None, 1) old = self.getOwnerTuple()
if old==new: return if old==new: return
if old is UnownableOwner: return if old is UnownableOwner: return
...@@ -117,7 +145,7 @@ class Owned(ExtensionClass.Base): ...@@ -117,7 +145,7 @@ class Owned(ExtensionClass.Base):
user=security.getUser() user=security.getUser()
info=ownerInfo(user) info=ownerInfo(user)
if info is None: return 0 if info is None: return 0
owner=self.getOwner(1) owner=self.getOwnerTuple()
if owner == info: return 0 if owner == info: return 0
return security.checkPermission('Take ownership', self) return security.checkPermission('Take ownership', self)
...@@ -147,7 +175,7 @@ class Owned(ExtensionClass.Base): ...@@ -147,7 +175,7 @@ class Owned(ExtensionClass.Base):
old=getattr(self, '_owner', None) old=getattr(self, '_owner', None)
if explicit: if explicit:
if old is not None: return if old is not None: return
owner=aq_get(self, '_owner', None, 1) owner = self.getOwnerTuple()
if owner is not None and owner is not UnownableOwner: if owner is not None and owner is not UnownableOwner:
self._owner=owner self._owner=owner
else: else:
......
"""Unit tests for AccessControl.Owned
$Id: testOwned.py,v 1.2 2004/01/27 16:59:23 tseaver Exp $
"""
import unittest
import Testing
import ZODB
from Acquisition import Implicit, aq_inner
class FauxUser(Implicit):
def __init__(self, id):
self._id = id
def getId(self):
return self._id
class FauxUserFolder(Implicit):
def getUserById(self, id, default):
return FauxUser(id)
class FauxRoot(Implicit):
def getPhysicalRoot(self):
return aq_inner(self)
def unrestrictedTraverse(self, path, default=None):
if type(path) is type(''):
path = path.split('/')
if not path[0]:
path = path[1:]
obj = self
try:
while path:
next, path = path[0], path[1:]
obj = getattr(obj, next)
except AttributeError:
obj = default
return obj
class OwnedTests(unittest.TestCase):
def _getTargetClass(self):
from AccessControl.Owned import Owned
return Owned
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
def _makeDummy(self, *args, **kw):
from AccessControl.Owned import Owned
class Dummy(Implicit, Owned):
pass
return Dummy(*args, **kw)
def test_getOwnerTuple_unowned(self):
owned = self._makeOne()
owner_tuple = owned.getOwnerTuple()
self.assertEqual(owner_tuple, None)
def test_getOwnerTuple_simple(self):
owned = self._makeOne()
owned._owner = ('/foobar', 'baz')
owner_tuple = owned.getOwnerTuple()
self.assertEqual(len(owner_tuple), 2)
self.assertEqual(owner_tuple[0], '/foobar')
self.assertEqual(owner_tuple[1], 'baz')
def test_getOwnerTuple_acquired(self):
root = FauxRoot()
root._owner = ('/foobar', 'baz')
owned = self._makeDummy().__of__(root)
owner_tuple = owned.getOwnerTuple()
self.assertEqual(len(owner_tuple), 2)
self.assertEqual(owner_tuple[0], '/foobar')
self.assertEqual(owner_tuple[1], 'baz')
def test_getOwnerTuple_acquired_no_tricks(self):
# Ensure that we acquire ownership only through containment.
root = FauxRoot()
root._owner = ('/foobar', 'baz')
owned = self._makeDummy().__of__(root)
owner_tuple = owned.getOwnerTuple()
tricky = self._makeDummy()
tricky._owner = ('/bambam', 'qux')
tricky = tricky.__of__(root)
not_tricked = owned.__of__(tricky)
owner_tuple = not_tricked.getOwnerTuple()
self.assertEqual(len(owner_tuple), 2)
self.assertEqual(owner_tuple[0], '/foobar')
self.assertEqual(owner_tuple[1], 'baz')
def test_getWrappedOwner_unowned(self):
owned = self._makeOne()
wrapped_owner = owned.getWrappedOwner()
self.assertEqual(wrapped_owner, None)
def test_getWrappedOwner_simple(self):
root = FauxRoot()
root.acl_users = FauxUserFolder()
owned = self._makeDummy().__of__(root)
owned._owner = ('/acl_users', 'user')
wrapped_owner = owned.getWrappedOwner()
self.assertEqual(wrapped_owner.getId(), 'user')
def test_getWrappedOwner_acquired(self):
root = FauxRoot()
root._owner = ('/acl_users', 'user')
root.acl_users = FauxUserFolder()
owned = self._makeDummy().__of__(root)
wrapped_owner = owned.getWrappedOwner()
self.assertEqual(wrapped_owner.getId(), 'user')
def test_getWrappedOwner_acquired_no_tricks(self):
root = FauxRoot()
root._owner = ('/acl_users', 'user')
root.acl_users = FauxUserFolder()
owned = self._makeDummy().__of__(root)
tricky = self._makeDummy()
tricky._owner = ('/acl_users', 'black_hat')
tricky = tricky.__of__(root)
not_tricked = owned.__of__(tricky)
wrapped_owner = not_tricked.getWrappedOwner()
self.assertEqual(wrapped_owner.getId(), 'user')
def test_suite():
return unittest.makeSuite(OwnedTests)
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
"""Tests of ZopeSecurityPolicy """Tests of ZopeSecurityPolicy
""" """
__rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.8 2003/11/28 16:44:07 jim Exp $' __rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.9 2004/01/27 16:59:23 tseaver Exp $'
__version__='$Revision: 1.8 $'[11:-2] __version__='$Revision: 1.9 $'[11:-2]
import os, sys, unittest import os, sys, unittest
...@@ -47,6 +47,9 @@ class PublicMethod (Method): ...@@ -47,6 +47,9 @@ class PublicMethod (Method):
def __call__(*args, **kw): def __call__(*args, **kw):
return args, kw return args, kw
def getWrappedOwner(self):
return None
__roles__ = None __roles__ = None
...@@ -60,6 +63,11 @@ class OwnedMethod (PublicMethod): ...@@ -60,6 +63,11 @@ class OwnedMethod (PublicMethod):
def getOwner(self): def getOwner(self):
return self.aq_parent.aq_parent.acl_users.getUserById('theowner') return self.aq_parent.aq_parent.acl_users.getUserById('theowner')
def getWrappedOwner(self):
acl_users = self.aq_parent.aq_parent.acl_users
user = acl_users.getUserById('theowner')
return user.__of__(acl_users)
class setuidMethod (PublicMethod): class setuidMethod (PublicMethod):
_proxy_roles = sysadmin_roles _proxy_roles = sysadmin_roles
......
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