Fix DAV:current-user-principal for iPhone devices

iPhone devices incorrectly implement DAV:current-user-principal from
RFC 5397. They assume that current-user-principal is the href for the
resource being queried. The RFC says it should be the current resource.

See: https://gitlab.com/davical-project/davical/-/issues/335
This commit is contained in:
Andrew Ruthven 2024-12-13 23:03:07 +13:00
parent c1cfd8eb0d
commit b4bcc6cc25
8 changed files with 205 additions and 1 deletions

View File

@ -1,6 +1,9 @@
2025-01-22 Andrew Ruthven <andrew@etc.gen.nz>
* Using a Ticket ID requires public.php
2024-12-13 Andrew Ruthven <andrew@etc.gen.nz>
* Fix iPhone's accessing other principal's collections.
2024-04-15 Andrew Ruthven <andrew@etc.gen.nz>
* Add caching of user credential success/failure

View File

@ -1881,8 +1881,15 @@ EOQRY;
$prop->NewElement( 'principal-collection-set', $reply->href( ConstructURL('/') ) );
break;
# iPhone devices incorrectly implement DAV:current-user-principal from
# RFC 5397. They assume that current-user-principal is the href for the
# resource being queried. The RFC says it should be the current resource.
# See: https://gitlab.com/davical-project/davical/-/issues/335
case 'DAV::current-user-principal':
$prop->NewElement('current-user-principal', $reply->href( ConstructURL(DeconstructURL($session->principal->url())) ) );
if ( preg_match('/iPhone/', $_SERVER['HTTP_USER_AGENT']) )
$prop->NewElement('current-user-principal', $reply->href( ConstructURL(DeconstructURL($request->principal->url())) ) );
else
$prop->NewElement('current-user-principal', $reply->href( ConstructURL(DeconstructURL($session->principal->url())) ) );
break;
case 'SOME-DENIED-PROPERTY': /** indicating the style for future expansion */

View File

@ -0,0 +1,15 @@
HTTP/1.1 200 OK
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
Content-Length: 0
Content-Type: text/plain; charset="utf-8"
SQL Query 1 Result:
by_collection: >1609<
by_principal: >NULL<
displayname: >User 4<
privileges: >000000000000000000100001<
to_principal: >1005<

View File

@ -0,0 +1,47 @@
# Test for iPhone devices which incorrectly implement
# DAV:current-user-principal from RFC 5397. They assume that
# current-user-principal is the href for the resource being queried. The
# RFC says it should be the current resource. #Sigh.
#
# See: https://gitlab.com/davical-project/davical/-/issues/335
#
# Ensure that user4 can access user1's address book.
TYPE=ACL
HEADER=User-Agent: RFC3744 Spec Tests
HEADER=Content-Type: text/xml; charset="UTF-8"
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<acl xmlns="DAV:" xmlns:CalDAV="urn:ietf:params:xml:ns:caldav">
<ace>
<principal>
<href>/caldav.php/user4/</href>
</principal>
<grant>
<privilege><read/></privilege>
<privilege><read-current-user-privilege-set/></privilege>
</grant>
</ace>
<ace>
<principal><authenticated/></principal>
<grant>
<privilege/>
</grant>
</ace>
</acl>
ENDDATA
URL=http://regression.host/caldav.php/user1/
# This is by_collection, and by_principal isn't set, shouldn't it be set?
# WHERE p_by.dav_name = '/user1/'
QUERY
SELECT by_principal, by_collection, privileges, p_to.displayname, to_principal
FROM grants JOIN dav_principal p_to ON (to_principal=principal_id)
LEFT JOIN collection ON (by_collection=collection.collection_id)
LEFT JOIN dav_principal p_by ON (by_principal=p_by.principal_id)
WHERE by_collection = 1609
AND p_to.dav_name = '/user4/'
ORDER BY by_principal, to_principal
ENDQUERY

View File

@ -0,0 +1,50 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
Content-Location: /caldav.php/user1/addresses/
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "43765875e20eef2d841725645b2f3c95"
Content-Length: 1129
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<response>
<href>/caldav.php/user1/addresses/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<C:addressbook/>
</resourcetype>
<displayname>user1 addresses</displayname>
<getlastmodified>Sun, 15 Mar 1998 12:00:00 GMT</getlastmodified>
<creationdate>19570725T120000Z</creationdate>
<getcontentlanguage/>
<supportedlock>
<lockentry>
<lockscope>
<exclusive/>
</lockscope>
<locktype>
<write/>
</locktype>
</lockentry>
</supportedlock>
<owner>
<href>/caldav.php/user1/</href>
</owner>
<current-user-principal>
<href>/caldav.php/user1/</href>
</current-user-principal>
<C:max-resource-size>6550000</C:max-resource-size>
<C:supported-address-data>
<C:address-data content-type="text/vcard" version="3.0"/>
</C:supported-address-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,16 @@
# Test for iPhone devices which incorrectly implement
# DAV:current-user-principal from RFC 5397. They assume that
# current-user-principal is the href for the resource being queried. The
# RFC says it should be the current resource. #Sigh.
#
# See: https://gitlab.com/davical-project/davical/-/issues/335
#
# Ensure that user4 has user1 as the current-user-principal as we're an
# 'iPhone'.
TYPE=PROPFIND
AUTH=user4:user4
HEADER=Content-Type: text/xml; charset="UTF-8"
HEADER=User-Agent: DAVKit/4.0 (728.3); iCalendar/1 (34); iPhone/3.0
HEAD
URL=http://regression.host/caldav.php/user1/addresses

View File

@ -0,0 +1,50 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
Content-Location: /caldav.php/user1/addresses/
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "3f9506c10fe5b434f966d4c82f026c40"
Content-Length: 1129
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<response>
<href>/caldav.php/user1/addresses/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<C:addressbook/>
</resourcetype>
<displayname>user1 addresses</displayname>
<getlastmodified>Sun, 15 Mar 1998 12:00:00 GMT</getlastmodified>
<creationdate>19570725T120000Z</creationdate>
<getcontentlanguage/>
<supportedlock>
<lockentry>
<lockscope>
<exclusive/>
</lockscope>
<locktype>
<write/>
</locktype>
</lockentry>
</supportedlock>
<owner>
<href>/caldav.php/user1/</href>
</owner>
<current-user-principal>
<href>/caldav.php/user4/</href>
</current-user-principal>
<C:max-resource-size>6550000</C:max-resource-size>
<C:supported-address-data>
<C:address-data content-type="text/vcard" version="3.0"/>
</C:supported-address-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,16 @@
# Test for iPhone devices which incorrectly implement
# DAV:current-user-principal from RFC 5397. They assume that
# current-user-principal is the href for the resource being queried. The
# RFC says it should be the current resource. #Sigh.
#
# See: https://gitlab.com/davical-project/davical/-/issues/335
#
# Ensure that user4 has user4 as the current-user-principal as we're not an
# 'iPhone'.
TYPE=PROPFIND
AUTH=user4:user4
HEADER=Content-Type: text/xml; charset="UTF-8"
HEADER=User-Agent: Evolution/1.8.1
HEAD
URL=http://regression.host/caldav.php/user1/addresses