Fix PROPPATCH handling of CardDAV addressbook setting.

This commit is contained in:
Andrew McMillan 2010-03-18 20:27:56 +13:00
parent 394f5d488f
commit 005c7a2773
9 changed files with 221 additions and 42 deletions

View File

@ -89,15 +89,20 @@ foreach( $setprops AS $k => $setting ) {
case 'DAV::resourcetype':
/**
* We don't allow a collection to change to/from a resource. Only collections may be CalDAV calendars.
* We only allow resourcetype setting on a normal collection, and not on a resource, a principal or a bind.
* Only collections may be CalDAV calendars or addressbooks, and they may not be both.
*/
$setcollection = count($setting->GetPath('DAV::resourcetype/DAV::collection'));
$setcalendar = count($setting->GetPath('DAV::resourcetype/urn:ietf:params:xml:ns:caldav:calendar'));
if ( $request->IsCollection() && $setcollection && ! $dav_resource->IsBinding() ) {
$setcollection = count($setting->GetPath('DAV::resourcetype/DAV::collection'));
$setcalendar = count($setting->GetPath('DAV::resourcetype/urn:ietf:params:xml:ns:caldav:calendar'));
$setaddressbook = count($setting->GetPath('DAV::resourcetype/urn:ietf:params:xml:ns:carddav:addressbook'));
if ( $request->IsCollection() && $setcollection && ! $dav_resource->IsPrincipal()
&& ! $dav_resource->IsBinding() && ! ($setaddressbook && $setcalendar) ) {
$resourcetypes = $setting->GetPath('DAV::resourcetype/*');
$resourcetypes = str_replace( "\n", "", implode('',$resourcetypes));
$qry->QDo('UPDATE collection SET is_calendar = :is_calendar::boolean, resourcetypes = :resourcetypes WHERE dav_name = :dav_name',
array( ':dav_name' => $dav_resource->dav_name(), ':is_calendar' => $setcalendar, ':resourcetypes' => $resourcetypes) );
$qry->QDo('UPDATE collection SET is_calendar = :is_calendar::boolean, is_addressbook = :is_addressbook::boolean,
resourcetypes = :resourcetypes WHERE dav_name = :dav_name',
array( ':dav_name' => $dav_resource->dav_name(), ':resourcetypes' => $resourcetypes,
':is_calendar' => $setcalendar, ':is_addressbook' => $setaddressbook ) );
$success[$tag] = 1;
}
else {
@ -190,27 +195,14 @@ foreach( $rmprops AS $k => $setting ) {
switch( $tag ) {
case 'DAV::resourcetype':
/**
* We don't allow a collection to change to/from a resource. Only collections may be CalDAV calendars.
*/
$rmcollection = (count($setting->GetPath('DAV::resourcetype/DAV::collection')) > 0);
$rmcalendar = (count($setting->GetPath('DAV::resourcetype/urn:ietf:params:xml:ns:caldav:calendar')) > 0);
if ( $request->IsCollection() && !$rmcollection ) {
dbg_error_log( 'PROPPATCH', ' RMProperty %s : IsCollection=%d, rmcoll=%d, rmcal=%d', $tag, $request->IsCollection(), $rmcollection, $rmcalendar );
if ( $rmcalendar ) {
$qry->QDo('UPDATE collection SET is_calendar = FALSE, resourcetypes = :resourcetypes WHERE dav_name = :dav_name',
array( ':dav_name' => $dav_resource->dav_name(), ':resourcetypes' => '<DAV::collection/>') );
}
$success[$tag] = 1;
}
else {
$failure['rm-'.$tag] = new XMLElement( 'propstat', array(
new XMLElement( 'prop', new XMLElement($tag)),
new XMLElement( 'status', 'HTTP/1.1 409 Conflict' ),
new XMLElement( 'responsedescription', translate("Resources may not be changed to / from collections.") )
));
dbg_error_log( 'PROPPATCH', ' RMProperty %s Resources may not be changed to / from Collections.', $tag);
}
$failure['rm-'.$tag] = new XMLElement( 'propstat', array(
new XMLElement( 'prop', new XMLElement($tag)),
new XMLElement( 'status', 'HTTP/1.1 403 Forbidden' ),
new XMLElement( 'responsedescription', array(
new XMLElement( 'error', new XMLElement( 'cannot-modify-protected-property') ),
translate("DAV::resourcetype may only be set to a new value, it may not be removed.") )
)
));
break;
case 'urn:ietf:params:xml:ns:caldav:calendar-timezone':

View File

@ -1,21 +1,44 @@
HTTP/1.1 200 OK
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy
Content-Length: 224
Content-Length: 742
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/</href>
<responsedescription>All requested changes were made.</responsedescription>
<propstat>
<prop>
<DAV::resourcetype/>
</prop>
<status>HTTP/1.1 403 Forbidden</status>
<responsedescription>
<error>
<cannot-modify-protected-property/>
</error>
</responsedescription>
</propstat>
<propstat>
<prop>
<urn:mcmillan:bogus:xml:ns:davical:arbitrary/>
</prop>
<status>HTTP/1.1 424 Failed Dependency</status>
</propstat>
<propstat>
<prop>
<DAV::displayname/>
</prop>
<status>HTTP/1.1 424 Failed Dependency</status>
</propstat>
<responsedescription>Some properties were not able to be changed.</responsedescription>
</response>
</multistatus>
changed_last_60se: >1<
dav_displayname: >User One's Not Calendar<
is_calendar: >0<
resourcetypes: ><DAV::collection/><
dav_displayname: >user1 home<
is_calendar: >1<
resourcetypes: ><DAV::collection/><urn:ietf:params:xml:ns:caldav:calendar/><
changed_by: >10<
changed_last_30se: >1<
@ -29,9 +52,3 @@ changed_last_30se: >1<
property_name: >http://apple.com/ns/ical/:calendar-order<
property_value: >1<
changed_by: >10<
changed_last_30se: >1<
dav_name: >/user1/home/<
property_name: >urn:mcmillan:bogus:xml:ns:davical:arbitrary<
property_value: >A completely bogus property which should be saved.<

View File

@ -1,7 +1,7 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy
Content-Length: 449
Content-Length: 469
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -12,8 +12,12 @@ Content-Type: text/xml; charset="utf-8"
<prop>
<DAV::resourcetype/>
</prop>
<status>HTTP/1.1 409 Conflict</status>
<responsedescription>Resources may not be changed to / from collections.</responsedescription>
<status>HTTP/1.1 403 Forbidden</status>
<responsedescription>
<error>
<cannot-modify-protected-property/>
</error>
</responsedescription>
</propstat>
<responsedescription>Some properties were not able to be changed.</responsedescription>
</response>

View File

@ -0,0 +1,20 @@
HTTP/1.1 200 OK
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy
Content-Length: 224
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/</href>
<responsedescription>All requested changes were made.</responsedescription>
</response>
</multistatus>
changed_last_5m: >1<
dav_displayname: >User One's addressbook<
is_addressbook: >1<
is_calendar: >0<
resourcetypes: ><DAV::collection/><urn:ietf:params:xml:ns:carddav:addressbook/><

View File

@ -0,0 +1,32 @@
#
# Check for support of PROPPATCH method
#
# Convert the collection to an addressbook, and change the displayname
# again
#
TYPE=PROPPATCH
URL=http://regression.host/caldav.php/user1/home/
HEADER=User-agent: SpecTest PROPPATCH
HEADER=Content-type: text/xml
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<propertyupdate xmlns="DAV:">
<set>
<prop>
<resourcetype>
<collection/>
<addressbook xmlns="urn:ietf:params:xml:ns:carddav"/>
</resourcetype>
<displayname>User One's addressbook</displayname>
</prop>
</set>
</propertyupdate>
ENDDATA
QUERY
SELECT dav_displayname, is_calendar, is_addressbook, resourcetypes,
modified > (current_timestamp - '5 minutes'::interval) AS changed_last_5m
FROM collection WHERE dav_name = '/user1/home/';
ENDQUERY

View File

@ -0,0 +1,31 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy
Content-Length: 469
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/</href>
<propstat>
<prop>
<DAV::resourcetype/>
</prop>
<status>HTTP/1.1 403 Forbidden</status>
<responsedescription>
<error>
<cannot-modify-protected-property/>
</error>
</responsedescription>
</propstat>
<responsedescription>Some properties were not able to be changed.</responsedescription>
</response>
</multistatus>
changed_last_5m: >1<
dav_displayname: >User One's addressbook<
is_addressbook: >1<
is_calendar: >0<
resourcetypes: ><DAV::collection/><urn:ietf:params:xml:ns:carddav:addressbook/><

View File

@ -0,0 +1,31 @@
#
# Check for support of PROPPATCH method
#
# Try (and fail) to set the collection to be both an addressbook and a calendar.
#
TYPE=PROPPATCH
URL=http://regression.host/caldav.php/user1/home/
HEADER=User-agent: SpecTest PROPPATCH
HEADER=Content-type: text/xml
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<propertyupdate xmlns="DAV:">
<set>
<prop>
<resourcetype>
<collection/>
<calendar xmlns="urn:ietf:params:xml:ns:caldav"/>
<addressbook xmlns="urn:ietf:params:xml:ns:carddav"/>
</resourcetype>
</prop>
</set>
</propertyupdate>
ENDDATA
QUERY
SELECT dav_displayname, is_calendar, is_addressbook, resourcetypes,
modified > (current_timestamp - '5 minutes'::interval) AS changed_last_5m
FROM collection WHERE dav_name = '/user1/home/';
ENDQUERY

View File

@ -0,0 +1,20 @@
HTTP/1.1 200 OK
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy
Content-Length: 224
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/</href>
<responsedescription>All requested changes were made.</responsedescription>
</response>
</multistatus>
changed_last_5m: >1<
dav_displayname: >User 1's Calendaranza<
is_addressbook: >0<
is_calendar: >1<
resourcetypes: ><DAV::collection/><urn:ietf:params:xml:ns:caldav:calendar/><http://xmlns.comical.net/birds:spotted-grebe/><

View File

@ -0,0 +1,32 @@
#
# Check for support of PROPPATCH method
#
# Try (and fail) to set the collection to be both an addressbook and a calendar.
#
TYPE=PROPPATCH
URL=http://regression.host/caldav.php/user1/home/
HEADER=User-agent: SpecTest PROPPATCH
HEADER=Content-type: text/xml
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<propertyupdate xmlns="DAV:">
<set>
<prop>
<resourcetype>
<collection/>
<calendar xmlns="urn:ietf:params:xml:ns:caldav"/>
<spotted-grebe xmlns="http://xmlns.comical.net/birds"/>
</resourcetype>
<displayname>User 1's Calendaranza</displayname>
</prop>
</set>
</propertyupdate>
ENDDATA
QUERY
SELECT dav_displayname, is_addressbook, is_calendar, resourcetypes,
modified > (current_timestamp - '5 minutes'::interval) AS changed_last_5m
FROM collection WHERE dav_name = '/user1/home/';
ENDQUERY