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 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__='''Support for owned objects
"""Support for owned objects
$Id: Owned.py,v 1.20 2003/11/28 16:45:32 jim Exp $'''
__version__='$Revision: 1.20 $'[11:-2]
$Id: Owned.py,v 1.21 2004/01/27 16:59:23 tseaver Exp $
"""
import Globals, urlparse, SpecialUsers, ExtensionClass
from AccessControl import getSecurityManager, Unauthorized
from Acquisition import aq_get, aq_parent, aq_base
UnownableOwner=[]
def ownableFilter(self,
aq_get=aq_get,
UnownableOwner=UnownableOwner):
_owner=aq_get(self, '_owner', None, 1)
def ownableFilter(self):
_owner = aq_get(self, '_owner', None, 1)
return _owner is not UnownableOwner
# Marker to use as a getattr default.
......@@ -52,8 +49,11 @@ class Owned(ExtensionClass.Base):
def owner_info(self):
"""Get ownership info for display
"""
owner=self.getOwner(1)
if owner is None or owner is UnownableOwner: return owner
owner=self.getOwnerTuple()
if owner is None or owner is UnownableOwner:
return owner
d={'path': '/'.join(owner[0]), 'id': owner[1],
'explicit': hasattr(self, '_owner'),
'userCanChangeOwnershipType':
......@@ -62,43 +62,71 @@ class Owned(ExtensionClass.Base):
return d
getOwner__roles__=()
def getOwner(self, info=0,
aq_get=aq_get,
UnownableOwner=UnownableOwner,
getSecurityManager=getSecurityManager,
):
def getOwner(self, info=0):
"""Get the owner
If a true argument is provided, then only the owner path and id are
returned. Otherwise, the owner object is returned.
"""
owner=aq_get(self, '_owner', None, 1)
if info or (owner is None): return owner
if info:
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:
user = SpecialUsers.nobody
else:
user = udb.getUserById(oid, None)
if user is None: user = SpecialUsers.nobody
return user
return SpecialUsers.nobody
user = udb.getUserById(oid, None)
if user is None:
return SpecialUsers.nobody
return user.__of__(udb)
changeOwnership__roles__=()
def changeOwnership(self, user, recursive=0,
aq_get=aq_get,
):
def changeOwnership(self, user, recursive=0):
"""Change the ownership to the given user. If 'recursive' is
true then also take ownership of all sub-objects, otherwise
sub-objects retain their ownership information."""
new=ownerInfo(user)
if new is None: return # Special user!
old=aq_get(self, '_owner', None, 1)
old = self.getOwnerTuple()
if old==new: return
if old is UnownableOwner: return
......@@ -117,7 +145,7 @@ class Owned(ExtensionClass.Base):
user=security.getUser()
info=ownerInfo(user)
if info is None: return 0
owner=self.getOwner(1)
owner=self.getOwnerTuple()
if owner == info: return 0
return security.checkPermission('Take ownership', self)
......@@ -147,7 +175,7 @@ class Owned(ExtensionClass.Base):
old=getattr(self, '_owner', None)
if explicit:
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:
self._owner=owner
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 @@
"""Tests of ZopeSecurityPolicy
"""
__rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.8 2003/11/28 16:44:07 jim Exp $'
__version__='$Revision: 1.8 $'[11:-2]
__rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.9 2004/01/27 16:59:23 tseaver Exp $'
__version__='$Revision: 1.9 $'[11:-2]
import os, sys, unittest
......@@ -47,6 +47,9 @@ class PublicMethod (Method):
def __call__(*args, **kw):
return args, kw
def getWrappedOwner(self):
return None
__roles__ = None
......@@ -60,6 +63,11 @@ class OwnedMethod (PublicMethod):
def getOwner(self):
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):
_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