diff --git a/inc/CalDAVPrincipal.php b/inc/CalDAVPrincipal.php index d3b4b802..dafef993 100644 --- a/inc/CalDAVPrincipal.php +++ b/inc/CalDAVPrincipal.php @@ -98,6 +98,16 @@ class CalDAVPrincipal */ protected $principal_address; + /** + * @var The username for this principal + */ + protected $username; + + /** + * @var The dav_name for this principal - a partial path + */ + protected $dav_name; + /** * Constructor * @param mixed $parameters If null, an empty Principal is created. If it @@ -122,24 +132,29 @@ class CalDAVPrincipal else if ( is_int($parameters) ) { dbg_error_log( 'principal', 'Principal: %d', $parameters ); $usr = getUserByID($parameters); + $this->user_no = $parameters['user_no']; } else if ( is_array($parameters) ) { if ( ! isset($parameters['options']['allow_by_email']) ) $parameters['options']['allow_by_email'] = false; if ( isset($parameters['username']) ) { $usr = getUserByName($parameters['username']); + $this->username = $parameters['username']; } else if ( isset($parameters['user_no']) ) { $usr = getUserByID($parameters['user_no']); + $this->user_no = $parameters['user_no']; } else if ( isset($parameters['email']) && $parameters['options']['allow_by_email'] ) { if ( $username = $this->UsernameFromEMail($parameters['email']) ) { $usr = getUserByName($username); + $this->username = $username; } } else if ( isset($parameters['path']) ) { dbg_error_log( 'principal', 'Finding Principal from path: "%s", options.allow_by_email: "%s"', $parameters['path'], $parameters['options']['allow_by_email'] ); if ( $username = $this->UsernameFromPath($parameters['path'], $parameters['options']) ) { $usr = getUserByName($username); + $this->username = $username; } } else if ( isset($parameters['principal-property-search']) ) { @@ -399,11 +414,33 @@ class CalDAVPrincipal } + /** + * Return the username + * @return string The username + */ + function username() { + return (isset($this->username)?$this->username:'username not set'); + } + + + /** + * Return the partial path representing this principal + * @return string The dav_name + */ + function dav_name() { + if ( !isset($this->dav_name) ) { + if ( !isset($this->username) ) $this->dav_name = ''; + else $this->dav_name = '/'.$this->username.'/'; + } + return $this->dav_name; + } + + /** * Return the privileges bits for the current session user to this resource */ function Privileges() { - if ( !isset($this->privileges) ) + if ( !isset($this->privileges) ) $this->privileges = 0; if ( is_string($this->privileges) ) $this->privileges = bindec( $this->privileges ); return $this->privileges; } @@ -419,15 +456,16 @@ class CalDAVPrincipal 'is_addressbook' => 'f', 'is_principal' => 't', 'user_no' => (isset($this->user_no) ? $this->user_no : 0), - 'username' => (isset($this->username) ? $this->username : 0), + 'username' => $this->username(), + 'dav_name' => $this->dav_name(), 'email' => (isset($this->email) ? $this->email : ''), - 'created' => (isset($this->created) ? $this->created : date('Ymd\THis')) + 'created' => (isset($this->created) ? $this->created : date('Ymd\THis')), + 'updated' => (isset($this->updated) ? $this->updated : date('Ymd\THis')) ); - if ( $this->exists ) { - $collection->dav_name = (isset($this->dav_name) ? $this->dav_name : '/' . $this->username . '/'); - $collection->dav_etag = (isset($this->dav_etag) ? $this->dav_etag : md5($this->username . $this->updated)); - $collection->dav_displayname = (isset($this->dav_displayname) ? $this->dav_displayname : (isset($this->fullname) ? $this->fullname : $this->username)); - } + $collection->dav_name = $this->dav_name(); + $collection->dav_etag = (isset($this->dav_etag) ? $this->dav_etag : md5($collection->username . $collection->updated)); + $collection->dav_displayname = (isset($this->dav_displayname) ? $this->dav_displayname : (isset($this->fullname) ? $this->fullname : $collection->username)); + return $collection; } diff --git a/inc/CalDAVRequest.php b/inc/CalDAVRequest.php index 5ce24998..77792aba 100644 --- a/inc/CalDAVRequest.php +++ b/inc/CalDAVRequest.php @@ -388,8 +388,15 @@ EOSQL; if ( isset($this->principal->by_email) && $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' ) { + if ( $this->collection_type == 'principal' || $this->collection_type == 'email' || $this->collection_type == 'proxy' ) { $this->collection = $this->principal->AsCollection(); + if( $this->collection_type == 'proxy' ) { + $this->collection = $this->principal->AsCollection(); + $this->collection->is_proxy = 't'; + $this->collection->type = 'proxy'; + $this->collection->proxy_type = $this->proxy_type; + $this->collection->dav_displayname = sprintf('Proxy %s for %s', $this->proxy_type, $this->principal->username() ); + } } elseif( $this->collection_type == 'root' ) { $this->collection = (object) array( @@ -404,23 +411,6 @@ EOSQL; 'created' => date('Ymd\THis') ); } - elseif( $this->collection_type == 'proxy' ) { - $this->collection = (object) array( - 'dav_name' => $this->collection_path, - 'is_calendar' => 'f', - 'is_principal' => 't', - 'is_proxy' => 't', - 'type' => 'proxy', - 'proxy_type' => $this->proxy_type, - 'dav_displayname' => sprintf('Proxy %s for %s', $this->proxy_type, $this->principal->username), - 'collection_id' => 0, - 'user_no' => $this->principal->user_no, - 'username' => $this->principal->username, - 'email' => $this->principal->email, - 'created' => $this->principal->created, - 'dav_etag' => $this->principal->created - ); - } /** * Evaluate our permissions for accessing the target @@ -470,6 +460,7 @@ EOSQL; $this->supported_methods['MKCOL'] = ''; $this->supported_methods['MKCALENDAR'] = ''; $this->supported_methods['PROPPATCH'] = ''; + $this->supported_methods['BIND'] = ''; break; } } diff --git a/inc/DAVResource.php b/inc/DAVResource.php index ef56c720..f6803486 100644 --- a/inc/DAVResource.php +++ b/inc/DAVResource.php @@ -146,12 +146,12 @@ class DAVResource $this->supported_methods = null; $this->supported_reports = null; - $this->_is_collection = false; - $this->_is_principal = false; - $this->_is_calendar = false; - $this->_is_binding = false; - $this->_is_addressbook = false; - $this->_is_proxy = false; + $this->_is_collection = false; + $this->_is_principal = false; + $this->_is_calendar = false; + $this->_is_binding = false; + $this->_is_addressbook = false; + $this->_is_proxy_request = false; if ( isset($parameters) && is_object($parameters) ) { $this->FromRow($parameters); } @@ -222,10 +222,15 @@ class DAVResource if ( !isset( $this->collection->type ) || $this->collection->type == 'collection' ) { if ( $this->_is_principal ) $this->collection->type = 'principal'; - else if ( $row->is_calendar == 't' ) + else if ( $row->is_calendar == 't' ) { $this->collection->type = 'calendar'; - else if ( $row->is_addressbook == 't' ) + } + else if ( $row->is_addressbook == 't' ) { $this->collection->type = 'addressbook'; + } + else if ( isset($row->is_proxy) && $row->is_proxy == 't' ) { + $this->collection->type = 'proxy'; + } else if ( preg_match( '#^((/[^/]+/)\.(in|out)/)[^/]*$#', $this->dav_name, $matches ) ) $this->collection->type = 'schedule-'. $matches[3]. 'box'; else if ( $this->dav_name == '/' ) @@ -236,9 +241,13 @@ class DAVResource $this->_is_calendar = ($this->collection->is_calendar == 't'); $this->_is_addressbook = ($this->collection->is_addressbook == 't'); + $this->_is_proxy_request= ($this->collection->type == 'proxy'); if ( $this->_is_principal && !isset($this->resourcetypes) ) { $this->resourcetypes = ''; } + else if ( $this->_is_proxy_request ) { + $this->resourcetypes = sprintf('', $this->collection->proxy_type ); + } if ( isset($this->collection->dav_displayname) ) $this->collection->displayname = $this->collection->dav_displayname; } else { @@ -536,7 +545,7 @@ EOQRY; if ( $this->IsPrincipal() ) { if ( !isset($this->principal) ) $this->FetchPrincipal(); $this->privileges = $this->principal->Privileges(); - dbg_error_log( 'DAVResource', 'Privileges of "%s" for user accessing principal "%s"', $this->privileges, $this->principal->username ); + dbg_error_log( 'DAVResource', 'Privileges of "%s" for user accessing "%s"', $this->privileges, $this->principal->username() ); return; } @@ -1384,7 +1393,7 @@ EOQRY; } $found = $this->ResourceProperty($tag, $prop, $reply, $denied ); if ( !$found ) { - if ( !isset($this->principal) ) $this->FetchPrincipal(); + if ( !isset($this->principal) ) $this->FetchPrincipal(); $found = $this->principal->PrincipalProperty( $tag, $prop, $reply, $denied ); } if ( ! $found ) { @@ -1431,7 +1440,7 @@ EOQRY; function RenderAsXML( $properties, &$reply, $props_only = false ) { global $session, $c, $request; - dbg_error_log('DAVResource',':RenderAsXML: Resource "%s"', $this->dav_name ); + dbg_error_log('DAVResource',':RenderAsXML: Resource "%s" exists(%d)', $this->dav_name, $this->Exists() ); if ( !$this->Exists() ) return null; diff --git a/inc/caldav-PROPFIND.php b/inc/caldav-PROPFIND.php index a659f565..45a6c318 100644 --- a/inc/caldav-PROPFIND.php +++ b/inc/caldav-PROPFIND.php @@ -49,11 +49,12 @@ foreach( $allprop AS $k1 => $propwrap ) { * Add the calendar-proxy-read/write pseudocollections * @param responses array of responses to which to add the collections */ -function add_proxy_response( &$responses, $which, $parent_path ) { +function add_proxy_response( $which, $parent_path ) { global $request, $reply, $c, $session, $property_list; - if ($parent_path != '/'.$request->principal->username.'/') { - return; // Nothing to proxy for + if ($parent_path != $request->principal->dav_name()) { + dbg_error_log( 'PROPFIND', 'Not returning proxy response since "%s" != "%s"', $parent_path, $request->principal->dav_name() ); + return null; // Nothing to proxy for } $collection = (object) ''; @@ -63,6 +64,8 @@ function add_proxy_response( &$responses, $which, $parent_path ) { $proxy_group = $request->principal->WriteProxyGroup(); } + dbg_error_log( 'PROPFIND', 'Returning proxy response to "%s" for "%s"', $which, $parent_path ); + $collection->dav_name = $parent_path.'calendar-proxy-'.$which.'/'; $collection->is_calendar = 'f'; $collection->is_addressbook = 'f'; @@ -86,7 +89,7 @@ function add_proxy_response( &$responses, $which, $parent_path ) { $resource = new DAVResource($collection); $resource->FetchPrincipal(); - $responses[] = $resource->RenderAsXML($property_list, $reply); + return $resource->RenderAsXML($property_list, $reply); } @@ -154,11 +157,13 @@ function get_collection_contents( $depth, $collection ) { } } - if ( $collection->IsPrincipal() == 't' ) { + if ( $collection->IsPrincipal() ) { // Caldav Proxy: 5.1 par. 2: Add child resources calendar-proxy-(read|write) dbg_error_log('PROPFIND','Adding calendar-proxy-read and write. Path: %s', $bound_from ); - add_proxy_response($responses, 'read', $bound_from ); - add_proxy_response($responses, 'write', $bound_from ); + $response = add_proxy_response('read', $bound_from ); + if ( isset($response) ) $responses[] = $response; + $response = add_proxy_response('write', $bound_from ); + if ( isset($response) ) $responses[] = $response; } } @@ -205,7 +210,8 @@ function get_collection_contents( $depth, $collection ) { */ $responses = array(); if ( $request->IsProxyRequest() ) { - add_proxy_response($responses, $request->proxy_type, '/' . $request->principal->username . '/' ); + $response = add_proxy_response($request->proxy_type, $request->principal->dav_name() ); + if ( isset($response) ) $responses[] = $response; } else { $resource = new DAVResource($request->path); diff --git a/testing/tests/regression-suite/827-Spec-PROPFIND.result b/testing/tests/regression-suite/827-Spec-PROPFIND.result index 3ff5a83a..c7834239 100644 --- a/testing/tests/regression-suite/827-Spec-PROPFIND.result +++ b/testing/tests/regression-suite/827-Spec-PROPFIND.result @@ -365,158 +365,6 @@ /manager1/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /assistant1/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /teamclient1/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - YYYY-MM-DDThh:mm:ss+ZZ:ZZ Manager 1 @@ -539,6 +387,12 @@ HTTP/1.1 200 OK + + + + + HTTP/1.1 403 Forbidden + @@ -555,127 +409,6 @@ /assistant1/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /teamclient1/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - YYYY-MM-DDThh:mm:ss+ZZ:ZZ Assistant 1 @@ -698,6 +431,12 @@ HTTP/1.1 200 OK + + + + + HTTP/1.1 403 Forbidden + diff --git a/testing/tests/regression-suite/873-GroupDAV-PROPFIND.result b/testing/tests/regression-suite/873-GroupDAV-PROPFIND.result index 4306799b..efcc641f 100644 --- a/testing/tests/regression-suite/873-GroupDAV-PROPFIND.result +++ b/testing/tests/regression-suite/873-GroupDAV-PROPFIND.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy ETag: "some valid etag" -Content-Length: 8808 +Content-Length: 8564 Content-Type: text/xml; charset="utf-8" @@ -143,21 +143,16 @@ Content-Type: text/xml; charset="utf-8" httpd/unix-directory - - - - - - - - - - - some valid etag HTTP/1.1 200 OK + + + + + HTTP/1.1 403 Forbidden + @@ -181,21 +176,16 @@ Content-Type: text/xml; charset="utf-8" httpd/unix-directory - - - - - - - - - - - some valid etag HTTP/1.1 200 OK + + + + + HTTP/1.1 403 Forbidden + diff --git a/testing/tests/regression-suite/921-PROPFIND-supported-stuff.result b/testing/tests/regression-suite/921-PROPFIND-supported-stuff.result index e625ae8b..f64e0439 100644 --- a/testing/tests/regression-suite/921-PROPFIND-supported-stuff.result +++ b/testing/tests/regression-suite/921-PROPFIND-supported-stuff.result @@ -1,7 +1,17 @@ -HTTP/1.1 404 Not Found +HTTP/1.1 403 Forbidden Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy -Content-Length: 44 -Content-Type: text/plain; charset="utf-8" +Content-Length: 223 +Content-Type: text/xml; charset="utf-8" -That resource is not present on this server. \ No newline at end of file + + + + + /caldav.php/bogusprincipal/ + + + + + + diff --git a/testing/tests/regression-suite/940-PROPFIND-acl.result b/testing/tests/regression-suite/940-PROPFIND-acl.result index e79f0399..ec0d25a2 100644 --- a/testing/tests/regression-suite/940-PROPFIND-acl.result +++ b/testing/tests/regression-suite/940-PROPFIND-acl.result @@ -1,26 +1,17 @@ -HTTP/1.1 207 Multi-Status +HTTP/1.1 403 Forbidden Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, access-control, calendar-access, calendar-schedule, extended-mkcol, calendar-proxy -ETag: "8073d2f394ea97ba89104f1834ad6c58" -Content-Length: 386 +Content-Length: 214 Content-Type: text/xml; charset="utf-8" - - - /caldav.php/user1/ - - - - - HTTP/1.1 200 OK - - - - - - - HTTP/1.1 403 Forbidden - - - + + + + /caldav.php/user1/ + + + + + +