summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-06-12 14:03:37 +0200
committerVincent Petry <pvince81@owncloud.com>2015-06-12 14:03:37 +0200
commitda96cbbcd4e3c81374ef51f52ab6a546db02c02d (patch)
treee96a9bd37496009b17b929c85af61deb90448092
parentabd70932c6d86d56d225c7762b9e9a0cfedf8640 (diff)
parent5586b2db096f64623b4df76da560c48198c573df (diff)
downloadnextcloud-server-da96cbbcd4e3c81374ef51f52ab6a546db02c02d.tar.gz
nextcloud-server-da96cbbcd4e3c81374ef51f52ab6a546db02c02d.zip
Merge pull request #16884 from owncloud/issue-16843-stop-locking-encryption-key-storage
Do not lock the encryption key storage
-rw-r--r--lib/private/files/view.php74
-rw-r--r--tests/lib/files/view.php78
2 files changed, 135 insertions, 17 deletions
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index b98842f5eb7..a206eab54e4 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -1661,52 +1661,72 @@ class View {
/**
* @param string $path the path of the file to lock, relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @return bool False if the path is excluded from locking, true otherwise
+ * @throws \OCP\Lock\LockedException if the path is already locked
*/
private function lockPath($path, $type) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if (!$this->shouldLockFile($absolutePath)) {
+ return false;
+ }
+
$mount = $this->getMount($path);
if ($mount) {
$mount->getStorage()->acquireLock(
- $mount->getInternalPath(
- $this->getAbsolutePath($path)
- ),
+ $mount->getInternalPath($absolutePath),
$type,
$this->lockingProvider
);
}
+
+ return true;
}
/**
* @param string $path the path of the file to lock, relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @return bool False if the path is excluded from locking, true otherwise
+ * @throws \OCP\Lock\LockedException if the path is already locked
*/
private function changeLock($path, $type) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if (!$this->shouldLockFile($absolutePath)) {
+ return false;
+ }
+
$mount = $this->getMount($path);
if ($mount) {
$mount->getStorage()->changeLock(
- $mount->getInternalPath(
- $this->getAbsolutePath($path)
- ),
+ $mount->getInternalPath($absolutePath),
$type,
$this->lockingProvider
);
}
+
+ return true;
}
/**
* @param string $path the path of the file to unlock, relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @return bool False if the path is excluded from locking, true otherwise
*/
private function unlockPath($path, $type) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if (!$this->shouldLockFile($absolutePath)) {
+ return false;
+ }
+
$mount = $this->getMount($path);
if ($mount) {
$mount->getStorage()->releaseLock(
- $mount->getInternalPath(
- $this->getAbsolutePath($path)
- ),
+ $mount->getInternalPath($absolutePath),
$type,
$this->lockingProvider
);
}
+
+ return true;
}
/**
@@ -1714,15 +1734,24 @@ class View {
*
* @param string $path the path of the file to lock relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @return bool False if the path is excluded from locking, true otherwise
*/
public function lockFile($path, $type) {
$path = '/' . trim($path, '/');
+
+ $absolutePath = $this->getAbsolutePath($path);
+ if (!$this->shouldLockFile($absolutePath)) {
+ return false;
+ }
+
$this->lockPath($path, $type);
$parents = $this->getParents($path);
foreach ($parents as $parent) {
$this->lockPath($parent, ILockingProvider::LOCK_SHARED);
}
+
+ return true;
}
/**
@@ -1730,14 +1759,41 @@ class View {
*
* @param string $path the path of the file to lock relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @return bool False if the path is excluded from locking, true otherwise
*/
public function unlockFile($path, $type) {
$path = rtrim($path, '/');
+
+ $absolutePath = $this->getAbsolutePath($path);
+ if (!$this->shouldLockFile($absolutePath)) {
+ return false;
+ }
+
$this->unlockPath($path, $type);
$parents = $this->getParents($path);
foreach ($parents as $parent) {
$this->unlockPath($parent, ILockingProvider::LOCK_SHARED);
}
+
+ return true;
+ }
+
+ /**
+ * Only lock files in data/user/files/
+ *
+ * @param string $path Absolute path to the file/folder we try to (un)lock
+ * @return bool
+ */
+ protected function shouldLockFile($path) {
+ $path = Filesystem::normalizePath($path);
+
+ $pathSegments = explode('/', $path);
+ if (isset($pathSegments[2])) {
+ // E.g.: /username/files/path-to-file
+ return $pathSegments[2] === 'files';
+ }
+
+ return true;
}
}
diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php
index 06a42d63431..1050c36d292 100644
--- a/tests/lib/files/view.php
+++ b/tests/lib/files/view.php
@@ -1086,25 +1086,87 @@ class View extends \Test\TestCase {
* e.g. reading from a folder that's being renamed
*
* @expectedException \OCP\Lock\LockedException
+ *
+ * @dataProvider dataLockPaths
+ *
+ * @param string $rootPath
+ * @param string $pathPrefix
*/
- public function testReadFromWriteLockedPath() {
- $view = new \OC\Files\View();
+ public function testReadFromWriteLockedPath($rootPath, $pathPrefix) {
+ $rootPath = str_replace('{folder}', 'files', $rootPath);
+ $pathPrefix = str_replace('{folder}', 'files', $pathPrefix);
+
+ $view = new \OC\Files\View($rootPath);
$storage = new Temporary(array());
\OC\Files\Filesystem::mount($storage, [], '/');
- $view->lockFile('/foo/bar', ILockingProvider::LOCK_EXCLUSIVE);
- $view->lockFile('/foo/bar/asd', ILockingProvider::LOCK_SHARED);
+ $this->assertTrue($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
+ $view->lockFile($pathPrefix . '/foo/bar/asd', ILockingProvider::LOCK_SHARED);
+ }
+
+ /**
+ * Reading from a files_encryption folder that's being renamed
+ *
+ * @dataProvider dataLockPaths
+ *
+ * @param string $rootPath
+ * @param string $pathPrefix
+ */
+ public function testReadFromWriteUnlockablePath($rootPath, $pathPrefix) {
+ $rootPath = str_replace('{folder}', 'files_encryption', $rootPath);
+ $pathPrefix = str_replace('{folder}', 'files_encryption', $pathPrefix);
+
+ $view = new \OC\Files\View($rootPath);
+ $storage = new Temporary(array());
+ \OC\Files\Filesystem::mount($storage, [], '/');
+ $this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
+ $this->assertFalse($view->lockFile($pathPrefix . '/foo/bar/asd', ILockingProvider::LOCK_SHARED));
}
/**
* e.g. writing a file that's being downloaded
*
* @expectedException \OCP\Lock\LockedException
+ *
+ * @dataProvider dataLockPaths
+ *
+ * @param string $rootPath
+ * @param string $pathPrefix
*/
- public function testWriteToReadLockedFile() {
- $view = new \OC\Files\View();
+ public function testWriteToReadLockedFile($rootPath, $pathPrefix) {
+ $rootPath = str_replace('{folder}', 'files', $rootPath);
+ $pathPrefix = str_replace('{folder}', 'files', $pathPrefix);
+
+ $view = new \OC\Files\View($rootPath);
$storage = new Temporary(array());
\OC\Files\Filesystem::mount($storage, [], '/');
- $view->lockFile('/foo/bar', ILockingProvider::LOCK_SHARED);
- $view->lockFile('/foo/bar', ILockingProvider::LOCK_EXCLUSIVE);
+ $this->assertTrue($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_SHARED));
+ $view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE);
+ }
+
+ /**
+ * Writing a file that's being downloaded
+ *
+ * @dataProvider dataLockPaths
+ *
+ * @param string $rootPath
+ * @param string $pathPrefix
+ */
+ public function testWriteToReadUnlockableFile($rootPath, $pathPrefix) {
+ $rootPath = str_replace('{folder}', 'files_encryption', $rootPath);
+ $pathPrefix = str_replace('{folder}', 'files_encryption', $pathPrefix);
+
+ $view = new \OC\Files\View($rootPath);
+ $storage = new Temporary(array());
+ \OC\Files\Filesystem::mount($storage, [], '/');
+ $this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_SHARED));
+ $this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
+ }
+
+ public function dataLockPaths() {
+ return [
+ ['/testuser/{folder}', ''],
+ ['/testuser', '/{folder}'],
+ ['', '/testuser/{folder}'],
+ ];
}
}