mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-04-25 15:10:13 +00:00
Removal of warnings, adding of permissions.
This commit is contained in:
parent
0a91dfdde6
commit
60ffd152aa
@ -6,10 +6,76 @@ require_once("BasicAuthSession.php");
|
||||
$raw_headers = apache_request_headers();
|
||||
$raw_post = file_get_contents ( 'php://input');
|
||||
|
||||
if ( $debugging && isset($_GET['method']) ) {
|
||||
if ( isset($debugging) && isset($_GET['method']) ) {
|
||||
$_SERVER['REQUEST_METHOD'] = $_GET['method'];
|
||||
}
|
||||
|
||||
/**
|
||||
* A variety of requests may set the "Depth" header to control recursion
|
||||
*/
|
||||
$query_depth = ( isset($_SERVER['HTTP_DEPTH']) ? $_SERVER['HTTP_DEPTH'] : 0 );
|
||||
if ( $query_depth == 'infinite' ) $query_depth = 99;
|
||||
$query_depth = intval($query_depth);
|
||||
|
||||
/**
|
||||
* Our path is /<script name>/<user name>/<user controlled> if it ends in
|
||||
* a trailing '/' then it is referring to a DAV 'collection' but otherwise
|
||||
* it is referring to a DAV data item.
|
||||
*
|
||||
* Permissions are controlled as follows:
|
||||
* 1. if there is no <user name> component, the request has read privileges
|
||||
* 2. if the requester is an admin, the request has read/write priviliges
|
||||
* 3. if there is a <user name> component which matches the logged on user
|
||||
* then the request has read/write privileges
|
||||
* 4. otherwise we query the defined relationships between users and use
|
||||
* the maximum privileges returned from that analysis.
|
||||
*/
|
||||
$request_path = $_SERVER['PATH_INFO'];
|
||||
$path_split = preg_split('#/+#', $request_path );
|
||||
$permissions = array();
|
||||
if ( !isset($path_split[1]) || $path_split[1] == '' ) {
|
||||
dbg_error_log( "caldav", "No useful path split possible" );
|
||||
unset($path_user_no);
|
||||
unset($path_username);
|
||||
$permissions = array("read" => 1 );
|
||||
}
|
||||
else {
|
||||
$path_username = $path_split[1];
|
||||
@dbg_error_log( "caldav", "Path split into at least /// %s /// %s /// %s", $path_split[1], $path_split[2], $path_split[3] );
|
||||
$qry = new PgQuery( "SELECT * FROM usr WHERE username = ?;", $path_username );
|
||||
if ( $qry->Exec("caldav") && $path_user_record = $qry->Fetch() ) {
|
||||
$path_user_no = $path_user_record->user_no;
|
||||
}
|
||||
if ( $session->AllowedTo("Admin") || $session->user_no == $path_user_no ) {
|
||||
$permissions = array('read' => 1, "write" => 1 );
|
||||
}
|
||||
else if ( isset($path_user_no) ) {
|
||||
/**
|
||||
* We need to query the database for permissions
|
||||
*/
|
||||
$qry = new PgQuery( "SELECT get_permissions( ?, ? ) AS perm;", $session->user_no, $path_user_no);
|
||||
if ( $qry->Exec("caldav") && $permission_result = $qry->Fetch() ) {
|
||||
$permission_result = "!".$permission_result->perm; // We prepend something to ensure we get a non-zero position.
|
||||
$permissions = array();
|
||||
if ( strpos($permission_result,"R") ) $permissions['read'] = 1;
|
||||
if ( strpos($permission_result,"W") ) $permissions['write'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the content we are receiving is XML then we parse it here.
|
||||
*/
|
||||
$xml_parser = xml_parser_create_ns('UTF-8');
|
||||
$xml_tags = array();
|
||||
xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
xml_parse_into_struct( $xml_parser, $raw_post, $xml_tags );
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
|
||||
/**
|
||||
* We put the code for each type of request into a separate include file
|
||||
*/
|
||||
switch ( $_SERVER['REQUEST_METHOD'] ) {
|
||||
case 'OPTIONS': include_once("caldav-OPTIONS.php"); break;
|
||||
case 'REPORT': include_once("caldav-REPORT.php"); break;
|
||||
|
||||
@ -5,7 +5,9 @@ dbg_error_log("get", "GET method handler");
|
||||
// The GET method is not sent with any wrapping XML so we simply fetch it
|
||||
|
||||
$get_path = $_SERVER['PATH_INFO'];
|
||||
$etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
if ( isset($_SERVER["HTTP_IF_NONE_MATCH"]) ) {
|
||||
$etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
}
|
||||
|
||||
$qry = new PgQuery( "SELECT * FROM caldav_data WHERE user_no = ? AND dav_name = ? ;", $session->user_no, $get_path);
|
||||
dbg_error_log("get", "%s", $qry->querystring );
|
||||
|
||||
@ -1,58 +1,26 @@
|
||||
<?php
|
||||
|
||||
dbg_error_log("PROPFIND", "method handler");
|
||||
|
||||
$attributes = array();
|
||||
$parser = xml_parser_create_ns('UTF-8');
|
||||
xml_parser_set_option ( $parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
require_once("XMLElement.php");
|
||||
require_once("iCalendar.php");
|
||||
|
||||
function xml_start_callback( $parser, $el_name, $el_attrs ) {
|
||||
// dbg_error_log( "PROPFIND", "Parsing $el_name" );
|
||||
// dbg_log_array( "PROPFIND", "$el_name::attrs", $el_attrs, true );
|
||||
$attributes[$el_name] = $el_attrs;
|
||||
}
|
||||
|
||||
function xml_end_callback( $parser, $el_name ) {
|
||||
// dbg_error_log( "PROPFIND", "Finished Parsing $el_name" );
|
||||
}
|
||||
|
||||
xml_set_element_handler ( $parser, 'xml_start_callback', 'xml_end_callback' );
|
||||
|
||||
$rpt_request = array();
|
||||
xml_parse_into_struct( $parser, $raw_post, $rpt_request );
|
||||
xml_parser_free($parser);
|
||||
|
||||
$find_path = $_SERVER['PATH_INFO'];
|
||||
list( $blank, $username, $calpath ) = split( '/', $find_path, 3);
|
||||
$calpath = "/".$calpath;
|
||||
$href_list = array();
|
||||
$attribute_list = array();
|
||||
$depth = $_SERVER['HTTP_DEPTH'];
|
||||
if ( $depth == 'infinite' ) $depth = 99;
|
||||
else $depth = intval($depth);
|
||||
|
||||
// dbg_log_array("PROPFIND","_SERVER", $_SERVER, true );
|
||||
|
||||
if ( isset($debugging) ) {
|
||||
$attribute_list = array( 'GETETAG' => 1, 'GETCONTENTLENGTH' => 1, 'GETCONTENTTYPE' => 1, 'RESOURCETYPE' => 1 );
|
||||
$depth = 1;
|
||||
}
|
||||
|
||||
$unsupported = array();
|
||||
foreach( $rpt_request AS $k => $v ) {
|
||||
|
||||
foreach( $xml_tags AS $k => $v ) {
|
||||
|
||||
$tag = $v['tag'];
|
||||
switch ( $tag ) {
|
||||
case 'DAV::PROPFIND':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $tag );
|
||||
// dbg_log_array( "PROPFIND", "DAV-PROPFIND", $v, true );
|
||||
break;
|
||||
|
||||
case 'DAV::PROP':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $tag );
|
||||
// dbg_log_array( "PROPFIND", "DAV::PROP", $v, true );
|
||||
break;
|
||||
|
||||
case 'HTTP://APACHE.ORG/DAV/PROPS/:EXECUTABLE':
|
||||
case 'DAV::CHECKED-OUT':
|
||||
case 'DAV::CHECKED-IN':
|
||||
case 'DAV::GETLASTMODIFIED':
|
||||
case 'DAV::GETETAG':
|
||||
case 'DAV::DISPLAYNAME':
|
||||
case 'DAV::GETCONTENTLENGTH':
|
||||
@ -80,8 +48,6 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
}
|
||||
|
||||
|
||||
require_once("XMLElement.php");
|
||||
|
||||
/**
|
||||
* Returns the array of privilege names converted into XMLElements
|
||||
*/
|
||||
@ -106,12 +72,15 @@ function collection_to_xml( $collection ) {
|
||||
$contentlength = false;
|
||||
if ( $collection->is_calendar == 't' ) {
|
||||
$resourcetypes[] = new XMLElement("calendar", false, array("xmlns" => "urn:ietf:params:xml:ns:caldav"));
|
||||
$lqry = new PgQuery("SELECT sum(length(caldav_data)) FROM caldav_data WHERE user_no = ? AND dav_name ~ ?;", $user_no, $collection_path.'[^/]+$' );
|
||||
if ( $lqry->Exec("PROPFIND",__LINE,__FILE__) && $row = $lqry->Fetch() ) {
|
||||
$lqry = new PgQuery("SELECT sum(length(caldav_data)) FROM caldav_data WHERE user_no = ? AND dav_name ~ ?;", $collection->user_no, $collection->dav_name.'[^/]+$' );
|
||||
if ( $lqry->Exec("PROPFIND",__LINE__,__FILE__) && $row = $lqry->Fetch() ) {
|
||||
$contentlength = $row->sum;
|
||||
}
|
||||
}
|
||||
$prop = new XMLElement("prop");
|
||||
if ( isset($attribute_list['GETLASTMODIFIED']) ) {
|
||||
$prop->NewElement("getlastmodified", ( isset($collection->modified)? $collection->modified : false ));
|
||||
}
|
||||
if ( isset($attribute_list['GETCONTENTLENGTH']) ) {
|
||||
$prop->NewElement("getcontentlength", $contentlength );
|
||||
}
|
||||
@ -130,19 +99,7 @@ function collection_to_xml( $collection ) {
|
||||
$prop->NewElement("getetag", '"'.$collection->dav_etag.'"' );
|
||||
}
|
||||
if ( isset($attribute_list['CURRENT-USER-PRIVILEGE-SET']) ) {
|
||||
/**
|
||||
* FIXME: Fairly basic set of privileges at present.
|
||||
*/
|
||||
if ( $session->AllowedTo("Admin") && preg_match("#/.+/#", $collection->dav_name) ) {
|
||||
$privs = array("all");
|
||||
}
|
||||
else {
|
||||
$privs = array("read");
|
||||
if ( $session->user_no == $collection->user_no || $session->AllowedTo("Admin") ) {
|
||||
$privs[] = "write";
|
||||
}
|
||||
}
|
||||
$prop->NewElement("current-user-privilege-set", privileges($privs) );
|
||||
$prop->NewElement("current-user-privilege-set", privileges($GLOBALS['permissions']) );
|
||||
}
|
||||
$status = new XMLElement("status", "HTTP/1.1 200 OK" );
|
||||
|
||||
@ -165,6 +122,9 @@ function item_to_xml( $item ) {
|
||||
|
||||
$url = $_SERVER['SCRIPT_NAME'] . $item->dav_name;
|
||||
$prop = new XMLElement("prop");
|
||||
if ( isset($attribute_list['GETLASTMODIFIED']) ) {
|
||||
$prop->NewElement("getlastmodified", ( isset($item->modified)? $item->modified : false ));
|
||||
}
|
||||
if ( isset($attribute_list['GETCONTENTLENGTH']) ) {
|
||||
$contentlength = strlen($item->caldav_data);
|
||||
$prop->NewElement("getcontentlength", $contentlength );
|
||||
@ -182,19 +142,7 @@ function item_to_xml( $item ) {
|
||||
$prop->NewElement("getetag", '"'.$item->dav_etag.'"' );
|
||||
}
|
||||
if ( isset($attribute_list['CURRENT-USER-PRIVILEGE-SET']) ) {
|
||||
/**
|
||||
* FIXME: Fairly basic set of privileges at present.
|
||||
*/
|
||||
if ( $session->AllowedTo("Admin") && preg_match("#/.+/.#", $item->dav_name) ) {
|
||||
$privs = array("all");
|
||||
}
|
||||
else {
|
||||
$privs = array("read");
|
||||
if ( $session->user_no == $item->user_no || $session->AllowedTo("Admin") ) {
|
||||
$privs[] = "write";
|
||||
}
|
||||
}
|
||||
$prop->NewElement("current-user-privilege-set", privileges($privs) );
|
||||
$prop->NewElement("current-user-privilege-set", privileges($GLOBALS['permissions']) );
|
||||
}
|
||||
$status = new XMLElement("status", "HTTP/1.1 200 OK" );
|
||||
|
||||
@ -213,40 +161,40 @@ function item_to_xml( $item ) {
|
||||
*
|
||||
* Permissions here might well be handled through an SQL function.
|
||||
*/
|
||||
function get_collection_contents( $depth, $user_no, $collection_path ) {
|
||||
function get_collection_contents( $depth, $user_no, $collection ) {
|
||||
global $session;
|
||||
|
||||
dbg_error_log("PROPFIND","Getting collection contents: Depth %d, User: %d, Path: %s, IsCalendar: %s", $depth, $user_no, $collection_path, $collection->is_calendar );
|
||||
dbg_error_log("PROPFIND","Getting collection contents: Depth %d, User: %d, Path: %s", $depth, $user_no, $collection->dav_name );
|
||||
|
||||
$responses = array();
|
||||
if ( $collection->is_calendar != 't' ) {
|
||||
/**
|
||||
* Calendar collections may not contain calendar collections.
|
||||
*/
|
||||
if ( $collection_path == '/' ) {
|
||||
$sql .= "SELECT user_no, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql .= "updated AS created, updated AS modified, fullname AS dav_displayname, FALSE AS is_calendar FROM usr";
|
||||
if ( $collection->dav_name == '/' ) {
|
||||
$sql = "SELECT user_no, user_no, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql .= "updated AS created, to_char(updated at time zone 'GMT',?) AS modified, fullname AS dav_displayname, FALSE AS is_calendar FROM usr";
|
||||
}
|
||||
else {
|
||||
$sql = "SELECT dav_name, dav_etag, created, modified, dav_displayname, is_calendar FROM collection WHERE parent_container=".qpg($collection_path);
|
||||
$sql = "SELECT user_no, dav_name, dav_etag, created, to_char(modified at time zone 'GMT',?), dav_displayname, is_calendar FROM collection WHERE parent_container=".qpg($collection->dav_name);
|
||||
}
|
||||
$qry = new PgQuery($sql);
|
||||
$qry = new PgQuery($sql, PgQuery::Plain(iCalendar::HttpDateFormat()));
|
||||
|
||||
if( $qry->Exec("PROPFIND",__LINE,__FILE__) && $qry->rows > 0 ) {
|
||||
while( $collection = $qry->Fetch() ) {
|
||||
$responses[] = collection_to_xml( $collection );
|
||||
if( $qry->Exec("PROPFIND",__LINE__,__FILE__) && $qry->rows > 0 ) {
|
||||
while( $subcollection = $qry->Fetch() ) {
|
||||
$responses[] = collection_to_xml( $subcollection );
|
||||
if ( $depth > 0 ) {
|
||||
$responses = array_merge( $responses, get_collection( $depth - 1, $user_no, $collection->dav_name ) );
|
||||
$responses = array_merge( $responses, get_collection( $depth - 1, $user_no, $subcollection->dav_name ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbg_error_log("PROPFIND","Getting collection items: Depth %d, User: %d, Path: %s", $depth, $user_no, $collection_path );
|
||||
dbg_error_log("PROPFIND","Getting collection items: Depth %d, User: %d, Path: %s", $depth, $user_no, $collection->dav_name );
|
||||
|
||||
$sql = "SELECT dav_name, caldav_data, dav_etag, created, modified FROM caldav_data WHERE dav_name ~ ".qpg('^'.$collection_path.'[^/]+$');
|
||||
$qry = new PgQuery($sql);
|
||||
if( $qry->Exec("PROPFIND",__LINE,__FILE__) && $qry->rows > 0 ) {
|
||||
$sql = "SELECT dav_name, caldav_data, dav_etag, created, to_char(modified at time zone 'GMT',?) FROM caldav_data WHERE dav_name ~ ".qpg('^'.$collection->dav_name.'[^/]+$');
|
||||
$qry = new PgQuery($sql, PgQuery::Plain(iCalendar::HttpDateFormat()));
|
||||
if( $qry->Exec("PROPFIND",__LINE__,__FILE__) && $qry->rows > 0 ) {
|
||||
while( $item = $qry->Fetch() ) {
|
||||
$responses[] = item_to_xml( $item );
|
||||
}
|
||||
@ -276,14 +224,14 @@ function get_collection( $depth, $user_no, $collection_path ) {
|
||||
else {
|
||||
$user_no = intval($user_no);
|
||||
if ( preg_match( '#^/[^/]+/$#', $collection_path) ) {
|
||||
$sql .= "SELECT user_no, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql = "SELECT user_no, '/' || username || '/' AS dav_name, md5( '/' || username || '/') AS dav_etag, ";
|
||||
$sql .= "updated AS created, fullname AS dav_displayname, FALSE AS is_calendar FROM usr WHERE user_no = $user_no ; ";
|
||||
}
|
||||
else {
|
||||
$sql = "SELECT dav_name, dav_etag, created, dav_displayname, is_calendar FROM collection WHERE user_no = $user_no AND dav_name = ".qpg($collection_path);
|
||||
$sql = "SELECT user_no, dav_name, dav_etag, created, dav_displayname, is_calendar FROM collection WHERE user_no = $user_no AND dav_name = ".qpg($collection_path);
|
||||
}
|
||||
$qry = new PgQuery($sql );
|
||||
if( $qry->Exec("PROPFIND",__LINE,__FILE__) && $qry->rows > 0 && $collection = $qry->Fetch() ) {
|
||||
if( $qry->Exec("PROPFIND",__LINE__,__FILE__) && $qry->rows > 0 && $collection = $qry->Fetch() ) {
|
||||
$responses[] = collection_to_xml( $collection );
|
||||
}
|
||||
elseif ( $c->collections_always_exist ) {
|
||||
@ -295,8 +243,8 @@ function get_collection( $depth, $user_no, $collection_path ) {
|
||||
$responses[] = collection_to_xml( $collection );
|
||||
}
|
||||
}
|
||||
if ( $depth > 0 ) {
|
||||
$responses = array_merge($responses, get_collection_contents( $depth-1, $user_no, $collection_path ) );
|
||||
if ( $depth > 0 && isset($collection) ) {
|
||||
$responses = array_merge($responses, get_collection_contents( $depth-1, $user_no, $collection ) );
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
@ -314,7 +262,7 @@ if ( count($unsupported) > 0 ) {
|
||||
$badprops = new XMLElement( "prop" );
|
||||
foreach( $unsupported AS $k => $v ) {
|
||||
// Not supported at this point...
|
||||
dbg_error_log("ERROR", " PROPFIND: Support for $v::$k properties is not implemented yet");
|
||||
dbg_error_log("ERROR", " PROPFIND: Support for $v:$k properties is not implemented yet");
|
||||
$badprops->NewElement(strtolower($k),false,array("xmlns" => strtolower($v)));
|
||||
}
|
||||
$error = new XMLElement("error", new XMLElement( "propfind",$badprops), array("xmlns" => "DAV:") );
|
||||
@ -323,19 +271,26 @@ if ( count($unsupported) > 0 ) {
|
||||
echo $error->Render(0,'<?xml version="1.0" ?>');
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
elseif ( isset($permissions['read']) || isset($permissions['write']) ) {
|
||||
|
||||
/**
|
||||
* Something that we can handle, at least roughly correctly.
|
||||
*/
|
||||
$url = sprintf("http://%s:%d%s%s", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $find_path );
|
||||
$url = $_SERVER['SCRIPT_NAME'] . $find_path ;
|
||||
$url = sprintf("http://%s:%d%s%s", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $request_path );
|
||||
$url = $_SERVER['SCRIPT_NAME'] . $request_path ;
|
||||
$url = preg_replace( '#/$#', '', $url);
|
||||
|
||||
$responses = get_collection( $depth, $session->user_no, $find_path );
|
||||
$responses = get_collection( $query_depth, (isset($path_user_no) ? $path_user_no : $session->user_no), $request_path );
|
||||
|
||||
$multistatus = new XMLElement( "multistatus", $responses, array('xmlns'=>'DAV:') );
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.1 403 Forbidden');
|
||||
header('Content-Type: text/plain');
|
||||
echo "You do not have appropriate rights to view that resource\n";
|
||||
dbg_log_array("caldav","PERMISSIONS", $permissions, true );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// dbg_log_array( "PROPFIND", "XML", $multistatus, true );
|
||||
$xmldoc = $multistatus->Render();
|
||||
|
||||
@ -10,43 +10,39 @@ fwrite($fh,$raw_post);
|
||||
fclose($fh);
|
||||
|
||||
$etag = md5($raw_post);
|
||||
$put_path = $_SERVER['PATH_INFO'];
|
||||
$etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
$etag_match = str_replace('"','',$_SERVER["HTTP_IF_MATCH"]);
|
||||
if ( isset($_SERVER["HTTP_IF_MATCH"]) ) $etag_match = str_replace('"','',$_SERVER["HTTP_IF_MATCH"]);
|
||||
if ( isset($_SERVER["HTTP_IF_NONE_MATCH"]) ) $etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
|
||||
dbg_log_array( "PUT", 'HEADERS', $raw_headers );
|
||||
dbg_log_array( "PUT", '_SERVER', $_SERVER, true );
|
||||
include_once("iCalendar.php");
|
||||
$ic = new iCalendar(array( 'icalendar' => $raw_post ));
|
||||
|
||||
include_once("vEvent.php");
|
||||
$ev = new vEvent(array( 'vevent' => $raw_post ));
|
||||
|
||||
dbg_log_array( "PUT", 'EVENT', $ev, true );
|
||||
dbg_log_array( "PUT", 'EVENT', $ic->properties['VCALENDAR'][0], true );
|
||||
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
if ( !isset($etag_match) || $etag_match == '*' || $etag_match == '' ) {
|
||||
/**
|
||||
* If they didn't send an etag_match header, we need to check if the PUT object already exists
|
||||
* and we are hence updating it. And we just set our etag_match to that.
|
||||
*/
|
||||
$qry = new PgQuery( "SELECT * FROM caldav_data WHERE user_no=? AND dav_name=?", $session->user_no, $put_path );
|
||||
$qry = new PgQuery( "SELECT * FROM caldav_data WHERE user_no=? AND dav_name=?", $session->user_no, $request_path );
|
||||
$qry->Exec("PUT");
|
||||
if ( $qry->rows > 1 ) {
|
||||
header("HTTP/1.1 500 Infernal Server Error");
|
||||
dbg_error_log("ERROR","Multiple events match replaced path for user %d, path %s", $session->user_no, $put_path );
|
||||
dbg_error_log("ERROR","Multiple events match replaced path for user %d, path %s", $session->user_no, $request_path );
|
||||
exit(0);
|
||||
}
|
||||
elseif ( $qry->rows == 1 ) {
|
||||
$event = $qry->Fetch();
|
||||
$etag_match = $event->dav_etag;
|
||||
$icalendar = $qry->Fetch();
|
||||
$etag_match = $icalendar->dav_etag;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
if ( !isset($etag_match) || $etag_match == '*' || $etag_match == '' ) {
|
||||
/**
|
||||
* If we got this far without an etag we must be inserting it.
|
||||
*/
|
||||
$qry = new PgQuery( "INSERT INTO caldav_data ( user_no, dav_name, dav_etag, caldav_data, caldav_type, logged_user, created, modified ) VALUES( ?, ?, ?, ?, ?, ?, current_timestamp, current_timestamp )",
|
||||
$session->user_no, $put_path, $etag, $raw_post, $ev->type, $session->user_no );
|
||||
$session->user_no, $request_path, $etag, $raw_post, $ic->type, $session->user_no );
|
||||
$qry->Exec("PUT");
|
||||
|
||||
header("HTTP/1.1 201 Created");
|
||||
@ -54,41 +50,43 @@ if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
}
|
||||
else {
|
||||
$qry = new PgQuery( "UPDATE caldav_data SET caldav_data=?, dav_etag=?, caldav_type=?, logged_user=?, modified=current_timestamp WHERE user_no=? AND dav_name=? AND dav_etag=?",
|
||||
$raw_post, $etag, $ev->type, $session->user_no, $session->user_no, $put_path, $etag_match );
|
||||
$raw_post, $etag, $ic->type, $session->user_no, $session->user_no, $request_path, $etag_match );
|
||||
$qry->Exec("PUT");
|
||||
|
||||
header("HTTP/1.1 201 Replaced");
|
||||
header("ETag: $etag");
|
||||
}
|
||||
|
||||
$sql = ( $ev->tz_locn == '' ? '' : "SET TIMEZONE TO ".qpg($ev->tz_locn).";" );
|
||||
$sql = ( $ic->tz_locn == '' ? '' : "SET TIMEZONE TO ".qpg($ic->tz_locn).";" );
|
||||
|
||||
$dtstart = $ev->Get('dtstart');
|
||||
if ( (!isset($dtstart) || $dtstart == "") && $ev->Get('due') != "" ) {
|
||||
$dtstart = $ev->Get('due');
|
||||
$dtstart = $ic->Get('dtstart');
|
||||
if ( (!isset($dtstart) || $dtstart == "") && $ic->Get('due') != "" ) {
|
||||
$dtstart = $ic->Get('due');
|
||||
}
|
||||
$dtend = $ev->Get('dtend');
|
||||
if ( (!isset($dtend) || "$dtend" == "") && $ev->Get('duration') != "" AND $dtstart != "" ) {
|
||||
$duration = preg_replace( '#[PT]#', ' ', $ev->Get('duration') );
|
||||
$dtend = $ic->Get('dtend');
|
||||
if ( (!isset($dtend) || "$dtend" == "") && $ic->Get('duration') != "" AND $dtstart != "" ) {
|
||||
$duration = preg_replace( '#[PT]#', ' ', $ic->Get('duration') );
|
||||
$dtend = '('.qpg($dtstart).'::timestamp with time zone + '.qpg($duration).'::interval)';
|
||||
}
|
||||
else {
|
||||
dbg_error_log( "PUT", " DTEND: '%s', DTSTART: '%s', DURATION: '%s'", $dtend, $dtstart, $ev->Get('duration') );
|
||||
dbg_error_log( "PUT", " DTEND: '%s', DTSTART: '%s', DURATION: '%s'", $dtend, $dtstart, $ic->Get('duration') );
|
||||
$dtend = qpg($dtend);
|
||||
}
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
|
||||
|
||||
if ( !isset($etag_match) || $etag_match == '*' || $etag_match == '' ) {
|
||||
$sql .= <<<EOSQL
|
||||
INSERT INTO calendar_item (user_no, dav_name, dav_etag, uid, dtstamp, dtstart, dtend, summary, location, class, transp,
|
||||
description, rrule, tz_id, last_modified, url, priority, created, due, percent_complete )
|
||||
VALUES ( ?, ?, ?, ?, ?, ?, $dtend, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
EOSQL;
|
||||
|
||||
$qry = new PgQuery( $sql, $session->user_no, $put_path, $etag, $ev->Get('uid'), $ev->Get('dtstamp'),
|
||||
$ev->Get('dtstart'), $ev->Get('summary'), $ev->Get('location'),
|
||||
$ev->Get('class'), $ev->Get('transp'), $ev->Get('description'), $ev->Get('rrule'), $ev->Get('tz_id'),
|
||||
$ev->Get('last-modified'), $ev->Get('url'), $ev->Get('priority'), $ev->Get('created'),
|
||||
$ev->Get('due'), $ev->Get('percent-complete')
|
||||
$qry = new PgQuery( $sql, $session->user_no, $request_path, $etag, $ic->Get('uid'), $ic->Get('dtstamp'),
|
||||
$ic->Get('dtstart'), $ic->Get('summary'), $ic->Get('location'),
|
||||
$ic->Get('class'), $ic->Get('transp'), $ic->Get('description'), $ic->Get('rrule'), $ic->Get('tz_id'),
|
||||
$ic->Get('last-modified'), $ic->Get('url'), $ic->Get('priority'), $ic->Get('created'),
|
||||
$ic->Get('due'), $ic->Get('percent-complete')
|
||||
);
|
||||
$qry->Exec("PUT");
|
||||
}
|
||||
@ -99,14 +97,14 @@ UPDATE calendar_item SET uid=?, dtstamp=?, dtstart=?, dtend=$dtend, summary=?, l
|
||||
WHERE user_no=? AND dav_name=?
|
||||
EOSQL;
|
||||
|
||||
$qry = new PgQuery( $sql, $ev->Get('uid'), $ev->Get('dtstamp'), $ev->Get('dtstart'), $ev->Get('summary'),
|
||||
$ev->Get('location'), $ev->Get('class'), $ev->Get('transp'), $ev->Get('description'), $ev->Get('rrule'),
|
||||
$ev->Get('tz_id'), $ev->Get('last-modified'), $ev->Get('url'), $ev->Get('priority'), $etag,
|
||||
$ev->Get('due'), $ev->Get('percent-complete'),
|
||||
$session->user_no, $put_path );
|
||||
$qry = new PgQuery( $sql, $ic->Get('uid'), $ic->Get('dtstamp'), $ic->Get('dtstart'), $ic->Get('summary'),
|
||||
$ic->Get('location'), $ic->Get('class'), $ic->Get('transp'), $ic->Get('description'), $ic->Get('rrule'),
|
||||
$ic->Get('tz_id'), $ic->Get('last-modified'), $ic->Get('url'), $ic->Get('priority'), $etag,
|
||||
$ic->Get('due'), $ic->Get('percent-complete'),
|
||||
$session->user_no, $request_path );
|
||||
$qry->Exec("PUT");
|
||||
}
|
||||
|
||||
dbg_error_log( "PUT", "User: %d, ETag: %s, Path: %s", $session->user_no, $etag, $put_path);
|
||||
dbg_error_log( "PUT", "User: %d, ETag: %s, Path: %s", $session->user_no, $etag, $request_path);
|
||||
|
||||
?>
|
||||
@ -2,31 +2,11 @@
|
||||
|
||||
dbg_error_log("REPORT", "method handler");
|
||||
|
||||
$attributes = array();
|
||||
$parser = xml_parser_create_ns('UTF-8');
|
||||
xml_parser_set_option ( $parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
|
||||
function xml_start_callback( $parser, $el_name, $el_attrs ) {
|
||||
// dbg_error_log( "REPORT", "Parsing $el_name" );
|
||||
// dbg_log_array( "REPORT", "$el_name::attrs", $el_attrs, true );
|
||||
$attributes[$el_name] = $el_attrs;
|
||||
}
|
||||
|
||||
function xml_end_callback( $parser, $el_name ) {
|
||||
// dbg_error_log( "REPORT", "Finished Parsing $el_name" );
|
||||
}
|
||||
|
||||
xml_set_element_handler ( $parser, 'xml_start_callback', 'xml_end_callback' );
|
||||
|
||||
$rpt_request = array();
|
||||
xml_parse_into_struct( $parser, $raw_post, $rpt_request );
|
||||
xml_parser_free($parser);
|
||||
|
||||
require_once("XMLElement.php");
|
||||
|
||||
$reportnum = -1;
|
||||
$report = array();
|
||||
foreach( $rpt_request AS $k => $v ) {
|
||||
foreach( $xml_tags AS $k => $v ) {
|
||||
|
||||
$fulltag = $v['tag'];
|
||||
if ( preg_match('/^(.*):([^:]+)$/', $fulltag, $matches) ) {
|
||||
@ -41,7 +21,7 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
switch ( $fulltag ) {
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
dbg_error_log( "REPORT", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
if ( $v['type'] == "open" ) {
|
||||
$reportnum++;
|
||||
$report[$reportnum]['type'] = $xmltag;
|
||||
@ -54,7 +34,7 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-MULTIGET':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
dbg_error_log( "REPORT", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
$report[$reportnum]['multiget'] = 1;
|
||||
if ( $v['type'] == "open" ) {
|
||||
$reportnum++;
|
||||
@ -68,7 +48,7 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:FILTER':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
dbg_error_log( "REPORT", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
if ( $v['type'] == "open" ) {
|
||||
$filters = array();
|
||||
}
|
||||
@ -80,7 +60,7 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:IS-DEFINED':
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER':
|
||||
dbg_error_log( "PROPFIND", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
dbg_error_log( "REPORT", ":Request: %s -> %s", $v['type'], $xmltag );
|
||||
if ( $v['type'] == "close" ) {
|
||||
break;
|
||||
}
|
||||
@ -172,7 +152,7 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
function calendar_to_xml( $properties, $item ) {
|
||||
global $session, $c;
|
||||
|
||||
dbg_error_log("PROPFIND","Building XML Response for item '%s'", $item->dav_name );
|
||||
dbg_error_log("REPORT","Building XML Response for item '%s'", $item->dav_name );
|
||||
|
||||
$url = sprintf( "%s://%s:%d%s%s", 'http', $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $item->dav_name );
|
||||
$prop = new XMLElement("prop");
|
||||
@ -222,7 +202,7 @@ function calendar_to_xml( $properties, $item ) {
|
||||
|
||||
|
||||
|
||||
if ( count($unsupported) > 0 ) {
|
||||
if ( isset($unsupported) && count($unsupported) > 0 ) {
|
||||
|
||||
/**
|
||||
* That's a *BAD* request!
|
||||
@ -251,8 +231,8 @@ else {
|
||||
$responses = array();
|
||||
|
||||
for ( $i=0; $i <= $reportnum; $i++ ) {
|
||||
dbg_error_log("REPORT", "Report[%d] Start:%s, End: %s, Events: %d, Todos: %d, Freebusy: %d",
|
||||
$i, $report[$i]['start'], $report[$i]['end'], $report[$i]['filters']['VEVENT'], $report[$i]['filters']['VTODO'], $report[$i]['filters']['VFREEBUSY']);
|
||||
// dbg_error_log("REPORT", "Report[%d] Start:%s, End: %s, Events: %d, Todos: %d, Freebusy: %d",
|
||||
// $i, $report[$i]['start'], $report[$i]['end'], $report[$i]['filters']['VEVENT'], $report[$i]['filters']['VTODO'], $report[$i]['filters']['VFREEBUSY']);
|
||||
|
||||
$where = "";
|
||||
switch( $report[$i]['type'] ) {
|
||||
@ -301,7 +281,7 @@ else {
|
||||
$qry = new PgQuery( "SELECT * FROM caldav_data INNER JOIN calendar_item USING(user_no, dav_name)". $where );
|
||||
if ( $qry->Exec("REPORT",__LINE__,__FILE__) && $qry->rows > 0 ) {
|
||||
while( $calendar_object = $qry->Fetch() ) {
|
||||
$responses[] = calendar_to_xml($report[$i]['properties'], $calendar_object );
|
||||
$responses[] = calendar_to_xml( $report[$i]['properties'], $calendar_object );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user