arnaudq's blog

Monday Nov 02, 2009

DAV:current-user-privilege-set

The DAV:current-user-privilege-set WebDAV ACL property allows a client application to know what operations the currently authenticated user can issue on a WebDAV resource (read, read-write, etc...).

Until now, I was under the impression that servers should return only the top level privileges (aggregate or not).

For example, given a server with the following supported set (note that DAV:all is not abstract):

 [DAV:, all] (aggregate)
      |
      +-- [DAV:, read] (aggregate)
             |
             +-- [DAV:, read-acl] (abstract)
             +-- [DAV:, read-current-user-privilege-set] (abstract)
      |
      +-- [DAV:, write] (aggregate)
             |
             +-- [DAV:, write-acl] (abstract)
             +-- [DAV:, write-properties]
             +-- [DAV:, write-content]

and a user with all rights on a resource,  I was expecting the following DAV:current-user-privilege-set:

 <D:current-user-privilege-set>
    <D:privilege><D:all/></D:privilege>
 </D:current-user-privilege-set>

But the WebDAV ACL specification clearly states that "Aggregate privileges and their contained privileges are listed". So what the server should return is really the full set:

 <D:current-user-privilege-set>
    <D:privilege><D:all/></D:privilege>
    <D:privilege><D:read/></D:privilege>
    <D:privilege><D:write/></D:privilege>
    <D:privilege><D:write-properties/></D:privilege>
    <D:privilege><D:write-content/></D:privilege>
 </D:current-user-privilege-set>

I guess this makes client implementers life easier.


Tuesday Aug 04, 2009

More CalDAV enabled phones... starting with Symbian ?

The iPhone might be the first CalDAV enabled phone but hopefully, it won't be long before other start to appear.

My colleague Maximilian Odendahl has been working on a CalDAV provider for the native Symbian OS Calendar application for a few months now.

He started with a standalone application that syncs up one or more CalDAV accounts using the native Calendar database API (using WebDAV Sync when appropriate).

This is already working great. Here is a screenshot of the native Calendar application, showing events pulled from our hosted preview server:



Now that Sun Microsystems has joined the Symbian foundation, Max will be able to fully integrate his CalDAV provider into the native application, for example to allow direct configuration of an account (image below is still a mockup):


More info on his work at http://developer.symbian.org/wiki/index.php/CalDav.

(Can't resist to mention that after testing his client against 8 different servers, he found the next generation Sun Calendar Server to be the most standard compliant ...)

Friday Jul 24, 2009

Email reminders mess (progress on the horizon)

One of my desktops is a Mac Mini and recently, I started to notice that the Apple Mail program would startup by itself at what seemed like random occasions and ask me for very private information like my uid, password etc... (Thunderbird is my main client).

After exonerating my kids I figured out what was happening: I have a family calendar at an ISP who now offers CalDAV access. A few days before I started to notice the ghost Mail, I had setup the Apple iCal calendar client to show that calendar. Most of the events on that calendar have email reminders associated with them. Those reminders are generated by the ISP Server but it looks like my desktop was trying to honor those as well. Would I have configure Apple Mail properly, I would have started to receive 2 copies of each reminders.

The fact that the iCalendar specification remains silent on the subject of who (client or server) should honor VALARM with an ACTION property set to EMAIL is a pretty well known issue but I always thought it was a rather theoritical one (Lightning for example does not honor email alarms). It is the first time that I face it as an end user.

It looks like the new VALARM Extension draft is coming at about the right time for me...

Thursday Jun 18, 2009

Setting up a demo CalDAV account on iPhone OS 3.0

As you probably know, the new iPhone OS 3.0 is CalDAV enabled.

The default configuration panel is very simple (server name, user name, password), but it makes some assumptions that may be valid for a production system but not for a demo server:

  • use of standard ports (443 or 80),
  • ssl is the default,
  • the account url follows a fixed pattern: http(s)://<server name>/principals/users/<user name>/

Demo servers usually run on non standard port numbers and they do not always own the full namespace, leading to account urls (actually principal url) that look more like :

http://caldav.example.com:3080/davserver/dav/principals/<user  name>/

Typing this kind of url can be very tedious and error prone, especially given that the advanced configuration panel offers just a tiny text box.

Here is the simplest way that I have found so far to make the process a little bit less painful, assuming that you have a mail account configured already.

1) email the principal url to yourself

... from your regular desktop/laptop email client of course. Check that the url is valid (using a regular browser) before sending it.

The principal url will vary from servers to servers. It is the same that you may have configured if you are using the Apple iCal client (iCal --> Preferences --> Accounts --> <your CalDAV account> --> Server Settings --> Account URL).

2) copy the url from the iPhone Mail App

Go to the iPhone Mail App and open the email.

Press and hold on the url in the message.

You should be asked whether you want to Open or copy the link:

Select copy.

3) go to the CalDAV account creation panel

Settings --> Mail, Contacts, Calendars --> Add Account... --> Other --> Add CalDAV Account

4) Enter the server info

Tap on the Server field. A "Paste" button should appear on top of the text field:

Press on "Paste". The full url is shown:

This is the only trick, really: the client accepts a full url in the server name field.

5) Enter the User Name and password

Go to the User Name field. The full principal url is replaced by the server name only. This is OK:

Finally, enter your password and tap "Next" --> the client indicates "Verifying CalDAV account", then "Account verified".

You can now go to the Calendar application.


Thursday May 07, 2009

Group event example using implicit scheduling

The iTIP specification (RFC 2446 or its Calsify successor) contains a group event example showing an initial invitation, a reply and an update to a group event.

The example only shows the messages that are exchanged between the different calendar clients. It does not show what each client would store in the actual calendars of the participants after each step. This is for good reason since iTIP defines only messages between CUAs and also because an iTIP aware client does not necessarily store the actual calendar in iCalendar format (might be a proprietary format).

But in any case, iTIP aware clients have to deal with 2 types of objects:

  • iTIP messages (invitations, responses,...).
  • calendar resources (the event and tasks that users see in their calendar).
The client must handle the complex logic of creating one from another, merging them together,...

Using the new CalDAV Scheduling model, this becomes much simpler since clients do need to worry only about their copy of the event. I'll try to show that by turning the above mentioned iTIP example into a CalDAV Scheduling example.

Organizer A invites B, C, D, and E (See 4.2.1 A Group Event Request in iTIP):

To initiate the group event , the organizer (A) simply creates a regular calendar resource in any of his calendar collections:

>> Request <<

PUT /home/A/calendar/qwue23489.ics HTTP/1.1
If-None-Match: *
Host: cal.example.com
Content-Type: text/calendar
Content-Length: xxxx
   
BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

>> Response <<

HTTP/1.1 201 Created
Content-Length: 0
Date: Thu, 11 Jun 2009 09:32:12 GMT

On storing this calendar resource, the server notices that it is a scheduling resource:

  • the organizer is the owner of the calendar collection,
  • the resource has attendees without a SCHEDULE-AGENT=CLIENT parameter.

As a consequence, the server will automatically deliver a copy of the same event in each attendee's calendar (and put a corresponding iTIP message in their scheduling inbox).

The Organizer client can check whether the delivery succeeded by doing a GET on the just created resource and checking the SCHEDULE-STATUS of each attendee:

>> Request <<

GET /home/A/calendar/qwue23489.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:32:24 GMT
ETag: "123456789-000-111"
Schedule-Tag: "123456789-000-111"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=ROOM:conf_Big@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Reply from attendee B (See 4.2.2 Reply To A Group Event Request in iTIP. )

The calendar client of user B does a synchronization between its local cache and the default calendar collection of user B and fetches the event.

>> Request <<

GET /home/B/calendar/bzyw23492.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:34:24 GMT
ETag: "123456789-000-112"
Schedule-Tag: "123456789-000-112"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Attendee B accepts the invitation. The CUA simply does so by issuing a PUT on the same (attendee's) calendar resource, with an updated PARTSTAT for Attendee B. It makes use of the conditional If-Schedule-Tag-Match header to avoid minor update by other attendees conflicting with its own change:

>> Request <<

PUT /home/B/calendar/bzyw23492.ics HTTP/1.1
If-Schedule-Tag-Match: "123456789-000-112"
Host: cal.example.com
Content-Type: text/calendar
Content-Length: xxxx   

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;PARTSTAT=ACCEPTED;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
>> Response <<

HTTP/1.1 204 No Content
Content-Length: 0
Date: Thu, 11 Jun 2009 09:34:30 GMT

The server will then automatically process the reply and update the Organizer's copy accordingly.

Organizer receives the reply from Attendee B

The Organizer's CUA fetches the new version of the group meeting:

>> Request <<

GET /home/A/calendar/qwue23489.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:40:24 GMT
ETag: "123456789-000-333"
Schedule-Tag: "123456789-000-333"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;SCHEDULE-STATUS="2.0";PARTSTAT=ACCEPTED;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=ROOM:conf_Big@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Of course, this example is only scratching the surface of what it takes to create a good scheduling aware client but it shows that minimal scheduling processing can be achieved at a very low cost.


Calendar

Feeds

Search

Links

Navigation

Referrers