Commit d6e7db04 authored by 's avatar

- always look for WriteLockInterface *and* IWriteLock (the z3 version of the same interface)

- import and whitespace cleanup
parent b368a027
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""WebDAV support - lockable item. """WebDAV support - lockable item.
...@@ -15,17 +15,17 @@ ...@@ -15,17 +15,17 @@
$Id$ $Id$
""" """
import Acquisition
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Globals import InitializeClass from Globals import InitializeClass
from Globals import PersistentMapping from Globals import PersistentMapping
import Acquisition
from zope.interface import implements from zope.interface import implements
from EtagSupport import EtagSupport from EtagSupport import EtagSupport
from interfaces import IWriteLock
from WriteLockInterface import LockItemInterface from WriteLockInterface import LockItemInterface
from WriteLockInterface import WriteLockInterface from WriteLockInterface import WriteLockInterface
from interfaces import IWriteLock
class ResourceLockedError(Exception): pass class ResourceLockedError(Exception): pass
...@@ -132,8 +132,10 @@ class LockableItem(EtagSupport): ...@@ -132,8 +132,10 @@ class LockableItem(EtagSupport):
except: except:
# The locks may be totally messed up, so we'll just delete # The locks may be totally messed up, so we'll just delete
# and replace. # and replace.
if hasattr(self, '_dav_writelocks'): del self._dav_writelocks if hasattr(self, '_dav_writelocks'):
if WriteLockInterface.isImplementedBy(self): del self._dav_writelocks
if IWriteLock.providedBy(self) or \
WriteLockInterface.isImplementedBy(self):
self._dav_writelocks = PersistentMapping() self._dav_writelocks = PersistentMapping()
# Call into a special hook used by LockNullResources to delete # Call into a special hook used by LockNullResources to delete
...@@ -150,4 +152,5 @@ InitializeClass(LockableItem) ...@@ -150,4 +152,5 @@ InitializeClass(LockableItem)
def wl_isLocked(ob): def wl_isLocked(ob):
""" Returns true if the object is locked, returns 0 if the object """ Returns true if the object is locked, returns 0 if the object
is not locked or does not implement the WriteLockInterface """ is not locked or does not implement the WriteLockInterface """
return WriteLockInterface.isImplementedBy(ob) and ob.wl_isLocked() return (IWriteLock.providedBy(ob) or
WriteLockInterface.isImplementedBy(ob)) and ob.wl_isLocked()
...@@ -7,29 +7,36 @@ ...@@ -7,29 +7,36 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""WebDAV support - null resource objects.
"""WebDAV support - null resource objects.""" $Id$
"""
__version__='$Revision: 1.43 $'[11:-2] import sys
import sys, Globals, davcmds
import Acquisition, OFS.content_types import Acquisition, OFS.content_types
from common import aq_base, tokenFinder, IfParser import Globals
import OFS.SimpleItem
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from Resource import Resource
from Globals import Persistent, DTMLFile from Globals import Persistent, DTMLFile
from WriteLockInterface import WriteLockInterface from OFS.CopySupport import CopyError
import OFS.SimpleItem
from zExceptions import Unauthorized, NotFound, Forbidden, BadRequest
from zExceptions import MethodNotAllowed from zExceptions import MethodNotAllowed
from zExceptions import Unauthorized, NotFound, Forbidden, BadRequest
import davcmds
from common import aq_base, tokenFinder, IfParser
from common import isDavCollection from common import isDavCollection
from common import Locked, Conflict, PreconditionFailed, UnsupportedMediaType from common import Locked, Conflict, PreconditionFailed, UnsupportedMediaType
from OFS.CopySupport import CopyError from interfaces import IWriteLock
from Resource import Resource
from WriteLockInterface import WriteLockInterface
class NullResource(Persistent, Acquisition.Implicit, Resource): class NullResource(Persistent, Acquisition.Implicit, Resource):
"""Null resources are used to handle HTTP method calls on """Null resources are used to handle HTTP method calls on
objects which do not yet exist in the url namespace.""" objects which do not yet exist in the url namespace."""
...@@ -94,7 +101,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource): ...@@ -94,7 +101,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource):
parent = self.__parent__ parent = self.__parent__
ifhdr = REQUEST.get_header('If', '') ifhdr = REQUEST.get_header('If', '')
if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if (IWriteLock.providedBy(parent) or
WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
if ifhdr: if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1) parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
else: else:
...@@ -172,7 +181,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource): ...@@ -172,7 +181,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource):
raise Forbidden, 'Cannot create collection at this location.' raise Forbidden, 'Cannot create collection at this location.'
ifhdr = REQUEST.get_header('If', '') ifhdr = REQUEST.get_header('If', '')
if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if (IWriteLock.providedBy(parent) or
WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
if ifhdr: if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1) parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
else: else:
...@@ -202,7 +213,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource): ...@@ -202,7 +213,9 @@ class NullResource(Persistent, Acquisition.Implicit, Resource):
name = self.__name__ name = self.__name__
parent = self.__parent__ parent = self.__parent__
if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if (IWriteLock.providedBy(parent) or
WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
if ifhdr: if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1) parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
else: else:
...@@ -234,7 +247,7 @@ class NullResource(Persistent, Acquisition.Implicit, Resource): ...@@ -234,7 +247,7 @@ class NullResource(Persistent, Acquisition.Implicit, Resource):
else: else:
# The command was succesful # The command was succesful
lock = locknull.wl_getLock(token) lock = locknull.wl_getLock(token)
RESPONSE.setStatus(200) RESPONSE.setStatus(200)
RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"') RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
RESPONSE.setHeader('Lock-Token', 'opaquelocktoken:' + token) RESPONSE.setHeader('Lock-Token', 'opaquelocktoken:' + token)
RESPONSE.setBody(lock.asXML()) RESPONSE.setBody(lock.asXML())
...@@ -369,7 +382,9 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__): ...@@ -369,7 +382,9 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__):
# First we need to see if the parent of the locknull is locked, and # First we need to see if the parent of the locknull is locked, and
# if the user owns that lock (checked by handling the information in # if the user owns that lock (checked by handling the information in
# the If header). # the If header).
if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if (IWriteLock.providedBy(parent) or
WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'PUT', itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'PUT',
col=1, url=parenturl, col=1, url=parenturl,
refresh=1) refresh=1)
...@@ -407,7 +422,8 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__): ...@@ -407,7 +422,8 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__):
raise Forbidden, sys.exc_info()[1] raise Forbidden, sys.exc_info()[1]
# Put the locks on the new object # Put the locks on the new object
if not WriteLockInterface.isImplementedBy(ob): if not (IWriteLock.providedBy(ob) or
WriteLockInterface.isImplementedBy(ob)):
raise MethodNotAllowed, ( raise MethodNotAllowed, (
'The target object type cannot be locked') 'The target object type cannot be locked')
for token, lock in locks: for token, lock in locks:
...@@ -439,7 +455,9 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__): ...@@ -439,7 +455,9 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__):
# If the parent object is locked, that information should be in the # If the parent object is locked, that information should be in the
# if-header if the user owns a lock on the parent # if-header if the user owns a lock on the parent
if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if (IWriteLock.providedBy(parent) or
WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'MKCOL', itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'MKCOL',
col=1, url=parenturl, col=1, url=parenturl,
refresh=1) refresh=1)
...@@ -466,5 +484,4 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__): ...@@ -466,5 +484,4 @@ class LockNullResource(NullResource, OFS.SimpleItem.Item_w__name__):
RESPONSE.setBody('') RESPONSE.setBody('')
return RESPONSE return RESPONSE
Globals.default__class_init__(LockNullResource) Globals.default__class_init__(LockNullResource)
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
$Id$ $Id$
""" """
import sys
import mimetypes import mimetypes
import sys
from urllib import unquote from urllib import unquote
import ExtensionClass import ExtensionClass
...@@ -35,6 +35,7 @@ from common import IfParser ...@@ -35,6 +35,7 @@ from common import IfParser
from common import isDavCollection from common import isDavCollection
from common import Locked, Conflict, PreconditionFailed from common import Locked, Conflict, PreconditionFailed
from interfaces import IDAVResource from interfaces import IDAVResource
from interfaces import IWriteLock
from WriteLockInterface import WriteLockInterface from WriteLockInterface import WriteLockInterface
...@@ -233,8 +234,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -233,8 +234,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
# We're locked, and no if header was passed in, so # We're locked, and no if header was passed in, so
# the client doesn't own a lock. # the client doesn't own a lock.
raise Locked, 'Resource is locked.' raise Locked, 'Resource is locked.'
elif WriteLockInterface.isImplementedBy(parent) and \ elif (IWriteLock.providedBy(parent) or
parent.wl_isLocked(): WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
if ifhdr: if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1) parent.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1)
else: else:
...@@ -361,8 +363,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -361,8 +363,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
if existing: if existing:
# The destination itself exists, so we need to check its locks # The destination itself exists, so we need to check its locks
destob = aq_base(parent)._getOb(name) destob = aq_base(parent)._getOb(name)
if WriteLockInterface.isImplementedBy(destob) and \ if (IWriteLock.providedBy(destob) or
destob.wl_isLocked(): WriteLockInterface.isImplementedBy(destob)) and \
destob.wl_isLocked():
if ifhdr: if ifhdr:
itrue = destob.dav__simpleifhandler( itrue = destob.dav__simpleifhandler(
REQUEST, RESPONSE, 'COPY', refresh=1) REQUEST, RESPONSE, 'COPY', refresh=1)
...@@ -370,8 +373,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -370,8 +373,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
raise PreconditonFailed raise PreconditonFailed
else: else:
raise Locked, 'Destination is locked.' raise Locked, 'Destination is locked.'
elif WriteLockInterface.isImplementedBy(parent) and \ elif (IWriteLock.providedBy(parent) or
parent.wl_isLocked(): WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
if ifhdr: if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, 'COPY', parent.dav__simpleifhandler(REQUEST, RESPONSE, 'COPY',
refresh=1) refresh=1)
...@@ -456,8 +460,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -456,8 +460,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
if existing: if existing:
# The destination itself exists, so we need to check its locks # The destination itself exists, so we need to check its locks
destob = aq_base(parent)._getOb(name) destob = aq_base(parent)._getOb(name)
if WriteLockInterface.isImplementedBy(destob) and \ if (IWriteLock.providedBy(destob) or
destob.wl_isLocked(): WriteLockInterface.isImplementedBy(destob)) and \
destob.wl_isLocked():
if ifhdr: if ifhdr:
itrue = destob.dav__simpleifhandler( itrue = destob.dav__simpleifhandler(
REQUEST, RESPONSE, 'MOVE', url=dest, refresh=1) REQUEST, RESPONSE, 'MOVE', url=dest, refresh=1)
...@@ -465,8 +470,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -465,8 +470,9 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
raise PreconditionFailed raise PreconditionFailed
else: else:
raise Locked, 'Destination is locked.' raise Locked, 'Destination is locked.'
elif WriteLockInterface.isImplementedBy(parent) and \ elif (IWriteLock.providedBy(parent) or
parent.wl_isLocked(): WriteLockInterface.isImplementedBy(parent)) and \
parent.wl_isLocked():
# There's no existing object in the destination folder, so # There's no existing object in the destination folder, so
# we need to check the folders locks since we're changing its # we need to check the folders locks since we're changing its
# member list # member list
......
...@@ -7,51 +7,58 @@ ...@@ -7,51 +7,58 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""WebDAV xml request objects. """WebDAV xml request objects.
$Id$ $Id$
""" """
import sys import sys
from common import absattr, aq_base, urlfix, urlbase
from OFS.PropertySheets import DAVProperties
from LockItem import LockItem
from WriteLockInterface import WriteLockInterface
from Acquisition import aq_parent
from xmltools import XmlParser
from cStringIO import StringIO from cStringIO import StringIO
from urllib import quote from urllib import quote
import transaction
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from Acquisition import aq_parent
from OFS.PropertySheets import DAVProperties
from ZConfig.url import urljoin
from zExceptions import BadRequest, Forbidden from zExceptions import BadRequest, Forbidden
from common import absattr, aq_base, urlfix, urlbase
from common import isDavCollection from common import isDavCollection
from common import PreconditionFailed from common import PreconditionFailed
from ZConfig.url import urljoin from interfaces import IWriteLock
import transaction from LockItem import LockItem
from WriteLockInterface import WriteLockInterface
from xmltools import XmlParser
def safe_quote(url, mark=r'%'): def safe_quote(url, mark=r'%'):
if url.find(mark) > -1: if url.find(mark) > -1:
return url return url
return quote(url) return quote(url)
class DAVProps(DAVProperties): class DAVProps(DAVProperties):
"""Emulate required DAV properties for objects which do """Emulate required DAV properties for objects which do
not themselves support properties. This is mainly so not themselves support properties. This is mainly so
that non-PropertyManagers can appear to support DAV that non-PropertyManagers can appear to support DAV
PROPFIND requests.""" PROPFIND requests."""
def __init__(self, obj): def __init__(self, obj):
self.__obj__=obj self.__obj__=obj
def v_self(self): def v_self(self):
return self.__obj__ return self.__obj__
p_self=v_self
p_self=v_self
class PropFind: class PropFind:
"""Model a PROPFIND request.""" """Model a PROPFIND request."""
def __init__(self, request): def __init__(self, request):
self.request=request self.request=request
self.depth='infinity' self.depth='infinity'
...@@ -175,9 +182,9 @@ class PropFind: ...@@ -175,9 +182,9 @@ class PropFind:
return result.getvalue() return result.getvalue()
class PropPatch: class PropPatch:
"""Model a PROPPATCH request.""" """Model a PROPPATCH request."""
def __init__(self, request): def __init__(self, request):
self.request=request self.request=request
self.values=[] self.values=[]
...@@ -295,11 +302,9 @@ class PropPatch: ...@@ -295,11 +302,9 @@ class PropPatch:
return result return result
class Lock: class Lock:
"""Model a LOCK request.""" """Model a LOCK request."""
def __init__(self, request): def __init__(self, request):
self.request = request self.request = request
data = request.get('BODY', '') data = request.get('BODY', '')
...@@ -365,7 +370,8 @@ class Lock: ...@@ -365,7 +370,8 @@ class Lock:
errmsg = "403 Forbidden" errmsg = "403 Forbidden"
try: try:
if not WriteLockInterface.isImplementedBy(obj): if not (IWriteLock.providedBy(obj) or
WriteLockInterface.isImplementedBy(obj)):
if top: if top:
# This is the top level object in the apply, so we # This is the top level object in the apply, so we
# do want an error # do want an error
...@@ -429,7 +435,8 @@ class Unlock: ...@@ -429,7 +435,8 @@ class Unlock:
url = url + '/' url = url + '/'
errmsg = None errmsg = None
islockable = WriteLockInterface.isImplementedBy(obj) islockable = IWriteLock.providedBy(obj) or \
WriteLockInterface.isImplementedBy(obj)
if islockable and obj.wl_hasLock(token): if islockable and obj.wl_hasLock(token):
method = getattr(obj, 'wl_delLock') method = getattr(obj, 'wl_delLock')
...@@ -465,7 +472,8 @@ class Unlock: ...@@ -465,7 +472,8 @@ class Unlock:
if iscol: if iscol:
for ob in obj.objectValues(): for ob in obj.objectValues():
if hasattr(ob, '__dav_resource__') and \ if hasattr(ob, '__dav_resource__') and \
WriteLockInterface.isImplementedBy(ob): (IWriteLock.providedBy(ob) or
WriteLockInterface.isImplementedBy(ob)):
uri = urljoin(url, absattr(ob.id)) uri = urljoin(url, absattr(ob.id))
self.apply(ob, token, uri, result, top=0) self.apply(ob, token, uri, result, top=0)
if not top: if not top:
...@@ -492,7 +500,8 @@ class DeleteCollection: ...@@ -492,7 +500,8 @@ class DeleteCollection:
errmsg = None errmsg = None
parent = aq_parent(obj) parent = aq_parent(obj)
islockable = WriteLockInterface.isImplementedBy(obj) islockable = IWriteLock.providedBy(obj) or \
WriteLockInterface.isImplementedBy(obj)
if parent and (not user.has_permission('Delete objects', parent)): if parent and (not user.has_permission('Delete objects', parent)):
# User doesn't have permission to delete this object # User doesn't have permission to delete this object
errmsg = "403 Forbidden" errmsg = "403 Forbidden"
......
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