From 65f3b2fad235417d3f653c9e11aa8d72e8944d28 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 29 Apr 2014 15:14:48 +0200 Subject: [PATCH] Add server<->server sharing backend --- apps/files_external/lib/webdav.php | 14 ++-- apps/files_sharing/appinfo/app.php | 9 ++ apps/files_sharing/appinfo/database.xml | 83 +++++++++++++++++++ apps/files_sharing/appinfo/version | 2 +- apps/files_sharing/lib/external/cache.php | 47 +++++++++++ apps/files_sharing/lib/external/manager.php | 90 ++++++++++++++++++++ apps/files_sharing/lib/external/storage.php | 91 +++++++++++++++++++++ apps/files_sharing/lib/isharedstorage.php | 13 +++ lib/private/connector/sabre/directory.php | 3 +- lib/private/connector/sabre/objecttree.php | 2 +- lib/private/files/cache/cache.php | 10 +-- lib/private/helper.php | 2 +- lib/private/share/share.php | 2 +- 13 files changed, 351 insertions(+), 17 deletions(-) create mode 100644 apps/files_sharing/appinfo/database.xml create mode 100644 apps/files_sharing/lib/external/cache.php create mode 100644 apps/files_sharing/lib/external/manager.php create mode 100644 apps/files_sharing/lib/external/storage.php create mode 100644 apps/files_sharing/lib/isharedstorage.php diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 525f41c127..3614b05e97 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -9,13 +9,13 @@ namespace OC\Files\Storage; class DAV extends \OC\Files\Storage\Common { - private $password; - private $user; - private $host; - private $secure; - private $root; - private $certPath; - private $ready; + protected $password; + protected $user; + protected $host; + protected $secure; + protected $root; + protected $certPath; + protected $ready; /** * @var \Sabre\DAV\Client */ diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 6b40ba921c..9ea969f4cf 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -11,6 +11,15 @@ OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php OC::$CLASSPATH['OCA\Files\Share\Api'] = 'files_sharing/lib/api.php'; OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php'; OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php'; + +$externalManager = new \OCA\Files_Sharing\External\Manager( + \OC::$server->getDatabaseConnection(), + \OC\Files\Filesystem::getMountManager(), + \OC\Files\Filesystem::getLoader(), + \OC::$server->getUserSession() +); +$externalManager->setup(); + OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); diff --git a/apps/files_sharing/appinfo/database.xml b/apps/files_sharing/appinfo/database.xml new file mode 100644 index 0000000000..b9c0d881fc --- /dev/null +++ b/apps/files_sharing/appinfo/database.xml @@ -0,0 +1,83 @@ + + + *dbname* + true + false + utf8 + + *dbprefix*share_external + + + id + integer + 0 + true + 1 + 4 + + + remote + text + true + 128 + + + token + text + true + 64 + + + password + text + true + 64 + + + name + text + true + 64 + + + owner + text + true + 64 + + + user + text + true + 64 + + + mountpoint + text + true + 512 + + + mountpoint_hash + text + true + 32 + + + sh_external_user + + user + ascending + + + + sh_external_mp + true + + mountpoint_hash + ascending + + + +
+
diff --git a/apps/files_sharing/appinfo/version b/apps/files_sharing/appinfo/version index 2eb3c4fe4e..4b9fcbec10 100644 --- a/apps/files_sharing/appinfo/version +++ b/apps/files_sharing/appinfo/version @@ -1 +1 @@ -0.5 +0.5.1 diff --git a/apps/files_sharing/lib/external/cache.php b/apps/files_sharing/lib/external/cache.php new file mode 100644 index 0000000000..cd06bfb127 --- /dev/null +++ b/apps/files_sharing/lib/external/cache.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\External; + +class Cache extends \OC\Files\Cache\Cache { + private $remote; + private $remoteUser; + private $storage; + + /** + * @param \OCA\Files_Sharing\External\Storage $storage + * @param string $remote + * @param string $remoteUser + */ + public function __construct($storage, $remote, $remoteUser) { + $this->storage = $storage; + list(, $remote) = explode('://', $remote, 2); + $this->remote = $remote; + $this->remoteUser = $remoteUser; + parent::__construct($storage); + } + + public function get($file) { + $result = parent::get($file); + $result['displayname_owner'] = $this->remoteUser . '@' . $this->remote; + if (!$file || $file === '') { + $result['is_share_mount_point'] = true; + $mountPoint = rtrim($this->storage->getMountPoint()); + $result['name'] = basename($mountPoint); + } + return $result; + } + + public function getFolderContentsById($id) { + $results = parent::getFolderContentsById($id); + foreach ($results as &$file) { + $file['displayname_owner'] = $this->remoteUser . '@' . $this->remote; + } + return $results; + } +} diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php new file mode 100644 index 0000000000..ffb673723a --- /dev/null +++ b/apps/files_sharing/lib/external/manager.php @@ -0,0 +1,90 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\External; + +use OC\Files\Mount\Mount; + +class Manager { + const STORAGE = '\OCA\Files_Sharing\External\Storage'; + + /** + * @var \OCP\IDBConnection + */ + private $connection; + + /** + * @var \OC\Files\Mount\Manager + */ + private $mountManager; + + /** + * @var \OC\Files\Storage\Loader + */ + private $storageLoader; + + /** + * @var \OC\User\Session + */ + private $userSession; + + /** + * @param \OCP\IDBConnection $connection + * @param \OC\Files\Mount\Manager $mountManager + * @param \OC\User\Session $userSession + * @param \OC\Files\Storage\Loader $storageLoader + */ + public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager, + \OC\Files\Storage\Loader $storageLoader, \OC\User\Session $userSession) { + $this->connection = $connection; + $this->mountManager = $mountManager; + $this->userSession = $userSession; + $this->storageLoader = $storageLoader; + } + + public function setup() { + $user = $this->userSession->getUser(); + if ($user) { + $query = $this->connection->prepare('SELECT `remote`, `token`, `password`, `mountpoint`, `owner` + FROM *PREFIX*share_external WHERE `user` = ?'); + $query->execute(array($user->getUID())); + + while ($row = $query->fetch()) { + $row['manager'] = $this; + $mount = new Mount(self::STORAGE, $row['mountpoint'], $row, $this->storageLoader); + $this->mountManager->addMount($mount); + } + } + } + + /** + * @return \OC\Files\Mount\Manager + */ + public function getMountManager() { + return $this->mountManager; + } + + /** + * @param string $source + * @param string $target + * @return bool + */ + public function setMountPoint($source, $target) { + $sourceHash = md5($source); + $targetHash = md5($target); + + $query = $this->connection->prepare('UPDATE *PREFIX*share_external SET + `mountpoint` = ?, `mountpoint_hash` = ? WHERE `mountpoint_hash` = ?'); + $query->execute(array($target, $targetHash, $sourceHash)); + + $mount = $this->mountManager->find($source); + $mount->setMountPoint($target . '/'); + $this->mountManager->addMount($mount); + $this->mountManager->removeMount($source . '/'); + } +} diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php new file mode 100644 index 0000000000..2683a6a690 --- /dev/null +++ b/apps/files_sharing/lib/external/storage.php @@ -0,0 +1,91 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\External; + +use OC\Files\Filesystem; +use OCA\Files_Sharing\ISharedStorage; + +class Storage extends \OC\Files\Storage\DAV implements ISharedStorage { + /** + * @var string + */ + private $remoteUser; + + /** + * @var string + */ + private $remote; + + /** + * @var string + */ + private $mountPoint; + + /** + * @var \OCA\Files_Sharing\External\Manager + */ + private $manager; + + public function __construct($options) { + $this->remote = $options['remote']; + $this->remoteUser = $options['owner']; + $this->manager = $options['manager']; + list($protocol, $remote) = explode('://', $this->remote); + list($host, $root) = explode('/', $remote); + $secure = $protocol === 'https'; + $root .= '/public.php/webdav'; + $this->mountPoint = $options['mountpoint']; + parent::__construct(array( + 'secure' => $secure, + 'host' => $host, + 'root' => $root, + 'user' => $options['token'], + 'password' => $options['password'] + )); + } + + public function getRemoteUser() { + return $this->remoteUser; + } + + public function getRemote() { + return $this->remote; + } + + public function getMountPoint() { + return $this->mountPoint; + } + + /** + * @brief get id of the mount point + * @return string + */ + public function getId() { + return 'shared::' . md5($this->user . '@' . $this->remote); + } + + public function getCache($path = '') { + if (!isset($this->cache)) { + $this->cache = new Cache($this, $this->remote, $this->remoteUser); + } + return $this->cache; + } + + public function rename($path1, $path2) { + // if we renamed the mount point we need to adjust the mountpoint in the database + if (Filesystem::normalizePath($this->mountPoint) === Filesystem::normalizePath($path1)) { + $this->manager->setMountPoint($path1, $path2); + $this->mountPoint = $path2; + return true; + } else { + // read only shares + return false; + } + } +} diff --git a/apps/files_sharing/lib/isharedstorage.php b/apps/files_sharing/lib/isharedstorage.php new file mode 100644 index 0000000000..75e0afef39 --- /dev/null +++ b/apps/files_sharing/lib/isharedstorage.php @@ -0,0 +1,13 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing; + +interface ISharedStorage{ + +} diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index aa467cec53..9904c3525c 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -202,7 +202,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node * @return array */ public function getQuotaInfo() { - $storageInfo = OC_Helper::getStorageInfo($this->path); + $path = \OC\Files\Filesystem::getView()->getRelativePath($this->info->getPath()); + $storageInfo = OC_Helper::getStorageInfo($path); return array( $storageInfo['used'], $storageInfo['free'] diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index c55a392bca..2cadb5af52 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -117,7 +117,7 @@ class ObjectTree extends \Sabre\DAV\ObjectTree { $isShareMountPoint = false; list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath( '/' . \OCP\User::getUser() . '/files/' . $sourcePath); - if ($storage instanceof \OC\Files\Storage\Shared && !$internalPath) { + if ($storage instanceof \OCA\Files_Sharing\ISharedStorage && !$internalPath) { $isShareMountPoint = true; } diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index bfd280a91a..48c57e2e43 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -22,20 +22,20 @@ class Cache { /** * @var array partial data for the cache */ - private $partial = array(); + protected $partial = array(); /** * @var string */ - private $storageId; + protected $storageId; /** * @var Storage $storageCache */ - private $storageCache; + protected $storageCache; - private static $mimetypeIds = array(); - private static $mimetypes = array(); + protected static $mimetypeIds = array(); + protected static $mimetypes = array(); /** * @param \OC\Files\Storage\Storage|string $storage diff --git a/lib/private/helper.php b/lib/private/helper.php index 3e2c1db79d..243baa4694 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -940,7 +940,7 @@ class OC_Helper { // return storage info without adding mount points $includeExtStorage = \OC_Config::getValue('quota_include_external_storage', false); - if (is_null($rootInfo)) { + if (!$rootInfo) { $rootInfo = \OC\Files\Filesystem::getFileInfo($path, false); } $used = $rootInfo->getSize(); diff --git a/lib/private/share/share.php b/lib/private/share/share.php index a3de8ebc0e..0a4d9a913e 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -510,7 +510,7 @@ class Share extends \OC\Share\Constants { $mountManager = \OC\Files\Filesystem::getMountManager(); $mounts = $mountManager->getAll(); foreach ($mounts as $mountPoint => $mount) { - if ($mount->getStorage() instanceof \OC\Files\Storage\Shared && strpos($mountPoint, $path) === 0) { + if ($mount->getStorage() instanceof \OCA\Files_Sharing\ISharedStorage && strpos($mountPoint, $path) === 0) { $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!'; \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); throw new \Exception($message);