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, authid="user01")

        @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)
Exemplo n.º 2
0
    def upgradeCalendarHome(homePath, directory):

        errorOccurred = False

        log.debug("Upgrading calendar home: %s" % (homePath,))

        try:
            for cal in os.listdir(homePath):
                calPath = os.path.join(homePath, cal)
                if not os.path.isdir(calPath):
                    # Skip non-directories; these might have been uploaded by a
                    # random DAV client, they can't be calendar collections.
                    continue
                if cal == 'notifications':
                    # Delete the old, now obsolete, notifications directory.
                    rmdir(calPath)
                    continue
                log.debug("Upgrading calendar: %s" % (calPath,))
                if not upgradeCalendarCollection(calPath, directory):
                    errorOccurred = True

                # Change the calendar-free-busy-set xattrs of the inbox to the
                # __uids__/<guid> form
                if cal == "inbox":
                    for attr, value in xattr.xattr(calPath).iteritems():
                        if attr == "WebDAV:{urn:ietf:params:xml:ns:caldav}calendar-free-busy-set":
                            value = updateFreeBusySet(value, directory)
                            if value is not None:
                                # Need to write the xattr back to disk
                                xattr.setxattr(calPath, attr, value)

        except Exception, e:
            log.error("Failed to upgrade calendar home %s: %s" % (homePath, e))
            raise
Exemplo n.º 3
0
 def restore(self):
     # Get rid of whatever messed up state the test has now so that we'll
     # get a fresh docroot.  This isn't very cool; tests should be doing
     # less so that they don't need a fresh copy of this state.
     if hasattr(self, "_docroot"):
         rmdir(self._docroot)
         del self._docroot
    def test_make_calendar_in_calendar(self):
        """
        Make calendar in calendar
        """
        first_uri  = "/calendar_in_calendar/"
        first_path = os.path.join(self.docroot, first_uri[1:])

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

        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 = SimpleRequest(self.site, "MKCALENDAR", nested_uri)
            self.send(request, do_test)

        request = SimpleRequest(self.site, "MKCALENDAR", first_uri)
        return self.send(request, next)
Exemplo n.º 5
0
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for COPY %s (depth=%r): %s != %s"
                          % (uri, depth, response.code, responsecode.CREATED))

            if response.headers.getHeader("location") is None:
                self.fail("Reponse to COPY %s (depth=%r) with CREATE status is missing location: header."
                          % (uri, depth))

            if os.path.isfile(path):
                if not os.path.isfile(dst_path):
                    self.fail("COPY %s (depth=%r) produced no output file" % (uri, depth))
                if not cmp(path, dst_path):
                    self.fail("COPY %s (depth=%r) produced different file" % (uri, depth))
                os.remove(dst_path)

            elif os.path.isdir(path):
                if not os.path.isdir(dst_path):
                    self.fail("COPY %s (depth=%r) produced no output directory" % (uri, depth))

                if depth in ("infinity", None):
                    if dircmp(path, dst_path):
                        self.fail("COPY %s (depth=%r) produced different directory" % (uri, depth))

                elif depth == "0":
                    for filename in os.listdir(dst_path):
                        self.fail("COPY %s (depth=%r) shouldn't copy directory contents (eg. %s)" % (uri, depth, filename))

                else: raise AssertionError("Unknown depth: %r" % (depth,))

                rmdir(dst_path)

            else:
                self.fail("Source %s is neither a file nor a directory"
                          % (path,))
    def addressbook_query(self, addressbook_uri, query, got_xml, data, no_init):
        addressbook_path = os.path.join(self.docroot, addressbook_uri[1:])

        if not no_init and os.path.exists(addressbook_path): rmdir(addressbook_path)

        def do_report(response):
            if not no_init:
                response = IResponse(response)
    
                if response.code != responsecode.CREATED:
                    self.fail("MKCOL failed: %s" % (response.code,))
    
                if data:
                    for filename, icaldata in data.iteritems():
                        path = os.path.join(addressbook_path, filename + ".vcf")
                        f = open(path, "w")
                        f.write(icaldata)
                        f.close()
                else:
                    # Add vcards to addressbook
                    # We're cheating by simply copying the files in
                    for filename in os.listdir(self.vcards_dir):
                        if os.path.splitext(filename)[1] != ".vcf": continue
                        path = os.path.join(self.vcards_dir, filename)
                        shutil.copy(path, addressbook_path)
    
                # Delete the index because we cheated
                index_path = os.path.join(addressbook_path, db_basename)
                if os.path.isfile(index_path): os.remove(index_path)

            request = SimpleRequest(self.site, "REPORT", addressbook_uri)
            request.stream = MemoryStream(query.toxml())

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

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

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

            return self.send(request, do_test)

        if no_init:
            return do_report(None)
        else:
            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>
"""
            request = SimpleRequest(self.site, "MKCOL", addressbook_uri, content=mkcol)
    
            return self.send(request, do_report)
    def calendar_query(self, calendar_uri, query, got_xml, data, no_init):
        calendar_path = os.path.join(self.docroot, calendar_uri[1:])

        if not no_init and os.path.exists(calendar_path): rmdir(calendar_path)

        def do_report(response):
            if not no_init:
                response = IResponse(response)
    
                if response.code != responsecode.CREATED:
                    self.fail("MKCALENDAR failed: %s" % (response.code,))
    
                if data:
                    for filename, icaldata in data.iteritems():
                        path = os.path.join(calendar_path, filename + ".ics")
                        f = open(path, "w")
                        f.write(icaldata)
                        f.close()
                else:
                    # Add holiday events to calendar
                    # We're cheating by simply copying the files in
                    for filename in os.listdir(self.holidays_dir):
                        if os.path.splitext(filename)[1] != ".ics": continue
                        path = os.path.join(self.holidays_dir, filename)
                        shutil.copy(path, calendar_path)
    
                # Delete the index because we cheated
                index_path = os.path.join(calendar_path, db_basename)
                if os.path.isfile(index_path): os.remove(index_path)

            request = SimpleRequest(self.site, "REPORT", calendar_uri)
            request.stream = MemoryStream(query.toxml())

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

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

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

            return self.send(request, do_test)

        if no_init:
            return do_report(None)
        else:
            request = SimpleRequest(self.site, "MKCALENDAR", calendar_uri)
    
            return self.send(request, do_report)
    def test_addressBookHomeURLs(self):
        """
        DirectoryPrincipalResource.addressBookHomeURLs(),
        """
        # No addressbook home provisioner should result in no addressbook homes.
        for provisioningResource, recordType, recordResource, record in self._allRecords():
            if record.enabledForAddressBooks:
                self.failIf(tuple(recordResource.addressBookHomeURLs()))

        # Need to create a addressbook home provisioner for each service.
        addressBookRootResources = {}

        for directory in self.directoryServices:
            path = os.path.join(self.docroot, directory.__class__.__name__)

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

            # Need a data store
            _newStore = CommonDataStore(path, None, True, False)

            provisioningResource = DirectoryAddressBookHomeProvisioningResource(
                directory,
                "/addressbooks/",
                _newStore
            )

            addressBookRootResources[directory.__class__.__name__] = provisioningResource

        # AddressBook home provisioners should result in addressBook homes.
        for provisioningResource, recordType, recordResource, record in self._allRecords():
            if record.enabledForAddressBooks:
                homeURLs = tuple(recordResource.addressBookHomeURLs())
                self.failUnless(homeURLs)

                # Turn off enabledForAddressBooks and addressBookHomeURLs should
                # be empty
                record.enabledForAddressBooks = False
                self.failIf(tuple(recordResource.addressBookHomeURLs()))
                record.enabledForAddressBooks = True

                addressBookRootURL = addressBookRootResources[record.service.__class__.__name__].url()

                for homeURL in homeURLs:
                    self.failUnless(homeURL.startswith(addressBookRootURL))
Exemplo n.º 9
0
    def test_MKCOL(self):
        """
        MKCOL request
        """
        path, uri = self.mkdtemp("collection")

        rmdir(path)

        def check_result(response):
            response = IResponse(response)

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

            if not os.path.isdir(path):
                self.fail("MKCOL did not create directory %s" % (path,))

        request = SimpleRequest(self.site, "MKCOL", uri)

        return self.send(request, check_result)
Exemplo n.º 10
0
def upgradeCalendarHome(homePath, directory, cuaCache):

    errorOccurred = False

    log.debug("Upgrading calendar home: %s" % (homePath,))

    try:
        for cal in os.listdir(homePath):
            calPath = os.path.join(homePath, cal)
            if not os.path.isdir(calPath):
                # Skip non-directories; these might have been uploaded by a
                # random DAV client, they can't be calendar collections.
                continue
            if cal == 'notifications':
                # Delete the old, now obsolete, notifications directory.
                rmdir(calPath)
                continue
            log.debug("Upgrading calendar: %s" % (calPath,))
            if not upgradeCalendarCollection(calPath, directory, cuaCache):
                errorOccurred = True

            # Change the calendar-free-busy-set xattrs of the inbox to the
            # __uids__/<guid> form
            if cal == "inbox":
                try:
                    for attr, value in xattr.xattr(calPath).iteritems():
                        if attr == xattrname("{urn:ietf:params:xml:ns:caldav}calendar-free-busy-set"):
                            value = updateFreeBusySet(value, directory)
                            if value is not None:
                                # Need to write the xattr back to disk
                                xattr.setxattr(calPath, attr, value)
                except IOError, ioe:
                    if ioe.errno == errno.EOPNOTSUPP:
                        # On non-native xattr systems we cannot do this,
                        # but those systems will typically not be migrating
                        # from pre-v1
                        pass
                except:
                    raise
    def free_busy_query(self, calendar_uri, query, got_calendar):
        calendar_path = os.path.join(self.docroot, calendar_uri[1:])

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

        def do_report(response):
            response = IResponse(response)

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

            # Add holiday events to calendar
            # We're cheating by simply copying the files in
            for filename in os.listdir(self.holidays_dir):
                if os.path.splitext(filename)[1] != ".ics": continue
                path = os.path.join(self.holidays_dir, filename)
                shutil.copy(path, calendar_path)

            # Delete the index because we cheated
            index_path = os.path.join(calendar_path, db_basename)
            if os.path.isfile(index_path): os.remove(index_path)

            request = SimpleRequest(self.site, "REPORT", calendar_uri)
            request.stream = MemoryStream(query.toxml())

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

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

                return Component.fromIStream(response.stream).addCallback(got_calendar)

            return self.send(request, do_test, calendar_path)

        request = SimpleRequest(self.site, "MKCALENDAR", calendar_uri)

        return self.send(request, do_report, calendar_path)
Exemplo n.º 12
0
    def test_MKCOL_invalid_body(self):
        """
        MKCOL request with invalid request body
        (Any body at all is invalid in our implementation; there is no
        such thing as a valid body.)
        """
        path, uri = self.mkdtemp("collection")

        rmdir(path)

        def check_result(response):
            response = IResponse(response)

            if response.code != responsecode.UNSUPPORTED_MEDIA_TYPE:
                self.fail("MKCOL response %s != %s" % (response.code, responsecode.UNSUPPORTED_MEDIA_TYPE))

            if os.path.isdir(path):
                self.fail("MKCOL incorrectly created directory %s" % (path,))

        request = SimpleRequest(self.site, "MKCOL", uri)
        request.stream = MemoryStream("This is not a valid MKCOL request body.")

        return self.send(request, check_result)
Exemplo n.º 13
0
    uid, gid = getCalendarServerIDs(config)

    if not os.path.exists(config.DataRoot):
        makeDirsUserGroup(config.DataRoot, uid=uid, gid=gid)

    if os.path.exists(docRoot):

        # Look for the /principals/ directory on disk
        oldPrincipals = os.path.join(docRoot, "principals")
        if os.path.exists(oldPrincipals):
            # First move the proxy database and rename it
            doProxyDatabaseMoveUpgrade(config, uid=uid, gid=gid)

            # Now delete the on disk representation of principals
            rmdir(oldPrincipals)
            log.debug(
                "Removed the old principal directory at '%s'."
                % (oldPrincipals,)
            )

        calRoot = os.path.join(docRoot, "calendars")
        if os.path.exists(calRoot):

            uidHomes = os.path.join(calRoot, "__uids__")

            # Move calendar homes to new location:

            log.warn("Moving calendar homes to %s" % (uidHomes,))

            if os.path.exists(uidHomes):
    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, authid="user01")
        request.stream = MemoryStream(mk.toxml())
        return self.send(request, do_test)
Exemplo n.º 15
0
    def test_calendarHomeURLs(self):
        """
        DirectoryPrincipalResource.calendarHomeURLs(),
        DirectoryPrincipalResource.scheduleInboxURL(),
        DirectoryPrincipalResource.scheduleOutboxURL()
        """
        # No calendar home provisioner should result in no calendar homes.
        for provisioningResource, recordType, recordResource, record in self._allRecords():
            if record.enabledForCalendaring:
                self.failIf(tuple(recordResource.calendarHomeURLs()))
                self.failIf(recordResource.scheduleInboxURL())
                self.failIf(recordResource.scheduleOutboxURL())

        # Need to create a calendar home provisioner for each service.
        calendarRootResources = {}

        for directory in self.directoryServices:
            path = os.path.join(self.docroot, directory.__class__.__name__)

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

            # Need a data store
            _newStore = CommonDataStore(path, None, True, False)

            provisioningResource = DirectoryCalendarHomeProvisioningResource(
                directory,
                "/calendars/",
                _newStore
            )

            calendarRootResources[directory.__class__.__name__] = provisioningResource

        # Calendar home provisioners should result in calendar homes.
        for provisioningResource, recordType, recordResource, record in self._allRecords():
            if record.enabledForCalendaring:
                homeURLs = tuple(recordResource.calendarHomeURLs())
                self.failUnless(homeURLs)

                # Turn off enabledForCalendaring and calendarHomeURLs should
                # be empty
                record.enabledForCalendaring = False
                self.failIf(tuple(recordResource.calendarHomeURLs()))
                record.enabledForCalendaring = True

                calendarRootURL = calendarRootResources[record.service.__class__.__name__].url()

                inboxURL = recordResource.scheduleInboxURL()
                outboxURL = recordResource.scheduleOutboxURL()

                self.failUnless(inboxURL)
                self.failUnless(outboxURL)

                for homeURL in homeURLs:
                    self.failUnless(homeURL.startswith(calendarRootURL))

                    if inboxURL and inboxURL.startswith(homeURL):
                        self.failUnless(len(inboxURL) > len(homeURL))
                        self.failUnless(inboxURL.endswith("/"))
                        inboxURL = None

                    if outboxURL and outboxURL.startswith(homeURL):
                        self.failUnless(len(outboxURL) > len(homeURL))
                        self.failUnless(outboxURL.endswith("/"))
                        outboxURL = None

                self.failIf(inboxURL)
                self.failIf(outboxURL)