Commit 9487026f authored by Hanno Schlichting's avatar Hanno Schlichting

Split up Owned and move its ZMI part into OFS

parent 9a804c3d
This diff is collapsed.
...@@ -25,7 +25,7 @@ from zope.interface import implements ...@@ -25,7 +25,7 @@ from zope.interface import implements
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.interfaces import IPermissionMappingSupport from AccessControl.interfaces import IPermissionMappingSupport
from AccessControl.Owned import UnownableOwner from AccessControl.owner import UnownableOwner
from AccessControl.Permission import pname from AccessControl.Permission import pname
from AccessControl.requestmethod import requestmethod from AccessControl.requestmethod import requestmethod
......
...@@ -27,7 +27,7 @@ from .rolemanager import gather_permissions ...@@ -27,7 +27,7 @@ from .rolemanager import gather_permissions
from zope.deferredimport import deprecated from zope.deferredimport import deprecated
deprecated("RoleManager is no longer part of AccessControl, please " deprecated("RoleManager is no longer part of AccessControl, please "
"depend on Zope2 and import from OFS.role or use the " "depend on Zope2 and import from OFS.role or use the new minimal "
"RoleManager class from AccessControl.rolemanager.", "RoleManager class from AccessControl.rolemanager.",
RoleManager = 'OFS.role:RoleManager', RoleManager = 'OFS.role:RoleManager',
) )
<dtml-var manage_page_header>
<dtml-with "_(management_view='Define Permissions')">
<dtml-if manage_tabs><dtml-var manage_tabs></dtml-if>
</dtml-with>
<p class="form-help">
This interface is used to define how the operations of this object
correspond to the operations defined by your product.
</p>
<p class="form-help">
The first column below lists the permissions for this object. The second
specifies the permissions that should have this permission in this product.
</p>
<p class="form-help">
In general, any permissions that include operations that change (mutate)
an object should be disabled. The listing below shows the current permission
mappings for this item.
</p>
xx
<dtml-with "_(valid=permissionMappingPossibleValues())">
<form action="manage_setPermissionMapping" method="post">
<table width="100%" cellpadding="2" cellspacing="0" border="0">
<tr class="list-header">
<td align="left" valign="top">
<div class="form-label">
Permission for this object
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
Permissions that correspond <br>
to (i.e. have) this permission
</div>
</td>
</tr>
<dtml-in manage_getPermissionMapping mapping>
<dtml-if sequence-odd>
<tr class="row-normal">
<dtml-else>
<tr class="row-hilite">
</dtml-if>
<td align="left" valign="top">
<div class="form-text">
&dtml-permission_name;
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<input type="hidden" name="permission_names:list" value="&dtml-permission_name;" />
<select name="class_permissions:list">
<option value=""<dtml-unless
class_permission> selected</dtml-unless>>(disabled)</option>
<dtml-in valid>
<option<dtml-if "_['sequence-item']==class_permission"
> selected</dtml-if>>&dtml-sequence-item;</option>
</dtml-in>
</select>
</div>
</td>
</tr>
</dtml-in>
<tr>
<td colspan="2" align="center">
<div class="form-element">
<input type="submit" name="submit" value="Save Changes">
</div>
</td>
</tr>
</table>
</form>
</dtml-with>
<dtml-var manage_page_footer>
...@@ -18,13 +18,8 @@ from zope.interface import Attribute ...@@ -18,13 +18,8 @@ from zope.interface import Attribute
from zope.interface import Interface from zope.interface import Interface
# XXX: might contain non-API methods and outdated comments;
# not synced with ZopeBook API Reference;
# based on AccessControl.Owned.Owned
class IOwned(Interface): class IOwned(Interface):
manage_owner = Attribute("""Manage owner view""")
def owner_info(): def owner_info():
"""Get ownership info for display """Get ownership info for display
""" """
...@@ -65,17 +60,6 @@ class IOwned(Interface): ...@@ -65,17 +60,6 @@ class IOwned(Interface):
""" """
""" """
def manage_takeOwnership(REQUEST, RESPONSE, recursive=0):
"""Take ownership (responsibility) for an object.
If 'recursive' is true, then also take ownership of all sub-objects.
"""
def manage_changeOwnershipType(explicit=1,
RESPONSE=None, REQUEST=None):
"""Change the type (implicit or explicit) of ownership.
"""
def _deleteOwnershipAfterAdd(): def _deleteOwnershipAfterAdd():
""" """
""" """
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Support for owned objects
"""
from Acquisition import aq_base
from Acquisition import aq_get
from Acquisition import aq_inner
from Acquisition import aq_parent
from ExtensionClass import Base
from zope.interface import implements
from AccessControl.class_init import InitializeClass
from AccessControl.interfaces import IOwned
from AccessControl.Permissions import view_management_screens
from AccessControl.Permissions import take_ownership
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager
# avoid importing 'emergency_user' / 'nobody' before set
from AccessControl import SpecialUsers as SU
UnownableOwner=[]
def ownableFilter(self):
_owner = aq_get(self, '_owner', None, 1)
return _owner is not UnownableOwner
# Marker to use as a getattr default.
_mark=ownableFilter
class Owned(Base):
implements(IOwned)
security = ClassSecurityInfo()
security.setPermissionDefault(take_ownership, ('Owner', ))
security.declareProtected(view_management_screens, 'owner_info')
def owner_info(self):
"""Get ownership info for display
"""
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':
getSecurityManager().checkPermission('Take ownership', self)
}
return d
security.declarePrivate('getOwner')
def getOwner(self, info=0,
aq_get=aq_get,
UnownableOwner=UnownableOwner,
getSecurityManager=getSecurityManager,
):
"""Get the owner
If a true argument is provided, then only the owner path and id are
returned. Otherwise, the owner object is returned.
"""
if info:
import warnings
warnings.warn('Owned.getOwner(1) is deprecated; '
'please use getOwnerTuple() instead.',
DeprecationWarning, stacklevel=2)
owner=aq_get(self, '_owner', None, 1)
if info or (owner is None): return owner
if owner is UnownableOwner: return None
udb, oid = owner
root=self.getPhysicalRoot()
udb=root.unrestrictedTraverse(udb, None)
if udb is None:
user = SU.nobody
else:
user = udb.getUserById(oid, None)
if user is None: user = SU.nobody
return user
security.declarePrivate('getOwnerTuple')
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)
security.declarePrivate('getWrappedOwner')
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 or owner is UnownableOwner:
return None
udb_path, oid = owner
root = self.getPhysicalRoot()
udb = root.unrestrictedTraverse(udb_path, None)
if udb is None:
return SU.nobody
user = udb.getUserById(oid, None)
if user is None:
return SU.nobody
return user.__of__(udb)
security.declarePrivate('changeOwnership')
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 = self.getOwnerTuple()
if not recursive:
if old == new or old is UnownableOwner:
return
if recursive:
children = getattr( aq_base(self), 'objectValues', lambda :() )()
for child in children:
child.changeOwnership(user, 1)
if old is not UnownableOwner:
self._owner = new
def userCanTakeOwnership(self):
security=getSecurityManager()
user=security.getUser()
info=ownerInfo(user)
if info is None: return 0
owner=self.getOwnerTuple()
if owner == info: return 0
return security.checkPermission('Take ownership', self)
def _deleteOwnershipAfterAdd(self):
# Only delete _owner if it is an instance attribute.
if self.__dict__.get('_owner', _mark) is not _mark:
del self._owner
for object in self.objectValues():
try: s=object._p_changed
except: s=0
try: object._deleteOwnershipAfterAdd()
except: pass
if s is None: object._p_deactivate()
def manage_fixupOwnershipAfterAdd(self):
# Sigh, get the parent's _owner
parent=getattr(self, '__parent__', None)
if parent is not None: _owner=aq_get(parent, '_owner', None, 1)
else: _owner=None
if (_owner is None and
((getattr(self, '__parent__', None) is None) or
(not hasattr(self, 'getPhysicalRoot'))
)
):
# This is a special case. An object is
# being added to an object that hasn't
# been added to the object hierarchy yet.
# We can delay fixing up the ownership until the
# object is actually added.
return None
if _owner is UnownableOwner:
# We want to acquire Unownable ownership!
return self._deleteOwnershipAfterAdd()
else:
# Otherwise change the ownership
user=getSecurityManager().getUser()
if (SU.emergency_user and aq_base(user) is SU.emergency_user):
__creatable_by_emergency_user__=getattr(
self,'__creatable_by_emergency_user__', None)
if (__creatable_by_emergency_user__ is None or
(not __creatable_by_emergency_user__())):
raise EmergencyUserCannotOwn(
"Objects cannot be owned by the emergency user")
self.changeOwnership(user)
# Force all subs to acquire ownership!
for object in self.objectValues():
try: s=object._p_changed
except: s=0
try: object._deleteOwnershipAfterAdd()
except: pass
if s is None: object._p_deactivate()
InitializeClass(Owned)
class EmergencyUserCannotOwn(Exception):
"The emergency user cannot own anything"
class EditUnowned(Exception):
"Can't edit unowned executables"
def absattr(attr):
if callable(attr): return attr()
return attr
def ownerInfo(user, getattr=getattr):
if user is None:
return None
uid=user.getId()
if uid is None: return uid
db=aq_parent(aq_inner(user))
path=[absattr(db.id)]
root=db.getPhysicalRoot()
while 1:
db=getattr(db,'aq_inner', None)
if db is None: break
db=aq_parent(db)
if db is root: break
id=db.id
if not isinstance(id, str):
try: id=id()
except: id=str(id)
path.append(id)
path.reverse()
return path, uid
...@@ -6,7 +6,7 @@ import unittest ...@@ -6,7 +6,7 @@ import unittest
from persistent import Persistent from persistent import Persistent
from Acquisition import Implicit, aq_inner from Acquisition import Implicit, aq_inner
from AccessControl.Owned import Owned from AccessControl.owner import Owned
class FauxUser(Implicit): class FauxUser(Implicit):
...@@ -142,7 +142,7 @@ class OwnedTests(unittest.TestCase): ...@@ -142,7 +142,7 @@ class OwnedTests(unittest.TestCase):
self.assertEqual(wrapped_owner, None) self.assertEqual(wrapped_owner, None)
def test_getWrappedOwner_unownable(self): def test_getWrappedOwner_unownable(self):
from AccessControl.Owned import UnownableOwner from AccessControl.owner import UnownableOwner
owned = self._makeOne() owned = self._makeOne()
owned._owner = UnownableOwner owned._owner = UnownableOwner
...@@ -196,7 +196,7 @@ class OwnedTests(unittest.TestCase): ...@@ -196,7 +196,7 @@ class OwnedTests(unittest.TestCase):
class OwnershipChangeTests(unittest.TestCase): class OwnershipChangeTests(unittest.TestCase):
def setUp(self): def setUp(self):
from AccessControl.Owned import UnownableOwner from AccessControl.owner import UnownableOwner
from AccessControl.User import UserFolder from AccessControl.User import UserFolder
super(OwnershipChangeTests, self).setUp() super(OwnershipChangeTests, self).setUp()
...@@ -275,7 +275,7 @@ class OwnershipChangeTests(unittest.TestCase): ...@@ -275,7 +275,7 @@ class OwnershipChangeTests(unittest.TestCase):
def test_changeOwnership_recursive_objectValues_acquisition(self): def test_changeOwnership_recursive_objectValues_acquisition(self):
# See https://bugs.launchpad.net/bugs/143403 # See https://bugs.launchpad.net/bugs/143403
from AccessControl.Owned import Owned from AccessControl.owner import Owned
class FauxContent(Implicit, Owned): class FauxContent(Implicit, Owned):
pass pass
previous_parent_owner = self.root.parent._owner previous_parent_owner = self.root.parent._owner
...@@ -297,6 +297,3 @@ def test_suite(): ...@@ -297,6 +297,3 @@ def test_suite():
unittest.makeSuite(OwnedTests), unittest.makeSuite(OwnedTests),
unittest.makeSuite(OwnershipChangeTests), unittest.makeSuite(OwnershipChangeTests),
)) ))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
...@@ -17,9 +17,9 @@ import sys ...@@ -17,9 +17,9 @@ import sys
import types import types
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.owner import UnownableOwner
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.PermissionMapping import aqwrap from AccessControl.PermissionMapping import aqwrap
from AccessControl.Owned import UnownableOwner
from Acquisition import Acquired from Acquisition import Acquired
from Acquisition import aq_base from Acquisition import aq_base
from Acquisition import Implicit from Acquisition import Implicit
......
...@@ -39,7 +39,7 @@ import os ...@@ -39,7 +39,7 @@ import os
import transaction import transaction
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.Owned import UnownableOwner from AccessControl.owner import UnownableOwner
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.unauthorized import Unauthorized from AccessControl.unauthorized import Unauthorized
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
......
...@@ -28,7 +28,6 @@ import time ...@@ -28,7 +28,6 @@ import time
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.Owned import Owned
from AccessControl.Permissions import view as View from AccessControl.Permissions import view as View
from AccessControl.unauthorized import Unauthorized from AccessControl.unauthorized import Unauthorized
from AccessControl.ZopeSecurityPolicy import getRoles from AccessControl.ZopeSecurityPolicy import getRoles
...@@ -56,6 +55,7 @@ from zope.interface import implements ...@@ -56,6 +55,7 @@ from zope.interface import implements
from OFS.interfaces import IItem from OFS.interfaces import IItem
from OFS.interfaces import IItemWithName from OFS.interfaces import IItemWithName
from OFS.interfaces import ISimpleItem from OFS.interfaces import ISimpleItem
from OFS.owner import Owned
from OFS.CopySupport import CopySource from OFS.CopySupport import CopySource
from OFS.role import RoleManager from OFS.role import RoleManager
from OFS.Traversable import Traversable from OFS.Traversable import Traversable
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Support for owned objects
"""
import urlparse
from Acquisition import aq_get
from Acquisition import aq_parent
from App.special_dtml import DTMLFile
from AccessControl.class_init import InitializeClass
from AccessControl.owner import Owned as BaseOwned
from AccessControl.owner import ownableFilter
from AccessControl.owner import UnownableOwner
from AccessControl.Permissions import view_management_screens
from AccessControl.Permissions import take_ownership
from AccessControl.requestmethod import requestmethod
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.unauthorized import Unauthorized
class Owned(BaseOwned):
security = ClassSecurityInfo()
security.setPermissionDefault(take_ownership, ('Owner', ))
manage_options=({'label': 'Ownership',
'action': 'manage_owner',
'filter': ownableFilter},
)
security.declareProtected(view_management_screens, 'manage_owner')
manage_owner = DTMLFile('dtml/owner', globals())
security.declareProtected(take_ownership, 'manage_takeOwnership')
@requestmethod('POST')
def manage_takeOwnership(self, REQUEST, RESPONSE, recursive=0):
"""Take ownership (responsibility) for an object.
If 'recursive' is true, then also take ownership of all sub-objects.
"""
security=getSecurityManager()
want_referer=REQUEST['URL1']+'/manage_owner'
got_referer=("%s://%s%s" %
urlparse.urlparse(REQUEST['HTTP_REFERER'])[:3])
__traceback_info__=want_referer, got_referer
if (want_referer != got_referer or security.calledByExecutable()):
raise Unauthorized(
'manage_takeOwnership was called from an invalid context')
self.changeOwnership(security.getUser(), recursive)
RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declareProtected(take_ownership, 'manage_changeOwnershipType')
@requestmethod('POST')
def manage_changeOwnershipType(self, explicit=1,
RESPONSE=None, REQUEST=None):
"""Change the type (implicit or explicit) of ownership.
"""
old=getattr(self, '_owner', None)
if explicit:
if old is not None:
return
owner = self.getOwnerTuple()
if owner is not None and owner is not UnownableOwner:
self._owner=owner
else:
if old is None:
return
new = aq_get(aq_parent(self), '_owner', None, 1)
_m = object()
if old is new and (self.__dict__.get('_owner', _m) is not _m):
del self._owner
if RESPONSE is not None:
RESPONSE.redirect(REQUEST['HTTP_REFERER'])
InitializeClass(Owned)
...@@ -26,7 +26,7 @@ class TestRecursiveChangeOwnership(ZopeTestCase.ZopeTestCase): ...@@ -26,7 +26,7 @@ class TestRecursiveChangeOwnership(ZopeTestCase.ZopeTestCase):
# remember user objects # remember user objects
# is the __of__() call correct? is it needed? without it ownerInfo in # is the __of__() call correct? is it needed? without it ownerInfo in
# Owned.py throws an AttributeError ... # owner.py throws an AttributeError ...
self.user1 = self.folder['acl_users'].getUser(ZopeTestCase.user_name self.user1 = self.folder['acl_users'].getUser(ZopeTestCase.user_name
).__of__(self.folder) ).__of__(self.folder)
self.user2 = self.folder['acl_users'].getUser(self.user_name2 self.user2 = self.folder['acl_users'].getUser(self.user_name2
......
...@@ -3,7 +3,7 @@ import unittest ...@@ -3,7 +3,7 @@ import unittest
from zope.component.testing import PlacelessSetup from zope.component.testing import PlacelessSetup
from zope.interface import implements from zope.interface import implements
from AccessControl.Owned import EmergencyUserCannotOwn from AccessControl.owner import EmergencyUserCannotOwn
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.User import User # before SpecialUsers from AccessControl.User import User # before SpecialUsers
......
...@@ -23,7 +23,6 @@ from urlparse import urlparse ...@@ -23,7 +23,6 @@ from urlparse import urlparse
from urlparse import urlunparse from urlparse import urlunparse
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.Owned import Owned
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Implicit from Acquisition import Implicit
from Acquisition import aq_parent from Acquisition import aq_parent
...@@ -32,6 +31,7 @@ from App.Management import Tabs ...@@ -32,6 +31,7 @@ from App.Management import Tabs
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from Persistence import Persistent from Persistence import Persistent
from persistent import TimeStamp from persistent import TimeStamp
from OFS.owner import Owned
from OFS.role import RoleManager from OFS.role import RoleManager
from OFS.SimpleItem import Item from OFS.SimpleItem import Item
from ZPublisher.BeforeTraverse import registerBeforeTraverse from ZPublisher.BeforeTraverse import registerBeforeTraverse
......
...@@ -15,11 +15,11 @@ import re ...@@ -15,11 +15,11 @@ import re
import sys import sys
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.Owned import Owned
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Implicit from Acquisition import Implicit
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from App.Management import Tabs from App.Management import Tabs
from OFS.owner import Owned
from OFS.role import RoleManager from OFS.role import RoleManager
from OFS.SimpleItem import Item from OFS.SimpleItem import Item
from Persistence import Persistent from Persistence import Persistent
......
...@@ -17,7 +17,7 @@ $Id$ ...@@ -17,7 +17,7 @@ $Id$
import time import time
from AccessControl.Owned import ownerInfo from AccessControl.owner import ownerInfo
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from Persistence import Persistent from Persistence import Persistent
from zope.interface import implements from zope.interface import implements
...@@ -79,7 +79,7 @@ class LockItem(Persistent): ...@@ -79,7 +79,7 @@ class LockItem(Persistent):
if errors: if errors:
raise ValueError, errors raise ValueError, errors
# AccessControl.Owned.ownerInfo returns the id of the creator # AccessControl.owner.ownerInfo returns the id of the creator
# and the path to the UserFolder they're defined in # and the path to the UserFolder they're defined in
self._creator = ownerInfo(creator) self._creator = ownerInfo(creator)
......
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