diff options
| author | atp (Open ERP) <atp@tinyerp.co.in> | 2010-12-23 16:27:05 +0530 |
|---|---|---|
| committer | atp (Open ERP) <atp@tinyerp.co.in> | 2010-12-23 16:27:05 +0530 |
| commit | 40201bfea2756b5681c8ef265fd8573d6d70726f (patch) | |
| tree | 636d010ca4421d704f2d56cc8accb95601323bed /addons/document_webdav/webdav_server.py | |
| parent | ffa6d2dda7b51660f0c647a4598090149c34c72a (diff) | |
| parent | 6b8317f70498d0d180879dff8a59ea05f4153ef7 (diff) | |
[MERGE]: Merge with lp:~openerp-dev/openobject-addons/trunk-dev-addons1
bzr revid: atp@tinyerp.co.in-20101223105705-xyo4vu424j3lhqlt
Diffstat (limited to 'addons/document_webdav/webdav_server.py')
| -rw-r--r-- | addons/document_webdav/webdav_server.py | 144 |
1 files changed, 143 insertions, 1 deletions
diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py index 07e6d85536b..82268ef8b1e 100644 --- a/addons/document_webdav/webdav_server.py +++ b/addons/document_webdav/webdav_server.py @@ -1,8 +1,14 @@ # -*- encoding: utf-8 -*- # -# Copyright P. Christeas <p_christ@hol.gr> 2008,2009 +# Copyright P. Christeas <p_christ@hol.gr> 2008-2010 # +# Disclaimer: Many of the functions below borrow code from the +# python-webdav library (http://code.google.com/p/pywebdav/ ), +# which they import and override to suit OpenERP functionality. +# python-webdav was written by: Simon Pamies <s.pamies@banality.de> +# Christian Scholz <mrtopf@webdav.de> +# Vince Spicer <vince@vince.ca> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential @@ -38,7 +44,9 @@ import urllib import re from string import atoi from DAV.errors import * +from DAV.utils import IfParser, TagList # from DAV.constants import DAV_VERSION_1, DAV_VERSION_2 +from xml.dom import minidom khtml_re = re.compile(r' KHTML/([0-9\.]+) ') @@ -102,6 +110,7 @@ class DAVHandler(HttpOptions, FixSendError, DAVRequestHandler): self.headers['Destination'] = up.path[len(self.davpath):] else: raise DAV_Forbidden("Not allowed to copy/move outside webdav path") + # TODO: locks DAVRequestHandler.copymove(self, CLASS) def get_davpath(self): @@ -261,6 +270,139 @@ class DAVHandler(HttpOptions, FixSendError, DAVRequestHandler): except DAV_Error, (ec, dd): return self.send_status(ec) + def do_UNLOCK(self): + """ Unlocks given resource """ + + dc = self.IFACE_CLASS + self.log_message('UNLOCKing resource %s' % self.headers) + + uri = urlparse.urljoin(self.get_baseuri(dc), self.path) + uri = urllib.unquote(uri) + + token = self.headers.get('Lock-Token', False) + if token: + token = token.strip() + if token[0] == '<' and token[-1] == '>': + token = token[1:-1] + else: + token = False + + if not token: + return self.send_status(400, 'Bad lock token') + + try: + res = dc.unlock(uri, token) + except DAV_Error, (ec, dd): + return self.send_status(ec, dd) + + if res == True: + self.send_body(None, '204', 'OK', 'Resource unlocked.') + else: + # We just differentiate the description, for debugging purposes + self.send_body(None, '204', 'OK', 'Resource not locked.') + + def do_LOCK(self): + """ Attempt to place a lock on the given resource. + """ + + dc = self.IFACE_CLASS + lock_data = {} + + self.log_message('LOCKing resource %s' % self.headers) + + body = None + if self.headers.has_key('Content-Length'): + l = self.headers['Content-Length'] + body = self.rfile.read(atoi(l)) + + depth = self.headers.get('Depth', 'infinity') + + uri = urlparse.urljoin(self.get_baseuri(dc), self.path) + uri = urllib.unquote(uri) + self.log_message('do_LOCK: uri = %s' % uri) + + ifheader = self.headers.get('If') + + if ifheader: + ldif = IfParser(ifheader) + if isinstance(ldif, list): + if len(ldif) !=1 or (not isinstance(ldif[0], TagList)) \ + or len(ldif[0].list) != 1: + raise DAV_Error(400, "Cannot accept multiple tokens") + ldif = ldif[0].list[0] + if ldif[0] == '<' and ldif[-1] == '>': + ldif = ldif[1:-1] + + lock_data['token'] = ldif + + if not body: + lock_data['refresh'] = True + else: + lock_data['refresh'] = False + lock_data.update(self._lock_unlock_parse(body)) + + if lock_data['refresh'] and not lock_data.get('token', False): + raise DAV_Error(400, 'Lock refresh must specify token') + + lock_data['depth'] = depth + + try: + created, data, lock_token = dc.lock(uri, lock_data) + except DAV_Error, (ec, dd): + return self.send_status(ec, dd) + + headers = {} + if not lock_data['refresh']: + headers['Lock-Token'] = '<%s>' % lock_token + + if created: + self.send_body(data, '201', 'Created', ctype='text/xml', headers=headers) + else: + self.send_body(data, '200', 'OK', ctype='text/xml', headers=headers) + + def _lock_unlock_parse(self, body): + # Override the python-webdav function, with some improvements + # Unlike the py-webdav one, we also parse the owner minidom elements into + # pure pythonic struct. + doc = minidom.parseString(body) + + data = {} + owners = [] + for info in doc.getElementsByTagNameNS('DAV:', 'lockinfo'): + for scope in info.getElementsByTagNameNS('DAV:', 'lockscope'): + for scc in scope.childNodes: + if scc.nodeType == info.ELEMENT_NODE \ + and scc.namespaceURI == 'DAV:': + data['lockscope'] = scc.localName + break + for ltype in info.getElementsByTagNameNS('DAV:', 'locktype'): + for ltc in ltype.childNodes: + if ltc.nodeType == info.ELEMENT_NODE \ + and ltc.namespaceURI == 'DAV:': + data['locktype'] = ltc.localName + break + for own in info.getElementsByTagNameNS('DAV:', 'owner'): + for ono in own.childNodes: + if ono.nodeType == info.TEXT_NODE: + if ono.data: + owners.append(ono.data) + elif ono.nodeType == info.ELEMENT_NODE \ + and ono.namespaceURI == 'DAV:' \ + and ono.localName == 'href': + href = '' + for hno in ono.childNodes: + if hno.nodeType == info.TEXT_NODE: + href += hno.data + owners.append(('href','DAV:', href)) + + if len(owners) == 1: + data['lockowner'] = owners[0] + elif not owners: + pass + else: + data['lockowner'] = owners + return data + from service.http_server import reg_http_service,OpenERPAuthProvider class DAVAuthProvider(OpenERPAuthProvider): |
