Exemple #1
0
    def test_wikiACL(self):
        """
        Ensure shareeAccessControlList( ) honors the access granted by the wiki
        to the sharee, so that delegates of the sharee get the same level of
        access.
        """
        sharedName = yield self.wikiSetup()
        access = WikiAccessLevel.read

        def stubAccessForRecord(*args):
            return succeed(access)

        self.patch(WikiDirectoryRecord, "accessForRecord", stubAccessForRecord)

        request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/")
        collection = yield request.locateResource("/calendars/__uids__/user01/" + sharedName)

        # Simulate the wiki server granting Read access
        acl = (yield collection.shareeAccessControlList(request))
        self.assertFalse("<write/>" in acl.toxml())

        # Simulate the wiki server granting Read-Write access
        access = WikiAccessLevel.write
        acl = (yield collection.shareeAccessControlList(request))
        self.assertTrue("<write/>" in acl.toxml())
def addEventsDir(testCase, eventsDir, uri):
    """
    Add events to a L{twistedcaldav.test.util.TestCase} from a directory.

    @param testCase: The test case to add events to.
    @type testCase: L{twistedcaldav.test.util.TestCase}

    @param eventsDir: A directory full of events.
    @type eventsDir: L{FilePath}

    @param uri: The URI-path of the calendar to insert events into.
    @type uri: C{str}

    @return: a L{Deferred} which fires with the number of added calendar object
        resources.
    """
    count = 0
    for child in eventsDir.children():
        count += 1
        if child.basename().split(".")[-1] != "ics":
            continue
        request = SimpleStoreRequest(testCase, "PUT", uri + "/" + child.basename())
        request.stream = MemoryStream(child.getContent())
        yield testCase.send(request)
    returnValue(count)
Exemple #3
0
    def test_wikiACL(self):
        """
        Ensure shareeAccessControlList( ) honors the access granted by the wiki
        to the sharee, so that delegates of the sharee get the same level of
        access.
        """
        sharedName = yield self.wikiSetup()
        access = WikiAccessLevel.read

        def stubAccessForRecord(*args):
            return succeed(access)

        self.patch(WikiDirectoryRecord, "accessForRecord", stubAccessForRecord)

        request = SimpleStoreRequest(self, "GET",
                                     "/calendars/__uids__/user01/")
        collection = yield request.locateResource(
            "/calendars/__uids__/user01/" + sharedName)

        # Simulate the wiki server granting Read access
        acl = (yield collection.shareeAccessControlList(request))
        self.assertFalse("<write/>" in acl.toxml())

        # Simulate the wiki server granting Read-Write access
        access = WikiAccessLevel.write
        acl = (yield collection.shareeAccessControlList(request))
        self.assertTrue("<write/>" in acl.toxml())
    def test_fail_dot_file_put_in_calendar(self):
        """
        Make (regular) collection in calendar
        """
        calendar_uri = "/calendars/users/wsanchez/dot_file_in_calendar/"
        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authPrincipal=principal)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.CREATED:
            self.fail("MKCALENDAR failed: %s" % (response.code,))

        stream = self.dataPath.child(
            "Holidays").child(
            "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics"
        ).open()
        try:
            calendar = str(Component.fromStream(stream))
        finally:
            stream.close()

        event_uri = "/".join([calendar_uri, ".event.ics"])

        request = SimpleStoreRequest(self, "PUT", event_uri, authPrincipal=principal)
        request.headers.setHeader("content-type", MimeType("text", "calendar"))
        request.stream = MemoryStream(calendar)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.FORBIDDEN:
            self.fail("Incorrect response to dot file PUT: %s" % (response.code,))
    def test_timeoutOnPUT(self):
        """
        PUT gets a 503 on a lock timeout.
        """

        # Create a fake lock
        txn = self.transactionUnderTest()
        yield NamedLock.acquire(txn, "ImplicitUIDLock:%s" % (hashlib.md5("uid1").hexdigest(),))

        # PUT fails
        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(
            self,
            "PUT",
            "/calendars/users/wsanchez/calendar/1.ics",
            headers=Headers({"content-type": MimeType.fromString("text/calendar")}),
            authPrincipal=principal
        )
        request.stream = MemoryStream("""BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
VERSION:2.0
BEGIN:VEVENT
UID:uid1
DTSTART;VALUE=DATE:20020101
DTEND;VALUE=DATE:20020102
DTSTAMP:20020101T121212Z
SUMMARY:New Year's Day
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n"))
        response = yield self.send(request)
        self.assertEqual(response.code, responsecode.SERVICE_UNAVAILABLE)
    def test_set_default_vevent_other(self):
        """
        Test that the default URL can be set to another VEVENT calendar
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property is present
        default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar")

        # Create a new default calendar
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield newcalendar.setSupportedComponents(("VEVENT",))
        yield self.commit()

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        yield inbox.writeProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")), request)

        default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")

        yield self.commit()
Exemple #7
0
def addEventsDir(testCase, eventsDir, uri):
    """
    Add events to a L{twistedcaldav.test.util.TestCase} from a directory.

    @param testCase: The test case to add events to.
    @type testCase: L{twistedcaldav.test.util.TestCase}

    @param eventsDir: A directory full of events.
    @type eventsDir: L{FilePath}

    @param uri: The URI-path of the calendar to insert events into.
    @type uri: C{str}

    @return: a L{Deferred} which fires with the number of added calendar object
        resources.
    """
    count = 0
    for child in eventsDir.children():
        count += 1
        if child.basename().split(".")[-1] != "ics":
            continue
        request = SimpleStoreRequest(testCase, "PUT",
                                     uri + "/" + child.basename())
        request.stream = MemoryStream(child.getContent())
        yield testCase.send(request)
    returnValue(count)
Exemple #8
0
    def test_timeoutOnPUT(self):
        """
        PUT gets a 503 on a lock timeout.
        """

        # Create a fake lock
        txn = self.transactionUnderTest()
        yield NamedLock.acquire(txn, "ImplicitUIDLock:%s" % (hashlib.md5("uid1").hexdigest(),))

        # PUT fails
        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(
            self,
            "PUT",
            "/calendars/users/wsanchez/calendar/1.ics",
            headers=Headers({"content-type": MimeType.fromString("text/calendar")}),
            authPrincipal=principal
        )
        request.stream = MemoryStream("""BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
VERSION:2.0
BEGIN:VEVENT
UID:uid1
DTSTART;VALUE=DATE:20020101
DTEND;VALUE=DATE:20020102
DTSTAMP:20020101T121212Z
SUMMARY:New Year's Day
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n"))
        response = yield self.send(request)
        self.assertEqual(response.code, responsecode.SERVICE_UNAVAILABLE)
    def test_fail_dot_file_put_in_calendar(self):
        """
        Make (regular) collection in calendar
        """
        calendar_uri = "/calendars/users/wsanchez/dot_file_in_calendar/"
        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self,
                                     "MKCALENDAR",
                                     calendar_uri,
                                     authPrincipal=principal)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.CREATED:
            self.fail("MKCALENDAR failed: %s" % (response.code, ))

        stream = self.dataPath.child("Holidays").child(
            "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics").open()
        try:
            calendar = str(Component.fromStream(stream))
        finally:
            stream.close()

        event_uri = "/".join([calendar_uri, ".event.ics"])

        request = SimpleStoreRequest(self,
                                     "PUT",
                                     event_uri,
                                     authPrincipal=principal)
        request.headers.setHeader("content-type", MimeType("text", "calendar"))
        request.stream = MemoryStream(calendar)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.FORBIDDEN:
            self.fail("Incorrect response to dot file PUT: %s" %
                      (response.code, ))
    def test_is_default_calendar(self):
        """
        Test .isDefaultCalendar() returns the proper class or None.
        """

        # Create a new non-default calendar
        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        newcalendar = yield request.locateResource(
            "/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield newcalendar.setSupportedComponents(("VEVENT", ))
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        yield inbox.defaultCalendar(request, "VEVENT")
        yield inbox.defaultCalendar(request, "VTODO")
        yield self.commit()

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        calendar = yield request.locateResource(
            "/calendars/users/wsanchez/calendar")
        newcalendar = yield request.locateResource(
            "/calendars/users/wsanchez/newcalendar")
        tasks = yield request.locateResource("/calendars/users/wsanchez/tasks")

        result = yield calendar.isDefaultCalendar(request)
        self.assertTrue(result)

        result = yield newcalendar.isDefaultCalendar(request)
        self.assertFalse(result)

        result = yield tasks.isDefaultCalendar(request)
        self.assertTrue(result)

        yield self.commit()
    def _test_file_in_calendar(self, what, *work):
        """
        Creates a calendar collection, then PUTs a resource into that collection
        with the data from given stream and verifies that the response code from the
        PUT request matches the given response_code.
        """
        calendar_uri = "/calendars/users/wsanchez/testing_calendar/"

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authPrincipal=principal)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.CREATED:
            self.fail("MKCALENDAR failed: %s" % (response.code,))

        c = 0
        for stream, response_code in work:
            dst_uri = joinURL(calendar_uri, "dst%d.ics" % (c,))
            request = SimpleStoreRequest(self, "PUT", dst_uri, authPrincipal=principal)
            request.headers.setHeader("if-none-match", "*")
            request.headers.setHeader("content-type", MimeType("text", "calendar"))
            request.stream = stream
            response = yield self.send(request)
            response = IResponse(response)

            if response.code != response_code:
                self.fail("Incorrect response to %s: %s (!= %s)" % (what, response.code, response_code))

            c += 1
    def test_missing_default_vtodo_calendar(self):
        """
        Test that readProperty will not create a missing default calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        home = yield request.locateResource("/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property present
        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL,
                                           request)
        self.assertEqual(
            str(default.children[0]),
            "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        # Forcibly remove the one we need
        yield home._newStoreHome.removeChildWithName("tasks")
        names = [
            calendarName
            for calendarName in (yield home._newStoreHome.listCalendars())
        ]
        self.assertTrue("tasks" not in names)

        # Property is empty now
        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL,
                                           request)
        self.assertEqual(len(default.children), 0)

        yield self.abort()
    def test_pick_default_addressbook(self):
        """
        Get adbk
        """

        request = SimpleStoreRequest(self,
                                     "GET",
                                     "/addressbooks/users/wsanchez/",
                                     authPrincipal=self.authPrincipal)
        home = yield request.locateResource("/addressbooks/users/wsanchez")

        # default property initially not present
        try:
            home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            pass
        else:
            self.fail("carddavxml.DefaultAddressBookURL is not empty")

        yield home.pickNewDefaultAddressBook(request)

        try:
            default = home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            self.fail("carddavxml.DefaultAddressBookURL is not present")
        else:
            self.assertEqual(
                str(default.children[0]),
                "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/"
            )
        def mkcalendar_cb(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            def put_cb(response):
                response = IResponse(response)

                if response.code != responsecode.FORBIDDEN:
                    self.fail("Incorrect response to dot file PUT: %s" % (response.code,))

            stream = self.dataPath.child(
                "Holidays").child(
                "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics"
            ).open()
            try:
                calendar = str(Component.fromStream(stream))
            finally:
                stream.close()

            event_uri = "/".join([calendar_uri, ".event.ics"])

            request = SimpleStoreRequest(self, "PUT", event_uri, authid="wsanchez")
            request.headers.setHeader("content-type", MimeType("text", "calendar"))
            request.stream = MemoryStream(calendar)
            return self.send(request, put_cb)
    def test_collection_in_calendar(self):
        """
        Make (regular) collection in calendar
        """
        calendar_uri = "/calendars/users/wsanchez/collection_in_calendar/"

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self,
                                     "MKCALENDAR",
                                     calendar_uri,
                                     authPrincipal=principal)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.CREATED:
            self.fail("MKCALENDAR failed: %s" % (response.code, ))
            nested_uri = joinURL(calendar_uri, "nested")

            request = SimpleStoreRequest(self,
                                         "MKCOL",
                                         nested_uri,
                                         authPrincipal=principal)
            response = yield self.send(request)
            response = IResponse(response)

            if response.code != responsecode.FORBIDDEN:
                self.fail("Incorrect response to nested MKCOL: %s" %
                          (response.code, ))
    def _test_file_in_calendar(self, what, *work):
        """
        Creates a calendar collection, then PUTs a resource into that collection
        with the data from given stream and verifies that the response code from the
        PUT request matches the given response_code.
        """
        calendar_uri = "/calendars/users/wsanchez/testing_calendar/"

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authPrincipal=principal)
        response = yield self.send(request)
        response = IResponse(response)
        if response.code != responsecode.CREATED:
            self.fail("MKCALENDAR failed: %s" % (response.code,))

        c = 0
        for stream, response_code in work:
            dst_uri = joinURL(calendar_uri, "dst%d.ics" % (c,))
            request = SimpleStoreRequest(self, "PUT", dst_uri, authPrincipal=principal)
            request.headers.setHeader("if-none-match", "*")
            request.headers.setHeader("content-type", MimeType("text", "calendar"))
            request.stream = stream
            response = yield self.send(request)
            response = IResponse(response)

            if response.code != response_code:
                self.fail("Incorrect response to %s: %s (!= %s)" % (what, response.code, response_code))

            c += 1
Exemple #17
0
    def calendar_query(self, calendar_uri, query, got_xml, data, no_init):

        if not no_init:
            response = yield self.send(
                SimpleStoreRequest(self,
                                   "MKCALENDAR",
                                   calendar_uri,
                                   authPrincipal=self.authPrincipal))
            response = IResponse(response)
            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code, ))

            if data:
                for filename, icaldata in data.iteritems():
                    request = SimpleStoreRequest(
                        self,
                        "PUT",
                        joinURL(calendar_uri, filename + ".ics"),
                        headers=Headers({
                            "content-type":
                            MimeType.fromString("text/calendar")
                        }),
                        authPrincipal=self.authPrincipal)
                    request.stream = MemoryStream(icaldata)
                    yield self.send(request)
            else:
                # Add holiday events to calendar
                for child in FilePath(self.holidays_dir).children():
                    if os.path.splitext(child.basename())[1] != ".ics":
                        continue
                    request = SimpleStoreRequest(
                        self,
                        "PUT",
                        joinURL(calendar_uri, child.basename()),
                        headers=Headers({
                            "content-type":
                            MimeType.fromString("text/calendar")
                        }),
                        authPrincipal=self.authPrincipal)
                    request.stream = MemoryStream(child.getContent())
                    yield self.send(request)

        request = SimpleStoreRequest(self,
                                     "REPORT",
                                     calendar_uri,
                                     authPrincipal=self.authPrincipal)
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code, ))

        returnValue((yield
                     davXMLFromStream(response.stream).addCallback(got_xml)))
    def test_pick_default_vtodo_calendar(self):
        """
        Test that pickNewDefaultCalendar will choose the correct tasks calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        yield self.abort()
    def test_pick_default_vevent_calendar(self):
        """
        Test that pickNewDefaultCalendar will choose the correct calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property initially present
        prop = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        self.assertEqual(str(prop.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar")

        yield self.abort()
Exemple #20
0
    def requestForPath(self, path, method='GET'):
        """
        Get a L{Request} with a L{FakeChanRequest} for a given path and method.
        """
        headers = Headers()
        headers.addRawHeader("Host", "localhost:8008")
        req = SimpleStoreRequest(self, method, path, headers)

        # 'process()' normally sets these.  Shame on web2, having so much
        # partially-initialized stuff floating around.
        req.remoteAddr = '127.0.0.1'
        req.chanRequest = FakeChanRequest()
        req.credentialFactories = {}
        return req
    def test_is_default_calendar(self):
        """
        Test .isDefaultCalendar() returns the proper class or None.
        """

        # Create a new non-default calendar
        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield newcalendar.setSupportedComponents(("VEVENT",))
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        yield inbox.defaultCalendar(request, "VEVENT")
        yield inbox.defaultCalendar(request, "VTODO")
        yield self.commit()

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        calendar = yield request.locateResource("/calendars/users/wsanchez/calendar")
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        tasks = yield request.locateResource("/calendars/users/wsanchez/tasks")

        result = yield calendar.isDefaultCalendar(request)
        self.assertTrue(result)

        result = yield newcalendar.isDefaultCalendar(request)
        self.assertFalse(result)

        result = yield tasks.isDefaultCalendar(request)
        self.assertTrue(result)

        yield self.commit()
    def requestForPath(self, path, method='GET'):
        """
        Get a L{Request} with a L{FakeChanRequest} for a given path and method.
        """
        headers = Headers()
        headers.addRawHeader("Host", "localhost:8008")
        req = SimpleStoreRequest(self, method, path, headers)

        # 'process()' normally sets these.  Shame on web2, having so much
        # partially-initialized stuff floating around.
        req.remoteAddr = '127.0.0.1'
        req.chanRequest = FakeChanRequest()
        req.credentialFactories = {}
        return req
    def calendar_query(self, query, got_xml):

        request = SimpleStoreRequest(self, "REPORT", "/calendars/users/wsanchez/calendar/", authid="wsanchez")
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code,))

        returnValue(
            (yield davXMLFromStream(response.stream).addCallback(got_xml))
        )
    def test_pick_default_vtodo_calendar(self):
        """
        Test that pickNewDefaultCalendar will choose the correct tasks calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL,
                                           request)
        self.assertEqual(
            str(default.children[0]),
            "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        yield self.abort()
    def test_failedPodChildRetry(self):
        """
        Test that a cross-pod error during an HTTP request results in a 503 error
        with a Retry-After header.
        """

        # Patch request handling to raise an exception
        def _objectResourceWithName(self, name):
            raise FailedCrossPodRequestError()

        self.patch(Calendar, "objectResourceWithName", _objectResourceWithName)

        self.patch(self.store, "timeoutTransactions", 1)

        # Run delayed request
        authPrincipal = yield self.actualRoot.findPrincipalForAuthID("user01")
        request = SimpleStoreRequest(
            self,
            "GET",
            "/calendars/__uids__/user01/calendar/1.ics",
            authPrincipal=authPrincipal)
        try:
            yield self.send(request)
        except HTTPError as e:
            self.assertEqual(e.response.code, responsecode.SERVICE_UNAVAILABLE)
            self.assertTrue(e.response.headers.hasHeader("Retry-After"))
            self.assertApproximates(
                int(e.response.headers.getRawHeaders("Retry-After")[0]),
                config.TransactionHTTPRetrySeconds, 1)
        else:
            self.fail("HTTPError not raised")
    def test_conduitRetry(self):
        """
        Test that a cross-pod error during an HTTP request results in a 503 error
        with a Retry-After header.
        """

        # Patch request handling to raise an exception
        def _iCalendarRolledup(self, request):
            raise FailedCrossPodRequestError()

        self.patch(CalendarCollectionResource, "iCalendarRolledup",
                   _iCalendarRolledup)

        self.patch(self.store, "timeoutTransactions", 1)

        # Run delayed request
        authPrincipal = yield self.actualRoot.findPrincipalForAuthID("user01")
        request = SimpleStoreRequest(self,
                                     "GET",
                                     "/calendars/__uids__/user01/calendar/",
                                     authPrincipal=authPrincipal)
        response = yield self.send(request)
        self.assertEqual(response.code, responsecode.SERVICE_UNAVAILABLE)
        self.assertTrue(response.headers.hasHeader("Retry-After"))
        self.assertApproximates(
            int(response.headers.getRawHeaders("Retry-After")[0]),
            config.TransactionHTTPRetrySeconds, 1)
Exemple #27
0
    def test_inSacls(self):
        """
        Test the behavior of locateChild when SACLs are enabled and the
        user is in the SACL group

        should return a valid resource
        """
        self.actualRoot.useSacls = True

        principal = yield self.actualRoot.findPrincipalForAuthID("dreid")
        request = SimpleStoreRequest(self,
                                     "GET",
                                     "/principals/",
                                     authPrincipal=principal)

        resrc, segments = (yield maybeDeferred(self.actualRoot.locateChild,
                                               request, ["principals"]))

        self.failUnless(
            isinstance(resrc, DirectoryPrincipalProvisioningResource),
            "Did not get a DirectoryPrincipalProvisioningResource: %s" %
            (resrc, ))

        self.assertEquals(segments, [])

        self.assertEquals(
            request.authzUser.principalElement(),
            davxml.Principal(
                davxml.HRef(
                    "/principals/__uids__/5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1/"
                )))
Exemple #28
0
    def test_timeoutRetry(self):
        """
        Test that a timed out transaction during an HTTP request results in a 503 error
        with a Retry-After header.
        """

        # Patch request handling to add a delay to trigger the txn time out
        original = CalendarCollectionResource.iCalendarRolledup

        @inlineCallbacks
        def _iCalendarRolledup(self, request):
            d = Deferred()
            reactor.callLater(2, d.callback, None)
            yield d
            result = yield original(self, request)
            returnValue(result)
        self.patch(CalendarCollectionResource, "iCalendarRolledup", _iCalendarRolledup)

        self.patch(self.store, "timeoutTransactions", 1)

        # Run delayed request
        authPrincipal = yield self.actualRoot.findPrincipalForAuthID("user01")
        request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/calendar/", authPrincipal=authPrincipal)
        try:
            yield self.send(request)
        except HTTPError as e:
            self.assertEqual(e.response.code, responsecode.SERVICE_UNAVAILABLE)
            self.assertTrue(e.response.headers.hasHeader("Retry-After"))
            self.assertApproximates(int(e.response.headers.getRawHeaders("Retry-After")[0]), config.TransactionHTTPRetrySeconds, 1)
        else:
            self.fail("HTTPError not raised")
    def test_notInSacls(self):
        """
        Test the behavior of locateChild when SACLs are enabled and the
        user is not in the SACL group

        should return a 403 forbidden response
        """
        self.actualRoot.useSacls = True

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")

        request = SimpleStoreRequest(
            self,
            "GET",
            "/principals/",
            authPrincipal=principal
        )

        try:
            _ignore_resrc, _ignore_segments = (yield maybeDeferred(
                self.actualRoot.locateChild, request, ["principals"]
            ))
            raise AssertionError(
                "RootResource.locateChild did not return an error"
            )
        except HTTPError, e:
            self.assertEquals(e.response.code, 403)
    def test_make_calendar_in_calendar(self):
        """
        Make calendar in calendar
        """
        first_uri = "/calendars/users/user01/calendar_in_calendar/"

        @inlineCallbacks
        def next(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code, ))

            def do_test(response):
                response = IResponse(response)

                if response.code != responsecode.FORBIDDEN:
                    self.fail("Incorrect response to nested MKCALENDAR: %s" %
                              (response.code, ))

            nested_uri = os.path.join(first_uri, "nested")

            request = SimpleStoreRequest(self,
                                         "MKCALENDAR",
                                         nested_uri,
                                         authPrincipal=self.authPrincipal)
            yield self.send(request, do_test)

        request = SimpleStoreRequest(self,
                                     "MKCALENDAR",
                                     first_uri,
                                     authPrincipal=self.authPrincipal)
        return self.send(request, next)
    def test_make_calendar(self):
        """
        Make calendar
        """
        uri = "/calendars/users/user01/calendar_make/"
        path = os.path.join(self.docroot, uri[1:])

        if os.path.exists(path):
            rmdir(path)

        request = SimpleStoreRequest(self,
                                     "MKCALENDAR",
                                     uri,
                                     authPrincipal=self.authPrincipal)

        @inlineCallbacks
        def do_test(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("Incorrect response to successful MKCALENDAR: %s" %
                          (response.code, ))
            resource = (yield request.locateResource(uri))

            if not resource:
                self.fail("MKCALENDAR made no calendar")

            if not resource.isCalendarCollection():
                self.fail("MKCALENDAR made non-calendar collection")

        return self.send(request, do_test)
    def test_badCredentials(self):
        """
        Test the behavior of locateChild when SACLS are enabled, and
        incorrect credentials are given.

        should return a 401 UnauthorizedResponse
        """
        self.actualRoot.useSacls = True

        request = SimpleStoreRequest(
            self,
            "GET",
            "/principals/",
            headers=http_headers.Headers(
                {
                    "Authorization": [
                        "basic", "%s" % ("dreid:dreid".encode("base64"),)
                    ]
                }
            )
        )

        try:
            _ignore_resrc, _ignore_segments = (yield maybeDeferred(
                self.actualRoot.locateChild, request, ["principals"]
            ))
            raise AssertionError(
                "RootResource.locateChild did not return an error"
            )
        except HTTPError, e:
            self.assertEquals(e.response.code, 401)
    def test_pick_default_vevent_calendar(self):
        """
        Test that pickNewDefaultCalendar will choose the correct calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property initially present
        prop = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL,
                                        request)
        self.assertEqual(
            str(prop.children[0]),
            "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar"
        )

        yield self.abort()
    def calendar_query(self, query, got_xml):

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self,
                                     "REPORT",
                                     "/calendars/users/wsanchez/calendar/",
                                     authPrincipal=principal)
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code, ))

        returnValue((yield
                     davXMLFromStream(response.stream).addCallback(got_xml)))
    def test_PROPFIND(self):
        self.actualRoot.useSacls = True

        body = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
<D:displayname/>
</D:prop>
</D:propfind>
"""
        principal = yield self.actualRoot.findPrincipalForAuthID("dreid")

        request = SimpleStoreRequest(
            self,
            "PROPFIND",
            "/principals/users/dreid/",
            headers=http_headers.Headers({
                'Depth': '1',
            }),
            authPrincipal=principal,
            content=body
        )
        response = yield self.send(request)
        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("Incorrect response for PROPFIND /principals/: %s" % (response.code,))

        request = SimpleStoreRequest(
            self,
            "PROPFIND",
            "/principals/users/dreid/",
            headers=http_headers.Headers({
                'Depth': '1',
            }),
            authPrincipal=principal,
            content=body
        )
        response = yield self.send(request)
        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("Incorrect response for PROPFIND /principals/: %s" % (response.code,))
        self.assertEqual(self.actualRoot.responseCache.cacheHitCount, 1)
    def test_DELETE(self):
        def do_test(response):
            response = IResponse(response)

            if response.code != responsecode.FORBIDDEN:
                self.fail("Incorrect response for DELETE /: %s"
                          % (response.code,))

        request = SimpleStoreRequest(self, "DELETE", "/")
        return self.send(request, do_test)
Exemple #37
0
    def test_oneTime(self):
        """
        Make sure wiki auth lookup is only done once per request;
        request.checkedWiki will be set to True
        """

        request = SimpleStoreRequest(self, "GET", "/principals/")

        _ignore_resrc, _ignore_segments = (yield maybeDeferred(
            self.actualRoot.locateChild, request, ["principals"]))
        self.assertTrue(request.checkedWiki)
    def calendar_query(self, query, got_xml, expected_code=responsecode.MULTI_STATUS):

        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        request = SimpleStoreRequest(self, "REPORT", "/calendars/users/wsanchez/calendar/", authPrincipal=principal)
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != expected_code:
            self.fail("REPORT failed: %s" % (response.code,))

        if got_xml is not None:
            returnValue(
                (yield davXMLFromStream(response.stream).addCallback(got_xml))
            )
        else:
            returnValue(
                (yield allDataFromStream(response.stream))
            )
Exemple #39
0
    def test_POSTShareeRemoveWithMissingSharer(self):

        yield self.resource.upgradeToShare()

        yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
            <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
                <CS:set>
                    <D:href>mailto:[email protected]</D:href>
                    <CS:summary>My Shared Calendar</CS:summary>
                    <CS:read-write/>
                </CS:set>
            </CS:share>
            """)

        propInvite = (yield self.resource.readProperty(customxml.Invite, None))
        uid = self._getUIDElementValue(propInvite)
        self.assertEquals(
            self._clearUIDElementValue(propInvite),
            customxml.Invite(
                customxml.InviteUser(
                    customxml.UID.fromString(""),
                    davxml.HRef.fromString("urn:x-uid:user02"),
                    customxml.CommonName.fromString("User 02"),
                    customxml.InviteAccess(customxml.ReadWriteAccess()),
                    customxml.InviteStatusNoResponse(),
                ), ))

        result = (yield self._doPOSTSharerAccept(
            """<?xml version='1.0' encoding='UTF-8'?>
            <invite-reply xmlns='http://calendarserver.org/ns/'>
              <href xmlns='DAV:'>mailto:[email protected]</href>
              <invite-accepted/>
              <hosturl>
                <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
              </hosturl>
              <in-reply-to>%s</in-reply-to>
              <summary>The Shared Calendar</summary>
              <common-name>User 02</common-name>
              <first-name>user</first-name>
              <last-name>02</last-name>
            </invite-reply>
            """ % (uid, )))
        href = self._getHRefElementValue(result) + "/"

        yield self.directory.removeRecords(
            ((yield self.userUIDFromShortName("user01")), ))
        self.assertTrue((yield self.userUIDFromShortName("user01")) is None)

        resource = (yield self._getResourceSharer(href))
        yield resource.removeShareeResource(
            SimpleStoreRequest(self, "DELETE", href))

        resource = (yield self._getResourceSharer(href))
        self.assertFalse(resource.exists())
    def test_pick_default_other(self):
        """
        Make calendar
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property present
        default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar")

        # Create a new default calendar
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield inbox.writeProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")), request)

        # Delete the normal calendar
        calendar = yield request.locateResource("/calendars/users/wsanchez/calendar")
        yield calendar.storeRemove(request)
        yield self.commit()

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")

        yield self.abort()
    def calendar_query(self, calendar_uri, query, got_xml, data, no_init):

        if not no_init:
            response = yield self.send(SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authid="wsanchez"))
            response = IResponse(response)
            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            if data:
                for filename, icaldata in data.iteritems():
                    request = SimpleStoreRequest(self, "PUT", joinURL(calendar_uri, filename + ".ics"), authid="wsanchez")
                    request.stream = MemoryStream(icaldata)
                    yield self.send(request)
            else:
                # Add holiday events to calendar
                for child in FilePath(self.holidays_dir).children():
                    if os.path.splitext(child.basename())[1] != ".ics":
                        continue
                    request = SimpleStoreRequest(self, "PUT", joinURL(calendar_uri, child.basename()), authid="wsanchez")
                    request.stream = MemoryStream(child.getContent())
                    yield self.send(request)

        request = SimpleStoreRequest(self, "REPORT", calendar_uri, authid="wsanchez")
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code,))

        returnValue(
            (yield davXMLFromStream(response.stream).addCallback(got_xml))
        )
        def mkcalendar_cb(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            c = 0

            for stream, response_code in work:

                dst_uri = joinURL(calendar_uri, "dst%d.ics" % (c,))
                request = SimpleStoreRequest(self, "PUT", dst_uri, authid="wsanchez")
                request.headers.setHeader("if-none-match", "*")
                request.headers.setHeader("content-type", MimeType("text", "calendar"))
                request.stream = stream
                response = yield self.send(request)
                response = IResponse(response)

                if response.code != response_code:
                    self.fail("Incorrect response to %s: %s (!= %s)" % (what, response.code, response_code))

                c += 1
    def addressbook_query(self, addressbook_uri, query, got_xml):
        ''' FIXME: clear address book, possibly by removing
        mkcol = """<?xml version="1.0" encoding="utf-8" ?>
<D:mkcol xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:set>
<D:prop>
<D:resourcetype><D:collection/><C:addressbook/></D:resourcetype>
</D:prop>
</D:set>
</D:mkcol>
"""
        response = yield self.send(SimpleStoreRequest(self, "MKCOL", addressbook_uri, content=mkcol, authid="wsanchez"))

        response = IResponse(response)

        if response.code != responsecode.CREATED:
            self.fail("MKCOL failed: %s" % (response.code,))
        '''
        principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez")
        # Add vCards to addressbook
        for child in FilePath(self.vcards_dir).children():
            if os.path.splitext(child.basename())[1] != ".vcf":
                continue
            request = SimpleStoreRequest(
                self, "PUT", joinURL(addressbook_uri, child.basename()), authPrincipal=principal
            )
            request.stream = MemoryStream(child.getContent())
            yield self.send(request)

        request = SimpleStoreRequest(self, "REPORT", addressbook_uri, authPrincipal=principal)
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code,))

        returnValue((yield davXMLFromStream(response.stream).addCallback(got_xml)))
    def addressbook_query(self, addressbook_uri, query, got_xml, data, no_init):

        if not no_init:
            ''' FIXME: clear address book, possibly by removing
            mkcol = """<?xml version="1.0" encoding="utf-8" ?>
<D:mkcol xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:set>
<D:prop>
<D:resourcetype><D:collection/><C:addressbook/></D:resourcetype>
</D:prop>
</D:set>
</D:mkcol>
"""
            response = yield self.send(SimpleStoreRequest(self, "MKCOL", addressbook_uri, content=mkcol, authPrincipal=self.authPrincipal))

            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCOL failed: %s" % (response.code,))
            '''
            if data:
                for filename, icaldata in data.iteritems():
                    request = SimpleStoreRequest(
                        self,
                        "PUT",
                        joinURL(addressbook_uri, filename + ".vcf"),
                        headers=Headers({"content-type": MimeType.fromString("text/vcard")}),
                        authPrincipal=self.authPrincipal
                    )
                    request.stream = MemoryStream(icaldata)
                    yield self.send(request)
            else:
                # Add vcards to addressbook
                for child in FilePath(self.vcards_dir).children():
                    if os.path.splitext(child.basename())[1] != ".vcf":
                        continue
                    request = SimpleStoreRequest(
                        self,
                        "PUT",
                        joinURL(addressbook_uri, child.basename()),
                        headers=Headers({"content-type": MimeType.fromString("text/vcard")}),
                        authPrincipal=self.authPrincipal
                    )
                    request.stream = MemoryStream(child.getContent())
                    yield self.send(request)

        request = SimpleStoreRequest(self, "REPORT", addressbook_uri, authPrincipal=self.authPrincipal)
        request.stream = MemoryStream(query.toxml())
        response = yield self.send(request)

        response = IResponse(response)

        if response.code != responsecode.MULTI_STATUS:
            self.fail("REPORT failed: %s" % (response.code,))

        returnValue(
            (yield davXMLFromStream(response.stream).addCallback(got_xml))
        )
    def test_missing_default_vtodo_calendar(self):
        """
        Test that readProperty will not create a missing default calendar.
        """

        request = SimpleStoreRequest(self, "GET", "/calendars/users/wsanchez/")
        home = yield request.locateResource("/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property present
        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL, request)
        self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        # Forcibly remove the one we need
        yield home._newStoreHome.removeChildWithName("tasks")
        names = [calendarName for calendarName in (yield home._newStoreHome.listCalendars())]
        self.assertTrue("tasks" not in names)

        # Property is empty now
        default = yield inbox.readProperty(customxml.ScheduleDefaultTasksURL, request)
        self.assertEqual(len(default.children), 0)

        yield self.abort()
Exemple #46
0
    def test_MOVE(self):
        def do_test(response):
            response = IResponse(response)

            if response.code != responsecode.FORBIDDEN:
                self.fail("Incorrect response for MOVE /: %s" %
                          (response.code, ))

        request = SimpleStoreRequest(self,
                                     "MOVE",
                                     "/",
                                     headers=http_headers.Headers(
                                         {"Destination": "/copy/"}))
        return self.send(request, do_test)
Exemple #47
0
    def issueRequest(self, segments, method="GET"):
        """
        Get a resource from a particular path from the root URI, and return a
        Deferred which will fire with (something adaptable to) an HTTP response
        object.
        """
        request = SimpleStoreRequest(self, method, ("/".join([""] + segments)))
        rsrc = self.actualRoot
        while segments:
            rsrc, segments = (yield maybeDeferred(rsrc.locateChild, request,
                                                  segments))

        result = yield rsrc.renderHTTP(request)
        returnValue(result)
    def test_wikiACL(self):
        """
        Ensure shareeAccessControlList( ) honors the access granted by the wiki
        to the sharee, so that delegates of the sharee get the same level of
        access.
        """

        access = "read"
        def stubWikiAccessMethod(userID, wikiID):
            return access
        self.patch(sharing, "getWikiAccess", stubWikiAccessMethod)

        sharedName = yield self.wikiSetup()
        request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/")
        collection = yield request.locateResource("/calendars/__uids__/user01/" + sharedName)

        # Simulate the wiki server granting Read access
        acl = (yield collection.shareeAccessControlList(request))
        self.assertFalse("<write/>" in acl.toxml())

        # Simulate the wiki server granting Read-Write access
        access = "write"
        acl = (yield collection.shareeAccessControlList(request))
        self.assertTrue("<write/>" in acl.toxml())
Exemple #49
0
    def test_pick_default_addressbook(self):
        """
        Get adbk
        """

        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authPrincipal=self.authPrincipal)
        home = yield request.locateResource("/addressbooks/users/wsanchez")

        # default property initially not present
        try:
            home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            pass
        else:
            self.fail("carddavxml.DefaultAddressBookURL is not empty")

        yield home.pickNewDefaultAddressBook(request)

        try:
            default = home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            self.fail("carddavxml.DefaultAddressBookURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/")
Exemple #50
0
    def test_make_calendar_on_collection(self):
        """
        Make calendar on existing collection
        """
        uri = "/calendars/users/user01/calendar/"

        def do_test(response):
            response = IResponse(response)

            if response.code != responsecode.FORBIDDEN:
                self.fail("Incorrect response to MKCALENDAR on existing resource: %s" % (response.code,))

            # FIXME: Check for DAV:resource-must-be-null element

        request = SimpleStoreRequest(self, "MKCALENDAR", uri, authPrincipal=self.authPrincipal)
        return self.send(request, do_test)
Exemple #51
0
        def next(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            def do_test(response):
                response = IResponse(response)

                if response.code != responsecode.FORBIDDEN:
                    self.fail("Incorrect response to nested MKCALENDAR: %s" % (response.code,))

            nested_uri = os.path.join(first_uri, "nested")

            request = SimpleStoreRequest(self, "MKCALENDAR", nested_uri, authPrincipal=self.authPrincipal)
            yield self.send(request, do_test)
Exemple #52
0
 def _getResourceSharer(self, name):
     request = SimpleStoreRequest(self, "GET", "%s" % (name,))
     resource = yield request.locateResource("%s" % (name,))
     returnValue(resource)
Exemple #53
0
        def mkcalendar_cb(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            def propfind_cb(response):
                response = IResponse(response)

                if response.code != responsecode.MULTI_STATUS:
                    self.fail("Incorrect response to PROPFIND: %s" % (response.code,))

                def got_xml(doc):
                    if not isinstance(doc.root_element, davxml.MultiStatus):
                        self.fail("PROPFIND response XML root element is not multistatus: %r" % (doc.root_element,))

                    response = doc.root_element.childOfType(davxml.Response)
                    href = response.childOfType(davxml.HRef)
                    self.failUnless(str(href) == calendar_uri)

                    for propstat in response.childrenOfType(davxml.PropertyStatus):
                        status = propstat.childOfType(davxml.Status)
                        if status.code != responsecode.OK:
                            self.fail("Unable to read requested properties (%s): %r"
                                      % (status, propstat.childOfType(davxml.PropertyContainer).toxml()))

                    container = propstat.childOfType(davxml.PropertyContainer)

                    #
                    # Check CalDAV:supported-calendar-component-set
                    #

                    supported_components = container.childOfType(caldavxml.SupportedCalendarComponentSet)
                    if not supported_components:
                        self.fail("Expected CalDAV:supported-calendar-component-set element; but got none.")

                    supported = set(("VEVENT",))

                    for component in supported_components.children:
                        if component.type in supported:
                            supported.remove(component.type)

                    if supported:
                        self.fail("Expected supported calendar component types: %s" % (tuple(supported),))

                    #
                    # Check CalDAV:supported-calendar-data
                    #

                    supported_calendar = container.childOfType(caldavxml.SupportedCalendarData)
                    if not supported_calendar:
                        self.fail("Expected CalDAV:supported-calendar-data element; but got none.")

                    for calendar in supported_calendar.children:
                        if calendar.content_type not in ("text/calendar", "application/calendar+json"):
                            self.fail("Expected a text/calendar calendar-data type restriction")
                        if calendar.version != "2.0":
                            self.fail("Expected a version 2.0 calendar-data restriction")

                    #
                    # Check DAV:supported-report-set
                    #

                    supported_reports = container.childOfType(davxml.SupportedReportSet)
                    if not supported_reports:
                        self.fail("Expected DAV:supported-report-set element; but got none.")

                    cal_query = False
                    cal_multiget = False
                    cal_freebusy = False
                    for supported in supported_reports.childrenOfType(davxml.SupportedReport):
                        report = supported.childOfType(davxml.Report)
                        if report.childOfType(caldavxml.CalendarQuery) is not None:
                            cal_query = True
                        if report.childOfType(caldavxml.CalendarMultiGet) is not None:
                            cal_multiget = True
                        if report.childOfType(caldavxml.FreeBusyQuery) is not None:
                            cal_freebusy = True

                    if not cal_query:
                        self.fail("Expected CalDAV:CalendarQuery element; but got none.")
                    if not cal_multiget:
                        self.fail("Expected CalDAV:CalendarMultiGet element; but got none.")
                    if not cal_freebusy:
                        self.fail("Expected CalDAV:FreeBusyQuery element; but got none.")

                return davXMLFromStream(response.stream).addCallback(got_xml)

            query = davxml.PropertyFind(
                davxml.PropertyContainer(
                    caldavxml.SupportedCalendarData(),
                    caldavxml.SupportedCalendarComponentSet(),
                    davxml.SupportedReportSet(),
                ),
            )

            request = SimpleStoreRequest(
                self,
                "PROPFIND",
                calendar_uri,
                headers=http_headers.Headers({"Depth": "0"}),
                authPrincipal=self.authPrincipal,
            )
            request.stream = MemoryStream(query.toxml())
            return self.send(request, propfind_cb)
Exemple #54
0
        def mkcalendar_cb(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            def propfind_cb(response):
                response = IResponse(response)

                if response.code != responsecode.MULTI_STATUS:
                    self.fail("Incorrect response to PROPFIND: %s" % (response.code,))

                def got_xml(doc):
                    if not isinstance(doc.root_element, davxml.MultiStatus):
                        self.fail("PROPFIND response XML root element is not multistatus: %r" % (doc.root_element,))

                    response = doc.root_element.childOfType(davxml.Response)
                    href = response.childOfType(davxml.HRef)
                    self.failUnless(str(href) == calendar_uri)

                    container = response.childOfType(davxml.PropertyStatus).childOfType(davxml.PropertyContainer)

                    #
                    # Check CalDAV:supported-calendar-component-set
                    #

                    supported_components = container.childOfType(caldavxml.SupportedCalendarComponentSet)
                    if supported_components:
                        self.fail("CalDAV:supported-calendar-component-set element was returned; but should be hidden.")

                    #
                    # Check CalDAV:supported-calendar-data
                    #

                    supported_calendar = container.childOfType(caldavxml.SupportedCalendarData)
                    if supported_calendar:
                        self.fail("CalDAV:supported-calendar-data elementwas returned; but should be hidden.")

                    #
                    # Check DAV:supported-report-set
                    #

                    supported_reports = container.childOfType(davxml.SupportedReportSet)
                    if supported_reports:
                        self.fail("DAV:supported-report-set element was returned; but should be hidden..")

                return davXMLFromStream(response.stream).addCallback(got_xml)

            query = davxml.PropertyFind(
                davxml.AllProperties(),
            )

            request = SimpleStoreRequest(
                self,
                "PROPFIND",
                calendar_uri,
                headers=http_headers.Headers({"Depth": "0"}),
                authPrincipal=self.authPrincipal,
            )
            request.stream = MemoryStream(query.toxml())
            return self.send(request, propfind_cb)
Exemple #55
0
 def _getResource(self):
     request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/calendar/")
     resource = yield request.locateResource("/calendars/__uids__/user01/calendar/")
     returnValue(resource)
    def test_make_calendar_with_props(self):
        """
        Make calendar with properties (CalDAV-access-09, section 5.3.1.2)
        """
        uri = "/calendars/users/user01/calendar_prop/"
        path = os.path.join(self.docroot, uri[1:])

        if os.path.exists(path):
            rmdir(path)

        @inlineCallbacks
        def do_test(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("MKCALENDAR failed: %s" % (response.code,))

            resource = (yield request.locateResource(uri))
            if not resource.isCalendarCollection():
                self.fail("MKCALENDAR made non-calendar collection")

            for qname, value in (
                (davxml.DisplayName.qname(), "Lisa's Events"),
                (caldavxml.CalendarDescription.qname(), "Calendar restricted to events."),
            ):
                stored = yield resource.readProperty(qname, None)
                stored = str(stored)
                if stored != value:
                    self.fail("MKCALENDAR failed to set property %s: %s != %s"
                              % (qname, stored, value))

            supported_components = yield resource.readProperty(caldavxml.SupportedCalendarComponentSet, None)
            supported_components = supported_components.children
            if len(supported_components) != 1:
                self.fail("MKCALENDAR failed to set property %s: len(%s) != 1"
                          % (caldavxml.SupportedCalendarComponentSet.qname(), supported_components))
            if supported_components[0] != caldavxml.CalendarComponent(name="VEVENT"):
                self.fail("MKCALENDAR failed to set property %s: %s != %s"
                          % (caldavxml.SupportedCalendarComponentSet.qname(),
                             supported_components[0].toxml(), caldavxml.CalendarComponent(name="VEVENT").toxml()))

            tz = (yield resource.readProperty(caldavxml.CalendarTimeZone, None))
            tz = tz.calendar()
            self.failUnless(tz.resourceType() == "VTIMEZONE")
            self.failUnless(tuple(tz.subcomponents())[0].propertyValue("TZID") == "US-Eastern")

        mk = caldavxml.MakeCalendar(
            davxml.Set(
                davxml.PropertyContainer(
                    davxml.DisplayName("Lisa's Events"),
                    caldavxml.CalendarDescription("Calendar restricted to events."), # FIXME: lang=en
                    caldavxml.SupportedCalendarComponentSet(caldavxml.CalendarComponent(name="VEVENT")),
                    caldavxml.CalendarTimeZone(
                        """BEGIN:VCALENDAR
PRODID:-//Example Corp.//CalDAV Client//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:US-Eastern
LAST-MODIFIED:19870101T000000Z
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:Eastern Standard Time (US & Canada)
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:Eastern Daylight Time (US & Canada)
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR
"""
                    )
                )
            )
        )

        request = SimpleStoreRequest(self, "MKCALENDAR", uri, authPrincipal=self.authPrincipal)
        request.stream = MemoryStream(mk.toxml())
        return self.send(request, do_test)