Merge pull request #16884 from owncloud/issue-16843-stop-locking-encryption-key-storage

Do not lock the encryption key storage
This commit is contained in:
Vincent Petry 2015-06-12 14:03:37 +02:00
commit da96cbbcd4
2 changed files with 135 additions and 17 deletions

View File

@ -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;
}
}

View File

@ -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}'],
];
}
}