def lock(self, request, path, xbody=None, *args, **kwargs): # TODO Lock refreshing if not self.has_access(self.resource, 'write'): return HttpResponseForbidden() if not xbody: return HttpResponseBadRequest('Lockinfo required') try: depth = int(request.META.get('HTTP_DEPTH', '0')) except ValueError: return HttpResponseBadRequest('Wrong depth') try: timeout = int(request.META.get('HTTP_LOCK_TIMEOUT', 'Seconds-600')[len('Seconds-'):]) except ValueError: return HttpResponseBadRequest('Wrong timeout') owner = None try: owner_obj = xbody('/D:lockinfo/D:owner')[0] # TODO: WEBDAV_NS except IndexError: owner_obj = None else: if owner_obj.text: owner = owner_obj.text if len(owner_obj): owner = owner_obj[0].text try: lockscope_obj = xbody('/D:lockinfo/D:lockscope/*')[0] # TODO: WEBDAV_NS except IndexError: return HttpResponseBadRequest('Lock scope required') else: lockscope = lockscope_obj.xpath('local-name()') try: locktype_obj = xbody('/D:lockinfo/D:locktype/*')[0] # TODO: WEBDAV_NS except IndexError: return HttpResponseBadRequest('Lock type required') else: locktype = locktype_obj.xpath('local-name()') token = self.lock_class(self.resource).acquire(lockscope, locktype, depth, timeout, owner) if not token: return HttpResponseLocked('Already locked') body = D.activelock(*([ D.locktype(locktype_obj), D.lockscope(lockscope_obj), D.depth(unicode(depth)), D.timeout("Second-%s" % timeout), D.locktoken(D.href('opaquelocktoken:%s' % token))] + ([owner_obj] if not owner_obj is None else []) )) return HttpResponse(etree.tostring(body, pretty_print=True, xml_declaration=True, encoding='utf-8'), content_type='application/xml')
def proppatch(self, request, path, xbody, *args, **kwargs): if not self.resource.exists: return HttpResponseNotFound() if not self.has_access(self.resource, 'write'): return HttpResponseForbidden() depth = self.get_depth(default="0") if depth != 0: return HttpResponseBadRequest('Invalid depth header value %s' % depth) props = xbody('/D:propertyupdate/D:set/D:prop/*') body = D.multistatus( D.response( D.href(url_join(self.base_url, self.resource.get_escaped_path())), *[D.propstat( D.status('HTTP/1.1 200 OK'), D.prop(el.tag) ) for el in props] ) ) return self.build_xml_response(body, HttpResponseMultiStatus)
def propfind(self, request, path, xbody=None, *args, **kwargs): if not self.has_access(self.resource, 'read'): return HttpResponseForbidden() if not self.resource.exists: return HttpResponseNotFound() if not self.get_access(self.resource): return HttpResponseForbidden() get_all_props, get_prop, get_prop_names = True, False, False if xbody: get_prop = [p.xpath('local-name()') for p in xbody('/D:propfind/D:prop/*')] get_all_props = xbody('/D:propfind/D:allprop') get_prop_names = xbody('/D:propfind/D:propname') if int(bool(get_prop)) + int(bool(get_all_props)) + int(bool(get_prop_names)) != 1: return HttpResponseBadRequest() children = self.resource.get_descendants(depth=self.get_depth(), include_self=True) if get_prop_names: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop(*[ D(name) for name in child.ALL_PROPS ]), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] else: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop( *get_property_tag_list(child, *(get_prop if get_prop else child.ALL_PROPS)) ), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] body = D.multistatus(*responses) response = HttpResponseMultiStatus(etree.tostring(body, pretty_print=True, xml_declaration=True, encoding='utf-8')) return response
def test_propfind_listing(self): self.top_collection.get_descendants.return_value += [self.top_collection] request = Mock(META={}) path = '/collection/' v = DavView(base_url='/base/', path=path, request=request, acl_class=FullAcl, xml_pretty_print=True) v.__dict__['resource'] = self.top_collection resp = v.propfind(request, path, None) self.assertEqual(resp.status_code, 207) self.assertEqual(resp.content, etree.tostring(D.multistatus( D.response( D.href('/base/collection/sub_object'), D.propstat( D.prop( D.getcontentlength("42"), D.creationdate("1983-12-24T06:00:00Z"), D.getlastmodified("Wed, 24 Dec 2014 06:00:00 +0000"), D.resourcetype(), D.displayname("sub_object"), ), D.status("HTTP/1.1 200 OK") ) ), D.response( D.href('/base/collection/sub_colection/'), D.propstat( D.prop( D.getcontentlength("0"), D.creationdate("1983-12-24T06:00:00Z"), D.getlastmodified("Wed, 24 Dec 2014 06:00:00 +0000"), D.resourcetype(D.collection()), D.displayname("sub_colection"), ), D.status("HTTP/1.1 200 OK") ) ), D.response( D.href('/base/collection/'), D.propstat( D.prop( D.getcontentlength("0"), D.creationdate("1983-12-24T06:00:00Z"), D.getlastmodified("Wed, 24 Dec 2014 06:00:00 +0000"), D.resourcetype(D.collection()), D.displayname("collection"), ), D.status("HTTP/1.1 200 OK") ) ), ), pretty_print=True, xml_declaration=True, encoding='utf-8') )
def test_propfind_all_names(self): self.sub_object.get_descendants.return_value += [self.sub_object] request = Mock(META={}) path = 'collection/sub_object' v = DavView(base_url='/base/', path=path, request=request, acl_class=FullAcl, xml_pretty_print=True) v.__dict__['resource'] = self.sub_object resp = v.propfind(request, path, etree.XPathDocumentEvaluator(ElementTree( D.propfind( D.propname() ) ), namespaces=WEBDAV_NSMAP) ) self.assertEqual(resp.status_code, 207) self.assertEqual(resp.content, etree.tostring(D.multistatus( D.response( D.href('/base/collection/sub_object'), D.propstat( D.prop( D.getcontentlength(), D.creationdate(), D.getlastmodified(), D.resourcetype(), D.displayname(), ), D.status("HTTP/1.1 200 OK") ) ), ), pretty_print=True, xml_declaration=True, encoding='utf-8') )
def propfind(self, request, path, xbody=None, *args, **kwargs): if not self.has_access(self.resource, 'read'): return self.no_access() if not self.resource.exists: raise Http404("Resource doesn't exists") if not self.get_access(self.resource): return self.no_access() get_all_props, get_prop, get_prop_names = True, False, False if xbody: get_prop = [ p.xpath('local-name()') for p in xbody('/D:propfind/D:prop/*') ] get_all_props = xbody('/D:propfind/D:allprop') get_prop_names = xbody('/D:propfind/D:propname') if int(bool(get_prop)) + int(bool(get_all_props)) + int( bool(get_prop_names)) != 1: return HttpResponseBadRequest() children = self.resource.get_descendants(depth=self.get_depth()) if get_prop_names: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop(*[D(name) for name in child.ALL_PROPS]), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] else: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop(*get_property_tag_list( child, *( get_prop if get_prop else child.ALL_PROPS))), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] body = D.multistatus(*responses) return self.build_xml_response(body, HttpResponseMultiStatus)
def lock(self, request, path, xbody=None, *args, **kwargs): # TODO Lock refreshing if not self.has_access(self.resource, 'write'): return self.no_access() if not xbody: return HttpResponseBadRequest('Lockinfo required') try: depth = int(request.META.get('HTTP_DEPTH', '0')) except ValueError: return HttpResponseBadRequest('Wrong depth') try: timeout = int( request.META.get('HTTP_LOCK_TIMEOUT', 'Seconds-600')[len('Seconds-'):]) except ValueError: return HttpResponseBadRequest('Wrong timeout') owner = None try: owner_obj = xbody('/D:lockinfo/D:owner')[0] # TODO: WEBDAV_NS except IndexError: owner_obj = None else: if owner_obj.text: owner = owner_obj.text if len(owner_obj): owner = owner_obj[0].text try: lockscope_obj = xbody('/D:lockinfo/D:lockscope/*')[ 0] # TODO: WEBDAV_NS except IndexError: return HttpResponseBadRequest('Lock scope required') else: lockscope = lockscope_obj.xpath('local-name()') try: locktype_obj = xbody('/D:lockinfo/D:locktype/*')[ 0] # TODO: WEBDAV_NS except IndexError: return HttpResponseBadRequest('Lock type required') else: locktype = locktype_obj.xpath('local-name()') token = self.lock_class(self.resource).acquire(lockscope, locktype, depth, timeout, owner) if not token: return HttpResponseLocked('Already locked') body = D.activelock(*([ D.locktype(locktype_obj), D.lockscope(lockscope_obj), D.depth(unicode(depth)), D.timeout("Second-%s" % timeout), D.locktoken(D.href('opaquelocktoken:%s' % token)) ] + ([owner_obj] if not owner_obj is None else []))) return self.build_xml_response(body)
def propfind(self, request, path, xbody=None, *args, **kwargs): if not self.has_access(self.resource, 'read'): return self.no_access() if not self.resource.exists: raise Http404("Resource doesn't exists") if not self.get_access(self.resource): return self.no_access() get_all_props, get_prop, get_prop_names = True, False, False if xbody: get_prop = [p.xpath('local-name()') for p in xbody('/D:propfind/D:prop/*')] get_all_props = xbody('/D:propfind/D:allprop') get_prop_names = xbody('/D:propfind/D:propname') if int(bool(get_prop)) + int(bool(get_all_props)) + int(bool(get_prop_names)) != 1: return HttpResponseBadRequest() children = self.resource.get_descendants(depth=self.get_depth()) if get_prop_names: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop(*[ D(name) for name in child.ALL_PROPS ]), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] else: responses = [ D.response( D.href(url_join(self.base_url, child.get_escaped_path())), D.propstat( D.prop( *get_property_tag_list(child, *(get_prop if get_prop else child.ALL_PROPS)) ), D.status('HTTP/1.1 200 OK'), ), ) for child in children ] body = D.multistatus(*responses) return self.build_xml_response(body, HttpResponseMultiStatus)