GNOME Bugzilla – Bug 359755
Support for CalDAV collections
Last modified: 2009-12-16 15:00:19 UTC
CalDAV supports having 'collections' which may contain either caldav resources, or which may themselves contain collections (but not both), in a tree structure. This feature is useful in many situations. For example a corporate calendar server might have a /users/person/calendars structure and a /resources/department/calendar hierarchy, where the person connects to the server once but is interested in caldav resources in a variety of places in the hierarchy. At present Evolution does not take any notice of whether a collection it connects to is actually a calendar collection and will attempt to store caldav resources anywhere in the tree. This enhancement would also make it much clearer to a user where their calendar was when they connected to a CalDAV server.
Yeah, we need logic in the eplugin for that. Also what I get from the RFC the preferred way to discover a users calendar is to give the client the principal url and the client then does a propfind requesting the calendar-home-set url. Does RSCDS already support that? Would be nice to have something to test against!
I added code to support that just very recently, and it will be in the next release which should be this week. Strangely enough, though the RFC does read that way, I have found no clients which actually try to do that yet. Mozilla is planning to use that approach, however, which is what has pushed me to implement it.
I thought I'll look at this, but I miss something obvious here, probably. With DAViCal, the calendar-home-set returns only "caldav.php/<username>" for me, not the full path I would expect, like "caldav.php/<username>/home". The thing I wanted to use collections are for letting user choose any calendar available on the server, as I understood your initial comment, with a tree structure, seeing my calendar and all public calendars in a tree. But I didn't find a way how to ask CalDAV server for a list of available calendars for a user. Neither the > <D:principal-property-search xmlns:D="DAV" xmlns:C="urn:ietf:pa...ns:caldav"> > <D:property-search/> > <D:prop> > <C:calendar-home-set/> > </D:prop> > </D:principal-property-search> which is returning > < HTTP/1.1 501 Not Implemented > ... > < The XML is not a supported REPORT query document but it seems I would be able to ask for public collections with the principal-property-search, as is shown in http://tools.ietf.org/html/rfc4791.html#section-8.4 (I know I didn't copy all the sample.) Interestingly with a namespace "DAV:" I get: > < HTTP/1.0 500 Internal Server Error on the latest DAViCal as of today (0.9.7.6-0) Any ideas?
The definition of 'calendar-home-set' is that it returns the URL of the collection which contains the user's calendars. Not the URLs of the calendars themselves. It's expected that you will then do a Depth: 1 PROPFIND on that URL to retrieve the actual calendars. When you do that you will request the resourcetype & supported-calendar-component-set (& getctag too, if you support that extension) so that you can know which ones are calendars, and whether they support VEVENT/VTASK/VJOURNAL etc. There seems to be a typo in the request you used above where 'xmlns:D="DAV"' should be 'xmlns:D="DAV:"'. The <D:property-search> tag should also contain the <prop> list of requested properties too, as in this example (which is from DAViCal's regression tests): <D:principal-property-search xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:property-search> <D:prop> <C:calendar-home-set/> </D:prop> <D:match>/caldav.php/user1</D:match> </D:property-search> <D:prop> <C:calendar-home-set/> <C:calendar-user-address-set/> <C:schedule-inbox-URL/> <C:schedule-outbox-URL/> </D:prop> </D:principal-property-search> The 500 error on the badly formed report request XML is not so good. Perhaps I should do something better there though... :-) So then the PROPFIND on the calendar-home-set would look something like this: PROPFIND /caldav.php/username/ HTTP/1.1 Depth: 1 Content-Type: text/xml; charset="UTF-8" <?xml version="1.0" encoding="utf-8"?> <propfind xmlns="DAV:" xmlns:caldav="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:ical="http://apple.com/ns/ical/"> <prop> <displayname/> <caldav:calendar-description/> <cs:getctag/> <ical:calendar-color/> <caldav:supported-calendar-component-set/> <resourcetype/> </prop> </propfind> Having consistent calendar colours is nice too - the ical:calendar-color property is how iCal/iPhone do this. It just holds an html colour spec like #RRGGBB. Cheers, Andrew.
Thanks for a reply. I'm sorry for a late response, I sort of overlooked this (I was disrupted with other issues). I've one more question, though. Am I able to fetch also public calendars from a server, or say calendars for a given user offered by other users on the server? What I thought would be a very nice feature is to let user give us only a server URI and username, and then he/she will click "Retrieve available calendars" button in the "New Calendar" window, and it'll search available calendars on that server. From the above I understand that I should do a query for "calendar-home-set", then on the result of that the PROPFIND to have user's calendars, which I might also filter based on the supported-component-set (not showing VTODO for calendar of type VEVENT). But I'm still missing those shared calendars. Maybe it's not possible? Oh, also, you mentioned that the result can be in a hierarchy, so for those of "resourcetype" being "collection", I can repeat the propfind with some URL? (I know, this would be basic questions, and if this is obvious from the results, then just tell me and I will try. I thought I will get an overview before starting real coding, somehow.)
There are a few tricks you can do for this, but the dust isn't fully settled on parts of this. Trick #1 is that you can try a PROPFIND request for current-user-principal which will hopefully work anywhere in the (DAV:) tree and return you the principal-URL for the currently authenticated user. See http://tools.ietf.org/html/rfc5397.html for the specification - it's pretty straightforward. Also planned for the future is the ability to query a 'well known URL' so that in theory you can do an _srv lookup on the domain to find the right port #, then PROPFIND the /.well-known/caldav/ URL for the current-user-principal (or maybe GET it and get a 302 - it's not fully finalised). See http://tools.ietf.org/html/draft-daboo-srv-caldav http://tools.ietf.org/html/draft-nottingham-site-meta for more details, but I don't know how final they are yet. Once you've *got* the principal-URL you can PROPFIND for the group-membership, and possibly do this repeatedly since it only returns *direct* memberships, not memberships of memberships (it's defined in RFC3744). Once *that's* fully expanded to a list of principal-URLs that the current user has access to, you can query the calendar-home-set for them and then *finally* you can do a Depth: 1 PROPFIND on those to find their calendars. Phew! One possible simplification to this is to use the DAV::expand-property REPORT to combine two steps of this into a single step, so that instead of getting the principal-URL and *then* getting the calendar-home-set you can REPORT something like the below, and get them both at once: <?xml version="1.0" encoding="utf-8" ?> <expand-property xmlns="DAV:"> <property name="group-membership"> <property name="displayname"/> <property name="calendar-home-set" namespace="urn:ietf:params:xml:ns:caldav"> <property name="resourcetype"/> </property> </property> </expand-property> For DAViCal the calendar-home-set *is* the principal-URL, so this will look somewhat redundant, but for other servers that is not always the case, so it will save a round-trip in those cases. The expand-property report is defined in RFC 3253 (WebDAV Versioning) along with the supported-report-set and supported-method-set properties, and none of these are implemented in any released DAViCal version, though they are implemented and working now, and will be in 0.9.8 when I release it... soon :-) Probably most other servers do support them since they are a REQUIRED part of CalDAV but I have only implemented them recently since they weren't used by any clients I knew of until (apparently) iCal4. I can't think of a way to get the actual collections themselves with expand-property, but maybe there is some trick that could do that. If there were a property that could be got from the calendar-home-set that returned a set of the principal's calendar URLs it could be done with one more recursion in the expand-property report. I guess at this point I'd recommend leaving the _srv and .well-known stuff out of it and just try for the current-user-principal in the first instance, and PROPFIND Depth: 1 on the calendar-home-set. That gets you the user's direct calendars, which should all be displayed. I think it would be worth differentiating between these direct calendars and the 'other calendars the user has access to', because that could very well be 'all other calendars in the organisation' - potentially a large number. So my approach would be to query for them 'on demand' when the user selects some option to e.g. 'display delegated calendar' or something, at which point I would recursively PROPFIND to expand their group-membership into a tree structure. They could then traverse the tree and the details could be filled out as they expand it, doing a PROPFIND for the calendar-home-set and a PROPFIND Depth: 1 on that for the calendars, for each node the user chose to expand. Possibly that group expansion could also be using the expand-property REPORT so the nodes were calendar-home-set nodes rather than principal nodes. That would save a round-trip, but it's possible other calendar servers might not have found the expand-property report when they first read the specification too... :-) This is kind of a ramble, so maybe you need some further clarification of some points... just ask! :-) Cheers, Andrew McMillan.
Created commit a7cede9 in evo master (2.29.4+) ------------------------------------------------------------------------------- So I'm PROPFIND-ing through collections and it seems to work fine. The only necessary thing is to enter a collection URL in the CalDAV calendar properties, otherwise it might fail for some servers. There will be most likely necessary some polishing and such, but let's see after wider testing. One thing I noticed and would like to change, but do not know how: when PROPFIND-ing on the correct calendar URL all the events are shown in a response. Can I limit the response to include only resources of type "collection" or "calendar"? I believe I can, but I've no idea how. By the way, Andrew, mine public.php of davical-0.9.7.6-0.noarch always claims that only unauthorized person can access this file. Is it necessary and/or correct? I hoped I can find there all public calendars for all users, regardless whether I'm correctly logged to the server or accessing it anonymously, but no luck.
By the way, I like to only enter caldav://server/davical and with this it shows me my calendars based on the logged user. I never knew the exact URL for my calendars :)
No, you can't limit the response size of a PROPFIND - at least not that I know of. Perhaps you could limit with a REPORT, but I don't think a REPORT would get you what you want in other ways. You could do a Depth: 0 PROPFIND in the first instance, just looking for resourcetype (and maybe also current-user-principal and owner to try and get a principal-URL out of it at the same time). If it was a calendar, and you didn't get a response to the current-user-principal or owner properties then you just do the single-calendar approach. If it was a principal, or you got a principal URL from the current-user-principal or owner properties, then you can attack that for a calendar-home-set and go from there. If it was neither, and you didn't manage to extract a principal at all, then you can go for the Depth: 1 PROPFIND and pursue the approach you're currently taking. In DAViCal the public.php is specifically for looking at calendars which have been declared to need no authentication at all, so it is only ever going to provide a very limited view. Anything else would be a security issue. Cheers, Andrew.
Created attachment 149836 [details] [review] evo patch for evolution; Yeah, thanks, doing the first fetch as depth 0 does the trick. I also fixed few other things around.
Created commit 3a0a795 in evo master (2.29.4+)