UserPreferences

OXWebDAV


Documentation of the OXWebDAV Interface

This document describes the OXWebDAV Interface. It gives a short overview of the basic applications and some development information.

Contents

Introduction

WebDAV, which stands for Web-based Distributed Authoring and Versioning, is based on the HTTP protocol. WebDAV permits sending and receiving information, including XML. For more information about WebDAV, check the references provided at the end of this document. The OXWebDAV Interface is a global interface that includes most functions of OX. For example, when you request all contacts from OX, only those contacts for which you have read access are returned. The same function is available for all other actions, such as update or delete (it is not possible to change or delete an object without write rights). If you want to create a task or appointment then inform all participants, as in the web interface), you can use the OXWebDAV Interface. For all these actions, the client must be authenticated by OX . Authentication must be done by sending the user name and password from the client to the server base64- encoded in the following format: base64encode(username:password). (If the authentication fails, OX responds with "401 Authorization Required".) The access rights of objects are based on the OX access logic: The objects in OX (like appointments, contacts, and tasks) gain the access rights from the folder where the object are stored. The owner of a folder can define which users or groups can see, edit or delete an object. The OXWebDAV Interface returns only those objects for which the logged in user has read rights. Only objects to which the logged in user has write rights can be edited.

Another point in the OXWebDAV Interface is the handling of fields in the XML request. All field have to contains the correct Namespace. For every function some fields are required, as in the web interface. These fields must be submitted in the requests. All others are optional.

For example, you want to update a contact, changing only the telephone number. To do this, create an update request with the required fields (for contacts, "last_name"), add the field "private_phone" in the request, and send it to OX. The result is that nothing will be changed in the contact other than the name and the phone number. All other fields will be fetched from the existing object. If you send all fields, OX will insert or update the given fields. If you only send the required and changed fields, just those fields will be updated and all other fields will be taken from the original object. When you send unkown fields with the OXWebDAV Interface, you will return a Conflict. Participants in the format "participant@domain.com" are entered as the user name (from the beginning of the value to the @ sign).

HTTP(s) and OXWebDAV Interfaces

OX provides a set of interfaces for the following modules:

These interfaces were designed for third party products or services. We have written sample applications to show some of the possibilities. Our own solutions (like the Netline Palm Sync (POX) or even the Outlook Connector (OXLook) are based on these interfaces.

Finding Users, Groups, and Resources

With the OXWebDAV Interface, request users, groups, and resources created on OX. The request supports search methods for users, groups, and resources. The search method supports wild cards. Creating and changing entries is not possible. To return all information as XML, send this PROPFIND request:

REQUEST:
PROPFIND /servlet/webdav.groupuser
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:prop>
   <ox:user>*</ox:user>
   <ox:group>*</ox:group>
   <ox:resource>*</ox:resource>
   <ox:resourcegroup>*</ox:resourcegroup>
 </D:prop>
</D:propfind>

RESPONSE:
<D:multistatus buildnumber="[buildnumber]" buildname="[buildname]">
 <D:response>
  <D:href>groupuser</D:href>
  <D:propstat>
   <D:prop>
    <ox:users>
     <ox:user>
      <ox:uid>fxpoffspring</ox:uid>
      <ox:forename>Sebastian</ox:forename>
      <ox:surename>Kauss</ox:surename>
      <ox:mail>fxpoffspring@example.org</ox:mail>
      <ox:memberingroups>
       <ox:groupuid>development</ox:groupuid>
       <ox:groupuid>users</ox:groupuid>
      </ox:memberingroups>
     </ox:user>
     <ox:user>
      <ox:uid>testuser1</ox:uid>
      <ox:forename>test</ox:forename>
      <ox:surename>user1</ox:surename>
      <ox:mail>test.user1@example.org</ox:mail>
          <ox:memberingroups>
       <ox:groupuid>development</ox:groupuid>
       <ox:groupuid>users</ox:groupuid>
      </ox:memberingroups>
     </ox:user>
        <ox:groups>-
         <ox:group>
      <ox:uid>development</ox:uid>
      <ox:members>
       <ox:memberuid>fxpoffspring</ox:memberuid>
       <ox:memberuid>testuser1</ox:memberuid>
      </ox:members>
     </ox:group>
         <ox:group>
      <ox:uid>users</ox:uid>
      <ox:members>
       <ox:memberuid>fxpoffspring</ox:memberuid>
       <ox:memberuid>testuser1</ox:memberuid>
      </ox:members>
     </ox:group>
    </ox:groups>
    <ox:resources>
     <ox:resource>
      <ox:uid>Resource1</ox:uid>
     </ox:resource>
     <ox:resource>
      <ox:uid>Beamer</ox:uid>
     </ox:resource>
    </ox:resources>
    <ox:resourcegroups>
         <ox:resourcegroup>
      <ox:uid>Resourcegroup1</ox:uid>
      <ox:resourcegroupmembers/>
     </ox:resourcegroup>
    </ox:resourcegroups>
   </D:prop>
   <D:status>HTTP/1.1 200 OK</D:status>
   <D:responsedescription>HTTP/1.1 200 OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

FreeBusy Interface

The OX FreeBusy Interface is the only interface that does not require authentication. With this interface, clients can request availability information for a user, group, or resource. All dates and times should be submitted as Unix Long (a Unix Long starts at January 1, 1970, 0:00:00 GMT and specifies the number of milliseconds since this date). All dates and times that the client receives from the OXWebDAV Interface have this format, too. To request this information, just make a http(s) connection with the following URL:

http://[OXIP]/servlet/webdav.freebusy?username=[NAME]&server=[SERVER]&start=[long]&end=[long]

Replace [OXIP] with the name or IP address of OX. Replace [USER] with a valid OX user name. For [SERVER], use the base dn. [start] is an optional parameter. You can define the start date (as Unix Long) for the FreeBusy information. [end], an optional parameter, defines the end date (as Unix Long) of the request. The reply is a document that looks like this:

BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
BEGIN:VFREEBUSY
ORGANIZER:[USER]@[SERVER]
FREEBUSY;FBTYPE=BUSY-TENTATIVE:20030212T100000Z/20030212T110000Z
FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20030303T080000Z/20030303T170000Z
FREEBUSY:FBTYPE=BUSY:20030417T080000Z/20030417T170000Z
END:VFREEBUSY
END:VCALENDAR

To learn more about the given format, check the references provided at the end of this manual.

Information about Folders

To structure your information, use the OX Folder Interface. This interface allows requesting the complete folder structure from OX as well as creating, editing, moving, and deleting folders. A user can obtain rights for the folder itself and for the objects inside this folder. OX supports the following folder types:

The "unbound" type is used for folders that are not internally supported by OX, such as Outlook notes. This allows display of external folders and subfolders. Users can have the the following access rights to folders:

object write (write rights for contained objects) When a user creates an object in a folder, the object acquires the rights from the folder itself. For every OXWebDAV request in calendar, tasks, and contacts, you can specify a "folder_id" to get all objects in the specified folder. The operations provided by this interface are listed below:

The usage and a detailed description for the OXWebDAV interface of these operations are listed in the following sections.

Creating a Folder

The following PROPPATCH/PUT is an example for creating a folder. The folder should have the following details:

REQUEST:
PUT /servlet/webdav.folders/file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
        <ox:title>OXWebDAV Public Folder</ox:title>
    <ox:module>2</ox:module>
    <ox:folder_id>2</ox:folder_id>
    <ox:type>public</ox:type>
    <ox:permissions>
     <ox:admin_user ox:folderpermission="128" ox:objectreadpermission="128" ox:objectwritepermission="128" ox:objectdeletepermission="128">fxpoffspring</ox:admin_user>
     <ox:group ox:folderpermission="2" ox:objectreadpermission="2" ox:objectwritepermission="2" ox:objectdeletepermission="0">users</ox:group>
    </ox:permissions>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

As you can see in the response, there is a field named "object_id". This "object_id" is a unique ID of the newly generated folder.

for the complete list of supported tags for the folders take a look here.

Editing a Folder

To update a folder, send the fields to edit (folder name and rights, for example) and the ID of the folder to change (field "object_id"). The other fields will not be changed in the update. For example, to change the folder name and add the group users to the write rights of the folder, the PROPPATCH/PUT request file should look like this:

REQUEST:
PUT /servlet/webdav.folders/file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
        <ox:title>OXWebDAV Public Folder - UPDATE</ox:title>
    <ox:folder_id>2</ox:folder_id>
    <ox:permissions>
     <ox:admin_user ox:folderpermission="128" ox:objectreadpermission="128" ox:objectwritepermission="128" ox:objectdeletepermission="128">fxpoffspring</ox:admin_user>
     <ox:group ox:folderpermission="2" ox:objectreadpermission="2" ox:objectwritepermission="2" ox:objectdeletepermission="0">users</ox:group>
    </ox:permissions>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

When changing a folder via OXWebDAV, the OXWebDAV Interface checks if the user of the request has the right to change the folder. If the user does not have enough rights, the following response will be sent:

RESPONSE:
HTTP/1.1 207
Response Date: [DATE]
Server: [Servername]
Connection: close
Content-Type: text/xml; charset="utf-8"

<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>403</D:status>
   <D:responsedescription>no permission to edit folder</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

this case, he does not have permission to change the folder. If everything is okay and the user has enough rights to edit the folder, the following OXWebDAV response should be transmitted:

RESPONSE:
HTTP/1.1 207
Response Date: [DATE]
Server: [Servername]
Connection: close
Content-Type: text/xml; charset="utf-8"

<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Moving a Folder

To move a folder, you need the folder ID ("object_id") of the folder to move and the folder ID of the new parent folder ("folder_id"). A folder PROPPATCH/PUT request will look like this:

REQUEST:
PUT /servlet/webdav.folders/file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive Authorization:
Basic [base64coded]

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
        <ox:title>OXWebDAV Public Folder - UPDATE</ox:title>
    <ox:object_id>[object_id]</ox:folder_id>
    <ox:folder_id>[new_folder_id]</ox:folder_id>
    <ox:permissions>
     <ox:admin_user ox:folderpermission="128" ox:objectreadwritepermission="128" ox:objectdeletepermission="128">fxpoffspring</ox:admin_user>
     <ox:group ox:folderpermission="2" ox:objectreadwritepermission="8" ox:objectdeletepermission="0">users</ox:group>
    </ox:permissions>
  </D:prop>
 </D:set>
</D:propertyupdate>

FAILED RESPONSE:
HTTP/1.1 207
Response Date: [DATE]
Server: [Servername]
Connection: close
Content-Type: text/xml; charset="utf-8"

<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>403</D:status>
   <D:responsedescription>no permission to create new folder</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

RESPONSE:
HTTP/1.1 207
Response Date: [DATE]
Server: [Servername]
Connection: close
Content-Type:

<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Fetching Folders

It is possible to request all folders for a specific user or even a only one folder if the unique ID ("object_id") is known.

With the PROPFIND method, request folder from OX:

PROPFIND /servlet/webdav.folders
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:prop>
   <ox:objectmode>NEW_AND_MODIFIED</ox:objectmode>
   <ox:objectmode>DELETED</ox:objectmode>
   <ox:lastsync>0</ox:lastsync>
   <ox:foldertype>PRIVATE</ox:foldertype>
   <ox:foldertype>PUBLIC</ox:foldertype>
   <ox:foldertype>SHARED</ox:foldertype>
   <ox:foldertype>GLOBALADDRESSBOOK</ox:foldertype>
   <ox:foldertype>INTERNALUSERS</ox:foldertype>
 </D:prop>
</D:propfind>

Deleting a Folder

To delete a folder, only the "object_id" of the folder is required. The OXWebDAV Interface will do the following operations:

A PROPPATCH/PUT request will look like the following example:

REQUEST:
PUT /servlet/webdav.folders/file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive Authorization:
Basic [base64coded}

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
        <ox:method>DELETE</ox:method>
    <ox:object_id>[object_id]</ox:folder_id>
  </D:prop>
 </D:set>
</D:propertyupdate>

Response:

<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Appointment Handling

The OXWebDAV Interface for appointments provides a set of functions for managing all kinds of appointments. All functions of the web interface are also available with the OXWebDAV Interface. The operations provided by this interface are listed below:

Fetching Appointments

It is possible to request all appointments for a specific user or even a single appointment if the unique ID ("object_id") is known. If a folder is given in the request, only appointments for this folder will be returned.

With the PROPFIND method, request appointments from OX:

PROPFIND /servlet/webdav.calendar
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:prop>
   <ox:lastsync>0</ox:lastsync>
 </D:prop>
</D:propfind>

With the field "lastsync", appointments since the given date are being requested. A valid date must be a Unix Long that starts January 1, 1970, 00:00:00 GMT and specifies the number of milliseconds since that date. The value 0 should result in all appointments being returned. If a "folder_id" is given, only appointments inside this folder will be returned. Leave this field empty or do not send it to receive all private appointments. Values for "objectmode" can be combined ("new, update, delete"). The default parameters will be taken for the request: lastsync = 0 objecttype = NEW_AND_MODIFED. All fields with dates as the value will also be returned as Unix Long (see desciption above). However, if there is a "full_time" event, the date will be calculated in GMT, but the start time should be 00:00 in GMT. The complete time zone calculation for any date is part of the client application. The value in the field "alarm" is in minutes before the start date ("start_date"). Four appointment types (field "shown_as") are supported: reserved = 1 temporary = 2 absent on business = 3 holiday = 4. Every appointment has a unique ID in the XML tag "object_id". With this value, it is possible to fetch, change, and delete a single appointment. This value cannot be changed. Recurring appointments are a little bit different. More information is available later in this documentation. The fields for recurring appointments are recurrence_type, interval, days, day_in_month, month, deleteexceptions, changeexceptions and until.

Here is an example response (normal appointment):

HTTP/1.1 207
Response [DATE]
Server: [Servename]
Connection: close
Content-Type: text/xml; charset="utf-8"

<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus buildnumber="[buildnumber]" buildname="[buildname]">
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_status>CREATE</ox:object_status>
     <ox:creation_time>1110199017535</ox:creation_time>
     <ox:created_by>fxpoffspring</ox:created_by>
     <ox:last_modified>1110199017535</ox:last_modified>
     <ox:full_time>false</ox:full_time>
     <ox:folder_id>-1</ox:folder_id>
     <ox:start_date>1110182400000</ox:start_date>
     <ox:end_date>1110214800000</ox:end_date>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:recurrence_id>0</ox:recurrence_id>
     <ox:recurrence_position>0</ox:recurrence_position>
     <ox:title>Item #1</ox:title>
     <ox:location>My Location</ox:location>
     <ox:shown_as>4</ox:shown_as>
     <ox:note>
Appointment Data:

No Participants
begins: 8:00 AM
end: 5: AM

Display as: free
     </ox:note>
     <ox:private>false</ox:private>
     <ox:personal_folder_id>[personal_folder_id]</ox:personal_folder_id>
     <ox:participants>
      <ox:user ox:confirm="none">fxpoffspring</ox:user>
     </ox:participants>
     <ox:alarm>0</ox:alarm>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
 <D:response>
</D:multistatus>

create or update Appointment

With PUT or PROPPATCH, it is possible to create and update appointments on OX:

REQUEST:
PROPPATCH /servlet/webdav.calendar /file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

or

PUT /servlet/webdav.calendar/file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:start_date>1110193200000</ox:start_date>
   <ox:end_date>1110200400000</ox:end_date>
   <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
   <ox:folder_id>-1</ox:folder_id>
   <ox:alarm>10</ox:alarm>
   <ox:title>My first Appointment with OXWebDAV</ox:title>
   <ox:participants>
    <ox:user>fxpoffspring</ox:user>
    <ox:user>test@open-xchange.org</ox:user>
   </ox:participants>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

As you can see, the client can define a "client_id" in the request and this value is also in the response, including the newly generated "object_id". This enables mapping between OX and other sources, such as a SAP system. Updating this appointment is very easy. Just add the tag "object_id" in your PUT or PROPPATCH xml file and send it to OX:

<ox:object_id>[object_id]</ox:object_id>

Deleting Appointments

To delete an appointment, you need the "object_id". The delete command looks like this:

DELETE /servlet/webdav.calendar/[object_id]
HTTP/1.1
Content-Type: text/xml
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded]

or a PUT/PROPPATCH with this XML:

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:method>DELETE</ox:method>
   <ox:object_id>[object_id]</ox:object_id>
  </D:prop>
 </D:set>
</D:propertyupdate>

Specify the "object_id" after the url to delete this appointment. If you do not have the rights to delete the appointment, you will get an 403 Error code from the server.

Recurring Appointments or Tasks

Each sequence returns only one object. Inside this object, find the deleted objects in field "delete_exceptions". Changed objects can be found in field "change_exceptions".

The field "sequence_position" indicates the position inside the sequence. The field "sequence_date_position" always contains the original date of the appointment, even if the appointment was moved. Delete and change single sequences (exceptions) can be done by the tag adding "sequence_position" into the proppatch or by adding the field "sequence_date_position". Then just send the normal PROPPATCH with the "object_id" of the "MAIN" sequence object. To change the whole sequence, just update the given object ("MAIN") and let the field "sequence_position" and the "sequence_date_postion" empty. In this case, the "change_exceptions" will be nulled!

Fields for a daily recurrece: <ox:recurrence_type>daily</ox:recurrence_type> <ox:interval>[daily interval]</ox:interval> <ox:until>[GMT Long]</ox:until>

Field for a weekly recurrence: <ox:recurrence_type>weekly</ox:recurrence_type> <ox:interval>[weekly interval]</ox:interval> <ox:days>[sum of days]</ox:days> <ox:until>[GMT Long]</ox:until>

integer valus of days:

Fields for a monthly recurrence:

Example1: 12th every 2nd Month

<ox:recurrence_type>monthly</ox:recurrence_type> <ox:interval>[monthly interval]</ox:interval> <ox:day_in_month>[day in month]</ox:day_in_month> <ox:until>[GMT Long]</ox:until>

Example2: every 3rd Wednesday every 2nd Month

<ox:recurrence_type>monthly</ox:recurrence_type> <ox:interval>[monthly interval]</ox:interval> <ox:day_in_month>[day in month]</ox:day_in_month> <ox:days>[day]</ox:day_in_month> <ox:until>[GMT Long]</ox:until>

Fields for a yearly recurrence:

Example1: every 12th in January

<ox:recurrence_type>monthly</ox:recurrence_type> <ox:interval>1</ox:interval> <ox:day_in_month>[day in month]</ox:day_in_month> <ox:month>[month]</ox:day_in_month> <ox:until>[GMT Long]</ox:until>

Example2: every 3rd Wednesday in May

<ox:recurrence_type>monthly</ox:recurrence_type> <ox:interval>1</ox:interval> <ox:day_in_month>[day in month]</ox:day_in_month> <ox:days>[day]</ox:day_in_month> <ox:month>[month]</ox:month> <ox:until>[GMT Long]</ox:until>

integer values of days:

Task Handling

With the OXWebDAV Interface, you have a set of functions for managing tasks. The interface allows you to use most of the functions available in the web front-end, like:

Fetching Tasks

With the PROPFIND method, you can request tasks from OX:

REQUEST:
PROPFIND /servlet/webdav.tasks
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:prop>
   <ox:lastsync>0</ox:lastsync>
 </D:prop>
</D:propfind>

RESPONSE:
<D:multistatus buildnumber="[buildnumber]" buildname="[buildname]">
 <D:response>
  <D:href>[object_id]</D:href>
  <D:propstat>
   <D:prop>
        <ox:object_status>CREATE</ox:object_status>
        <ox:creation_time>1110289406807</ox:creation_time>
        <ox:created_by>fxpoffspring</ox:created_by>
        <ox:last_modified>1110289406807</ox:last_modified>
        <ox:folder_id>-1</ox:folder_id>
        <ox:start_date>1110236400000</ox:start_date>
        <ox:end_date>1110409200000</ox:end_date>
        <ox:object_id>[object_id]</ox:object_id>
        <ox:target_costs>0.0</ox:target_costs>
        <ox:actual_costs>0.0</ox:actual_costs>
        <ox:target_duration>0.0</ox:target_duration>
        <ox:actual_duration>0.0</ox:actual_duration>
        <ox:title>Task Subject</ox:title>
        <ox:note>Note</ox:note>
        <ox:priority>3</ox:priority>
        <ox:percent_complete>50</ox:percent_complete>
        <ox:duration_type>H</ox:duration_type>
        <ox:type_of_costs>F</ox:type_of_costs>
        <ox:currency>EUR</ox:currency>
        <ox:status>2</ox:status>
        <ox:private>false</ox:private>
        <ox:personal_folder_id>[folder_id]</ox:personal_folder_id>
        <ox:participants>
         <ox:user ox:confirm="none">fxpoffspring</ox:user>
        </ox:participants>
        <ox:alarm>0</ox:alarm>
   </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

With the field "lastsync", request tasks since the given date. A valid date is a Unix Long, which starts at January 1, 1970, 00:00:00 GMT and specifies the number of milliseconds since this date. The value 0 should find all tasks. If "folder_id" is given, only tasks inside this folder will be returned. Leave this field empty or do not send it to receive all private tasks. Values for "objectmode" can be combined. For example, "NEW_AND_MODIFED or DELETED". If you make a request without parameters, the default parameters will be taken for the request:

All fields with dates will be returned as Unix Long (see desciption above). The value in the field "alarm" is in minutes before the "start_date". Every task has a Unique ID in the XML tag "object_id". With this value, it is possible to fetch a single task, change a task, and delete a task. This value cannot be changed.

create or update tasks

With PUT or PROPPATCH, it is possible to create or update tasks on OX:

REQUEST:
PROPPATCH /servlet/webdav.tasks /file.xml
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded]

or

PUT /servlet/webdav.tasks/file.xml
HTTP/1.1 Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
   <ox:start_date>1109847600000</ox:start_date>
   <ox:end_date>1109847600000</ox:end_date>
   <ox:folder_id>[folder_id]</ox:folder_id>
   <ox:alarm>10</ox:alarm>
   <ox:title>Subject</ox:title>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

As you can see, the client can define a "client_id" in the request. This value is also in the response including the newly generated "object_id". This is for easy mapping. To update this task, add the "object_id" tag in your PUT or PROPPATCH XML file and send it to OX:

<ox:object_id>[object_id]</ox:object_id> To fetch your updated task, make a PROPFIND with the "object_id" and only this item will be returned:

REQUEST:
PROPFIND /servlet/webdav.calendar
HTTP/1.1
Content-Type: text/xml
Content-Length: [content length]
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded}

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:prop>
   <ox:object_id>[object_id]</ox:object_id>
 </D:prop>
</D:propfind>

Creating Private or Group Tasks In OX, it is possible to create "group" or "private" tasks. To create a group task, add the following tags to your XML file:

 <ox:participant>
  <ox:user>offspring</ox:user>
  <ox:group>users</S:group>
 </ox:participants>

You can use a mixture of single members and groups.

Deleting Tasks

To delete a task, you need the "object_id". The delete command looks like this:

DELETE /servlet/webdav.tasks/[object_id]
HTTP/1.1
Content-Type: text/xml
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded]

Alternatively, send a PUT/PROPPATCH with this XML:

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:method>DELETE</ox:method>
   <ox:object_id>[object_id]</ox:object_id>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Specials inside the OXWebDAV Interface

Setting Confirmation Status for Participants The OXWebDAV Interface allows you to set the confirmation status of a participant. To set the status, add the following attribute to the participants tag:

<ox:participants>
 <ox:user confirm="accept">[UID]</ox:user>
</S:participants>

There are three different confirmation status:

Contact Handling

The OXWebDAV Interface for contact management provides a workflow for managing contacts and distribution lists. Private information about the OX users are also stored in the OX contact management. The contact management in OX consists of two main parts: the contacts and the distribution lists. The OXWebDAV Interface combines these two parts to one contact, so each OX contact provides contact information and his attached distribution list information. Contacts without an attached distribution list only provide simple contact information. To edit distribution list information, edit a contact associated with the distribution list to edit. This structure allows different ways for handling contact and distribution list management:

Fetching Contacts

<D:multistatus buildnumber="[buildnumber]" buildname="[buildname]">
 <D:response>
  <D:href>[object_id]</D:href>
  <D:propstat>
   <D:prop>
        <ox:object_status>CREATE</ox:object_status>
        <ox:creation_time>1110285019907</ox:creation_time>
        <ox:created_by>offspring</ox:created_by>
        <ox:last_modified>1110285081029</ox:last_modified>
        <ox:modified_by>fxpoffspring</ox:modified_by>
        <ox:object_id>[object_id]</ox:object_id>
        <ox:distributionlist_flag>false</ox:distributionlist_flag>
        <ox:displayname>Title First name Second name Last name Suffix</ox:displayname>
        <ox:last_name>Last name</ox:last_name>
        <ox:first_name>First name</ox:first_name>
        <ox:second_name>Second name</ox:second_name>
        <ox:suffix>Suffix</ox:suffix>
        <ox:title>Title</ox:title>
        <ox:street>Street (private)</ox:street>
        <ox:postal_code>Postal code (private)</ox:postal_code>
        <ox:city>City (private)</ox:city>
        <ox:state>State (private)</ox:state>
        <ox:country>Country (private)</ox:country>
        <ox:birthday>319417200000</ox:birthday>
        <ox:martital_status>Marital Status</ox:martital_status>
        <ox:number_of_children>Number of Children</ox:number_of_children>
        <ox:profession>Profession</ox:profession>
        <ox:nickname>Nickname</ox:nickname>
        <ox:spouse_name>Spouse name</ox:spouse_name>
        <ox:anniversary>326066400000</ox:anniversary>
        <ox:note>Comment

...

...
        </ox:note>
        <ox:company>Company</ox:company>
        <ox:department>Department</ox:department>
        <ox:position>Position</ox:position>
        <ox:employee_type>Employee Type</ox:employee_type>
        <ox:room_number>Room Number</ox:room_number>
        <ox:business_street>Street</ox:business_street>
        <ox:business_postal_code>Postal code</ox:business_postal_code>
        <ox:business_city>City</ox:business_city>
        <ox:business_state>State</ox:business_state>
        <ox:business_country>Country</ox:business_country>
        <ox:number_of_employee>Number of Employee</ox:number_of_employee>
        <ox:sales_volume>Sales Volume</ox:sales_volume>
        <ox:tax_id>TAX-ID Number</ox:tax_id>
        <ox:commercial_register>Commercial Register</ox:commercial_register>
        <ox:branches>Branches</ox:branches>
        <ox:business_category>Business Kategorie</ox:business_category>
        <ox:more_info>More Informations

...

...
        </ox:more_info>
        <ox:managers_name>Managers name</ox:managers_name>
        <ox:assistants_name>Assistants name</ox:assistants_name>
        <ox:second_street>Street (other)</ox:second_street>
        <ox:second_postal_code>Postal code (other)</ox:second_postal_code>
        <ox:second_city>City (other)</ox:second_city>
        <ox:second_state>State (other)</ox:second_state>
        <ox:second_country>Country (other)</ox:second_country>
        <ox:phone_assistant>Tel. Assistant</ox:phone_assistant>
        <ox:phone_business>Tel. Business</ox:phone_business>
        <ox:phone_business2>Tel. Business (2)</ox:phone_business2>
        <ox:fax_business>Business Fax</ox:fax_business>
        <ox:callback>Tel. Callback</ox:callback>
        <ox:phone_car>Tel. Car</ox:phone_car>
        <ox:phone_company>Tel. Company</ox:phone_company>
        <ox:phone_home>Tel. Home</ox:phone_home>
        <ox:phone_home2>Tel. Home (2)</ox:phone_home2>
        <ox:fax_home>Home Fax</ox:fax_home>
        <ox:isdn>ISDN</ox:isdn>
        <ox:mobile1>Tel. Mobile</ox:mobile1>
        <ox:mobile2>Tel. Mobile alt.</ox:mobile2>
        <ox:phone_other>Tel. Other</ox:phone_other>
        <ox:fax_other>Other Fax</ox:fax_other>
        <ox:pager>Pager</ox:pager>
        <ox:primary>Primary</ox:primary>
        <ox:radio>Radio</ox:radio>
        <ox:telex>Telex</ox:telex>
        <ox:tty_tdd>TTY/TDD</ox:tty_tdd>
        <ox:instant_messenger>Instant Messanger</ox:instant_messenger>
        <ox:instant_messenger2>Instant Messanger (2)</ox:instant_messenger2>
        <ox:ip_phone>IP-Phone</ox:ip_phone>
        <ox:email1>emal1@open-xchange.org</ox:email1>
        <ox:email2>emal2@open-xchange.org</ox:email2>
        <ox:email3>emal3@open-xchange.org</ox:email3>
        <ox:url>http://www.open-xchange.org</ox:url>
        <ox:defaultaddress>2</ox:defaultaddress>
        <ox:categories>Important, Office</ox:categories>
        <ox:folder_id>-1</ox:folder_id>
        <ox:personal_folder_id>196</ox:personal_folder_id>
   </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

create or update a contact

PROPPATCH /servlet/webdav.contacts/file.xml
HTTP/1.1
Content-Type: text/xml
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded]

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
   <ox:folder_id>-1</ox:folder_id>
   <ox:last_name>LAST NAME</ox:last_name>
   <ox:email1>test@test.de</ox:email1>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Update example: The handling provides the same XML tree as an insert. Just add a "object_id" to the given contact ID:

Deleting a Contact

To delete a contact, you need the "object_id". The delete command looks like this:

DELETE /servlet/webdav.tasks/[object_id]
HTTP/1.1
Content-Type: text/xml
User-Agent: Netline WebDAV Client
Connection: Keep-Alive
Authorization: Basic [base64coded]

Alternatively, send a PUT/PROPPATCH with this XML:

<D:propertyupdate xmlns:D="DAV:" xmlns:ox="http://www.open-xchange.org">
 <D:set>
  <D:prop>
   <ox:method>DELETE</ox:method>
   <ox:object_id>[object_id]</ox:object_id>
  </D:prop>
 </D:set>
</D:propertyupdate>

RESPONSE:
<D:multistatus>
 <D:response>
  <D:href>[object_id]</D:href>
   <D:propstat>
    <D:prop>
     <ox:object_id>[object_id]</ox:object_id>
     <ox:client_id>INTERFACE PLEASE RETURN THIS FOR MY MAPPING</ox:client_id>
    </D:prop>
   <D:status>200</D:status>
   <D:responsedescription>OK</D:responsedescription>
  </D:propstat>
 </D:response>
</D:multistatus>

Documents

The OXWebDAV Interface for documents provides a workflow for managing uploaded documents. Folders are used for organizing documents. The main focus for implementing the OXWebDAV Interface for documents is set on a direct file system support, as it can be found in most operating systems. Folders and documents can be created, renamed, copied, and moved like on a local file system. The documents area of OX has many more functions than the WebDAV protocol supports. Some functions are not accessible through OXWebDAV Interface. The communication protocol of OXWebDAV Interface for documents works according to the explanations of RFC 2518. The following operations are supported through OXWebDAV Interface for documents:

The following parts of a document cannot be created, modified, or deleted with the OXWebDAV Interface:

The access rights of documents and folders are set automatically and cannot be set manually. If a new folder or a new document is created, it has the same access rights as the folder in which it is created in all other cases, the access rights are not changed. Use the web front-end to change access rights. If you overwrite a file in a normal file system, the overwritten file will be lost.

Overwriting a document with the OXWebDAV Interface saves the overwritten document as an older version and creates a new version of the document. It is impossible to download any older version of a document. This can be only done with the web front-end.

When using special characters (german umlauts etc.) for folder or file names, then you have to make sure your webdav client does send the names with UTF-8 encoding. Windows 2000 and XP do usually send iso-8859-1 encoded names. But if Office XP (or later) is installed, then it sends UTF-8 encoded names.

http://www.lyra.org/pipermail/dav-dev/2005-April/005930.html

Interface for ICal and VCards

The OXWebDAV Interface enables the import and export of special files (ical, vcard).

To export, for example, a ical connect via HTTP(s) to the following URL: http://[OXIP]/servlet/webdav.ical Replace [OXIP] with the name or IP address of OX.

To import file(s), connect with HTTP(s) to the URL and send the file via PUT: http://[OXIP]/servlet/webdav.ical Replace [OXIP] with the name or IP address of OX. In default configuration the interface don't delete objects to enable this feature add this paramter to the url: enabledelete=yes

To select a different calendar than the default calendar, the extension calendarfolder=fuid (where fuid is the folder id of the calendar) can be added to the URL.

To export, for example, a vcard connect via HTTP(s) to the following URL: http://[OXIP]/servlet/webdav.vcard Replace [OXIP] with the name or IP address of OX.

To import a file, connect with HTTP(s) to the URL and send the file via PUT: http://[OXIP]/servlet/webdav.vcard] Replace [OXIP] with the name or IP address of OX. In default configuration the interface don't delete objects to enable this feature add this paramter to the url: enabledelete=yes

Some clients can connect to ICal interface like:

Other References

Tag descriptions

Calendar Tags description

Tagname Writeable Description
objectmode yes type of the returned objects
lastsync yes GMT long
folder_id yes Unique ID of the folder
object_id yes Unique ID of the object
href no Unique ID of the object
object_status no status of the object (CREATED or DELETED)
creation_time no GMT long
created_by no UID
last_modified no GMT long
modified_by no UID
start_date yes GMT long
end_date yes GMT long
title yes text
location yes text
shown_as yes integer
full_time yes boolean
alarm yes integer
notify_participants yes boolean
recurrence_type yes integer
interval yes integer
days yes integer
day_in_month yes integer
month yes integer
recurrence_position yes integer
delete_exceptions yes text
change_exceptions yes text
until yes GMT long
participants yes text
resources yes text
categries yes text

Contact Tags

Tagname Writeable Description
objectmode yes type of the returned objects
lastsync yes GMT long
folder_id yes Unique ID of the folder
object_id yes/no Unique ID of the object. Only writeable in PROPFIND to request one object by ID
href no Unique ID of the object
object_status no status of the object (CREATED or DELETED)
creation_time no GMT long (unix timestamp)
created_by no UID
last_modified no GMT long (unix timestamp)
modified_by no UID
distributionlist_flag no boolean
attachment_flag no boolean
displayname yes text
first_name yes text
last_name yes text
second_name yes text
suffix yes text
title yes text
street yes text
postal_code yes text
city yes text
country yes text
state yes text
birthday yes GMT long
anniversary yes GMT long
martital_status yes text
number_of_children yes text
profession yes text
nickname yes text
spouse_name yes text
note yes text
company yes text
department yes text
position yes text
employee_type yes text
room_number yes text
business_street yes text
business_postal_code yes text
business_city yes text
business_state yes text
business_country yes text
commercial_register yes text
number_of_employee yes text
sales_volume yes text
tax_id yes text
branches yes text
business_category yes text
more_info yes text
managers_name yes text
assistants_name yes text
second_street yes text
second_postal_code yes text
second_city yes text
second_state yes text
second_country yes text
phone_assistant yes text
phone_business yes text
phone_business2 yes text
fax_business yes
callback yes text
phone_car yes text
phone_company yes text
phone_home yes text
phone_home2 yes text
fax_home yes text
isdn yes text
mobile1 yes text
mobile2 yes text
phone_other yes text
fax_other yes text
pager yes text
primary yes text
radio yes text
telex yes text
tty_tdd yes text
instant_messenger yes text
instant_messenger2 yes text
ip_phone yes text
email1 yes text
email2 yes text
email3 yes text
url yes text
userfield01 yes text
userfield02 yes text
userfield03 yes text
userfield04 yes text
userfield05 yes text
userfield06 yes text
userfield07 yes text
userfield08 yes text
userfield09 yes text
userfield10 yes text
userfield11 yes text
userfield12 yes text
userfield13 yes text
userfield14 yes text
userfield15 yes text
userfield16 yes text
userfield17 yes text
userfield18 yes text
userfield19 yes text
userfield20 yes text
categories yes text
distributionlist yes text

Folder Tags

Tagname Writeable Description
objectmode yes type of the returned objects
lastsync yes GMT long
folder_id yes object_id of the parent folder
object_id yes/no Unique ID of the object. Only writeable in PROPFIND to request one object by ID
href no Unique ID of the object
object_status no status of the object (CREATED or DELETED)
creation_time no GMT long
created_by no UID
last_modified no GMT long
title yes text
module no UID
type no UID

Task Tags

Tagname Writeable Description
objectmode yes type of the returned objects
lastsync yes GMT long
folder_id yes Unique ID of the folder
object_id yes/no Unique ID of the object. Only writeable in PROPFIND to request one object by ID
href no Unique ID of the object
object_status no status of the object (CREATED or DELETED)
creation_time no GMT long
created_by no UID
last_modified no GMT long
modified_by no UID
start_date yes GMT long
end_date yes GMT long
title yes text
project_id yes integer
percent_complete yes integer
status yes integer
priority yes integer
duration_type yes text
type_of_costs yes text
currency yes text
trip_meter yes text
billing_information yes text
companies yes text
alarm yes integer
notify_participants yes boolean
recurrence_type yes integer
interval yes integer
days yes integer
day_in_month yes integer
month yes integer
recurrence_position yes integer
delete_exceptions yes text
change_exceptions yes text
until yes GMT long
participants yes text
resources yes text
categries yes text