Page MenuHomePhorge

No OneTemporary

diff --git a/lib/Kolab/DAV/Backend.php b/lib/Kolab/DAV/Backend.php
index 816d8e1..555ee56 100644
--- a/lib/Kolab/DAV/Backend.php
+++ b/lib/Kolab/DAV/Backend.php
@@ -1,98 +1,77 @@
<?php
/**
* SabreDAV File Backend implementation for Kolab.
*
* @author Aleksander Machniak <machniak@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\DAV;
-use \rcube;
+use Kolab\DAV\Auth\HTTPBasic;
-class Backend
+class Backend extends \file_api_lib
{
+ protected $configured = false;
protected static $instance;
- protected $api;
- protected $conf;
- protected $app_name = 'Kolab File API';
- protected $config = array(
- 'date_format' => 'Y-m-d H:i',
- 'language' => 'en_US',
- );
-
/**
* This implements the 'singleton' design pattern
*
* @return Backend The one and only instance
*/
static function get_instance()
{
if (!self::$instance) {
self::$instance = new Backend();
- self::$instance->init();
}
return self::$instance;
}
/**
* Private constructor
*/
protected function __construct()
{
- $rcube = rcube::get_instance();
- $this->conf = $rcube->config;
- }
-
- /**
- * Returns file API backend
- */
- public function get_backend()
- {
- return $this->api;
}
/**
- * Initialise backend class
+ * Configure main (authentication) driver
*/
protected function init()
{
- $driver = $this->conf->get('fileapi_backend', 'kolab');
- $class = $driver . '_file_storage';
+ // We currently support only one auth driver which is Kolab driver.
+ // Because of that we don't need to authenticate in Kolab again,
+ // we need only to configure it to use current username/password.
+ // This is required if we want to use external storage drivers.
- $this->api = new $class;
- $this->api->configure($this->config);
- }
+ if (!$this->configured && !empty(HTTPBasic::$current_user)) {
+ // configure authentication driver
+ $config = array(
+ 'username' => HTTPBasic::$current_user,
+ 'password' => HTTPBasic::$current_pass,
+ );
- /*
- * Returns API capabilities
- */
- protected function capabilities()
- {
- foreach ($this->api->capabilities() as $name => $value) {
- // skip disabled capabilities
- if ($value !== false) {
- $caps[$name] = $value;
- }
- }
+ $backend = $this->get_backend();
+ $backend->configure($config, '');
- return $caps;
+ $this->configured = true;
+ }
}
}
diff --git a/lib/Kolab/DAV/Collection.php b/lib/Kolab/DAV/Collection.php
index d8d39b7..b148ece 100644
--- a/lib/Kolab/DAV/Collection.php
+++ b/lib/Kolab/DAV/Collection.php
@@ -1,226 +1,227 @@
<?php
/**
* SabreDAV File Backend implementation for Kolab.
*
* @author Aleksander Machniak <machniak@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\DAV;
use \Exception;
/**
* Collection class
*/
class Collection extends \Kolab\DAV\Node implements \Sabre\DAV\ICollection
{
const ROOT_DIRECTORY = 'files';
public $children;
function getChildren()
{
// @TODO: maybe children array is too big to keep it in memory?
if (is_array($this->children)) {
return $this->children;
}
$path_len = strlen($this->path);
$this->children = array();
try {
// @TODO: This should be cached too (out of this class)
$folders = $this->backend->folder_list();
+ $folders = $folders['list'];
}
catch (Exception $e) {
}
// get subfolders
foreach ($folders as $folder) {
// need root-folders or subfolders of specified folder
if (!$path_len || strpos($folder, $this->path . '/') === 0) {
$virtual = false;
// remove path suffix, the list might contain folders (roots) that
// do not exist e.g.:
// Files
// Files/Sub
// Other Users/machniak/Files
// Other Users/machniak/Files/Sub
// the list is sorted so we can do this in such a way
if ($pos = strpos($folder, '/', $path_len + 1)) {
$folder = substr($folder, 0, $pos);
$virtual = true;
}
$path = Collection::ROOT_DIRECTORY . '/' . $folder;
if ($path_len) {
$folder = substr($folder, $path_len + 1);
}
if (!array_key_exists($folder, $this->children)) {
$this->children[$folder] = new Collection($path, $this, array('virtual' => $virtual));
}
}
}
// non-root existing folder, get files list
if ($path_len && empty($this->data['virtual'])) {
try {
$files = $this->backend->file_list($this->path);
}
catch (Exception $e) {
}
foreach ($files as $filename => $file) {
$path = Collection::ROOT_DIRECTORY . '/' . $filename;
// remove path prefix
$filename = substr($filename, $path_len + 1);
$this->children[$filename] = new File($path, $this, $file);
}
}
return $this->children;
}
/**
* Returns a child object, by its name.
*
* This method makes use of the getChildren method to grab all the child
* nodes, and compares the name.
* Generally its wise to override this, as this can usually be optimized
*
* This method must throw Sabre\DAV\Exception\NotFound if the node does not
* exist.
*
* @param string $name
* @throws Sabre\DAV\Exception\NotFound
* @return INode
*/
public function getChild($name)
{
// no support for hidden system files
if ($name[0] == '.') {
throw new \Sabre\DAV\Exception\NotFound('File not found: ' . $name);
}
$children = $this->getChildren();
if (array_key_exists($name, $children)) {
return $children[$name];
}
throw new \Sabre\DAV\Exception\NotFound('File not found: ' . $name);
}
/**
* Checks if a child-node exists.
*
* It is generally a good idea to try and override this. Usually it can be optimized.
*
* @param string $name
* @return bool
*/
public function childExists($name)
{
try {
$this->getChild($name);
return true;
}
catch (\Sabre\DAV\Exception\NotFound $e) {
return false;
}
}
/**
* Creates a new file in the directory
*
* Data will either be supplied as a stream resource, or in certain cases
* as a string. Keep in mind that you may have to support either.
*
* After succesful creation of the file, you may choose to return the ETag
* of the new file here.
*
* The returned ETag must be surrounded by double-quotes (The quotes should
* be part of the actual string).
*
* If you cannot accurately determine the ETag, you should not return it.
* If you don't store the file exactly as-is (you're transforming it
* somehow) you should also not return an ETag.
*
* This means that if a subsequent GET to this new file does not exactly
* return the same contents of what was submitted here, you are strongly
* recommended to omit the ETag.
*
* @param string $name Name of the file
* @param resource|string $data Initial payload
* @return null|string
*/
public function createFile($name, $data = null)
{
// no support for hidden system files
if ($name[0] == '.') {
throw new \Sabre\DAV\Exception\Forbidden('Hidden files are not accepted');
}
$filename = $this->path . '/' . $name;
$filedata = $this->fileData($name, $data);
try {
$this->backend->file_create($filename, $filedata);
}
catch (Exception $e) {
// throw new \Sabre\DAV\Exception\Forbidden($e->getMessage());
}
// reset cache
$this->children = null;
}
/**
* Creates a new subdirectory
*
* @param string $name
* @throws Exception\Forbidden
* @return void
*/
public function createDirectory($name)
{
// no support for hidden system files
if ($name[0] == '.') {
throw new \Sabre\DAV\Exception\Forbidden('Hidden files are not accepted');
}
$folder = $this->path . '/' . $name;
try {
$this->backend->folder_create($folder);
}
catch (Exception $e) {
throw new \Sabre\DAV\Exception\Forbidden($e->getMessage());
}
// reset cache
$this->children = null;
}
}
diff --git a/lib/Kolab/DAV/Locks/Chwala.php b/lib/Kolab/DAV/Locks/Chwala.php
index f5eb8d8..d85ad3a 100644
--- a/lib/Kolab/DAV/Locks/Chwala.php
+++ b/lib/Kolab/DAV/Locks/Chwala.php
@@ -1,196 +1,196 @@
<?php
/**
* Chwala-based lock manager for the Kolab WebDAV service.
*
* @author Aleksander Machniak <machniak@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\DAV\Locks;
use \file_storage;
use \Kolab\DAV\Backend;
use Sabre\DAV\Server;
use Sabre\DAV\Locks\LockInfo;
use Sabre\DAV\Locks\Backend\AbstractBackend;
use \Exception;
/**
* The Lock manager that maintains a lock file per user in the local file system.
*/
class Chwala extends AbstractBackend
{
/**
* The base Path
*
* @var string
*/
protected $basePath;
/**
* The file API backend class
*
- * @var file_api_storage
+ * @var Kolab\DAV\Backend
*/
protected $backend;
/**
* Constructor
*
* @param string $path Base path
*/
public function __construct($path = null)
{
- $this->backend = Backend::get_instance()->get_backend();
+ $this->backend = Backend::get_instance();
$this->basePath = $path;
}
/**
* Returns a list of Sabre\DAV\Locks\LockInfo objects
*
* This method should return all the locks for a particular uri, including
* locks that might be set on a parent uri.
*
* If returnChildLocks is set to true, this method should also look for
* any locks in the subtree of the uri for locks.
*
* @param string $uri
* @param bool $returnChildLocks
* @return array
*/
public function getLocks($uri, $returnChildLocks)
{
console(__METHOD__, $uri, $returnChildLocks);
$path = $this->uri2path($uri);
if (!strlen($path)) {
return array();
}
// @TODO: when using Dolphin I've found that this method
// is called for every file in a folder, this might become
// a performance issue.
$list = $this->backend->lock_list($path, $returnChildLocks);
$list = array_map(array($this, 'to_lockinfo'), (array) $list);
return $list;
}
/**
* Locks a uri
*
* @param string $uri
* @param LockInfo $lockInfo
* @return bool
*/
public function lock($uri, LockInfo $lockInfo)
{
console(__METHOD__, $uri, $lockInfo);
try {
- $this->backend->lock($this->uri2path($uri), $this->from_lockinfo($lockInfo));
+ $this->backend->lock_create($this->uri2path($uri), $this->from_lockinfo($lockInfo));
}
catch (Exception $e) {
return false;
}
return true;
}
/**
* Removes a lock from a uri
*
* @param string $uri
* @param LockInfo $lockInfo
* @return bool
*/
public function unlock($uri, LockInfo $lockInfo)
{
console(__METHOD__, $uri, $lockInfo);
try {
- $this->backend->unlock($this->uri2path($uri), $this->from_lockinfo($lockInfo));
+ $this->backend->lock_delete($this->uri2path($uri), $this->from_lockinfo($lockInfo));
}
catch (Exception $e) {
return false;
}
return true;
}
/**
* Converts URI according to root directory
*/
protected function uri2path($uri)
{
if ($this->basePath) {
if (strpos($uri, $this->basePath . '/') === 0) {
$uri = substr($uri, strlen($this->basePath) + 1);
}
}
return $uri;
}
/**
* Converts URI according to root directory
*/
protected function path2uri($path)
{
if ($this->basePath) {
$path = $this->basePath . '/' . $path;
}
return $path;
}
/**
* Convert LockInfo object into Chwala's lock data array
*/
public function from_lockinfo(LockInfo $lockInfo)
{
$lock = (array) $lockInfo;
// map to Chwala scope/depth values
$lock['scope'] = $lock['scope'] == LockInfo::SHARED ? file_storage::LOCK_SHARED : file_storage::LOCK_EXCLUSIVE;
$lock['depth'] = $lock['depth'] == Server::DEPTH_INFINITY ? file_storage::LOCK_INFINITE : $record['depth'];
return $lock;
}
/**
* Convert Chwala's lock data array into SabreDav LockInfo object
*/
public function to_lockinfo(array $lock)
{
$lockInfo = new LockInfo;
$lockInfo->uri = $this->path2uri($lock['uri']);
$lockInfo->owner = $lock['owner'];
$lockInfo->scope = $lock['scope'] == file_storage::LOCK_SHARED ? LockInfo::SHARED : LockInfo::EXCLUSIVE;
$lockInfo->depth = $lock['depth'] == file_storage::LOCK_INFINITE ? Server::DEPTH_INFINITY : $lock['depth'];
$lockInfo->token = $lock['token'];
$lockInfo->timeout = $lock['timeout'];
$lockInfo->created = $lock['created'];
return $lockInfo;
}
}
diff --git a/lib/Kolab/DAV/Node.php b/lib/Kolab/DAV/Node.php
index b8d3542..beba2a9 100644
--- a/lib/Kolab/DAV/Node.php
+++ b/lib/Kolab/DAV/Node.php
@@ -1,200 +1,196 @@
<?php
/**
* SabreDAV File Backend implementation for Kolab.
*
* @author Aleksander Machniak <machniak@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\DAV;
use \rcube;
use \rcube_mime;
use \Exception;
/**
* Node class
*/
class Node implements \Sabre\DAV\INode
{
/**
* The path to the current node
*
* @var string
*/
protected $path;
/**
* The file API backend class
*
- * @var file_api_storage
+ * @var Kolab\DAV\Backend
*/
protected $backend;
/**
* Internal node data (e.g. file parameters)
*
* @var array
*/
protected $data;
/**
* Parent node
*
* @var Kolab\DAV\Node
*/
protected $parent;
/**
* @brief Sets up the node, expects a full path name
* @param string $path Node name with path
* @param Kolab\DAV\Node $parent Parent node
* @param array $data Node data
*
* @return void
*/
public function __construct($path, $parent = null, $data = array())
{
$this->data = $data;
$this->path = $path;
$this->parent = $parent;
- $this->backend = Backend::get_instance()->get_backend();
+ $this->backend = Backend::get_instance();
if ($this->path == Collection::ROOT_DIRECTORY) {
$this->path = '';
}
else if (strpos($this->path, Collection::ROOT_DIRECTORY . '/') === 0) {
$this->path = substr($this->path, strlen(Collection::ROOT_DIRECTORY . '/'));
}
}
/**
* Returns the last modification time
*
* In this case, it will simply return the current time
*
* @return int
*/
public function getLastModified()
{
return $this->data['modified'] ? $this->data['modified'] : null;
}
/**
* Deletes the current node (folder)
*
* @throws Sabre\DAV\Exception\Forbidden
* @return void
*/
public function delete()
{
try {
$this->backend->folder_delete($this->path);
}
catch (Exception $e) {
throw new \Sabre\DAV\Exception\Forbidden($e->getMessage());
}
// reset cache
if ($this->parent) {
$this->parent->children = null;
}
}
/**
* Renames the node
*
* @throws Sabre\DAV\Exception\Forbidden
* @param string $name The new name
* @return void
*/
public function setName($name)
{
$path = explode('/', $this->path);
array_pop($path);
$newname = implode('/', $path) . '/' . $name;
$method = (is_a($this, 'Kolab\\DAV\\File') ? 'file' : 'folder') . '_move';
try {
$this->backend->$method($this->path, $newname);
}
catch (Exception $e) {
throw new \Sabre\DAV\Exception\Forbidden($e->getMessage());
}
// reset cache
if ($this->parent) {
$this->parent->children = null;
}
}
/**
* @brief Returns the name of the node
* @return string
*/
public function getName()
{
if ($this->path === '') {
return Collection::ROOT_DIRECTORY;
}
return array_pop(explode('/', $this->path));
}
/**
* Build file data array to pass into backend
*/
protected function fileData($name, $data = null)
{
if ($this->data && $this->data['type']) {
$type = $this->data['type'];
}
else {
$type = 'application/octet-stream';
}
// $data can be a resource or a string
if (is_resource($data)) {
+ rewind($data);
+
// $data can be php://input or php://temp
// php://input is not seekable, we need to "convert"
// it to seekable resource, fstat/rewind later will work
$meta = stream_get_meta_data($data);
if (!$meta['seekable']) {
$new_data = fopen('php://temp','r+');
stream_copy_to_stream($data, $new_data);
rewind($new_data);
$data = $new_data;
}
-
- $content = stream_get_contents($data, 1024000, 0);
- rewind($data);
- }
- else {
- $content = &$data;
}
$filedata = array(
'content' => $data,
- 'type' => rcube_mime::file_content_type($content, $name, $type, true),
+ 'type' => $type,
);
return $filedata;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 10, 1:32 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
197116
Default Alt Text
(21 KB)

Event Timeline