Merge pull request #10107 from owncloud/sharing_group_shares
[sharing] group shares
This commit is contained in:
commit
8c8e5c168e
|
@ -12,6 +12,9 @@ OC::$CLASSPATH['OCA\Files\Share\Api'] = 'files_sharing/lib/api.php';
|
|||
OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
|
||||
OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
|
||||
|
||||
// Exceptions
|
||||
OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
|
||||
|
||||
\OCP\App::registerAdmin('files_sharing', 'settings-admin');
|
||||
|
||||
\OCA\Files_Sharing\Helper::registerHooks();
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Bjoern Schiessle
|
||||
* @copyright 2014 Bjoern Schiessle <schiessle@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Sharing\Exceptions;
|
||||
|
||||
/**
|
||||
* Expected path with a different root
|
||||
* Possible Error Codes:
|
||||
* 10 - Path not relative to data/ and point to the users file directory
|
||||
|
||||
*/
|
||||
class BrokenPath extends \Exception {
|
||||
}
|
|
@ -38,7 +38,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
// FIXME: attributes should not be set here,
|
||||
// keeping this pattern for now to avoid unexpected
|
||||
// regressions
|
||||
$this->path = basename($path);
|
||||
$this->path = \OC\Files\Filesystem::normalizePath(basename($path));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -57,7 +57,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
* create unique target
|
||||
* @param string $filePath
|
||||
* @param string $shareWith
|
||||
* @param string $exclude
|
||||
* @param array $exclude (optional)
|
||||
* @return string
|
||||
*/
|
||||
public function generateTarget($filePath, $shareWith, $exclude = null) {
|
||||
|
@ -83,10 +83,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
}
|
||||
}
|
||||
|
||||
$excludeList = \OCP\Share::getItemsSharedWithUser('file', $shareWith, self::FORMAT_TARGET_NAMES);
|
||||
if (is_array($exclude)) {
|
||||
$excludeList = array_merge($excludeList, $exclude);
|
||||
}
|
||||
$excludeList = (is_array($exclude)) ? $exclude : array();
|
||||
|
||||
return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class SharedMount extends Mount implements MoveableMount {
|
|||
* update fileTarget in the database if the mount point changed
|
||||
* @param string $newPath
|
||||
* @param array $share reference to the share which should be modified
|
||||
* @return type
|
||||
* @return bool
|
||||
*/
|
||||
private static function updateFileTarget($newPath, &$share) {
|
||||
// if the user renames a mount point from a group share we need to create a new db entry
|
||||
|
@ -91,7 +91,7 @@ class SharedMount extends Mount implements MoveableMount {
|
|||
* @param string $path the absolute path
|
||||
* @return string e.g. turns '/admin/files/test.txt' into '/test.txt'
|
||||
*/
|
||||
private function stripUserFilesPath($path) {
|
||||
protected function stripUserFilesPath($path) {
|
||||
$trimmed = ltrim($path, '/');
|
||||
$split = explode('/', $trimmed);
|
||||
|
||||
|
@ -99,8 +99,8 @@ class SharedMount extends Mount implements MoveableMount {
|
|||
if (count($split) < 3 || $split[1] !== 'files') {
|
||||
\OCP\Util::writeLog('file sharing',
|
||||
'Can not strip userid and "files/" from path: ' . $path,
|
||||
\OCP\Util::DEBUG);
|
||||
return false;
|
||||
\OCP\Util::ERROR);
|
||||
throw new \OCA\Files_Sharing\Exceptions\BrokenPath('Path does not start with /user/files', 10);
|
||||
}
|
||||
|
||||
// skip 'user' and 'files'
|
||||
|
@ -121,7 +121,15 @@ class SharedMount extends Mount implements MoveableMount {
|
|||
$relTargetPath = $this->stripUserFilesPath($target);
|
||||
$share = $this->storage->getShare();
|
||||
|
||||
$result = $this->updateFileTarget($relTargetPath, $share);
|
||||
$result = true;
|
||||
|
||||
if (!empty($share['grouped'])) {
|
||||
foreach ($share['grouped'] as $s) {
|
||||
$result = $this->updateFileTarget($relTargetPath, $s) && $result;
|
||||
}
|
||||
} else {
|
||||
$result = $this->updateFileTarget($relTargetPath, $share) && $result;
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$this->setMountPoint($target);
|
||||
|
@ -144,8 +152,9 @@ class SharedMount extends Mount implements MoveableMount {
|
|||
*/
|
||||
public function removeMount() {
|
||||
$mountManager = \OC\Files\Filesystem::getMountManager();
|
||||
/** @var \OC\Files\Storage\Shared */
|
||||
$storage = $this->getStorage();
|
||||
$result = \OCP\Share::unshareFromSelf($storage->getItemType(), $storage->getMountPoint());
|
||||
$result = $storage->unshareStorage();
|
||||
$mountManager->removeMount($this->mountPoint);
|
||||
|
||||
return $result;
|
||||
|
|
|
@ -532,4 +532,21 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* unshare complete storage, also the grouped shares
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function unshareStorage() {
|
||||
$result = true;
|
||||
if (!empty($this->share['grouped'])) {
|
||||
foreach ($this->share['grouped'] as $share) {
|
||||
$result = $result && \OCP\Share::unshareFromSelf($share['item_type'], $share['file_target']);
|
||||
}
|
||||
}
|
||||
$result = $result && \OCP\Share::unshareFromSelf($this->getItemType(), $this->getMountPoint());
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {
|
|||
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
|
||||
const TEST_FILES_SHARING_API_USER3 = "test-share-user3";
|
||||
|
||||
const TEST_FILES_SHARING_API_GROUP1 = "test-share-group1";
|
||||
|
||||
public $stateFilesEncryption;
|
||||
public $filename;
|
||||
public $data;
|
||||
|
@ -60,6 +62,10 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {
|
|||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2, true);
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER3, true);
|
||||
|
||||
// create group
|
||||
\OC_Group::createGroup(self::TEST_FILES_SHARING_API_GROUP1);
|
||||
\OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_GROUP1);
|
||||
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
|
@ -86,6 +92,9 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {
|
|||
} else {
|
||||
\OC_App::disable('files_encryption');
|
||||
}
|
||||
|
||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share`');
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass() {
|
||||
|
@ -94,6 +103,9 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {
|
|||
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER3);
|
||||
|
||||
// delete group
|
||||
\OC_Group::deleteGroup(self::TEST_FILES_SHARING_API_GROUP1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,6 +57,10 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
|
||||
self::$tempStorage = null;
|
||||
|
||||
// clear database table
|
||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share`');
|
||||
$query->execute();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
|
@ -68,10 +72,6 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
|
||||
$fileinfo = $this->view->getFileInfo($this->filename);
|
||||
|
||||
$pathinfo = pathinfo($this->filename);
|
||||
|
||||
$duplicate = '/' . $pathinfo['filename'] . ' (2).' . $pathinfo['extension'];
|
||||
|
||||
$result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, 31);
|
||||
|
||||
|
@ -84,47 +84,146 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
\OC\Files\Filesystem::unlink($this->filename);
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
// both group share and user share should be gone
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
|
||||
// for user3 nothing should change
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
}
|
||||
|
||||
/**
|
||||
* if a file was shared as group share and as individual share they should be grouped
|
||||
*/
|
||||
function testGroupingOfShares() {
|
||||
|
||||
$fileinfo = $this->view->getFileInfo($this->filename);
|
||||
|
||||
$result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
|
||||
\Test_Files_Sharing::TEST_FILES_SHARING_API_GROUP1, \OCP\PERMISSION_READ);
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_UPDATE);
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
\OC\Files\Filesystem::unlink($duplicate);
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
|
||||
// for user3 nothing should change
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
|
||||
$this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
|
||||
$this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate));
|
||||
$result = \OCP\Share::getItemSharedWith('file', null);
|
||||
|
||||
$this->assertTrue(is_array($result));
|
||||
|
||||
// test should return exactly one shares created from testCreateShare()
|
||||
$this->assertSame(1, count($result));
|
||||
|
||||
$share = reset($result);
|
||||
$this->assertSame(\OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE, $share['permissions']);
|
||||
|
||||
\OC\Files\Filesystem::rename($this->filename, $this->filename . '-renamed');
|
||||
|
||||
$result = \OCP\Share::getItemSharedWith('file', null);
|
||||
|
||||
$this->assertTrue(is_array($result));
|
||||
|
||||
// test should return exactly one shares created from testCreateShare()
|
||||
$this->assertSame(1, count($result));
|
||||
|
||||
$share = reset($result);
|
||||
$this->assertSame(\OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE, $share['permissions']);
|
||||
$this->assertSame($this->filename . '-renamed', $share['file_target']);
|
||||
|
||||
//cleanup
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
\OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
|
||||
'testGroup');
|
||||
\OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
self::TEST_FILES_SHARING_API_USER2);
|
||||
\OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
|
||||
\OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
|
||||
\OC_Group::deleteGroup('testGroup');
|
||||
|
||||
// unshare user share
|
||||
$result = \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2);
|
||||
$this->assertTrue($result);
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
|
||||
$result = \OCP\Share::getItemSharedWith('file', null);
|
||||
|
||||
$this->assertTrue(is_array($result));
|
||||
|
||||
// test should return the remaining group share
|
||||
$this->assertSame(1, count($result));
|
||||
|
||||
$share = reset($result);
|
||||
// only the group share permissions should be available now
|
||||
$this->assertSame(\OCP\PERMISSION_READ, $share['permissions']);
|
||||
$this->assertSame($this->filename . '-renamed', $share['file_target']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* user1 share file to a group and to a user2 in the same group. Then user2
|
||||
* unshares the file from self. Afterwards user1 should no longer see the
|
||||
* single user share to user2. If he re-shares the file to user2 the same target
|
||||
* then the group share should be used to group the item
|
||||
*/
|
||||
function testShareAndUnshareFromSelf() {
|
||||
$fileinfo = $this->view->getFileInfo($this->filename);
|
||||
|
||||
// share the file to group1 (user2 is a member of this group) and explicitely to user2
|
||||
\OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1, \OCP\PERMISSION_ALL);
|
||||
\OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL);
|
||||
|
||||
// user1 should have to shared files
|
||||
$shares = \OCP\Share::getItemsShared('file');
|
||||
$this->assertSame(2, count($shares));
|
||||
|
||||
// user2 should have two files "welcome.txt" and the shared file,
|
||||
// both the group share and the single share of the same file should be
|
||||
// grouped to one file
|
||||
\Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
$dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
|
||||
$this->assertSame(2, count($dirContent));
|
||||
$this->verifyDirContent($dirContent, array('welcome.txt', ltrim($this->filename, '/')));
|
||||
|
||||
// now user2 deletes the share (= unshare from self)
|
||||
\OC\Files\Filesystem::unlink($this->filename);
|
||||
|
||||
// only welcome.txt should exists
|
||||
$dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
|
||||
$this->assertSame(1, count($dirContent));
|
||||
$this->verifyDirContent($dirContent, array('welcome.txt'));
|
||||
|
||||
// login as user1...
|
||||
\Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
|
||||
// ... now user1 should have only one shared file, the group share
|
||||
$shares = \OCP\Share::getItemsShared('file');
|
||||
$this->assertSame(1, count($shares));
|
||||
|
||||
// user1 shares a gain the file directly to user2
|
||||
\OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL);
|
||||
|
||||
// user2 should see again welcome.txt and the shared file
|
||||
\Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
$dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
|
||||
$this->assertSame(2, count($dirContent));
|
||||
$this->verifyDirContent($dirContent, array('welcome.txt', ltrim($this->filename, '/')));
|
||||
|
||||
|
||||
}
|
||||
|
||||
function verifyDirContent($content, $expected) {
|
||||
foreach ($content as $c) {
|
||||
if (!in_array($c['name'], $expected)) {
|
||||
$this->assertTrue(false, "folder should only contain '" . implode(',', $expected) . "', found: " .$c['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testShareWithDifferentShareFolder() {
|
||||
|
||||
$fileinfo = $this->view->getFileInfo($this->filename);
|
||||
|
@ -146,12 +245,6 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
$this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/subfolder/' . $this->folder));
|
||||
|
||||
//cleanup
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
\OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
self::TEST_FILES_SHARING_API_USER2);
|
||||
\OCP\Share::unshare('folder', $folderinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
self::TEST_FILES_SHARING_API_USER2);
|
||||
|
||||
\OCP\Config::deleteSystemValue('share_folder');
|
||||
}
|
||||
|
||||
|
@ -173,18 +266,14 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
$this->assertTrue(is_array($result));
|
||||
|
||||
// test should return exactly one shares created from testCreateShare()
|
||||
$this->assertTrue(count($result) === 1);
|
||||
$this->assertSame(1, count($result), 'more then one share found');
|
||||
|
||||
$share = reset($result);
|
||||
$this->assertSame($expectedPermissions, $share['permissions']);
|
||||
|
||||
\OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||
\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2);
|
||||
}
|
||||
|
||||
function DataProviderTestFileSharePermissions() {
|
||||
$permission1 = \OCP\PERMISSION_ALL;
|
||||
$permission2 = \OCP\PERMISSION_DELETE;
|
||||
$permission3 = \OCP\PERMISSION_READ;
|
||||
$permission4 = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE;
|
||||
$permission5 = \OCP\PERMISSION_READ | \OCP\PERMISSION_DELETE;
|
||||
|
@ -192,7 +281,6 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base {
|
|||
|
||||
return array(
|
||||
array($permission1, \OCP\PERMISSION_ALL & ~\OCP\PERMISSION_DELETE),
|
||||
array($permission2, 0),
|
||||
array($permission3, $permission3),
|
||||
array($permission4, $permission4),
|
||||
array($permission5, $permission3),
|
||||
|
|
|
@ -194,4 +194,41 @@ class Test_Files_Sharing_Mount extends Test_Files_Sharing_Base {
|
|||
\OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderTestStripUserFilesPath
|
||||
* @param string $path
|
||||
* @param string $expectedResult
|
||||
* @param bool $exception if a exception is expected
|
||||
*/
|
||||
function testStripUserFilesPath($path, $expectedResult, $exception) {
|
||||
$testClass = new DummyTestClassSharedMount(null, null);
|
||||
try {
|
||||
$result = $testClass->stripUserFilesPathDummy($path);
|
||||
$this->assertSame($expectedResult, $result);
|
||||
} catch (\Exception $e) {
|
||||
if ($exception) {
|
||||
$this->assertSame(10, $e->getCode());
|
||||
} else {
|
||||
$this->assertTrue(false, "Exception catched, but expected: " . $expectedResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dataProviderTestStripUserFilesPath() {
|
||||
return array(
|
||||
array('/user/files/foo.txt', '/foo.txt', false),
|
||||
array('/user/files/folder/foo.txt', '/folder/foo.txt', false),
|
||||
array('/data/user/files/foo.txt', null, true),
|
||||
array('/data/user/files/', null, true),
|
||||
array('/files/foo.txt', null, true),
|
||||
array('/foo.txt', null, true),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DummyTestClassSharedMount extends \OCA\Files_Sharing\SharedMount {
|
||||
public function stripUserFilesPathDummy($path) {
|
||||
return $this->stripUserFilesPath($path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ class Helper extends \OC\Share\Constants {
|
|||
* @throws \Exception
|
||||
* @return string Item target
|
||||
*/
|
||||
public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
||||
$suggestedTarget = null, $groupParent = null) {
|
||||
public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
|
||||
// FIXME: $uidOwner and $groupParent seems to be unused
|
||||
$backend = \OC\Share\Share::getBackend($itemType);
|
||||
if ($shareType == self::SHARE_TYPE_LINK) {
|
||||
if (isset($suggestedTarget)) {
|
||||
|
@ -54,102 +54,41 @@ class Helper extends \OC\Share\Constants {
|
|||
if ($shareType == self::SHARE_TYPE_USER) {
|
||||
// Share with is a user, so set share type to user and groups
|
||||
$shareType = self::$shareTypeUserAndGroups;
|
||||
$userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
|
||||
} else {
|
||||
$userAndGroups = false;
|
||||
}
|
||||
$exclude = null;
|
||||
// Backend has 3 opportunities to generate a unique target
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
// Check if suggested target exists first
|
||||
if ($i == 0 && isset($suggestedTarget)) {
|
||||
$target = $suggestedTarget;
|
||||
} else {
|
||||
if ($shareType == self::SHARE_TYPE_GROUP) {
|
||||
$target = $backend->generateTarget($itemSource, false, $exclude);
|
||||
} else {
|
||||
$target = $backend->generateTarget($itemSource, $shareWith, $exclude);
|
||||
}
|
||||
if (is_array($exclude) && in_array($target, $exclude)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check if target already exists
|
||||
$checkTarget = \OC\Share\Share::getItems($itemType, $target, $shareType, $shareWith);
|
||||
if (!empty($checkTarget)) {
|
||||
foreach ($checkTarget as $item) {
|
||||
// Skip item if it is the group parent row
|
||||
if (isset($groupParent) && $item['id'] == $groupParent) {
|
||||
if (count($checkTarget) == 1) {
|
||||
return $target;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($item['uid_owner'] == $uidOwner) {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($itemSource);
|
||||
if ($item['file_source'] == $meta['fileid']) {
|
||||
return $target;
|
||||
}
|
||||
} else if ($item['item_source'] == $itemSource) {
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($exclude)) {
|
||||
$exclude = array();
|
||||
}
|
||||
// Find similar targets to improve backend's chances to generate a unqiue target
|
||||
if ($userAndGroups) {
|
||||
if ($column == 'file_target') {
|
||||
$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
|
||||
.' WHERE `item_type` IN (\'file\', \'folder\')'
|
||||
.' AND `share_type` IN (?,?,?)'
|
||||
.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
|
||||
$result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
|
||||
self::$shareTypeGroupUserUnique));
|
||||
} else {
|
||||
$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
|
||||
.' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
|
||||
.' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
|
||||
$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
|
||||
self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
|
||||
}
|
||||
} else {
|
||||
if ($column == 'file_target') {
|
||||
$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
|
||||
.' WHERE `item_type` IN (\'file\', \'folder\')'
|
||||
.' AND `share_type` = ? AND `share_with` = ?');
|
||||
$result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
|
||||
} else {
|
||||
$checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
|
||||
.' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
|
||||
$result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
|
||||
}
|
||||
}
|
||||
while ($row = $result->fetchRow()) {
|
||||
|
||||
$result = \OCP\Share::getItemsSharedWithUser($itemType, $shareWith);
|
||||
foreach ($result as $row) {
|
||||
if ($row['permissions'] > 0) {
|
||||
$exclude[] = $row[$column];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if suggested target exists first
|
||||
if (!isset($suggestedTarget)) {
|
||||
$suggestedTarget = $itemSource;
|
||||
}
|
||||
if ($shareType == self::SHARE_TYPE_GROUP) {
|
||||
$target = $backend->generateTarget($suggestedTarget, false, $exclude);
|
||||
} else {
|
||||
$target = $backend->generateTarget($suggestedTarget, $shareWith, $exclude);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
}
|
||||
$message = 'Sharing backend registered for '.$itemType.' did not generate a unique target for '.$itemSource;
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
throw new \Exception($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all reshares of an item
|
||||
* @param int $parent Id of item to delete
|
||||
* @param bool $excludeParent If true, exclude the parent from the delete (optional)
|
||||
* @param string $uidOwner The user that the parent was shared with (optional)
|
||||
* @param int $newParent new parent for the childrens
|
||||
*/
|
||||
public static function delete($parent, $excludeParent = false, $uidOwner = null) {
|
||||
public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null) {
|
||||
$ids = array($parent);
|
||||
$deletedItems = array();
|
||||
$changeParent = array();
|
||||
$parents = array($parent);
|
||||
while (!empty($parents)) {
|
||||
$parents = "'".implode("','", $parents)."'";
|
||||
|
@ -167,8 +106,6 @@ class Helper extends \OC\Share\Constants {
|
|||
// Reset parents array, only go through loop again if items are found
|
||||
$parents = array();
|
||||
while ($item = $result->fetchRow()) {
|
||||
$ids[] = $item['id'];
|
||||
$parents[] = $item['id'];
|
||||
$tmpItem = array(
|
||||
'id' => $item['id'],
|
||||
'shareWith' => $item['share_with'],
|
||||
|
@ -179,12 +116,28 @@ class Helper extends \OC\Share\Constants {
|
|||
if (isset($item['file_target'])) {
|
||||
$tmpItem['fileTarget'] = $item['file_target'];
|
||||
}
|
||||
// if we have a new parent for the child we remember the child
|
||||
// to update the parent, if not we add it to the list of items
|
||||
// which should be deleted
|
||||
if ($newParent !== null) {
|
||||
$changeParent[] = $item['id'];
|
||||
} else {
|
||||
$deletedItems[] = $tmpItem;
|
||||
$ids[] = $item['id'];
|
||||
$parents[] = $item['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($excludeParent) {
|
||||
unset($ids[0]);
|
||||
}
|
||||
|
||||
if (!empty($changeParent)) {
|
||||
$idList = "'".implode("','", $changeParent)."'";
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
|
||||
$query->execute(array($newParent));
|
||||
}
|
||||
|
||||
if (!empty($ids)) {
|
||||
$idList = "'".implode("','", $ids)."'";
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
|
||||
|
|
|
@ -45,6 +45,7 @@ class Hooks extends \OC\Share\Constants {
|
|||
* @param array $arguments
|
||||
*/
|
||||
public static function post_addToGroup($arguments) {
|
||||
|
||||
// Find the group shares and check if the user needs a unique target
|
||||
$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?');
|
||||
$result = $query->execute(array(self::SHARE_TYPE_GROUP, $arguments['gid']));
|
||||
|
@ -52,18 +53,25 @@ class Hooks extends \OC\Share\Constants {
|
|||
.' `item_target`, `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`,'
|
||||
.' `stime`, `file_source`, `file_target`) VALUES (?,?,?,?,?,?,?,?,?,?,?)');
|
||||
while ($item = $result->fetchRow()) {
|
||||
if ($item['item_type'] == 'file' || $item['item_type'] == 'file') {
|
||||
$itemTarget = null;
|
||||
|
||||
$sourceExists = \OC\Share\Share::getItemSharedWithBySource($item['item_type'], $item['item_source'], self::FORMAT_NONE, null, true, $arguments['uid']);
|
||||
|
||||
if ($sourceExists) {
|
||||
$fileTarget = $sourceExists['file_target'];
|
||||
$itemTarget = $sourceExists['item_target'];
|
||||
} else {
|
||||
$itemTarget = Helper::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
|
||||
$arguments['uid'], $item['uid_owner'], $item['item_target'], $item['id']);
|
||||
}
|
||||
if (isset($item['file_source'])) {
|
||||
$fileTarget = Helper::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER,
|
||||
$arguments['uid'], $item['uid_owner'], $item['file_target'], $item['id']);
|
||||
$itemTarget = Helper::generateTarget($item['item_type'], $item['item_source'], self::SHARE_TYPE_USER, $arguments['uid'],
|
||||
$item['owner'], null, $item['parent']);
|
||||
|
||||
// do we also need a file target
|
||||
if ($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
|
||||
$fileTarget = Helper::generateTarget('file', $item['file_target'], self::SHARE_TYPE_USER, $arguments['uid'],
|
||||
$item['owner'], null, $item['parent']);
|
||||
} else {
|
||||
$fileTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert an extra row for the group share if the item or file target is unique for this user
|
||||
if ($itemTarget != $item['item_target'] || $fileTarget != $item['file_target']) {
|
||||
$query->execute(array($item['item_type'], $item['item_source'], $itemTarget, $item['id'],
|
||||
|
|
|
@ -294,23 +294,32 @@ class Share extends \OC\Share\Constants {
|
|||
|
||||
$shares = array();
|
||||
|
||||
$column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
|
||||
|
||||
$where = ' `' . $column . '` = ? AND `item_type` = ? ';
|
||||
$arguments = array($itemSource, $itemType);
|
||||
// for link shares $user === null
|
||||
if ($user !== null) {
|
||||
$where .= ' AND `share_with` = ? ';
|
||||
$arguments[] = $user;
|
||||
}
|
||||
|
||||
// first check if there is a db entry for the specific user
|
||||
$query = \OC_DB::prepare(
|
||||
'SELECT `file_target`, `permissions`, `expiration`
|
||||
'SELECT *
|
||||
FROM
|
||||
`*PREFIX*share`
|
||||
WHERE
|
||||
`item_source` = ? AND `item_type` = ? AND `share_with` = ?'
|
||||
WHERE' . $where
|
||||
);
|
||||
|
||||
$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, $user));
|
||||
$result = \OC_DB::executeAudited($query, $arguments);
|
||||
|
||||
while ($row = $result->fetchRow()) {
|
||||
$shares[] = $row;
|
||||
}
|
||||
|
||||
//if didn't found a result than let's look for a group share.
|
||||
if(empty($shares)) {
|
||||
if(empty($shares) && $user !== null) {
|
||||
$groups = \OC_Group::getUserGroups($user);
|
||||
|
||||
$query = \OC_DB::prepare(
|
||||
|
@ -318,7 +327,7 @@ class Share extends \OC\Share\Constants {
|
|||
FROM
|
||||
`*PREFIX*share`
|
||||
WHERE
|
||||
`item_source` = ? AND `item_type` = ? AND `share_with` in (?)'
|
||||
`' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'
|
||||
);
|
||||
|
||||
$result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups)));
|
||||
|
@ -339,11 +348,13 @@ class Share extends \OC\Share\Constants {
|
|||
* @param int $format (optional) Format type must be defined by the backend
|
||||
* @param mixed $parameters
|
||||
* @param boolean $includeCollections
|
||||
* @return mixed Return depends on format
|
||||
* @param string $shareWith (optional) define against which user should be checked, default: current user
|
||||
* @return array
|
||||
*/
|
||||
public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
|
||||
$parameters = null, $includeCollections = false) {
|
||||
return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
|
||||
$parameters = null, $includeCollections = false, $shareWith = null) {
|
||||
$shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith;
|
||||
return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format,
|
||||
$parameters, 1, $includeCollections, true);
|
||||
}
|
||||
|
||||
|
@ -679,9 +690,31 @@ class Share extends \OC\Share\Constants {
|
|||
* @return boolean true on success or false on failure
|
||||
*/
|
||||
public static function unshare($itemType, $itemSource, $shareType, $shareWith) {
|
||||
$item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(),self::FORMAT_NONE, null, 1);
|
||||
if (!empty($item)) {
|
||||
self::unshareItem($item);
|
||||
|
||||
// check if it is a valid itemType
|
||||
self::getBackend($itemType);
|
||||
|
||||
$items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith);
|
||||
|
||||
$toDelete = array();
|
||||
$newParent = null;
|
||||
$currentUser = \OC_User::getUser();
|
||||
foreach ($items as $item) {
|
||||
// delete the item with the expected share_type and owner
|
||||
if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
|
||||
$toDelete = $item;
|
||||
// if there is more then one result we don't have to delete the children
|
||||
// but update their parent. For group shares the new parent should always be
|
||||
// the original group share and not the db entry with the unique name
|
||||
} else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
|
||||
$newParent = $item['parent'];
|
||||
} else {
|
||||
$newParent = $item['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($toDelete)) {
|
||||
self::unshareItem($toDelete, $newParent);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -773,7 +806,7 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
}
|
||||
|
||||
if (!$itemUnshared && isset($groupShare)) {
|
||||
if (!$itemUnshared && isset($groupShare) && !isset($uniqueGroupShare)) {
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`'
|
||||
.' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,'
|
||||
.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)'
|
||||
|
@ -1054,9 +1087,10 @@ class Share extends \OC\Share\Constants {
|
|||
/**
|
||||
* Unshares a share given a share data array
|
||||
* @param array $item Share data (usually database row)
|
||||
* @param int new parent ID
|
||||
* @return null
|
||||
*/
|
||||
protected static function unshareItem(array $item) {
|
||||
protected static function unshareItem(array $item, $newParent = null) {
|
||||
// Pass all the vars we have for now, they may be useful
|
||||
$hookParams = array(
|
||||
'id' => $item['id'],
|
||||
|
@ -1073,7 +1107,7 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
|
||||
\OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
|
||||
$deletedShares = Helper::delete($item['id']);
|
||||
$deletedShares = Helper::delete($item['id'], false, null, $newParent);
|
||||
$deletedShares[] = $hookParams;
|
||||
$hookParams['deletedShares'] = $deletedShares;
|
||||
\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
|
||||
|
@ -1292,13 +1326,17 @@ class Share extends \OC\Share\Constants {
|
|||
$queryArgs = array_merge($queryArgs, $collectionTypes);
|
||||
}
|
||||
}
|
||||
if ($limit != -1 && !$includeCollections) {
|
||||
if ($shareType == self::$shareTypeUserAndGroups) {
|
||||
|
||||
if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
|
||||
// Make sure the unique user target is returned if it exists,
|
||||
// unique targets should follow the group share in the database
|
||||
// If the limit is not 1, the filtering can be done later
|
||||
$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
|
||||
} else {
|
||||
$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
|
||||
}
|
||||
|
||||
if ($limit != -1 && !$includeCollections) {
|
||||
// The limit must be at least 3, because filtering needs to be done
|
||||
if ($limit < 3) {
|
||||
$queryLimit = 3;
|
||||
|
@ -1307,7 +1345,6 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
} else {
|
||||
$queryLimit = null;
|
||||
$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
|
||||
}
|
||||
$select = self::createSelectStatement($format, $fileDependent, $uidOwner);
|
||||
$root = strlen($root);
|
||||
|
@ -1315,7 +1352,7 @@ class Share extends \OC\Share\Constants {
|
|||
$result = $query->execute($queryArgs);
|
||||
if (\OC_DB::isError($result)) {
|
||||
\OC_Log::write('OCP\Share',
|
||||
\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where,
|
||||
\OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=',
|
||||
\OC_Log::ERROR);
|
||||
}
|
||||
$items = array();
|
||||
|
@ -1329,6 +1366,12 @@ class Share extends \OC\Share\Constants {
|
|||
$row['share_type'] = self::SHARE_TYPE_GROUP;
|
||||
$row['unique_name'] = true; // remember that we use a unique name for this user
|
||||
$row['share_with'] = $items[$row['parent']]['share_with'];
|
||||
// if the group share was unshared from the user we keep the permission, otherwise
|
||||
// we take the permission from the parent because this is always the up-to-date
|
||||
// permission for the group share
|
||||
if ($row['permissions'] > 0) {
|
||||
$row['permissions'] = $items[$row['parent']]['permissions'];
|
||||
}
|
||||
// Remove the parent group share
|
||||
unset($items[$row['parent']]);
|
||||
if ($row['permissions'] == 0) {
|
||||
|
@ -1336,10 +1379,10 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
} else if (!isset($uidOwner)) {
|
||||
// Check if the same target already exists
|
||||
if (isset($targets[$row[$column]])) {
|
||||
if (isset($targets[$row['id']])) {
|
||||
// Check if the same owner shared with the user twice
|
||||
// through a group and user share - this is allowed
|
||||
$id = $targets[$row[$column]];
|
||||
$id = $targets[$row['id']];
|
||||
if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
|
||||
// Switch to group share type to ensure resharing conditions aren't bypassed
|
||||
if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
|
||||
|
@ -1355,12 +1398,12 @@ class Share extends \OC\Share\Constants {
|
|||
unset($items[$id]);
|
||||
$id = $row['id'];
|
||||
}
|
||||
// Combine the permissions for the item
|
||||
$items[$id]['permissions'] |= (int)$row['permissions'];
|
||||
continue;
|
||||
|
||||
}
|
||||
} else {
|
||||
$targets[$row[$column]] = $row['id'];
|
||||
continue;
|
||||
} elseif (!empty($row['parent'])) {
|
||||
$targets[$row['parent']] = $row['id'];
|
||||
}
|
||||
}
|
||||
// Remove root from file source paths if retrieving own shared items
|
||||
|
@ -1398,6 +1441,7 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($checkExpireDate) {
|
||||
if (self::expireItem($row)) {
|
||||
continue;
|
||||
|
@ -1415,8 +1459,17 @@ class Share extends \OC\Share\Constants {
|
|||
$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
|
||||
}
|
||||
|
||||
if ($row['permissions'] > 0) {
|
||||
$items[$row['id']] = $row;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// group items if we are looking for items shared with the current user
|
||||
if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
|
||||
$items = self::groupItems($items, $itemType);
|
||||
}
|
||||
|
||||
if (!empty($items)) {
|
||||
$collectionItems = array();
|
||||
foreach ($items as &$row) {
|
||||
|
@ -1502,6 +1555,47 @@ class Share extends \OC\Share\Constants {
|
|||
}
|
||||
|
||||
/**
|
||||
* group items with link to the same source
|
||||
*
|
||||
* @param array $items
|
||||
* @param string $itemType
|
||||
* @return array of grouped items
|
||||
*/
|
||||
protected static function groupItems($items, $itemType) {
|
||||
|
||||
$fileSharing = ($itemType === 'file' || $itemType === 'folder') ? true : false;
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($items as $item) {
|
||||
$grouped = false;
|
||||
foreach ($result as $key => $r) {
|
||||
// for file/folder shares we need to compare file_source, otherwise we compare item_source
|
||||
// only group shares if they already point to the same target, otherwise the file where shared
|
||||
// before grouping of shares was added. In this case we don't group them toi avoid confusions
|
||||
if (( $fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
|
||||
(!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
|
||||
// add the first item to the list of grouped shares
|
||||
if (!isset($result[$key]['grouped'])) {
|
||||
$result[$key]['grouped'][] = $result[$key];
|
||||
}
|
||||
$result[$key]['permissions'] = (int) $item['permissions'] | (int) $r['permissions'];
|
||||
$result[$key]['grouped'][] = $item;
|
||||
$grouped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$grouped) {
|
||||
$result[] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put shared item into the database
|
||||
* @param string $itemType Item type
|
||||
* @param string $itemSource Item source
|
||||
|
@ -1518,121 +1612,34 @@ class Share extends \OC\Share\Constants {
|
|||
*/
|
||||
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
||||
$permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) {
|
||||
$backend = self::getBackend($itemType);
|
||||
$l = \OC::$server->getL10N('lib');
|
||||
// Check if this is a reshare
|
||||
if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) {
|
||||
|
||||
// Check if attempting to share back to owner
|
||||
if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
|
||||
$message = 'Sharing %s failed, because the user %s is the original sharer';
|
||||
$message_t = $l->t('Sharing %s failed, because the user %s is the original sharer', array($itemSourceName, $shareWith));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
// Check if share permissions is granted
|
||||
if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\PERMISSION_SHARE) {
|
||||
if (~(int)$checkReshare['permissions'] & $permissions) {
|
||||
$message = 'Sharing %s failed, because the permissions exceed permissions granted to %s';
|
||||
$message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $uidOwner), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
} else {
|
||||
// TODO Don't check if inside folder
|
||||
$parent = $checkReshare['id'];
|
||||
$itemSource = $checkReshare['item_source'];
|
||||
$fileSource = $checkReshare['file_source'];
|
||||
$suggestedItemTarget = $checkReshare['item_target'];
|
||||
$suggestedFileTarget = $checkReshare['file_target'];
|
||||
$filePath = $checkReshare['file_target'];
|
||||
$expirationDate = min($expirationDate, $checkReshare['expiration']);
|
||||
}
|
||||
} else {
|
||||
$message = 'Sharing %s failed, because resharing is not allowed';
|
||||
$message_t = $l->t('Sharing %s failed, because resharing is not allowed', array($itemSourceName));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
} else {
|
||||
$parent = null;
|
||||
$queriesToExecute = array();
|
||||
$suggestedItemTarget = null;
|
||||
$suggestedFileTarget = null;
|
||||
if (!$backend->isValidSource($itemSource, $uidOwner)) {
|
||||
$message = 'Sharing %s failed, because the sharing backend for '
|
||||
.'%s could not find its source';
|
||||
$message_t = $l->t('Sharing %s failed, because the sharing backend for %s could not find its source', array($itemSource, $itemType));
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSource, $itemType), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
|
||||
$filePath = $backend->getFilePath($itemSource, $uidOwner);
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$fileSource = $itemSource;
|
||||
} else {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($filePath);
|
||||
$fileSource = $meta['fileid'];
|
||||
}
|
||||
if ($fileSource == -1) {
|
||||
$message = 'Sharing %s failed, because the file could not be found in the file cache';
|
||||
$message_t = $l->t('Sharing %s failed, because the file could not be found in the file cache', array($itemSource));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSource), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
} else {
|
||||
$filePath = null;
|
||||
$fileSource = null;
|
||||
}
|
||||
$result = self::checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate);
|
||||
if(!empty($result)) {
|
||||
$parent = $result['parent'];
|
||||
$itemSource = $result['itemSource'];
|
||||
$fileSource = $result['fileSource'];
|
||||
$suggestedItemTarget = $result['suggestedItemTarget'];
|
||||
$suggestedFileTarget = $result['suggestedFileTarget'];
|
||||
$filePath = $result['filePath'];
|
||||
$expirationDate = $result['expirationDate'];
|
||||
}
|
||||
|
||||
// Share with a group
|
||||
$isGroupShare = false;
|
||||
if ($shareType == self::SHARE_TYPE_GROUP) {
|
||||
$isGroupShare = true;
|
||||
$users = \OC_Group::usersInGroup($shareWith['group']);
|
||||
// remove current user from list
|
||||
if (in_array(\OCP\User::getUser(), $users)) {
|
||||
unset($users[array_search(\OCP\User::getUser(), $users)]);
|
||||
}
|
||||
$groupItemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'],
|
||||
$uidOwner, $suggestedItemTarget);
|
||||
$run = true;
|
||||
$error = '';
|
||||
\OC_Hook::emit('OCP\Share', 'pre_shared', array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $groupItemTarget,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $shareWith['group'],
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'fileSource' => $fileSource,
|
||||
'expiration' => $expirationDate,
|
||||
'token' => $token,
|
||||
'run' => &$run,
|
||||
'error' => &$error
|
||||
));
|
||||
$groupFileTarget = $filePath;
|
||||
|
||||
if ($run === false) {
|
||||
throw new \Exception($error);
|
||||
}
|
||||
|
||||
if (isset($fileSource)) {
|
||||
if ($parentFolder) {
|
||||
if ($parentFolder === true) {
|
||||
$groupFileTarget = Helper::generateTarget('file', $filePath, $shareType,
|
||||
$shareWith['group'], $uidOwner, $suggestedFileTarget);
|
||||
// Set group default file target for future use
|
||||
$parentFolders[0]['folder'] = $groupFileTarget;
|
||||
} else {
|
||||
// Get group default file target
|
||||
$groupFileTarget = $parentFolder[0]['folder'].$itemSource;
|
||||
$parent = $parentFolder[0]['id'];
|
||||
}
|
||||
} else {
|
||||
$groupFileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith['group'],
|
||||
$uidOwner, $suggestedFileTarget);
|
||||
}
|
||||
} else {
|
||||
$groupFileTarget = null;
|
||||
}
|
||||
$queriesToExecute = array();
|
||||
// add group share to table and remember the id as parent
|
||||
$queriesToExecute['groupShare'] = array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
|
@ -1643,167 +1650,233 @@ class Share extends \OC\Share\Constants {
|
|||
'permissions' => $permissions,
|
||||
'shareTime' => time(),
|
||||
'fileSource' => $fileSource,
|
||||
'fileTarget' => $groupFileTarget,
|
||||
'fileTarget' => $filePath,
|
||||
'token' => $token,
|
||||
'parent' => $parent,
|
||||
'expiration' => $expirationDate,
|
||||
);
|
||||
// Loop through all users of this group in case we need to add an extra row
|
||||
foreach ($shareWith['users'] as $uid) {
|
||||
$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
|
||||
|
||||
} else {
|
||||
$users = array($shareWith);
|
||||
$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
||||
$suggestedItemTarget);
|
||||
}
|
||||
|
||||
$run = true;
|
||||
$error = '';
|
||||
$preHookData = array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'shareType' => $shareType,
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'fileSource' => $fileSource,
|
||||
'expiration' => $expirationDate,
|
||||
'token' => $token,
|
||||
'run' => &$run,
|
||||
'error' => &$error
|
||||
);
|
||||
|
||||
$preHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
|
||||
$preHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
|
||||
|
||||
\OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
|
||||
|
||||
if ($run === false) {
|
||||
throw new \Exception($error);
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
|
||||
$sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
|
||||
|
||||
$shareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
|
||||
|
||||
if ($sourceExists) {
|
||||
$fileTarget = $sourceExists['file_target'];
|
||||
$itemTarget = $sourceExists['item_target'];
|
||||
|
||||
// for group shares we don't need a additional entry if the target is the same
|
||||
if($isGroupShare && $groupItemTarget === $itemTarget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} elseif(!$sourceExists && !$isGroupShare) {
|
||||
|
||||
$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user,
|
||||
$uidOwner, $suggestedItemTarget, $parent);
|
||||
if (isset($fileSource)) {
|
||||
if ($parentFolder) {
|
||||
if ($parentFolder === true) {
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $uid,
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user,
|
||||
$uidOwner, $suggestedFileTarget, $parent);
|
||||
if ($fileTarget != $groupFileTarget) {
|
||||
$parentFolders[$uid]['folder'] = $fileTarget;
|
||||
$parentFolders[$user]['folder'] = $fileTarget;
|
||||
}
|
||||
} else if (isset($parentFolder[$uid])) {
|
||||
$fileTarget = $parentFolder[$uid]['folder'].$itemSource;
|
||||
$parent = $parentFolder[$uid]['id'];
|
||||
} else if (isset($parentFolder[$user])) {
|
||||
$fileTarget = $parentFolder[$user]['folder'].$itemSource;
|
||||
$parent = $parentFolder[$user]['id'];
|
||||
}
|
||||
} else {
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER,
|
||||
$uid, $uidOwner, $suggestedFileTarget, $parent);
|
||||
$user, $uidOwner, $suggestedFileTarget, $parent);
|
||||
}
|
||||
} else {
|
||||
$fileTarget = null;
|
||||
}
|
||||
// Insert an extra row for the group share if the item or file target is unique for this user
|
||||
if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
|
||||
|
||||
} else {
|
||||
|
||||
// group share which doesn't exists until now, check if we need a unique target for this user
|
||||
|
||||
$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user,
|
||||
$uidOwner, $suggestedItemTarget, $parent);
|
||||
|
||||
// do we also need a file target
|
||||
if (isset($fileSource)) {
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user,
|
||||
$uidOwner, $suggestedFileTarget, $parent);
|
||||
} else {
|
||||
$fileTarget = null;
|
||||
}
|
||||
|
||||
if ($itemTarget === $groupItemTarget && (isset($fileSource) && $fileTarget === $groupItemTarget)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$queriesToExecute[] = array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $itemTarget,
|
||||
'shareType' => self::$shareTypeGroupUserUnique,
|
||||
'shareWith' => $uid,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $user,
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'shareTime' => time(),
|
||||
'fileSource' => $fileSource,
|
||||
'fileTarget' => $fileTarget,
|
||||
'token' => $token,
|
||||
//'parent' => $parent,
|
||||
'parent' => $parent,
|
||||
'expiration' => $expirationDate,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($isGroupShare) {
|
||||
self::insertShare($queriesToExecute['groupShare']);
|
||||
// Save this id, any extra rows for this group share will need to reference it
|
||||
$parent = \OC_DB::insertid('*PREFIX*share');
|
||||
unset($queriesToExecute['groupShare']);
|
||||
}
|
||||
|
||||
foreach ($queriesToExecute as $shareQuery) {
|
||||
$shareQuery['parent'] = $parent;
|
||||
self::insertShare($shareQuery);
|
||||
}
|
||||
|
||||
\OC_Hook::emit('OCP\Share', 'post_shared', array(
|
||||
$postHookData = array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $groupItemTarget,
|
||||
'parent' => $parent,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $shareWith['group'],
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'fileSource' => $fileSource,
|
||||
'fileTarget' => $groupFileTarget,
|
||||
'id' => $parent,
|
||||
'token' => $token,
|
||||
'expirationDate' => $expirationDate,
|
||||
));
|
||||
);
|
||||
|
||||
if ($parentFolder === true) {
|
||||
// Return parent folders to preserve file target paths for potential children
|
||||
return $parentFolders;
|
||||
}
|
||||
} else {
|
||||
$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
||||
$suggestedItemTarget);
|
||||
$run = true;
|
||||
$error = '';
|
||||
\OC_Hook::emit('OCP\Share', 'pre_shared', array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $itemTarget,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $shareWith,
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'fileSource' => $fileSource,
|
||||
'token' => $token,
|
||||
'expirationDate' => $expirationDate,
|
||||
'run' => &$run,
|
||||
'error' => &$error,
|
||||
));
|
||||
$postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
|
||||
$postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
|
||||
$postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget;
|
||||
|
||||
if ($run === false) {
|
||||
throw new \Exception($error);
|
||||
}
|
||||
\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
|
||||
|
||||
if (isset($fileSource)) {
|
||||
if ($parentFolder) {
|
||||
if ($parentFolder === true) {
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith,
|
||||
$uidOwner, $suggestedFileTarget);
|
||||
$parentFolders['folder'] = $fileTarget;
|
||||
} else {
|
||||
$fileTarget = $parentFolder['folder'].$itemSource;
|
||||
$parent = $parentFolder['id'];
|
||||
}
|
||||
} else {
|
||||
$fileTarget = Helper::generateTarget('file', $filePath, $shareType, $shareWith, $uidOwner,
|
||||
$suggestedFileTarget);
|
||||
}
|
||||
} else {
|
||||
$fileTarget = null;
|
||||
}
|
||||
|
||||
self::insertShare(array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $itemTarget,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $shareWith,
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'shareTime' => time(),
|
||||
'fileSource' => $fileSource,
|
||||
'fileTarget' => $fileTarget,
|
||||
'token' => $token,
|
||||
'parent' => $parent,
|
||||
'expiration' => $expirationDate,
|
||||
));
|
||||
|
||||
$id = \OC_DB::insertid('*PREFIX*share');
|
||||
\OC_Hook::emit('OCP\Share', 'post_shared', array(
|
||||
'itemType' => $itemType,
|
||||
'itemSource' => $itemSource,
|
||||
'itemTarget' => $itemTarget,
|
||||
'parent' => $parent,
|
||||
'shareType' => $shareType,
|
||||
'shareWith' => $shareWith,
|
||||
'uidOwner' => $uidOwner,
|
||||
'permissions' => $permissions,
|
||||
'fileSource' => $fileSource,
|
||||
'fileTarget' => $fileTarget,
|
||||
'id' => $id,
|
||||
'token' => $token,
|
||||
'expirationDate' => $expirationDate,
|
||||
));
|
||||
if ($parentFolder === true) {
|
||||
$parentFolders['id'] = $id;
|
||||
// Return parent folder to preserve file target paths for potential children
|
||||
return $parentFolders;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
|
||||
$backend = self::getBackend($itemType);
|
||||
|
||||
$l = \OC::$server->getL10N('lib');
|
||||
$result = array();
|
||||
|
||||
$checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true);
|
||||
if ($checkReshare) {
|
||||
// Check if attempting to share back to owner
|
||||
if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
|
||||
$message = 'Sharing %s failed, because the user %s is the original sharer';
|
||||
$message_t = $l->t('Sharing %s failed, because the user %s is the original sharer', array($itemSourceName, $shareWith));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
|
||||
// Check if share permissions is granted
|
||||
if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\PERMISSION_SHARE) {
|
||||
if (~(int)$checkReshare['permissions'] & $permissions) {
|
||||
$message = 'Sharing %s failed, because the permissions exceed permissions granted to %s';
|
||||
$message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $uidOwner), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
} else {
|
||||
// TODO Don't check if inside folder
|
||||
$result['parent'] = $checkReshare['id'];
|
||||
$result['itemSource'] = $checkReshare['item_source'];
|
||||
$result['fileSource'] = $checkReshare['file_source'];
|
||||
$result['suggestedItemTarget'] = $checkReshare['item_target'];
|
||||
$result['suggestedFileTarget'] = $checkReshare['file_target'];
|
||||
$result['filePath'] = $checkReshare['file_target'];
|
||||
$result['expirationDate'] = min($expirationDate, $checkReshare['expiration']);
|
||||
}
|
||||
} else {
|
||||
$message = 'Sharing %s failed, because resharing is not allowed';
|
||||
$message_t = $l->t('Sharing %s failed, because resharing is not allowed', array($itemSourceName));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
} else {
|
||||
$result['parent'] = null;
|
||||
$result['suggestedItemTarget'] = null;
|
||||
$result['suggestedFileTarget'] = null;
|
||||
$result['itemSource'] = $itemSource;
|
||||
$result['expirationDate'] = $expirationDate;
|
||||
if (!$backend->isValidSource($itemSource, $uidOwner)) {
|
||||
$message = 'Sharing %s failed, because the sharing backend for '
|
||||
.'%s could not find its source';
|
||||
$message_t = $l->t('Sharing %s failed, because the sharing backend for %s could not find its source', array($itemSource, $itemType));
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSource, $itemType), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
|
||||
$result['filePath'] = $backend->getFilePath($itemSource, $uidOwner);
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$result['fileSource'] = $itemSource;
|
||||
} else {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($result['filePath']);
|
||||
$result['fileSource'] = $meta['fileid'];
|
||||
}
|
||||
if ($result['fileSource'] == -1) {
|
||||
$message = 'Sharing %s failed, because the file could not be found in the file cache';
|
||||
$message_t = $l->t('Sharing %s failed, because the file could not be found in the file cache', array($itemSource));
|
||||
|
||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSource), \OC_Log::ERROR);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
} else {
|
||||
$result['filePath'] = null;
|
||||
$result['fileSource'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function insertShare(array $shareData)
|
||||
{
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
|
||||
|
@ -1877,9 +1950,9 @@ class Share extends \OC\Share\Constants {
|
|||
$select = '*';
|
||||
if ($format == self::FORMAT_STATUSES) {
|
||||
if ($fileDependent) {
|
||||
$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, `share_with`, `uid_owner` , `file_source`, `stime`';
|
||||
$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, `share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`';
|
||||
} else {
|
||||
$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`';
|
||||
$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
|
||||
}
|
||||
} else {
|
||||
if (isset($uidOwner)) {
|
||||
|
|
|
@ -139,7 +139,7 @@ class Share extends \OC\Share\Constants {
|
|||
* @param int $format (optional) Format type must be defined by the backend
|
||||
* @param mixed $parameters
|
||||
* @param bool $includeCollections
|
||||
* @return mixed Return depends on format
|
||||
* @return array
|
||||
*/
|
||||
public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
|
||||
$parameters = null, $includeCollections = false) {
|
||||
|
@ -361,7 +361,7 @@ interface Share_Backend {
|
|||
* Get a unique name of the item for the specified user
|
||||
* @param string $itemSource
|
||||
* @param string|false $shareWith User the item is being shared with
|
||||
* @param array|null $exclude List of similar item names already existing as shared items
|
||||
* @param array|null $exclude List of similar item names already existing as shared items @deprecated since version OC7
|
||||
* @return string Target name
|
||||
*
|
||||
* This function needs to verify that the user does not already have an item with this name.
|
||||
|
|
|
@ -38,19 +38,36 @@ class Test_Share_Backend implements OCP\Share_Backend {
|
|||
|
||||
public function generateTarget($itemSource, $shareWith, $exclude = null) {
|
||||
// Always make target be test.txt to cause conflicts
|
||||
$target = 'test.txt';
|
||||
if (isset($exclude)) {
|
||||
|
||||
if (substr($itemSource, 0, strlen('test')) !== 'test') {
|
||||
$target = "test.txt";
|
||||
} else {
|
||||
$target = $itemSource;
|
||||
}
|
||||
|
||||
|
||||
$shares = \OCP\Share::getItemsSharedWithUser('test', $shareWith);
|
||||
|
||||
$knownTargets = array();
|
||||
foreach ($shares as $share) {
|
||||
$knownTargets[] = $share['item_target'];
|
||||
}
|
||||
|
||||
|
||||
if (in_array($target, $knownTargets)) {
|
||||
$pos = strrpos($target, '.');
|
||||
$name = substr($target, 0, $pos);
|
||||
$ext = substr($target, $pos);
|
||||
$append = '';
|
||||
$i = 1;
|
||||
while (in_array($name.$append.$ext, $exclude)) {
|
||||
while (in_array($name.$append.$ext, $knownTargets)) {
|
||||
$append = $i;
|
||||
$i++;
|
||||
}
|
||||
$target = $name.$append.$ext;
|
||||
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ class Test_Share extends PHPUnit_Framework_TestCase {
|
|||
OC_User::setUserId($this->user1);
|
||||
OC_Group::clearBackends();
|
||||
OC_Group::useBackend(new OC_Group_Dummy);
|
||||
$this->group1 = uniqid('group_');
|
||||
$this->group2 = uniqid('group_');
|
||||
$this->group1 = uniqid('group1_');
|
||||
$this->group2 = uniqid('group2_');
|
||||
OC_Group::createGroup($this->group1);
|
||||
OC_Group::createGroup($this->group2);
|
||||
OC_Group::addToGroup($this->user1, $this->group1);
|
||||
|
@ -541,7 +541,7 @@ class Test_Share extends PHPUnit_Framework_TestCase {
|
|||
OC_User::setUserId($this->user2);
|
||||
$this->assertEquals(array(OCP\PERMISSION_READ | OCP\PERMISSION_UPDATE), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_PERMISSIONS));
|
||||
OC_User::setUserId($this->user4);
|
||||
$this->assertEquals(array(), OCP\Share::getItemsSharedWith('test', Test_Share_Backend::FORMAT_TARGET));
|
||||
$this->assertEquals(array('test.txt'), OCP\Share::getItemsSharedWith('test', Test_Share_Backend::FORMAT_TARGET));
|
||||
|
||||
// Valid share with same person - group then user
|
||||
OC_User::setUserId($this->user1);
|
||||
|
@ -757,20 +757,88 @@ class Test_Share extends PHPUnit_Framework_TestCase {
|
|||
array(false, array('share_with' => '1234567890', 'share_type' => '3', 'id' => 101)),
|
||||
array(false, array('share_with' => '1234567890', 'share_type' => 3, 'id' => 101)),
|
||||
);
|
||||
|
||||
/*
|
||||
if (!isset($linkItem['share_with'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
|
||||
return true;
|
||||
/**
|
||||
* @dataProvider dataProviderTestGroupItems
|
||||
* @param type $ungrouped
|
||||
* @param type $grouped
|
||||
*/
|
||||
function testGroupItems($ungrouped, $grouped) {
|
||||
|
||||
$result = DummyShareClass::groupItemsTest($ungrouped);
|
||||
|
||||
$this->compareArrays($grouped, $result);
|
||||
|
||||
}
|
||||
|
||||
if ( \OC::$server->getSession()->exists('public_link_authenticated')
|
||||
&& \OC::$server->getSession()->get('public_link_authenticated') === $linkItem['id'] ) {
|
||||
return true;
|
||||
function compareArrays($result, $expectedResult) {
|
||||
foreach ($expectedResult as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$this->compareArrays($result[$key], $value);
|
||||
} else {
|
||||
$this->assertSame($value, $result[$key]);
|
||||
}
|
||||
* */
|
||||
}
|
||||
}
|
||||
|
||||
function dataProviderTestGroupItems() {
|
||||
return array(
|
||||
// one array with one share
|
||||
array(
|
||||
array( // input
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_ALL, 'item_target' => 't1')),
|
||||
array( // expected result
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_ALL, 'item_target' => 't1'))),
|
||||
// two shares both point to the same source
|
||||
array(
|
||||
array( // input
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't1'),
|
||||
),
|
||||
array( // expected result
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE, 'item_target' => 't1',
|
||||
'grouped' => array(
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't1'),
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
// two shares both point to the same source but with different targets
|
||||
array(
|
||||
array( // input
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't2'),
|
||||
),
|
||||
array( // expected result
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't2'),
|
||||
)
|
||||
),
|
||||
// three shares two point to the same source
|
||||
array(
|
||||
array( // input
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 2, 'permissions' => \OCP\PERMISSION_CREATE, 'item_target' => 't2'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't1'),
|
||||
),
|
||||
array( // expected result
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE, 'item_target' => 't1',
|
||||
'grouped' => array(
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_READ, 'item_target' => 't1'),
|
||||
array('item_source' => 1, 'permissions' => \OCP\PERMISSION_UPDATE, 'item_target' => 't1'),
|
||||
)
|
||||
),
|
||||
array('item_source' => 2, 'permissions' => \OCP\PERMISSION_CREATE, 'item_target' => 't2'),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DummyShareClass extends \OC\Share\Share {
|
||||
public static function groupItemsTest($items) {
|
||||
return parent::groupItems($items, 'test');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue