CLASS is an optional field, don't set it to PUBLIC

As specified in RFC5545 the CLASS field is optional, and if it isn't present
is treated as PUBLIC. To allow a is-not-defined prop-filter to find
resources without CLASS set, we need to not store in the database. This
turns out to be okay, because to enforce privacy we always check to see if
it is PRIVATE or CONFIDENTIAL. We never check to see if it is PUBLIC.

Closes #284.
This commit is contained in:
Andrew Ruthven 2023-02-05 01:32:16 +13:00 committed by Florian Schlichting
parent 4a380b12a2
commit 149ec3555f
8 changed files with 171 additions and 21 deletions

View File

@ -180,11 +180,7 @@ class WritableCollection extends DAVResource {
$calitem_params[':dtstamp'] = $dtstamp;
$class = $first->GetPValue('CLASS');
/*
* It seems that some calendar clients don't set a class...
* RFC2445, 4.8.1.3: Default is PUBLIC
*/
if ( $this->IsPublicOnly() || !isset($class) || $class == '' ) {
if ( $this->IsPublicOnly() && isset($class)) {
$class = 'PUBLIC';
}
$calitem_params[':class'] = $class;

View File

@ -1170,9 +1170,8 @@ EOSQL;
if ( empty($dtstamp) ) $dtstamp = $last_modified;
$calitem_params[':dtstamp'] = $dtstamp;
/** RFC2445, 4.8.1.3: Default is PUBLIC, or also if overridden by the collection settings */
$class = ($collection->public_events_only == 't' ? 'PUBLIC' : $first->GetPValue('CLASS') );
if ( !isset($class) || $class == '' ) $class = 'PUBLIC';
/** Allow overridding class by the collection settings */
$class = ($collection->public_events_only == 't' && isset($class) ? 'PUBLIC' : $first->GetPValue('CLASS') );
$calitem_params[':class'] = $class;
@ -1534,18 +1533,10 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle
$class = $first->GetPValue('CLASS');
/* Check and see if we should over ride the class. */
/** @todo is there some way we can move this out of this function? Or at least get rid of the need for the SQL query here. */
if ( public_events_only($user_no, $path) ) {
if ( public_events_only($user_no, $path) && isset($class) ) {
$class = 'PUBLIC';
}
/*
* It seems that some calendar clients don't set a class...
* RFC2445, 4.8.1.3:
* Default is PUBLIC
*/
if ( !isset($class) || $class == '' ) {
$class = 'PUBLIC';
}
$calitem_params[':class'] = $class;
/** Calculate what timezone to set, first, if possible */

View File

@ -125,6 +125,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
case 'priority':
case 'status':
case 'class':
if ($not_defined == "not ") {
// "not IS NOT NULL" is a syntax error in SQL.
$property_defined_match = "IS NULL";

View File

@ -18,8 +18,8 @@ UID:19920901T130000Z-123407@host.com
DTSTAMP:19920901T130000Z
DTSTART:19920415T133000Z
DUE:19920516T045959Z
SUMMARY:Status is set to COMPLETED, empty URL
CLASS:CONFIDENTIAL
SUMMARY:Status is set to COMPLETED, empty URL, CLASS set
CLASS:PUBLIC
CATEGORIES:FAMILY,FINANCE
STATUS:COMPLETED
URL:
@ -30,10 +30,9 @@ BEGIN:VTODO
UID:19920901T130000Z-123408@host.com
DTSTAMP:19920901T130000Z
DTSTART:19920415T133000Z
SUMMARY:Status is IN-PROCESS, URL is set
SUMMARY:Status is IN-PROCESS, URL is set, CLASS isn't set
STATUS:IN-PROCESS
URL:https://www.davical.org
CLASS:CONFIDENTIAL
CATEGORIES:FAMILY,FINANCE
PRIORITY:1
END:VTODO

View File

@ -0,0 +1,62 @@
HTTP/1.1 207 Multi-Status
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
ETag: "c073b3f2dd8d609971aaafee83aa4002"
Content-Length: 1321
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<response>
<href>/caldav.php/user1/events/19970901T130000Z-123405host.com.ics</href>
<propstat>
<prop>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//davical.org//NONSGML AWL Calendar//EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTODO
UID:19970901T130000Z-123405@host.com
DTSTAMP:19970901T130000Z
DTSTART:19970415T133000Z
DUE:19970516T045959Z
SUMMARY:Status is not set
CLASS:CONFIDENTIAL
CATEGORIES:FAMILY,FINANCE
PRIORITY:1
END:VTODO
END:VCALENDAR
</C:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/events/19920901T130000Z-123407host.com.ics</href>
<propstat>
<prop>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//davical.org//NONSGML AWL Calendar//EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTODO
UID:19920901T130000Z-123407@host.com
DTSTAMP:19920901T130000Z
DTSTART:19920415T133000Z
DUE:19920516T045959Z
SUMMARY:Status is set to COMPLETED, empty URL, CLASS set
CLASS:PUBLIC
CATEGORIES:FAMILY,FINANCE
STATUS:COMPLETED
URL:
COMPLETED:19940101T000000Z
PRIORITY:1
END:VTODO
END:VCALENDAR
</C:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,33 @@
#
# is-defined REPORT
#
# Regression test for https://gitlab.com/davical-project/davical/-/issues/279
#
# Check that CLASS is defined.
#
TYPE=REPORT
URL=http://regression.host/caldav.php/user1/events/
HEADER=Content-Type: text/xml; charset="UTF-8"
HEADER=Depth: 0
HEAD
BEGINDATA
<?xml version='1.0' encoding='utf-8'?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VTODO">
<C:prop-filter name="CLASS">
<C:is-defined/>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
ENDDATA

View File

@ -0,0 +1,35 @@
HTTP/1.1 207 Multi-Status
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
ETag: "b9f1d001b8dd22ce62bf8e98c0bbca20"
Content-Length: 721
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<response>
<href>/caldav.php/user1/events/19920901T130000Z-123408host.com.ics</href>
<propstat>
<prop>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//davical.org//NONSGML AWL Calendar//EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTODO
UID:19920901T130000Z-123408@host.com
DTSTAMP:19920901T130000Z
DTSTART:19920415T133000Z
SUMMARY:Status is IN-PROCESS, URL is set, CLASS isn't set
STATUS:IN-PROCESS
URL:https://www.davical.org
CATEGORIES:FAMILY,FINANCE
PRIORITY:1
END:VTODO
END:VCALENDAR
</C:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,33 @@
#
# is-not-defined REPORT
#
# Regression test for https://gitlab.com/davical-project/davical/-/issues/279
#
# Check that CLASS is not defined.
#
TYPE=REPORT
URL=http://regression.host/caldav.php/user1/events/
HEADER=Content-Type: text/xml; charset="UTF-8"
HEADER=Depth: 0
HEAD
BEGINDATA
<?xml version='1.0' encoding='utf-8'?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VTODO">
<C:prop-filter name="CLASS">
<C:is-not-defined/>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
ENDDATA