From 10c9b8eb996bcabbe4ef40c51248fd6fca70814a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 20 Mar 2014 16:15:18 +0100 Subject: [PATCH 1/3] Cache folder is now configurable When using an external cache folder, it is automatically mounted in FileSystem::initFileSystem so that any app can use it transparently by creating a view on the "/$user/cache" directory. --- config/config.sample.php | 13 +++++++++-- lib/private/cache/file.php | 15 +++++++------ lib/private/files/filesystem.php | 36 ++++++++++++++++++++++++++++++ lib/private/forbiddenexception.php | 16 +++++++++++++ 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 lib/private/forbiddenexception.php diff --git a/config/config.sample.php b/config/config.sample.php index 987a866e49..f8e216d1e2 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -273,6 +273,15 @@ $CONFIG = array( /* all css and js files will be served by the web server statically in one js file and ons css file*/ 'asset-pipeline.enabled' => false, - /* where mount.json file should be stored, defaults to data/mount.json */ - 'mount_file' => '', +/* where mount.json file should be stored, defaults to data/mount.json */ +'mount_file' => '', + +/* + * Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user. + * + * When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured + * cache directory and "$user" is the user. + * + */ +'cache_path' => '' ); diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php index 8a6ef39f61..be6805a9a5 100644 --- a/lib/private/cache/file.php +++ b/lib/private/cache/file.php @@ -1,6 +1,7 @@ + * Copyright (c) 2014 Vincent Petry * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -10,22 +11,22 @@ namespace OC\Cache; class File { protected $storage; + + /** + * Returns the cache storage for the logged in user + * @return cache storage + */ protected function getStorage() { if (isset($this->storage)) { return $this->storage; } if(\OC_User::isLoggedIn()) { \OC\Files\Filesystem::initMountPoints(\OC_User::getUser()); - $subdir = 'cache'; - $view = new \OC\Files\View('/' . \OC_User::getUser()); - if(!$view->file_exists($subdir)) { - $view->mkdir($subdir); - } - $this->storage = new \OC\Files\View('/' . \OC_User::getUser().'/'.$subdir); + $this->storage = new \OC\Files\View('/' . \OC_User::getUser() . '/cache'); return $this->storage; }else{ \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR); - return false; + throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in'); } } diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index c31e0c3818..56bafc7e97 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -321,10 +321,46 @@ class Filesystem { self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); } + self::mountCacheDir($user); + // Chance to mount for other storages \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); } + /** + * Mounts the cache directory + * @param string $user user name + */ + private static function mountCacheDir($user) { + $cacheBaseDir = \OC_Config::getValue('cache_path', ''); + if ($cacheBaseDir === '') { + // use local cache dir relative to the user's home + $subdir = 'cache'; + $view = new \OC\Files\View('/' . $user); + if(!$view->file_exists($subdir)) { + $view->mkdir($subdir); + } + } else { + $cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user; + if (!file_exists($cacheDir)) { + mkdir($cacheDir, 0770, true); + } + // mount external cache dir to "/$user/cache" mount point + self::mount('\OC\Files\Storage\Local', array('datadir' => $cacheDir), '/' . $user . '/cache'); + } + } + + /** + * fill in the correct values for $user + * + * @param string $user + * @param string $input + * @return string + */ + private static function setUserVars($user, $input) { + return str_replace('$user', $user, $input); + } + /** * get the default filesystem view * diff --git a/lib/private/forbiddenexception.php b/lib/private/forbiddenexception.php new file mode 100644 index 0000000000..14a4cd1498 --- /dev/null +++ b/lib/private/forbiddenexception.php @@ -0,0 +1,16 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +/** + * Exception thrown whenever access to a resource has + * been forbidden or whenever a user isn't authenticated. + */ +class ForbiddenException extends \Exception { +} From 1e39719926ea4b204a3b0a3e8aeba6a9a9ad5a96 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Mar 2014 14:32:04 +0100 Subject: [PATCH 2/3] Added unit tests for external cache folder --- tests/lib/files/filesystem.php | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 90f1dfe581..53f528af79 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -226,4 +226,55 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $path = $arguments['path']; $this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } + + /** + * Test that the default cache dir is part of the user's home + */ + public function testMountDefaultCacheDir() { + $userId = uniqid('user_'); + $oldCachePath = \OC_Config::getValue('cache_path', ''); + // no cache path configured + \OC_Config::setValue('cache_path', ''); + + \OC_User::createUser($userId, $userId); + \OC\Files\Filesystem::initMountPoints($userId); + + $this->assertEquals( + '/' . $userId . '/', + \OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache') + ); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache'); + $this->assertInstanceOf('\OC\Files\Storage\Home', $storage); + $this->assertEquals('cache', $internalPath); + \OC_User::deleteUser($userId); + + \OC_Config::setValue('cache_path', $oldCachePath); + } + + /** + * Test that an external cache is mounted into + * the user's home + */ + public function testMountExternalCacheDir() { + $userId = uniqid('user_'); + + $oldCachePath = \OC_Config::getValue('cache_path', ''); + // set cache path to temp dir + $cachePath = \OC_Helper::tmpFolder() . '/extcache'; + \OC_Config::setValue('cache_path', $cachePath); + + \OC_User::createUser($userId, $userId); + \OC\Files\Filesystem::initMountPoints($userId); + + $this->assertEquals( + '/' . $userId . '/cache/', + \OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache') + ); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache'); + $this->assertInstanceOf('\OC\Files\Storage\Local', $storage); + $this->assertEquals('', $internalPath); + \OC_User::deleteUser($userId); + + \OC_Config::setValue('cache_path', $oldCachePath); + } } From e76be308eb8e969b1a4b74d97c2ccb320a986937 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 26 Mar 2014 09:39:09 +0100 Subject: [PATCH 3/3] Remove unused setUserVars utility method That method was moved to the external storage recently so isn't needed here any more. --- lib/private/files/filesystem.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 56bafc7e97..7e27650c55 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -350,17 +350,6 @@ class Filesystem { } } - /** - * fill in the correct values for $user - * - * @param string $user - * @param string $input - * @return string - */ - private static function setUserVars($user, $input) { - return str_replace('$user', $user, $input); - } - /** * get the default filesystem view *