Replaced the old get_permissions() call with the new permissions model.

This commit is contained in:
Andrew McMillan 2009-12-21 13:04:25 +13:00
parent 50ddbe6272
commit 19199d5f86
31 changed files with 1174 additions and 229 deletions

View File

@ -900,9 +900,11 @@ BEGIN
SELECT bit_or(subquery.privileges) INTO out_conferred FROM
(SELECT privileges FROM grants WHERE by_principal = in_grantor AND to_principal = in_accessor AND NOT is_group AND by_collection IS NULL
UNION
UNION
SELECT privileges FROM grants JOIN group_member ON (to_principal=group_id AND member_id=in_accessor)
WHERE by_principal = in_grantor AND is_group AND by_collection IS NULL
UNION
SELECT 32::BIT(24) FROM group_member WHERE group_id = in_grantor AND member_id=in_accessor
) AS subquery ;
IF out_conferred IS NULL THEN
SELECT default_privileges INTO out_conferred FROM principal WHERE principal_id = in_grantor;
@ -913,6 +915,7 @@ END;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
-- Privileges from accessor to grantor, by user_no
CREATE or REPLACE FUNCTION user_privileges( INT8, INT8 ) RETURNS BIT(24) AS $$
DECLARE
@ -927,10 +930,19 @@ BEGIN
END IF;
SELECT bit_or(subquery.privileges) INTO out_conferred FROM
(SELECT privileges FROM grants JOIN principal ON (to_principal=principal_id) WHERE user_no = in_grantor AND to_principal = in_accessor AND NOT is_group AND by_collection IS NULL
UNION
SELECT privileges FROM grants JOIN group_member ON (to_principal=group_id AND member_id=in_accessor) JOIN principal ON (by_principal=principal_id)
WHERE user_no = in_grantor AND is_group AND by_collection IS NULL
(SELECT privileges FROM grants JOIN principal by_p ON (by_principal=by_p.principal_id)
JOIN principal to_p ON (to_principal=to_p.principal_id)
WHERE by_p.user_no = in_grantor AND to_p.user_no = in_accessor AND by_collection IS NULL
UNION
SELECT privileges FROM grants JOIN group_member ON (to_principal=group_id AND member_id=in_accessor)
JOIN principal by_p ON (by_principal=principal_id)
JOIN principal to_p ON (member_id=to_p.principal_id)
WHERE by_p.user_no = in_grantor AND to_p.user_no = in_accessor AND by_collection IS NULL
UNION
SELECT 32::BIT(24) FROM group_member
JOIN principal by_p ON (group_id=by_p.principal_id)
JOIN principal to_p ON (member_id=to_p.principal_id)
WHERE group_id = in_grantor AND member_id=in_accessor
) AS subquery ;
IF out_conferred IS NULL THEN
SELECT default_privileges INTO out_conferred FROM principal WHERE user_no = in_grantor;
@ -992,6 +1004,160 @@ END;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
-- Expanded group memberships out to some depth
CREATE or REPLACE FUNCTION expand_memberships( INT8, INT ) RETURNS SETOF INT8 AS $$
SELECT group_id FROM group_member WHERE member_id = $1
UNION
SELECT expanded.g_id FROM (SELECT CASE WHEN $2 > 0 THEN expand_memberships( group_id, $2 - 1) END AS g_id
FROM group_member WHERE member_id = $1) AS expanded
WHERE expanded.g_id IS NOT NULL;
$$ LANGUAGE 'SQL' STABLE STRICT;
-- Expanded group members out to some depth
CREATE or REPLACE FUNCTION expand_members( INT8, INT ) RETURNS SETOF INT8 AS $$
SELECT member_id FROM group_member WHERE group_id = $1
UNION
SELECT expanded.m_id FROM (SELECT CASE WHEN $2 > 0 THEN expand_members( member_id, $2 - 1) END AS m_id
FROM group_member WHERE group_id = $1) AS expanded
WHERE expanded.m_id IS NOT NULL;
$$ LANGUAGE 'SQL' STABLE STRICT;
-- Privileges from accessor to grantor, by principal_id
CREATE or REPLACE FUNCTION pprivs( INT8, INT8, INT ) RETURNS BIT(24) AS $$
DECLARE
in_accessor ALIAS FOR $1;
in_grantor ALIAS FOR $2;
in_depth ALIAS FOR $3;
out_conferred BIT(24);
BEGIN
out_conferred := 0::BIT(24);
-- Self can always have full access
IF in_grantor = in_accessor THEN
RETURN ~ out_conferred;
END IF;
SELECT bit_or(subquery.privileges) INTO out_conferred FROM
(
SELECT privileges FROM grants WHERE by_principal=in_grantor AND by_collection IS NULL
AND (to_principal=in_accessor OR to_principal IN (SELECT expand_memberships(in_accessor,in_depth)))
UNION
SELECT 32::BIT(24) AS privileges FROM expand_memberships(in_accessor,in_depth) WHERE expand_memberships = in_grantor
) AS subquery ;
IF out_conferred IS NULL THEN
SELECT default_privileges INTO out_conferred FROM principal WHERE principal_id = in_grantor;
END IF;
RETURN out_conferred;
END;
$$ LANGUAGE 'plpgsql' STABLE STRICT;
-- Privileges from accessor to grantor, by user_no
CREATE or REPLACE FUNCTION uprivs( INT8, INT8, INT ) RETURNS BIT(24) AS $$
DECLARE
in_accessor ALIAS FOR $1;
in_grantor ALIAS FOR $2;
in_depth ALIAS FOR $3;
out_conferred BIT(24);
BEGIN
out_conferred := 0::BIT(24);
-- Self can always have full access
IF in_grantor = in_accessor THEN
RETURN ~ out_conferred;
END IF;
SELECT pprivs( p1.principal_id, p2.principal_id, in_depth ) INTO out_conferred
FROM principal p1, principal p2
WHERE p1.user_no = in_accessor AND p2.user_no = in_grantor;
RETURN out_conferred;
END;
$$ LANGUAGE 'plpgsql' STABLE STRICT;
-- Privileges from accessor (by principal_id) to path
CREATE or REPLACE FUNCTION path_privs( INT8, TEXT, INT ) RETURNS BIT(24) AS $$
DECLARE
in_accessor ALIAS FOR $1;
in_path ALIAS FOR $2;
in_depth ALIAS FOR $3;
alt1_path TEXT;
alt2_path TEXT;
grantor_collection INT8;
grantor_principal INT8;
collection_path TEXT;
collection_privileges BIT(24);
out_conferred BIT(24);
BEGIN
out_conferred := 0::BIT(24);
IF in_path ~ '^/?$' THEN
-- RAISE NOTICE 'Collection is root: Collection: %', in_path;
RETURN 1; -- basic read privileges on root directory
END IF;
-- We need to canonicalise the path, so:
-- If it matches '/' + some characters (+ optional '/') => a principal URL
IF in_path ~ '^/[^/]+/?$' THEN
alt1_path := replace(in_path, '/', '');
SELECT pprivs(in_accessor,principal_id, in_depth) INTO out_conferred FROM usr JOIN principal USING(user_no) WHERE username = alt1_path;
-- RAISE NOTICE 'Path is Principal: Principal: %, Collection: %, Permissions: %', in_accessor, in_path, out_conferred;
RETURN out_conferred;
END IF;
-- Otherwise look for the longest segment matching up to the last '/', or if we append one, or if we replace a final '.ics' with one.
alt1_path := in_path;
IF alt1_path ~ E'\\.ics$' THEN
alt1_path := substr(alt1_path, 1, length(alt1_path) - 4) || '/';
END IF;
alt2_path := regexp_replace( in_path, '[^/]*$', '');
SELECT collection.collection_id, grantor.principal_id, collection.dav_name, collection.default_privileges
INTO grantor_collection, grantor_principal, collection_path, collection_privileges
FROM collection JOIN principal grantor USING (user_no)
WHERE dav_name = in_path || '/' OR dav_name = alt1_path OR dav_name = alt2_path
ORDER BY LENGTH(collection.dav_name) DESC LIMIT 1;
-- Self will always need full access to their own collections!
IF grantor_principal = in_accessor THEN
-- RAISE NOTICE 'Principal IS owner: Principal: %, Collection: %', in_accessor, in_path;
RETURN ~ out_conferred;
END IF;
SELECT privileges INTO out_conferred FROM grants
WHERE by_collection = grantor_collection
AND (to_principal=in_accessor OR to_principal IN (SELECT expand_memberships(in_accessor,in_depth)));
IF out_conferred IS NULL THEN
IF collection_privileges IS NULL THEN
IF grantor_principal IS NULL THEN
alt1_path := regexp_replace( in_path, '/[^/]+/?$', '/');
SELECT path_privs(in_accessor,alt1_path,in_depth) INTO out_conferred;
-- RAISE NOTICE 'Collection is NULL: Principal: %, Collection: %, Permissions: %', in_accessor, in_path, out_conferred;
ELSE
SELECT pprivs(in_accessor,grantor_principal,in_depth) INTO out_conferred;
-- RAISE NOTICE 'Collection priveleges are NULL: Principal: %, Collection: %, Permissions: %', in_accessor, in_path, out_conferred;
END IF;
ELSE
out_conferred := collection_privileges;
-- RAISE NOTICE 'Default Collection priveleges apply: Principal: %, Collection: %, Permissions: %', in_accessor, in_path, out_conferred;
END IF;
END IF;
RETURN out_conferred;
END;
$$ LANGUAGE 'plpgsql' STABLE STRICT;
-- CREATE or REPLACE FUNCTION get_permissions( INT, INT ) RETURNS TEXT AS $$
-- SELECT bits_to_legacy_privilege(user_privileges( $1, $2 ));
-- $$ LANGUAGE 'sql' IMMUTABLE STRICT;
-- List a user's memberships as a text string
CREATE or REPLACE FUNCTION is_member_of_list( INT8 ) RETURNS TEXT AS $$
DECLARE
@ -1000,16 +1166,16 @@ DECLARE
mlist TEXT;
BEGIN
mlist := '';
FOR m IN SELECT displayname FROM group_member JOIN principal ON (group_id = principal_id)
FOR m IN SELECT displayname, group_id FROM group_member JOIN principal ON (group_id = principal_id)
WHERE member_id = in_member_id
LOOP
mlist := mlist
|| CASE WHEN mlist = '' THEN '' ELSE ', ' END
|| m.displayname;
|| COALESCE( m.displayname, m.group_id::text);
END LOOP;
RETURN mlist;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' STRICT;
-- List a user's members as a text string
@ -1020,16 +1186,16 @@ DECLARE
mlist TEXT;
BEGIN
mlist := '';
FOR m IN SELECT displayname FROM group_member JOIN principal ON (member_id = principal_id)
FOR m IN SELECT displayname, group_id FROM group_member JOIN principal ON (member_id = principal_id)
WHERE group_id = in_member_id
LOOP
mlist := mlist
|| CASE WHEN mlist = '' THEN '' ELSE ', ' END
|| m.displayname;
|| COALESCE( m.displayname, m.group_id::text);
END LOOP;
RETURN mlist;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' STRICT;
-- List the privileges as a text string
@ -1054,17 +1220,138 @@ BEGIN
END LOOP;
RETURN plist;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
DROP TRIGGER principal_modified ON principal CASCADE;
CREATE or REPLACE FUNCTION principal_modified() RETURNS TRIGGER AS $$
DECLARE
BEGIN
-- in case we trigger on other events in future
IF TG_OP = 'UPDATE' THEN
IF NEW.type_id != OLD.type_id THEN
UPDATE grants
SET is_group = (NEW.type_id = 3)
WHERE grants.to_principal = NEW.principal_id;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER principal_modified AFTER UPDATE ON principal
FOR EACH ROW EXECUTE PROCEDURE principal_modified();
DROP TRIGGER grants_modified ON grants CASCADE;
CREATE or REPLACE FUNCTION grants_modified() RETURNS TRIGGER AS $$
DECLARE
old_to_principal INT8;
new_is_group BOOL;
BEGIN
-- in case we trigger on other events in future
IF TG_OP = 'INSERT' THEN
old_to_principal := NULL;
ELSE
old_to_principal := OLD.to_principal;
END IF;
IF TG_OP = 'INSERT' OR NEW.to_principal != old_to_principal THEN
SELECT (type_id = 3) INTO new_is_group FROM principal WHERE principal_id = NEW.to_principal;
IF NEW.is_group != new_is_group THEN
NEW.is_group := new_is_group;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER grants_modified AFTER INSERT OR UPDATE ON grants
FOR EACH ROW EXECUTE PROCEDURE grants_modified();
-- An expanded list of the grants this principal has access to
CREATE or REPLACE FUNCTION g_has_proxy_access_to( INT8, INT ) RETURNS SETOF grants AS $$
SELECT $1, by_collection, by_principal,
(CASE WHEN by_collection IS NULL THEN pprivs($1,by_principal,$2)
ELSE path_privs($1,(SELECT dav_name FROM collection WHERE collection_id = by_collection),$2)
END) AS privileges,
coalesce((principal.type_id=3), FALSE) AS is_group
FROM (
SELECT by_principal, by_collection FROM grants
WHERE to_principal IN (SELECT $1 UNION SELECT expand_memberships($1,$2))
AND (privileges & 5::BIT(24)) != 0::BIT(24)
AND by_principal != $1
UNION
SELECT principal_id AS by_principal, NULL::INT8 FROM principal
WHERE (default_privileges & 5::BIT(24)) != 0::BIT(24)
AND principal_id != $1
) subquery LEFT JOIN principal ON (subquery.by_principal = principal_id);
$$ LANGUAGE 'SQL' STABLE STRICT;
-- A list of the principals who can proxy to this principal
CREATE or REPLACE FUNCTION g_grants_proxy_access_from( INT8, INT ) RETURNS SETOF grants AS $$
SELECT DISTINCT ON (grants.by_principal) by_principal, NULL::INT8, $1 AS to_principal, pprivs(by_principal,$1,$2), (principal.type_id=3) AS is_group
FROM grants JOIN principal ON (by_principal = principal_id)
WHERE by_collection IS NULL AND by_principal != $1
AND by_principal IN (SELECT $1 UNION SELECT expand_members(g2.to_principal,$2) FROM grants g2 WHERE g2.by_principal = $1)
;
$$ LANGUAGE 'SQL' STABLE STRICT;
-- An expanded list of the grants this principal has access to
CREATE or REPLACE FUNCTION p_has_proxy_access_to( INT8, INT ) RETURNS SETOF INT8 AS $$
SELECT by_principal
FROM (
SELECT by_principal FROM grants
WHERE to_principal IN (SELECT $1 UNION SELECT expand_memberships($1,$2))
AND (privileges & 5::BIT(24)) != 0::BIT(24)
AND by_collection IS NULL
AND by_principal != $1
UNION
SELECT principal_id AS by_principal FROM principal
WHERE (default_privileges & 5::BIT(24)) != 0::BIT(24)
AND principal_id != $1
) subquery;
$$ LANGUAGE 'SQL' STABLE STRICT;
-- A list of the principals who can proxy to this principal
CREATE or REPLACE FUNCTION grants_proxy_access_from_p( INT8, INT ) RETURNS SETOF INT8 AS $$
SELECT DISTINCT by_principal
FROM grants
WHERE by_collection IS NULL AND by_principal != $1
AND by_principal IN (SELECT expand_members(g2.to_principal,$2) FROM grants g2 WHERE g2.by_principal = $1)
;
$$ LANGUAGE 'SQL' STABLE STRICT;
-- A list of the principals who can proxy to this principal
CREATE or REPLACE FUNCTION i_proxy_to( INT8 ) RETURNS SETOF grants AS $$
SELECT by_principal, by_collection, to_principal, privileges, is_group FROM grants WHERE by_principal = $1 AND NOT is_group AND by_collection IS NULL
UNION
SELECT by_principal, by_collection, member_id, privileges, is_group FROM grants
JOIN group_member ON (to_principal=group_id) where by_principal = $1 and is_group AND by_collection IS NULL;
SELECT by_principal, by_collection, to_principal, bit_or(privileges), bool_or(is_group)
FROM (SELECT by_principal, by_collection, to_principal, pprivs(to_principal,by_principal,2) AS privileges, is_group FROM grants WHERE by_principal = $1 AND by_collection IS NULL
UNION
SELECT $1, NULL, group_id, 32::BIT(24), TRUE FROM group_member WHERE member_id = $1
UNION
SELECT $1, NULL, principal_id, pprivs(principal_id,$1,2) AS privileges, (type_id=3) AS is_group FROM principal WHERE (default_privileges & 5::BIT(24)) != 0::BIT(24)
UNION
SELECT $1, collection_id, NULL, path_privs($1,collection.dav_name,2) AS privileges, FALSE AS is_group FROM collection WHERE (default_privileges & 5::BIT(24)) != 0::BIT(24)
) a GROUP BY 1, 2, 3;
$$ LANGUAGE 'SQL' STRICT;
CREATE or REPLACE FUNCTION i_proxy_for( INT8 ) RETURNS SETOF grants AS $$
SELECT by_principal, by_collection, to_principal, bit_or(privileges), bool_or(is_group)
FROM (SELECT by_principal, by_collection, to_principal, privileges, is_group FROM grants WHERE to_principal = $1
UNION
SELECT member_id, NULL, $1, 32::BIT(24), TRUE FROM group_member WHERE group_id = $1
) a GROUP BY 1, 2, 3;
$$ LANGUAGE 'SQL' STRICT;
-- A list of the principals who this principal can proxy
CREATE or REPLACE FUNCTION proxied_by( INT8 ) RETURNS SETOF grants AS $$
SELECT by_principal, by_collection, to_principal, privileges, is_group FROM grants WHERE to_principal = $1 AND NOT is_group AND by_collection IS NULL

View File

@ -91,7 +91,7 @@ CREATE TABLE collection (
public_events_only BOOLEAN NOT NULL DEFAULT FALSE,
publicly_readable BOOLEAN NOT NULL DEFAULT FALSE,
collection_id INT8 PRIMARY KEY DEFAULT nextval('dav_id_seq'),
default_privileges BIT(24) DEFAULT privilege_to_bits('caldav:read-free-busy'),
default_privileges BIT(24),
is_addressbook BOOLEAN DEFAULT FALSE,
resourcetypes TEXT DEFAULT '<DAV::collection/>',
in_freebusy_set BOOLEAN DEFAULT TRUE,

View File

@ -500,7 +500,7 @@ 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 SET confers = (SELECT bit_confers FROM relationship_type AS rt WHERE rt.rt_id=relationship.rt_id);
ALTER TABLE collection ADD COLUMN default_privileges BIT(24) DEFAULT privilege_to_bits('caldav:read-free-busy');
ALTER TABLE collection ADD COLUMN default_privileges BIT(24);
INSERT INTO principal_type (principal_type_id, principal_type_desc) VALUES( 1, 'Person' );
INSERT INTO principal_type (principal_type_id, principal_type_desc) VALUES( 2, 'Resource' );
@ -531,7 +531,7 @@ INSERT INTO principal (type_id, user_no, displayname, default_privileges)
UPDATE collection SET default_privileges = CASE
WHEN publicly_readable THEN privilege_to_bits(ARRAY['read'])
ELSE (SELECT default_privileges FROM principal WHERE principal.user_no = collection.user_no)
ELSE NULL
END;
INSERT INTO group_member ( group_id, member_id)

View File

@ -205,7 +205,7 @@ class CalDAVPrincipal
if ( $this->_is_group ) {
$this->group_member_set = array();
$qry = new PgQuery('SELECT * FROM group_member JOIN principal ON (principal_id=member_id) JOIN usr USING(user_no) WHERE group_id = ?', $this->principal_id );
$qry = new PgQuery('SELECT usr.username FROM group_member JOIN principal ON (principal_id=member_id) JOIN usr USING(user_no) WHERE group_id = ?', $this->principal_id );
if ( $qry->Exec('CalDAVPrincipal') && $qry->rows > 0 ) {
while( $member = $qry->Fetch() ) {
$this->group_member_set[] = ConstructURL( '/'. $member->username . '/', true);
@ -214,7 +214,7 @@ class CalDAVPrincipal
}
$this->group_membership = array();
$qry = new PgQuery('SELECT * FROM group_member JOIN principal ON (principal_id=group_id) JOIN usr USING(user_no) WHERE member_id = ?', $this->principal_id );
$qry = new PgQuery('SELECT usr.username FROM group_member JOIN principal ON (principal_id=group_id) JOIN usr USING(user_no) WHERE member_id = ? UNION SELECT usr.username FROM group_member LEFT JOIN grants ON (to_principal=group_id) JOIN principal ON (principal_id=by_principal) JOIN usr USING(user_no) WHERE member_id = ? and by_principal != member_id', $this->principal_id, $this->principal_id );
if ( $qry->Exec('CalDAVPrincipal') && $qry->rows > 0 ) {
while( $group = $qry->Fetch() ) {
$this->group_membership[] = ConstructURL( '/'. $group->username . '/', true);
@ -254,31 +254,34 @@ class CalDAVPrincipal
$this->read_proxy_for = array();
if ( !isset($c->disable_caldav_proxy) || $c->disable_caldav_proxy === false ) {
$write_priv = privilege_to_bits(array('write'));
// whom are we a proxy for? who is a proxy for us?
// (as per Caldav Proxy section 5.1 Paragraph 7 and 5)
$qry = new PgQuery('SELECT from_user.user_no AS from_user_no, from_user.username AS from_username,'.
'get_permissions(from_user.user_no, to_user.user_no) AS confers,'.
'to_user.user_no AS to_user_no, to_user.username AS to_username '.
'FROM usr from_user, usr to_user WHERE '.
"get_permissions(from_user.user_no, to_user.user_no) ~ '[AWR]' AND ".
'to_user.user_no != from_user.user_no AND (from_user.user_no = ? OR '.
'to_user.user_no = ?)', $this->user_no, $this->user_no );
$sql = 'SELECT principal_id, username, pprivs(?,principal_id,?) FROM principal JOIN usr USING(user_no) WHERE principal_id IN (SELECT * from p_has_proxy_access_to(?,?))';
$qry = new PgQuery($sql, $this->principal_id, $c->permission_scan_depth, $this->principal_id, $c->permission_scan_depth );
if ( $qry->Exec('CalDAVPrincipal') && $qry->rows > 0 ) {
while( $relationship = $qry->Fetch() ) {
if ($relationship->confers == 'R') {
if ($relationship->from_user_no == $this->user_no) {
// spec says without trailing slash, CalServ does it with slash, and so do we.
$this->read_proxy_for[] = ConstructURL( '/'. $relationship->to_username . '/', true);
} else /* ($relationship->to_user_no == $this->user_no) */ {
$this->read_proxy_group[] = ConstructURL( '/'. $relationship->from_username . '/', true);
}
} else if (preg_match('/[WA]/', $relationship->confers)) {
if ($relationship->from_user_no == $this->user_no) {
$this->write_proxy_for[] = ConstructURL( '/'. $relationship->to_username . '/', true);
}
else /* ($relationship->to_user_no == $this->user_no) */ {
$this->write_proxy_group[] = ConstructURL( '/'. $relationship->from_username . '/', true);
}
if ( (bindec($relationship->pprivs) & $write_priv) != 0 ) {
$this->write_proxy_for[] = ConstructURL( '/'. $relationship->username . '/', true);
$this->group_membership[] = ConstructURL( '/'. $relationship->username . '/calendar-proxy-write/', true);
}
else {
$this->read_proxy_for[] = ConstructURL( '/'. $relationship->username . '/', true);
$this->group_membership[] = ConstructURL( '/'. $relationship->username . '/calendar-proxy-read/', true);
}
}
}
$sql = 'SELECT principal_id, username, pprivs(?,principal_id,?) FROM principal JOIN usr USING(user_no) WHERE principal_id IN (SELECT * from grants_proxy_access_from_p(?,?))';
$qry = new PgQuery($sql, $this->principal_id, $c->permission_scan_depth, $this->principal_id, $c->permission_scan_depth );
if ( $qry->Exec('CalDAVPrincipal') && $qry->rows > 0 ) {
while( $relationship = $qry->Fetch() ) {
if ( bindec($relationship->pprivs) & $write_priv ) {
$this->write_proxy_group[] = ConstructURL( '/'. $relationship->username . '/', true);
}
else {
$this->read_proxy_group[] = ConstructURL( '/'. $relationship->username . '/', true);
}
}
}
@ -319,6 +322,7 @@ class CalDAVPrincipal
* Accessor for the group membership - the groups this principal is a member of
*/
function GroupMembership() {
if ( !isset($this->read_proxy_group) ) $this->FetchProxyGroups();
return $this->group_membership;
}
@ -489,9 +493,9 @@ class CalDAVPrincipal
$reply->CalendarserverElement($prop, 'dropbox-home-URL', $reply->href($this->dropbox_url) );
break;
case 'http://calendarserver.org/ns/:notifications-URL':
$reply->CalendarserverElement($prop, 'notifications-URL', $reply->href($this->notifications_url) );
break;
# case 'http://calendarserver.org/ns/:notifications-URL':
# $reply->CalendarserverElement($prop, 'notifications-URL', $reply->href($this->notifications_url) );
# break;
case 'http://calendarserver.org/ns/:xmpp-server':
if ( ! isset( $this->xmpp_uri ) ) return false;

View File

@ -344,6 +344,7 @@ EOSQL;
if ( isset($this->principal->user_no) ) $this->user_no = $this->principal->user_no;
if ( isset($this->principal->username)) $this->username = $this->principal->username;
if ( isset($this->principal->by_email)) $this->by_email = true;
if ( isset($this->principal->principal_id)) $this->principal_id = $this->principal->principal_id;
if ( $this->collection_type == 'principal' || $this->collection_type == 'email' ) {
$this->collection = $this->principal->AsCollection();
@ -497,6 +498,7 @@ EOSQL;
$this->user_no = $session->user_no;
$this->username = $session->username;
$this->principal_id = $session->principal_id;
@dbg_error_log( "WARN", "Call to deprecated CalDAVRequest::UserFromPath()" );
@ -511,15 +513,17 @@ EOSQL;
@dbg_error_log( "caldav", "Path split into at least /// %s /// %s /// %s", $path_split[1], $path_split[2], $path_split[3] );
if ( isset($this->options['allow_by_email']) && preg_match( '#/(\S+@\S+[.]\S+)/?$#', $this->path, $matches) ) {
$this->by_email = $matches[1];
// $qry = new PgQuery("SELECT user_no FROM usr WHERE email = ? AND get_permissions(?,user_no) ~ '[FRA]';", $this->by_email, $session->user_no );
$qry = new PgQuery("SELECT user_no FROM usr WHERE email = ?;", $this->by_email );
$qry = new PgQuery("SELECT user_no, principal_id, username FROM usr JOIN principal USING (user_no) WHERE email = ?;", $this->by_email );
if ( $qry->Exec("caldav") && $user = $qry->Fetch() ) {
$this->user_no = $user->user_no;
$this->username = $user->username;
$this->principal_id = $user->principal_id;
}
}
elseif( $user = getUserByName($this->username,'caldav',__LINE__,__FILE__)) {
$this->principal = $user;
$this->user_no = $user->user_no;
$this->principal_id = $user->principal_id;
}
}
@ -575,40 +579,22 @@ EOSQL;
/**
* In other cases we need to query the database for permissions
*/
$qry = new PgQuery( "SELECT get_permissions( ?, ? ) AS perm;", $session->user_no, $this->user_no);
if ( isset($this->by_email) ) {
$qry = new PgQuery( "SELECT pprivs( ?, ?, ? ) AS perm", $session->principal_id, $this->principal_id, $c->permission_scan_depth );
}
else {
$qry = new PgQuery( "SELECT path_privs( ?, ?, ? ) AS perm", $session->principal_id, $this->path, $c->permission_scan_depth );
}
if ( $qry->Exec("caldav") && $permission_result = $qry->Fetch() ) {
$permission_result = "!".$permission_result->perm; // We prepend something to ensure we get a non-zero position.
if ( strpos($permission_result,"A") ) {
$this->permissions['all'] = 'abstract';
$this->permissions['urn:ietf:params:xml:ns:caldav:read-free-busy'] = 'real';
$this->permissions['read'] = 'real';
$this->permissions['write'] = 'aggregate';
$this->permissions['bind'] = 'real'; // PUT of new content (i.e. Create)
$this->permissions['unbind'] = 'real'; // DELETE
$this->permissions['write-content'] = 'real'; // PUT Modify
$this->permissions['write-properties'] = 'real'; // PROPPATCH
$this->permissions['lock'] = 'real';
$this->permissions['unlock'] = 'real';
$this->permissions['read-acl'] = 'real';
$this->permissions['read-current-user-privilege-set'] = 'real';
}
else {
if ( strpos($permission_result,"F") ) $this->permissions['urn:ietf:params:xml:ns:caldav:read-free-busy'] = 'real';
if ( strpos($permission_result,"R") ) $this->permissions['read'] = 'real';
if ( strpos($permission_result,"W") ) {
$this->permissions['write'] = 'aggregate';
$this->permissions['bind'] = 'real'; // PUT of new content (i.e. Create)
$this->permissions['unbind'] = 'real'; // DELETE
$this->permissions['write-content'] = 'real'; // PUT Modify
$this->permissions['write-properties'] = 'real'; // PROPPATCH
$this->permissions['lock'] = 'real';
$this->permissions['unlock'] = 'real';
}
else {
if ( strpos($permission_result,"C") ) $this->permissions['bind'] = 'real'; // PUT of new content (i.e. Create)
if ( strpos($permission_result,"D") ) $this->permissions['unbind'] = 'real'; // DELETE
if ( strpos($permission_result,"M") ) $this->permissions['write-content'] = 'real'; // PUT Modify
$privs = bits_to_privilege($permission_result->perm);
foreach( $privs AS $k => $v ) {
switch( $v ) {
case 'DAV::all': $type = 'abstract'; break;
case 'DAV::write': $type = 'aggregate'; break;
default: $type = 'real';
}
$v = str_replace('DAV::', '', $v);
$this->permissions[$v] = $type;
}
dbg_error_log( "caldav", "Restricted permissions for user accessing someone elses hierarchy: %s", implode( ", ", $this->permissions ) );
}

View File

@ -27,6 +27,7 @@ $c->domain_name = (isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:$_SERV
$c->save_time_zone_defs = true;
$c->collections_always_exist = false;
$c->allow_get_email_visibility = false;
$c->permission_scan_depth = 2;
$c->home_calendar_name = 'home';
$c->enable_row_linking = true;
$c->http_auth_mode = 'Basic';
@ -124,7 +125,7 @@ awl_set_locale($c->default_locale);
*
*/
$c->code_version = 0;
$c->version_string = '0.9.7.4'; // The actual version # is replaced into that during the build /release process
$c->version_string = '0.9.7.99'; // The actual version # is replaced into that during the build /release process
if ( isset($c->version_string) && preg_match( '/(\d+)\.(\d+)\.(\d+)(.*)/', $c->version_string, $matches) ) {
$c->code_major = $matches[1];
$c->code_minor = $matches[2];
@ -353,6 +354,8 @@ function privilege_to_bits( $raw_privs ) {
if ( gettype($raw_privs) == 'string' ) $raw_privs = array( $raw_privs );
if ( ! is_array($raw_privs) ) $raw_privs = array($raw_privs);
foreach( $raw_privs AS $priv ) {
$trim_priv = trim(strtolower(preg_replace( '/^.*:/', '', $priv)));
switch( $trim_priv ) {

View File

@ -27,6 +27,7 @@ $c->domain_name = (isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:$_SERV
$c->save_time_zone_defs = true;
$c->collections_always_exist = false;
$c->allow_get_email_visibility = false;
$c->permission_scan_depth = 2;
$c->home_calendar_name = 'home';
$c->enable_row_linking = true;
$c->http_auth_mode = 'Basic';
@ -353,6 +354,8 @@ function privilege_to_bits( $raw_privs ) {
if ( gettype($raw_privs) == 'string' ) $raw_privs = array( $raw_privs );
if ( ! is_array($raw_privs) ) $raw_privs = array($raw_privs);
foreach( $raw_privs AS $priv ) {
$trim_priv = trim(strtolower(preg_replace( '/^.*:/', '', $priv)));
switch( $trim_priv ) {

View File

@ -10,7 +10,7 @@
*/
dbg_error_log('MKCOL', 'method handler');
if ( ! $request->AllowedTo('mkcalendar') ) {
if ( ! $request->AllowedTo('bind') ) {
$request->DoResponse( 403, translate('You may not create a calendar there.') );
}

View File

@ -56,11 +56,11 @@ function handle_freebusy_request( $ic ) {
}
/** @TODO: Refactor this so we only do one query here and loop through the results */
$qry = new PgQuery("SELECT get_permissions(?,user_no) AS p FROM usr WHERE lower(usr.email) = lower(?)", $session->user_no, $attendee_email );
$qry = new PgQuery("SELECT pprivs(?,principal_id,?) AS p FROM usr JOIN principal USING(user_no) WHERE lower(usr.email) = lower(?)", $session->principal_id, $c->permission_scan_depth, $attendee_email );
if ( !$qry->Exec("POST") ) $request->DoResponse( 501, 'Database error');
if ( $qry->rows > 1 ) {
// Unlikely, but if we get more than one result we'll do an exact match instead.
$qry = new PgQuery("SELECT get_permissions(?,user_no) AS p FROM usr WHERE usr.email = ?", $session->user_no, $attendee_email );
$qry = new PgQuery("SELECT pprivs(?,principal_id,?) AS p FROM usr JOIN principal USING(user_no) WHERE usr.email = ?", $session->principal_id, $c->permission_scan_depth, $attendee_email );
if ( !$qry->Exec("POST") ) $request->DoResponse( 501, 'Database error');
}
@ -74,7 +74,7 @@ function handle_freebusy_request( $ic ) {
continue;
}
if ( ! $userperms = $qry->Fetch() ) $request->DoResponse( 501, 'Database error');
if ( !preg_match( '/[AWRF]/', $userperms->p ) ) {
if ( (privilege_to_bits('schedule-query-freebusy') & bindec($userperms->p)) == 0 ) {
$reply->CalDAVElement($response, "request-status", "3.8;No authority" );
$reply->CalDAVElement($response, "calendar-data" );
$responses[] = $response;

View File

@ -10,8 +10,9 @@
*/
dbg_error_log('PROPFIND', 'method handler');
if ( ! ($request->AllowedTo('read') || $request->AllowedTo('freebusy')) ) {
$request->DoResponse( 403, translate('You may not access that calendar') );
if ( ! ($request->AllowedTo('read') || $request->AllowedTo('freebusy') || $request->AllowedTo('read-current-user-privilege-set') ) ) {
dbg_error_log('ERROR','Insufficient privileges for "%s" of "%s"', $request->path, implode(', ', $request->permissions) );
$request->DoResponse( 403, translate('You may not access that collection') );
}
require_once('iCalendar.php');

View File

@ -48,18 +48,17 @@ foreach( $mg_hrefs AS $k => $v ) {
}
$where = " WHERE caldav_data.dav_name ~ ".qpg("^".$request->path)." ";
if ( $href_in != "" ) {
$where .= " AND caldav_data.dav_name IN ( $href_in ) ";
}
$where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL OR get_permissions($session->user_no,calendar_item.user_no) ~ 'A') ";
$where .= "AND caldav_data.dav_name IN ( $href_in ) ";
$where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL ";
$where .= "OR (uprivs($session->user_no,calendar_item.user_no,$c->permission_scan_depth) = privilege_to_bits('all')) ) ";
if ( isset($c->hide_TODO) && $c->hide_TODO && ! $request->AllowedTo('all') ) {
$where .= "AND caldav_data.caldav_type NOT IN ('VTODO') ";
}
if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $where .= " ORDER BY dav_id";
$qry = new PgQuery( "SELECT * FROM caldav_data INNER JOIN calendar_item USING(dav_id, user_no, dav_name)". $where );
if ( $qry->Exec("REPORT",__LINE__,__FILE__) && $qry->rows > 0 ) {
if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $where .= " ORDER BY caldav_data.dav_id";
$qry = new PgQuery( "SELECT caldav_data.*,calendar_item.* FROM caldav_data INNER JOIN calendar_item USING(dav_id, user_no, dav_name, collection_id) LEFT JOIN collection USING(collection_id)". $where );
if ( $qry->Exec('REPORT',__LINE__,__FILE__) && $qry->rows > 0 ) {
while( $calendar_object = $qry->Fetch() ) {
$responses[] = calendar_to_xml( $properties, $calendar_object );
}

View File

@ -283,10 +283,14 @@ EOTEMPLATE;
$grantrow = new Editor("Grants", "grants");
$grantrow->SetSubmitName( 'savegrantrow' );
$grantrow->SetLookup( 'to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = '.$id.')' );
$edit_grant_clause = '';
if ( isset($_GET['edit_grant']) ) {
$edit_grant_clause = ' AND to_principal != '.intval($_GET['edit_grant']);
}
$grantrow->SetLookup( 'to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT to_principal FROM grants WHERE by_principal = '.$id.$edit_grant_clause.')' );
if ( $can_write_principal ) {
if ( $grantrow->IsSubmit() ) {
if ( $grouprow->IsUpdate() )
if ( $grantrow->IsUpdate() )
$c->messages[] = translate('Updating grants by this Principal');
else
$c->messages[] = translate('Granting new privileges from this Principal');

View File

@ -2,8 +2,8 @@ HTTP/1.1 200 OK
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule, extended-mkcol
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, POST, GET, PUT, HEAD, PROPPATCH
ETag: "6ade03a359008583053c8c3a5dc72a10"
Content-Length: 318
ETag: "ae241cc30505f7f7148b7fee176731fb"
Content-Length: 968
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -12,7 +12,26 @@ Content-Type: text/xml; charset="utf-8"
<C:recipient>
<href>mailto:user3@example.net</href>
</C:recipient>
<C:request-status>3.8;No authority</C:request-status>
<C:calendar-data/>
<C:request-status>2.0;Success</C:request-status>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//davical.org//NONSGML AWL Calendar//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REPLY
BEGIN:VFREEBUSY
DTSTAMP:yyyymmddThhmmssZ
DTSTART:20081020T110000Z
DTEND:20081105T110000Z
UID:c5bd82ea-cd89-4f58-8d31-336f47e44f97
ORGANIZER:mailto:user1@example.net
ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVIDUAL:
mailto:user3@example.net
FREEBUSY;FBTYPE=BUSY:20081024T054500Z/20081023T193000Z
FREEBUSY;FBTYPE=BUSY:20081027T164500Z/20081027T193000Z
FREEBUSY;FBTYPE=BUSY:20081030T164500Z/20081030T193000Z
FREEBUSY;FBTYPE=BUSY:20081103T164500Z/20081103T193000Z
END:VFREEBUSY
END:VCALENDAR
</C:calendar-data>
</C:response>
</C:schedule-response>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "66e8dfdd986cf80ca4e0a454a5f403e4"
Content-Length: 969
ETag: "566f3d4049b468c63b21a2c381ab500b"
Content-Length: 989
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -28,12 +28,15 @@ Content-Type: text/xml; charset="utf-8"
<A:dropbox-home-URL>
<href>/caldav.php/user1/.drop/</href>
</A:dropbox-home-URL>
<A:notifications-URL>
<href>/caldav.php/user1/.notify/</href>
</A:notifications-URL>
<displayname>User 1</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<A:notifications-URL/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD
ETag: "0ca7a94e77fef5944b1a51b09795fd1d"
Content-Length: 978
ETag: "acfaf4c13829d0f908c2bd54a2180454"
Content-Length: 998
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -28,12 +28,15 @@ Content-Type: text/xml; charset="utf-8"
<A:dropbox-home-URL>
<href>/caldav.php/user1/.drop/</href>
</A:dropbox-home-URL>
<A:notifications-URL>
<href>/caldav.php/user1/.notify/</href>
</A:notifications-URL>
<displayname>user1 home</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<A:notifications-URL/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT
ETag: "a3b0bb6df3ed4c8912f90b680bdb1392"
Content-Length: 967
ETag: "58ac2b1da600dda0e7b2e256a8dac271"
Content-Length: 987
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -28,12 +28,15 @@ Content-Type: text/xml; charset="utf-8"
<A:dropbox-home-URL>
<href>/caldav.php/user1/.drop/</href>
</A:dropbox-home-URL>
<A:notifications-URL>
<href>/caldav.php/user1/.notify/</href>
</A:notifications-URL>
<displayname>DAViCal CalDAV Server</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<A:notifications-URL/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

View File

@ -3,8 +3,8 @@ Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule, extended-mkcol
Content-Location: /caldav.php/user2/
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "24e8f1abe05b588f205fda4b1a6da119"
Content-Length: 969
ETag: "cb2395b4d4b229e5ea994113535bf173"
Content-Length: 989
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -29,12 +29,15 @@ Content-Type: text/xml; charset="utf-8"
<A:dropbox-home-URL>
<href>/caldav.php/user2/.drop/</href>
</A:dropbox-home-URL>
<A:notifications-URL>
<href>/caldav.php/user2/.notify/</href>
</A:notifications-URL>
<displayname>User 2</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<A:notifications-URL/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "220fe991d684589214ff030857a16459"
Content-Length: 2525
ETag: "a599c80c9c8cc0c6600ebfd664ecc806"
Content-Length: 3805
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -19,7 +19,13 @@ Content-Type: text/xml; charset="utf-8"
<principal/>
</resourcetype>
<group-membership>
<href>/caldav.php/assistant1/</href>
<href>/caldav.php/teamclient1/</href>
<href>/caldav.php/user1/</href>
<href>/caldav.php/user1/calendar-proxy-read/</href>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<href>/caldav.php/resource1/calendar-proxy-read/</href>
<href>/caldav.php/resource2/calendar-proxy-read/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>
@ -43,7 +49,13 @@ Content-Type: text/xml; charset="utf-8"
<C1:calendar/>
</resourcetype>
<group-membership>
<href>/caldav.php/assistant1/</href>
<href>/caldav.php/teamclient1/</href>
<href>/caldav.php/user1/</href>
<href>/caldav.php/user1/calendar-proxy-read/</href>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<href>/caldav.php/resource1/calendar-proxy-read/</href>
<href>/caldav.php/resource2/calendar-proxy-read/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>
@ -60,14 +72,20 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/manager1/calendar-proxy-read/</href>
<propstat>
<prop>
<C:getctag>"81833b8410a85c2e86dd32ae4470e72b"</C:getctag>
<C:getctag>"ccdfbfa2e7ee6c47d3ea8f134d415b89"</C:getctag>
<displayname>/manager1/calendar-proxy-read/</displayname>
<resourcetype>
<collection/>
<C:calendar-proxy-read/>
</resourcetype>
<group-membership>
<href>/caldav.php/assistant1/</href>
<href>/caldav.php/teamclient1/</href>
<href>/caldav.php/user1/</href>
<href>/caldav.php/user1/calendar-proxy-read/</href>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<href>/caldav.php/resource1/calendar-proxy-read/</href>
<href>/caldav.php/resource2/calendar-proxy-read/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>
@ -84,14 +102,20 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/manager1/calendar-proxy-write/</href>
<propstat>
<prop>
<C:getctag>"9849062cdad5f238a4ac4a9829bcdbcf"</C:getctag>
<C:getctag>"ff25f14bac404c0aae34b5e75618d479"</C:getctag>
<displayname>/manager1/calendar-proxy-write/</displayname>
<resourcetype>
<collection/>
<C:calendar-proxy-write/>
</resourcetype>
<group-membership>
<href>/caldav.php/assistant1/</href>
<href>/caldav.php/teamclient1/</href>
<href>/caldav.php/user1/</href>
<href>/caldav.php/user1/calendar-proxy-read/</href>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<href>/caldav.php/resource1/calendar-proxy-read/</href>
<href>/caldav.php/resource2/calendar-proxy-read/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>

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, extended-mkcol
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "2452693212d28984215f9229be531dc0"
ETag: "04833ee3ba208ef1e89c2c0254b99737"
Content-Length: 19035
Content-Type: text/xml; charset="utf-8"
@ -620,7 +620,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/calendar-proxy-read/</href>
<propstat>
<prop>
<C:getctag>"c26fa324d66fa84a0da8e1ec8c4566fd"</C:getctag>
<C:getctag>"abad5538c4aa570cc54b6ff0d36a4565"</C:getctag>
<displayname>/user1/calendar-proxy-read/</displayname>
<resourcetype>
<collection/>
@ -717,7 +717,7 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user1/calendar-proxy-write/</href>
<propstat>
<prop>
<C:getctag>"1fe22bc6877accf64891e7c9c5428b86"</C:getctag>
<C:getctag>"04ba2c2164225fb5abce13f2c523b6c7"</C:getctag>
<displayname>/user1/calendar-proxy-write/</displayname>
<resourcetype>
<collection/>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "ebdd8e95b8e7b43904f7cb1032c8aa34"
Content-Length: 975
ETag: "9c0097968135b1bb539cee7121158c9c"
Content-Length: 995
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -28,12 +28,15 @@ Content-Type: text/xml; charset="utf-8"
<A:dropbox-home-URL>
<href>/caldav.php/user1/.drop/</href>
</A:dropbox-home-URL>
<A:notifications-URL>
<href>/caldav.php/user1/.notify/</href>
</A:notifications-URL>
<displayname>User 1</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
<propstat>
<prop>
<A:notifications-URL/>
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>

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, extended-mkcol
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "ca16ae2f358c4719219d0f3a6696fd39"
ETag: "2091d92f09f393ede66728896d167240"
Content-Length: 15401
Content-Type: text/xml; charset="utf-8"
@ -543,7 +543,7 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<displayname>/user1/calendar-proxy-read/</displayname>
<C1:getctag>"c26fa324d66fa84a0da8e1ec8c4566fd"</C1:getctag>
<C1:getctag>"abad5538c4aa570cc54b6ff0d36a4565"</C1:getctag>
<resourcetype>
<collection/>
<C1:calendar-proxy-read/>
@ -627,7 +627,7 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<displayname>/user1/calendar-proxy-write/</displayname>
<C1:getctag>"1fe22bc6877accf64891e7c9c5428b86"</C1:getctag>
<C1:getctag>"04ba2c2164225fb5abce13f2c523b6c7"</C1:getctag>
<resourcetype>
<collection/>
<C1:calendar-proxy-write/>

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, extended-mkcol
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "ca16ae2f358c4719219d0f3a6696fd39"
ETag: "2091d92f09f393ede66728896d167240"
Content-Length: 15401
Content-Type: text/xml; charset="utf-8"
@ -543,7 +543,7 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<displayname>/user1/calendar-proxy-read/</displayname>
<C1:getctag>"c26fa324d66fa84a0da8e1ec8c4566fd"</C1:getctag>
<C1:getctag>"abad5538c4aa570cc54b6ff0d36a4565"</C1:getctag>
<resourcetype>
<collection/>
<C1:calendar-proxy-read/>
@ -627,7 +627,7 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<displayname>/user1/calendar-proxy-write/</displayname>
<C1:getctag>"1fe22bc6877accf64891e7c9c5428b86"</C1:getctag>
<C1:getctag>"04ba2c2164225fb5abce13f2c523b6c7"</C1:getctag>
<resourcetype>
<collection/>
<C1:calendar-proxy-write/>

View File

@ -16,6 +16,9 @@
<owner>
<href>/caldav.php/user1/</href>
</owner>
<current-user-principal>
<href>/caldav.php/user1/</href>
</current-user-principal>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>

View File

@ -15,6 +15,9 @@
<owner>
<href>/caldav.php/user1/</href>
</owner>
<current-user-principal>
<href>/caldav.php/user1/</href>
</current-user-principal>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>

View File

@ -1,5 +1,343 @@
HTTP/1.1 404 Not Found
HTTP/1.1 200 OK
Date: Dow, 01 Jan 2000 00:00:00 GMT
Content-Length: 0
Content-Type: text/plain; charset="utf-8"
Content-Length: 14366
Content-Type: text/calendar
BEGIN:VCALENDAR
PRODID:-//davical.org//NONSGML AWL Calendar//EN
VERSION:2.0
BEGIN:VFREEBUSY
DTSTAMP:yyyymmddThhmmssZ
DTSTART:20060930T120000Z
DTEND:20070630T115959Z
FREEBUSY;FBTYPE=BUSY-TENTATIVE:20061223T060000Z/20061223T080000Z
FREEBUSY:20061101T233000Z/20061102T003000Z
FREEBUSY:20061031T210000Z/20061031T220000Z
FREEBUSY:20061101T210000Z/20061101T090000Z
FREEBUSY:20061109T080000Z/20061109T090000Z
FREEBUSY:20061116T080000Z/20061116T090000Z
FREEBUSY:20061123T080000Z/20061123T090000Z
FREEBUSY:20061130T080000Z/20061130T090000Z
FREEBUSY:20061207T080000Z/20061207T090000Z
FREEBUSY:20061214T080000Z/20061214T090000Z
FREEBUSY:20061221T080000Z/20061221T090000Z
FREEBUSY:20061228T080000Z/20061228T090000Z
FREEBUSY:20070104T080000Z/20070104T090000Z
FREEBUSY:20070111T080000Z/20070111T090000Z
FREEBUSY:20070118T080000Z/20070118T090000Z
FREEBUSY:20070125T080000Z/20070125T090000Z
FREEBUSY:20070201T080000Z/20070201T090000Z
FREEBUSY:20070208T080000Z/20070208T090000Z
FREEBUSY:20070215T080000Z/20070215T090000Z
FREEBUSY:20070222T080000Z/20070222T090000Z
FREEBUSY:20070301T080000Z/20070301T090000Z
FREEBUSY:20070308T080000Z/20070308T090000Z
FREEBUSY:20070315T080000Z/20070315T090000Z
FREEBUSY:20070322T090000Z/20070322T100000Z
FREEBUSY:20070329T090000Z/20070329T100000Z
FREEBUSY:20070405T090000Z/20070405T100000Z
FREEBUSY:20070412T090000Z/20070412T100000Z
FREEBUSY:20070419T090000Z/20070419T100000Z
FREEBUSY:20070426T090000Z/20070426T100000Z
FREEBUSY:20061223T030000Z/20061223T050000Z
FREEBUSY:20061103T030000Z/20061102T154500Z
FREEBUSY:20061116T140000Z/20061116T154500Z
FREEBUSY:20061130T140000Z/20061130T154500Z
FREEBUSY:20061214T140000Z/20061214T154500Z
FREEBUSY:20061228T140000Z/20061228T154500Z
FREEBUSY:20070111T140000Z/20070111T154500Z
FREEBUSY:20070125T140000Z/20070125T154500Z
FREEBUSY:20070208T140000Z/20070208T154500Z
FREEBUSY:20070222T140000Z/20070222T154500Z
FREEBUSY:20070308T140000Z/20070308T154500Z
FREEBUSY:20070322T150000Z/20070322T164500Z
FREEBUSY:20070405T150000Z/20070405T164500Z
FREEBUSY:20070419T150000Z/20070419T164500Z
FREEBUSY:20070503T150000Z/20070503T164500Z
FREEBUSY:20070517T150000Z/20070517T164500Z
FREEBUSY:20070531T150000Z/20070531T164500Z
FREEBUSY:20070614T150000Z/20070614T164500Z
FREEBUSY:20070628T150000Z/20070628T164500Z
FREEBUSY:20061102T183000Z/20061102T073000Z
FREEBUSY:20061202T053000Z/20061202T073000Z
FREEBUSY:20070102T053000Z/20070102T073000Z
FREEBUSY:20070202T053000Z/20070202T073000Z
FREEBUSY:20070302T053000Z/20070302T073000Z
FREEBUSY:20070402T063000Z/20070402T083000Z
FREEBUSY:20070502T063000Z/20070502T083000Z
FREEBUSY:20070602T063000Z/20070602T083000Z
FREEBUSY:20061001T090000Z/20061001T100000Z
FREEBUSY:20061002T090000Z/20061002T100000Z
FREEBUSY:20061003T090000Z/20061003T100000Z
FREEBUSY:20061004T090000Z/20061004T100000Z
FREEBUSY:20061005T090000Z/20061005T100000Z
FREEBUSY:20061006T090000Z/20061006T100000Z
FREEBUSY:20061007T090000Z/20061007T100000Z
FREEBUSY:20061008T090000Z/20061008T100000Z
FREEBUSY:20061009T090000Z/20061009T100000Z
FREEBUSY:20061010T090000Z/20061010T100000Z
FREEBUSY:20061011T090000Z/20061011T100000Z
FREEBUSY:20061012T090000Z/20061012T100000Z
FREEBUSY:20061013T090000Z/20061013T100000Z
FREEBUSY:20061014T090000Z/20061014T100000Z
FREEBUSY:20061015T090000Z/20061015T100000Z
FREEBUSY:20061016T090000Z/20061016T100000Z
FREEBUSY:20061017T090000Z/20061017T100000Z
FREEBUSY:20061018T090000Z/20061018T100000Z
FREEBUSY:20061019T090000Z/20061019T100000Z
FREEBUSY:20061020T090000Z/20061020T100000Z
FREEBUSY:20061021T090000Z/20061021T100000Z
FREEBUSY:20061022T090000Z/20061022T100000Z
FREEBUSY:20061023T090000Z/20061023T100000Z
FREEBUSY:20061024T090000Z/20061024T100000Z
FREEBUSY:20061025T090000Z/20061025T100000Z
FREEBUSY:20061026T090000Z/20061026T100000Z
FREEBUSY:20061027T090000Z/20061027T100000Z
FREEBUSY:20061028T090000Z/20061028T100000Z
FREEBUSY:20061029T090000Z/20061029T100000Z
FREEBUSY:20061030T090000Z/20061030T100000Z
FREEBUSY:20061031T090000Z/20061031T100000Z
FREEBUSY:20061101T090000Z/20061101T100000Z
FREEBUSY:20061102T090000Z/20061102T100000Z
FREEBUSY:20061103T090000Z/20061103T100000Z
FREEBUSY:20061104T090000Z/20061104T100000Z
FREEBUSY:20061105T090000Z/20061105T100000Z
FREEBUSY:20061106T090000Z/20061106T100000Z
FREEBUSY:20061107T090000Z/20061107T100000Z
FREEBUSY:20061108T090000Z/20061108T100000Z
FREEBUSY:20061109T090000Z/20061109T100000Z
FREEBUSY:20061110T090000Z/20061110T100000Z
FREEBUSY:20061111T090000Z/20061111T100000Z
FREEBUSY:20061112T090000Z/20061112T100000Z
FREEBUSY:20061113T090000Z/20061113T100000Z
FREEBUSY:20061114T090000Z/20061114T100000Z
FREEBUSY:20061115T090000Z/20061115T100000Z
FREEBUSY:20061116T090000Z/20061116T100000Z
FREEBUSY:20061117T090000Z/20061117T100000Z
FREEBUSY:20061118T090000Z/20061118T100000Z
FREEBUSY:20061119T090000Z/20061119T100000Z
FREEBUSY:20061120T090000Z/20061120T100000Z
FREEBUSY:20061121T090000Z/20061121T100000Z
FREEBUSY:20061122T090000Z/20061122T100000Z
FREEBUSY:20061123T090000Z/20061123T100000Z
FREEBUSY:20061124T090000Z/20061124T100000Z
FREEBUSY:20061125T090000Z/20061125T100000Z
FREEBUSY:20061126T090000Z/20061126T100000Z
FREEBUSY:20061127T090000Z/20061127T100000Z
FREEBUSY:20061128T090000Z/20061128T100000Z
FREEBUSY:20061129T090000Z/20061129T100000Z
FREEBUSY:20061130T090000Z/20061130T100000Z
FREEBUSY:20061201T090000Z/20061201T100000Z
FREEBUSY:20061202T090000Z/20061202T100000Z
FREEBUSY:20061203T090000Z/20061203T100000Z
FREEBUSY:20061204T090000Z/20061204T100000Z
FREEBUSY:20061205T090000Z/20061205T100000Z
FREEBUSY:20061206T090000Z/20061206T100000Z
FREEBUSY:20061207T090000Z/20061207T100000Z
FREEBUSY:20061208T090000Z/20061208T100000Z
FREEBUSY:20061209T090000Z/20061209T100000Z
FREEBUSY:20061210T090000Z/20061210T100000Z
FREEBUSY:20061211T090000Z/20061211T100000Z
FREEBUSY:20061212T090000Z/20061212T100000Z
FREEBUSY:20061213T090000Z/20061213T100000Z
FREEBUSY:20061214T090000Z/20061214T100000Z
FREEBUSY:20061215T090000Z/20061215T100000Z
FREEBUSY:20061216T090000Z/20061216T100000Z
FREEBUSY:20061217T090000Z/20061217T100000Z
FREEBUSY:20061218T090000Z/20061218T100000Z
FREEBUSY:20061219T090000Z/20061219T100000Z
FREEBUSY:20061220T090000Z/20061220T100000Z
FREEBUSY:20061221T090000Z/20061221T100000Z
FREEBUSY:20061222T090000Z/20061222T100000Z
FREEBUSY:20061223T090000Z/20061223T100000Z
FREEBUSY:20061224T090000Z/20061224T100000Z
FREEBUSY:20061225T090000Z/20061225T100000Z
FREEBUSY:20061226T090000Z/20061226T100000Z
FREEBUSY:20061227T090000Z/20061227T100000Z
FREEBUSY:20061228T090000Z/20061228T100000Z
FREEBUSY:20061229T090000Z/20061229T100000Z
FREEBUSY:20061230T090000Z/20061230T100000Z
FREEBUSY:20061231T090000Z/20061231T100000Z
FREEBUSY:20070101T090000Z/20070101T100000Z
FREEBUSY:20070102T090000Z/20070102T100000Z
FREEBUSY:20070103T090000Z/20070103T100000Z
FREEBUSY:20070104T090000Z/20070104T100000Z
FREEBUSY:20070105T090000Z/20070105T100000Z
FREEBUSY:20070106T090000Z/20070106T100000Z
FREEBUSY:20070107T090000Z/20070107T100000Z
FREEBUSY:20070108T090000Z/20070108T100000Z
FREEBUSY:20070109T090000Z/20070109T100000Z
FREEBUSY:20070110T090000Z/20070110T100000Z
FREEBUSY:20070111T090000Z/20070111T100000Z
FREEBUSY:20070112T090000Z/20070112T100000Z
FREEBUSY:20070113T090000Z/20070113T100000Z
FREEBUSY:20070114T090000Z/20070114T100000Z
FREEBUSY:20070115T090000Z/20070115T100000Z
FREEBUSY:20070116T090000Z/20070116T100000Z
FREEBUSY:20070117T090000Z/20070117T100000Z
FREEBUSY:20070118T090000Z/20070118T100000Z
FREEBUSY:20070119T090000Z/20070119T100000Z
FREEBUSY:20070120T090000Z/20070120T100000Z
FREEBUSY:20070121T090000Z/20070121T100000Z
FREEBUSY:20070122T090000Z/20070122T100000Z
FREEBUSY:20070123T090000Z/20070123T100000Z
FREEBUSY:20070124T090000Z/20070124T100000Z
FREEBUSY:20070125T090000Z/20070125T100000Z
FREEBUSY:20070126T090000Z/20070126T100000Z
FREEBUSY:20070127T090000Z/20070127T100000Z
FREEBUSY:20070128T090000Z/20070128T100000Z
FREEBUSY:20070129T090000Z/20070129T100000Z
FREEBUSY:20070130T090000Z/20070130T100000Z
FREEBUSY:20070131T090000Z/20070131T100000Z
FREEBUSY:20070201T090000Z/20070201T100000Z
FREEBUSY:20070202T090000Z/20070202T100000Z
FREEBUSY:20070203T090000Z/20070203T100000Z
FREEBUSY:20070204T090000Z/20070204T100000Z
FREEBUSY:20070205T090000Z/20070205T100000Z
FREEBUSY:20070206T090000Z/20070206T100000Z
FREEBUSY:20070207T090000Z/20070207T100000Z
FREEBUSY:20070208T090000Z/20070208T100000Z
FREEBUSY:20070209T090000Z/20070209T100000Z
FREEBUSY:20070210T090000Z/20070210T100000Z
FREEBUSY:20070211T090000Z/20070211T100000Z
FREEBUSY:20070212T090000Z/20070212T100000Z
FREEBUSY:20070213T090000Z/20070213T100000Z
FREEBUSY:20070214T090000Z/20070214T100000Z
FREEBUSY:20070215T090000Z/20070215T100000Z
FREEBUSY:20070216T090000Z/20070216T100000Z
FREEBUSY:20070217T090000Z/20070217T100000Z
FREEBUSY:20070218T090000Z/20070218T100000Z
FREEBUSY:20070219T090000Z/20070219T100000Z
FREEBUSY:20070220T090000Z/20070220T100000Z
FREEBUSY:20070221T090000Z/20070221T100000Z
FREEBUSY:20070222T090000Z/20070222T100000Z
FREEBUSY:20070223T090000Z/20070223T100000Z
FREEBUSY:20070224T090000Z/20070224T100000Z
FREEBUSY:20070225T090000Z/20070225T100000Z
FREEBUSY:20070226T090000Z/20070226T100000Z
FREEBUSY:20070227T090000Z/20070227T100000Z
FREEBUSY:20070228T090000Z/20070228T100000Z
FREEBUSY:20070301T090000Z/20070301T100000Z
FREEBUSY:20070302T090000Z/20070302T100000Z
FREEBUSY:20070303T090000Z/20070303T100000Z
FREEBUSY:20070304T090000Z/20070304T100000Z
FREEBUSY:20070305T090000Z/20070305T100000Z
FREEBUSY:20070306T090000Z/20070306T100000Z
FREEBUSY:20070307T090000Z/20070307T100000Z
FREEBUSY:20070308T090000Z/20070308T100000Z
FREEBUSY:20070309T090000Z/20070309T100000Z
FREEBUSY:20070310T090000Z/20070310T100000Z
FREEBUSY:20070311T090000Z/20070311T100000Z
FREEBUSY:20070312T090000Z/20070312T100000Z
FREEBUSY:20070313T090000Z/20070313T100000Z
FREEBUSY:20070314T090000Z/20070314T100000Z
FREEBUSY:20070315T090000Z/20070315T100000Z
FREEBUSY:20070316T090000Z/20070316T100000Z
FREEBUSY:20070317T090000Z/20070317T100000Z
FREEBUSY:20070318T100000Z/20070318T110000Z
FREEBUSY:20070319T100000Z/20070319T110000Z
FREEBUSY:20070320T100000Z/20070320T110000Z
FREEBUSY:20070321T100000Z/20070321T110000Z
FREEBUSY:20070322T100000Z/20070322T110000Z
FREEBUSY:20070323T100000Z/20070323T110000Z
FREEBUSY:20070324T100000Z/20070324T110000Z
FREEBUSY:20070325T100000Z/20070325T110000Z
FREEBUSY:20070326T100000Z/20070326T110000Z
FREEBUSY:20070327T100000Z/20070327T110000Z
FREEBUSY:20070328T100000Z/20070328T110000Z
FREEBUSY:20070329T100000Z/20070329T110000Z
FREEBUSY:20070330T100000Z/20070330T110000Z
FREEBUSY:20070331T100000Z/20070331T110000Z
FREEBUSY:20070401T100000Z/20070401T110000Z
FREEBUSY:20070402T100000Z/20070402T110000Z
FREEBUSY:20070403T100000Z/20070403T110000Z
FREEBUSY:20070404T100000Z/20070404T110000Z
FREEBUSY:20070405T100000Z/20070405T110000Z
FREEBUSY:20070406T100000Z/20070406T110000Z
FREEBUSY:20070407T100000Z/20070407T110000Z
FREEBUSY:20070408T100000Z/20070408T110000Z
FREEBUSY:20070409T100000Z/20070409T110000Z
FREEBUSY:20070410T100000Z/20070410T110000Z
FREEBUSY:20070411T100000Z/20070411T110000Z
FREEBUSY:20070412T100000Z/20070412T110000Z
FREEBUSY:20070413T100000Z/20070413T110000Z
FREEBUSY:20070414T100000Z/20070414T110000Z
FREEBUSY:20070415T100000Z/20070415T110000Z
FREEBUSY:20070416T100000Z/20070416T110000Z
FREEBUSY:20070417T100000Z/20070417T110000Z
FREEBUSY:20070418T100000Z/20070418T110000Z
FREEBUSY:20070419T100000Z/20070419T110000Z
FREEBUSY:20070420T100000Z/20070420T110000Z
FREEBUSY:20070421T100000Z/20070421T110000Z
FREEBUSY:20070422T100000Z/20070422T110000Z
FREEBUSY:20070423T100000Z/20070423T110000Z
FREEBUSY:20070424T100000Z/20070424T110000Z
FREEBUSY:20070425T100000Z/20070425T110000Z
FREEBUSY:20070426T100000Z/20070426T110000Z
FREEBUSY:20070427T100000Z/20070427T110000Z
FREEBUSY:20070428T100000Z/20070428T110000Z
FREEBUSY:20070429T100000Z/20070429T110000Z
FREEBUSY:20070430T100000Z/20070430T110000Z
FREEBUSY:20070501T100000Z/20070501T110000Z
FREEBUSY:20070502T100000Z/20070502T110000Z
FREEBUSY:20070503T100000Z/20070503T110000Z
FREEBUSY:20070504T100000Z/20070504T110000Z
FREEBUSY:20070505T100000Z/20070505T110000Z
FREEBUSY:20070506T100000Z/20070506T110000Z
FREEBUSY:20070507T100000Z/20070507T110000Z
FREEBUSY:20070508T100000Z/20070508T110000Z
FREEBUSY:20070509T100000Z/20070509T110000Z
FREEBUSY:20070510T100000Z/20070510T110000Z
FREEBUSY:20070511T100000Z/20070511T110000Z
FREEBUSY:20070512T100000Z/20070512T110000Z
FREEBUSY:20070513T100000Z/20070513T110000Z
FREEBUSY:20070514T100000Z/20070514T110000Z
FREEBUSY:20070515T100000Z/20070515T110000Z
FREEBUSY:20070516T100000Z/20070516T110000Z
FREEBUSY:20070517T100000Z/20070517T110000Z
FREEBUSY:20070518T100000Z/20070518T110000Z
FREEBUSY:20070519T100000Z/20070519T110000Z
FREEBUSY:20070520T100000Z/20070520T110000Z
FREEBUSY:20070521T100000Z/20070521T110000Z
FREEBUSY:20070522T100000Z/20070522T110000Z
FREEBUSY:20070523T100000Z/20070523T110000Z
FREEBUSY:20070524T100000Z/20070524T110000Z
FREEBUSY:20070525T100000Z/20070525T110000Z
FREEBUSY:20070526T100000Z/20070526T110000Z
FREEBUSY:20070527T100000Z/20070527T110000Z
FREEBUSY:20070528T100000Z/20070528T110000Z
FREEBUSY:20070529T100000Z/20070529T110000Z
FREEBUSY:20070530T100000Z/20070530T110000Z
FREEBUSY:20070531T100000Z/20070531T110000Z
FREEBUSY:20070601T100000Z/20070601T110000Z
FREEBUSY:20070602T100000Z/20070602T110000Z
FREEBUSY:20070603T100000Z/20070603T110000Z
FREEBUSY:20070604T100000Z/20070604T110000Z
FREEBUSY:20070605T100000Z/20070605T110000Z
FREEBUSY:20070606T100000Z/20070606T110000Z
FREEBUSY:20070607T100000Z/20070607T110000Z
FREEBUSY:20070608T100000Z/20070608T110000Z
FREEBUSY:20070609T100000Z/20070609T110000Z
FREEBUSY:20070610T100000Z/20070610T110000Z
FREEBUSY:20070611T100000Z/20070611T110000Z
FREEBUSY:20070612T100000Z/20070612T110000Z
FREEBUSY:20070613T100000Z/20070613T110000Z
FREEBUSY:20070614T100000Z/20070614T110000Z
FREEBUSY:20070615T100000Z/20070615T110000Z
FREEBUSY:20070616T100000Z/20070616T110000Z
FREEBUSY:20070617T100000Z/20070617T110000Z
FREEBUSY:20070618T100000Z/20070618T110000Z
FREEBUSY:20070619T100000Z/20070619T110000Z
FREEBUSY:20070620T100000Z/20070620T110000Z
FREEBUSY:20070621T100000Z/20070621T110000Z
FREEBUSY:20070622T100000Z/20070622T110000Z
FREEBUSY:20070623T100000Z/20070623T110000Z
FREEBUSY:20070624T100000Z/20070624T110000Z
FREEBUSY:20070625T100000Z/20070625T110000Z
FREEBUSY:20070626T100000Z/20070626T110000Z
FREEBUSY:20070627T100000Z/20070627T110000Z
FREEBUSY:20070628T100000Z/20070628T110000Z
FREEBUSY:20070629T100000Z/20070629T110000Z
FREEBUSY:20070630T100000Z/20070630T110000Z
END:VFREEBUSY
END:VCALENDAR

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT
ETag: "8f4ecca4cebdbf26f6a439035ec65d61"
Content-Length: 4038
ETag: "135496e5aa8c45c3ba999c28f7ffec62"
Content-Length: 4037
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -15,7 +15,7 @@ Content-Type: text/xml; charset="utf-8"
<C:calendar-home-set>
<href>/caldav.php/admin/</href>
</C:calendar-home-set>
<displayname>Calendar Administrator</displayname>
<displayname>DAViCal Administrator</displayname>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT
ETag: "f58718d47e33b0a952219bb94caee446"
Content-Length: 816
ETag: "1959f23de5a6bd3c525c504c09804d15"
Content-Length: 1226
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -25,8 +25,16 @@ Content-Type: text/xml; charset="utf-8"
</principal-URL>
<alternate-URI-set/>
<group-membership>
<href>/caldav.php/manager1/</href>
<href>/caldav.php/resource1/</href>
<href>/caldav.php/assistant1/</href>
<href>/caldav.php/resource2/</href>
<href>/caldav.php/resmgr1/</href>
<href>/caldav.php/teamclient1/</href>
<href>/caldav.php/manager1/calendar-proxy-read/</href>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<href>/caldav.php/resource1/calendar-proxy-write/</href>
<href>/caldav.php/resource2/calendar-proxy-write/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT
ETag: "725f2713529ca881526736b9dae5a92a"
Content-Length: 776
ETag: "d047d6bb34fe6e227afcb6ca4336883b"
Content-Length: 923
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -29,7 +29,10 @@ Content-Type: text/xml; charset="utf-8"
<href>/caldav.php/user2/</href>
<href>/caldav.php/assistant1/</href>
</group-member-set>
<group-membership/>
<group-membership>
<href>/caldav.php/resource1/calendar-proxy-write/</href>
<href>/caldav.php/resource2/calendar-proxy-write/</href>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT
ETag: "4f8ed125097724d9b6dad906e317f01d"
Content-Length: 8948
ETag: "8dade0339d83135c772d8f0838cc8339"
Content-Length: 8407
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -139,15 +139,33 @@ Content-Type: text/xml; charset="utf-8"
</resourcetype>
<getcontenttype>httpd/unix-directory</getcontenttype>
<current-user-privilege-set>
<privilege>
<read/>
</privilege>
<privilege>
<C:read-free-busy/>
</privilege>
<privilege>
<C:schedule-deliver/>
</privilege>
<privilege>
<C:schedule-deliver-invite/>
</privilege>
<privilege>
<C:schedule-deliver-reply/>
</privilege>
<privilege>
<C:schedule-query-freebusy/>
</privilege>
<privilege>
<C:schedule-send/>
</privilege>
<privilege>
<C:schedule-send-invite/>
</privilege>
<privilege>
<C:schedule-send-reply/>
</privilege>
<privilege>
<C:schedule-send-freebusy/>
</privilege>
</current-user-privilege-set>
<C2:getctag>ab4a67c917e242e0989cd278c75a510e</C2:getctag>
</prop>
@ -177,30 +195,33 @@ Content-Type: text/xml; charset="utf-8"
</resourcetype>
<getcontenttype>httpd/unix-directory</getcontenttype>
<current-user-privilege-set>
<privilege>
<read/>
</privilege>
<privilege>
<C:read-free-busy/>
</privilege>
<privilege>
<write/>
<C:schedule-deliver/>
</privilege>
<privilege>
<write-properties/>
<C:schedule-deliver-invite/>
</privilege>
<privilege>
<write-content/>
</privilege>
<privilege>
<bind/>
</privilege>
<privilege>
<unbind/>
<C:schedule-deliver-reply/>
</privilege>
<privilege>
<C:schedule-query-freebusy/>
</privilege>
<privilege>
<C:schedule-send/>
</privilege>
<privilege>
<C:schedule-send-invite/>
</privilege>
<privilege>
<C:schedule-send-reply/>
</privilege>
<privilege>
<C:schedule-send-freebusy/>
</privilege>
</current-user-privilege-set>
<C2:getctag>4d470212545b8dd76f702fe2444accad</C2:getctag>
</prop>
@ -230,42 +251,12 @@ Content-Type: text/xml; charset="utf-8"
</resourcetype>
<getcontenttype>httpd/unix-directory</getcontenttype>
<current-user-privilege-set>
<privilege>
<all/>
</privilege>
<privilege>
<read/>
</privilege>
<privilege>
<unlock/>
</privilege>
<privilege>
<read-acl/>
</privilege>
<privilege>
<read-current-user-privilege-set/>
</privilege>
<privilege>
<write-acl/>
</privilege>
<privilege>
<C:read-free-busy/>
</privilege>
<privilege>
<write/>
</privilege>
<privilege>
<write-properties/>
</privilege>
<privilege>
<write-content/>
</privilege>
<privilege>
<bind/>
</privilege>
<privilege>
<unbind/>
</privilege>
<privilege>
<C:schedule-deliver/>
</privilege>
@ -319,42 +310,12 @@ Content-Type: text/xml; charset="utf-8"
</resourcetype>
<getcontenttype>httpd/unix-directory</getcontenttype>
<current-user-privilege-set>
<privilege>
<all/>
</privilege>
<privilege>
<read/>
</privilege>
<privilege>
<unlock/>
</privilege>
<privilege>
<read-acl/>
</privilege>
<privilege>
<read-current-user-privilege-set/>
</privilege>
<privilege>
<write-acl/>
</privilege>
<privilege>
<C:read-free-busy/>
</privilege>
<privilege>
<write/>
</privilege>
<privilege>
<write-properties/>
</privilege>
<privilege>
<write-content/>
</privilege>
<privilege>
<bind/>
</privilege>
<privilege>
<unbind/>
</privilege>
<privilege>
<C:schedule-deliver/>
</privilege>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD
ETag: "d2647e4027425f0fe49ad06b992e27e4"
Content-Length: 943
ETag: "fcb2b06e2039d4cfe89b55caeb0098ef"
Content-Length: 3601
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -13,6 +13,58 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<group-membership>
<response>
<href>/caldav.php/manager1/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/assistant1/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resmgr1/</href>
<propstat>
@ -39,6 +91,54 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/manager1/calendar-proxy-read/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/calendar-proxy-write/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/calendar-proxy-write/</href>
<propstat>
<prop>
<getcontenttype>httpd/unix-directory</getcontenttype>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>

View File

@ -2,8 +2,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
Allow: OPTIONS, PROPFIND, REPORT, DELETE, LOCK, UNLOCK, MOVE, GET, PUT, HEAD, MKCOL, MKCALENDAR, PROPPATCH
ETag: "d5cc117a7382cebe6ed7ca36b21af7e6"
Content-Length: 1535
ETag: "28de2f8aacb30df4a2b3631090940876"
Content-Length: 6499
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
@ -13,6 +13,98 @@ Content-Type: text/xml; charset="utf-8"
<propstat>
<prop>
<group-membership>
<response>
<href>/caldav.php/manager1/</href>
<propstat>
<prop>
<displayname>Manager 1</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/manager1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<displayname>Resource 1</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/assistant1/</href>
<propstat>
<prop>
<displayname>Assistant 1</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/assistant1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<displayname>Resource 2</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resmgr1/</href>
<propstat>
@ -59,6 +151,98 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/manager1/calendar-proxy-read/</href>
<propstat>
<prop>
<displayname>manager1 proxy read</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/manager1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/assistant1/calendar-proxy-read/</href>
<propstat>
<prop>
<displayname>assistant1 proxy read</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/assistant1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/calendar-proxy-write/</href>
<propstat>
<prop>
<displayname>resource1 proxy write</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/calendar-proxy-write/</href>
<propstat>
<prop>
<displayname>resource2 proxy write</displayname>
<C:calendar-home-set>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</C:calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</group-membership>
</prop>
<status>HTTP/1.1 200 OK</status>