From 1c9c77e412f6c467c7890a8fc5282ff0b8c2eedc Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Fri, 12 Mar 2010 11:29:27 +1300 Subject: [PATCH] Add initial support for BIND method. --- dba/davical.sql | 6 ++-- dba/patches/1.2.8.sql | 6 ++-- inc/caldav-BIND.php | 78 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 inc/caldav-BIND.php diff --git a/dba/davical.sql b/dba/davical.sql index 501f46d0..7afc3acb 100644 --- a/dba/davical.sql +++ b/dba/davical.sql @@ -317,9 +317,9 @@ CREATE TABLE access_ticket ( -- At this point we only support binding collections CREATE TABLE dav_binding ( bind_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY, - target_collection_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, - target_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL, - parent_container TEXT NOT NULL, + bound_source_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, + access_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL, + parent_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, dav_name TEXT UNIQUE NOT NULL, dav_displayname TEXT ); diff --git a/dba/patches/1.2.8.sql b/dba/patches/1.2.8.sql index d10c3a10..0d5f59f8 100644 --- a/dba/patches/1.2.8.sql +++ b/dba/patches/1.2.8.sql @@ -22,9 +22,9 @@ CREATE TABLE access_ticket ( -- At this point we only support binding collections CREATE TABLE dav_binding ( bind_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY, - target_collection_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, - target_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL, - parent_container TEXT NOT NULL, + bound_source_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, + access_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL, + parent_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, dav_name TEXT UNIQUE NOT NULL, dav_displayname TEXT ); diff --git a/inc/caldav-BIND.php b/inc/caldav-BIND.php new file mode 100644 index 00000000..1aa59b5c --- /dev/null +++ b/inc/caldav-BIND.php @@ -0,0 +1,78 @@ + +* @copyright Morphoss Ltd - http://www.morphoss.com/ +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later +*/ +dbg_error_log('BIND', 'method handler'); +require_once('AwlQuery.php'); + +$request->NeedPrivilege('DAV::bind'); + +if ( ! $request->IsCollection() || ! $request->Exists() ) { + $request->PreconditionFailed(403,'DAV::bind-into-collection',translate('The BIND Request-URI MUST identify a collection.')); +} + +require_once('DAVResource.php'); +$parent = new DAVResource( $parent_container ); +if ( $parent->IsSchedulingCollection() ) { + $request->PreconditionFailed(403, 'DAV::method-not-allowed',translate('The BIND method is not allowed at that location.') ); +} + +require_once('XMLDocument.php'); +$reply = new XMLDocument(array( 'DAV:' => '' )); + +$position = 0; +$xmltree = BuildXMLTree( $request->xml_tags, $position); + +$segment = $xmltree->GetElements('DAV::segment'); +$segment = $segment[0]->GetContent(); + +if ( preg_match( '{[/\\]}', $segment ) ) { + $request->PreconditionFailed(403, 'DAV::name-allowed',translate('That destination name contains invalid characters.') ); +} + +$href = $xmltree->GetElements('DAV::href')[0]->GetContent(); +// $href = $href[0]->GetContent(); + +$destination_path = $request->path; +if ( preg_match( '{[^/]$}', $destination_path ) ) $destination_path .= '/'; +$destination_path .= $segment; +$destination = new DAVResource( $destination_path ); +if ( $destination->Exists() ) { + $request->PreconditionFailed(403,'DAV::can-overwrite',translate('A resource already exists at the destination.')); +} + +$source = new DAVResource( $href ); +if ( !$source->Exists() ) { + $request->PreconditionFailed(403,'DAV::bind-source-exists',translate('The BIND Request MUST identify an existing resource.')); +} + +if ( $source->IsPrincipal() || !$source->IsCollection() ) { + $request->PreconditionFailed(403,'DAV::binding-allowed',translate('DAViCal only allows BIND requests for collections at present.')); +} + +/* + bind_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY, + bound_source_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, + access_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL, + parent_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE, + dav_name TEXT UNIQUE NOT NULL, + dav_displayname TEXT +*/ + +$sql = 'INSERT INTO dav_binding ( bound_source_id, access_ticket_id, parent_id, dav_name, dav_displayname ) +VALUES( :target_id, :ticket_id, :container_id, :dav_name, :displayname )'; +$params = array( + ':target_id' => $source->GetProperty('collection_id'), + ':ticket_id' => (isset($request->ticket) ? $request->ticket->id() : null), + ':container_id' => $destination->GetProperty('collection_id'), + ':dav_name' => $destination_path, + ':displayname' => 'Bind to '.$source->GetProperty('DAV::displayname') +); +$qry = new AwlQuery( $sql, $params ); +