Add ROOM as a principal type

This hopefully resolves #282.
This commit is contained in:
Andrew Ruthven 2024-01-21 17:57:04 +13:00
parent bc33199083
commit 1ca8284bdc
25 changed files with 251 additions and 33 deletions

42
dba/patches/1.3.6.sql Normal file
View File

@ -0,0 +1,42 @@
-- Add CalDAV labels to principal types to remove hardcoded ID -> Label
-- mappings in code.
--
-- List is from: https://tools.ietf.org/html/rfc5545#section-3.2.3
BEGIN;
SELECT check_db_revision(1,3,5);
INSERT INTO roles ( role_no, role_name ) VALUES( 5, 'Room');
ALTER TABLE principal_type ADD COLUMN label VARCHAR;
-- Add labels
UPDATE principal_type
SET label = 'INDIVIDUAL'
WHERE principal_type_id = 1;
UPDATE principal_type
SET label = 'RESOURCE'
WHERE principal_type_id = 2;
UPDATE principal_type
SET label = 'GROUP'
WHERE principal_type_id = 3;
-- Add suport for the ROOM principal type.
-- Having hardcoded IDs pains me. A lot.
INSERT INTO principal_type
(principal_type_id, principal_type_desc, label)
VALUES (4, 'Room', 'ROOM');
-- Ensure that the sequence is primed, on my instance the sequence had
-- last_value as 0.
SELECT setval('principal_type_principal_type_id_seq',
(SELECT max(principal_type_id) FROM principal_type)
);
-- http://blogs.transparent.com/polish/names-of-the-months-and-their-meaning/
SELECT new_db_revision(1,3,6, 'Czerwiec');
COMMIT;
ROLLBACK;

View File

@ -560,20 +560,8 @@ class DAVPrincipal extends Principal
* and https://tools.ietf.org/html/rfc5545#section-3.2.3
*/
$type = 'UNKNOWN';
if ( isset($this->type_id) ) {
switch ( $this->type_id ) {
case 1:
$type = 'INDIVIDUAL';
break;
case 2:
$type = 'RESOURCE';
break;
case 3:
$type = 'GROUP';
break;
// 'ROOM' type is not supported yet
}
}
if ( isset($this->type_label) )
$type = $this->type_label;
$reply->CalDAVElement($prop, 'calendar-user-type', $type);
break;

View File

@ -60,6 +60,7 @@ class Principal {
public $date_format_type;
public $locale;
public $type_id;
public $type_label;
public $displayname;
public $default_privileges;
public $is_principal;
@ -193,7 +194,7 @@ class Principal {
}
}
$sql = 'SELECT *, ';
$sql = 'SELECT dav_principal.*, principal_type.label AS type_label, ';
if ( isset($session->principal_id) && $session->principal_id !== false ) {
$sql .= 'pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS privileges ';
$params = array( ':session_principal' => $session->principal_id, ':scan_depth' => $c->permission_scan_depth );
@ -202,7 +203,7 @@ class Principal {
$sql .= '0::BIT(24) AS privileges ';
$params = array( );
}
$sql .= 'FROM dav_principal WHERE ';
$sql .= 'FROM dav_principal LEFT JOIN principal_type ON (type_id = principal_type_id) WHERE ';
switch ( $type ) {
case 'username':
$sql .= 'lower(username)=lower(text(:param))';

View File

@ -102,6 +102,8 @@ function CreateHomeCollections( $username, $default_timezone = null ) {
'name' => $c->home_in_calendar_name,
'displayname_suffix' => ' Inbox'
);
// XXX Should we not do this for ROOMS?
if( !empty($c->home_addressbook_name) )
$c->default_collections[] = array(
'type' => 'addressbook',

View File

@ -16,8 +16,24 @@ if ( isset($CS_search_test) && $CS_search_test == 'anyof' ) {
$clause_joiner = " OR ";
}
# Calendar on macOS searches for the principal type as an attribute.
$principal_type = $xmltree->GetAttribute('type');
$params = array();
$typewhere = "";
$where = "";
$join = "";
dbg_error_log("SEARCH", "type: '%s'", $principal_type );
// This is ugly, but macOS specifies the calendar type as an attribute
if (isset($principal_type)) {
$typewhere = 'principal_type.label = :principal_type';
$params[':principal_type'] = $principal_type;
$join = 'LEFT JOIN principal_type ON (type_id = principal_type_id)';
}
foreach( $searches AS $k => $search ) {
$qry_props = $search->GetPath('/DAV::property-search/DAV::prop/*'); // There may be many
$match = $search->GetPath('/DAV::property-search/DAV::match'); // There may only be one
@ -61,8 +77,16 @@ foreach( $searches AS $k => $search ) {
$where .= sprintf( "%s(%s)", ($where == "" ? "" : $clause_joiner), $subwhere );
}
}
if ( $where != "" ) $where = "WHERE $where";
$sql = "SELECT * FROM dav_principal $where ORDER BY principal_id LIMIT 100";
if ( $where != "" && $typewhere != "" ) {
$where = "WHERE $typewhere AND $where";
} elseif ( $where != "" ) {
$where = "WHERE $where";
} elseif ( $typewhere != "" ) {
$where = "WHERE $typewhere";
}
$sql = "SELECT * FROM dav_principal $join $where ORDER BY principal_id LIMIT 100";
$qry = new AwlQuery($sql, $params);

View File

@ -38,6 +38,7 @@ $user_menu->AddOption(translate('View My Details'),$c->base_url.'/admin.php?acti
$user_menu->AddOption(translate('List Users'),$c->base_url.'/admin.php?action=browse&t=principal&type=1');
$user_menu->AddOption(translate('List Resources'),$c->base_url.'/admin.php?action=browse&t=principal&type=2');
$user_menu->AddOption(translate('List Groups'),$c->base_url.'/admin.php?action=browse&t=principal&type=3');
$user_menu->AddOption(translate('List Rooms'),$c->base_url.'/admin.php?action=browse&t=principal&type=4');
$admin_menu = new MenuSet('submenu', 'submenu', 'submenu_active');
if ( $session->AllowedTo('Admin' )) {

View File

@ -762,6 +762,9 @@ msgstr ""
msgid "List Resources"
msgstr ""
msgid "List Rooms"
msgstr ""
msgid "List Users"
msgstr ""

View File

@ -207,12 +207,15 @@ initialise_regression() {
drop_database ${DBNAME}
TEST="Create-Database"
../dba/create-database.sh ${DBNAME} 'nimda' >"${RESULTS}/${TEST}" 2>&1
../dba/create-database.sh ${DBNAME} 'nimda' \
| sed -r 's/is version [.0-9]+/is version XX/' 2>&1 \
> "${RESULTS}/${TEST}"
check_result "${TEST}"
TEST="Upgrade-Database"
../dba/update-davical-database ${DBAOPTS} --dbname=${DBNAME} --nopatch --appuser davical_app --owner davical_dba >"${RESULTS}/${TEST}" \
| sed -r 's/is version [.0-9]+/is version XX/'2>&1
../dba/update-davical-database ${DBAOPTS} --dbname=${DBNAME} --nopatch --appuser davical_app --owner davical_dba \
| sed -r 's/is version [.0-9]+/is version XX/' 2>&1 \
> "${RESULTS}/${TEST}"
check_result "${TEST}"
if [ -f "${REGRESSION}/sample-data.sql" ]; then

View File

@ -1,5 +1,13 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
The database is version XX currently at revision 1.3.5.
Applying patch 1.3.6.sql ... succeeded.
Successfully applied 1 patches.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.

View File

@ -1,4 +1,4 @@
The database is version XX currently at revision 1.3.5.
The database is version XX currently at revision 1.3.6.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.

View File

@ -1,5 +1,13 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
The database is version XX currently at revision 1.3.5.
Applying patch 1.3.6.sql ... succeeded.
Successfully applied 1 patches.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.

View File

@ -1,4 +1,4 @@
The database is version XX currently at revision 1.3.5.
The database is version XX currently at revision 1.3.6.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.

View File

@ -0,0 +1,14 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
NOTE
====
* The password for the 'admin' user has been set to 'nimda'
Thanks for trying DAViCal! Check the configuration in /etc/davical/config.php.
For help, look at our website and wiki, or visit #davical on irc.oftc.net.

View File

@ -0,0 +1,7 @@
The database is version XX currently at revision 1.3.3.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.

View File

@ -2,7 +2,7 @@ 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: "ae8aac5229a8a5d9ee7c86100322162d"
ETag: "37368bb270ff51917cca6373cacd5681"
Content-Length: 28703
Content-Type: text/xml; charset="utf-8"
@ -443,7 +443,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href>
</owner>
<resource-id>
<href>/caldav.php/.resources/1523</href>
<href>/caldav.php/.resources/1525</href>
</resource-id>
<resourcetype>
<collection/>
@ -592,7 +592,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href>
</owner>
<resource-id>
<href>/caldav.php/.resources/1541</href>
<href>/caldav.php/.resources/1543</href>
</resource-id>
<resourcetype>
<collection/>
@ -726,7 +726,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href>
</owner>
<resource-id>
<href>/caldav.php/.resources/1542</href>
<href>/caldav.php/.resources/1544</href>
</resource-id>
<resourcetype>
<collection/>
@ -852,7 +852,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href>
</owner>
<resource-id>
<href>/caldav.php/.resources/1547</href>
<href>/caldav.php/.resources/1549</href>
</resource-id>
<resourcetype>
<collection/>

View File

@ -0,0 +1,55 @@
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: "ba0504f201a1e6dcd1ff676796726780"
Content-Length: 1237
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" xmlns:C1="http://calendarserver.org/ns/">
<response>
<href>/caldav.php/room1/</href>
<propstat>
<prop>
<C:calendar-user-address-set>
<href>mailto:room1@example.net</href>
<href>/caldav.php/room1/</href>
</C:calendar-user-address-set>
<principal-URL>
<href>/caldav.php/room1/</href>
</principal-URL>
<C:calendar-user-type>ROOM</C:calendar-user-type>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<C1:record-type/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
<response>
<href>/caldav.php/room2/</href>
<propstat>
<prop>
<C:calendar-user-address-set>
<href>mailto:room2@example.net</href>
<href>/caldav.php/room2/</href>
</C:calendar-user-address-set>
<principal-URL>
<href>/caldav.php/room2/</href>
</principal-URL>
<C:calendar-user-type>ROOM</C:calendar-user-type>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<C1:record-type/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,24 @@
#
# Query from Calendar on macOS >= Ventura
#
# Should only report principals that match ROOM
#
TYPE=REPORT
URL=http://regression.host/caldav.php/user1/home/
HEADER=User-Agent: DAViCal/RegressionTest
HEADER=Content-Type: text/xml
HEADER=Depth: 0
HEAD
BEGINDATA
<?xml version="1.0" encoding="UTF-8"?>
<A:principal-property-search xmlns:A="DAV:" type="ROOM" test="anyof">
<A:prop>
<B:calendar-user-address-set xmlns:B="urn:ietf:params:xml:ns:caldav"/>
<A:principal-URL/>
<B:calendar-user-type xmlns:B="urn:ietf:params:xml:ns:caldav"/>
<C:record-type xmlns:C="http://calendarserver.org/ns/"/>
</A:prop>
</A:principal-property-search>
ENDDATA

View File

@ -1,5 +1,13 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
The database is version XX currently at revision 1.3.5.
Applying patch 1.3.6.sql ... succeeded.
Successfully applied 1 patches.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.

View File

@ -1,4 +1,4 @@
The database is version XX currently at revision 1.3.5.
The database is version XX currently at revision 1.3.6.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.

View File

@ -5,7 +5,7 @@
setval
--------
1013
1015
(1 row)
setval
@ -105,7 +105,7 @@
setval
--------
1
4
(1 row)
setval

View File

@ -33,6 +33,13 @@ INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullna
VALUES( 101, TRUE, current_date, current_date, 'resource2', '*salt*unpossible', 'Resource 2', 'resource2@example.net' );
INSERT INTO role_member (user_no, role_no) VALUES( 101, 4);
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
VALUES( 150, TRUE, current_date, current_date, 'room1', '*salt*unpossible', 'Room 1', 'room1@example.net' );
INSERT INTO role_member (user_no, role_no) VALUES( 150, 5);
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
VALUES( 151, TRUE, current_date, current_date, 'room2', '*salt*unpossible', 'Room 2', 'room2@example.net' );
INSERT INTO role_member (user_no, role_no) VALUES( 151, 5);
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
VALUES( 200, TRUE, current_date, current_date, 'resmgr1', '*salt*unpossible', 'Resource Managers', 'resource-managers@example.net' );
INSERT INTO role_member (user_no, role_no) VALUES( 200, 2);
@ -41,6 +48,7 @@ INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullna
VALUES( 300, TRUE, current_date, current_date, 'teamclient1', '*salt*unpossible', 'Team for Client1', 'team-client1@example.net' );
INSERT INTO role_member (user_no, role_no) VALUES( 300, 2);
SELECT setval('usr_user_no_seq', 1000);
SELECT setval('dav_id_seq', 1000);
@ -67,6 +75,7 @@ INSERT INTO principal (type_id, user_no, displayname, default_privileges)
SELECT 1, user_no, fullname, privilege_to_bits(ARRAY['read-free-busy','schedule-send','schedule-deliver']) FROM usr
WHERE NOT EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Group' AND role_member.user_no = usr.user_no)
AND NOT EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Resource' AND role_member.user_no = usr.user_no)
AND NOT EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Room' AND role_member.user_no = usr.user_no)
AND NOT EXISTS(SELECT 1 FROM principal WHERE principal.user_no = usr.user_no) ORDER BY user_no;
INSERT INTO principal (type_id, user_no, displayname, default_privileges)
@ -79,6 +88,11 @@ INSERT INTO principal (type_id, user_no, displayname, default_privileges)
WHERE EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Group' AND role_member.user_no = usr.user_no)
AND NOT EXISTS(SELECT 1 FROM principal WHERE principal.user_no = usr.user_no) ORDER BY user_no;
INSERT INTO principal (type_id, user_no, displayname, default_privileges)
SELECT 4, user_no, fullname, privilege_to_bits(ARRAY['read-free-busy','schedule-send','schedule-deliver']) FROM usr
WHERE EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Room' AND role_member.user_no = usr.user_no)
AND NOT EXISTS(SELECT 1 FROM principal WHERE principal.user_no = usr.user_no) ORDER BY user_no;
-- Set the insert sequence to the next number, with a minimum of 1000
SELECT setval('relationship_type_rt_id_seq', (SELECT 10 UNION SELECT rt_id FROM relationship_type ORDER BY 1 DESC LIMIT 1) );

View File

@ -1,5 +1,13 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
The database is version XX currently at revision 1.3.5.
Applying patch 1.3.6.sql ... succeeded.
Successfully applied 1 patches.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.

View File

@ -1,4 +1,4 @@
The database is version XX currently at revision 1.3.5.
The database is version XX currently at revision 1.3.6.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.

View File

@ -1,5 +1,13 @@
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.
RRULE functions updated.
Database permissions updated.
The database is version XX currently at revision 1.3.5.
Applying patch 1.3.6.sql ... succeeded.
Successfully applied 1 patches.
Supported locales updated.
Updated view: dav_principal.sql applied.
CalDAV functions updated.

View File

@ -1,4 +1,4 @@
The database is version XX currently at revision 1.3.5.
The database is version XX currently at revision 1.3.6.
No patches were applied.
Supported locales updated.
Updated view: dav_principal.sql applied.