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 * and https://tools.ietf.org/html/rfc5545#section-3.2.3
*/ */
$type = 'UNKNOWN'; $type = 'UNKNOWN';
if ( isset($this->type_id) ) { if ( isset($this->type_label) )
switch ( $this->type_id ) { $type = $this->type_label;
case 1:
$type = 'INDIVIDUAL';
break;
case 2:
$type = 'RESOURCE';
break;
case 3:
$type = 'GROUP';
break;
// 'ROOM' type is not supported yet
}
}
$reply->CalDAVElement($prop, 'calendar-user-type', $type); $reply->CalDAVElement($prop, 'calendar-user-type', $type);
break; break;

View File

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

View File

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

View File

@ -16,8 +16,24 @@ if ( isset($CS_search_test) && $CS_search_test == 'anyof' ) {
$clause_joiner = " OR "; $clause_joiner = " OR ";
} }
# Calendar on macOS searches for the principal type as an attribute.
$principal_type = $xmltree->GetAttribute('type');
$params = array(); $params = array();
$typewhere = "";
$where = ""; $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 ) { foreach( $searches AS $k => $search ) {
$qry_props = $search->GetPath('/DAV::property-search/DAV::prop/*'); // There may be many $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 $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 ); $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); $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 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 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 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'); $admin_menu = new MenuSet('submenu', 'submenu', 'submenu_active');
if ( $session->AllowedTo('Admin' )) { if ( $session->AllowedTo('Admin' )) {

View File

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

View File

@ -207,12 +207,15 @@ initialise_regression() {
drop_database ${DBNAME} drop_database ${DBNAME}
TEST="Create-Database" 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}" check_result "${TEST}"
TEST="Upgrade-Database" TEST="Upgrade-Database"
../dba/update-davical-database ${DBAOPTS} --dbname=${DBNAME} --nopatch --appuser davical_app --owner davical_dba >"${RESULTS}/${TEST}" \ ../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 | sed -r 's/is version [.0-9]+/is version XX/' 2>&1 \
> "${RESULTS}/${TEST}"
check_result "${TEST}" check_result "${TEST}"
if [ -f "${REGRESSION}/sample-data.sql" ]; then 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. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.
CalDAV functions updated. 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. No patches were applied.
Supported locales updated. Supported locales updated.
Updated view: dav_principal.sql applied. 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. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.
CalDAV functions updated. 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. No patches were applied.
Supported locales updated. Supported locales updated.
Updated view: dav_principal.sql applied. 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 Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "ae8aac5229a8a5d9ee7c86100322162d" ETag: "37368bb270ff51917cca6373cacd5681"
Content-Length: 28703 Content-Length: 28703
Content-Type: text/xml; charset="utf-8" Content-Type: text/xml; charset="utf-8"
@ -443,7 +443,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href> <href>/caldav.php/user1/</href>
</owner> </owner>
<resource-id> <resource-id>
<href>/caldav.php/.resources/1523</href> <href>/caldav.php/.resources/1525</href>
</resource-id> </resource-id>
<resourcetype> <resourcetype>
<collection/> <collection/>
@ -592,7 +592,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href> <href>/caldav.php/user1/</href>
</owner> </owner>
<resource-id> <resource-id>
<href>/caldav.php/.resources/1541</href> <href>/caldav.php/.resources/1543</href>
</resource-id> </resource-id>
<resourcetype> <resourcetype>
<collection/> <collection/>
@ -726,7 +726,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href> <href>/caldav.php/user1/</href>
</owner> </owner>
<resource-id> <resource-id>
<href>/caldav.php/.resources/1542</href> <href>/caldav.php/.resources/1544</href>
</resource-id> </resource-id>
<resourcetype> <resourcetype>
<collection/> <collection/>
@ -852,7 +852,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/</href> <href>/caldav.php/user1/</href>
</owner> </owner>
<resource-id> <resource-id>
<href>/caldav.php/.resources/1547</href> <href>/caldav.php/.resources/1549</href>
</resource-id> </resource-id>
<resourcetype> <resourcetype>
<collection/> <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. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.
CalDAV functions updated. 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. No patches were applied.
Supported locales updated. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.

View File

@ -5,7 +5,7 @@
setval setval
-------- --------
1013 1015
(1 row) (1 row)
setval setval
@ -105,7 +105,7 @@
setval setval
-------- --------
1 4
(1 row) (1 row)
setval 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' ); 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 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 ) 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' ); 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); 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' ); 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); INSERT INTO role_member (user_no, role_no) VALUES( 300, 2);
SELECT setval('usr_user_no_seq', 1000); SELECT setval('usr_user_no_seq', 1000);
SELECT setval('dav_id_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 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) 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 = '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; 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) 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) 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; 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 -- 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) ); 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. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.
CalDAV functions updated. 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. No patches were applied.
Supported locales updated. Supported locales updated.
Updated view: dav_principal.sql applied. 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. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.
CalDAV functions updated. 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. No patches were applied.
Supported locales updated. Supported locales updated.
Updated view: dav_principal.sql applied. Updated view: dav_principal.sql applied.