diff --git a/dba/appuser_permissions.txt b/dba/appuser_permissions.txt index 71cf4842..325af656 100644 --- a/dba/appuser_permissions.txt +++ b/dba/appuser_permissions.txt @@ -42,7 +42,6 @@ GRANT SELECT,UPDATE ON usr_user_no_seq ON roles_role_no_seq ON session_session_id_seq - ON principal_principal_id_seq ON principal_type_principal_type_id_seq ON sync_tokens_sync_token_seq diff --git a/dba/base-data.sql b/dba/base-data.sql index c69de848..35509ea1 100644 --- a/dba/base-data.sql +++ b/dba/base-data.sql @@ -20,13 +20,13 @@ SELECT setval('usr_user_no_seq', (SELECT 1000 UNION SELECT user_no FROM usr ORDE INSERT INTO relationship_type ( rt_id, rt_name, confers, bit_confers ) VALUES( 1, 'Administers', 'A', privilege_to_bits('DAV::all') ); -INSERT INTO relationship_type ( rt_id, rt_name, confers ) +INSERT INTO relationship_type ( rt_id, rt_name, confers, bit_confers ) VALUES( 2, 'Can read/write to', 'RW', privilege_to_bits( ARRAY['DAV::read','DAV::write']) ); -INSERT INTO relationship_type ( rt_id, rt_name, confers ) +INSERT INTO relationship_type ( rt_id, rt_name, confers, bit_confers ) VALUES( 3, 'Can read from', 'R', privilege_to_bits( 'DAV::read') ); -INSERT INTO relationship_type ( rt_id, rt_name, confers ) +INSERT INTO relationship_type ( rt_id, rt_name, confers, bit_confers ) VALUES( 4, 'Can see free/busy time of', 'F', privilege_to_bits( 'caldav:read-free-busy') ); INSERT INTO principal_type (principal_type_id, principal_type_desc) VALUES( 1, 'Person' ); diff --git a/dba/caldav_functions.sql b/dba/caldav_functions.sql index 35231ea7..b8e136ac 100644 --- a/dba/caldav_functions.sql +++ b/dba/caldav_functions.sql @@ -246,7 +246,7 @@ CREATE or REPLACE FUNCTION usr_is_role( INT, TEXT ) RETURNS BOOLEAN AS $$ SELECT EXISTS( SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_member.user_no=$1 AND roles.role_name=$2 ) $$ LANGUAGE 'sql' IMMUTABLE STRICT; -CREATE or REPLACE FUNCTION get_permissions( INT, INT ) RETURNS TEXT AS $$ +CREATE or REPLACE FUNCTION legacy_get_permissions( INT, INT ) RETURNS TEXT AS $$ DECLARE in_from ALIAS FOR $1; in_to ALIAS FOR $2; diff --git a/dba/davical.sql b/dba/davical.sql index 6e8ff66c..4e586892 100644 --- a/dba/davical.sql +++ b/dba/davical.sql @@ -38,6 +38,31 @@ END $$ LANGUAGE 'PlPgSQL' IMMUTABLE STRICT; +-- Given an array of verbose DAV: or CalDAV: privilege names return the bitmask +CREATE or REPLACE FUNCTION privilege_to_bits( TEXT[] ) RETURNS BIT(24) AS $$ +DECLARE + raw_privs ALIAS FOR $1; + in_priv TEXT; + out_bits BIT(24); + i INT; + all BIT(24); + start INT; + finish INT; +BEGIN + out_bits := 0::BIT(24); + all := ~ out_bits; + SELECT array_lower(raw_privs,1) INTO start; + SELECT array_upper(raw_privs,1) INTO finish; + FOR i IN start .. finish LOOP + SELECT out_bits | privilege_to_bits(raw_privs[i]) INTO out_bits; + IF out_bits = all THEN + RETURN all; + END IF; + END LOOP; + RETURN out_bits; +END +$$ +LANGUAGE 'PlPgSQL' IMMUTABLE STRICT; -- This sequence is used in a number of places so that any DAV resource will have a unique ID @@ -139,7 +164,7 @@ CREATE TABLE relationship_type ( rt_togroup BOOLEAN, confers TEXT DEFAULT 'RW', rt_fromgroup BOOLEAN, - bit_confers BIT(24) DEFAULT legacy_privilege_to_bits('RW') + bit_confers BIT(24) DEFAULT privilege_to_bits(ARRAY['DAV::read','DAV::write']) ); @@ -147,7 +172,7 @@ CREATE TABLE relationship ( from_user INT REFERENCES usr (user_no) ON UPDATE CASCADE ON DELETE CASCADE, to_user INT REFERENCES usr (user_no) ON UPDATE CASCADE ON DELETE CASCADE, rt_id INT REFERENCES relationship_type (rt_id) ON UPDATE CASCADE ON DELETE CASCADE, - bit_confers BIT(24) DEFAULT legacy_privilege_to_bits('RW'), + confers BIT(24) DEFAULT privilege_to_bits(ARRAY['DAV::read','DAV::write']), PRIMARY KEY ( from_user, to_user, rt_id ) ); @@ -230,9 +255,8 @@ CREATE TABLE principal_type ( -- web needs SELECT,INSERT,UPDATE,DELETE -DROP TABLE principal CASCADE; CREATE TABLE principal ( - principal_id DEFAULT nextval('dav_id_seq') PRIMARY KEY, + principal_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY, type_id INT8 NOT NULL REFERENCES principal_type(principal_type_id) ON UPDATE CASCADE ON DELETE RESTRICT DEFERRABLE, user_no INT8 NULL REFERENCES usr(user_no) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, displayname TEXT, diff --git a/dba/patches/1.2.6.sql b/dba/patches/1.2.6.sql index 613aa1dc..36cedef6 100644 --- a/dba/patches/1.2.6.sql +++ b/dba/patches/1.2.6.sql @@ -498,7 +498,7 @@ ALTER TABLE relationship_type ADD COLUMN bit_confers BIT(24) DEFAULT privilege_t UPDATE relationship_type SET bit_confers = legacy_privilege_to_bits(confers); ALTER TABLE relationship ADD COLUMN confers BIT(24) DEFAULT privilege_to_bits('caldav:read-free-busy'); -UPDATE relationship r SET confers = bit_confers FROM relationship_type rt WHERE rt.rt_id=r.rt_id; +UPDATE relationship r SET confers = (SELECT bit_confers FROM relationship_type rt WHERE rt.rt_id=r.rt_id); ALTER TABLE collection ADD COLUMN default_privileges BIT(24) DEFAULT privilege_to_bits('caldav:read-free-busy'); @@ -509,7 +509,7 @@ INSERT INTO principal_type (principal_type_id, principal_type_desc) VALUES( 3, ' -- web needs SELECT,INSERT,UPDATE,DELETE DROP TABLE principal CASCADE; CREATE TABLE principal ( - principal_id DEFAULT nextval('dav_id_seq') PRIMARY KEY, + principal_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY, type_id INT8 NOT NULL REFERENCES principal_type(principal_type_id) ON UPDATE CASCADE ON DELETE RESTRICT DEFERRABLE, user_no INT8 NULL REFERENCES usr(user_no) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, displayname TEXT, diff --git a/dba/sample-data.sql b/dba/sample-data.sql index edf5fcf2..b0ef3677 100644 --- a/dba/sample-data.sql +++ b/dba/sample-data.sql @@ -28,8 +28,10 @@ INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullna INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email ) VALUES( 100, TRUE, current_date, current_date, 'resource1', '*salt*unpossible', 'Resource 1', 'resource1@example.net' ); +INSERT INTO role_member (user_no, role_no) VALUES( 100, 3); INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email ) 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, 3); 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' ); @@ -45,10 +47,24 @@ UPDATE usr SET joined = '2009-06-01', updated = '2009-06-02'; INSERT INTO collection (user_no, parent_container, dav_name, dav_etag, dav_displayname, is_calendar, created, modified, - public_events_only, publicly_readable, collection_id) + public_events_only, publicly_readable, collection_id, resourcetypes ) SELECT user_no, '/' || username || '/', '/' || username || '/home/', md5(username), username || ' home', TRUE, '2009-06-03', '2009-06-04', - FALSE, FALSE, user_no FROM usr; + FALSE, FALSE, user_no, '' + FROM usr; + +INSERT INTO principal (type_id, user_no, displayname, active, default_privileges) + SELECT 1, user_no, fullname, active, 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) ; + +INSERT INTO principal (type_id, user_no, displayname, active, default_privileges) + SELECT 2, user_no, fullname, active, privilege_to_bits(ARRAY['read','schedule-send','schedule-deliver']) FROM usr + WHERE EXISTS(SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_name = 'Resource' AND role_member.user_no = usr.user_no); + +INSERT INTO principal (type_id, user_no, displayname, active, default_privileges) + SELECT 3, user_no, fullname, active, 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 = 'Group' AND role_member.user_no = usr.user_no); SELECT setval('dav_id_seq', 1000); @@ -68,11 +84,32 @@ INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 200, 1 ); INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 20, 2 ); INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 10, 2 ); + -- Between a team INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 20, 300, 3 ); INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 10, 300, 3 ); INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 300, 3 ); +INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 300, 20, 3 ); +INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 300, 10, 3 ); +INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 300, 30, 3 ); -- Granting explicit free/busy permission INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 11, 10, 4 ); INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 10, 11, 4 ); + + +UPDATE relationship r SET confers = (SELECT bit_confers FROM relationship_type rt WHERE rt.rt_id=r.rt_id); + +INSERT INTO group_member ( group_id, member_id) + SELECT g.principal_id, m.principal_id + FROM relationship JOIN principal g ON(to_user=g.user_no AND g.type_id = 3) -- Group + JOIN principal m ON(from_user=m.user_no AND m.type_id = 1); -- Person + +INSERT INTO grants ( by_principal, dav_name, to_principal, privileges, is_group ) + SELECT pby.principal_id AS by_principal, '/' ||t.username||'/' AS dav_name, pto.principal_id AS to_principal, + confers AS privileges, pto.type_id > 2 AS is_group + FROM relationship r JOIN usr f ON(f.user_no=r.from_user) + JOIN usr t ON(t.user_no=r.to_user) + JOIN principal pby ON(t.user_no=pby.user_no) + JOIN principal pto ON(pto.user_no=f.user_no) + WHERE rt_id < 4 AND pby.type_id < 3; diff --git a/testing/tests/regression-suite/524-iCal-PROPFIND.result b/testing/tests/regression-suite/524-iCal-PROPFIND.result index 124b844b..09281589 100644 --- a/testing/tests/regression-suite/524-iCal-PROPFIND.result +++ b/testing/tests/regression-suite/524-iCal-PROPFIND.result @@ -1,8 +1,8 @@ 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, extended-mkcol -ETag: "432aa6b31d8dbe82651aef6bac55ea55" -Content-Length: 3515 +ETag: "cc705bcb25130c21378d93e32747c072" +Content-Length: 3601 Content-Type: text/xml; charset="utf-8" @@ -75,6 +75,7 @@ Content-Type: text/xml; charset="utf-8" /caldav.php/user1/ + /caldav.php/teamclient1/ /caldav.php/teamclient1/ @@ -82,9 +83,10 @@ Content-Type: text/xml; charset="utf-8" /caldav.php/assistant1/calendar-proxy-read/ /manager1/calendar-proxy-read/ - "d6996992ae401eb02ed8fed0bfb22895" + "81833b8410a85c2e86dd32ae4470e72b" /caldav.php/user1/ + /caldav.php/teamclient1/ HTTP/1.1 200 OK diff --git a/testing/tests/regression-suite/553-iPhone-PROPFIND.result b/testing/tests/regression-suite/553-iPhone-PROPFIND.result index f7e83a01..7558f9ae 100644 --- a/testing/tests/regression-suite/553-iPhone-PROPFIND.result +++ b/testing/tests/regression-suite/553-iPhone-PROPFIND.result @@ -1,7 +1,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, extended-mkcol -ETag: "67c73d7155944138de99f14a0872e727" +ETag: "5771fd61ef8348f364c7fc69c578028a" Transfer-Encoding: chunked Content-Type: text/xml; charset="utf-8" @@ -285,7 +285,7 @@ Content-Type: text/xml; charset="utf-8" /user1/calendar-proxy-read/ - "3646538a5bdbcc9a144ee36f36000214" + "c26fa324d66fa84a0da8e1ec8c4566fd" diff --git a/testing/tests/regression-suite/554-iPhone-PROPFIND.result b/testing/tests/regression-suite/554-iPhone-PROPFIND.result index f7e83a01..7558f9ae 100644 --- a/testing/tests/regression-suite/554-iPhone-PROPFIND.result +++ b/testing/tests/regression-suite/554-iPhone-PROPFIND.result @@ -1,7 +1,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, extended-mkcol -ETag: "67c73d7155944138de99f14a0872e727" +ETag: "5771fd61ef8348f364c7fc69c578028a" Transfer-Encoding: chunked Content-Type: text/xml; charset="utf-8" @@ -285,7 +285,7 @@ Content-Type: text/xml; charset="utf-8" /user1/calendar-proxy-read/ - "3646538a5bdbcc9a144ee36f36000214" + "c26fa324d66fa84a0da8e1ec8c4566fd"