Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check trashbin perms before moving to trash #29820

Merged
merged 2 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion apps/files_trashbin/lib/Trashbin.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,23 @@ public static function getLocation($user, $filename, $timestamp) {
}
}

/**
* Sets up the trashbin for the given user
*
* @param string $user user id
* @return bool true if trashbin is setup and usable, false otherwise
*/
private static function setUpTrash($user) {
$view = new View('/' . $user);
if (!$view->is_dir('files_trashbin')) {
$view->mkdir('files_trashbin');
}

if (!$view->isUpdatable('files_trashbin')) {
// no trashbin access or denied
return false;
}

if (!$view->is_dir('files_trashbin/files')) {
$view->mkdir('files_trashbin/files');
}
Expand All @@ -155,6 +167,8 @@ private static function setUpTrash($user) {
if (!$view->is_dir('files_trashbin/keys')) {
$view->mkdir('files_trashbin/keys');
}

return true;
}


Expand Down Expand Up @@ -249,7 +263,14 @@ public static function move2trash($file_path) {
return true;
}

self::setUpTrash($user);
if (!self::setUpTrash($user)) {
// trashbin not usable for user (ex: guest), switch to owner only
$user = $owner;
if (!self::setUpTrash($owner)) {
// nothing to do as no trash is available anywheree
return true;
}
}
if ($owner !== $user) {
// also setup for owner
self::setUpTrash($owner);
Expand Down
103 changes: 103 additions & 0 deletions apps/files_trashbin/tests/StorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,109 @@ public function testCrossStorageDeleteFolder() {
$this->assertEquals('subfile.txt', $name);
}

/**
* Test that deleted folder appear in the trashbin of both owner and recipient
*/
public function testDeleteFolderAsRecipient() {
$this->userView->mkdir('share');
$this->userView->mkdir('share/folder');
$this->userView->file_put_contents('share/folder/test.txt', 'Yarrr! Content!');

$originalFileId = $this->userView->getFileInfo('share/folder/test.txt')->getId();

$recipientUser = $this->getUniqueId('recipient_');
\OC::$server->getUserManager()->createUser($recipientUser, $recipientUser);

$node = \OC::$server->getUserFolder($this->user)->get('share');
$share = \OC::$server->getShareManager()->newShare();
$share->setNode($node)
->setShareType(\OCP\Share::SHARE_TYPE_USER)
->setSharedBy($this->user)
->setSharedWith($recipientUser)
->setPermissions(\OCP\Constants::PERMISSION_ALL);
\OC::$server->getShareManager()->createShare($share);

$this->loginAsUser($recipientUser);

// delete as recipient
$recipientView = new View('/' . $recipientUser . '/files');
$recipientView->rmdir('share/folder');

// check if folder is in trashbin for owner
$results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/');
$this->assertCount(1, $results);
$name = $results[0]->getName();
$this->assertEquals('folder', substr($name, 0, strrpos($name, '.')));

// check if file is in trashbin for owner and has the same file id
$info = $this->rootView->getFileInfo($this->user . '/files_trashbin/files/' . $name . '/test.txt');
$this->assertNotNull($info);
$this->assertEquals($originalFileId, $info->getId());

// check if folder is in trashbin for recipient
$results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/files/');
$this->assertCount(1, $results);
$name = $results[0]->getName();
$this->assertEquals('folder', substr($name, 0, strrpos($name, '.')));

// check if file has a copy in trashbin for recipient (different file id)
$info = $this->rootView->getFileInfo($recipientUser . '/files_trashbin/files/' . $name . '/test.txt');
$this->assertNotNull($info);
$this->assertNotEquals($originalFileId, $info->getId());
}

/**
* Test that deleted folder appear only in the trashbin of owner when recipient
* has a read-only access home storage
*/
public function testDeleteFolderAsReadOnlyRecipient() {
$readOnlyGroups = \OC::$server->getConfig()->getAppValue('core', 'read_only_groups', null);
\OC::$server->getConfig()->setAppValue('core', 'read_only_groups', '["rogroup"]');

$this->userView->mkdir('share');
$this->userView->mkdir('share/folder');
$this->userView->file_put_contents('share/folder/test.txt', 'Yarrr! Content!');

$originalFileId = $this->userView->getFileInfo('share/folder/test.txt')->getId();

$recipientUser = $this->getUniqueId('recipient_');
$recipientUserObject = \OC::$server->getUserManager()->createUser($recipientUser, $recipientUser);
$roGroupObject = \OC::$server->getGroupManager()->createGroup('rogroup');
$roGroupObject->addUser($recipientUserObject);

$node = \OC::$server->getUserFolder($this->user)->get('share');
$share = \OC::$server->getShareManager()->newShare();
$share->setNode($node)
->setShareType(\OCP\Share::SHARE_TYPE_USER)
->setSharedBy($this->user)
->setSharedWith($recipientUser)
->setPermissions(\OCP\Constants::PERMISSION_ALL);
\OC::$server->getShareManager()->createShare($share);

$this->loginAsUser($recipientUser);

// delete as recipient
$recipientView = new View('/' . $recipientUser . '/files');
$recipientView->rmdir('share/folder');

// check if folder is in trashbin for owner
$results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/');
$this->assertCount(1, $results);
$name = $results[0]->getName();
$this->assertEquals('folder', substr($name, 0, strrpos($name, '.')));

// check if file is in trashbin for owner and has the same file id
$info = $this->rootView->getFileInfo($this->user . '/files_trashbin/files/' . $name . '/test.txt');
$this->assertNotNull($info);
$this->assertEquals($originalFileId, $info->getId());

// check that folder is NOT in trashbin for recipient
$this->assertFalse($this->rootView->file_exists($recipientUser . '/files_trashbin'));

\OC::$server->getConfig()->setAppValue('core', 'read_only_groups', $readOnlyGroups);
$roGroupObject->delete();
}

/**
* Test that deleted versions properly land in the trashbin.
*/
Expand Down
7 changes: 7 additions & 0 deletions lib/private/Files/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ public function get($file) {
$data['storage_mtime'] = $data['mtime'];
}
$data['permissions'] = (int)$data['permissions'];
// Oracle stores empty strings as null...
if (is_null($data['name'])) {
$data['name'] = '';
}
if (is_null($data['path'])) {
$data['path'] = '';
}
return new CacheEntry($data);
} else if (!$data and is_string($file)) {
if (isset($this->partial[$file])) {
Expand Down