Merge pull request #9357 from owncloud/sharing_unshare_on_delete
[sharing] unshare childrens on delete
This commit is contained in:
commit
a544bd3a0f
|
@ -340,7 +340,7 @@ class Hooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* unshare file/folder from a user with whom you shared the file before
|
||||||
*/
|
*/
|
||||||
public static function postUnshare($params) {
|
public static function postUnshare($params) {
|
||||||
|
|
||||||
|
@ -385,8 +385,10 @@ class Hooks {
|
||||||
// Unshare every user who no longer has access to the file
|
// Unshare every user who no longer has access to the file
|
||||||
$delUsers = array_diff($userIds, $sharingUsers);
|
$delUsers = array_diff($userIds, $sharingUsers);
|
||||||
|
|
||||||
|
list($owner, $ownerPath) = $util->getUidAndFilename($path);
|
||||||
|
|
||||||
// delete share key
|
// delete share key
|
||||||
Keymanager::delShareKey($view, $delUsers, $path);
|
Keymanager::delShareKey($view, $delUsers, $ownerPath, $owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -441,7 +443,7 @@ class Hooks {
|
||||||
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
|
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
|
||||||
$pathOld = self::$renamedFiles[$params['oldpath']]['path'];
|
$pathOld = self::$renamedFiles[$params['oldpath']]['path'];
|
||||||
} else {
|
} else {
|
||||||
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::ERROR);
|
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,6 +597,7 @@ class Hooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* unmount file from yourself
|
||||||
* remember files/folders which get unmounted
|
* remember files/folders which get unmounted
|
||||||
*/
|
*/
|
||||||
public static function preUmount($params) {
|
public static function preUmount($params) {
|
||||||
|
@ -613,6 +616,9 @@ class Hooks {
|
||||||
'itemType' => $itemType);
|
'itemType' => $itemType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unmount file from yourself
|
||||||
|
*/
|
||||||
public static function postUmount($params) {
|
public static function postUmount($params) {
|
||||||
|
|
||||||
if (!isset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
|
if (!isset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
|
||||||
|
@ -642,7 +648,7 @@ class Hooks {
|
||||||
// check if the user still has access to the file, otherwise delete share key
|
// check if the user still has access to the file, otherwise delete share key
|
||||||
$sharingUsers = \OCP\Share::getUsersSharingFile($path, $user);
|
$sharingUsers = \OCP\Share::getUsersSharingFile($path, $user);
|
||||||
if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) {
|
if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) {
|
||||||
Keymanager::delShareKey($view, array(\OCP\User::getUser()), $path);
|
Keymanager::delShareKey($view, array(\OCP\User::getUser()), $path, $user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,17 +444,18 @@ class Keymanager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a single user's shareKey for a single file
|
* Delete a single user's shareKey for a single file
|
||||||
|
*
|
||||||
|
* @param \OC\Files\View $view relative to data/
|
||||||
|
* @param array $userIds list of users we want to remove
|
||||||
|
* @param string $filename the owners name of the file for which we want to remove the users relative to data/user/files
|
||||||
|
* @param string $owner owner of the file
|
||||||
*/
|
*/
|
||||||
public static function delShareKey(\OC\Files\View $view, $userIds, $filePath) {
|
public static function delShareKey($view, $userIds, $filename, $owner) {
|
||||||
|
|
||||||
$proxyStatus = \OC_FileProxy::$enabled;
|
$proxyStatus = \OC_FileProxy::$enabled;
|
||||||
\OC_FileProxy::$enabled = false;
|
\OC_FileProxy::$enabled = false;
|
||||||
|
|
||||||
$userId = Helper::getUser($filePath);
|
$util = new Util($view, $owner);
|
||||||
|
|
||||||
$util = new Util($view, $userId);
|
|
||||||
|
|
||||||
list($owner, $filename) = $util->getUidAndFilename($filePath);
|
|
||||||
|
|
||||||
if ($util->isSystemWideMountPoint($filename)) {
|
if ($util->isSystemWideMountPoint($filename)) {
|
||||||
$shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename);
|
$shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename);
|
||||||
|
|
|
@ -225,7 +225,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
|
||||||
$this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user3.shareKey', 'data');
|
$this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user3.shareKey', 'data');
|
||||||
|
|
||||||
// recursive delete share keys from user1 and user2
|
// recursive delete share keys from user1 and user2
|
||||||
Encryption\Keymanager::delShareKey($this->view, array('user1', 'user2', Test_Encryption_Keymanager::TEST_USER), '/folder1/');
|
Encryption\Keymanager::delShareKey($this->view, array('user1', 'user2', Test_Encryption_Keymanager::TEST_USER), '/folder1/', Test_Encryption_Keymanager::TEST_USER);
|
||||||
|
|
||||||
// check if share keys from user1 and user2 are deleted
|
// check if share keys from user1 and user2 are deleted
|
||||||
$this->assertFalse($this->view->file_exists(
|
$this->assertFalse($this->view->file_exists(
|
||||||
|
@ -274,7 +274,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
|
||||||
$this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data');
|
$this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data');
|
||||||
|
|
||||||
// recursive delete share keys from user1 and user2
|
// recursive delete share keys from user1 and user2
|
||||||
Encryption\Keymanager::delShareKey($this->view, array('user1', 'user2', Test_Encryption_Keymanager::TEST_USER), '/folder1/existingFile.txt');
|
Encryption\Keymanager::delShareKey($this->view, array('user1', 'user2', Test_Encryption_Keymanager::TEST_USER), '/folder1/existingFile.txt', Test_Encryption_Keymanager::TEST_USER);
|
||||||
|
|
||||||
// check if share keys from user1 and user2 are deleted
|
// check if share keys from user1 and user2 are deleted
|
||||||
$this->assertFalse($this->view->file_exists(
|
$this->assertFalse($this->view->file_exists(
|
||||||
|
|
|
@ -21,47 +21,43 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OCA\Files\Share;
|
namespace OCA\Files\Share;
|
||||||
|
use OCA\Files_Sharing\Helper;
|
||||||
|
|
||||||
class Proxy extends \OC_FileProxy {
|
class Proxy extends \OC_FileProxy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the deleted folder contains share mount points and move them
|
* check if the deleted folder contains share mount points and unshare them
|
||||||
* up to the parent
|
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*/
|
*/
|
||||||
public function preUnlink($path) {
|
public function preUnlink($path) {
|
||||||
$this->moveMountPointsUp($path);
|
$this->unshareChildren($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the deleted folder contains share mount points and move them
|
* check if the deleted folder contains share mount points and unshare them
|
||||||
* up to the parent
|
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*/
|
*/
|
||||||
public function preRmdir($path) {
|
public function preRmdir($path) {
|
||||||
$this->moveMountPointsUp($path);
|
$this->unshareChildren($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move share mount points up to the parent
|
* unshare shared items below the deleted folder
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*/
|
*/
|
||||||
private function moveMountPointsUp($path) {
|
private function unshareChildren($path) {
|
||||||
$view = new \OC\Files\View('/');
|
$view = new \OC\Files\View('/');
|
||||||
|
|
||||||
// find share mount points within $path and move them up to the parent folder
|
// find share mount points within $path and unmount them
|
||||||
// before we delete $path
|
|
||||||
$mountManager = \OC\Files\Filesystem::getMountManager();
|
$mountManager = \OC\Files\Filesystem::getMountManager();
|
||||||
$mountedShares = $mountManager->findIn($path);
|
$mountedShares = $mountManager->findIn($path);
|
||||||
foreach ($mountedShares as $mount) {
|
foreach ($mountedShares as $mount) {
|
||||||
if ($mount->getStorage()->instanceOfStorage('\OC\Files\Storage\Shared')) {
|
if ($mount->getStorage()->instanceOfStorage('OCA\Files_Sharing\ISharedStorage')) {
|
||||||
$mountPoint = $mount->getMountPoint();
|
$mountPoint = $mount->getMountPoint();
|
||||||
$mountPointName = $mount->getMountPointName();
|
$view->unlink($mountPoint);
|
||||||
$target = \OCA\Files_Sharing\Helper::generateUniqueTarget(dirname($path) . '/' . $mountPointName, array(), $view);
|
|
||||||
$view->rename($mountPoint, $target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,8 +143,10 @@ class SharedMount extends Mount implements MoveableMount {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function removeMount() {
|
public function removeMount() {
|
||||||
|
$mountManager = \OC\Files\Filesystem::getMountManager();
|
||||||
$storage = $this->getStorage();
|
$storage = $this->getStorage();
|
||||||
$result = \OCP\Share::unshareFromSelf($storage->getItemType(), $storage->getMountPoint());
|
$result = \OCP\Share::unshareFromSelf($storage->getItemType(), $storage->getMountPoint());
|
||||||
|
$mountManager->removeMount($this->mountPoint);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ class Test_Files_Sharing_Proxy extends Test_Files_Sharing_Base {
|
||||||
$this->filename = '/share-api-test';
|
$this->filename = '/share-api-test';
|
||||||
|
|
||||||
// save file with content
|
// save file with content
|
||||||
$this->view->file_put_contents($this->filename, $this->data);
|
|
||||||
$this->view->mkdir($this->folder);
|
$this->view->mkdir($this->folder);
|
||||||
$this->view->mkdir($this->folder . $this->subfolder);
|
$this->view->mkdir($this->folder . $this->subfolder);
|
||||||
$this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
|
$this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
|
||||||
|
@ -56,7 +55,6 @@ class Test_Files_Sharing_Proxy extends Test_Files_Sharing_Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
function tearDown() {
|
function tearDown() {
|
||||||
$this->view->unlink($this->filename);
|
|
||||||
$this->view->deleteAll($this->folder);
|
$this->view->deleteAll($this->folder);
|
||||||
|
|
||||||
self::$tempStorage = null;
|
self::$tempStorage = null;
|
||||||
|
@ -69,30 +67,33 @@ class Test_Files_Sharing_Proxy extends Test_Files_Sharing_Base {
|
||||||
*/
|
*/
|
||||||
function testpreUnlink() {
|
function testpreUnlink() {
|
||||||
|
|
||||||
$fileInfo1 = \OC\Files\Filesystem::getFileInfo($this->filename);
|
|
||||||
$fileInfo2 = \OC\Files\Filesystem::getFileInfo($this->folder);
|
$fileInfo2 = \OC\Files\Filesystem::getFileInfo($this->folder);
|
||||||
|
|
||||||
$result = \OCP\Share::shareItem('file', $fileInfo1->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
|
|
||||||
$this->assertTrue($result);
|
|
||||||
|
|
||||||
$result = \OCP\Share::shareItem('folder', $fileInfo2->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
|
$result = \OCP\Share::shareItem('folder', $fileInfo2->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
|
||||||
$this->assertTrue($result);
|
$this->assertTrue($result);
|
||||||
|
|
||||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||||
|
|
||||||
// move shared folder to 'localDir' and rename it, so that it uses the same
|
// one folder should be shared with the user
|
||||||
// name as the shared file
|
$sharedFolders = \OCP\Share::getItemsSharedWith('folder');
|
||||||
|
$this->assertSame(1, count($sharedFolders));
|
||||||
|
|
||||||
|
// move shared folder to 'localDir'
|
||||||
\OC\Files\Filesystem::mkdir('localDir');
|
\OC\Files\Filesystem::mkdir('localDir');
|
||||||
$result = \OC\Files\Filesystem::rename($this->folder, '/localDir/' . $this->filename);
|
$result = \OC\Files\Filesystem::rename($this->folder, '/localDir/' . $this->folder);
|
||||||
$this->assertTrue($result);
|
$this->assertTrue($result);
|
||||||
|
|
||||||
\OC\Files\Filesystem::unlink('localDir');
|
\OC\Files\Filesystem::unlink('localDir');
|
||||||
|
|
||||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||||
|
|
||||||
// after we deleted 'localDir' the share should be moved up to the root and be
|
// after the parent directory was deleted the share should be unshared
|
||||||
// renamed to "filename (2)"
|
$sharedFolders = \OCP\Share::getItemsSharedWith('folder');
|
||||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
|
$this->assertTrue(empty($sharedFolders));
|
||||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename . ' (2)' ));
|
|
||||||
|
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||||
|
|
||||||
|
// the folder for the owner should still exists
|
||||||
|
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->folder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test deletion of a folder which contains share mount points. Share mount
|
* test deletion of a folder which contains share mount points. Share mount
|
||||||
* points should move up to the parent before the folder gets deleted so
|
* points should be unshared before the folder gets deleted so
|
||||||
* that the mount point doesn't end up at the trash bin
|
* that the mount point doesn't end up at the trash bin
|
||||||
*/
|
*/
|
||||||
function testDeleteParentFolder() {
|
function testDeleteParentFolder() {
|
||||||
|
@ -78,6 +78,9 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base {
|
||||||
// check if user2 can see the shared folder
|
// check if user2 can see the shared folder
|
||||||
$this->assertTrue($view->file_exists($this->folder));
|
$this->assertTrue($view->file_exists($this->folder));
|
||||||
|
|
||||||
|
$foldersShared = \OCP\Share::getItemsSharedWith('folder');
|
||||||
|
$this->assertSame(1, count($foldersShared));
|
||||||
|
|
||||||
$view->mkdir("localFolder");
|
$view->mkdir("localFolder");
|
||||||
$view->file_put_contents("localFolder/localFile.txt", "local file");
|
$view->file_put_contents("localFolder/localFile.txt", "local file");
|
||||||
|
|
||||||
|
@ -91,8 +94,9 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base {
|
||||||
|
|
||||||
$this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
$this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||||
|
|
||||||
// mount point should move up again
|
// shared folder should be unshared
|
||||||
$this->assertTrue($view->file_exists($this->folder));
|
$foldersShared = \OCP\Share::getItemsSharedWith('folder');
|
||||||
|
$this->assertTrue(empty($foldersShared));
|
||||||
|
|
||||||
// trashbin should contain the local file but not the mount point
|
// trashbin should contain the local file but not the mount point
|
||||||
$rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
|
$rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
|
||||||
|
@ -109,10 +113,6 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base {
|
||||||
if ($status === false) {
|
if ($status === false) {
|
||||||
\OC_App::disable('files_trashbin');
|
\OC_App::disable('files_trashbin');
|
||||||
}
|
}
|
||||||
// cleanup
|
|
||||||
$this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
|
||||||
$result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
|
|
||||||
$this->assertTrue($result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -161,17 +161,27 @@ class View {
|
||||||
return $this->basicOperation('mkdir', $path, array('create', 'write'));
|
return $this->basicOperation('mkdir', $path, array('create', 'write'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove mount point
|
||||||
|
*
|
||||||
|
* @param \OC\Files\Mount\MoveableMount $mount
|
||||||
|
* @param string $path relative to data/
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
protected function removeMount($mount, $path){
|
protected function removeMount($mount, $path){
|
||||||
if ($mount instanceof MoveableMount) {
|
if ($mount instanceof MoveableMount) {
|
||||||
|
// cut of /user/files to get the relative path to data/user/files
|
||||||
|
$pathParts= explode('/', $path, 4);
|
||||||
|
$relPath = '/' . $pathParts[3];
|
||||||
\OC_Hook::emit(
|
\OC_Hook::emit(
|
||||||
Filesystem::CLASSNAME, "umount",
|
Filesystem::CLASSNAME, "umount",
|
||||||
array(Filesystem::signal_param_path => $path)
|
array(Filesystem::signal_param_path => $relPath)
|
||||||
);
|
);
|
||||||
$result = $mount->removeMount();
|
$result = $mount->removeMount();
|
||||||
if ($result) {
|
if ($result) {
|
||||||
\OC_Hook::emit(
|
\OC_Hook::emit(
|
||||||
Filesystem::CLASSNAME, "post_umount",
|
Filesystem::CLASSNAME, "post_umount",
|
||||||
array(Filesystem::signal_param_path => $path)
|
array(Filesystem::signal_param_path => $relPath)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -387,7 +397,7 @@ class View {
|
||||||
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
|
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
|
||||||
$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
|
$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
|
||||||
if ($mount->getInternalPath($absolutePath) === '') {
|
if ($mount->getInternalPath($absolutePath) === '') {
|
||||||
return $this->removeMount($mount, $path);
|
return $this->removeMount($mount, $absolutePath);
|
||||||
}
|
}
|
||||||
return $this->basicOperation('unlink', $path, array('delete'));
|
return $this->basicOperation('unlink', $path, array('delete'));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue