mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-04-26 15:20:16 +00:00
Move principal rendering into principal.
This commit is contained in:
parent
ba67df4d1f
commit
1f8b3a2af9
@ -148,6 +148,8 @@ class CalDAVPrincipal
|
||||
foreach( $usr AS $k => $v ) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
if ( !isset($this->modified) ) $this->modified = ISODateToHTTPDate($this->updated);
|
||||
if ( !isset($this->created) ) $this->created = ISODateToHTTPDate($this->joined);
|
||||
|
||||
$this->by_email = false;
|
||||
$this->url = ConstructURL( "/".$this->username."/" );
|
||||
@ -247,27 +249,20 @@ class CalDAVPrincipal
|
||||
$path_split = explode('/', $path );
|
||||
@dbg_error_log( "principal", "Path split into at least /// %s /// %s /// %s", $path_split[1], $path_split[2], $path_split[3] );
|
||||
|
||||
if ( substr($path,0,1) == '~' ) {
|
||||
// URL is for a principal, by name
|
||||
$username = substr($path_split[1],1);
|
||||
$user = getUserByID($username);
|
||||
$user_no = $user->user_no;
|
||||
}
|
||||
else {
|
||||
$username = $path_split[1];
|
||||
$username = $path_split[1];
|
||||
if ( substr($username,0,1) == '~' ) $username = substr($username,1);
|
||||
|
||||
if ( isset($options['allow_by_email']) && preg_match( '#/(\S+@\S+[.]\S+)$#', $path, $matches) ) {
|
||||
$email = $matches[1];
|
||||
$qry = new PgQuery("SELECT user_no, username FROM usr WHERE email = ?;", $email );
|
||||
if ( $qry->Exec("principal") && $user = $qry->Fetch() ) {
|
||||
$user_no = $user->user_no;
|
||||
$username = $user->username;
|
||||
}
|
||||
}
|
||||
elseif( $user = getUserByName( $username, 'caldav') ) {
|
||||
if ( isset($options['allow_by_email']) && preg_match( '#/(\S+@\S+[.]\S+)$#', $path, $matches) ) {
|
||||
$email = $matches[1];
|
||||
$qry = new PgQuery("SELECT user_no, username FROM usr WHERE email = ?;", $email );
|
||||
if ( $qry->Exec("principal") && $user = $qry->Fetch() ) {
|
||||
$user_no = $user->user_no;
|
||||
$username = $user->username;
|
||||
}
|
||||
}
|
||||
elseif( $user = getUserByName( $username, 'caldav') ) {
|
||||
$user_no = $user->user_no;
|
||||
}
|
||||
return $username;
|
||||
}
|
||||
|
||||
@ -287,6 +282,26 @@ class CalDAVPrincipal
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a representation of the principal as a collection
|
||||
*/
|
||||
function AsCollection() {
|
||||
$collection = (object) array(
|
||||
'collection_id' => (isset($this->collection_id) ? $this->collection_id : 0),
|
||||
'is_calendar' => 'f',
|
||||
'is_principal' => 't',
|
||||
'user_no' => (isset($this->user_no) ? $this->user_no : 0),
|
||||
'username' => (isset($this->username) ? $this->username : 0),
|
||||
'email' => (isset($this->email) ? $this->email : ''),
|
||||
'created' => (isset($this->created) ? $this->created : date('Ymd\THis'))
|
||||
);
|
||||
$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));
|
||||
return $collection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the array of privilege names converted into XMLElements
|
||||
*/
|
||||
@ -336,27 +351,19 @@ class CalDAVPrincipal
|
||||
break;
|
||||
|
||||
case 'DAV::getlastmodified':
|
||||
$prop->NewElement("getlastmodified", ISODateToHTTPDate($this->updated) );
|
||||
$prop->NewElement("getlastmodified", $this->modified );
|
||||
break;
|
||||
|
||||
case 'DAV::creationdate':
|
||||
$prop->NewElement("creationdate", ISODateToHTTPDate($this->joined) );
|
||||
$prop->NewElement("creationdate", $this->created );
|
||||
break;
|
||||
|
||||
case 'DAV::group-member-set':
|
||||
$set = array();
|
||||
foreach( $this->group_member_set AS $k => $url ) {
|
||||
$set[] = $reply->href($url );
|
||||
}
|
||||
$prop->NewElement("group-member-set", $set );
|
||||
$prop->NewElement("group-member-set", $reply->href($this->group_member_set) );
|
||||
break;
|
||||
|
||||
case 'DAV::group-membership':
|
||||
$set = array();
|
||||
foreach( $this->group_membership AS $k => $url ) {
|
||||
$set[] = $reply->href($url );
|
||||
}
|
||||
$prop->NewElement("group-membership", $set );
|
||||
$prop->NewElement("group-membership", $reply->href($this->group_membership) );
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:caldav:schedule-inbox-URL':
|
||||
@ -376,11 +383,7 @@ class CalDAVPrincipal
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:caldav:calendar-home-set':
|
||||
$set = array();
|
||||
foreach( $this->calendar_home_set AS $k => $url ) {
|
||||
$set[] = $reply->href( $url );
|
||||
}
|
||||
$reply->CalDAVElement($prop, "calendar-home-set", $set );
|
||||
$reply->CalDAVElement($prop, "calendar-home-set", $reply->href( $this->calendar_home_set ) );
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:caldav:calendar-user-address-set':
|
||||
|
||||
@ -177,6 +177,7 @@ class CalDAVRequest
|
||||
if ( preg_match( $bad_chars_regex, $this->path ) ) {
|
||||
$this->DoResponse( 400, translate("The calendar path contains illegal characters.") );
|
||||
}
|
||||
if ( strstr($this->path,'//') ) $this->path = preg_replace( '#//+#', '/', $this->path);
|
||||
|
||||
$this->user_no = $session->user_no;
|
||||
$this->username = $session->username;
|
||||
@ -234,10 +235,23 @@ EOSQL;
|
||||
$this->collection = $row;
|
||||
}
|
||||
}
|
||||
else if ( preg_match( '#/(\S+@\S+[.]\S+)/?$#', $this->path) ) {
|
||||
else if ( preg_match( '#^((/[^/]+/)calendar-proxy-(read|write))/?[^/]*$#', $this->path, $matches ) ) {
|
||||
$this->collection_type = 'proxy';
|
||||
$this->_is_proxy_request = true;
|
||||
$this->proxy_type = $matches[3];
|
||||
$this->collection_path = $matches[1].'/'; // Enforce trailling '/'
|
||||
if ( $this->collection_path == $this->path."/" ) {
|
||||
$this->path .= '/';
|
||||
dbg_error_log( "caldav", "Path is actually a (proxy) collection - sending Content-Location header." );
|
||||
header( "Content-Location: ".ConstructURL($this->path) );
|
||||
}
|
||||
}
|
||||
else if ( preg_match( '#^/(\S+@\S+[.]\S+)/?$#', $this->path) ) {
|
||||
/** @TODO: we should deprecate this now that Evolution 2.27 can do scheduling extensions */
|
||||
$this->collection_id = -1;
|
||||
$this->collection_type = 'email';
|
||||
$this->collection_path = $this->path;
|
||||
$this->_is_principal = true;
|
||||
}
|
||||
else if ( preg_match( '#^(/[^/]+)/?$#', $this->path, $matches) ) {
|
||||
$this->collection_id = -1;
|
||||
@ -267,6 +281,38 @@ EOSQL;
|
||||
if ( isset($this->principal->username)) $this->username = $this->principal->username;
|
||||
if ( isset($this->principal->by_email)) $this->by_email = true;
|
||||
|
||||
if ( $this->collection_type == 'principal' || $this->collection_type == 'email' ) {
|
||||
$this->collection = $this->principal->AsCollection();
|
||||
}
|
||||
elseif( $this->collection_type == 'root' ) {
|
||||
$this->collection = (object) array(
|
||||
'collection_id' => 0,
|
||||
'dav_name' => '/',
|
||||
'dav_etag' => md5($c->system_name),
|
||||
'is_calendar' => 'f',
|
||||
'is_principal' => 'f',
|
||||
'user_no' => 0,
|
||||
'dav_displayname' => $c->system_name,
|
||||
'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',
|
||||
'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
|
||||
*/
|
||||
@ -582,6 +628,17 @@ EOSQL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the URL referenced by this request is within a proxy URL
|
||||
*/
|
||||
function IsProxyRequest( ) {
|
||||
if ( !isset($this->_is_proxy_request) ) {
|
||||
$this->_is_proxy_request = preg_match( '#^/[^/]+/calendar-proxy-(read|write)/?[^/]*$#', $this->path );
|
||||
}
|
||||
return $this->_is_proxy_request;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the request asked for infinite depth
|
||||
*/
|
||||
|
||||
@ -70,13 +70,13 @@ foreach( $request->xml_tags AS $k => $v ) {
|
||||
case 'urn:ietf:params:xml:ns:caldav:schedule-inbox-URL': /** Support in development */
|
||||
case 'urn:ietf:params:xml:ns:caldav:schedule-outbox-URL': /** Support in development */
|
||||
case 'urn:ietf:params:xml:ns:caldav:calendar-free-busy-set': /** Deprecated, but should work fine */
|
||||
case 'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set':
|
||||
case 'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set': /** Should work fine */
|
||||
|
||||
/**
|
||||
* Handled calendarserver properties
|
||||
*/
|
||||
case 'http://calendarserver.org/ns/:getctag': /** Calendar Server extension like etag - should work fine (we just return etag) */
|
||||
case 'http://calendarserver.org/ns/:calendar-proxy-read-for': /** Calendar Server Delegation readonly */
|
||||
case 'http://calendarserver.org/ns/:calendar-proxy-read-for': /** Calendar Server Delegation readonly */
|
||||
case 'http://calendarserver.org/ns/:calendar-proxy-write-for': /** Calendar Server Delegation read-write */
|
||||
case 'http://calendarserver.org/ns/:dropbox-home-URL':
|
||||
case 'http://calendarserver.org/ns/:notifications-URL':
|
||||
@ -202,10 +202,6 @@ function add_principal_properties( &$prop, &$denied ) {
|
||||
$reply->DAVElement( $prop, "alternate-URI-set" ); // Empty - there are no alternatives!
|
||||
}
|
||||
|
||||
if (isset($prop_list['DAV::group-membership'])) {
|
||||
$reply->DAVElement($prop, "group-membership", href_set_from_paths( $request->principal->group_membership ));
|
||||
}
|
||||
|
||||
if ( isset($prop_list['urn:ietf:params:xml:ns:caldav:calendar-home-set'] ) ) {
|
||||
$reply->CalDAVElement( $prop, "calendar-home-set", href_set_from_paths( $request->principal->calendar_home_set ) );
|
||||
}
|
||||
@ -223,14 +219,6 @@ function add_principal_properties( &$prop, &$denied ) {
|
||||
$reply->CalendarserverElement($prop, "notifications-URL", $reply->href( $request->principal->notifications_url) );
|
||||
}
|
||||
|
||||
// Caldav proxy (not described in rfc, but CalendarServer has it)
|
||||
if ( isset($prop_list['http://calendarserver.org/ns/:calendar-proxy-read-for'] ) ) {
|
||||
$reply->CalendarserverElement($prop, "calendar-proxy-read-for", href_set_from_paths( $request->principal->read_proxy_for ) );
|
||||
}
|
||||
if ( isset($prop_list['http://calendarserver.org/ns/:calendar-proxy-write-for'] ) ) {
|
||||
$reply->CalendarserverElement($prop, "calendar-proxy-write-for", href_set_from_paths( $request->principal->write_proxy_for ) );
|
||||
}
|
||||
|
||||
if ( isset($prop_list['urn:ietf:params:xml:ns:caldav:calendar-user-address-set'] ) ) {
|
||||
$reply->CalDAVElement( $prop, "calendar-user-address-set", href_set_from_paths( $request->principal->user_address_set ) );
|
||||
}
|
||||
@ -374,18 +362,23 @@ function add_proxy_response( &$responses, $which, $parent_path ) {
|
||||
} else if ( $which == "write" ) {
|
||||
$proxy_group = $request->principal->write_proxy_group;
|
||||
}
|
||||
if ( !isset($proxy_group) || !is_array($proxy_group) || count($proxy_group) < 1 ) {
|
||||
if ($parent_path != '/'.$request->principal->username.'/') {
|
||||
return; // Nothing to proxy for
|
||||
}
|
||||
|
||||
$collection->dav_name = $parent_path."calendar-proxy-".$which."/";
|
||||
$collection->is_calendar = 'f';
|
||||
$collection->is_calendar = 'f';
|
||||
$collection->is_principal = 't';
|
||||
$collection->is_proxy = 't';
|
||||
$collection->proxy_type = $which;
|
||||
$collection->dav_displayname = $collection->dav_name;
|
||||
$collection->collection_id = 0;
|
||||
$collection->user_no = $session->user_no;
|
||||
$collection->username = $session->username;
|
||||
$collection->email = $session->email;
|
||||
$collection->created = date('Ymd\THis');
|
||||
$collection->dav_etag = md5($c->system_name . $collection->dav_name . implode($proxy_group) );
|
||||
$collection->proxy_for = $proxy_group;
|
||||
|
||||
$responses[] = collection_to_xml( $collection );
|
||||
}
|
||||
@ -458,9 +451,9 @@ function collection_to_xml( $collection ) {
|
||||
$resourcetypes[] = $reply->NewXMLElement( "principal", false, false, 'DAV:');
|
||||
}
|
||||
|
||||
// As per Caldav Proxy 5.1 par. 3
|
||||
if (preg_match('#(calendar-proxy-(read|write))#', $collection->dav_displayname, $matches) && isset($prop_list['DAV::resourcetype'])) {
|
||||
$resourcetypes[] = $reply->NewXMLElement($matches[1], false, false, 'http://calendarserver.org/ns/');
|
||||
if ( isset($collection->is_proxy) && $collection->is_proxy == 't' ) {
|
||||
// As per Caldav Proxy 5.1 par. 3
|
||||
$resourcetypes[] = $reply->NewXMLElement('calendar-proxy-'.$collection->proxy_type, false, false, 'http://calendarserver.org/ns/');
|
||||
}
|
||||
|
||||
if ( $allprop || isset($prop_list['DAV::getcontentlength']) ) {
|
||||
@ -471,6 +464,33 @@ function collection_to_xml( $collection ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($collection->is_proxy) && $collection->is_proxy == 't' ) {
|
||||
// Caldav proxy (not described in rfc, but CalendarServer has it)
|
||||
if ( isset($prop_list['http://calendarserver.org/ns/:calendar-proxy-'.$collection->proxy_type.'-for'] ) ) {
|
||||
if ( $collection->proxy_type == "read" ) {
|
||||
$proxy_group = $request->principal->read_proxy_for;
|
||||
} else if ( $collection->proxy_type == "write" ) {
|
||||
$proxy_group = $request->principal->write_proxy_for;
|
||||
}
|
||||
$reply->CalendarserverElement($prop, 'calendar-proxy-'.$collection->proxy_type.'-for', $reply->href( $proxy_group ) );
|
||||
}
|
||||
|
||||
if ( isset($prop_list['DAV::group-member-set']) ) {
|
||||
if ( $collection->proxy_type == "read" ) {
|
||||
$proxy_group = $request->principal->read_proxy_group;
|
||||
} else if ( $collection->proxy_type == "write" ) {
|
||||
$proxy_group = $request->principal->write_proxy_group;
|
||||
}
|
||||
$reply->DAVElement($prop, "group-member-set", $reply->href( $proxy_group ) );
|
||||
}
|
||||
|
||||
if (isset($prop_list['DAV::group-membership'])) {
|
||||
$reply->DAVElement($prop, "group-membership", $reply->href( $request->principal->group_membership ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( $allprop || isset($prop_list['DAV::displayname']) ) {
|
||||
$displayname = ( $collection->dav_displayname == "" ? ucfirst(trim(str_replace("/"," ", $collection->dav_name))) : $collection->dav_displayname );
|
||||
$reply->DAVElement( $prop, "displayname", $displayname );
|
||||
@ -578,8 +598,8 @@ function get_collection_contents( $depth, $user_no, $collection ) {
|
||||
* Calendar collections may not contain calendar collections.
|
||||
*/
|
||||
if ( $collection->dav_name == '/' ) {
|
||||
$sql = "SELECT usr.*, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql .= "to_char(updated at time zone 'GMT',?) AS created, ";
|
||||
$sql = "SELECT usr.*, '/' || username || '/' AS dav_name, md5(username || updated::text) AS dav_etag, ";
|
||||
$sql .= "to_char(joined at time zone 'GMT',?) AS created, ";
|
||||
$sql .= "to_char(updated at time zone 'GMT',?) AS modified, ";
|
||||
$sql .= "fullname AS dav_displayname, FALSE AS is_calendar, TRUE AS is_principal, ";
|
||||
$sql .= "0 AS collection_id ";
|
||||
@ -613,6 +633,12 @@ function get_collection_contents( $depth, $user_no, $collection ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $collection->is_principal == "t" ) {
|
||||
// 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", $collection->dav_name);
|
||||
add_proxy_response($responses, "read", $collection->dav_name);
|
||||
add_proxy_response($responses, "write", $collection->dav_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -674,8 +700,8 @@ function get_collection( $depth, $user_no, $collection_path ) {
|
||||
else {
|
||||
$user_no = intval($user_no);
|
||||
if ( preg_match( '#^/[^/]+/$#', $collection_path) ) {
|
||||
$sql = "SELECT usr.*, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql .= "to_char(updated at time zone 'GMT',?) AS created, ";
|
||||
$sql = "SELECT usr.*, '/' || username || '/' AS dav_name, md5( username || updated::text ) AS dav_etag, ";
|
||||
$sql .= "to_char(joined at time zone 'GMT',?) AS created, ";
|
||||
$sql .= "to_char(updated at time zone 'GMT',?) AS modified, ";
|
||||
$sql .= "fullname AS dav_displayname, FALSE AS is_calendar, TRUE AS is_principal, 0 AS collection_id ";
|
||||
$sql .= "FROM usr WHERE user_no = $user_no ";
|
||||
@ -700,13 +726,6 @@ function get_collection( $depth, $user_no, $collection_path ) {
|
||||
$responses[] = collection_to_xml( $collection );
|
||||
}
|
||||
|
||||
// Caldav Proxy: 5.1 par. 2: Add child resources calendar-proxy-(read|write)
|
||||
if (($collection->is_principal && isset($prop_list['DAV::resourcetype'])) ) { // atm, only users/resources/groups are principals, so it's ok to add these.
|
||||
// this is added when /<principal>/ is queried for resourcetype
|
||||
dbg_error_log("PROPFIND","Adding calendar-proxy-read and write. Path: %s", $collection->dav_name);
|
||||
add_proxy_response($responses, "read", $collection->dav_name);
|
||||
add_proxy_response($responses, "write", $collection->dav_name);
|
||||
}
|
||||
}
|
||||
elseif ( $c->collections_always_exist && preg_match( "#^/$session->username/#", $collection_path) ) {
|
||||
dbg_error_log("PROPFIND","Using $c->collections_always_exist setting is deprecated" );
|
||||
@ -763,7 +782,19 @@ $request->UnsupportedRequest($unsupported); // Won't return if there was unsuppo
|
||||
*/
|
||||
$url = ConstructURL( $request->path );
|
||||
$url = preg_replace( '#/$#', '', $url);
|
||||
if ( $request->IsCollection() ) {
|
||||
$responses = array();
|
||||
if ( $request->IsPrincipal() ) {
|
||||
$responses[] = $request->principal->RenderAsXML(array_merge($prop_list,$arbitrary), &$reply);
|
||||
if ( $request->depth > 0 ) {
|
||||
$collection = (object) array( 'dav_name' => '/'.$request->username.'/', 'is_calendar' => 'f', 'is_principal' => 't' );
|
||||
$responses = array_merge($responses, get_collection_contents( $request->depth - 1, $request->user_no, $collection ) );
|
||||
}
|
||||
}
|
||||
if ( $request->IsProxyRequest() ) {
|
||||
add_proxy_response($responses, $request->proxy_type, '/' . $request->principal->username . '/' );
|
||||
/** Nothing inside these, as yet. */
|
||||
}
|
||||
elseif ( $request->IsCollection() ) {
|
||||
$responses = get_collection( $request->depth, $request->user_no, $request->path );
|
||||
}
|
||||
elseif ( $request->AllowedTo('read') ) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user