From bf1ca75710a99a96ba39790e9db79bb0a0f950b4 Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Wed, 20 Jul 2011 15:53:34 +0200 Subject: Integration of SabreDAV --- lib/Sabre/DAV/FS/OwncloudDirectory.php | 131 +++++++++++++++++++++++++++++++++ lib/Sabre/DAV/FS/OwncloudFile.php | 89 ++++++++++++++++++++++ lib/Sabre/DAV/FS/OwncloudNode.php | 81 ++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 lib/Sabre/DAV/FS/OwncloudDirectory.php create mode 100644 lib/Sabre/DAV/FS/OwncloudFile.php create mode 100644 lib/Sabre/DAV/FS/OwncloudNode.php (limited to 'lib') diff --git a/lib/Sabre/DAV/FS/OwncloudDirectory.php b/lib/Sabre/DAV/FS/OwncloudDirectory.php new file mode 100644 index 00000000000..5a5e9fcabf6 --- /dev/null +++ b/lib/Sabre/DAV/FS/OwncloudDirectory.php @@ -0,0 +1,131 @@ +path . '/' . $name; + OC_FILESYSTEM::file_put_contents($newPath,$data); + + } + + /** + * Creates a new subdirectory + * + * @param string $name + * @return void + */ + public function createDirectory($name) { + + $newPath = $this->path . '/' . $name; + OC_FILESYSTEM::mkdir($newPath); + + } + + /** + * Returns a specific child node, referenced by its name + * + * @param string $name + * @throws Sabre_DAV_Exception_FileNotFound + * @return Sabre_DAV_INode + */ + public function getChild($name) { + + $path = $this->path . '/' . $name; + + if (!OC_FILESYSTEM::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located'); + + if (OC_FILESYSTEM::is_dir($path)) { + + return new OC_Sabre_DAV_FS_OwncloudDirectory($path); + + } else { + + return new OC_Sabre_DAV_FS_OwncloudFile($path); + + } + + } + + /** + * Returns an array with all the child nodes + * + * @return Sabre_DAV_INode[] + */ + public function getChildren() { + + $nodes = array(); + // foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); + if( OC_FILESYSTEM::is_dir($this->path)){ + $dh = OC_FILESYSTEM::opendir($this->path); + while(( $node = readdir($dh)) !== false ){ + if($node!='.' && $node!='..'){ + $nodes[] = $this->getChild($node); + } + } + } + return $nodes; + + } + + /** + * Checks if a child exists. + * + * @param string $name + * @return bool + */ + public function childExists($name) { + + $path = $this->path . '/' . $name; + return OC_FILESYSTEM::file_exists($path); + + } + + /** + * Deletes all files in this directory, and then itself + * + * @return void + */ + public function delete() { + + foreach($this->getChildren() as $child) $child->delete(); + OC_FILESYSTEM::rmdir($this->path); + + } + + /** + * Returns available diskspace information + * + * @return array + */ + public function getQuotaInfo() { + + return array( + OC_FILESYSTEM::filesize('/'), + OC_FILESYSTEM::free_space() + ); + + } + +} + diff --git a/lib/Sabre/DAV/FS/OwncloudFile.php b/lib/Sabre/DAV/FS/OwncloudFile.php new file mode 100644 index 00000000000..8c390302a64 --- /dev/null +++ b/lib/Sabre/DAV/FS/OwncloudFile.php @@ -0,0 +1,89 @@ +path,$data); + + } + + /** + * Returns the data + * + * @return string + */ + public function get() { + + return OC_FILESYSTEM::file_get_contents($this->path); + + } + + /** + * Delete the current file + * + * @return void + */ + public function delete() { + + OC_FILESYSTEM::unlink($this->path); + + } + + /** + * Returns the size of the node, in bytes + * + * @return int + */ + public function getSize() { + + return OC_FILESYSTEM::filesize($this->path); + + } + + /** + * Returns the ETag for a file + * + * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. + * The ETag is an arbritrary string, but MUST be surrounded by double-quotes. + * + * Return null if the ETag can not effectively be determined + * + * @return mixed + */ + public function getETag() { + + return null; + + } + + /** + * Returns the mime-type for a file + * + * If null is returned, we'll assume application/octet-stream + * + * @return mixed + */ + public function getContentType() { + + return OC_FILESYSTEM::getMimeType($this->path); + + } +} + diff --git a/lib/Sabre/DAV/FS/OwncloudNode.php b/lib/Sabre/DAV/FS/OwncloudNode.php new file mode 100644 index 00000000000..7ccd410e627 --- /dev/null +++ b/lib/Sabre/DAV/FS/OwncloudNode.php @@ -0,0 +1,81 @@ +path = $path; + } + + + + /** + * Returns the name of the node + * + * @return string + */ + public function getName() { + + list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path); + return $name; + + } + + /** + * Renames the node + * + * @param string $name The new name + * @return void + */ + public function setName($name) { + + list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); + list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); + + $newPath = $parentPath . '/' . $newName; + OC_FILESYSTEM::rename($this->path,$newPath); + + $this->path = $newPath; + + } + + + + /** + * Returns the last modification time, as a unix timestamp + * + * @return int + */ + public function getLastModified() { + + return OC_FILESYSTEM::filemtime($this->path); + + } + +} + -- cgit v1.2.3 From 86cd8063b49315246929f51774ac5314dab2c2cb Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Wed, 20 Jul 2011 16:36:36 +0200 Subject: Use SabreDAV authentication Code! --- files/webdav.php | 40 ++++++++++----------------------- lib/Sabre/DAV/Auth/Backend/Owncloud.php | 35 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 lib/Sabre/DAV/Auth/Backend/Owncloud.php (limited to 'lib') diff --git a/files/webdav.php b/files/webdav.php index ffcad303879..7d5855672ac 100644 --- a/files/webdav.php +++ b/files/webdav.php @@ -28,40 +28,24 @@ $RUNTIME_NOSETUPFS = true; require_once('../lib/base.php'); require_once('Sabre/autoload.php'); +require_once('Sabre/DAV/Auth/Backend/Owncloud.php'); require_once('Sabre/DAV/FS/OwncloudNode.php'); require_once('Sabre/DAV/FS/OwncloudFile.php'); require_once('Sabre/DAV/FS/OwncloudDirectory.php'); -ini_set('default_charset', 'UTF-8'); -#ini_set('error_reporting', ''); -@ob_clean(); +// Create ownCloud Dir +$publicDir = new OC_Sabre_DAV_FS_OwncloudDirectory(''); +$server = new Sabre_DAV_Server($publicDir); -if(empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['REDIRECT_REMOTE_USER'])) { - header('WWW-Authenticate: Basic realm="ownCloud"'); - header('HTTP/1.0 401 Unauthorized'); - die('401 Unauthorized'); -} +// Path to our script +$server->setBaseUri($WEBROOT.'/files/webdav.php'); -$user=$_SERVER['PHP_AUTH_USER']; -$passwd=$_SERVER['PHP_AUTH_PW']; +// Auth backend +$authBackend = new OC_Sabre_DAV_Auth_Backend_Owncloud(); +$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'); +$server->addPlugin($authPlugin); -if(OC_USER::login($user,$passwd)){ - OC_UTIL::setUpFS(); - - // Make sure there is a directory in your current directory named 'public'. We will be exposing that directory to WebDAV - $publicDir = new OC_Sabre_DAV_FS_OwncloudDirectory(''); - $server = new Sabre_DAV_Server($publicDir); - - // We're required to set the base uri, it is recommended to put your webdav server on a root of a domain - $server->setBaseUri($WEBROOT.'/files/webdav.php'); - - // And off we go! - $server->exec(); -} -else{ - header('WWW-Authenticate: Basic realm="ownCloud"'); - header('HTTP/1.0 401 Unauthorized'); - die('401 Unauthorized'); -} +// And off we go! +$server->exec(); ?> diff --git a/lib/Sabre/DAV/Auth/Backend/Owncloud.php b/lib/Sabre/DAV/Auth/Backend/Owncloud.php new file mode 100644 index 00000000000..8c8556f9f20 --- /dev/null +++ b/lib/Sabre/DAV/Auth/Backend/Owncloud.php @@ -0,0 +1,35 @@ + Date: Fri, 22 Jul 2011 14:38:42 +0200 Subject: Support for locks, minor changes --- files/webdav.php | 18 +++-- lib/Connector/Sabre/auth.php | 35 ++++++++ lib/Connector/Sabre/directory.php | 131 ++++++++++++++++++++++++++++++ lib/Connector/Sabre/file.php | 89 ++++++++++++++++++++ lib/Connector/Sabre/locks.php | 138 ++++++++++++++++++++++++++++++++ lib/Connector/Sabre/node.php | 81 +++++++++++++++++++ lib/Sabre/DAV/Auth/Backend/Owncloud.php | 35 -------- lib/Sabre/DAV/FS/OwncloudDirectory.php | 131 ------------------------------ lib/Sabre/DAV/FS/OwncloudFile.php | 89 -------------------- lib/Sabre/DAV/FS/OwncloudNode.php | 81 ------------------- 10 files changed, 486 insertions(+), 342 deletions(-) create mode 100644 lib/Connector/Sabre/auth.php create mode 100644 lib/Connector/Sabre/directory.php create mode 100644 lib/Connector/Sabre/file.php create mode 100644 lib/Connector/Sabre/locks.php create mode 100644 lib/Connector/Sabre/node.php delete mode 100644 lib/Sabre/DAV/Auth/Backend/Owncloud.php delete mode 100644 lib/Sabre/DAV/FS/OwncloudDirectory.php delete mode 100644 lib/Sabre/DAV/FS/OwncloudFile.php delete mode 100644 lib/Sabre/DAV/FS/OwncloudNode.php (limited to 'lib') diff --git a/files/webdav.php b/files/webdav.php index 7d5855672ac..7dce0b48197 100644 --- a/files/webdav.php +++ b/files/webdav.php @@ -28,23 +28,29 @@ $RUNTIME_NOSETUPFS = true; require_once('../lib/base.php'); require_once('Sabre/autoload.php'); -require_once('Sabre/DAV/Auth/Backend/Owncloud.php'); -require_once('Sabre/DAV/FS/OwncloudNode.php'); -require_once('Sabre/DAV/FS/OwncloudFile.php'); -require_once('Sabre/DAV/FS/OwncloudDirectory.php'); +require_once('Connector/Sabre/auth.php'); +require_once('Connector/Sabre/node.php'); +require_once('Connector/Sabre/file.php'); +require_once('Connector/Sabre/directory.php'); +require_once('Connector/Sabre/locks.php'); // Create ownCloud Dir -$publicDir = new OC_Sabre_DAV_FS_OwncloudDirectory(''); +$publicDir = new OC_Connector_Sabre_Directory(''); $server = new Sabre_DAV_Server($publicDir); // Path to our script $server->setBaseUri($WEBROOT.'/files/webdav.php'); // Auth backend -$authBackend = new OC_Sabre_DAV_Auth_Backend_Owncloud(); +$authBackend = new OC_Connector_Sabre_Auth(); $authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'); $server->addPlugin($authPlugin); +// Also make sure there is a 'data' directory, writable by the server. This directory is used to store information about locks +$lockBackend = new OC_Connector_Sabre_Locks(); +$lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend); +$server->addPlugin($lockPlugin); + // And off we go! $server->exec(); diff --git a/lib/Connector/Sabre/auth.php b/lib/Connector/Sabre/auth.php new file mode 100644 index 00000000000..cfe7723e761 --- /dev/null +++ b/lib/Connector/Sabre/auth.php @@ -0,0 +1,35 @@ +path . '/' . $name; + OC_FILESYSTEM::file_put_contents($newPath,$data); + + } + + /** + * Creates a new subdirectory + * + * @param string $name + * @return void + */ + public function createDirectory($name) { + + $newPath = $this->path . '/' . $name; + OC_FILESYSTEM::mkdir($newPath); + + } + + /** + * Returns a specific child node, referenced by its name + * + * @param string $name + * @throws Sabre_DAV_Exception_FileNotFound + * @return Sabre_DAV_INode + */ + public function getChild($name) { + + $path = $this->path . '/' . $name; + + if (!OC_FILESYSTEM::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located'); + + if (OC_FILESYSTEM::is_dir($path)) { + + return new OC_Connector_Sabre_Directory($path); + + } else { + + return new OC_Connector_Sabre_File($path); + + } + + } + + /** + * Returns an array with all the child nodes + * + * @return Sabre_DAV_INode[] + */ + public function getChildren() { + + $nodes = array(); + // foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); + if( OC_FILESYSTEM::is_dir($this->path)){ + $dh = OC_FILESYSTEM::opendir($this->path); + while(( $node = readdir($dh)) !== false ){ + if($node!='.' && $node!='..'){ + $nodes[] = $this->getChild($node); + } + } + } + return $nodes; + + } + + /** + * Checks if a child exists. + * + * @param string $name + * @return bool + */ + public function childExists($name) { + + $path = $this->path . '/' . $name; + return OC_FILESYSTEM::file_exists($path); + + } + + /** + * Deletes all files in this directory, and then itself + * + * @return void + */ + public function delete() { + + foreach($this->getChildren() as $child) $child->delete(); + OC_FILESYSTEM::rmdir($this->path); + + } + + /** + * Returns available diskspace information + * + * @return array + */ + public function getQuotaInfo() { + + return array( + OC_FILESYSTEM::filesize('/'), + OC_FILESYSTEM::free_space() + ); + + } + +} + diff --git a/lib/Connector/Sabre/file.php b/lib/Connector/Sabre/file.php new file mode 100644 index 00000000000..bb5ab738430 --- /dev/null +++ b/lib/Connector/Sabre/file.php @@ -0,0 +1,89 @@ +path,$data); + + } + + /** + * Returns the data + * + * @return string + */ + public function get() { + + return OC_FILESYSTEM::file_get_contents($this->path); + + } + + /** + * Delete the current file + * + * @return void + */ + public function delete() { + + OC_FILESYSTEM::unlink($this->path); + + } + + /** + * Returns the size of the node, in bytes + * + * @return int + */ + public function getSize() { + + return OC_FILESYSTEM::filesize($this->path); + + } + + /** + * Returns the ETag for a file + * + * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. + * The ETag is an arbritrary string, but MUST be surrounded by double-quotes. + * + * Return null if the ETag can not effectively be determined + * + * @return mixed + */ + public function getETag() { + + return null; + + } + + /** + * Returns the mime-type for a file + * + * If null is returned, we'll assume application/octet-stream + * + * @return mixed + */ + public function getContentType() { + + return OC_FILESYSTEM::getMimeType($this->path); + + } +} + diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php new file mode 100644 index 00000000000..58a0359899e --- /dev/null +++ b/lib/Connector/Sabre/locks.php @@ -0,0 +1,138 @@ + CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; + $params = array(time(),$uri); + + // We need to check locks for every part in the uri. + $uriParts = explode('/',$uri); + + // We already covered the last part of the uri + array_pop($uriParts); + + $currentPath=''; + + foreach($uriParts as $part) { + + if ($currentPath) $currentPath.='/'; + $currentPath.=$part; + + $query.=' OR (depth!=0 AND uri = ?)'; + $params[] = $currentPath; + + } + + if ($returnChildLocks) { + + $query.=' OR (uri LIKE ?)'; + $params[] = $uri . '/%'; + + } + $query.=')'; + + $stmt = OC_DB::prepare($query); + $result = $stmt->execute($params); + + $lockList = array(); + while( $row = $result->fetchRow()){ + + $lockInfo = new Sabre_DAV_Locks_LockInfo(); + $lockInfo->owner = $row['owner']; + $lockInfo->token = $row['token']; + $lockInfo->timeout = $row['timeout']; + $lockInfo->created = $row['created']; + $lockInfo->scope = $row['scope']; + $lockInfo->depth = $row['depth']; + $lockInfo->uri = $row['uri']; + $lockList[] = $lockInfo; + + } + + return $lockList; + + } + + /** + * Locks a uri + * + * @param string $uri + * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @return bool + */ + public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { + + // We're making the lock timeout 5 minutes + $lockInfo->timeout = 300; + $lockInfo->created = time(); + $lockInfo->uri = $uri; + + $locks = $this->getLocks($uri,false); + $exists = false; + foreach($locks as $k=>$lock) { + if ($lock->token == $lockInfo->token) $exists = true; + } + + if ($exists) { + $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + } else { + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + } + + return true; + + } + + + + /** + * Removes a lock from a uri + * + * @param string $uri + * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @return bool + */ + public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { + + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE path=? AND token=?' ); + $result = $query->execute( array($uri,$lockInfo->token)); + + return $result->numRows() === 1; + + } + +} + diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php new file mode 100644 index 00000000000..fb607a709e4 --- /dev/null +++ b/lib/Connector/Sabre/node.php @@ -0,0 +1,81 @@ +path = $path; + } + + + + /** + * Returns the name of the node + * + * @return string + */ + public function getName() { + + list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path); + return $name; + + } + + /** + * Renames the node + * + * @param string $name The new name + * @return void + */ + public function setName($name) { + + list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); + list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); + + $newPath = $parentPath . '/' . $newName; + OC_FILESYSTEM::rename($this->path,$newPath); + + $this->path = $newPath; + + } + + + + /** + * Returns the last modification time, as a unix timestamp + * + * @return int + */ + public function getLastModified() { + + return OC_FILESYSTEM::filemtime($this->path); + + } + +} + diff --git a/lib/Sabre/DAV/Auth/Backend/Owncloud.php b/lib/Sabre/DAV/Auth/Backend/Owncloud.php deleted file mode 100644 index 8c8556f9f20..00000000000 --- a/lib/Sabre/DAV/Auth/Backend/Owncloud.php +++ /dev/null @@ -1,35 +0,0 @@ -path . '/' . $name; - OC_FILESYSTEM::file_put_contents($newPath,$data); - - } - - /** - * Creates a new subdirectory - * - * @param string $name - * @return void - */ - public function createDirectory($name) { - - $newPath = $this->path . '/' . $name; - OC_FILESYSTEM::mkdir($newPath); - - } - - /** - * Returns a specific child node, referenced by its name - * - * @param string $name - * @throws Sabre_DAV_Exception_FileNotFound - * @return Sabre_DAV_INode - */ - public function getChild($name) { - - $path = $this->path . '/' . $name; - - if (!OC_FILESYSTEM::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located'); - - if (OC_FILESYSTEM::is_dir($path)) { - - return new OC_Sabre_DAV_FS_OwncloudDirectory($path); - - } else { - - return new OC_Sabre_DAV_FS_OwncloudFile($path); - - } - - } - - /** - * Returns an array with all the child nodes - * - * @return Sabre_DAV_INode[] - */ - public function getChildren() { - - $nodes = array(); - // foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); - if( OC_FILESYSTEM::is_dir($this->path)){ - $dh = OC_FILESYSTEM::opendir($this->path); - while(( $node = readdir($dh)) !== false ){ - if($node!='.' && $node!='..'){ - $nodes[] = $this->getChild($node); - } - } - } - return $nodes; - - } - - /** - * Checks if a child exists. - * - * @param string $name - * @return bool - */ - public function childExists($name) { - - $path = $this->path . '/' . $name; - return OC_FILESYSTEM::file_exists($path); - - } - - /** - * Deletes all files in this directory, and then itself - * - * @return void - */ - public function delete() { - - foreach($this->getChildren() as $child) $child->delete(); - OC_FILESYSTEM::rmdir($this->path); - - } - - /** - * Returns available diskspace information - * - * @return array - */ - public function getQuotaInfo() { - - return array( - OC_FILESYSTEM::filesize('/'), - OC_FILESYSTEM::free_space() - ); - - } - -} - diff --git a/lib/Sabre/DAV/FS/OwncloudFile.php b/lib/Sabre/DAV/FS/OwncloudFile.php deleted file mode 100644 index 8c390302a64..00000000000 --- a/lib/Sabre/DAV/FS/OwncloudFile.php +++ /dev/null @@ -1,89 +0,0 @@ -path,$data); - - } - - /** - * Returns the data - * - * @return string - */ - public function get() { - - return OC_FILESYSTEM::file_get_contents($this->path); - - } - - /** - * Delete the current file - * - * @return void - */ - public function delete() { - - OC_FILESYSTEM::unlink($this->path); - - } - - /** - * Returns the size of the node, in bytes - * - * @return int - */ - public function getSize() { - - return OC_FILESYSTEM::filesize($this->path); - - } - - /** - * Returns the ETag for a file - * - * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. - * The ETag is an arbritrary string, but MUST be surrounded by double-quotes. - * - * Return null if the ETag can not effectively be determined - * - * @return mixed - */ - public function getETag() { - - return null; - - } - - /** - * Returns the mime-type for a file - * - * If null is returned, we'll assume application/octet-stream - * - * @return mixed - */ - public function getContentType() { - - return OC_FILESYSTEM::getMimeType($this->path); - - } -} - diff --git a/lib/Sabre/DAV/FS/OwncloudNode.php b/lib/Sabre/DAV/FS/OwncloudNode.php deleted file mode 100644 index 7ccd410e627..00000000000 --- a/lib/Sabre/DAV/FS/OwncloudNode.php +++ /dev/null @@ -1,81 +0,0 @@ -path = $path; - } - - - - /** - * Returns the name of the node - * - * @return string - */ - public function getName() { - - list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path); - return $name; - - } - - /** - * Renames the node - * - * @param string $name The new name - * @return void - */ - public function setName($name) { - - list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); - list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); - - $newPath = $parentPath . '/' . $newName; - OC_FILESYSTEM::rename($this->path,$newPath); - - $this->path = $newPath; - - } - - - - /** - * Returns the last modification time, as a unix timestamp - * - * @return int - */ - public function getLastModified() { - - return OC_FILESYSTEM::filemtime($this->path); - - } - -} - -- cgit v1.2.3 From 5851da47f11d0b06c6415e22b080341d643aef14 Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 16:21:29 +0200 Subject: properties nearly work --- lib/Connector/Sabre/locks.php | 17 ++++++++++ lib/Connector/Sabre/node.php | 77 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index 58a0359899e..ed5ea17beab 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -13,6 +13,23 @@ require_once("lib/base.php"); * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ +/* + * + * The following SQL statement is just a help for developers and will not be + * executed! + * + * CREATE TABLE locks ( + * `id` INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + * `owner` VARCHAR(100), + * `timeout` INTEGER UNSIGNED, + * `created` INTEGER, + * `token` VARCHAR(100), + * `scope` TINYINT, + * `depth` TINYINT, + * `uri` text + * ); + * + */ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { /** diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php index fb607a709e4..0e8bae75fd9 100644 --- a/lib/Connector/Sabre/node.php +++ b/lib/Connector/Sabre/node.php @@ -13,7 +13,20 @@ require_once("lib/base.php"); * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode { +/* + * + * The following SQL statement is just a help for developers and will not be + * executed! + * + * CREATE TABLE IF NOT EXISTS `properties` ( + * `userid` varchar(200) COLLATE utf8_unicode_ci NOT NULL, + * `propertypath` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + * `propertyname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + * `propertyvalue` text COLLATE utf8_unicode_ci NOT NULL + * ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + * + */ +abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { /** * The path to the current node @@ -77,5 +90,67 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode { } + /** + * Updates properties on this node, + * + * @param array $mutations + * @see Sabre_DAV_IProperties::updateProperties + * @return bool|array + */ + public function updateProperties($properties) { + $existing = $this->getProperties(array()); + foreach($properties as $propertyName => $propertyValue) { + // If it was null, we need to delete the property + if (is_null($propertyValue)) { + if(array_key_exists( $propertyName, $existing )){ + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName )); + } + } + else { + if(!array_key_exists( $propertyName, $existing )){ + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); + $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName,$propertyValue )); + } + elseif($existing[$propertyName] !== $propertyValue){ + $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyvalue = ? WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( $propertyValue,'OC_USER::getUser()', $this->path, $propertyName )); + } + } + + } + return true; + } + + /** + * Returns a list of properties for this nodes.; + * + * The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author + * If the array is empty, all properties should be returned + * + * @param array $properties + * @return void + */ + function getProperties($properties) { + // At least some magic in here :-) + $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); + $result = $query->execute( array( 'OC_USER::getUser()', $this->path )); + + $existing = array(); + while( $row = $result->fetchRow()){ + $existing[$row['propertyname']] = $row['propertyvalue']; + } + + if(count($properties) == 0){ + return $existing; + } + + // if the array was empty, we need to return everything + $props = array(); + foreach($properties as $property) { + if (isset($existing[$property])) $props[$property] = $existing[$property]; + } + return $props; + } } -- cgit v1.2.3 From 3b92ec12c215754e84d7702e3f98e9428d5f9c3f Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 22:30:45 +0200 Subject: Properties work fine now --- lib/Connector/Sabre/locks.php | 19 +++++++++---------- lib/Connector/Sabre/node.php | 15 ++++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index ed5ea17beab..6c370b188fb 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -20,6 +20,7 @@ require_once("lib/base.php"); * * CREATE TABLE locks ( * `id` INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + * `userid` VARCHAR(200), * `owner` VARCHAR(100), * `timeout` INTEGER UNSIGNED, * `created` INTEGER, @@ -50,8 +51,8 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { // NOTE: the following 10 lines or so could be easily replaced by // pure sql. MySQL's non-standard string concatination prevents us // from doing this though. - $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM *PREFIX*locks WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; - $params = array(time(),$uri); + $query = 'SELECT * FROM *PREFIX*locks WHERE userid = ? AND ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; + $params = array(OC_USER::getUser(),time(),$uri); // We need to check locks for every part in the uri. $uriParts = explode('/',$uri); @@ -122,19 +123,17 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { } if ($exists) { - $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?' ); - $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE userid = ? AND token = ?' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,OC_USER::getUser(),$lockInfo->token)); } else { - $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)' ); - $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (userid,owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?,?)' ); + $result = $query->execute( array(OC_USER::getUser(),$lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); } return true; } - - /** * Removes a lock from a uri * @@ -144,8 +143,8 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { */ public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { - $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE path=? AND token=?' ); - $result = $query->execute( array($uri,$lockInfo->token)); + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND path=? AND token=?' ); + $result = $query->execute( array(OC_USER::getUser(),$uri,$lockInfo->token)); return $result->numRows() === 1; diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php index 0e8bae75fd9..dc1013dc524 100644 --- a/lib/Connector/Sabre/node.php +++ b/lib/Connector/Sabre/node.php @@ -71,9 +71,14 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; + $oldPath = $this->path; + OC_FILESYSTEM::rename($this->path,$newPath); $this->path = $newPath; + + $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertypath = ? WHERE userid = ? AND propertypath = ?' ); + $query->execute( array( $newPath,OC_USER::getUser(), $oldPath )); } @@ -104,17 +109,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr if (is_null($propertyValue)) { if(array_key_exists( $propertyName, $existing )){ $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); - $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName )); + $query->execute( array( OC_USER::getUser(), $this->path, $propertyName )); } } else { if(!array_key_exists( $propertyName, $existing )){ $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); - $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName,$propertyValue )); + $query->execute( array( OC_USER::getUser(), $this->path, $propertyName,$propertyValue )); } - elseif($existing[$propertyName] !== $propertyValue){ + else{ $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyvalue = ? WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); - $query->execute( array( $propertyValue,'OC_USER::getUser()', $this->path, $propertyName )); + $query->execute( array( $propertyValue,OC_USER::getUser(), $this->path, $propertyName )); } } @@ -134,7 +139,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr function getProperties($properties) { // At least some magic in here :-) $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); - $result = $query->execute( array( 'OC_USER::getUser()', $this->path )); + $result = $query->execute( array( OC_USER::getUser(), $this->path )); $existing = array(); while( $row = $result->fetchRow()){ -- cgit v1.2.3 From 18a36be28cd94dd8d04c60f02b42bc79a5173b2f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 22 Jul 2011 23:06:53 +0200 Subject: fix problem with removing locks --- lib/Connector/Sabre/locks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index 6c370b188fb..8414891b778 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -143,7 +143,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { */ public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { - $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND path=? AND token=?' ); + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND uri=? AND token=?' ); $result = $query->execute( array(OC_USER::getUser(),$uri,$lockInfo->token)); return $result->numRows() === 1; -- cgit v1.2.3 From 5416c0e6f828ef09d54f36d6ce39ec962ff4d156 Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 23:16:14 +0200 Subject: Remove HTTP_Webdav --- lib/HTTP/WebDAV/Server/Filesystem.php | 757 ---------------------------------- 1 file changed, 757 deletions(-) delete mode 100644 lib/HTTP/WebDAV/Server/Filesystem.php (limited to 'lib') diff --git a/lib/HTTP/WebDAV/Server/Filesystem.php b/lib/HTTP/WebDAV/Server/Filesystem.php deleted file mode 100644 index 5f261643624..00000000000 --- a/lib/HTTP/WebDAV/Server/Filesystem.php +++ /dev/null @@ -1,757 +0,0 @@ - - * @version @package-version@ - */ - class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server - { - /** - * Root directory for WebDAV access - * - * Defaults to webserver document root (set by ServeRequest) - * - * @access private - * @var string - */ - var $base = ""; - - /** - * Serve a webdav request - * - * @access public - * @param string - */ - function ServeRequest($base = false) - { - // special treatment for litmus compliance test - // reply on its identifier header - // not needed for the test itself but eases debugging - if (isset($this->_SERVER['HTTP_X_LITMUS'])) { - error_log("Litmus test ".$this->_SERVER['HTTP_X_LITMUS']); - header("X-Litmus-reply: ".$this->_SERVER['HTTP_X_LITMUS']); - } - - // set root directory, defaults to webserver document root if not set - if ($base) { - $this->base = realpath($base); // TODO throw if not a directory - } else if (!$this->base) { - $this->base = $this->_SERVER['DOCUMENT_ROOT']; - } - - // let the base class do all the work - parent::ServeRequest(); - } - - /** - * No authentication is needed here - * - * @access private - * @param string HTTP Authentication type (Basic, Digest, ...) - * @param string Username - * @param string Password - * @return bool true on successful authentication - */ - function check_auth($type, $user, $pass) - { - return true; - } - - - /** - * PROPFIND method handler - * - * @param array general parameter passing array - * @param array return array for file properties - * @return bool true on success - */ - function PROPFIND(&$options, &$files) - { - // get absolute fs path to requested resource - $fspath = $options["path"]; - - // sanity check - if (!OC_FILESYSTEM::file_exists($fspath)) { - return false; - } - - // prepare property array - $files["files"] = array(); - // store information for the requested path itself - $files["files"][] = $this->fileinfo($options["path"]); - // information for contained resources requested? - if (!empty($options["depth"]) && OC_FILESYSTEM::is_dir($fspath) && OC_FILESYSTEM::is_readable($fspath)) { - // make sure path ends with '/' - $options["path"] = $this->_slashify($options["path"]); - - // try to open directory - $handle = @OC_FILESYSTEM::opendir($fspath); - - if ($handle) { - // ok, now get all its contents - while ($filename = readdir($handle)) { - if ($filename != "." && $filename != "..") { - $files["files"][] = $this->fileinfo($options["path"].$filename); - } - } - // TODO recursion needed if "Depth: infinite" - } - } - - // ok, all done - return true; - } - - /** - * Get properties for a single file/resource - * - * @param string resource path - * @return array resource properties - */ - function fileinfo($path) - { - - // map URI path to filesystem path - $fspath =$path; - - // create result array - $info = array(); - // TODO remove slash append code when base clase is able to do it itself - $info["path"] = OC_FILESYSTEM::is_dir($fspath) ? $this->_slashify($path) : $path; - $info["props"] = array(); - // no special beautified displayname here ... - $info["props"][] = $this->mkprop("displayname", strtoupper($path)); - - // creation and modification time - $info["props"][] = $this->mkprop("creationdate", OC_FILESYSTEM::filectime($fspath)); - $info["props"][] = $this->mkprop("getlastmodified", OC_FILESYSTEM::filemtime($fspath)); - // Microsoft extensions: last access time and 'hidden' status - $info["props"][] = $this->mkprop("lastaccessed", OC_FILESYSTEM::fileatime($fspath)); - $info["props"][] = $this->mkprop("ishidden", ('.' === substr(basename($fspath), 0, 1))); - // type and size (caller already made sure that path exists) - if ( OC_FILESYSTEM::is_dir($fspath)) { - // directory (WebDAV collection) - $info["props"][] = $this->mkprop("resourcetype", "collection"); - $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory"); - } else { - // plain file (WebDAV resource) - $info["props"][] = $this->mkprop("resourcetype", ""); - if ( OC_FILESYSTEM::is_readable($fspath)) { - $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath)); - } else { - $info["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable"); - } - $info["props"][] = $this->mkprop("getcontentlength", OC_FILESYSTEM::filesize($fspath)); - } - // get additional properties from database - $query = OC_DB::prepare("SELECT ns, name, value FROM *PREFIX*properties WHERE path = ?"); - $res = $query->execute(array($path))->fetchAll(); - foreach($res as $row){ - $info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]); - } - return $info; - } - - /** - * try to detect the mime type of a file - * - * @param string file path - * @return string guessed mime type - */ - function _mimetype($fspath) - { - return OC_FILESYSTEM::getMimeType($fspath); - } - - /** - * HEAD method handler - * - * @param array parameter passing array - * @return bool true on success - */ - function HEAD(&$options) - { - // get absolute fs path to requested resource - $fspath = $options["path"]; - - // sanity check - if (! OC_FILESYSTEM::file_exists($fspath)) return false; - - // detect resource type - $options['mimetype'] = $this->_mimetype($fspath); - - // detect modification time - // see rfc2518, section 13.7 - // some clients seem to treat this as a reverse rule - // requiering a Last-Modified header if the getlastmodified header was set - $options['mtime'] = OC_FILESYSTEM::filemtime($fspath); - - // detect resource size - $options['size'] = OC_FILESYSTEM::filesize($fspath); - - return true; - } - - /** - * GET method handler - * - * @param array parameter passing array - * @return bool true on success - */ - function GET(&$options) - { - // get absolute fs path to requested resource) - $fspath = $options["path"]; - // is this a collection? - if (OC_FILESYSTEM::is_dir($fspath)) { - return $this->GetDir($fspath, $options); - } - - // the header output is the same as for HEAD - if (!$this->HEAD($options)) { - return false; - } - - // no need to check result here, it is handled by the base class - $options['stream'] = OC_FILESYSTEM::fopen($fspath, "r"); - - return true; - } - - /** - * GET method handler for directories - * - * This is a very simple mod_index lookalike. - * See RFC 2518, Section 8.4 on GET/HEAD for collections - * - * @param string directory path - * @return void function has to handle HTTP response itself - */ - function GetDir($fspath, &$options) - { - $path = $this->_slashify($options["path"]); - if ($path != $options["path"]) { - header("Location: ".$this->base_uri.$path); - exit; - } - - // fixed width directory column format - $format = "%15s %-19s %-s\n"; - - if (!OC_FILESYSTEM::is_readable($fspath)) { - return false; - } - - $handle = OC_FILESYSTEM::opendir($fspath); - if (!$handle) { - return false; - } - - echo "Index of ".htmlspecialchars($options['path'])."\n"; - - echo "

Index of ".htmlspecialchars($options['path'])."

\n"; - - echo "
";
-        printf($format, "Size", "Last modified", "Filename");
-        echo "
"; - - while ($filename = readdir($handle)) { - if ($filename != "." && $filename != "..") { - if( substr($fspath, -1) != '/' ){ - $fspath .= '/'; - } - $fullpath = $fspath.$filename; - $name = htmlspecialchars($filename); - $uri = $_SERVER['SCRIPT_NAME'] . $fullpath; - printf($format, - number_format(OC_FILESYSTEM::filesize($fullpath)), - strftime("%Y-%m-%d %H:%M:%S", OC_FILESYSTEM::filemtime($fullpath)), - "$name"); - } - } - - echo "
"; - - closedir($handle); - - echo "\n"; - - exit; - } - - /** - * PUT method handler - * - * @param array parameter passing array - * @return bool true on success - */ - function PUT(&$options) - { - $fspath = $options["path"]; - $dir = dirname($fspath); - if (!OC_FILESYSTEM::file_exists($dir) || !OC_FILESYSTEM::is_dir($dir)) { - return "409 Conflict"; // TODO right status code for both? - } - - $options["new"] = ! OC_FILESYSTEM::file_exists($fspath); - - if ($options["new"] && !OC_FILESYSTEM::is_writeable($dir)) { - return "403 Forbidden"; - } - if (!$options["new"] && !OC_FILESYSTEM::is_writeable($fspath)) { - return "403 Forbidden"; - } - if (!$options["new"] && OC_FILESYSTEM::is_dir($fspath)) { - return "403 Forbidden"; - } - $fp = OC_FILESYSTEM::fopen($fspath, "w"); - - return $fp; - } - - - /** - * MKCOL method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function MKCOL($options) - { - $path = $options["path"]; - $parent = dirname($path); - $name = basename($path); - if (!OC_FILESYSTEM::file_exists($parent)) { - return "409 Conflict"; - } - - if (!OC_FILESYSTEM::is_dir($parent)) { - return "403 Forbidden"; - } - - if ( OC_FILESYSTEM::file_exists($parent."/".$name) ) { - return "405 Method not allowed"; - } - - if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet - return "415 Unsupported media type"; - } - - $stat = OC_FILESYSTEM::mkdir($parent."/".$name, 0777); - if (!$stat) { - return "403 Forbidden"; - } - - return ("201 Created"); - } - - - /** - * DELETE method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function DELETE($options) - { - $path =$options["path"]; - if (!OC_FILESYSTEM::file_exists($path)) { - return "404 Not found"; - } - $lock=self::checkLock($path); - if(is_array($lock)){ - $owner=$options['owner']; - $lockOwner=$lock['owner']; - if($owner==$lockOwner){ - return "423 Locked"; - } - } - if (OC_FILESYSTEM::is_dir($path)) { - $query = OC_DB::prepare("DELETE FROM *PREFIX*properties WHERE path LIKE '?%'"); - $query->execute(array($this->_slashify($options["path"]))); - OC_FILESYSTEM::delTree($path); - } else { - OC_FILESYSTEM::unlink($path); - } - $query = OC_DB::prepare("DELETE FROM *PREFIX*properties WHERE path = ?"); - $query->execute(array($options['path'])); - - return "204 No Content"; - } - - - /** - * MOVE method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function MOVE($options) - { - return $this->COPY($options, true); - } - - /** - * COPY method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function COPY($options, $del=false) - { - // TODO Property updates still broken (Litmus should detect this?) - - if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet - return "415 Unsupported media type"; - } - - // no copying to different WebDAV Servers yet - if (isset($options["dest_url"])) { - return "502 bad gateway"; - } - - $source = $options["path"]; - if (!OC_FILESYSTEM::file_exists($source)) { - return "404 Not found"; - } - - if (OC_FILESYSTEM::is_dir($source)) { // resource is a collection - switch ($options["depth"]) { - case "infinity": // valid - break; - case "0": // valid for COPY only - if ($del) { // MOVE? - return "400 Bad request"; - } - break; - case "1": // invalid for both COPY and MOVE - default: - return "400 Bad request"; - } - } - - $dest = $options["dest"]; - $destdir = dirname($dest); - - if (!OC_FILESYSTEM::file_exists($destdir) || !OC_FILESYSTEM::is_dir($destdir)) { - return "409 Conflict"; - } - - - $new = !OC_FILESYSTEM::file_exists($dest); - $existing_col = false; - - if (!$new) { - if ($del && OC_FILESYSTEM::is_dir($dest)) { - if (!$options["overwrite"]) { - return "412 precondition failed"; - } - $dest .= basename($source); - if (OC_FILESYSTEM::file_exists($dest)) { - $options["dest"] .= basename($source); - } else { - $new = true; - $existing_col = true; - } - } - } - - if (!$new) { - if ($options["overwrite"]) { - $stat = $this->DELETE(array("path" => $options["dest"])); - if (($stat{0} != "2") && (substr($stat, 0, 3) != "404")) { - return $stat; - } - } else { - return "412 precondition failed"; - } - } - - if ($del) { - if (!OC_FILESYSTEM::rename($source, $dest)) { - return "500 Internal server error"; - } - $destpath = $this->_unslashify($options["dest"]); - if (is_dir($source)) { - $dpath=$destpath; - $path=$options["path"]; - $query = OC_DB::prepare("UPDATE *PREFIX*properties - SET path = REPLACE(path, ?, ?) - WHERE path LIKE '?%'"); - $query->execute(array($path,$dpath,$path)); - } - - $query = OC_DB::prepare("UPDATE *PREFIX*properties - SET path = ? - WHERE path = ?"); - $query->execute(array($dpath,$path)); - } else { - if (OC_FILESYSTEM::is_dir($source)) { - $files = OC_FILESYSTEM::getTree($source); - } else { - $files = array($source); - } - - if (!is_array($files) || empty($files)) { - return "500 Internal server error"; - } - - - foreach ($files as $file) { - if (OC_FILESYSTEM::is_dir($file)) { - $file = $this->_slashify($file); - } - $destfile = str_replace($source, $dest, $file); - - if (OC_FILESYSTEM::is_dir($file)) { - if (!OC_FILESYSTEM::file_exists($destfile)) { - if (!OC_FILESYSTEM::is_writeable(dirname($destfile))) { - return "403 Forbidden"; - } - if (!OC_FILESYSTEM::mkdir($destfile)) { - return "409 Conflict"; - } - } else if (!OC_FILESYSTEM::is_dir($destfile)) { - return "409 Conflict"; - } - } else { - if (!OC_FILESYSTEM::copy($file, $destfile)) { - return "409 Conflict($source) $file --> $destfile ".implode('::',$files); - } - } - } - } - return ($new && !$existing_col) ? "201 Created" : "204 No Content"; - } - - /** - * PROPPATCH method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function PROPPATCH(&$options) - { - global $prefs, $tab; - - $msg = ""; - $path = $options["path"]; - $dir = dirname($path)."/"; - $base = basename($path); - - foreach ($options["props"] as $key => $prop) { - if ($prop["ns"] == "DAV:") { - $options["props"][$key]['status'] = "403 Forbidden"; - } else { - $path=$options['path']; - $name=$prop['name']; - $ns=$prop['ns']; - if (isset($prop["val"])) { - $val=$prop['val']; - $query = OC_DB::prepare("REPLACE INTO *PREFIX*properties (path,name,ns,value) VALUES(?,?,?,?)"); - $query->execute(array($path,$name,$ns,$val)); - } else { - $query = $query = OC_DB::prepare("DELETE FROM *PREFIX*properties WHERE path = ? AND name = ? AND ns = ?"); - $query->execute(array($path,$name,$ns)); - } - } - } - - return ""; - } - - - /** - * LOCK method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function LOCK(&$options) - { - - // get absolute fs path to requested resource - $fspath = $options["path"]; - // TODO recursive locks on directories not supported yet - // makes litmus test "32. lock_collection" fail - if (OC_FILESYSTEM::is_dir($fspath) && !empty($options["depth"])) { - switch($options["depth"]){ - case 'infinity': - $recursion=1; - break; - case '0': - $recursion=0; - break; - } - }else{ - $recursion=0; - } - - $options["timeout"] = time()+300; // 5min. hardcoded - - if (isset($options["update"])) { // Lock Update - $where = "WHERE path = ? AND token = ?"; - - $query = OC_DB::prepare("SELECT owner, exclusivelock FROM *PREFIX*locks $where"); - $res = $query->execute(array($options[path],$options[update]))->fetchAll(); - - if (is_array($res) and isset($res[0])) { - $row=$res[0]; - $query = OC_DB::prepare("UPDATE `*PREFIX*locks` SET `expires` = , `modified` = $where"); - $query->execute(array($options[timeout],time(),$options[path],$options[update])); - - $options['owner'] = $row['owner']; - $options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared"; - $options['type'] = $row["exclusivelock"] ? "write" : "read"; - - return true; - } else {//check for indirect refresh - $query = OC_DB::prepare("SELECT * FROM *PREFIX*locks WHERE recursive = 1"); - $res = $query->execute(); - foreach($res as $row){ - if(strpos($options['path'],$row['path'])==0){//are we a child of a folder with an recursive lock - $where = "WHERE path = ? AND token = ?"; - $query = OC_DB::prepare("UPDATE `*PREFIX*locks` SET `expires` = ?, `modified` = ? $where"); - $query->execute(array($options[timeout],time(),$row[path],$options[update])); - $options['owner'] = $row['owner']; - $options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared"; - $options['type'] = $row["exclusivelock"] ? "write" : "read"; - return true; - } - } - } - } - - $locktoken=$options['locktoken']; - $path=$options['path']; - $time=time(); - $owner=$options['owner']; - $timeout=$options['timeout']; - $exclusive=($options['scope'] === "exclusive" ? "1" : "0"); - $query = OC_DB::prepare("INSERT INTO `*PREFIX*locks` -(`token`,`path`,`created`,`modified`,`owner`,`expires`,`exclusivelock`,`recursive`) -VALUES (?,?,?,?,?,'timeout',?,?)"); - $result=$query->execute(array($locktoken,$path,$time,$time,$owner,$exclusive,$recursion)); - if(!OC_FILESYSTEM::file_exists($fspath) and $rows>0) { - return "201 Created"; - } - return PEAR::isError($result) ? "409 Conflict" : "200 OK"; - } - - /** - * UNLOCK method handler - * - * @param array general parameter passing array - * @return bool true on success - */ - function UNLOCK(&$options) - { - $query = OC_DB::prepare("DELETE FROM *PREFIX*locks - WHERE path = '$options[path]' - AND token = '$options[token]'"); - /* - $query = OC_DB::prepare("DELETE FROM *PREFIX*locks - WHERE path = ? - AND token = ?"); - */ - $query->execute();#array($options[path]),$options[token]); - return PEAR::isError($result) ? "409 Conflict" : "204 No Content"; - } - - /** - * checkLock() helper - * - * @param string resource path to check for locks - * @return bool true on success - */ - function checkLock($path) - { - $result = false; - $query = OC_DB::prepare("SELECT * - FROM *PREFIX*locks - WHERE path = ? - "); - $res = $query->execute(array($path))->fetchAll(); - if (is_array($res) and isset($res[0])) { - $row=$res[0]; - - if ($row) { - $result = array( "type" => "write", - "scope" => $row["exclusivelock"] ? "exclusive" : "shared", - "depth" => 0, - "owner" => $row['owner'], - "token" => $row['token'], - "created" => $row['created'], - "modified" => $row['modified'], - "expires" => $row['expires'], - "recursive" => $row['recursive'] - ); - } - }else{ - //check for recursive locks; - $query = OC_DB::prepare("SELECT * - FROM *PREFIX*locks - WHERE recursive = 1 - "); - $res = $query->execute()->fetchAll(); - foreach($res as $row){ - if(strpos($path,$row['path'])==0){//are we a child of a folder with an recursive lock - $result = array( "type" => "write", - "scope" => $row["exclusivelock"] ? "exclusive" : "shared", - "depth" => 0, - "owner" => $row['owner'], - "token" => $row['token'], - "created" => $row['created'], - "modified" => $row['modified'], - "expires" => $row['expires'], - "recursive" => $row['recursive'] - ); - } - } - } - - return $result; - } -} - -?> -- cgit v1.2.3