def testCollectionAccessSuperUser(self): # super user accessing (non-)shared res from nu parentColl = '/SOGo/dav/%s/Calendar/' % subscriber_username self.createdRsrc = '%stest-dav-acl/' % parentColl for rsrc in ['personal', 'test-dav-acl']: resource = '%s%s/' % (parentColl, rsrc) mkcol = webdavlib.WebDAVMKCOL(resource) self.superuser_client.execute(mkcol) acl_utility = utilities.TestCalendarACLUtility( self, self.subscriber_client, resource) acl_utility.setupRights(username, {}) propfind = webdavlib.WebDAVPROPFIND(parentColl, ["displayname"], 1) self.subscriber_client.execute(propfind) hrefs = [x.text \ for x in propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href")] self.assertTrue( len(hrefs) > 2, "expected at least 3 hrefs in response") self.assertEquals(hrefs[0], parentColl, "the href must be the 'Calendar' parent coll.") for rsrc in ['personal', 'test-dav-acl']: resource = '%s%s/' % (parentColl, rsrc) self.assertTrue( hrefs.index(resource) > -1, "resource '%s' not returned" % resource)
def _propfindEvent(self): propfind = webdavlib.WebDAVPROPFIND( self.resource, ["{urn:ietf:params:xml:ns:caldav}calendar-data"], 1) self.client.execute(propfind) if propfind.response["status"] != 404: event = self._calendarDataInMultistatus(propfind) return event
def _propfindEvent(self, event_class): event = None icsClass = self.classToICSClass[event_class] filename = "%s-event.ics" % icsClass.lower() propfind = webdavlib.WebDAVPROPFIND( self.resource, ["{urn:ietf:params:xml:ns:caldav}calendar-data"], 1) self.subscriber_client.execute(propfind) if propfind.response["status"] != 404: event = self._calendarDataInMultistatus(propfind, filename) return event
def fetchUserEmail(login): client = webdavlib.WebDAVClient(hostname, port, username, password) resource = '/SOGo/dav/%s/' % login propfind = webdavlib.WebDAVPROPFIND(resource, ["{urn:ietf:params:xml:ns:caldav}calendar-user-address-set"], 0) client.execute(propfind) nodes = propfind.xpath_evaluate('{DAV:}response/{DAV:}propstat/{DAV:}prop/C:calendar-user-address-set/{DAV:}href', None) return nodes[0].childNodes[0].nodeValue
def _getAllEvents(self, client, collection, exp_status=207): propfind = webdavlib.WebDAVPROPFIND(collection, None) client.execute(propfind) if exp_status is not None: self.assertEquals(propfind.response["status"], exp_status) content = [] nodes = propfind.response["document"].findall('{DAV:}response') for node in nodes: responseHref = node.find('{DAV:}href').text content += [responseHref] return content
def _getProxyFor(self, user, perm): resource = '/SOGo/dav/%s/' % user prop = "{http://calendarserver.org/ns/}calendar-proxy-%s-for" % perm propfind = webdavlib.WebDAVPROPFIND(resource, [prop], 0) client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password) client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)" client.execute(propfind) hrefs = propfind.response["document"].findall( "{DAV:}response/{DAV:}propstat/{DAV:}prop/{http://calendarserver.org/ns/}calendar-proxy-%s-for/{DAV:}href" % perm) members = [x.text[len("/SOGo/dav/"):-1] for x in hrefs] return members
def testPrincipalCollectionSet(self): """principal-collection-set: 'DAV' header must be returned with iCal 4""" client = webdavlib.WebDAVClient(hostname, port, username, password) resource = '/SOGo/dav/%s/' % username # NOT iCal4 propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}principal-collection-set"], 0) client.execute(propfind) self.assertEquals(propfind.response["status"], 207) headers = propfind.response["headers"] self.assertFalse( headers.has_key("dav"), "DAV header must not be returned when user-agent is NOT iCal 4") # iCal4 propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}principal-collection-set"], 0) client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)" client.execute(propfind) self.assertEquals(propfind.response["status"], 207) headers = propfind.response["headers"] self.assertTrue( headers.has_key("dav"), "DAV header must be returned when user-agent is iCal 4") expectedDAVClasses = [ "1", "2", "access-control", "calendar-access", "calendar-schedule", "calendar-auto-schedule", "calendar-proxy" ] davClasses = [x.strip() for x in headers["dav"].split(",")] for davClass in expectedDAVClasses: self.assertTrue(davClass in davClasses, "DAV class '%s' not found" % davClass)
def _getMembership(self, user): resource = '/SOGo/dav/%s/' % user propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}group-membership"], 0) client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password) client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)" client.execute(propfind) hrefs = propfind.response["document"].findall( "{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}group-membership/{DAV:}href" ) members = [x.text for x in hrefs] return members
def _currentUserPrivilegeSet(self, resource, expStatus = 207): propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}current-user-privilege-set"], 0) self.subscriber_client.execute(propfind) self.assertEquals(propfind.response["status"], expStatus, "unexected status code when reading privileges:" + " %s instead of %d" % (propfind.response["status"], expStatus)) privileges = [] if expStatus < 300: response_nodes = propfind.response["document"].findall("{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}current-user-privilege-set/{DAV:}privilege") for node in response_nodes: privileges.extend([x.tag for x in node.getchildren()]) return privileges
def _getClassification(self, user, component): resource = '/SOGo/dav/%s/Calendar/' % user property_name = "{urn:inverse:params:xml:ns:inverse-dav}%s-default-classification" % component propfind = webdavlib.WebDAVPROPFIND(resource, [property_name], "0") client = webdavlib.WebDAVClient(hostname, port, username, password) client.execute(propfind) classification = None propstat_nodes = propfind.response["document"].findall( "{DAV:}response/{DAV:}propstat") for propstat_node in propstat_nodes: status_nodes = propstat_node.findall("{DAV:}status") if status_nodes[0].text.lower() == "http/1.1 200 ok": property_nodes = propstat_node.findall("{DAV:}prop/%s" % property_name) if len(property_nodes) > 0: classification = property_nodes[0].text return classification
def testPrincipalCollectionSet(self): """property: 'principal-collection-set' on collection object""" resource = '/SOGo/dav/%s/' % username propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}principal-collection-set"], 0) self.client.execute(propfind) self.assertEquals(propfind.response["status"], 207) nodes = propfind.response["document"] \ .findall('{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}principal-collection-set/{DAV:}href') responseHref = nodes[0].text if responseHref[0:4] == "http": self.assertEquals("http://%s/SOGo/dav/" % hostname, responseHref, "{DAV:}principal-collection-set returned %s instead of 'http../SOGo/dav/'" % ( responseHref, resource )) else: self.assertEquals("/SOGo/dav/", responseHref, "{DAV:}principal-collection-set returned %s instead of '/SOGo/dav/'" % responseHref)
def getAllCollections(client, uri): collections = [] depth = 1 propfind = webdavlib.WebDAVPROPFIND(uri, ["allprop"], depth) client.execute(propfind) client.conn.close() doc = propfind.response["document"] for response in doc.iter("{DAV:}response"): propstat = response.find("{DAV:}propstat") if propstat is not None: prop = propstat.find("{DAV:}prop") if prop is not None: resourcetype = prop.find("{DAV:}resourcetype") if resourcetype.find("{DAV:}collection") is not None: href = prop.find("{DAV:}href") if href is not None and href.text != uri: collections.append(href.text) return collections
def testPrincipalCollectionSet2(self): """property: 'principal-collection-set' on non-collection object""" resource = '/SOGo/dav/%s/freebusy.ifb' % username propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}principal-collection-set"], 0) self.client.execute(propfind) self.assertEquals(propfind.response["status"], 207) node = propfind.response["document"] \ .find('{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}principal-collection-set/{DAV:}href') responseHref = node.text expectedHref = '/SOGo/dav/' if responseHref[0:4] == "http": self.assertEquals("http://%s%s" % (hostname, expectedHref), responseHref, "{DAV:}principal-collection-set returned %s instead of '%s'" % ( responseHref, expectedHref )) else: self.assertEquals(expectedHref, responseHref, "{DAV:}principal-collection-set returned %s instead of '%s'" % ( responseHref, expectedHref ))
def _testProperty (self, url, property, expected, isDate = 0): propfind = webdavlib.WebDAVPROPFIND(url, (property, ), 0) self.client.execute(propfind) key = property.replace("{urn:schemas:httpmail:}", "a:") key = key.replace("{urn:schemas:mailheader:}", "a:") tmp = propfind.xpath_evaluate("{DAV:}response/{DAV:}propstat/{DAV:}prop") prop = tmp[0].firstChild; result = None if prop: result = prop._get_firstChild()._get_nodeValue() #print key, result if isDate: tstruct = time.strptime (result, "%a, %d %b %Y %H:%M:%S %Z") result = int (time.mktime (tstruct)) self.assertEquals(result, expected, "failure in propfind" "(%s != %s)" % (result, expected))
def _testPropfindURL(self, resource): resourceWithSlash = resource[-1] == '/' propfind = webdavlib.WebDAVPROPFIND(resource, ["{DAV:}displayname", "{DAV:}resourcetype"], 1) self.client.execute(propfind) self.assertEquals(propfind.response["status"], 207) nodes = propfind.response["document"].findall('{DAV:}response') for node in nodes: responseHref = node.find('{DAV:}href').text hasSlash = responseHref[-1] == '/' resourcetype = node.find('{DAV:}propstat/{DAV:}prop/{DAV:}resourcetype') isCollection = len(resourcetype.getchildren()) > 0 if isCollection: self.assertEquals(hasSlash, resourceWithSlash, "failure with href '%s' while querying '%s'" % (responseHref, resource)) else: self.assertEquals(hasSlash, False, "failure with href '%s' while querying '%s'" % (responseHref, resource))
def _getCategories(self, user): resource = '/SOGo/dav/%s/Contacts/' % user props = ["{urn:inverse:params:xml:ns:inverse-dav}contacts-categories"] propfind = webdavlib.WebDAVPROPFIND(resource, props, "0") client = webdavlib.WebDAVClient(hostname, port, username, password) client.execute(propfind) self.assertEquals( propfind.response["status"], 207, "failure (%s) getting categories on %s's contacts" % (propfind.response["status"], user)) categories = [] prop_nodes = propfind.response["document"].findall( "{DAV:}response/{DAV:}propstat/{DAV:}prop/{urn:inverse:params:xml:ns:inverse-dav}contacts-categories" ) for prop_node in prop_nodes: cat_nodes = prop_node.findall( "{urn:inverse:params:xml:ns:inverse-dav}category") if cat_nodes is not None: for cat_node in cat_nodes: categories.append(cat_node.text) return categories
def fetchUserInfo(self, login): if not self.userInfo.has_key(login): resource = "/SOGo/dav/%s/" % login propfind = webdavlib.WebDAVPROPFIND(resource, [ "displayname", "{urn:ietf:params:xml:ns:caldav}calendar-user-address-set" ], 0) self.client.execute(propfind) self.test.assertEquals(propfind.response["status"], 207) common_tree = "{DAV:}response/{DAV:}propstat/{DAV:}prop" name_nodes = propfind.response["document"] \ .findall('%s/{DAV:}displayname' % common_tree) email_nodes = propfind.response["document"] \ .findall('%s/{urn:ietf:params:xml:ns:caldav}calendar-user-address-set/{DAV:}href' % common_tree) if len(name_nodes[0].text) > 0: displayName = name_nodes[0].text else: displayName = "" self.userInfo[login] = (displayName, email_nodes[0].text) return self.userInfo[login]
def testDavScheduleCalendarTransparency(self): """{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp""" ## PROPFIND propfind = webdavlib.WebDAVPROPFIND( self.test_calendar, ["{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp"], 0) self.client.execute(propfind) response = propfind.response["document"].find('{DAV:}response') propstat = response.find('{DAV:}propstat') status = propstat.find('{DAV:}status').text[9:12] self.assertEquals( status, "200", "schedule-calendar-transp marked as 'Not Found' in response") transp = propstat.find( '{DAV:}prop/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' ) values = transp.getchildren() self.assertEquals(len(values), 1, "one and only one element expected") value = values[0] self.assertTrue(xml.etree.ElementTree.iselement(value)) ns = value.tag[0:31] tag = value.tag[31:] self.assertTrue(ns == "{urn:ietf:params:xml:ns:caldav}", "schedule-calendar-transp must have a value in"\ " namespace '%s', not '%s'" % ("urn:ietf:params:xml:ns:caldav", ns)) self.assertTrue(tag == "opaque", "schedule-calendar-transp must be 'opaque' on new" \ " collections, not '%s'" % tag) ## PROPPATCH newValueNode = "{urn:ietf:params:xml:ns:caldav}thisvaluedoesnotexist" proppatch = webdavlib.WebDAVPROPPATCH(self.test_calendar, {"{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp": \ { newValueNode: True }}) self.client.execute(proppatch) self.assertEquals(proppatch.response["status"], 400, "expecting failure when setting transparency to" \ " an invalid value") newValueNode = "{urn:ietf:params:xml:ns:caldav}transparent" proppatch = webdavlib.WebDAVPROPPATCH(self.test_calendar, {"{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp": \ { newValueNode: True }}) self.client.execute(proppatch) self.assertEquals(proppatch.response["status"], 207, "failure (%s) setting transparency to" \ " 'transparent': '%s'" % (proppatch.response["status"], proppatch.response["body"])) newValueNode = "{urn:ietf:params:xml:ns:caldav}opaque" proppatch = webdavlib.WebDAVPROPPATCH(self.test_calendar, {"{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp": \ { newValueNode: True }}) self.client.execute(proppatch) self.assertEquals(proppatch.response["status"], 207, "failure (%s) setting transparency to" \ " 'transparent': '%s'" % (proppatch.response["status"], proppatch.response["body"]))
if (pair[0] == "-d" or pair[0] == "--depth"): depth = pair[1] elif (pair[0] == "-q" or pair[0] == "--quiet"): quiet = True # print "depth: " + depth nargs = len(args) if (nargs > 0): resource = args[0] if (nargs > 1): properties = args[1:] else: properties = ["allprop"] else: print "resource required" sys.exit(-1) client = webdavlib.WebDAVClient(hostname, port, username, password) propfind = webdavlib.WebDAVPROPFIND(resource, properties, depth) client.execute(propfind) sys.stderr.write("response:\n\n") print propfind.response["body"] if propfind.response.has_key("document"): sys.stderr.write("document tree:\n") elem = propfind.response["document"] dom = xml.dom.minidom.parseString(xml.etree.ElementTree.tostring(elem)) print dom.toprettyxml()
def testCollectionAccessNormalUser(self): """normal user access to (non-)shared resource from su""" # 1. all rights removed parentColl = '/SOGo/dav/%s/Calendar/' % username self.createdRsrc = '%stest-dav-acl/' % parentColl for rsrc in ['personal', 'test-dav-acl']: resource = '%s%s/' % (parentColl, rsrc) mkcol = webdavlib.WebDAVMKCOL(resource) self.client.execute(mkcol) acl_utility = utilities.TestCalendarACLUtility( self, self.client, resource) acl_utility.setupRights("anonymous", {}) acl_utility.setupRights(subscriber_username, {}) acl_utility.setupRights("<default>", {}) propfind = webdavlib.WebDAVPROPFIND(parentColl, ["displayname"], 1) self.subscriber_client.execute(propfind) hrefs = propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href") self.assertEquals( len(hrefs), 1, "expected 1 href in response instead of %d" % len(hrefs)) self.assertEquals(hrefs[0].text, parentColl, "the href must be the 'Calendar' parent coll.") acl_utility = utilities.TestCalendarACLUtility(self, self.client, self.createdRsrc) # 2. creation right added acl_utility.setupRights(subscriber_username, {"c": True}) self.subscriber_client.execute(propfind) hrefs = propfind.response["document"].findall( "{DAV:}response/{DAV:}href") self.assertEquals( len(hrefs), 4, "expected 4 hrefs in response, got %d: %s" % (len(hrefs), ", ".join([x.text for x in hrefs]))) self.assertEquals(hrefs[0].text, parentColl, "the first href is not a 'Calendar' parent coll.") resourceHrefs = { resource: False, "%s.xml" % resource[:-1]: False, "%s.ics" % resource[:-1]: False } for href in hrefs[1:]: self.assertTrue(resourceHrefs.has_key(href.text), "received unexpected href: %s" % href.text) self.assertFalse( resourceHrefs[href.text], "href was returned more than once: %s" % href.text) resourceHrefs[href.text] = True acl_utility.setupRights(subscriber_username) # 3. creation right added for "default user" # subscriber_username expected to have access, but not "anonymous" acl_utility.setupRights("<default>", {"c": True}) self.subscriber_client.execute(propfind) hrefs = propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href") self.assertEquals( len(hrefs), 4, "expected 4 hrefs in response, got %d: %s" % (len(hrefs), ", ".join([x.text for x in hrefs]))) self.assertEquals(hrefs[0].text, parentColl, "the first href is not a 'Calendar' parent coll.") resourceHrefs = { resource: False, "%s.xml" % resource[:-1]: False, "%s.ics" % resource[:-1]: False } for href in hrefs[1:]: self.assertTrue(resourceHrefs.has_key(href.text), "received unexpected href: %s" % href.text) self.assertFalse( resourceHrefs[href.text], "href was returned more than once: %s" % href.text) resourceHrefs[href.text] = True anonParentColl = '/SOGo/dav/public/%s/Calendar/' % username anon_propfind = webdavlib.WebDAVPROPFIND(anonParentColl, ["displayname"], 1) self.anon_client.execute(anon_propfind) hrefs = anon_propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href") self.assertEquals(len(hrefs), 1, "expected only 1 href in response") self.assertEquals(hrefs[0].text, anonParentColl, "the first href is not a 'Calendar' parent coll.") acl_utility.setupRights("<default>", {}) # 4. creation right added for "anonymous" # "anonymous" expected to have access, but not subscriber_username acl_utility.setupRights("anonymous", {"c": True}) self.anon_client.execute(anon_propfind) hrefs = anon_propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href") self.assertEquals( len(hrefs), 4, "expected 4 hrefs in response, got %d: %s" % (len(hrefs), ", ".join([x.text for x in hrefs]))) self.assertEquals(hrefs[0].text, anonParentColl, "the first href is not a 'Calendar' parent coll.") anonResource = '%stest-dav-acl/' % anonParentColl resourceHrefs = { anonResource: False, "%s.xml" % anonResource[:-1]: False, "%s.ics" % anonResource[:-1]: False } for href in hrefs[1:]: self.assertTrue(resourceHrefs.has_key(href.text), "received unexpected href: %s" % href.text) self.assertFalse( resourceHrefs[href.text], "href was returned more than once: %s" % href.text) resourceHrefs[href.text] = True self.subscriber_client.execute(propfind) hrefs = propfind.response["document"] \ .findall("{DAV:}response/{DAV:}href") self.assertEquals(len(hrefs), 1, "expected only 1 href in response") self.assertEquals(hrefs[0].text, parentColl, "the first href is not a 'Calendar' parent coll.")