mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-08-29 18:26:05 +00:00
Now handling LOCK + refresh LOCK on a calendar resource.
This commit is contained in:
parent
ecc3b2cb06
commit
7f13003a14
@ -10,7 +10,7 @@
|
||||
* @package rscds
|
||||
* @subpackage CalDAVRequest
|
||||
* @author Andrew McMillan <andrew@mcmillan.net.nz>
|
||||
* @copyright Andrew McMillan
|
||||
* @copyright Catalyst .Net Ltd
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2
|
||||
*/
|
||||
|
||||
@ -54,7 +54,9 @@ class CalDAVRequest
|
||||
* LOCK things use an "If" header to hold the lock in some cases, and "Lock-token" in others
|
||||
*/
|
||||
if ( isset($_SERVER['HTTP_IF']) ) $this->if_clause = $_SERVER['HTTP_IF'];
|
||||
if ( isset($_SERVER['HTTP_LOCK-TOKEN']) ) $this->lock_token = $_SERVER['HTTP_LOCK-TOKEN'];
|
||||
if ( isset($_SERVER['HTTP_LOCK_TOKEN']) && preg_match( '#[<]opaquelocktoken:(.*)[>]#', $_SERVER['HTTP_LOCK_TOKEN'], $matches ) ) {
|
||||
$this->lock_token = $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* LOCK things use a "Timeout" header to set a series of reducing alternative values
|
||||
@ -245,13 +247,22 @@ class CalDAVRequest
|
||||
function ValidateLockToken( $lock_token ) {
|
||||
if ( isset($this->lock_token) && $this->lock_token == $lock_token ) return true;
|
||||
if ( isset($this->if_clause) ) {
|
||||
dbg_error_log( "caldav", "Checking lock token '%s' against '%s'", $lock_token, $this->if_clause );
|
||||
$tokens = preg_split( '/[<>]/', $this->if_clause );
|
||||
foreach( $tokens AS $k => $v ) {
|
||||
dbg_error_log( "caldav", "Checking lock token '%s' against '%s'", $lock_token, $v );
|
||||
if ( 'opaquelocktoken:' == substr( $v, 0, 16 ) ) {
|
||||
if ( substr( $v, 16 ) == $lock_token ) return true;
|
||||
if ( substr( $v, 16 ) == $lock_token ) {
|
||||
dbg_error_log( "caldav", "Lock token '%s' validated OK against '%s'", $lock_token, $v );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@dbg_error_log( "caldav", "Invalid lock token '%s' - not in Lock-token (%s) or If headers (%s) ", $lock_token, $this->lock_token, $this->if_clause );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -364,6 +375,8 @@ class CalDAVRequest
|
||||
case 415: $status_text = "Unsupported Media Type"; break;
|
||||
case 416: $status_text = "Requested Range Not Satisfiable"; break;
|
||||
case 417: $status_text = "Expectation Failed"; break;
|
||||
case 423: $status_text = "Locked"; break;
|
||||
case 424: $status_text = "Failed Dependency"; break;
|
||||
case 500: $status_text = "Internal Server Error"; break;
|
||||
case 501: $status_text = "Not Implemented"; break;
|
||||
case 502: $status_text = "Bad Gateway"; break;
|
||||
|
||||
@ -93,28 +93,42 @@ function lock_resource( $user_no, $path ) {
|
||||
|
||||
dbg_error_log( "LOCK", "Attempting to lock resource '%s'", $path);
|
||||
if ( ($lock_token = $request->IsLocked()) ) { // NOTE Assignment in if() is expected here.
|
||||
dbg_error_log( "LOCK", "Attempting to renew resource lock on '%s'", $path);
|
||||
if ( $request->ValidateLockToken($lock_token) ) {
|
||||
$sql = "UPDATE locks SET start = current_timestamp WHERE opaquelocktoken = ?;";
|
||||
$qry = new PgQuery($sql, $lock_token );
|
||||
$qry->Exec("LOCK",__LINE__,__FILE__);
|
||||
}
|
||||
else {
|
||||
/** FIXME: Deny the lock */
|
||||
/**
|
||||
* Already locked - deny it
|
||||
*/
|
||||
$response = array(
|
||||
new XMLElement( 'href', $request->path ),
|
||||
new XMLElement( 'status', 'HTTP/1.1 423 Resource Locked')
|
||||
);
|
||||
$response = new XMLElement( "multistatus", new XMLElement( 'response', $response), array('xmlns'=>'DAV:') );
|
||||
$xmldoc = $response->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
|
||||
$request->DoResponse( 423, $xmldoc, 'text/xml; charset="utf-8"' );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* A fresh lock
|
||||
*/
|
||||
$lock_token = uuid();
|
||||
$sql = "INSERT INTO locks ( dav_name, opaquelocktoken, type, scope, depth, owner, timeout, start ) VALUES( ?, ?, ?, ?, ?, ?, ?::interval, current_timestamp );";
|
||||
$qry = new PgQuery($sql, $request->path, $lock_token, $lockinfo['type'], $lockinfo['scope'], $request->depth, $lockinfo['owner'], $request->timeout.' seconds' );
|
||||
$qry->Exec("LOCK",__LINE__,__FILE__);
|
||||
header( "Lock-Token: <opaquelocktoken:$lock_token>" );
|
||||
}
|
||||
|
||||
$lock_row = $request->GetLockRow($lock_token);
|
||||
$activelock = array(
|
||||
new XMLElement( 'locktype', new XMLElement( $lockinfo['type'] )),
|
||||
new XMLElement( 'lockscope', new XMLElement( $lockinfo['scope'] )),
|
||||
new XMLElement( 'locktype', new XMLElement( $lock_row->type )),
|
||||
new XMLElement( 'lockscope', new XMLElement( $lock_row->scope )),
|
||||
new XMLElement( 'depth', $request->GetDepthName() ),
|
||||
new XMLElement( 'owner', new XMLElement( 'href', $lockinfo['owner'] )),
|
||||
new XMLElement( 'owner', new XMLElement( 'href', $lock_row->owner )),
|
||||
new XMLElement( 'timeout', 'Second-'.$request->timeout),
|
||||
new XMLElement( 'locktoken', new XMLElement( 'href', 'opaquelocktoken:'.$lock_token ))
|
||||
);
|
||||
@ -153,7 +167,7 @@ else {
|
||||
}
|
||||
|
||||
$prop = new XMLElement( "prop", $response, array('xmlns'=>'DAV:') );
|
||||
dbg_log_array( "LOCK", "XML", $response, true );
|
||||
// dbg_log_array( "LOCK", "XML", $response, true );
|
||||
$xmldoc = $prop->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
|
||||
$request->DoResponse( 200, $xmldoc, 'text/xml; charset="utf-8"' );
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user