From da90da49293b088d30ea415d33c02fcba74661aa Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 11 Nov 2016 12:34:01 +0100 Subject: [PATCH 01/21] Remove file/folder share backends --- apps/files_sharing/appinfo/app.php | 3 - apps/files_sharing/lib/ShareBackend/File.php | 241 ------------------ .../files_sharing/lib/ShareBackend/Folder.php | 107 -------- apps/files_sharing/tests/BackendTest.php | 106 -------- lib/private/Share/Share.php | 16 -- lib/private/legacy/template.php | 14 + lib/public/Share_Backend_File_Dependent.php | 41 --- tests/lib/Files/EtagTest.php | 2 - 8 files changed, 14 insertions(+), 516 deletions(-) delete mode 100644 apps/files_sharing/lib/ShareBackend/File.php delete mode 100644 apps/files_sharing/lib/ShareBackend/Folder.php delete mode 100644 apps/files_sharing/tests/BackendTest.php delete mode 100644 lib/public/Share_Backend_File_Dependent.php diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 23f358e3a815..a64a17c81872 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -29,9 +29,6 @@ \OCA\Files_Sharing\Helper::registerHooks(); -\OCP\Share::registerBackend('file', 'OCA\Files_Sharing\ShareBackend\File'); -\OCP\Share::registerBackend('folder', 'OCA\Files_Sharing\ShareBackend\Folder', 'file'); - $application = new \OCA\Files_Sharing\AppInfo\Application(); $application->registerMountProviders(); $application->registerNotifier(); diff --git a/apps/files_sharing/lib/ShareBackend/File.php b/apps/files_sharing/lib/ShareBackend/File.php deleted file mode 100644 index e2d109ce8aed..000000000000 --- a/apps/files_sharing/lib/ShareBackend/File.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @author Bart Visscher - * @author Björn Schießle - * @author Joas Schilling - * @author Lukas Reschke - * @author Michael Gapczynski - * @author Morris Jobke - * @author Robin Appelman - * @author Roeland Jago Douma - * @author Thomas Müller - * @author Vincent Petry - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Files_Sharing\ShareBackend; - -use OCA\FederatedFileSharing\FederatedShareProvider; - -class File implements \OCP\Share_Backend_File_Dependent { - const FORMAT_SHARED_STORAGE = 0; - const FORMAT_GET_FOLDER_CONTENTS = 1; - const FORMAT_FILE_APP_ROOT = 2; - const FORMAT_OPENDIR = 3; - const FORMAT_GET_ALL = 4; - const FORMAT_PERMISSIONS = 5; - const FORMAT_TARGET_NAMES = 6; - - private $path; - - /** @var FederatedShareProvider */ - private $federatedShareProvider; - - public function __construct(FederatedShareProvider $federatedShareProvider = null) { - if ($federatedShareProvider) { - $this->federatedShareProvider = $federatedShareProvider; - } else { - $federatedSharingApp = new \OCA\FederatedFileSharing\AppInfo\Application(); - $this->federatedShareProvider = $federatedSharingApp->getFederatedShareProvider(); - } - } - - public function isValidSource($itemSource, $uidOwner) { - try { - $path = \OC\Files\Filesystem::getPath($itemSource); - // FIXME: attributes should not be set here, - // keeping this pattern for now to avoid unexpected - // regressions - $this->path = \OC\Files\Filesystem::normalizePath(\basename($path)); - return true; - } catch (\OCP\Files\NotFoundException $e) { - return false; - } - } - - public function getFilePath($itemSource, $uidOwner) { - if (isset($this->path)) { - $path = $this->path; - $this->path = null; - return $path; - } else { - try { - $path = \OC\Files\Filesystem::getPath($itemSource); - return $path; - } catch (\OCP\Files\NotFoundException $e) { - return false; - } - } - } - - /** - * create unique target - * @param string $filePath - * @param string $shareWith - * @param array $exclude (optional) - * @return string - */ - public function generateTarget($filePath, $shareWith, $exclude = null) { - $shareFolder = \OCA\Files_Sharing\Helper::getShareFolder(); - $target = \OC\Files\Filesystem::normalizePath($shareFolder . '/' . \basename($filePath)); - - // for group shares we return the target right away - if ($shareWith === false) { - return $target; - } - - \OC\Files\Filesystem::initMountPoints($shareWith); - $view = new \OC\Files\View('/' . $shareWith . '/files'); - - if (!$view->is_dir($shareFolder)) { - $dir = ''; - $subdirs = \explode('/', $shareFolder); - foreach ($subdirs as $subdir) { - $dir = $dir . '/' . $subdir; - if (!$view->is_dir($dir)) { - $view->mkdir($dir); - } - } - } - - $excludeList = (\is_array($exclude)) ? $exclude : []; - - return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view); - } - - public function formatItems($items, $format, $parameters = null) { - if ($format == self::FORMAT_SHARED_STORAGE) { - // Only 1 item should come through for this format call - $item = \array_shift($items); - return [ - 'parent' => $item['parent'], - 'path' => $item['path'], - 'storage' => $item['storage'], - 'permissions' => $item['permissions'], - 'uid_owner' => $item['uid_owner'], - ]; - } elseif ($format == self::FORMAT_GET_FOLDER_CONTENTS) { - $files = []; - foreach ($items as $item) { - $file = []; - $file['fileid'] = $item['file_source']; - $file['storage'] = $item['storage']; - $file['path'] = $item['file_target']; - $file['parent'] = $item['file_parent']; - $file['name'] = \basename($item['file_target']); - $file['mimetype'] = $item['mimetype']; - $file['mimepart'] = $item['mimepart']; - $file['mtime'] = $item['mtime']; - $file['encrypted'] = $item['encrypted']; - $file['etag'] = $item['etag']; - $file['uid_owner'] = $item['uid_owner']; - $file['displayname_owner'] = $item['displayname_owner']; - - $storage = \OC\Files\Filesystem::getStorage('/'); - $cache = $storage->getCache(); - $file['size'] = $item['size']; - $files[] = $file; - } - return $files; - } elseif ($format == self::FORMAT_OPENDIR) { - $files = []; - foreach ($items as $item) { - $files[] = \basename($item['file_target']); - } - return $files; - } elseif ($format == self::FORMAT_GET_ALL) { - $ids = []; - foreach ($items as $item) { - $ids[] = $item['file_source']; - } - return $ids; - } elseif ($format === self::FORMAT_PERMISSIONS) { - $filePermissions = []; - foreach ($items as $item) { - $filePermissions[$item['file_source']] = $item['permissions']; - } - return $filePermissions; - } elseif ($format === self::FORMAT_TARGET_NAMES) { - $targets = []; - foreach ($items as $item) { - $targets[] = $item['file_target']; - } - return $targets; - } - return []; - } - - /** - * check if server2server share is enabled - * - * @param int $shareType - * @return boolean - */ - public function isShareTypeAllowed($shareType) { - if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { - return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled(); - } - - return true; - } - - /** - * resolve reshares to return the correct source item - * @param array $source - * @return array source item - */ - protected static function resolveReshares($source) { - if (isset($source['parent'])) { - $parent = $source['parent']; - while (isset($parent)) { - $query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1); - $item = $query->execute([$parent])->fetchRow(); - if (isset($item['parent'])) { - $parent = $item['parent']; - } else { - $fileOwner = $item['uid_owner']; - break; - } - } - } else { - $fileOwner = $source['uid_owner']; - } - if (isset($fileOwner)) { - $source['fileOwner'] = $fileOwner; - } else { - \OCP\Util::writeLog('files_sharing', "No owner found for reshare", \OCP\Util::ERROR); - } - - return $source; - } - - /** - * @param string $target - * @param array $share - * @return array|false source item - */ - public static function getSource($target, $share) { - if ($share['item_type'] === 'folder' && $target !== '') { - // note: in case of ext storage mount points the path might be empty - // which would cause a leading slash to appear - $share['path'] = \ltrim($share['path'] . '/' . $target, '/'); - } - return self::resolveReshares($share); - } -} diff --git a/apps/files_sharing/lib/ShareBackend/Folder.php b/apps/files_sharing/lib/ShareBackend/Folder.php deleted file mode 100644 index 98a4c060cde5..000000000000 --- a/apps/files_sharing/lib/ShareBackend/Folder.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @author Björn Schießle - * @author Joas Schilling - * @author Michael Gapczynski - * @author Morris Jobke - * @author Robin McCorkell - * @author Roeland Jago Douma - * @author Thomas Müller - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Files_Sharing\ShareBackend; - -class Folder extends File implements \OCP\Share_Backend_Collection { - - /** - * get shared parents - * - * @param int $itemSource item source ID - * @param string $shareWith with whom should the item be shared - * @param string $owner owner of the item - * @return array with shares - */ - public function getParents($itemSource, $shareWith = null, $owner = null) { - $result = []; - $parent = $this->getParentId($itemSource); - while ($parent) { - $shares = \OCP\Share::getItemSharedWithUser('folder', $parent, $shareWith, $owner); - if ($shares) { - foreach ($shares as $share) { - $name = \basename($share['path']); - $share['collection']['path'] = $name; - $share['collection']['item_type'] = 'folder'; - $share['file_path'] = $name; - $displayNameOwner = \OCP\User::getDisplayName($share['uid_owner']); - $displayNameShareWith = \OCP\User::getDisplayName($share['share_with']); - $share['displayname_owner'] = ($displayNameOwner) ? $displayNameOwner : $share['uid_owner']; - $share['share_with_displayname'] = ($displayNameShareWith) ? $displayNameShareWith : $share['uid_owner']; - - $result[] = $share; - } - } - $parent = $this->getParentId($parent); - } - - return $result; - } - - /** - * get file cache ID of parent - * - * @param int $child file cache ID of child - * @return mixed parent ID or null - */ - private function getParentId($child) { - $query = \OCP\DB::prepare('SELECT `parent` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); - $result = $query->execute([$child]); - $row = $result->fetchRow(); - $parent = ($row) ? $row['parent'] : null; - - return $parent; - } - - public function getChildren($itemSource) { - $children = []; - $parents = [$itemSource]; - $query = \OCP\DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); - $result = $query->execute(['httpd/unix-directory']); - if ($row = $result->fetchRow()) { - $mimetype = $row['id']; - } else { - $mimetype = -1; - } - while (!empty($parents)) { - $parents = "'".\implode("','", $parents)."'"; - $query = \OCP\DB::prepare('SELECT `fileid`, `name`, `mimetype` FROM `*PREFIX*filecache`' - .' WHERE `parent` IN ('.$parents.')'); - $result = $query->execute(); - $parents = []; - while ($file = $result->fetchRow()) { - $children[] = ['source' => $file['fileid'], 'file_path' => $file['name']]; - // If a child folder is found look inside it - if ($file['mimetype'] == $mimetype) { - $parents[] = $file['fileid']; - } - } - } - return $children; - } -} diff --git a/apps/files_sharing/tests/BackendTest.php b/apps/files_sharing/tests/BackendTest.php deleted file mode 100644 index 704ab2d5f755..000000000000 --- a/apps/files_sharing/tests/BackendTest.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @author Joas Schilling - * @author Morris Jobke - * @author Robin Appelman - * @author Thomas Müller - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Files_Sharing\Tests; - -/** - * Class BackendTest - * - * @group DB - */ -class BackendTest extends TestCase { - const TEST_FOLDER_NAME = '/folder_share_api_test'; - - public $folder; - public $subfolder; - public $subsubfolder; - - protected function setUp() { - parent::setUp(); - - $this->folder = self::TEST_FOLDER_NAME; - $this->subfolder = '/subfolder_share_backend_test'; - $this->subsubfolder = '/subsubfolder_share_backend_test'; - - $this->filename = '/share-backend-test.txt'; - - // save file with content - $this->view->file_put_contents($this->filename, $this->data); - $this->view->mkdir($this->folder); - $this->view->mkdir($this->folder . $this->subfolder); - $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder); - $this->view->file_put_contents($this->folder.$this->filename, $this->data); - $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data); - $this->view->file_put_contents($this->folder . $this->subfolder . $this->subsubfolder . $this->filename, $this->data); - } - - protected function tearDown() { - if ($this->view) { - $this->view->unlink($this->filename); - $this->view->deleteAll($this->folder); - } - - parent::tearDown(); - } - - public function testGetParents() { - $fileinfo1 = $this->view->getFileInfo($this->folder); - $fileinfo2 = $this->view->getFileInfo($this->folder . $this->subfolder . $this->subsubfolder); - $fileinfo3 = $this->view->getFileInfo($this->folder . $this->subfolder . $this->subsubfolder . $this->filename); - - $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, - self::TEST_FILES_SHARING_API_USER2, 31)); - $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, - self::TEST_FILES_SHARING_API_USER3, 31)); - - $backend = new \OCA\Files_Sharing\ShareBackend\Folder(); - - $result = $backend->getParents($fileinfo3['fileid']); - $this->assertCount(2, $result); - - $count1 = 0; - $count2 = 0; - foreach ($result as $r) { - if ($r['path'] === 'files' . $this->folder) { - $this->assertSame(\ltrim($this->folder, '/'), $r['collection']['path']); - $count1++; - } elseif ($r['path'] === 'files' . $this->folder . $this->subfolder . $this->subsubfolder) { - $this->assertSame(\ltrim($this->subsubfolder, '/'), $r['collection']['path']); - $count2++; - } else { - $this->assertTrue(false, 'unexpected result'); - } - } - - $this->assertSame(1, $count1); - $this->assertSame(1, $count2); - - $result1 = $backend->getParents($fileinfo3['fileid'], self::TEST_FILES_SHARING_API_USER3); - $this->assertCount(1, $result1); - $elemet = \reset($result1); - $this->assertSame('files' . $this->folder . $this->subfolder . $this->subsubfolder, $elemet['path']); - $this->assertSame(\ltrim($this->subsubfolder, '/'), $elemet['collection']['path']); - } -} diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 0d53f8a1d63c..c48a0e86f722 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -91,22 +91,6 @@ public static function registerBackend($itemType, $class, $collectionOf = null, 'collectionOf' => $collectionOf, 'supportedFileExtensions' => $supportedFileExtensions ]; - if (\count(self::$backendTypes) === 1) { - \OC_Util::addScript('core', 'shareconfigmodel'); - \OC_Util::addScript('core', 'sharemodel'); - \OC_Util::addScript('core', 'sharescollection'); - \OC_Util::addScript('core', 'shareitemmodel'); - \OC_Util::addScript('core', 'sharedialogresharerinfoview'); - \OC_Util::addScript('core', 'sharedialoglinklistview'); - \OC_Util::addScript('core', 'sharedialoglinkshareview'); - \OC_Util::addScript('core', 'sharedialogmailview'); - \OC_Util::addScript('core', 'sharedialoglinksocialview'); - \OC_Util::addScript('core', 'sharedialogexpirationview'); - \OC_Util::addScript('core', 'sharedialogshareelistview'); - \OC_Util::addScript('core', 'sharedialogview'); - \OC_Util::addScript('core', 'share'); - \OC_Util::addStyle('core', 'share'); - } return true; } \OCP\Util::writeLog('OCP\Share', diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php index 6253dd99176f..5fa7db8f85ca 100644 --- a/lib/private/legacy/template.php +++ b/lib/private/legacy/template.php @@ -156,6 +156,20 @@ public static function initTemplateEngine($renderAs) { OC_Util::addScript('files/fileinfo'); OC_Util::addScript('files/client'); + if (\OCP\Share::isEnabled()) { + \OC_Util::addScript('core', 'shareconfigmodel'); + \OC_Util::addScript('core', 'shareitemmodel'); + \OC_Util::addScript('core', 'sharedialogresharerinfoview'); + \OC_Util::addScript('core', 'sharedialoglinkshareview'); + \OC_Util::addScript('core', 'sharedialoglinksocialview'); + \OC_Util::addScript('core', 'sharedialogmailview'); + \OC_Util::addScript('core', 'sharedialogexpirationview'); + \OC_Util::addScript('core', 'sharedialogshareelistview'); + \OC_Util::addScript('core', 'sharedialogview'); + \OC_Util::addScript('core', 'share'); + \OC_Util::addStyle('core', 'share'); + } + // Add the stuff we need always // following logic will import all vendor libraries that are // specified in core/js/core.json diff --git a/lib/public/Share_Backend_File_Dependent.php b/lib/public/Share_Backend_File_Dependent.php deleted file mode 100644 index 5f0b9f4df68a..000000000000 --- a/lib/public/Share_Backend_File_Dependent.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @author Morris Jobke - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -// use OCP namespace for all classes that are considered public. -// This means that they should be used by apps instead of the internal ownCloud classes -namespace OCP; - -/** - * Interface for share backends that share content that is dependent on files. - * Extends the Share_Backend interface. - * @since 5.0.0 - */ -interface Share_Backend_File_Dependent extends Share_Backend { - /** - * Get the file path of the item - * @param string $itemSource - * @param string $uidOwner User that is the owner of shared item - * @return string|false - * @since 5.0.0 - */ - public function getFilePath($itemSource, $uidOwner); -} diff --git a/tests/lib/Files/EtagTest.php b/tests/lib/Files/EtagTest.php index 57738feb80ca..2ffc340f3cb4 100644 --- a/tests/lib/Files/EtagTest.php +++ b/tests/lib/Files/EtagTest.php @@ -32,8 +32,6 @@ protected function setUp() { \OC_Hook::clear('OC_Filesystem', 'setup'); $application = new \OCA\Files_Sharing\AppInfo\Application(); $application->registerMountProviders(); - \OCP\Share::registerBackend('file', 'OCA\Files_Sharing\ShareBackend\File'); - \OCP\Share::registerBackend('folder', 'OCA\Files_Sharing\ShareBackend\Folder', 'file'); $config = \OC::$server->getConfig(); $this->datadir = $config->getSystemValue('datadirectory'); From 4e42f22e9baf055daf7d382b4a52fbdd59e6cd59 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 11 Nov 2016 12:34:12 +0100 Subject: [PATCH 02/21] Remove file/folder backend from old share API --- lib/private/Share/Share.php | 349 ++++++++---------------------------- 1 file changed, 72 insertions(+), 277 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index c48a0e86f722..449d9eac3b01 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -85,6 +85,9 @@ class Share extends Constants { */ public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) { if (self::isEnabled()) { + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } if (!isset(self::$backendTypes[$itemType])) { self::$backendTypes[$itemType] = [ 'class' => $class, @@ -126,6 +129,7 @@ public static function isEnabled() { * not '/admin/data/file.txt' */ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) { + // FIXME: make ths use IShareProvider::getSharesByPath and extract users $userManager = \OC::$server->getUserManager(); $userObject = $userManager->get($ownerUser); @@ -376,24 +380,18 @@ public static function getItemSharedWith($itemType, $itemTarget, $format = self: * @param string $user User to whom the item was shared * @param string $owner Owner of the share * @param int $shareType only look for a specific share type - * @return array Return list of items with file_target, permissions and expiration + * @return array Return list of items with item_target, permissions and expiration */ public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) { + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } $shares = []; - $fileDependent = false; $where = 'WHERE'; - $fileDependentWhere = ''; - if ($itemType === 'file' || $itemType === 'folder') { - $fileDependent = true; - $column = 'file_source'; - $fileDependentWhere = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` '; - $fileDependentWhere .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` '; - } else { - $column = 'item_source'; - } + $column = 'item_source'; - $select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent); + $select = self::createSelectStatement(self::FORMAT_NONE); $where .= ' `' . $column . '` = ? AND `item_type` = ? '; $arguments = [$itemSource, $itemType]; @@ -413,30 +411,11 @@ public static function getItemSharedWithUser($itemType, $itemSource, $user, $own $arguments[] = $owner; } - $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where); + $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where); $result = \OC_DB::executeAudited($query, $arguments); while ($row = $result->fetchRow()) { - if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) { - continue; - } - if ($fileDependent && (int)$row['file_parent'] === -1) { - // if it is a mount point we need to get the path from the mount manager - $mountManager = \OC\Files\Filesystem::getMountManager(); - $mountPoint = $mountManager->findByStorageId($row['storage_id']); - if (!empty($mountPoint)) { - $path = $mountPoint[0]->getMountPoint(); - $path = \trim($path, '/'); - $path = \substr($path, \strlen($owner) + 1); //normalize path to 'files/foo.txt` - $row['path'] = $path; - } else { - \OC::$server->getLogger()->warning( - 'Could not resolve mount point for ' . $row['storage_id'], - ['app' => 'OCP\Share'] - ); - } - } $shares[] = $row; } @@ -445,7 +424,7 @@ public static function getItemSharedWithUser($itemType, $itemSource, $user, $own $groups = self::getGroupsForUser($user); if (!empty($groups)) { - $where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'; + $where = ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'; $arguments = [$itemSource, $itemType, $groups]; $types = [null, null, IQueryBuilder::PARAM_STR_ARRAY]; @@ -533,7 +512,7 @@ public static function getShareByToken($token, $checkPasswordProtection = true) /** * resolves reshares down to the last real share * @param array $linkItem - * @return array file owner + * @return array item owner */ public static function resolveReShare($linkItem) { if (isset($linkItem['parent'])) { @@ -639,53 +618,13 @@ public static function shareItem($itemType, $itemSource, $shareType, $shareWith, } $itemName = $itemSourceName; - // check if file can be shared - if ($itemType === 'file' or $itemType === 'folder') { - $path = \OC\Files\Filesystem::getPath($itemSource); - $itemName = $path; - - // verify that the file exists before we try to share it - if (!$path) { - $message = 'Sharing %s failed, because the file does not exist'; - $message_t = $l->t('Sharing %s failed, because the file does not exist', [$itemSourceName]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - // verify that the user has share permission - if (!\OC\Files\Filesystem::isSharable($path) || \OCP\Util::isSharingDisabledForUser()) { - $message = 'You are not allowed to share %s'; - $message_t = $l->t('You are not allowed to share %s', [$path]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $path), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - - //verify that we don't share a folder which already contains a share mount point - if ($itemType === 'folder') { - $path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/'; - $mountManager = \OC\Files\Filesystem::getMountManager(); - $mounts = $mountManager->findIn($path); - foreach ($mounts as $mount) { - if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) { - $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!'; - \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG); - throw new \Exception($message); - } - } - } - - // single file shares should never have delete permissions - if ($itemType === 'file') { - $permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE; - } - //Validate expirationDate if ($expirationDate !== null) { try { /* * Reuse the validateExpireDate. * We have to pass time() since the second arg is the time - * the file was shared, since it is not shared yet we just use + * the item was shared, since it is not shared yet we just use * the current time. */ $expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), \time(), $itemType, $itemSource); @@ -858,7 +797,7 @@ public static function shareItem($itemType, $itemSource, $shareType, $shareWith, } elseif ($shareType === self::SHARE_TYPE_REMOTE) { /* - * Check if file is not already shared with the remote user + * Check if item is not already shared with the remote user */ if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_REMOTE, $shareWith, $uidOwner, self::FORMAT_NONE, null, 1, true, true)) { @@ -994,14 +933,13 @@ public static function unshareAll($itemType, $itemSource) { * Unsharing from self is not allowed for items inside collections */ public static function unshareFromSelf($itemType, $itemOrigin, $originIsSource = false) { + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } $originType = ($originIsSource) ? 'source' : 'target'; $uid = \OCP\User::getUser(); - if ($itemType === 'file' || $itemType === 'folder') { - $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_' . $originType . '` = ?'; - } else { - $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?'; - } + $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?'; $query = \OCP\DB::prepare($statement); $result = $query->execute([$itemType, $itemOrigin]); @@ -1161,18 +1099,6 @@ public static function setPermissions($itemType, $itemSource, $shareType, $share ->setParameter(':id', $rootItem['id']) ->setParameter(':permissions', $permissions); $qb->execute(); - if ($itemType === 'file' || $itemType === 'folder') { - \OC_Hook::emit('OCP\Share', 'post_update_permissions', [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'shareType' => $shareType, - 'shareWith' => $shareWith, - 'uidOwner' => \OC_User::getUser(), - 'permissions' => $permissions, - 'path' => $rootItem['path'], - 'share' => $rootItem - ]); - } // Share id's to update with the new permissions $ids = []; @@ -1500,10 +1426,6 @@ protected static function unshareItem(array $item, $newParent = null) { 'itemParent' => $item['parent'], 'uidOwner' => $item['uid_owner'], ]; - if ($item['item_type'] === 'file' || $item['item_type'] === 'folder') { - $hookParams['fileSource'] = $item['file_source']; - $hookParams['fileTarget'] = $item['file_target']; - } \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams); $deletedShares = Helper::delete($item['id'], false, null, $newParent); @@ -1579,8 +1501,8 @@ private static function getCollectionItemTypes($itemType) { $collectionTypes[] = $type; } } - // TODO Add option for collections to be collection of themselves, only 'folder' does it now... - if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder')) { + // TODO Add option for collections to be collection of themselves... + if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection)) { unset($collectionTypes[0]); } // Return array if collections were found or the item type is a @@ -1666,41 +1588,28 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha if (!self::isEnabled()) { return []; } + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } $backend = self::getBackend($itemType); $collectionTypes = false; // Get filesystem root to add it to the file target and remove from the // file source, match file_source with the file cache - if ($itemType == 'file' || $itemType == 'folder') { - if ($uidOwner !== null) { - $root = \OC\Files\Filesystem::getRoot(); + $root = ''; + $collectionTypes = self::getCollectionItemTypes($itemType); + if ($includeCollections && !isset($item) && $collectionTypes) { + // If includeCollections is true, find collections of this item type, e.g. a music album contains songs + if (!in_array($itemType, $collectionTypes)) { + $itemTypes = array_merge([$itemType], $collectionTypes); } else { - $root = ''; - } - $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` '; - if (!isset($item)) { - $where .= ' AND `file_target` IS NOT NULL '; + $itemTypes = $collectionTypes; } - $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` '; - $fileDependent = true; - $queryArgs = []; + $placeholders = join(',', array_fill(0, count($itemTypes), '?')); + $where = ' WHERE `item_type` IN ('.$placeholders.'))'; + $queryArgs = $itemTypes; } else { - $fileDependent = false; - $root = ''; - $collectionTypes = self::getCollectionItemTypes($itemType); - if ($includeCollections && !isset($item) && $collectionTypes) { - // If includeCollections is true, find collections of this item type, e.g. a music album contains songs - if (!\in_array($itemType, $collectionTypes)) { - $itemTypes = \array_merge([$itemType], $collectionTypes); - } else { - $itemTypes = $collectionTypes; - } - $placeholders = \join(',', \array_fill(0, \count($itemTypes), '?')); - $where = ' WHERE `item_type` IN ('.$placeholders.'))'; - $queryArgs = $itemTypes; - } else { - $where = ' WHERE `item_type` = ?'; - $queryArgs = [$itemType]; - } + $where = ' WHERE `item_type` = ?'; + $queryArgs = [$itemType]; } if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { $where .= ' AND `share_type` != ?'; @@ -1741,21 +1650,13 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha $where .= ' AND `share_type` != ?'; $queryArgs[] = self::$shareTypeGroupUserUnique; } - if ($fileDependent) { - $column = 'file_source'; - } else { - $column = 'item_source'; - } + $column = 'item_source'; } else { - if ($fileDependent) { - $column = 'file_target'; - } else { - $column = 'item_target'; - } + $column = 'item_target'; } if (isset($item)) { $collectionTypes = self::getCollectionItemTypes($itemType); - if ($includeCollections && $collectionTypes && !\in_array('folder', $collectionTypes)) { + if ($includeCollections && $collectionTypes) { $where .= ' AND ('; } else { $where .= ' AND'; @@ -1763,24 +1664,14 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha // If looking for own shared items, check item_source else check item_target if (isset($uidOwner) || $itemShareWithBySource) { // If item type is a file, file source needs to be checked in case the item was converted - if ($fileDependent) { - $where .= ' `file_source` = ?'; - $column = 'file_source'; - } else { - $where .= ' `item_source` = ?'; - $column = 'item_source'; - } + $where .= ' `item_source` = ?'; + $column = 'item_source'; } else { - if ($fileDependent) { - $where .= ' `file_target` = ?'; - $item = \OC\Files\Filesystem::normalizePath($item); - } else { - $where .= ' `item_target` = ?'; - } + $where .= ' `item_target` = ?'; } $queryArgs[] = $item; - if ($includeCollections && $collectionTypes && !\in_array('folder', $collectionTypes)) { - $placeholders = \join(',', \array_fill(0, \count($collectionTypes), '?')); + if ($includeCollections && $collectionTypes) { + $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); $where .= ' OR `item_type` IN ('.$placeholders.'))'; $queryArgs = \array_merge($queryArgs, $collectionTypes); } @@ -1805,8 +1696,8 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha } else { $queryLimit = null; } - $select = self::createSelectStatement($format, $fileDependent, $uidOwner); - $root = \strlen($root); + $select = self::createSelectStatement($format, $uidOwner); + $root = strlen($root); $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit); $result = $query->execute($queryArgs); if ($result === false) { @@ -1821,9 +1712,6 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha while ($row = $result->fetchRow()) { self::transformDBResults($row); // Filter out duplicate group shares for users with unique targets - if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) { - continue; - } if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { $row['share_type'] = self::SHARE_TYPE_GROUP; $row['unique_name'] = true; // remember that we use a unique name for this user @@ -1946,7 +1834,7 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha $collectionItems = []; foreach ($items as &$row) { // Return only the item instead of a 2-dimensional array - if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { + if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType)) { if ($format == self::FORMAT_NONE) { return $row; } else { @@ -1954,7 +1842,7 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha } } // Check if this is a collection of the requested item type - if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && \in_array($row['item_type'], $collectionTypes)) { + if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof \OCP\Share_Backend_Collection) { // Collections can be inside collections, check if the item is a collection @@ -1963,29 +1851,14 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha } else { $collection = []; $collection['item_type'] = $row['item_type']; - if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { - $collection['path'] = \basename($row['path']); - } $row['collection'] = $collection; // Fetch all of the children sources $children = $collectionBackend->getChildren($row[$column]); foreach ($children as $child) { $childItem = $row; $childItem['item_type'] = $itemType; - if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') { - $childItem['item_source'] = $child['source']; - $childItem['item_target'] = $child['target']; - } - if ($backend instanceof \OCP\Share_Backend_File_Dependent) { - if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { - $childItem['file_source'] = $child['source']; - } else { // TODO is this really needed if we already know that we use the file backend? - $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); - $childItem['file_source'] = $meta['fileid']; - } - $childItem['file_target'] = - \OC\Files\Filesystem::normalizePath($child['file_path']); - } + $childItem['item_source'] = $child['source']; + $childItem['item_target'] = $child['target']; if (isset($item)) { if ($childItem[$column] == $item) { // Return only the item instead of a 2-dimensional array @@ -2037,20 +1910,6 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha }); return self::formatResult($items, $column, $backend, $format, $parameters); - } elseif ($includeCollections && $collectionTypes && \in_array('folder', $collectionTypes)) { - // FIXME: Thats a dirty hack to improve file sharing performance, - // see github issue #10588 for more details - // Need to find a solution which works for all back-ends - $collectionItems = []; - $collectionBackend = self::getBackend('folder'); - $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner); - foreach ($sharedParents as $parent) { - $collectionItems[] = $parent; - } - if ($limit === 1) { - return \reset($collectionItems); - } - return self::formatResult($collectionItems, $column, $backend, $format, $parameters); } return []; @@ -2064,7 +1923,10 @@ public static function getItems($itemType, $item = null, $shareType = null, $sha * @return array of grouped items */ protected static function groupItems($items, $itemType) { - $fileSharing = ($itemType === 'file' || $itemType === 'folder') ? true : false; + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } + $fileSharing = false; $result = []; @@ -2112,6 +1974,10 @@ protected static function groupItems($items, $itemType) { */ private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) { + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } + $queriesToExecute = []; $suggestedItemTarget = null; $groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = ''; @@ -2191,7 +2057,7 @@ private static function put($itemType, $itemSource, $shareType, $shareWith, $uid } foreach ($users as $user) { - $sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource; + $sourceId = $itemSource; $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user); $userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType; @@ -2207,25 +2073,6 @@ private static function put($itemType, $itemSource, $shareType, $shareWith, $uid } elseif (!$sourceExists && !$isGroupShare) { $itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user, $uidOwner, $suggestedItemTarget, $parent); - if (isset($fileSource)) { - if ($parentFolder) { - if ($parentFolder === true) { - $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user, - $uidOwner, $suggestedFileTarget, $parent); - if ($fileTarget != $groupFileTarget) { - $parentFolders[$user]['folder'] = $fileTarget; - } - } elseif (isset($parentFolder[$user])) { - $fileTarget = $parentFolder[$user]['folder'].$itemSource; - $parent = $parentFolder[$user]['id']; - } - } else { - $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, - $user, $uidOwner, $suggestedFileTarget, $parent); - } - } else { - $fileTarget = null; - } } else { // group share which doesn't exists until now, check if we need a unique target for this user @@ -2234,15 +2081,7 @@ private static function put($itemType, $itemSource, $shareType, $shareWith, $uid $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 === $groupFileTarget)) { + if (($itemTarget === $groupItemTarget)) { continue; } } @@ -2310,12 +2149,15 @@ private static function put($itemType, $itemSource, $shareType, $shareWith, $uid * @param null|\DateTime $expirationDate */ private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) { + if ($itemType === 'file' || $itemType === 'folder') { + throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); + } $backend = self::getBackend($itemType); $l = \OC::$server->getL10N('lib'); $result = []; - $column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source'; + $column = 'item_source'; $checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true); if ($checkReshare) { @@ -2357,11 +2199,11 @@ private static function checkReshare($itemType, $itemSource, $shareType, $shareW $result['suggestedItemTarget'] = $checkReshare['item_target']; $result['suggestedFileTarget'] = $checkReshare['file_target']; } else { - $result['filePath'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $backend->getFilePath($itemSource, $uidOwner) : null; + $result['filePath'] = null; $result['suggestedItemTarget'] = null; $result['suggestedFileTarget'] = null; $result['itemSource'] = $itemSource; - $result['fileSource'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $itemSource : null; + $result['fileSource'] = null; } } } else { @@ -2384,25 +2226,8 @@ private static function checkReshare($itemType, $itemSource, $shareType, $shareW \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSource, $itemType), \OCP\Util::DEBUG); 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', [$itemSource]); - - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSource), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } else { - $result['filePath'] = null; - $result['fileSource'] = null; - } + $result['filePath'] = null; + $result['fileSource'] = null; } return $result; @@ -2485,47 +2310,17 @@ public static function checkPasswordProtectedShare(array $linkItem) { /** * construct select statement * @param int $format - * @param boolean $fileDependent ist it a file/folder share or a generla share * @param string $uidOwner * @return string select statement */ - private static function createSelectStatement($format, $fileDependent, $uidOwner = null) { + private static function createSelectStatement($format, $uidOwner = null) { $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`, `*PREFIX*share`.`permissions`, ' - . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`, ' - . '`uid_initiator`'; - } else { - $select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`'; - } + $select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`'; } else { if (isset($uidOwner)) { - if ($fileDependent) { - $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,' - . ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,' - . ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, ' - . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`'; - } else { - $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,' - . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`'; - } - } else { - if ($fileDependent) { - if ($format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_GET_FOLDER_CONTENTS || $format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_FILE_APP_ROOT) { - $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, ' - . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, ' - . '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' - . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`'; - } else { - $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,' - . '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,' - . '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,' - . '`stime`, `expiration`, `token`, `storage`, `mail_send`,' - . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`'; - } - } + $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,' + . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`'; } } return $select; From 3d52560265e38676c65cfab4e151fa33b00a0dfc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 11 Nov 2016 12:53:19 +0100 Subject: [PATCH 03/21] Decouple Sharees API from Share backend --- .../lib/Controller/ShareesController.php | 12 +++++++++++- apps/files_sharing/tests/API/ShareesTest.php | 14 +++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesController.php b/apps/files_sharing/lib/Controller/ShareesController.php index 459659b58427..2c8758074636 100644 --- a/apps/files_sharing/lib/Controller/ShareesController.php +++ b/apps/files_sharing/lib/Controller/ShareesController.php @@ -41,6 +41,7 @@ use OCP\IUserSession; use OCP\Share; use OCA\Files_Sharing\SharingBlacklist; +use OCA\FederatedFileSharing\FederatedShareProvider; class ShareesController extends OCSController { @@ -71,6 +72,9 @@ class ShareesController extends OCSController { /** @var \OCP\Share\IManager */ protected $shareManager; + /** @var FederatedShareProvider */ + protected $federatedShareProvider; + /** @var bool */ protected $shareWithGroupOnly = false; @@ -132,7 +136,9 @@ public function __construct($appName, IURLGenerator $urlGenerator, ILogger $logger, \OCP\Share\IManager $shareManager, - SharingBlacklist $sharingBlacklist) { + SharingBlacklist $sharingBlacklist, + FederatedShareProvider $federatedShareProvider + ) { parent::__construct($appName, $request); $this->groupManager = $groupManager; @@ -146,6 +152,7 @@ public function __construct($appName, $this->shareManager = $shareManager; $this->sharingBlacklist = $sharingBlacklist; $this->additionalInfoField = $this->config->getAppValue('core', 'user_additional_info_field', ''); + $this->federatedShareProvider = $federatedShareProvider; } /** @@ -579,6 +586,9 @@ public function search($search = '', $itemType = null, $page = 1, $perPage = 200 */ protected function isRemoteSharingAllowed($itemType) { try { + if ($itemType === 'file' || $itemType === 'folder') { + return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled(); + } $backend = Share::getBackend($itemType); return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE); } catch (\Exception $e) { diff --git a/apps/files_sharing/tests/API/ShareesTest.php b/apps/files_sharing/tests/API/ShareesTest.php index a08b0daf72db..a2f5ba78ff64 100644 --- a/apps/files_sharing/tests/API/ShareesTest.php +++ b/apps/files_sharing/tests/API/ShareesTest.php @@ -41,6 +41,7 @@ use OCP\IUserManager; use OCP\IUserSession; use OCP\Share; +use OCA\FederatedFileSharing\FederatedShareProvider; /** * Class ShareesTest @@ -107,6 +108,10 @@ protected function setUp() { $this->config = $this->getMockBuilder(IConfig::class) ->disableOriginalConstructor() ->getMock(); + $federatedShareProviderMock = $this->getMockBuilder(FederatedShareProvider::class)->disableOriginalConstructor()->getMock(); + $federatedShareProviderMock->expects($this->any()) + ->method('isOutgoingServer2serverShareEnabled') + ->willReturn(true); $this->sharingBlacklist = $this->getMockBuilder(SharingBlacklist::class) ->disableOriginalConstructor() @@ -123,7 +128,8 @@ protected function setUp() { $this->getMockBuilder(IURLGenerator::class)->disableOriginalConstructor()->getMock(), $this->getMockBuilder(ILogger::class)->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->sharingBlacklist + $this->sharingBlacklist, + $federatedShareProviderMock ); } @@ -1523,7 +1529,8 @@ public function testSearchInvalid($message, $search = '', $itemType = null, $pag $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->sharingBlacklist + $this->sharingBlacklist, + $this->getMockBuilder(FederatedShareProvider::class)->disableOriginalConstructor()->getMock() ]) ->setMethods(['searchSharees', 'isRemoteSharingAllowed']) ->getMock(); @@ -1673,7 +1680,8 @@ public function testSearchSharees($searchTerm, $itemType, array $shareTypes, $pa $this->getMockBuilder(IURLGenerator::class)->disableOriginalConstructor()->getMock(), $this->getMockBuilder(ILogger::class)->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->sharingBlacklist + $this->sharingBlacklist, + $this->getMockBuilder(FederatedShareProvider::class)->disableOriginalConstructor()->getMock() ]) ->setMethods(['getShareesForShareIds', 'getUsers', 'getGroups', 'getRemote']) ->getMock(); From d10252a32e24335998d843fdff08b2b86ad507fa Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 11 Nov 2016 17:13:25 +0100 Subject: [PATCH 04/21] Moved sharing related tests to Share2.0 --- apps/files_sharing/tests/SharedStorageTest.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/files_sharing/tests/SharedStorageTest.php b/apps/files_sharing/tests/SharedStorageTest.php index 7b66dad6e12e..4f4e601f2c16 100644 --- a/apps/files_sharing/tests/SharedStorageTest.php +++ b/apps/files_sharing/tests/SharedStorageTest.php @@ -291,10 +291,7 @@ public function testFopenWithCreateOnlyPermission() { $this->assertFalse($user2View->unlink($this->folder . '/existing.txt')); //cleanup - self::loginHelper(self::TEST_FILES_SHARING_API_USER1); - $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, - self::TEST_FILES_SHARING_API_USER2); - $this->assertTrue($result); + $this->shareManager->deleteShare($share); } public function testFopenWithUpdateOnlyPermission() { From 4f121dc928a1b164fc6d99b8d749ad806dcd094f Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 16 Dec 2016 15:40:41 +0100 Subject: [PATCH 05/21] Fix expire shares job --- apps/files_sharing/lib/ExpireSharesJob.php | 39 +++++++++++++++---- .../tests/ExpireSharesJobTest.php | 19 +++++---- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/apps/files_sharing/lib/ExpireSharesJob.php b/apps/files_sharing/lib/ExpireSharesJob.php index 80c05f4b1dab..eacb15c706ee 100644 --- a/apps/files_sharing/lib/ExpireSharesJob.php +++ b/apps/files_sharing/lib/ExpireSharesJob.php @@ -22,6 +22,9 @@ namespace OCA\Files_Sharing; use OC\BackgroundJob\TimedJob; +use OCP\Share\IManager; +use OCP\IDBConnection; +use OCP\Share\Exceptions\ShareNotFound; /** * Delete all shares that are expired @@ -29,9 +32,27 @@ class ExpireSharesJob extends TimedJob { /** - * sets the correct interval for this timed job + * Database connection + * + * @var IDBConnection + */ + private $connection; + + /** + * Share manager + * + * @var IManager + */ + private $shareManager; + + /** + * Constructor + * + * @param IDBConnection $connection connection */ - public function __construct() { + public function __construct(IDBConnection $connection, IManager $shareManager) { + $this->connection = $connection; + $this->shareManager = $shareManager; // Run once a day $this->setInterval(24 * 60 * 60); } @@ -43,15 +64,12 @@ public function __construct() { */ public function run($argument) { $connection = \OC::$server->getDatabaseConnection(); - $logger = \OC::$server->getLogger(); - //Current time + // Current time $now = new \DateTime(); $now = $now->format('Y-m-d H:i:s'); - /* - * Expire file link shares only (for now) - */ + // Expire file link shares only (for now) $qb = $connection->getQueryBuilder(); $qb->select('id', 'file_source', 'uid_owner', 'item_type') ->from('share') @@ -68,7 +86,12 @@ public function run($argument) { $shares = $qb->execute(); while ($share = $shares->fetch()) { - \OCP\Share::unshare($share['item_type'], $share['file_source'], \OCP\Share::SHARE_TYPE_LINK, null, $share['uid_owner']); + try { + // the getShareById already deletes those automatically + $this->shareManager->getShareById('ocinternal:' . $share['id']); + } catch (ShareNotFound $e) { + // ignore, already deleted + } } $shares->closeCursor(); } diff --git a/apps/files_sharing/tests/ExpireSharesJobTest.php b/apps/files_sharing/tests/ExpireSharesJobTest.php index 0091cd85fb17..3119d71f2071 100644 --- a/apps/files_sharing/tests/ExpireSharesJobTest.php +++ b/apps/files_sharing/tests/ExpireSharesJobTest.php @@ -24,6 +24,7 @@ namespace OCA\Files_Sharing\Tests; use OCA\Files_Sharing\ExpireSharesJob; +use OCP\Share\IManager; /** * Class ExpireSharesJobTest @@ -44,6 +45,11 @@ class ExpireSharesJobTest extends \Test\TestCase { */ private $connection; + /** + * @var IManager + */ + private $shareManager; + /** * @var string */ @@ -57,6 +63,7 @@ class ExpireSharesJobTest extends \Test\TestCase { protected function setup() { parent::setUp(); + $this->shareManager = \OC::$server->getShareManager(); $this->connection = \OC::$server->getDatabaseConnection(); // clear occasional leftover shares from other tests $this->connection->executeUpdate('DELETE FROM `*PREFIX*share`'); @@ -70,7 +77,7 @@ protected function setup() { \OC::registerShareHooks(); - $this->job = new ExpireSharesJob(); + $this->job = new ExpireSharesJob($this->connection, $this->shareManager); } protected function tearDown() { @@ -135,13 +142,12 @@ public function testExpireLinkShare($addExpiration, $interval, $addInterval, $sh $userFolder = \OC::$server->getUserFolder($this->user1); $sharedFolder = $userFolder->newFolder('test'); - $shareManager = \OC::$server->getShareManager(); - $share = $shareManager->newShare(); + $share = $this->shareManager->newShare(); $share->setSharedBy($this->user1); $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); $share->setNode($sharedFolder); $share->setPermissions(\OCP\Constants::PERMISSION_READ); - $shareManager->createShare($share); + $this->shareManager->createShare($share); $shares = $this->getShares(); $this->assertCount(1, $shares); @@ -190,14 +196,13 @@ public function testDoNotExpireOtherShares() { $userFolder = \OC::$server->getUserFolder($this->user1); $sharedFolder = $userFolder->newFolder('test'); - $shareManager = \OC::$server->getShareManager(); - $share = $shareManager->newShare(); + $share = $this->shareManager->newShare(); $share->setSharedBy($this->user1); $share->setSharedWith($this->user2); $share->setShareType(\OCP\Share::SHARE_TYPE_USER); $share->setNode($sharedFolder); $share->setPermissions(\OCP\Constants::PERMISSION_READ); - $shareManager->createShare($share); + $this->shareManager->createShare($share); $shares = $this->getShares(); $this->assertCount(1, $shares); From cda95d6fee2d57de386626eedbfb03ebc2325fea Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 23 Dec 2016 10:25:45 +0100 Subject: [PATCH 06/21] Remove obsolete sharing tests These are either obsolete or exist in a different form inside the share manager tests. --- apps/files_sharing/tests/ApiTest.php | 84 ---------------------------- 1 file changed, 84 deletions(-) diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php index 336f847d42f4..b2f7a11ad17c 100644 --- a/apps/files_sharing/tests/ApiTest.php +++ b/apps/files_sharing/tests/ApiTest.php @@ -1345,90 +1345,6 @@ public function testShareStorageMountPoint() { \OC_Hook::clear('OC_Filesystem', 'post_initMountPoints', '\OCA\Files_Sharing\Tests\ApiTest', 'initTestMountPointsHook'); } - /** - * @expectedException \Exception - */ - public function testShareNonExisting() { - self::loginHelper(self::TEST_FILES_SHARING_API_USER1); - - $id = PHP_INT_MAX - 1; - Share::shareItem('file', $id, Share::SHARE_TYPE_LINK, self::TEST_FILES_SHARING_API_USER2, 31); - } - - /** - * @expectedException \Exception - */ - public function testShareNotOwner() { - self::loginHelper(self::TEST_FILES_SHARING_API_USER2); - \OC\Files\Filesystem::file_put_contents('foo.txt', 'bar'); - $info = \OC\Files\Filesystem::getFileInfo('foo.txt'); - - self::loginHelper(self::TEST_FILES_SHARING_API_USER1); - - Share::shareItem('file', $info->getId(), Share::SHARE_TYPE_LINK, self::TEST_FILES_SHARING_API_USER2, 31); - } - - public function testDefaultExpireDate() { - self::loginHelper(self::TEST_FILES_SHARING_API_USER1); - - // TODO drop this once all code paths use the DI version - otherwise - // the cache inside this config object is out of date because - // OC_Appconfig is used and bypasses this cache which lead to integrity - // constraint violations - $config = \OC::$server->getConfig(); - $config->deleteAppValue('core', 'shareapi_default_expire_date'); - $config->deleteAppValue('core', 'shareapi_enforce_expire_date'); - $config->deleteAppValue('core', 'shareapi_expire_after_n_days'); - - $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); - $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); - $config->setAppValue('core', 'shareapi_expire_after_n_days', '2'); - - // default expire date is set to 2 days - // the time when the share was created is set to 3 days in the past - // user defined expire date is set to +2 days from now on - // -> link should be already expired by the default expire date but the user - // share should still exists. - $now = \time(); - $dateFormat = 'Y-m-d H:i:s'; - $shareCreated = $now - 3 * 24 * 60 * 60; - $expireDate = \date($dateFormat, $now + 2 * 24 * 60 * 60); - - $info = \OC\Files\Filesystem::getFileInfo($this->filename); - $this->assertInstanceOf(\OC\Files\FileInfo::class, $info); - - $result = Share::shareItem('file', $info->getId(), Share::SHARE_TYPE_LINK, null, Constants::PERMISSION_READ); - $this->assertInternalType('string', $result); - - $result = Share::shareItem('file', $info->getId(), Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); - $this->assertTrue($result); - - $result = Share::setExpirationDate('file', $info->getId(), $expireDate, $now); - $this->assertTrue($result); - - //manipulate stime so that both shares are older then the default expire date - $statement = "UPDATE `*PREFIX*share` SET `stime` = ? WHERE `share_type` = ?"; - $query = \OCP\DB::prepare($statement); - $result = $query->execute([$shareCreated, Share::SHARE_TYPE_LINK]); - $this->assertSame(1, $result); - $query = \OCP\DB::prepare($statement); - $result = $query->execute([$shareCreated, Share::SHARE_TYPE_USER]); - $this->assertSame(1, $result); - - // now the link share should expire because of enforced default expire date - // the user share should still exist - $result = Share::getItemShared('file', $info->getId()); - $this->assertInternalType('array', $result); - $this->assertCount(1, $result); - $share = \reset($result); - $this->assertSame(Share::SHARE_TYPE_USER, $share['share_type']); - - //cleanup - $result = Share::unshare('file', $info->getId(), Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); - $this->assertTrue($result); - $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); - $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); - } public function datesProvider() { $date = new \DateTime(); From ae2f73f73fc4a90aa30c94ec477d1458344c3a58 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 20 Jan 2017 10:09:11 +0100 Subject: [PATCH 07/21] Fix ExpireShareJobs --- apps/files_sharing/lib/ExpireSharesJob.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/ExpireSharesJob.php b/apps/files_sharing/lib/ExpireSharesJob.php index eacb15c706ee..f56a79cfad42 100644 --- a/apps/files_sharing/lib/ExpireSharesJob.php +++ b/apps/files_sharing/lib/ExpireSharesJob.php @@ -25,6 +25,7 @@ use OCP\Share\IManager; use OCP\IDBConnection; use OCP\Share\Exceptions\ShareNotFound; +use OCP\ILogger; /** * Delete all shares that are expired @@ -45,14 +46,22 @@ class ExpireSharesJob extends TimedJob { */ private $shareManager; + /** + * Logger + * + * @var ILogger + */ + private $logger; + /** * Constructor * * @param IDBConnection $connection connection */ - public function __construct(IDBConnection $connection, IManager $shareManager) { + public function __construct(IDBConnection $connection, IManager $shareManager, ILogger $logger) { $this->connection = $connection; $this->shareManager = $shareManager; + $this->logger = $logger; // Run once a day $this->setInterval(24 * 60 * 60); } @@ -63,14 +72,12 @@ public function __construct(IDBConnection $connection, IManager $shareManager) { * @param array $argument unused argument */ public function run($argument) { - $connection = \OC::$server->getDatabaseConnection(); - // Current time $now = new \DateTime(); $now = $now->format('Y-m-d H:i:s'); // Expire file link shares only (for now) - $qb = $connection->getQueryBuilder(); + $qb = $this->connection->getQueryBuilder(); $qb->select('id', 'file_source', 'uid_owner', 'item_type') ->from('share') ->where( @@ -91,6 +98,7 @@ public function run($argument) { $this->shareManager->getShareById('ocinternal:' . $share['id']); } catch (ShareNotFound $e) { // ignore, already deleted + $this->logger->debug('ExpireSharesJob: Share with id "' . $share['id'] . '" was already deleted', ['app' => 'files_sharing']); } } $shares->closeCursor(); From 3341c3a0c6504c11b357b7dba1d4e28ea10d31dc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 23 Feb 2018 15:03:31 +0100 Subject: [PATCH 08/21] Properly load JS files related to sharing --- lib/private/legacy/template.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php index 5fa7db8f85ca..eb3cbe378ce9 100644 --- a/lib/private/legacy/template.php +++ b/lib/private/legacy/template.php @@ -192,6 +192,21 @@ public static function initTemplateEngine($renderAs) { \OCP\Util::addScript('files/iedavclient'); } + \OCP\Util::addScript('core', 'shareconfigmodel'); + \OCP\Util::addScript('core', 'sharemodel'); + \OCP\Util::addScript('core', 'sharescollection'); + \OCP\Util::addScript('core', 'shareitemmodel'); + \OCP\Util::addScript('core', 'sharedialogresharerinfoview'); + \OCP\Util::addScript('core', 'sharedialoglinklistview'); + \OCP\Util::addScript('core', 'sharedialoglinkshareview'); + \OCP\Util::addScript('core', 'sharedialogmailview'); + \OCP\Util::addScript('core', 'sharedialoglinksocialview'); + \OCP\Util::addScript('core', 'sharedialogexpirationview'); + \OCP\Util::addScript('core', 'sharedialogshareelistview'); + \OCP\Util::addScript('core', 'sharedialogview'); + \OCP\Util::addScript('core', 'share'); + \OCP\Util::addStyle('core', 'share'); + self::$initTemplateEngineFirstRun = false; } } From 01abc3c7911606b290e46bb13516a158d8a4c382 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:05:03 +0200 Subject: [PATCH 09/21] Remove old Share::shareItem() --- .../tests/DeleteOrphanedSharesJobTest.php | 17 -- lib/private/Share/Share.php | 267 ------------------ lib/public/Share.php | 19 -- 3 files changed, 303 deletions(-) diff --git a/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php b/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php index 508b51caa1a0..5350507101bf 100644 --- a/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php +++ b/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php @@ -153,21 +153,4 @@ public function testClearShares() { $this->assertCount(0, $this->getShares(), 'Orphaned shares deleted'); } - - public function testKeepNonFileShares() { - $this->loginAsUser($this->user1); - - \OCP\Share::registerBackend('test', 'Test\Share\Backend'); - - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), - 'Failed asserting that user 1 successfully shared something with user 2.' - ); - - $this->assertCount(1, $this->getShares()); - - $this->job->run([]); - - $this->assertCount(1, $this->getShares(), 'Non-file shares kept'); - } } diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 449d9eac3b01..7f504a41829a 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -584,273 +584,6 @@ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $in return $users; } - /** - * Share an item with a user, group, or via private link - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param int $permissions CRUDS - * @param string $itemSourceName - * @param \DateTime $expirationDate - * @param bool $passwordChanged - * @return boolean|string Returns true on success or false on failure, Returns token on success for links - * @throws \OC\HintException when the share type is remote and the shareWith is invalid - * @throws \Exception - */ - public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null, $passwordChanged = null) { - $backend = self::getBackend($itemType); - $l = \OC::$server->getL10N('lib'); - - if ($backend->isShareTypeAllowed($shareType) === false) { - $message = 'Sharing %s failed, because the backend does not allow shares from type %i'; - $message_t = $l->t('Sharing %s failed, because the backend does not allow shares from type %i', [$itemSourceName, $shareType]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareType), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - $uidOwner = \OC_User::getUser(); - $shareWithinGroupOnly = self::shareWithGroupMembersOnly(); - $shareWithMembershipGroupOnly = self::shareWithMembershipGroupOnly(); - - if ($itemSourceName === null) { - $itemSourceName = $itemSource; - } - $itemName = $itemSourceName; - - //Validate expirationDate - if ($expirationDate !== null) { - try { - /* - * Reuse the validateExpireDate. - * We have to pass time() since the second arg is the time - * the item was shared, since it is not shared yet we just use - * the current time. - */ - $expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), \time(), $itemType, $itemSource); - } catch (\Exception $e) { - throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404); - } - } - - // Verify share type and sharing conditions are met - if ($shareType === self::SHARE_TYPE_USER) { - if ($shareWith == $uidOwner) { - $message = 'Sharing %s failed, because you can not share with yourself'; - $message_t = $l->t('Sharing %s failed, because you can not share with yourself', [$itemName]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - if (!\OC_User::userExists($shareWith)) { - $message = 'Sharing %s failed, because the user %s does not exist'; - $message_t = $l->t('Sharing %s failed, because the user %s does not exist', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - if ($shareWithinGroupOnly) { - $inGroup = \array_intersect(self::getGroupsForUser($uidOwner), self::getGroupsForUser($shareWith)); - if (empty($inGroup)) { - $message = 'Sharing %s failed, because the user ' - .'%s is not a member of any groups that %s is a member of'; - $message_t = $l->t('Sharing %s failed, because the user %s is not a member of any groups that %s is a member of', [$itemName, $shareWith, $uidOwner]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemName, $shareWith, $uidOwner), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - // Check if the item source is already shared with the user, either from the same owner or a different user - if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, - $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) { - // Only allow the same share to occur again if it is the same - // owner and is not a user share, this use case is for increasing - // permissions for a specific user - if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { - $message = 'Sharing %s failed, because this item is already shared with %s'; - $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_USER, - $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) { - // Only allow the same share to occur again if it is the same - // owner and is not a user share, this use case is for increasing - // permissions for a specific user - if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { - $message = 'Sharing %s failed, because this item is already shared with user %s'; - $message_t = $l->t('Sharing %s failed, because this item is already shared with user %s', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::ERROR); - throw new \Exception($message_t); - } - } - } elseif ($shareType === self::SHARE_TYPE_GROUP) { - if (!\OC::$server->getGroupManager()->groupExists($shareWith)) { - $message = 'Sharing %s failed, because the group %s does not exist'; - $message_t = $l->t('Sharing %s failed, because the group %s does not exist', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - if ($shareWithMembershipGroupOnly && !\OC::$server->getGroupManager()->inGroup($uidOwner, $shareWith)) { - $message = 'Sharing %s failed, because ' - .'%s is not a member of the group %s'; - $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', [$itemSourceName, $uidOwner, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - // Check if the item source is already shared with the group, either from the same owner or a different user - // The check for each user in the group is done inside the put() function - if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith, - null, self::FORMAT_NONE, null, 1, true, true)) { - if ($checkExists['share_with'] === $shareWith && $checkExists['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) { - $message = 'Sharing %s failed, because this item is already shared with %s'; - $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - // Convert share with into an array with the keys group and users - $group = $shareWith; - $usersInGroup = \OC::$server->getGroupManager()->get($group)->getUsers(); - $usersInGroup = \array_values(\array_map(function (IUser $u) { - return $u->getUID(); - }, $usersInGroup)); - $shareWith = []; - $shareWith['group'] = $group; - $shareWith['users'] = \array_diff($usersInGroup, [$uidOwner]); - } elseif ($shareType === self::SHARE_TYPE_LINK) { - $updateExistingShare = false; - if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') == 'yes') { - - // IF the password is changed via the old ajax endpoint verify it before deleting the old share - if ($passwordChanged === true) { - self::verifyPassword($shareWith); - } - - // when updating a link share - // FIXME Don't delete link if we update it - if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, - $uidOwner, self::FORMAT_NONE, null, 1)) { - // remember old token - $oldToken = $checkExists['token']; - $oldPermissions = $checkExists['permissions']; - //delete the old share - Helper::delete($checkExists['id']); - $updateExistingShare = true; - } - - if ($passwordChanged === null) { - // Generate hash of password - same method as user passwords - if (\is_string($shareWith) && $shareWith !== '') { - self::verifyPassword($shareWith); - $shareWith = \OC::$server->getHasher()->hash($shareWith); - } else { - // reuse the already set password, but only if we change permissions - // otherwise the user disabled the password protection - if ($checkExists && (int)$permissions !== (int)$oldPermissions) { - $shareWith = $checkExists['share_with']; - } - } - } else { - if ($passwordChanged === true) { - if (\is_string($shareWith) && $shareWith !== '') { - self::verifyPassword($shareWith); - $shareWith = \OC::$server->getHasher()->hash($shareWith); - } - } elseif ($updateExistingShare) { - $shareWith = $checkExists['share_with']; - } - } - - if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) { - $message = 'You need to provide a password to create a public link, only protected links are allowed'; - $message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed'); - \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - if ($updateExistingShare === false && - self::isDefaultExpireDateEnabled() && - empty($expirationDate)) { - $expirationDate = Helper::calcExpireDate(); - } - - // Generate token - if (isset($oldToken)) { - $token = $oldToken; - } else { - $token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, - \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER. - \OCP\Security\ISecureRandom::CHAR_DIGITS - ); - } - $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, - null, $token, $itemSourceName, $expirationDate); - if ($result) { - return $token; - } else { - return false; - } - } - $message = 'Sharing %s failed, because sharing with links is not allowed'; - $message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', [$itemSourceName]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } elseif ($shareType === self::SHARE_TYPE_REMOTE) { - - /* - * Check if item is not already shared with the remote user - */ - if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_REMOTE, - $shareWith, $uidOwner, self::FORMAT_NONE, null, 1, true, true)) { - $message = 'Sharing %s failed, because this item is already shared with %s'; - $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', [$itemSourceName, $shareWith]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - // don't allow federated shares if source and target server are the same - list($user, $remote) = Helper::splitUserRemote($shareWith); - $currentServer = self::removeProtocolFromUrl(\OC::$server->getURLGenerator()->getAbsoluteURL('/')); - $currentUser = \OC::$server->getUserSession()->getUser()->getUID(); - if (Helper::isSameUserOnSameServer($user, $remote, $currentUser, $currentServer)) { - $message = 'Not allowed to create a federated share with the same user.'; - $message_t = $l->t('Not allowed to create a federated share with the same user'); - \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - $token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER . - \OCP\Security\ISecureRandom::CHAR_DIGITS); - - $shareWith = $user . '@' . $remote; - $shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName); - - $send = false; - if ($shareId) { - $send = self::sendRemoteShare($token, $shareWith, $itemSourceName, $shareId, $uidOwner); - } - - if ($send === false) { - $currentUser = \OC::$server->getUserSession()->getUser()->getUID(); - self::unshare($itemType, $itemSource, $shareType, $shareWith, $currentUser); - $message_t = $l->t('Sharing %s failed, could not find %s, check spelling and server availability.', [$itemSourceName, $shareWith]); - throw new \Exception($message_t); - } - - return $send; - } else { - // Future share types need to include their own conditions - $message = 'Share type %s is not valid for %s'; - $message_t = $l->t('Share type %s is not valid for %s', [$shareType, $itemSource]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $shareType, $itemSource), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - // Put the item into the database - $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate); - - return $result ? true : false; - } - /** * Unshare an item from a user, group, or delete a private link * @param string $itemType diff --git a/lib/public/Share.php b/lib/public/Share.php index 723acfe14b92..5b3fb423f34a 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -242,25 +242,6 @@ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $in return \OC\Share\Share::getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections, $checkExpireDate); } - /** - * Share an item with a user, group, or via private link - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param int $permissions CRUDS - * @param string $itemSourceName - * @param \DateTime $expirationDate - * @param bool $passwordChanged - * @return bool|string Returns true on success or false on failure, Returns token on success for links - * @throws \OC\HintException when the share type is remote and the shareWith is invalid - * @throws \Exception - * @since 5.0.0 - parameter $itemSourceName was added in 6.0.0, parameter $expirationDate was added in 7.0.0, parameter $passwordChanged added in 9.0.0 - */ - public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null, $passwordChanged = null) { - return \OC\Share\Share::shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName, $expirationDate, $passwordChanged); - } - /** * Unshare an item from a user, group, or delete a private link * @param string $itemType From 87ce05f523edb0e9e099ec908c602782aa76bbe1 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:06:05 +0200 Subject: [PATCH 10/21] Remove old Share::unshareAll() --- lib/private/Share/Share.php | 32 -------------------------------- lib/public/Share.php | 11 ----------- 2 files changed, 43 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 7f504a41829a..36feff5cd2fc 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -624,38 +624,6 @@ public static function unshare($itemType, $itemSource, $shareType, $shareWith, $ return false; } - /** - * Unshare an item from all users, groups, and remove all links - * @param string $itemType - * @param string $itemSource - * @return boolean true on success or false on failure - */ - public static function unshareAll($itemType, $itemSource) { - // Get all of the owners of shares of this item. - $query = \OC_DB::prepare('SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?'); - $result = $query->execute([$itemType, $itemSource]); - $shares = []; - // Add each owner's shares to the array of all shares for this item. - while ($row = $result->fetchRow()) { - $shares = \array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner'])); - } - if (!empty($shares)) { - // Pass all the vars we have for now, they may be useful - $hookParams = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'shares' => $shares, - ]; - \OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams); - foreach ($shares as $share) { - self::unshareItem($share); - } - \OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams); - return true; - } - return false; - } - /** * Unshare an item shared with the current user * @param string $itemType diff --git a/lib/public/Share.php b/lib/public/Share.php index 5b3fb423f34a..1cb89a71603c 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -256,17 +256,6 @@ public static function unshare($itemType, $itemSource, $shareType, $shareWith, $ return \OC\Share\Share::unshare($itemType, $itemSource, $shareType, $shareWith, $owner); } - /** - * Unshare an item from all users, groups, and remove all links - * @param string $itemType - * @param string $itemSource - * @return boolean true on success or false on failure - * @since 5.0.0 - */ - public static function unshareAll($itemType, $itemSource) { - return \OC\Share\Share::unshareAll($itemType, $itemSource); - } - /** * Unshare an item shared with the current user * @param string $itemType From c765b712615570fc6b106df6890affee78e01840 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:08:18 +0200 Subject: [PATCH 11/21] Remove old Share::registerBackend() --- lib/private/Share/Share.php | 29 ----------------------------- lib/public/Share.php | 14 -------------- 2 files changed, 43 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 36feff5cd2fc..8320897319f6 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -75,35 +75,6 @@ class Share extends Constants { * @see lib/public/constants.php */ - /** - * Register a sharing backend class that implements OCP\Share_Backend for an item type - * @param string $itemType Item type - * @param string $class Backend class - * @param string $collectionOf (optional) Depends on item type - * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files - * @return boolean true if backend is registered or false if error - */ - public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) { - if (self::isEnabled()) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - if (!isset(self::$backendTypes[$itemType])) { - self::$backendTypes[$itemType] = [ - 'class' => $class, - 'collectionOf' => $collectionOf, - 'supportedFileExtensions' => $supportedFileExtensions - ]; - return true; - } - \OCP\Util::writeLog('OCP\Share', - 'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class'] - .' is already registered for '.$itemType, - \OCP\Util::WARN); - } - return false; - } - /** * Check if the Share API is enabled * @return boolean true if enabled or false diff --git a/lib/public/Share.php b/lib/public/Share.php index 1cb89a71603c..49e65d17f0e5 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -50,20 +50,6 @@ * @since 5.0.0 */ class Share extends \OC\Share\Constants { - - /** - * Register a sharing backend class that implements OCP\Share_Backend for an item type - * @param string $itemType Item type - * @param string $class Backend class - * @param string $collectionOf (optional) Depends on item type - * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files - * @return boolean true if backend is registered or false if error - * @since 5.0.0 - */ - public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) { - return \OC\Share\Share::registerBackend($itemType, $class, $collectionOf, $supportedFileExtensions); - } - /** * Check if the Share API is enabled * @return boolean true if enabled or false From 4b00b1084181a44e59e3b95d2b8a3f26136e0229 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:09:55 +0200 Subject: [PATCH 12/21] Remove Share::unshare() and Share::unshareFromSelf() --- lib/private/Share/Share.php | 139 ------------------------------------ lib/public/Share.php | 28 -------- 2 files changed, 167 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 8320897319f6..cd94554f1b7d 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -555,145 +555,6 @@ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $in return $users; } - /** - * Unshare an item from a user, group, or delete a private link - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param string $owner owner of the share, if null the current user is used - * @return boolean true on success or false on failure - */ - public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) { - - // check if it is a valid itemType - self::getBackend($itemType); - - $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $owner, $shareType); - - $toDelete = []; - $newParent = null; - $currentUser = $owner ? $owner : \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 - } elseif ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) { - $newParent = $item['parent']; - } else { - $newParent = $item['id']; - } - } - - if (!empty($toDelete)) { - self::unshareItem($toDelete, $newParent); - return true; - } - return false; - } - - /** - * Unshare an item shared with the current user - * @param string $itemType - * @param string $itemOrigin Item target or source - * @param boolean $originIsSource true if $itemOrigin is the source, false if $itemOrigin is the target (optional) - * @return boolean true on success or false on failure - * - * Unsharing from self is not allowed for items inside collections - */ - public static function unshareFromSelf($itemType, $itemOrigin, $originIsSource = false) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - $originType = ($originIsSource) ? 'source' : 'target'; - $uid = \OCP\User::getUser(); - - $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?'; - - $query = \OCP\DB::prepare($statement); - $result = $query->execute([$itemType, $itemOrigin]); - - $shares = $result->fetchAll(); - - $listOfUnsharedItems = []; - - $itemUnshared = false; - foreach ($shares as $share) { - if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER && - $share['share_with'] === $uid) { - $deletedShares = Helper::delete($share['id']); - $shareTmp = [ - 'id' => $share['id'], - 'shareWith' => $share['share_with'], - 'itemTarget' => $share['item_target'], - 'itemType' => $share['item_type'], - 'shareType' => (int)$share['share_type'], - ]; - if (isset($share['file_target'])) { - $shareTmp['fileTarget'] = $share['file_target']; - } - $listOfUnsharedItems = \array_merge($listOfUnsharedItems, $deletedShares, [$shareTmp]); - $itemUnshared = true; - break; - } elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) { - if (\OC::$server->getGroupManager()->inGroup($uid, $share['share_with'])) { - $groupShare = $share; - } - } elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique && - $share['share_with'] === $uid) { - $uniqueGroupShare = $share; - } - } - - 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`)' - .' VALUES (?,?,?,?,?,?,?,?,?,?,?)'); - $query->execute([$groupShare['item_type'], $groupShare['item_source'], $groupShare['item_target'], - $groupShare['id'], self::$shareTypeGroupUserUnique, - \OC_User::getUser(), $groupShare['uid_owner'], 0, $groupShare['stime'], $groupShare['file_source'], - $groupShare['file_target']]); - $shareTmp = [ - 'id' => $groupShare['id'], - 'shareWith' => $groupShare['share_with'], - 'itemTarget' => $groupShare['item_target'], - 'itemType' => $groupShare['item_type'], - 'shareType' => (int)$groupShare['share_type'], - ]; - if (isset($groupShare['file_target'])) { - $shareTmp['fileTarget'] = $groupShare['file_target']; - } - $listOfUnsharedItems = \array_merge($listOfUnsharedItems, [$shareTmp]); - $itemUnshared = true; - } elseif (!$itemUnshared && isset($uniqueGroupShare)) { - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); - $query->execute([0, $uniqueGroupShare['id']]); - $shareTmp = [ - 'id' => $uniqueGroupShare['id'], - 'shareWith' => $uniqueGroupShare['share_with'], - 'itemTarget' => $uniqueGroupShare['item_target'], - 'itemType' => $uniqueGroupShare['item_type'], - 'shareType' => (int)$uniqueGroupShare['share_type'], - ]; - if (isset($uniqueGroupShare['file_target'])) { - $shareTmp['fileTarget'] = $uniqueGroupShare['file_target']; - } - $listOfUnsharedItems = \array_merge($listOfUnsharedItems, [$shareTmp]); - $itemUnshared = true; - } - - if ($itemUnshared) { - \OC_Hook::emit('OCP\Share', 'post_unshareFromSelf', - ['unsharedItems' => $listOfUnsharedItems, 'itemType' => $itemType]); - } - - return $itemUnshared; - } - /** * sent status if users got informed by mail about share * @param string $itemType diff --git a/lib/public/Share.php b/lib/public/Share.php index 49e65d17f0e5..f2582aff1fb6 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -228,34 +228,6 @@ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $in return \OC\Share\Share::getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections, $checkExpireDate); } - /** - * Unshare an item from a user, group, or delete a private link - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param string $owner owner of the share, if null the current user is used - * @return boolean true on success or false on failure - * @since 5.0.0 - parameter $owner was added in 8.0.0 - */ - public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) { - return \OC\Share\Share::unshare($itemType, $itemSource, $shareType, $shareWith, $owner); - } - - /** - * Unshare an item shared with the current user - * @param string $itemType - * @param string $itemOrigin Item target or source - * @param boolean $originIsSource true if $itemOrigin is the source, false if $itemOrigin is the target (optional) - * @return boolean true on success or false on failure - * - * Unsharing from self is not allowed for items inside collections - * @since 5.0.0 - parameter $originIsSource was added in 8.0.0 - */ - public static function unshareFromSelf($itemType, $itemOrigin, $originIsSource = false) { - return \OC\Share\Share::unshareFromSelf($itemType, $itemOrigin, $originIsSource); - } - /** * sent status if users got informed by mail about share * @param string $itemType From c2346fd2aa4e65b60d2aee70b11587322961c0a0 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:13:57 +0200 Subject: [PATCH 13/21] Remove obsolete methods in ajax/share.php --- core/ajax/share.php | 171 +------------------------------------------- 1 file changed, 1 insertion(+), 170 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index ad2c07caf084..969a3f53dfc8 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -194,39 +194,7 @@ function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { } } elseif (isset($_GET['fetch'])) { switch ($_GET['fetch']) { - case 'getItemsSharedStatuses': - if (isset($_GET['itemType'])) { - $return = OCP\Share::getItemsShared((string)$_GET['itemType'], OCP\Share::FORMAT_STATUSES); - \is_array($return) ? OC_JSON::success(['data' => $return]) : OC_JSON::error(); - } - break; - case 'getItem': - if (isset($_GET['itemType'], $_GET['itemSource'], $_GET['checkReshare'], $_GET['checkShares'])) { - if ($_GET['checkReshare'] == 'true') { - $reshare = OCP\Share::getItemSharedWithBySource( - (string)$_GET['itemType'], - (string)$_GET['itemSource'], - OCP\Share::FORMAT_NONE, - null, - true - ); - } else { - $reshare = false; - } - if ($_GET['checkShares'] == 'true') { - $shares = OCP\Share::getItemShared( - (string)$_GET['itemType'], - (string)$_GET['itemSource'], - OCP\Share::FORMAT_NONE, - null, - true - ); - } else { - $shares = false; - } - OC_JSON::success(['data' => ['reshare' => $reshare, 'shares' => $shares]]); - } - break; + // still used by email recipient autocomplete in link share dialog case 'getShareWithEmail': $result = []; if (isset($_GET['search'])) { @@ -269,142 +237,5 @@ function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { } OC_JSON::success(['data' => $result]); break; - case 'getShareWith': - if (isset($_GET['search'])) { - $shareWithinGroupOnly = OC\Share\Share::shareWithGroupMembersOnly(); - $shareWith = []; - $groups = getGroups((string)$_GET['search']); - if ($shareWithinGroupOnly) { - $usergroups = \OC::$server->getGroupManager()->getUserIdGroups(OC_User::getUser()); - $usergroups = \array_values(\array_map(function (\OCP\IGroup $g) { - return $g->getGID(); - }, $usergroups)); - $groups = \array_intersect($groups, $usergroups); - } - - $sharedUsers = []; - $sharedGroups = []; - if (isset($_GET['itemShares'])) { - if (isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) && - \is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) { - $sharedUsers = $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]; - } - - if (isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP]) && - \is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])) { - $sharedGroups = $_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP]; - } - } - - $count = 0; - $users = []; - $limit = 0; - $offset = 0; - // limit defaults to 15 if not specified via request parameter and can be no larger than 500 - $request_limit = \min((int)$_GET['limit'] ?: 15, 500); - while ($count < $request_limit && \count($users) == $limit) { - $limit = $request_limit - $count; - if ($shareWithinGroupOnly) { - $users = displayNamesInGroups($usergroups, (string)$_GET['search'], $limit, $offset); - } else { - $users = OC_User::getDisplayNames((string)$_GET['search'], $limit, $offset); - } - - $offset += $limit; - foreach ($users as $uid => $displayName) { - if (\in_array($uid, $sharedUsers)) { - continue; - } - - if ((!isset($_GET['itemShares']) - || !\is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) - || !\in_array($uid, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) - && $uid != OC_User::getUser()) { - $shareWith[] = [ - 'label' => $displayName, - 'value' => [ - 'shareType' => OCP\Share::SHARE_TYPE_USER, - 'shareWith' => $uid] - ]; - $count++; - } - } - } - $count = 0; - - // enable l10n support - $l = \OC::$server->getL10N('core'); - - foreach ($groups as $group) { - if (\in_array($group, $sharedGroups)) { - continue; - } - - if ($count < $request_limit) { - if (!isset($_GET['itemShares']) - || !isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP]) - || !\is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP]) - || !\in_array($group, $_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])) { - $shareWith[] = [ - 'label' => $group, - 'value' => [ - 'shareType' => OCP\Share::SHARE_TYPE_GROUP, - 'shareWith' => $group - ] - ]; - $count++; - } - } else { - break; - } - } - - // allow user to add unknown remote addresses for server-to-server share - $backend = \OCP\Share::getBackend((string)$_GET['itemType']); - if ($backend->isShareTypeAllowed(\OCP\Share::SHARE_TYPE_REMOTE)) { - if (\substr_count((string)$_GET['search'], '@') >= 1) { - $shareWith[] = [ - 'label' => (string)$_GET['search'], - 'value' => [ - 'shareType' => \OCP\Share::SHARE_TYPE_REMOTE, - 'shareWith' => (string)$_GET['search'] - ] - ]; - } - $contactManager = \OC::$server->getContactsManager(); - $addressBookContacts = $contactManager->search($_GET['search'], ['CLOUD', 'FN']); - foreach ($addressBookContacts as $contact) { - if (isset($contact['CLOUD'])) { - foreach ($contact['CLOUD'] as $cloudId) { - $shareWith[] = [ - 'label' => $contact['FN'] . ' (' . $cloudId . ')', - 'value' => [ - 'shareType' => \OCP\Share::SHARE_TYPE_REMOTE, - 'shareWith' => $cloudId - ] - ]; - } - } - } - } - - $sharingAutocompletion = \OC::$server->getConfig() - ->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'); - - if ($sharingAutocompletion !== 'yes') { - $searchTerm = \strtolower($_GET['search']); - $shareWith = \array_filter($shareWith, function ($user) use ($searchTerm) { - return \strtolower($user['label']) === $searchTerm - || \strtolower($user['value']['shareWith']) === $searchTerm; - }); - } - - $sorter = new \OC\Share\SearchResultSorter((string)$_GET['search'], - 'label', - \OC::$server->getLogger()); - \usort($shareWith, [$sorter, 'sort']); - OC_JSON::success(['data' => $shareWith]); - } - break; } } From f189943059055f4aa917db482d45dda2af938698 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:24:12 +0200 Subject: [PATCH 14/21] Remove Share::getItemSharedWithBySource + cleanup Remove unused private functions --- lib/private/Share/Helper.php | 11 - lib/private/Share/Share.php | 392 ----------------------------------- lib/public/Share.php | 15 -- 3 files changed, 418 deletions(-) diff --git a/lib/private/Share/Helper.php b/lib/private/Share/Helper.php index d0e1b073a81f..63c7db58f2b2 100644 --- a/lib/private/Share/Helper.php +++ b/lib/private/Share/Helper.php @@ -174,17 +174,6 @@ public static function getDefaultExpireSetting() { return $defaultExpireSettings; } - public static function calcExpireDate() { - $expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60; - $expireAt = \time() + $expireAfter; - $date = new \DateTime(); - $date->setTimestamp($expireAt); - $date->setTime(0, 0, 0); - //$dateString = $date->format('Y-m-d') . ' 00:00:00'; - - return $date; - } - /** * calculate expire date * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays' diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index cd94554f1b7d..e19dcd433779 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -423,23 +423,6 @@ public static function getItemSharedWithUser($itemType, $itemSource, $user, $own return $shares; } - /** - * Get the item of item type shared with the current user by source - * @param string $itemType - * @param string $itemSource - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param boolean $includeCollections - * @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, $shareWith = null) { - $shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith; - return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format, - $parameters, 1, $includeCollections, true); - } - /** * Get the item of item type shared by a link * @param string $itemType @@ -1490,315 +1473,6 @@ protected static function groupItems($items, $itemType) { return $result; } - /** - * Put shared item into the database - * @param string $itemType Item type - * @param string $itemSource Item source - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param string $uidOwner User that is the owner of shared item - * @param int $permissions CRUDS permissions - * @param boolean|array $parentFolder Parent folder target (optional) - * @param string $token (optional) - * @param string $itemSourceName name of the source item (optional) - * @param \DateTime $expirationDate (optional) - * @throws \Exception - * @return mixed id of the new share or false - */ - private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, - $permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - - $queriesToExecute = []; - $suggestedItemTarget = null; - $groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = ''; - $groupItemTarget = $itemTarget = $fileSource = $parent = 0; - - $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']; - } - - $isGroupShare = false; - if ($shareType == self::SHARE_TYPE_GROUP) { - $isGroupShare = true; - if (isset($shareWith['users'])) { - $users = $shareWith['users']; - } else { - $users = self::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); - $groupFileTarget = Helper::generateTarget($itemType, $itemSource, - $shareType, $shareWith['group'], $uidOwner, $filePath); - - // add group share to table and remember the id as parent - $queriesToExecute['groupShare'] = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'itemTarget' => $groupItemTarget, - 'shareType' => $shareType, - 'shareWith' => $shareWith['group'], - 'uidOwner' => $uidOwner, - 'permissions' => $permissions, - 'shareTime' => \time(), - 'fileSource' => $fileSource, - 'fileTarget' => $groupFileTarget, - 'token' => $token, - 'parent' => $parent, - 'expiration' => $expirationDate, - ]; - } else { - $users = [$shareWith]; - $itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, - $suggestedItemTarget); - } - - $run = true; - $error = ''; - $preHookData = [ - '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 = $itemSource; - $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user); - - $userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType; - - if ($sourceExists && $sourceExists['item_source'] === $itemSource) { - $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, $userShareType, $user, - $uidOwner, $suggestedItemTarget, $parent); - } 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 (($itemTarget === $groupItemTarget)) { - continue; - } - } - - $queriesToExecute[] = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'itemTarget' => $itemTarget, - 'shareType' => $userShareType, - 'shareWith' => $user, - 'uidOwner' => $uidOwner, - 'permissions' => $permissions, - 'shareTime' => \time(), - 'fileSource' => $fileSource, - 'fileTarget' => $fileTarget, - 'token' => $token, - 'parent' => $parent, - 'expiration' => $expirationDate, - ]; - } - - $id = false; - if ($isGroupShare) { - $id = self::insertShare($queriesToExecute['groupShare']); - // Save this id, any extra rows for this group share will need to reference it - $parent = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share'); - unset($queriesToExecute['groupShare']); - } - - foreach ($queriesToExecute as $shareQuery) { - $shareQuery['parent'] = $parent; - $id = self::insertShare($shareQuery); - } - - $postHookData = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'parent' => $parent, - 'shareType' => $shareType, - 'uidOwner' => $uidOwner, - 'permissions' => $permissions, - 'fileSource' => $fileSource, - 'id' => $parent, - 'token' => $token, - 'expirationDate' => $expirationDate, - ]; - - $postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith; - $postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget; - $postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget; - - \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData); - - return $id ? $id : false; - } - - /** - * @param string $itemType - * @param string $itemSource - * @param int $shareType - * @param string $shareWith - * @param string $uidOwner - * @param int $permissions - * @param string|null $itemSourceName - * @param null|\DateTime $expirationDate - */ - private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - $backend = self::getBackend($itemType); - - $l = \OC::$server->getL10N('lib'); - $result = []; - - $column = 'item_source'; - - $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 failed, because the user %s is the original sharer', [$shareWith]); - - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - - if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) { - // Check if share permissions is granted - if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::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', [$itemSourceName, $uidOwner]); - - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName, $uidOwner), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } else { - // TODO Don't check if inside folder - $result['parent'] = $checkReshare['id']; - - $result['expirationDate'] = $expirationDate; - // $checkReshare['expiration'] could be null and then is always less than any value - if (isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) { - $result['expirationDate'] = $checkReshare['expiration']; - } - - // only suggest the same name as new target if it is a reshare of the - // same file/folder and not the reshare of a child - if ($checkReshare[$column] === $itemSource) { - $result['filePath'] = $checkReshare['file_target']; - $result['itemSource'] = $checkReshare['item_source']; - $result['fileSource'] = $checkReshare['file_source']; - $result['suggestedItemTarget'] = $checkReshare['item_target']; - $result['suggestedFileTarget'] = $checkReshare['file_target']; - } else { - $result['filePath'] = null; - $result['suggestedItemTarget'] = null; - $result['suggestedFileTarget'] = null; - $result['itemSource'] = $itemSource; - $result['fileSource'] = null; - } - } - } else { - $message = 'Sharing %s failed, because resharing is not allowed'; - $message_t = $l->t('Sharing %s failed, because resharing is not allowed', [$itemSourceName]); - - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSourceName), \OCP\Util::DEBUG); - 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', [$itemSource, $itemType]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSource, $itemType), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - $result['filePath'] = null; - $result['fileSource'] = null; - } - - return $result; - } - - /** - * - * @param array $shareData - * @return mixed false in case of a failure or the id of the new share - */ - private static function insertShare(array $shareData) { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (' - .' `item_type`, `item_source`, `item_target`, `share_type`,' - .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - .' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)'); - $query->bindValue(1, $shareData['itemType']); - $query->bindValue(2, $shareData['itemSource']); - $query->bindValue(3, $shareData['itemTarget']); - $query->bindValue(4, $shareData['shareType']); - $query->bindValue(5, $shareData['shareWith']); - $query->bindValue(6, $shareData['uidOwner']); - $query->bindValue(7, $shareData['permissions']); - $query->bindValue(8, $shareData['shareTime']); - $query->bindValue(9, $shareData['fileSource']); - $query->bindValue(10, $shareData['fileTarget']); - $query->bindValue(11, $shareData['token']); - $query->bindValue(12, $shareData['parent']); - $query->bindValue(13, $shareData['expiration'], 'datetime'); - $result = $query->execute(); - - $id = false; - if ($result) { - $id = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share'); - } - - return $id; - } - /** * Delete all shares with type SHARE_TYPE_LINK */ @@ -2041,72 +1715,6 @@ private static function sendRemoteUnshare($remote, $id, $token) { return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)); } - /** - * check if user can only share with group members - * @return bool - */ - public static function shareWithGroupMembersOnly() { - $value = \OC::$server->getAppConfig()->getValue('core', 'shareapi_only_share_with_group_members', 'no'); - return ($value === 'yes') ? true : false; - } - - /** - * check if user can only share with groups he's member of - * @return bool - */ - public static function shareWithMembershipGroupOnly() { - $value = \OC::$server->getAppConfig()->getValue('core', 'shareapi_only_share_with_membership_groups', 'no'); - return ($value === 'yes') ? true : false; - } - - /** - * @return bool - */ - public static function isDefaultExpireDateEnabled() { - $defaultExpireDateEnabled = \OC::$server->getConfig()->getAppValue('core', 'shareapi_default_expire_date', 'no'); - return ($defaultExpireDateEnabled === "yes") ? true : false; - } - - /** - * @return bool - */ - public static function enforceDefaultExpireDate() { - $enforceDefaultExpireDate = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_expire_date', 'no'); - return ($enforceDefaultExpireDate === "yes") ? true : false; - } - - /** - * @return int - */ - public static function getExpireInterval() { - return (int)\OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7'); - } - - /** - * Checks whether the given path is reachable for the given owner - * - * @param string $path path relative to files - * @param string $ownerStorageId storage id of the owner - * - * @return boolean true if file is reachable, false otherwise - */ - private static function isFileReachable($path, $ownerStorageId) { - // if outside the home storage, file is always considered reachable - if (!(\substr($ownerStorageId, 0, 6) === 'home::' || - \substr($ownerStorageId, 0, 13) === 'object::user:' - )) { - return true; - } - - // if inside the home storage, the file has to be under "/files/" - $path = \ltrim($path, '/'); - if (\substr($path, 0, 6) === 'files/') { - return true; - } - - return false; - } - /** * @param IConfig $config * @return bool diff --git a/lib/public/Share.php b/lib/public/Share.php index f2582aff1fb6..095bef567d43 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -136,21 +136,6 @@ public static function getItemSharedWithUser($itemType, $itemSource, $user, $own return \OC\Share\Share::getItemSharedWithUser($itemType, $itemSource, $user, $owner); } - /** - * Get the item of item type shared with the current user by source - * @param string $itemType - * @param string $itemSource - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param bool $includeCollections - * @return array - * @since 5.0.0 - */ - public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE, - $parameters = null, $includeCollections = false) { - return \OC\Share\Share::getItemSharedWithBySource($itemType, $itemSource, $format, $parameters, $includeCollections); - } - /** * Get the item of item type shared by a link * @param string $itemType From c0b2e4f8b08f2f054b7e534ea9908a89be5fe707 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 22:33:01 +0200 Subject: [PATCH 15/21] Remove old Share::getItemsShared() --- lib/private/Share/Share.php | 15 --------------- lib/public/Share.php | 15 --------------- 2 files changed, 30 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index e19dcd433779..46d4a46c7632 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -484,21 +484,6 @@ public static function resolveReShare($linkItem) { return $linkItem; } - /** - * Get the shared items of item type owned by the current user - * @param string $itemType - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param int $limit Number of items to return (optional) Returns all by default - * @param boolean $includeCollections - * @return mixed Return depends on format - */ - public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null, - $limit = -1, $includeCollections = false) { - return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, - $parameters, $limit, $includeCollections); - } - /** * Get the shared item of item type owned by the current user * @param string $itemType diff --git a/lib/public/Share.php b/lib/public/Share.php index 095bef567d43..4e3f25aef5a8 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -169,21 +169,6 @@ public static function resolveReShare($linkItem) { return \OC\Share\Share::resolveReShare($linkItem); } - /** - * Get the shared items of item type owned by the current user - * @param string $itemType - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param int $limit Number of items to return (optional) Returns all by default - * @param bool $includeCollections - * @return mixed Return depends on format - * @since 5.0.0 - */ - public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null, - $limit = -1, $includeCollections = false) { - return \OC\Share\Share::getItemsShared($itemType, $format, $parameters, $limit, $includeCollections); - } - /** * Get the shared item of item type owned by the current user * @param string $itemType From 058e1a3c9ff31294636ff39d0aa81c493f978ae3 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 23:18:55 +0200 Subject: [PATCH 16/21] Delete share backend classes and more Share 1.0 cleanup --- lib/private/Share/Helper.php | 40 - lib/private/Share/Share.php | 1002 +---------------------- lib/private/Tags.php | 29 +- lib/public/Share.php | 160 ---- lib/public/Share_Backend.php | 95 --- lib/public/Share_Backend_Collection.php | 40 - 6 files changed, 3 insertions(+), 1363 deletions(-) delete mode 100644 lib/public/Share_Backend.php delete mode 100644 lib/public/Share_Backend_Collection.php diff --git a/lib/private/Share/Helper.php b/lib/private/Share/Helper.php index 63c7db58f2b2..2b3209074841 100644 --- a/lib/private/Share/Helper.php +++ b/lib/private/Share/Helper.php @@ -32,46 +32,6 @@ class Helper extends \OC\Share\Constants { - /** - * Generate a unique target for the item - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param string $uidOwner User that is the owner of shared item - * @param string $suggestedTarget The suggested target originating from a reshare (optional) - * @param int $groupParent The id of the parent group share (optional) - * @throws \Exception - * @return string Item target - */ - 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 || $shareType === self::SHARE_TYPE_REMOTE) { - if (isset($suggestedTarget)) { - return $suggestedTarget; - } - return $backend->generateTarget($itemSource, false); - } else { - if ($shareType == self::SHARE_TYPE_USER) { - // Share with is a user, so set share type to user and groups - $shareType = self::$shareTypeUserAndGroups; - } - - // Check if suggested target exists first - if (!isset($suggestedTarget)) { - $suggestedTarget = $itemSource; - } - if ($shareType == self::SHARE_TYPE_GROUP) { - $target = $backend->generateTarget($suggestedTarget, false); - } else { - $target = $backend->generateTarget($suggestedTarget, $shareWith); - } - - return $target; - } - } - /** * Delete all reshares and group share children of an item * @param int $parent Id of item to delete diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 46d4a46c7632..87159c7cae9e 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -53,7 +53,6 @@ /** * This class provides the ability for apps to share their content between users. - * Apps must create a backend class that implements OCP\Share_Backend and register it with this class. * * It provides the following hooks: * - post_shared @@ -298,143 +297,6 @@ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = fa return ['users' => \array_unique($shares), 'public' => $publicShare, 'remote' => $remoteShare]; } - /** - * Get the items of item type shared with the current user - * @param string $itemType - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param int $limit Number of items to return (optional) Returns all by default - * @param boolean $includeCollections (optional) - * @return mixed Return depends on format - */ - public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, - $parameters = null, $limit = -1, $includeCollections = false) { - return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, - $parameters, $limit, $includeCollections); - } - - /** - * Get the items of item type shared with a user - * @param string $itemType - * @param string $user id for which user we want the shares - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param int $limit Number of items to return (optional) Returns all by default - * @param boolean $includeCollections (optional) - * @return mixed Return depends on format - */ - public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE, - $parameters = null, $limit = -1, $includeCollections = false) { - return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format, - $parameters, $limit, $includeCollections); - } - - /** - * Get the item of item type shared with the current user - * @param string $itemType - * @param string $itemTarget - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param boolean $includeCollections (optional) - * @return mixed Return depends on format - */ - public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, - $parameters = null, $includeCollections = false) { - return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, - $parameters, 1, $includeCollections); - } - - /** - * Get the item of item type shared with a given user by source - * @param string $itemType - * @param string $itemSource - * @param string $user User to whom the item was shared - * @param string $owner Owner of the share - * @param int $shareType only look for a specific share type - * @return array Return list of items with item_target, permissions and expiration - */ - public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - $shares = []; - - $where = 'WHERE'; - $column = 'item_source'; - - $select = self::createSelectStatement(self::FORMAT_NONE); - - $where .= ' `' . $column . '` = ? AND `item_type` = ? '; - $arguments = [$itemSource, $itemType]; - // for link shares $user === null - if ($user !== null) { - $where .= ' AND `share_with` = ? '; - $arguments[] = $user; - } - - if ($shareType !== null) { - $where .= ' AND `share_type` = ? '; - $arguments[] = $shareType; - } - - if ($owner !== null) { - $where .= ' AND `uid_owner` = ? '; - $arguments[] = $owner; - } - - $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where); - - $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) && $user !== null) { - $groups = self::getGroupsForUser($user); - - if (!empty($groups)) { - $where = ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'; - $arguments = [$itemSource, $itemType, $groups]; - $types = [null, null, IQueryBuilder::PARAM_STR_ARRAY]; - - if ($owner !== null) { - $where .= ' AND `uid_owner` = ?'; - $arguments[] = $owner; - $types[] = null; - } - - // TODO: inject connection, hopefully one day in the future when this - // class isn't static anymore... - $conn = \OC::$server->getDatabaseConnection(); - $result = $conn->executeQuery( - 'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, - $arguments, - $types - ); - - while ($row = $result->fetch()) { - $shares[] = $row; - } - } - } - - return $shares; - } - - /** - * Get the item of item type shared by a link - * @param string $itemType - * @param string $itemSource - * @param string $uidOwner Owner of link - * @return array - */ - public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) { - return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, - null, 1); - } - /** * Based on the given token the share information will be returned - password protected shares will be verified * @param string $token @@ -484,45 +346,6 @@ public static function resolveReShare($linkItem) { return $linkItem; } - /** - * Get the shared item of item type owned by the current user - * @param string $itemType - * @param string $itemSource - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param boolean $includeCollections - * @return mixed Return depends on format - */ - public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE, - $parameters = null, $includeCollections = false) { - return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format, - $parameters, -1, $includeCollections); - } - - /** - * Get all users an item is shared with - * @param string $itemType - * @param string $itemSource - * @param string $uidOwner - * @param boolean $includeCollections - * @param boolean $checkExpireDate - * @return array Return array of users - */ - public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) { - $users = []; - $items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate); - if ($items) { - foreach ($items as $item) { - if ((int)$item['share_type'] === self::SHARE_TYPE_USER) { - $users[] = $item['share_with']; - } elseif ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) { - $users = \array_merge($users, self::usersInGroup($item['share_with'])); - } - } - } - return $users; - } - /** * sent status if users got informed by mail about share * @param string $itemType @@ -546,330 +369,6 @@ public static function setSendMailStatus($itemType, $itemSource, $shareType, $re } } - /** - * Set the permissions of an item for a specific user or group - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param int $permissions CRUDS permissions - * @return boolean true on success or false on failure - * @throws \Exception when trying to grant more permissions then the user has himself - */ - public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { - $l = \OC::$server->getL10N('lib'); - $connection = \OC::$server->getDatabaseConnection(); - - $intArrayToLiteralArray = function ($intArray, $eb) { - return \array_map(function ($int) use ($eb) { - return $eb->literal((int)$int, 'integer'); - }, $intArray); - }; - $sanitizeItem = function ($item) { - $item['id'] = (int)$item['id']; - $item['premissions'] = (int)$item['permissions']; - return $item; - }; - - if ($rootItem = self::getItems($itemType, $itemSource, $shareType, $shareWith, - \OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) { - // Check if this item is a reshare and verify that the permissions - // granted don't exceed the parent shared item - if (isset($rootItem['parent'])) { - $qb = $connection->getQueryBuilder(); - $qb->select('permissions') - ->from('share') - ->where($qb->expr()->eq('id', $qb->createParameter('id'))) - ->setParameter(':id', $rootItem['parent']); - $dbresult = $qb->execute(); - - $result = $dbresult->fetch(); - $dbresult->closeCursor(); - if (~(int)$result['permissions'] & $permissions) { - $message = 'Setting permissions for %s failed,' - .' because the permissions exceed permissions granted to %s'; - $message_t = $l->t('Setting permissions for %s failed, because the permissions exceed permissions granted to %s', [$itemSource, \OC_User::getUser()]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSource, \OC_User::getUser()), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - } - $qb = $connection->getQueryBuilder(); - $qb->update('share') - ->set('permissions', $qb->createParameter('permissions')) - ->where($qb->expr()->eq('id', $qb->createParameter('id'))) - ->setParameter(':id', $rootItem['id']) - ->setParameter(':permissions', $permissions); - $qb->execute(); - - // Share id's to update with the new permissions - $ids = []; - $items = []; - - // Check if permissions were removed - if ((int)$rootItem['permissions'] & ~$permissions) { - // If share permission is removed all reshares must be deleted - if (($rootItem['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) { - // delete all shares, keep parent and group children - Helper::delete($rootItem['id'], true, null, null, true); - } - - // Remove permission from all children - $parents = [$rootItem['id']]; - while (!empty($parents)) { - $parents = $intArrayToLiteralArray($parents, $qb->expr()); - $qb = $connection->getQueryBuilder(); - $qb->select('id', 'permissions', 'item_type') - ->from('share') - ->where($qb->expr()->in('parent', $parents)); - $result = $qb->execute(); - // Reset parents array, only go through loop again if - // items are found that need permissions removed - $parents = []; - while ($item = $result->fetch()) { - $item = $sanitizeItem($item); - - $items[] = $item; - // Check if permissions need to be removed - if ($item['permissions'] & ~$permissions) { - // Add to list of items that need permissions removed - $ids[] = $item['id']; - $parents[] = $item['id']; - } - } - $result->closeCursor(); - } - - // Remove the permissions for all reshares of this item - if (!empty($ids)) { - $ids = "'".\implode("','", $ids)."'"; - // TODO this should be done with Doctrine platform objects - if (\OC::$server->getConfig()->getSystemValue("dbtype") === 'oci') { - $andOp = 'BITAND(`permissions`, ?)'; - } else { - $andOp = '`permissions` & ?'; - } - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp - .' WHERE `id` IN ('.$ids.')'); - $query->execute([$permissions]); - } - } - - /* - * Permissions were added - * Update all USERGROUP shares. (So group shares where the user moved their mountpoint). - */ - if ($permissions & ~(int)$rootItem['permissions']) { - $qb = $connection->getQueryBuilder(); - $qb->select('id', 'permissions', 'item_type') - ->from('share') - ->where($qb->expr()->eq('parent', $qb->createParameter('parent'))) - ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type'))) - ->andWhere($qb->expr()->neq('permissions', $qb->createParameter('shareDeleted'))) - ->setParameter(':parent', (int)$rootItem['id']) - ->setParameter(':share_type', 2) - ->setParameter(':shareDeleted', 0); - $result = $qb->execute(); - - $ids = []; - while ($item = $result->fetch()) { - $item = $sanitizeItem($item); - $items[] = $item; - $ids[] = $item['id']; - } - $result->closeCursor(); - - // Add permssions for all USERGROUP shares of this item - if (!empty($ids)) { - $ids = $intArrayToLiteralArray($ids, $qb->expr()); - - $qb = $connection->getQueryBuilder(); - $qb->update('share') - ->set('permissions', $qb->createParameter('permissions')) - ->where($qb->expr()->in('id', $ids)) - ->setParameter(':permissions', $permissions); - $qb->execute(); - } - } - - foreach ($items as $item) { - \OC_Hook::emit('OCP\Share', 'post_update_permissions', ['share' => $item]); - } - - return true; - } - $message = 'Setting permissions for %s failed, because the item was not found'; - $message_t = $l->t('Setting permissions for %s failed, because the item was not found', [$itemSource]); - - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemSource), \OCP\Util::DEBUG); - throw new \Exception($message_t); - } - - /** - * validate expiration date if it meets all constraints - * - * @param string $expireDate well formatted date string, e.g. "DD-MM-YYYY" - * @param string $shareTime timestamp when the file was shared - * @param string $itemType - * @param string $itemSource - * @return \DateTime validated date - * @throws \Exception when the expire date is in the past or further in the future then the enforced date - */ - private static function validateExpireDate($expireDate, $shareTime, $itemType, $itemSource) { - $l = \OC::$server->getL10N('lib'); - $date = new \DateTime($expireDate); - $today = new \DateTime('now'); - - // if the user doesn't provide a share time we need to get it from the database - // fall-back mode to keep API stable, because the $shareTime parameter was added later - $defaultExpireDateEnforced = \OCP\Util::isDefaultExpireDateEnforced(); - if ($defaultExpireDateEnforced && $shareTime === null) { - $items = self::getItemShared($itemType, $itemSource); - $firstItem = \reset($items); - $shareTime = (int)$firstItem['stime']; - } - - if ($defaultExpireDateEnforced) { - // initialize max date with share time - $maxDate = new \DateTime(); - $maxDate->setTimestamp($shareTime); - $maxDays = \OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7'); - $maxDate->add(new \DateInterval('P' . $maxDays . 'D')); - if ($date > $maxDate) { - $warning = 'Cannot set expiration date. Shares cannot expire later than ' . $maxDays . ' after they have been shared'; - $warning_t = $l->t('Cannot set expiration date. Shares cannot expire later than %s after they have been shared', [$maxDays]); - \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN); - throw new \Exception($warning_t); - } - } - - if ($date < $today) { - $message = 'Cannot set expiration date. Expiration date is in the past'; - $message_t = $l->t('Cannot set expiration date. Expiration date is in the past'); - \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::WARN); - throw new \Exception($message_t); - } - - return $date; - } - - /** - * Set expiration date for a share - * @param string $itemType - * @param string $itemSource - * @param string $date expiration date - * @param int $shareTime timestamp from when the file was shared - * @return boolean - * @throws \Exception when the expire date is not set, in the past or further in the future then the enforced date - */ - public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) { - $user = \OC_User::getUser(); - $l = \OC::$server->getL10N('lib'); - - if ($date == '') { - if (\OCP\Util::isDefaultExpireDateEnforced()) { - $warning = 'Cannot clear expiration date. Shares are required to have an expiration date.'; - $warning_t = $l->t('Cannot clear expiration date. Shares are required to have an expiration date.'); - \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN); - throw new \Exception($warning_t); - } else { - $date = null; - } - } else { - $date = self::validateExpireDate($date, $shareTime, $itemType, $itemSource); - } - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?'); - $query->bindValue(1, $date, 'datetime'); - $query->bindValue(2, $itemType); - $query->bindValue(3, $itemSource); - $query->bindValue(4, $user); - $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK); - - $query->execute(); - - \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'date' => $date, - 'uidOwner' => $user - ]); - - return true; - } - - /** - * Retrieve the owner of a connection - * - * @param IDBConnection $connection - * @param int $shareId - * @throws \Exception - * @return string uid of share owner - */ - private static function getShareOwner(IDBConnection $connection, $shareId) { - $qb = $connection->getQueryBuilder(); - - $qb->select('uid_owner') - ->from('share') - ->where($qb->expr()->eq('id', $qb->createParameter('shareId'))) - ->setParameter(':shareId', $shareId); - $result = $qb->execute(); - $result = $result->fetch(); - - if (empty($result)) { - throw new \Exception('Share not found'); - } - - return $result['uid_owner']; - } - - /** - * Set password for a public link share - * - * @param IUserSession $userSession - * @param IDBConnection $connection - * @param IConfig $config - * @param int $shareId - * @param string $password - * @throws \Exception - * @return boolean - */ - public static function setPassword(IUserSession $userSession, - IDBConnection $connection, - IConfig $config, - $shareId, $password) { - $user = $userSession->getUser(); - if ($user === null) { - throw new \Exception("User not logged in"); - } - - $uid = self::getShareOwner($connection, $shareId); - - if ($uid !== $user->getUID()) { - throw new \Exception('Cannot update share of a different user'); - } - - if ($password === '') { - $password = null; - } - - //If passwords are enforced the password can't be null - if (self::enforcePassword($config) && $password === null) { - throw new \Exception('Cannot remove password'); - } - - self::verifyPassword($password); - - $qb = $connection->getQueryBuilder(); - $qb->update('share') - ->set('share_with', $qb->createParameter('pass')) - ->where($qb->expr()->eq('id', $qb->createParameter('shareId'))) - ->setParameter(':pass', $password === null ? null : \OC::$server->getHasher()->hash($password)) - ->setParameter(':shareId', $shareId); - - $qb->execute(); - - return true; - } - /** * Checks whether a share has expired, calls unshareItem() if yes. * @param array $item Share data (usually database row) @@ -939,40 +438,6 @@ protected static function unshareItem(array $item, $newParent = null) { } } - /** - * Get the backend class for the specified item type - * @param string $itemType - * @throws \Exception - * @return \OCP\Share_Backend - */ - public static function getBackend($itemType) { - $l = \OC::$server->getL10N('lib'); - if (isset(self::$backends[$itemType])) { - return self::$backends[$itemType]; - } elseif (isset(self::$backendTypes[$itemType]['class'])) { - $class = self::$backendTypes[$itemType]['class']; - if (\class_exists($class)) { - self::$backends[$itemType] = new $class; - if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) { - $message = 'Sharing backend %s must implement the interface OCP\Share_Backend'; - $message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', [$class]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $class), \OCP\Util::ERROR); - throw new \Exception($message_t); - } - return self::$backends[$itemType]; - } else { - $message = 'Sharing backend %s not found'; - $message_t = $l->t('Sharing backend %s not found', [$class]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $class), \OCP\Util::ERROR); - throw new \Exception($message_t); - } - } - $message = 'Sharing backend for %s not found'; - $message_t = $l->t('Sharing backend for %s not found', [$itemType]); - \OCP\Util::writeLog('OCP\Share', \sprintf($message, $itemType), \OCP\Util::ERROR); - throw new \Exception($message_t); - } - /** * Check if resharing is allowed * @return boolean true if allowed or false @@ -997,15 +462,6 @@ public static function isResharingAllowed() { */ private static function getCollectionItemTypes($itemType) { $collectionTypes = [$itemType]; - foreach (self::$backendTypes as $type => $backend) { - if (\in_array($backend['collectionOf'], $collectionTypes)) { - $collectionTypes[] = $type; - } - } - // TODO Add option for collections to be collection of themselves... - if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection)) { - unset($collectionTypes[0]); - } // Return array if collections were found or the item type is a // collection itself - collections can be inside collections if (\count($collectionTypes) > 0) { @@ -1014,462 +470,6 @@ private static function getCollectionItemTypes($itemType) { return false; } - /** - * Get the owners of items shared with a user. - * - * @param string $user The user the items are shared with. - * @param string $type The type of the items shared with the user. - * @param boolean $includeCollections Include collection item types (optional) - * @param boolean $includeOwner include owner in the list of users the item is shared with (optional) - * @return array - */ - public static function getSharedItemsOwners($user, $type, $includeCollections = false, $includeOwner = false) { - // First, we find out if $type is part of a collection (and if that collection is part of - // another one and so on). - $collectionTypes = []; - if (!$includeCollections || !$collectionTypes = self::getCollectionItemTypes($type)) { - $collectionTypes[] = $type; - } - - // Of these collection types, along with our original $type, we make a - // list of the ones for which a sharing backend has been registered. - // FIXME: Ideally, we wouldn't need to nest getItemsSharedWith in this loop but just call it - // with its $includeCollections parameter set to true. Unfortunately, this fails currently. - $allMaybeSharedItems = []; - foreach ($collectionTypes as $collectionType) { - if (isset(self::$backends[$collectionType])) { - $allMaybeSharedItems[$collectionType] = self::getItemsSharedWithUser( - $collectionType, - $user, - self::FORMAT_NONE - ); - } - } - - $owners = []; - if ($includeOwner) { - $owners[] = $user; - } - - // We take a look at all shared items of the given $type (or of the collections it is part of) - // and find out their owners. Then, we gather the tags for the original $type from all owners, - // and return them as elements of a list that look like "Tag (owner)". - foreach ($allMaybeSharedItems as $collectionType => $maybeSharedItems) { - foreach ($maybeSharedItems as $sharedItem) { - if (isset($sharedItem['id'])) { //workaround for https://github.com/owncloud/core/issues/2814 - $owners[] = $sharedItem['uid_owner']; - } - } - } - - return $owners; - } - - /** - * Get shared items from the database - * @param string $itemType - * @param string $item Item source or target (optional) - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique - * @param string $shareWith User or group the item is being shared with - * @param string $uidOwner User that is the owner of shared items (optional) - * @param int $format Format to convert items to with formatItems() (optional) - * @param mixed $parameters to pass to formatItems() (optional) - * @param int $limit Number of items to return, -1 to return all matches (optional) - * @param boolean $includeCollections Include collection item types (optional) - * @param boolean $itemShareWithBySource (optional) - * @param boolean $checkExpireDate - * @return array - * - * See public functions getItem(s)... for parameter usage - * - */ - public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, - $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, - $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true) { - if (!self::isEnabled()) { - return []; - } - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - $backend = self::getBackend($itemType); - $collectionTypes = false; - // Get filesystem root to add it to the file target and remove from the - // file source, match file_source with the file cache - $root = ''; - $collectionTypes = self::getCollectionItemTypes($itemType); - if ($includeCollections && !isset($item) && $collectionTypes) { - // If includeCollections is true, find collections of this item type, e.g. a music album contains songs - if (!in_array($itemType, $collectionTypes)) { - $itemTypes = array_merge([$itemType], $collectionTypes); - } else { - $itemTypes = $collectionTypes; - } - $placeholders = join(',', array_fill(0, count($itemTypes), '?')); - $where = ' WHERE `item_type` IN ('.$placeholders.'))'; - $queryArgs = $itemTypes; - } else { - $where = ' WHERE `item_type` = ?'; - $queryArgs = [$itemType]; - } - if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { - $where .= ' AND `share_type` != ?'; - $queryArgs[] = self::SHARE_TYPE_LINK; - } - if (isset($shareType)) { - // Include all user and group items - if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { - $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) '; - $queryArgs[] = self::SHARE_TYPE_USER; - $queryArgs[] = self::$shareTypeGroupUserUnique; - $queryArgs[] = $shareWith; - $groups = self::getGroupsForUser($shareWith); - if (!empty($groups)) { - $placeholders = \join(',', \array_fill(0, \count($groups), '?')); - $where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) '; - $queryArgs[] = self::SHARE_TYPE_GROUP; - $queryArgs = \array_merge($queryArgs, $groups); - } - $where .= ')'; - // Don't include own group shares - $where .= ' AND `uid_owner` != ?'; - $queryArgs[] = $shareWith; - } else { - $where .= ' AND `share_type` = ?'; - $queryArgs[] = $shareType; - if (isset($shareWith)) { - $where .= ' AND `share_with` = ?'; - $queryArgs[] = $shareWith; - } - } - } - if (isset($uidOwner)) { - $where .= ' AND `uid_owner` = ?'; - $queryArgs[] = $uidOwner; - if (!isset($shareType)) { - // Prevent unique user targets for group shares from being selected - $where .= ' AND `share_type` != ?'; - $queryArgs[] = self::$shareTypeGroupUserUnique; - } - $column = 'item_source'; - } else { - $column = 'item_target'; - } - if (isset($item)) { - $collectionTypes = self::getCollectionItemTypes($itemType); - if ($includeCollections && $collectionTypes) { - $where .= ' AND ('; - } else { - $where .= ' AND'; - } - // If looking for own shared items, check item_source else check item_target - if (isset($uidOwner) || $itemShareWithBySource) { - // If item type is a file, file source needs to be checked in case the item was converted - $where .= ' `item_source` = ?'; - $column = 'item_source'; - } else { - $where .= ' `item_target` = ?'; - } - $queryArgs[] = $item; - if ($includeCollections && $collectionTypes) { - $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); - $where .= ' OR `item_type` IN ('.$placeholders.'))'; - $queryArgs = \array_merge($queryArgs, $collectionTypes); - } - } - - 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; - } else { - $queryLimit = $limit; - } - } else { - $queryLimit = null; - } - $select = self::createSelectStatement($format, $uidOwner); - $root = strlen($root); - $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit); - $result = $query->execute($queryArgs); - if ($result === false) { - \OCP\Util::writeLog('OCP\Share', - \OC_DB::getErrorMessage() . ', select=' . $select . ' where=', - \OCP\Util::ERROR); - } - $items = []; - $targets = []; - $switchedItems = []; - $mounts = []; - while ($row = $result->fetchRow()) { - self::transformDBResults($row); - // Filter out duplicate group shares for users with unique targets - if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { - $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) { - continue; - } - } elseif (!isset($uidOwner)) { - // Check if the same target already exists - 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['id']]; - if (isset($items[$id]) && $row['uid_owner'] == $items[$id]['uid_owner']) { - // Switch to group share type to ensure resharing conditions aren't bypassed - if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) { - $items[$id]['share_type'] = self::SHARE_TYPE_GROUP; - $items[$id]['share_with'] = $row['share_with']; - } - // Switch ids if sharing permission is granted on only - // one share to ensure correct parent is used if resharing - if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE - && (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) { - $items[$row['id']] = $items[$id]; - $switchedItems[$id] = $row['id']; - unset($items[$id]); - $id = $row['id']; - } - $items[$id]['permissions'] |= (int)$row['permissions']; - } - continue; - } elseif (!empty($row['parent'])) { - $targets[$row['parent']] = $row['id']; - } - } - // Remove root from file source paths if retrieving own shared items - if (isset($uidOwner, $row['path'])) { - if (isset($row['parent'])) { - $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); - $parentResult = $query->execute([$row['parent']]); - if ($result === false) { - \OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' . - \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where, - \OCP\Util::ERROR); - } else { - $parentRow = $parentResult->fetchRow(); - $tmpPath = $parentRow['file_target']; - // find the right position where the row path continues from the target path - $pos = \strrpos($row['path'], $parentRow['file_target']); - $subPath = \substr($row['path'], $pos); - $splitPath = \explode('/', $subPath); - foreach (\array_slice($splitPath, 2) as $pathPart) { - $tmpPath = $tmpPath . '/' . $pathPart; - } - $row['path'] = $tmpPath; - } - } else { - if (!isset($mounts[$row['storage']])) { - $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); - if (\is_array($mountPoints) && !empty($mountPoints)) { - $mounts[$row['storage']] = \current($mountPoints); - } - } - if (!empty($mounts[$row['storage']])) { - $path = $mounts[$row['storage']]->getMountPoint().$row['path']; - $relPath = \substr($path, $root); // path relative to data/user - $row['path'] = \rtrim($relPath, '/'); - } - } - } - - if ($checkExpireDate) { - if (self::expireItem($row)) { - continue; - } - } - // Check if resharing is allowed, if not remove share permission - if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) { - $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE; - } - // Add display names to result - $row['share_with_displayname'] = $row['share_with']; - if (isset($row['share_with']) && $row['share_with'] != '' && - $row['share_type'] === self::SHARE_TYPE_USER) { - $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); - } elseif (isset($row['share_with']) && $row['share_with'] != '' && - $row['share_type'] === self::SHARE_TYPE_REMOTE) { - $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']); - foreach ($addressBookEntries as $entry) { - foreach ($entry['CLOUD'] as $cloudID) { - if ($cloudID === $row['share_with']) { - $row['share_with_displayname'] = $entry['FN']; - } - } - } - } - if (isset($row['uid_owner']) && $row['uid_owner'] != '') { - $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 = []; - foreach ($items as &$row) { - // Return only the item instead of a 2-dimensional array - if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType)) { - if ($format == self::FORMAT_NONE) { - return $row; - } else { - break; - } - } - // Check if this is a collection of the requested item type - if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { - if (($collectionBackend = self::getBackend($row['item_type'])) - && $collectionBackend instanceof \OCP\Share_Backend_Collection) { - // Collections can be inside collections, check if the item is a collection - if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) { - $collectionItems[] = $row; - } else { - $collection = []; - $collection['item_type'] = $row['item_type']; - $row['collection'] = $collection; - // Fetch all of the children sources - $children = $collectionBackend->getChildren($row[$column]); - foreach ($children as $child) { - $childItem = $row; - $childItem['item_type'] = $itemType; - $childItem['item_source'] = $child['source']; - $childItem['item_target'] = $child['target']; - if (isset($item)) { - if ($childItem[$column] == $item) { - // Return only the item instead of a 2-dimensional array - if ($limit == 1) { - if ($format == self::FORMAT_NONE) { - return $childItem; - } else { - // Unset the items array and break out of both loops - $items = []; - $items[] = $childItem; - break 2; - } - } else { - $collectionItems[] = $childItem; - } - } - } else { - $collectionItems[] = $childItem; - } - } - } - } - // Remove collection item - $toRemove = $row['id']; - if (\array_key_exists($toRemove, $switchedItems)) { - $toRemove = $switchedItems[$toRemove]; - } - unset($items[$toRemove]); - } elseif ($includeCollections && $collectionTypes && \in_array($row['item_type'], $collectionTypes)) { - // FIXME: Thats a dirty hack to improve file sharing performance, - // see github issue #10588 for more details - // Need to find a solution which works for all back-ends - $collectionBackend = self::getBackend($row['item_type']); - $sharedParents = $collectionBackend->getParents($row['item_source']); - foreach ($sharedParents as $parent) { - $collectionItems[] = $parent; - } - } - } - if (!empty($collectionItems)) { - $collectionItems = \array_unique($collectionItems, SORT_REGULAR); - $items = \array_merge($items, $collectionItems); - } - - // filter out invalid items, these can appear when subshare entries exist - // for a group in which the requested user isn't a member any more - $items = \array_filter($items, function ($item) { - return $item['share_type'] !== self::$shareTypeGroupUserUnique; - }); - - return self::formatResult($items, $column, $backend, $format, $parameters); - } - - return []; - } - - /** - * 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) { - if ($itemType === 'file' || $itemType === 'folder') { - throw new \InvalidArgumentException('Item type "' . $itemType . '" not supported by old share API any more'); - } - $fileSharing = false; - - $result = []; - - 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; - } - - /** - * Delete all shares with type SHARE_TYPE_LINK - */ - public static function removeAllLinkShares() { - // Delete any link shares - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ?'); - $result = $query->execute([self::SHARE_TYPE_LINK]); - while ($item = $result->fetchRow()) { - Helper::delete($item['id']); - } - } - /** * In case a password protected link is not yet authenticated this function will return false * @@ -1583,7 +583,7 @@ private static function formatResult($items, $column, $backend, $format = self:: } return $statuses; } else { - return $backend->formatItems($items, $format, $parameters); + return null; } } diff --git a/lib/private/Tags.php b/lib/private/Tags.php index 4cf8c418b6d3..a94b5258616a 100644 --- a/lib/private/Tags.php +++ b/lib/private/Tags.php @@ -97,14 +97,6 @@ class Tags implements \OCP\ITags { */ private $mapper; - /** - * The sharing backend for objects of $this->type. Required if - * $this->includeShared === true to determine ownership of items. - * - * @var \OCP\Share_Backend - */ - private $backend; - const TAG_TABLE = '*PREFIX*vcategory'; const RELATION_TABLE = '*PREFIX*vcategory_to_object'; @@ -123,12 +115,8 @@ public function __construct(TagMapper $mapper, $user, $type, array $defaultTags $this->mapper = $mapper; $this->user = $user; $this->type = $type; - $this->includeShared = $includeShared; + $this->includeShared = false; // obsolete $this->owners = [$this->user]; - if ($this->includeShared) { - $this->owners = \array_merge($this->owners, \OC\Share\Share::getSharedItemsOwners($this->user, $this->type, true)); - $this->backend = \OC\Share\Share::getBackend($this->type); - } $this->tags = $this->mapper->loadTags($this->owners, $this->type); if (\count($defaultTags) > 0 && \count($this->tags) === 0) { @@ -297,20 +285,7 @@ public function getIdsForTag($tag) { while ($row = $result->fetchRow()) { $id = (int)$row['objid']; - if ($this->includeShared) { - // We have to check if we are really allowed to access the - // items that are tagged with $tag. To that end, we ask the - // corresponding sharing backend if the item identified by $id - // is owned by any of $this->owners. - foreach ($this->owners as $owner) { - if ($this->backend->isValidSource($id, $owner)) { - $ids[] = $id; - break; - } - } - } else { - $ids[] = $id; - } + $ids[] = $id; } } diff --git a/lib/public/Share.php b/lib/public/Share.php index 4e3f25aef5a8..32d6341bbd49 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -43,7 +43,6 @@ /** * This class provides the ability for apps to share their content between users. - * Apps must create a backend class that implements OCP\Share_Backend and register it with this class. * * It provides the following hooks: * - post_shared @@ -77,77 +76,6 @@ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = fa return \OC\Share\Share::getUsersSharingFile($path, $ownerUser, $includeOwner, $returnUserPaths, $recursive); } - /** - * Get the items of item type shared with the current user - * @param string $itemType - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param int $limit Number of items to return (optional) Returns all by default - * @param bool $includeCollections (optional) - * @return mixed Return depends on format - * @since 5.0.0 - */ - public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, - $parameters = null, $limit = -1, $includeCollections = false) { - return \OC\Share\Share::getItemsSharedWith($itemType, $format, $parameters, $limit, $includeCollections); - } - - /** - * Get the items of item type shared with a user - * @param string $itemType - * @param string $user for which user we want the shares - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param int $limit Number of items to return (optional) Returns all by default - * @param bool $includeCollections (optional) - * @return mixed Return depends on format - * @since 7.0.0 - */ - public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE, - $parameters = null, $limit = -1, $includeCollections = false) { - return \OC\Share\Share::getItemsSharedWithUser($itemType, $user, $format, $parameters, $limit, $includeCollections); - } - - /** - * Get the item of item type shared with the current user - * @param string $itemType - * @param string $itemTarget - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters (optional) - * @param bool $includeCollections (optional) - * @return mixed Return depends on format - * @since 5.0.0 - */ - public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, - $parameters = null, $includeCollections = false) { - return \OC\Share\Share::getItemSharedWith($itemType, $itemTarget, $format, $parameters, $includeCollections); - } - - /** - * Get the item of item type shared with a given user by source - * @param string $itemType - * @param string $itemSource - * @param string $user User to whom the item was shared - * @param string $owner Owner of the share - * @return array Return list of items with file_target, permissions and expiration - * @since 6.0.0 - parameter $owner was added in 8.0.0 - */ - public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null) { - return \OC\Share\Share::getItemSharedWithUser($itemType, $itemSource, $user, $owner); - } - - /** - * Get the item of item type shared by a link - * @param string $itemType - * @param string $itemSource - * @param string $uidOwner Owner of link - * @return array - * @since 5.0.0 - */ - public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) { - return \OC\Share\Share::getItemSharedWithByLink($itemType, $itemSource, $uidOwner); - } - /** * Based on the given token the share information will be returned - password protected shares will be verified * @param string $token @@ -169,35 +97,6 @@ public static function resolveReShare($linkItem) { return \OC\Share\Share::resolveReShare($linkItem); } - /** - * Get the shared item of item type owned by the current user - * @param string $itemType - * @param string $itemSource - * @param int $format (optional) Format type must be defined by the backend - * @param mixed $parameters - * @param bool $includeCollections - * @return mixed Return depends on format - * @since 5.0.0 - */ - public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE, - $parameters = null, $includeCollections = false) { - return \OC\Share\Share::getItemShared($itemType, $itemSource, $format, $parameters, $includeCollections); - } - - /** - * Get all users an item is shared with - * @param string $itemType - * @param string $itemSource - * @param string $uidOwner - * @param bool $includeCollections - * @param bool $checkExpireDate - * @return array Return array of users - * @since 5.0.0 - parameter $checkExpireDate was added in 7.0.0 - */ - public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) { - return \OC\Share\Share::getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections, $checkExpireDate); - } - /** * sent status if users got informed by mail about share * @param string $itemType @@ -211,65 +110,6 @@ public static function setSendMailStatus($itemType, $itemSource, $shareType, $re return \OC\Share\Share::setSendMailStatus($itemType, $itemSource, $shareType, $recipient, $status); } - /** - * Set the permissions of an item for a specific user or group - * @param string $itemType - * @param string $itemSource - * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string $shareWith User or group the item is being shared with - * @param int $permissions CRUDS permissions - * @return boolean true on success or false on failure - * @since 5.0.0 - */ - public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { - return \OC\Share\Share::setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions); - } - - /** - * Set expiration date for a share - * @param string $itemType - * @param string $itemSource - * @param string $date expiration date - * @param int $shareTime timestamp from when the file was shared - * @return boolean - * @since 5.0.0 - parameter $shareTime was added in 8.0.0 - */ - public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) { - return \OC\Share\Share::setExpirationDate($itemType, $itemSource, $date, $shareTime); - } - - /** - * Set password for a public link share - * @param int $shareId - * @param string $password - * @return boolean - * @since 8.1.0 - */ - public static function setPassword($shareId, $password) { - $userSession = \OC::$server->getUserSession(); - $connection = \OC::$server->getDatabaseConnection(); - $config = \OC::$server->getConfig(); - return \OC\Share\Share::setPassword($userSession, $connection, $config, $shareId, $password); - } - - /** - * Get the backend class for the specified item type - * @param string $itemType - * @return Share_Backend - * @since 5.0.0 - */ - public static function getBackend($itemType) { - return \OC\Share\Share::getBackend($itemType); - } - - /** - * Delete all shares with type SHARE_TYPE_LINK - * @since 6.0.0 - */ - public static function removeAllLinkShares() { - return \OC\Share\Share::removeAllLinkShares(); - } - /** * In case a password protected link is not yet authenticated this function will return false * diff --git a/lib/public/Share_Backend.php b/lib/public/Share_Backend.php deleted file mode 100644 index d388adbba17f..000000000000 --- a/lib/public/Share_Backend.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @author Joas Schilling - * @author Morris Jobke - * @author Robin McCorkell - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -// use OCP namespace for all classes that are considered public. -// This means that they should be used by apps instead of the internal ownCloud classes -namespace OCP; - -/** - * Interface that apps must implement to share content. - * @since 5.0.0 - */ -interface Share_Backend { - - /** - * Check if this $itemSource exist for the user - * @param string $itemSource - * @param string $uidOwner Owner of the item - * @return boolean|null Source - * - * Return false if the item does not exist for the user - * @since 5.0.0 - */ - public function isValidSource($itemSource, $uidOwner); - - /** - * 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 @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. - * If it does generate a new name e.g. name_# - * @since 5.0.0 - */ - public function generateTarget($itemSource, $shareWith, $exclude = null); - - /** - * Converts the shared item sources back into the item in the specified format - * @param array $items Shared items - * @param int $format - * @return array - * - * The items array is a 3-dimensional array with the item_source as the - * first key and the share id as the second key to an array with the share - * info. - * - * The key/value pairs included in the share info depend on the function originally called: - * If called by getItem(s)Shared: id, item_type, item, item_source, - * share_type, share_with, permissions, stime, file_source - * - * If called by getItem(s)SharedWith: id, item_type, item, item_source, - * item_target, share_type, share_with, permissions, stime, file_source, - * file_target - * - * This function allows the backend to control the output of shared items with custom formats. - * It is only called through calls to the public getItem(s)Shared(With) functions. - * @since 5.0.0 - */ - public function formatItems($items, $format, $parameters = null); - - /** - * Check if a given share type is allowd by the back-end - * - * @param int $shareType share type - * @return boolean - * - * The back-end can enable/disable specific share types. Just return true if - * the back-end doesn't provide any specific settings for it and want to allow - * all share types defined by the share API - * @since 8.0.0 - */ - public function isShareTypeAllowed($shareType); -} diff --git a/lib/public/Share_Backend_Collection.php b/lib/public/Share_Backend_Collection.php deleted file mode 100644 index 23dd2db1ac57..000000000000 --- a/lib/public/Share_Backend_Collection.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @author Morris Jobke - * - * @copyright Copyright (c) 2018, ownCloud GmbH - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see - * - */ - -// use OCP namespace for all classes that are considered public. -// This means that they should be used by apps instead of the internal ownCloud classes -namespace OCP; - -/** - * Interface for collections of of items implemented by another share backend. - * Extends the Share_Backend interface. - * @since 5.0.0 - */ -interface Share_Backend_Collection extends Share_Backend { - /** - * Get the sources of the children of the item - * @param string $itemSource - * @return array Returns an array of children each inside an array with the keys: source, target, and file_path if applicable - * @since 5.0.0 - */ - public function getChildren($itemSource); -} From e89431bd01e7ef7b40c48f8780e621dcf30d8c3d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 23:34:14 +0200 Subject: [PATCH 17/21] More Share backend removal --- .../lib/Controller/ShareesController.php | 3 +- tests/lib/Share/Backend.php | 88 ------------------- tests/lib/Share/ShareTest.php | 1 - tests/lib/TagsTest.php | 1 - 4 files changed, 1 insertion(+), 92 deletions(-) delete mode 100644 tests/lib/Share/Backend.php diff --git a/apps/files_sharing/lib/Controller/ShareesController.php b/apps/files_sharing/lib/Controller/ShareesController.php index 2c8758074636..eb029f9e8b7a 100644 --- a/apps/files_sharing/lib/Controller/ShareesController.php +++ b/apps/files_sharing/lib/Controller/ShareesController.php @@ -589,8 +589,7 @@ protected function isRemoteSharingAllowed($itemType) { if ($itemType === 'file' || $itemType === 'folder') { return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled(); } - $backend = Share::getBackend($itemType); - return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE); + return false; } catch (\Exception $e) { return false; } diff --git a/tests/lib/Share/Backend.php b/tests/lib/Share/Backend.php deleted file mode 100644 index f22469782b16..000000000000 --- a/tests/lib/Share/Backend.php +++ /dev/null @@ -1,88 +0,0 @@ -. -*/ - -namespace Test\Share; - -class Backend implements \OCP\Share_Backend { - const FORMAT_SOURCE = 0; - const FORMAT_TARGET = 1; - const FORMAT_PERMISSIONS = 2; - - private $testItem1 = 'test.txt'; - private $testItem2 = 'share.txt'; - private $testId = 1; - - public function isValidSource($itemSource, $uidOwner) { - if ($itemSource == $this->testItem1 || $itemSource == $this->testItem2 || $itemSource == 1) { - return true; - } - } - - public function generateTarget($itemSource, $shareWith, $exclude = null) { - // Always make target be test.txt to cause conflicts - - if (\substr($itemSource, 0, \strlen('test')) !== 'test') { - $target = "test.txt"; - } else { - $target = $itemSource; - } - - $shares = \OCP\Share::getItemsSharedWithUser('test', $shareWith); - - $knownTargets = []; - 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, $knownTargets)) { - $append = $i; - $i++; - } - $target = $name.$append.$ext; - } - - return $target; - } - - public function formatItems($items, $format, $parameters = null) { - $testItems = []; - foreach ($items as $item) { - if ($format === self::FORMAT_SOURCE) { - $testItems[] = $item['item_source']; - } elseif ($format === self::FORMAT_TARGET) { - $testItems[] = $item['item_target']; - } elseif ($format === self::FORMAT_PERMISSIONS) { - $testItems[] = $item['permissions']; - } - } - return $testItems; - } - - public function isShareTypeAllowed($shareType) { - return true; - } -} diff --git a/tests/lib/Share/ShareTest.php b/tests/lib/Share/ShareTest.php index 60eeee8b162c..6e4422a5fc54 100644 --- a/tests/lib/Share/ShareTest.php +++ b/tests/lib/Share/ShareTest.php @@ -82,7 +82,6 @@ protected function setUp() { $g2->addUser($u4); $gAU->addUser($u2); $gAU->addUser($u3); - \OCP\Share::registerBackend('test', 'Test\Share\Backend'); \OC_Hook::clear('OCP\\Share'); \OC::registerShareHooks(); $this->resharing = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_resharing', 'yes'); diff --git a/tests/lib/TagsTest.php b/tests/lib/TagsTest.php index ead493bc2ff7..9e50d52fb5f8 100644 --- a/tests/lib/TagsTest.php +++ b/tests/lib/TagsTest.php @@ -287,7 +287,6 @@ public function testFavorite() { public function testShareTags() { $testTag = 'TestTag'; - \OCP\Share::registerBackend('test', 'Test\Share\Backend'); $tagger = $this->tagMgr->load('test'); $tagger->tagAs(1, $testTag); From 7722a40e092cfd185b88c71862c2f01557389860 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 28 Aug 2018 23:45:12 +0200 Subject: [PATCH 18/21] Fix ShareesController test --- apps/files_sharing/tests/API/ShareesTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/tests/API/ShareesTest.php b/apps/files_sharing/tests/API/ShareesTest.php index a2f5ba78ff64..7ca6e9c02dd8 100644 --- a/apps/files_sharing/tests/API/ShareesTest.php +++ b/apps/files_sharing/tests/API/ShareesTest.php @@ -550,7 +550,8 @@ public function testGetUsers( $this->getMockBuilder(IURLGenerator::class)->disableOriginalConstructor()->getMock(), $this->getMockBuilder(ILogger::class)->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->sharingBlacklist + $this->sharingBlacklist, + $this->getMockBuilder(FederatedShareProvider::class)->disableOriginalConstructor()->getMock() ); $this->invokePrivate($this->sharees, 'limit', [2]); $this->invokePrivate($this->sharees, 'offset', [0]); From 057568b1d81161320314bc74823e5cdaa0aec69d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 10 Oct 2018 18:26:57 +0200 Subject: [PATCH 19/21] Remove obsolete Share.php tests --- .../tests/ExpireSharesJobTest.php | 2 +- tests/lib/Share/ShareTest.php | 1341 ----------------- tests/lib/TagsTest.php | 29 - 3 files changed, 1 insertion(+), 1371 deletions(-) diff --git a/apps/files_sharing/tests/ExpireSharesJobTest.php b/apps/files_sharing/tests/ExpireSharesJobTest.php index 3119d71f2071..d5b530df8ceb 100644 --- a/apps/files_sharing/tests/ExpireSharesJobTest.php +++ b/apps/files_sharing/tests/ExpireSharesJobTest.php @@ -77,7 +77,7 @@ protected function setup() { \OC::registerShareHooks(); - $this->job = new ExpireSharesJob($this->connection, $this->shareManager); + $this->job = new ExpireSharesJob($this->connection, $this->shareManager, \OC::$server->getLogger()); } protected function tearDown() { diff --git a/tests/lib/Share/ShareTest.php b/tests/lib/Share/ShareTest.php index 6e4422a5fc54..4b3d0ba422fd 100644 --- a/tests/lib/Share/ShareTest.php +++ b/tests/lib/Share/ShareTest.php @@ -147,754 +147,6 @@ protected function tearDown() { parent::tearDown(); } - protected function setHttpHelper($httpHelper) { - \OC::$server->registerService('HTTPHelper', function () use ($httpHelper) { - return $httpHelper; - }); - } - - public function testShareInvalidShareType() { - $message = 'Share type foobar is not valid for test.txt'; - try { - \OCP\Share::shareItem('test', 'test.txt', 'foobar', $this->user2, \OCP\Constants::PERMISSION_READ); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - } - - public function testInvalidItemType() { - $message = 'Sharing backend for foobar not found'; - try { - \OCP\Share::shareItem('foobar', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::getItemsSharedWith('foobar'); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::getItemSharedWith('foobar', 'test.txt'); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::getItemSharedWithBySource('foobar', 'test.txt'); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::getItemShared('foobar', 'test.txt'); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::unshare('foobar', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - try { - \OCP\Share::setPermissions('foobar', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_UPDATE); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - } - - protected function shareUserOneTestFileWithUserTwo() { - \OC_User::setUserId($this->user1); - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), - 'Failed asserting that user 1 successfully shared text.txt with user 2.' - ); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemShared('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that test.txt is a shared file of user 1.' - ); - - \OC_User::setUserId($this->user2); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that user 2 has access to test.txt after initial sharing.' - ); - } - - protected function shareUserTestFileAsLink() { - \OC_User::setUserId($this->user1); - $result = \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); - $this->assertInternalType('string', $result); - } - - /** - * @param string $sharer - * @param string $receiver - */ - protected function shareUserTestFileWithUser($sharer, $receiver) { - \OC_User::setUserId($sharer); - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $receiver, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE), - 'Failed asserting that ' . $sharer . ' successfully shared text.txt with ' . $receiver . '.' - ); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemShared('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that test.txt is a shared file of ' . $sharer . '.' - ); - - \OC_User::setUserId($receiver); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that ' . $receiver . ' has access to test.txt after initial sharing.' - ); - } - - public function testShareWithUser() { - // Invalid shares - $message = 'Sharing test.txt failed, because you can not share with yourself'; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user1, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - $message = 'Sharing test.txt failed, because the user foobar does not exist'; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, 'foobar', \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - $message = 'Sharing foobar failed, because the sharing backend for test could not find its source'; - try { - \OCP\Share::shareItem('test', 'foobar', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Valid share - $this->shareUserOneTestFileWithUserTwo(); - - // Attempt to share again - \OC_User::setUserId($this->user1); - $message = 'Sharing test.txt failed, because this item is already shared with '.$this->user2; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Attempt to share back - \OC_User::setUserId($this->user2); - $message = 'Sharing failed, because the user '.$this->user1.' is the original sharer'; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user1, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Unshare - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::unshare('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2)); - - // Attempt reshare without share permission - $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - \OC_User::setUserId($this->user2); - $message = 'Sharing test.txt failed, because resharing is not allowed'; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user3, \OCP\Constants::PERMISSION_READ); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Owner grants share and update permission - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::setPermissions('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE)); - - // Attempt reshare with escalated permissions - \OC_User::setUserId($this->user2); - $message = 'Sharing test.txt failed, because the permissions exceed permissions granted to '.$this->user2; - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user3, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Valid reshare - $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user3, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE)); - $this->assertEquals(['test.txt'], \OCP\Share::getItemShared('test', 'test.txt', Backend::FORMAT_SOURCE)); - \OC_User::setUserId($this->user3); - $this->assertEquals(['test.txt'], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE)); - $this->assertEquals([\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_PERMISSIONS)); - - // Attempt to escalate permissions - \OC_User::setUserId($this->user2); - $message = 'Setting permissions for test.txt failed, because the permissions exceed permissions granted to '.$this->user2; - try { - \OCP\Share::setPermissions('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user3, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE); - $this->fail('Exception was expected: '.$message); - } catch (\Exception $exception) { - $this->assertEquals($message, $exception->getMessage()); - } - - // Remove update permission - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::setPermissions('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE)); - \OC_User::setUserId($this->user2); - $this->assertEquals([\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_PERMISSIONS)); - \OC_User::setUserId($this->user3); - $this->assertEquals([\OCP\Constants::PERMISSION_READ], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_PERMISSIONS)); - - // Remove share permission - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::setPermissions('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - \OC_User::setUserId($this->user2); - $this->assertEquals([\OCP\Constants::PERMISSION_READ], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_PERMISSIONS)); - \OC_User::setUserId($this->user3); - $this->assertSame([], \OCP\Share::getItemSharedWith('test', 'test.txt')); - - // Reshare again, and then have owner unshare - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::setPermissions('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE)); - \OC_User::setUserId($this->user2); - $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user3, \OCP\Constants::PERMISSION_READ)); - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::unshare('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2)); - \OC_User::setUserId($this->user2); - $this->assertSame([], \OCP\Share::getItemSharedWith('test', 'test.txt')); - \OC_User::setUserId($this->user3); - $this->assertSame([], \OCP\Share::getItemSharedWith('test', 'test.txt')); - - // Attempt target conflict - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - \OC_User::setUserId($this->user3); - $this->assertTrue(\OCP\Share::shareItem('test', 'share.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - - \OC_User::setUserId($this->user2); - $to_test = \OCP\Share::getItemsSharedWith('test', Backend::FORMAT_TARGET); - $this->assertCount(2, $to_test); - $this->assertContains('test.txt', $to_test); - $this->assertContains('test1.txt', $to_test); - - // Unshare from self - $this->assertTrue(\OCP\Share::unshareFromSelf('test', 'test.txt')); - $this->assertEquals(['test1.txt'], \OCP\Share::getItemsSharedWith('test', Backend::FORMAT_TARGET)); - - // Unshare from self via source - $this->assertTrue(\OCP\Share::unshareFromSelf('test', 'share.txt', true)); - $this->assertEquals([], \OCP\Share::getItemsSharedWith('test', Backend::FORMAT_TARGET)); - - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - \OC_User::setUserId($this->user3); - $this->assertTrue(\OCP\Share::shareItem('test', 'share.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); - - \OC_User::setUserId($this->user2); - $to_test = \OCP\Share::getItemsSharedWith('test', Backend::FORMAT_TARGET); - $this->assertCount(2, $to_test); - $this->assertContains('test.txt', $to_test); - $this->assertContains('test1.txt', $to_test); - - // Remove user - \OC_User::setUserId($this->user1); - $user = \OC::$server->getUserManager()->get($this->user1); - $user->delete(); - \OC_User::setUserId($this->user2); - $this->assertEquals(['test1.txt'], \OCP\Share::getItemsSharedWith('test', Backend::FORMAT_TARGET)); - } - - public function testShareWithUserExpirationExpired() { - \OC_User::setUserId($this->user1); - $this->shareUserOneTestFileWithUserTwo(); - $this->shareUserTestFileAsLink(); - - // manipulate share table and set expire date to the past - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?'); - $query->bindValue(1, new \DateTime($this->dateInPast), 'datetime'); - $query->bindValue(2, 'test'); - $query->bindValue(3, 'test.txt'); - $query->bindValue(4, $this->user1); - $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK); - $query->execute(); - - $shares = \OCP\Share::getItemsShared('test'); - $this->assertCount(1, $shares); - $share = \reset($shares); - $this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share['share_type']); - } - - public function testSetExpireDateInPast() { - \OC_User::setUserId($this->user1); - $this->shareUserOneTestFileWithUserTwo(); - $this->shareUserTestFileAsLink(); - - $setExpireDateFailed = false; - try { - $this->assertTrue( - \OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInPast, ''), - 'Failed asserting that user 1 successfully set an expiration date for the test.txt share.' - ); - } catch (\Exception $e) { - $setExpireDateFailed = true; - } - - $this->assertTrue($setExpireDateFailed); - } - - public function testShareWithUserExpirationValid() { - \OC_User::setUserId($this->user1); - $this->shareUserOneTestFileWithUserTwo(); - $this->shareUserTestFileAsLink(); - - $this->assertTrue( - \OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture, ''), - 'Failed asserting that user 1 successfully set an expiration date for the test.txt share.' - ); - - $shares = \OCP\Share::getItemsShared('test'); - $this->assertCount(2, $shares); - } - - /* - * if user is in a group excluded from resharing, then the share permission should - * be removed - */ - public function testShareWithUserAndUserIsExcludedFromResharing() { - \OC_User::setUserId($this->user1); - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user4, \OCP\Constants::PERMISSION_ALL), - 'Failed asserting that user 1 successfully shared text.txt with user 4.' - ); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemShared('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that test.txt is a shared file of user 1.' - ); - - // exclude group2 from sharing - \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups_list', $this->group2); - \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups', "yes"); - - \OC_User::setUserId($this->user4); - - $share = \OCP\Share::getItemSharedWith('test', 'test.txt'); - - $this->assertSame(\OCP\Constants::PERMISSION_ALL & ~\OCP\Constants::PERMISSION_SHARE, $share['permissions'], - 'Failed asserting that user 4 is excluded from re-sharing'); - - \OC::$server->getAppConfig()->deleteKey('core', 'shareapi_exclude_groups_list'); - \OC::$server->getAppConfig()->deleteKey('core', 'shareapi_exclude_groups'); - } - - protected function shareUserOneTestFileWithGroupOne() { - \OC_User::setUserId($this->user1); - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_GROUP, $this->group1, \OCP\Constants::PERMISSION_READ), - 'Failed asserting that user 1 successfully shared text.txt with group 1.' - ); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemShared('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that test.txt is a shared file of user 1.' - ); - - \OC_User::setUserId($this->user2); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that user 2 has access to test.txt after initial sharing.' - ); - - \OC_User::setUserId($this->user3); - $this->assertContains( - 'test.txt', - \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'Failed asserting that user 3 has access to test.txt after initial sharing.' - ); - } - - /** - * Test that unsharing from group will also delete all - * child entries - */ - public function testShareWithGroupThenUnshare() { - \OC_User::setUserId($this->user5); - \OCP\Share::shareItem( - 'test', - 'test.txt', - \OCP\Share::SHARE_TYPE_GROUP, - $this->group1, - \OCP\Constants::PERMISSION_ALL - ); - - $targetUsers = [$this->user1, $this->user2, $this->user3]; - - foreach ($targetUsers as $targetUser) { - \OC_User::setUserId($targetUser); - $items = \OCP\Share::getItemsSharedWithUser( - 'test', - $targetUser, - Backend::FORMAT_TARGET - ); - $this->assertCount(1, $items); - } - - \OC_User::setUserId($this->user5); - \OCP\Share::unshare( - 'test', - 'test.txt', - \OCP\Share::SHARE_TYPE_GROUP, - $this->group1 - ); - - // verify that all were deleted - foreach ($targetUsers as $targetUser) { - \OC_User::setUserId($targetUser); - $items = \OCP\Share::getItemsSharedWithUser( - 'test', - $targetUser, - Backend::FORMAT_TARGET - ); - $this->assertCount(0, $items); - } - } - - public function testShareWithGroupAndUserBothHaveTheSameId() { - $this->shareUserTestFileWithUser($this->user1, $this->groupAndUser); - - \OC_User::setUserId($this->groupAndUser); - - $this->assertEquals(['test.txt'], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - '"groupAndUser"-User does not see the file but it was shared with him'); - - \OC_User::setUserId($this->user2); - $this->assertEquals([], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'User2 sees test.txt but it was only shared with the user "groupAndUser" and not with group'); - - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::unshareAll('test', 'test.txt')); - - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_GROUP, $this->groupAndUser, \OCP\Constants::PERMISSION_READ), - 'Failed asserting that user 1 successfully shared text.txt with group 1.' - ); - - \OC_User::setUserId($this->groupAndUser); - $this->assertEquals([], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - '"groupAndUser"-User sees test.txt but it was only shared with the group "groupAndUser" and not with the user'); - - \OC_User::setUserId($this->user2); - $this->assertEquals(['test.txt'], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), - 'User2 does not see test.txt but it was shared with the group "groupAndUser"'); - - \OC_User::setUserId($this->user1); - $this->assertTrue(\OCP\Share::unshareAll('test', 'test.txt')); - } - - /** - * @param boolean|string $token - * @return array - */ - protected function getShareByValidToken($token) { - $row = \OCP\Share::getShareByToken($token); - $this->assertInternalType( - 'array', - $row, - "Failed asserting that a share for token $token exists." - ); - return $row; - } - - public function testGetItemSharedWithUser() { - \OC_User::setUserId($this->user1); - - //add dummy values to the share table - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (' - .' `item_type`, `item_source`, `item_target`, `share_type`,' - .' `share_with`, `uid_owner`) VALUES (?,?,?,?,?,?)'); - $args = ['test', 99, 'target1', \OCP\Share::SHARE_TYPE_USER, $this->user2, $this->user1]; - $query->execute($args); - $args = ['test', 99, 'target2', \OCP\Share::SHARE_TYPE_USER, $this->user4, $this->user1]; - $query->execute($args); - $args = ['test', 99, 'target3', \OCP\Share::SHARE_TYPE_USER, $this->user3, $this->user2]; - $query->execute($args); - $args = ['test', 99, 'target4', \OCP\Share::SHARE_TYPE_USER, $this->user3, $this->user4]; - $query->execute($args); - $args = ['test', 99, 'target4', \OCP\Share::SHARE_TYPE_USER, $this->user6, $this->user4]; - $query->execute($args); - - $result1 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user2, $this->user1); - $this->assertCount(1, $result1); - $this->verifyResult($result1, ['target1']); - - $result2 = \OCP\Share::getItemSharedWithUser('test', 99, null, $this->user1); - $this->assertCount(2, $result2); - $this->verifyResult($result2, ['target1', 'target2']); - - $result3 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user3); - $this->assertCount(2, $result3); - $this->verifyResult($result3, ['target3', 'target4']); - - $result4 = \OCP\Share::getItemSharedWithUser('test', 99, null, null); - $this->assertCount(5, $result4); // 5 because target4 appears twice - $this->verifyResult($result4, ['target1', 'target2', 'target3', 'target4']); - - $result6 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user6, null); - $this->assertCount(1, $result6); - $this->verifyResult($result6, ['target4']); - } - - public function testGetItemSharedWithUserFromGroupShare() { - \OC_User::setUserId($this->user1); - - //add dummy values to the share table - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (' - .' `item_type`, `item_source`, `item_target`, `share_type`,' - .' `share_with`, `uid_owner`) VALUES (?,?,?,?,?,?)'); - $args = ['test', 99, 'target1', \OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user1]; - $query->execute($args); - $args = ['test', 99, 'target2', \OCP\Share::SHARE_TYPE_GROUP, $this->group2, $this->user1]; - $query->execute($args); - $args = ['test', 99, 'target3', \OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user2]; - $query->execute($args); - $args = ['test', 99, 'target4', \OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user4]; - $query->execute($args); - - // user2 is in group1 and group2 - $result1 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user2, $this->user1); - $this->assertCount(2, $result1); - $this->verifyResult($result1, ['target1', 'target2']); - - $result2 = \OCP\Share::getItemSharedWithUser('test', 99, null, $this->user1); - $this->assertCount(2, $result2); - $this->verifyResult($result2, ['target1', 'target2']); - - // user3 is in group1 and group2 - $result3 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user3); - $this->assertCount(3, $result3); - $this->verifyResult($result3, ['target1', 'target3', 'target4']); - - $result4 = \OCP\Share::getItemSharedWithUser('test', 99, null, null); - $this->assertCount(4, $result4); - $this->verifyResult($result4, ['target1', 'target2', 'target3', 'target4']); - - $result6 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user6, null); - $this->assertCount(0, $result6); - } - - public function verifyResult($result, $expected) { - foreach ($result as $r) { - if (\in_array($r['item_target'], $expected)) { - $key = \array_search($r['item_target'], $expected); - unset($expected[$key]); - } - } - $this->assertEmpty($expected, 'did not found all expected values'); - } - - public function testGetShareSubItemsWhenUserNotInGroup() { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_GROUP, $this->group1, \OCP\Constants::PERMISSION_READ); - - $result = \OCP\Share::getItemsSharedWithUser('test', $this->user2); - $this->assertCount(1, $result); - - $groupShareId = \array_keys($result)[0]; - - // remove user from group - $userObject = \OC::$server->getUserManager()->get($this->user2); - \OC::$server->getGroupManager()->get($this->group1)->removeUser($userObject); - - $result = \OCP\Share::getItemsSharedWithUser('test', $this->user2); - $this->assertCount(0, $result); - - // test with buggy data - $qb = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(2), // group sub-share - 'share_with' => $qb->expr()->literal($this->user2), - 'parent' => $qb->expr()->literal($groupShareId), - 'uid_owner' => $qb->expr()->literal($this->user1), - 'item_type' => $qb->expr()->literal('test'), - 'item_source' => $qb->expr()->literal('test.txt'), - 'item_target' => $qb->expr()->literal('test.txt'), - 'file_target' => $qb->expr()->literal('test2.txt'), - 'permissions' => $qb->expr()->literal(1), - 'stime' => $qb->expr()->literal(\time()), - ])->execute(); - - $result = \OCP\Share::getItemsSharedWithUser('test', $this->user2); - $this->assertCount(0, $result); - - $qb->delete('share')->execute(); - } - - public function testShareItemWithLink() { - \OC_User::setUserId($this->user1); - $token = \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); - $this->assertInternalType( - 'string', - $token, - 'Failed asserting that user 1 successfully shared text.txt as link with token.' - ); - - // testGetShareByTokenNoExpiration - $row = $this->getShareByValidToken($token); - $this->assertEmpty( - $row['expiration'], - 'Failed asserting that the returned row does not have an expiration date.' - ); - - // testGetShareByTokenExpirationValid - $this->assertTrue( - \OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture, ''), - 'Failed asserting that user 1 successfully set a future expiration date for the test.txt share.' - ); - $row = $this->getShareByValidToken($token); - $this->assertNotEmpty( - $row['expiration'], - 'Failed asserting that the returned row has an expiration date.' - ); - - // manipulate share table and set expire date to the past - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?'); - $query->bindValue(1, new \DateTime($this->dateInPast), 'datetime'); - $query->bindValue(2, 'test'); - $query->bindValue(3, 'test.txt'); - $query->bindValue(4, $this->user1); - $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK); - $query->execute(); - - $this->assertFalse( - \OCP\Share::getShareByToken($token), - 'Failed asserting that an expired share could not be found.' - ); - } - - public function testShareItemWithLinkAndDefaultExpireDate() { - \OC_User::setUserId($this->user1); - - $config = \OC::$server->getConfig(); - - $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); - $config->setAppValue('core', 'shareapi_expire_after_n_days', '2'); - - $token = \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); - $this->assertInternalType( - 'string', - $token, - 'Failed asserting that user 1 successfully shared text.txt as link with token.' - ); - - // share should have default expire date - - $row = $this->getShareByValidToken($token); - $this->assertNotEmpty( - $row['expiration'], - 'Failed asserting that the returned row has an default expiration date.' - ); - - $config->deleteAppValue('core', 'shareapi_default_expire_date'); - $config->deleteAppValue('core', 'shareapi_expire_after_n_days'); - } - - public function dataShareWithRemoteUserAndRemoteIsInvalid() { - return [ - // Invalid path - ['user@'], - - // Invalid user - ['@server'], - ['us/er@server'], - ['us:er@server'], - - // Invalid splitting - ['user'], - [''], - ['us/erserver'], - ['us:erserver'], - ]; - } - - /** - * @dataProvider dataShareWithRemoteUserAndRemoteIsInvalid - * - * @param string $remoteId - * @expectedException \OC\HintException - */ - public function testShareWithRemoteUserAndRemoteIsInvalid($remoteId) { - \OC_User::setUserId($this->user1); - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, $remoteId, \OCP\Constants::PERMISSION_ALL); - } - - public function testUnshareAll() { - $this->shareUserTestFileWithUser($this->user1, $this->user2); - $this->shareUserTestFileWithUser($this->user2, $this->user3); - $this->shareUserTestFileWithUser($this->user3, $this->user4); - $this->shareUserOneTestFileWithGroupOne(); - - \OC_User::setUserId($this->user1); - $this->assertEquals( - ['test.txt', 'test.txt'], - \OCP\Share::getItemsShared('test', Backend::FORMAT_SOURCE), - 'Failed asserting that the test.txt file is shared exactly two times by user1.' - ); - - \OC_User::setUserId($this->user2); - $this->assertEquals( - ['test.txt'], - \OCP\Share::getItemsShared('test', Backend::FORMAT_SOURCE), - 'Failed asserting that the test.txt file is shared exactly once by user2.' - ); - - \OC_User::setUserId($this->user3); - $this->assertEquals( - ['test.txt'], - \OCP\Share::getItemsShared('test', Backend::FORMAT_SOURCE), - 'Failed asserting that the test.txt file is shared exactly once by user3.' - ); - - $this->assertTrue( - \OCP\Share::unshareAll('test', 'test.txt'), - 'Failed asserting that user 3 successfully unshared all shares of the test.txt share.' - ); - - $this->assertEquals( - [], - \OCP\Share::getItemsShared('test'), - 'Failed asserting that the share of the test.txt file by user 3 has been removed.' - ); - - \OC_User::setUserId($this->user1); - $this->assertEquals( - [], - \OCP\Share::getItemsShared('test'), - 'Failed asserting that both shares of the test.txt file by user 1 have been removed.' - ); - - \OC_User::setUserId($this->user2); - $this->assertEquals( - [], - \OCP\Share::getItemsShared('test'), - 'Failed asserting that the share of the test.txt file by user 2 has been removed.' - ); - } - /** * @dataProvider checkPasswordProtectedShareDataProvider * @param $expected @@ -940,598 +192,5 @@ public function urls() { ['owncloud.org', 'owncloud.org'], ]; } - - public function dataRemoteShareUrlCalls() { - $expectedException = \Exception::class; - return [ - // Fallback prohibited - ['admin@localhost', 'localhost', false, false, $expectedException], - ['admin@localhost', 'localhost', false, true], - ['admin@https://localhost', 'localhost', false, false, $expectedException], - ['admin@https://localhost', 'localhost', false, true], - ['admin@http://localhost', 'localhost', false, false, $expectedException], - ['admin@http://localhost', 'localhost', false, true], - ['admin@localhost/subFolder', 'localhost/subFolder', false, false, $expectedException], - ['admin@localhost/subFolder', 'localhost/subFolder', false, true], - // Fallback allowed - ['admin@localhost', 'localhost', true, true], - ['admin@https://localhost', 'localhost', true, true], - ['admin@http://localhost', 'localhost', true, true], - ['admin@localhost/subFolder', 'localhost/subFolder', true, true], - ]; - } - - /** - * @dataProvider dataRemoteShareUrlCalls - * - * @param string $shareWith - * @param string $urlHost - * @param bool $allowFallback - * @param bool $httpsSuccess - * @param string $expectedException - */ - public function testRemoteShareUrlCalls($shareWith, $urlHost, $allowFallback, $httpsSuccess, $expectedException = null) { - $oldHttpHelper = \OC::$server->query('HTTPHelper'); - $httpHelperMock = $this->getMockBuilder('OC\HttpHelper') - ->disableOriginalConstructor() - ->getMock(); - $this->setHttpHelper($httpHelperMock); - - if ($expectedException !== null) { - $this->expectException($expectedException); - } - - $oldFallbackValue = \OC::$server->getConfig()->getSystemValue('sharing.federation.allowHttpFallback'); - \OC::$server->getConfig()->setSystemValue('sharing.federation.allowHttpFallback', $allowFallback); - - if ($httpsSuccess) { - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://' . $urlHost . '/ocs/v1.php/cloud/shares'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - } else { - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://' . $urlHost . '/ocs/v1.php/cloud/shares'), $this->anything()) - ->willReturn(['success' => false, 'result' => 'Exception']); - } - - if ($allowFallback && !$httpsSuccess) { - $httpHelperMock->expects($this->at(1)) - ->method('post') - ->with($this->stringStartsWith('http://' . $urlHost . '/ocs/v1.php/cloud/shares'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - } - - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, $shareWith, \OCP\Constants::PERMISSION_READ); - - $shares = \OCP\Share::getItemShared('test', 'test.txt'); - $share = \array_shift($shares); - - if ($httpsSuccess) { - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://' . $urlHost . '/ocs/v1.php/cloud/shares/' . $share['id'] . '/unshare'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - } else { - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://' . $urlHost . '/ocs/v1.php/cloud/shares/' . $share['id'] . '/unshare'), $this->anything()) - ->willReturn(['success' => false, 'result' => 'Exception']); - } - - if ($allowFallback && !$httpsSuccess) { - $httpHelperMock->expects($this->at(1)) - ->method('post') - ->with($this->stringStartsWith('http://' . $urlHost . '/ocs/v1.php/cloud/shares/' . $share['id'] . '/unshare'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - } - - \OCP\Share::unshare('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, $shareWith); - - $this->setHttpHelper($oldHttpHelper); - \OC::$server->getConfig()->setSystemValue('sharing.federation.allowHttpFallback', $oldFallbackValue); - } - - /** - * @dataProvider dataProviderTestGroupItems - * @param array $ungrouped - * @param array $grouped - */ - public function testGroupItems($ungrouped, $grouped) { - $result = DummyShareClass::groupItemsTest($ungrouped); - - $this->compareArrays($grouped, $result); - } - - public function compareArrays($result, $expectedResult) { - foreach ($expectedResult as $key => $value) { - if (\is_array($value)) { - $this->compareArrays($result[$key], $value); - } else { - $this->assertSame($value, $result[$key]); - } - } - } - - public function dataProviderTestGroupItems() { - return [ - // one array with one share - [ - [ // input - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_ALL, 'item_target' => 't1']], - [ // expected result - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_ALL, 'item_target' => 't1']]], - // two shares both point to the same source - [ - [ // input - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1'], - ], - [ // expected result - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1', - 'grouped' => [ - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1'], - ] - ], - ] - ], - // two shares both point to the same source but with different targets - [ - [ // input - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't2'], - ], - [ // expected result - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't2'], - ] - ], - // three shares two point to the same source - [ - [ // input - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 2, 'permissions' => \OCP\Constants::PERMISSION_CREATE, 'item_target' => 't2'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1'], - ], - [ // expected result - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1', - 'grouped' => [ - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_READ, 'item_target' => 't1'], - ['item_source' => 1, 'permissions' => \OCP\Constants::PERMISSION_UPDATE, 'item_target' => 't1'], - ] - ], - ['item_source' => 2, 'permissions' => \OCP\Constants::PERMISSION_CREATE, 'item_target' => 't2'], - ] - ], - ]; - } - - /** - * Ensure that we do not allow removing a an expiration date from a link share if this - * is enforced by the settings. - */ - public function testClearExpireDateWhileEnforced() { - \OC_User::setUserId($this->user1); - - \OC::$server->getAppConfig()->setValue('core', 'shareapi_default_expire_date', 'yes'); - \OC::$server->getAppConfig()->setValue('core', 'shareapi_expire_after_n_days', '2'); - \OC::$server->getAppConfig()->setValue('core', 'shareapi_enforce_expire_date', 'yes'); - - $token = \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); - $this->assertInternalType( - 'string', - $token, - 'Failed asserting that user 1 successfully shared text.txt as link with token.' - ); - - $setExpireDateFailed = false; - try { - $this->assertTrue( - \OCP\Share::setExpirationDate('test', 'test.txt', '', ''), - 'Failed asserting that user 1 successfully set an expiration date for the test.txt share.' - ); - } catch (\Exception $e) { - $setExpireDateFailed = true; - } - - $this->assertTrue($setExpireDateFailed); - - \OC::$server->getAppConfig()->deleteKey('core', 'shareapi_default_expire_date'); - \OC::$server->getAppConfig()->deleteKey('core', 'shareapi_expire_after_n_days'); - \OC::$server->getAppConfig()->deleteKey('core', 'shareapi_enforce_expire_date'); - } - - /** - * Cannot set password is there is no user - * - * @expectedException \Exception - * @expectedExceptionMessage User not logged in - */ - public function testSetPasswordNoUser() { - $userSession = $this->getMockBuilder('\OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - - $connection = $this->getMockBuilder('\OC\DB\Connection') - ->disableOriginalConstructor() - ->getMock(); - - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - - \OC\Share\Share::setPassword($userSession, $connection, $config, 1, 'pass'); - } - - public function testPasswords() { - $pass = 'secret'; - - $this->shareUserTestFileAsLink(); - - $userSession = \OC::$server->getUserSession(); - $connection = \OC::$server->getDatabaseConnection(); - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - - // Find the share ID in the db - $qb = $connection->getQueryBuilder(); - $qb->select('id') - ->from('share') - ->where($qb->expr()->eq('item_type', $qb->createParameter('type'))) - ->andWhere($qb->expr()->eq('item_source', $qb->createParameter('source'))) - ->andWhere($qb->expr()->eq('uid_owner', $qb->createParameter('owner'))) - ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type'))) - ->setParameter('type', 'test') - ->setParameter('source', 'test.txt') - ->setParameter('owner', $this->user1) - ->setParameter('share_type', \OCP\Share::SHARE_TYPE_LINK); - - $res = $qb->execute()->fetchAll(); - $this->assertCount(1, $res); - $id = $res[0]['id']; - - // Set password on share - $res = \OC\Share\Share::setPassword($userSession, $connection, $config, $id, $pass); - $this->assertTrue($res); - - // Fetch the hash from the database - $qb = $connection->getQueryBuilder(); - $qb->select('share_with') - ->from('share') - ->where($qb->expr()->eq('id', $qb->createParameter('id'))) - ->setParameter('id', $id); - $hash = $qb->execute()->fetch()['share_with']; - - $hasher = \OC::$server->getHasher(); - - // Verify hash - $this->assertTrue($hasher->verify($pass, $hash)); - } - - /** - * Test setting a password when everything is fine - */ - public function testSetPassword() { - $user = $this->getMockBuilder('\OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $user->method('getUID')->willReturn('user'); - - $userSession = $this->getMockBuilder('\OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - $userSession->method('getUser')->willReturn($user); - - $ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb->method('update')->will($this->returnSelf()); - $qb->method('set')->will($this->returnSelf()); - $qb->method('where')->will($this->returnSelf()); - $qb->method('andWhere')->will($this->returnSelf()); - $qb->method('select')->will($this->returnSelf()); - $qb->method('from')->will($this->returnSelf()); - $qb->method('setParameter')->will($this->returnSelf()); - $qb->method('expr')->willReturn($ex); - - $ret = $this->getMockBuilder('\Doctrine\DBAL\Driver\ResultStatement') - ->disableOriginalConstructor() - ->getMock(); - $ret->method('fetch')->willReturn(['uid_owner' => 'user']); - $qb->method('execute')->willReturn($ret); - - $connection = $this->getMockBuilder('\OC\DB\Connection') - ->disableOriginalConstructor() - ->getMock(); - $connection->method('getQueryBuilder')->willReturn($qb); - - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - - $event = null; - \OC::$server->getEventDispatcher()->addListener('OCP\Share::validatePassword', - function (GenericEvent $receivedEvent) use (&$event) { - $event = $receivedEvent; - } - ); - - $res = \OC\Share\Share::setPassword($userSession, $connection, $config, 1, 'pass'); - - $this->assertTrue($res); - $this->assertEquals('pass', $event->getArgument('password')); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage Cannot remove password - * - * Test removing a password when password is enforced - */ - public function testSetPasswordRemove() { - $user = $this->getMockBuilder('\OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $user->method('getUID')->willReturn('user'); - - $userSession = $this->getMockBuilder('\OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - $userSession->method('getUser')->willReturn($user); - - $ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb->method('update')->will($this->returnSelf()); - $qb->method('select')->will($this->returnSelf()); - $qb->method('from')->will($this->returnSelf()); - $qb->method('set')->will($this->returnSelf()); - $qb->method('where')->will($this->returnSelf()); - $qb->method('andWhere')->will($this->returnSelf()); - $qb->method('setParameter')->will($this->returnSelf()); - $qb->method('expr')->willReturn($ex); - - $ret = $this->getMockBuilder('\Doctrine\DBAL\Driver\ResultStatement') - ->disableOriginalConstructor() - ->getMock(); - $ret->method('fetch')->willReturn(['uid_owner' => 'user']); - $qb->method('execute')->willReturn($ret); - - $connection = $this->getMockBuilder('\OC\DB\Connection') - ->disableOriginalConstructor() - ->getMock(); - $connection->method('getQueryBuilder')->willReturn($qb); - - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - $config->method('getAppValue')->willReturn('yes'); - - \OC\Share\Share::setPassword($userSession, $connection, $config, 1, ''); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage Share not found - * - * Test modification of invaid share - */ - public function testSetPasswordInvalidShare() { - $user = $this->getMockBuilder('\OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $user->method('getUID')->willReturn('user'); - - $userSession = $this->getMockBuilder('\OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - $userSession->method('getUser')->willReturn($user); - - $ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb->method('update')->will($this->returnSelf()); - $qb->method('set')->will($this->returnSelf()); - $qb->method('where')->will($this->returnSelf()); - $qb->method('andWhere')->will($this->returnSelf()); - $qb->method('select')->will($this->returnSelf()); - $qb->method('from')->will($this->returnSelf()); - $qb->method('setParameter')->will($this->returnSelf()); - $qb->method('expr')->willReturn($ex); - - $ret = $this->getMockBuilder('\Doctrine\DBAL\Driver\ResultStatement') - ->disableOriginalConstructor() - ->getMock(); - $ret->method('fetch')->willReturn([]); - $qb->method('execute')->willReturn($ret); - - $connection = $this->getMockBuilder('\OC\DB\Connection') - ->disableOriginalConstructor() - ->getMock(); - $connection->method('getQueryBuilder')->willReturn($qb); - - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - - \OC\Share\Share::setPassword($userSession, $connection, $config, 1, 'pass'); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage Cannot update share of a different user - * - * Test modification of share of another user - */ - public function testSetPasswordShareOtherUser() { - $user = $this->getMockBuilder('\OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $user->method('getUID')->willReturn('user'); - - $userSession = $this->getMockBuilder('\OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - $userSession->method('getUser')->willReturn($user); - - $ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') - ->disableOriginalConstructor() - ->getMock(); - $qb->method('update')->will($this->returnSelf()); - $qb->method('set')->will($this->returnSelf()); - $qb->method('where')->will($this->returnSelf()); - $qb->method('andWhere')->will($this->returnSelf()); - $qb->method('select')->will($this->returnSelf()); - $qb->method('from')->will($this->returnSelf()); - $qb->method('setParameter')->will($this->returnSelf()); - $qb->method('expr')->willReturn($ex); - - $ret = $this->getMockBuilder('\Doctrine\DBAL\Driver\ResultStatement') - ->disableOriginalConstructor() - ->getMock(); - $ret->method('fetch')->willReturn(['uid_owner' => 'user2']); - $qb->method('execute')->willReturn($ret); - - $connection = $this->getMockBuilder('\OC\DB\Connection') - ->disableOriginalConstructor() - ->getMock(); - $connection->method('getQueryBuilder')->willReturn($qb); - - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - - \OC\Share\Share::setPassword($userSession, $connection, $config, 1, 'pass'); - } - - /** - * Make sure that a user cannot have multiple identical shares to remote users - */ - public function testOnlyOneRemoteShare() { - $oldHttpHelper = \OC::$server->query('HTTPHelper'); - $httpHelperMock = $this->getMockBuilder('OC\HttpHelper') - ->disableOriginalConstructor() - ->getMock(); - $this->setHttpHelper($httpHelperMock); - - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://localhost/ocs/v1.php/cloud/shares'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, 'foo@localhost', \OCP\Constants::PERMISSION_READ); - $shares = \OCP\Share::getItemShared('test', 'test.txt'); - $share = \array_shift($shares); - - //Try share again - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, 'foo@localhost', \OCP\Constants::PERMISSION_READ); - $this->fail('Identical remote shares are not allowed'); - } catch (\Exception $e) { - $this->assertEquals('Sharing test.txt failed, because this item is already shared with foo@localhost', $e->getMessage()); - } - - $httpHelperMock->expects($this->at(0)) - ->method('post') - ->with($this->stringStartsWith('https://localhost/ocs/v1.php/cloud/shares/' . $share['id'] . '/unshare'), $this->anything()) - ->willReturn(['success' => true, 'result' => \json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])]); - - \OCP\Share::unshare('test', 'test.txt', \OCP\Share::SHARE_TYPE_REMOTE, 'foo@localhost'); - $this->setHttpHelper($oldHttpHelper); - } - - /** - * Test case for #19119 - */ - public function testReshareWithLinkDefaultExpirationDate() { - $config = \OC::$server->getConfig(); - $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); - $config->setAppValue('core', 'shareapi_expire_after_n_days', '2'); - - // Expiration date - $expireAt = \time() + 2 * 24*60*60; - $date = new \DateTime(); - $date->setTimestamp($expireAt); - $date->setTime(0, 0, 0); - - //Share a file from user 1 to user 2 - $this->shareUserTestFileWithUser($this->user1, $this->user2); - - //User 2 shares as link - \OC_User::setUserId($this->user2); - $result = \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); - $this->assertInternalType('string', $result); - - //Check if expire date is correct - $result = \OCP\Share::getItemShared('test', 'test.txt'); - $this->assertCount(1, $result); - $result = \reset($result); - $this->assertNotEmpty($result['expiration']); - $expireDate = new \DateTime($result['expiration']); - $this->assertEquals($date, $expireDate); - - //Unshare - $this->assertTrue(\OCP\Share::unshareAll('test', 'test.txt')); - - //Reset config - $config->deleteAppValue('core', 'shareapi_default_expire_date'); - $config->deleteAppValue('core', 'shareapi_expire_after_n_days'); - } - - public function testShareWithSelfError() { - \OC_User::setUserId($this->user1); - - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user1, \OCP\Constants::PERMISSION_ALL); - $this->fail(); - } catch (\Exception $e) { - $this->assertEquals('Sharing test.txt failed, because you can not share with yourself', $e->getMessage()); - } - } - - public function testShareWithOwnerError() { - \OC_User::setUserId($this->user1); - - $this->assertTrue( - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_ALL), - 'Failed asserting that user 1 successfully shared "test" with user 2.' - ); - - \OC_User::setUserId($this->user2); - try { - \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user1, \OCP\Constants::PERMISSION_ALL); - $this->fail(); - } catch (\Exception $e) { - $this->assertEquals('Sharing failed, because the user ' . $this->user1 . ' is the original sharer', $e->getMessage()); - } - } -} - -class DummyShareClass extends \OC\Share\Share { - public static function groupItemsTest($items) { - return parent::groupItems($items, 'test'); - } } -class DummyHookListener { - public static $shareType = null; - - public static function listen($params) { - self::$shareType = $params['shareType']; - } -} diff --git a/tests/lib/TagsTest.php b/tests/lib/TagsTest.php index 9e50d52fb5f8..2f8d2086d70a 100644 --- a/tests/lib/TagsTest.php +++ b/tests/lib/TagsTest.php @@ -284,33 +284,4 @@ public function testFavorite() { $this->assertTrue($tagger->removeFromFavorites(1)); $this->assertEquals([], $tagger->getFavorites()); } - - public function testShareTags() { - $testTag = 'TestTag'; - - $tagger = $this->tagMgr->load('test'); - $tagger->tagAs(1, $testTag); - - $otherUserId = $this->getUniqueID('user2_'); - $otherUser = $this->createUser($otherUserId, 'pass'); - \OC_User::setUserId($otherUserId); - /** @var IUserSession | \PHPUnit_Framework_MockObject_MockObject $otherUserSession */ - $otherUserSession = $this->createMock(IUserSession::class); - $otherUserSession - ->expects($this->any()) - ->method('getUser') - ->will($this->returnValue($otherUser)); - - $otherTagMgr = new TagManager($this->tagMapper, $otherUserSession); - $otherTagger = $otherTagMgr->load('test'); - $this->assertFalse($otherTagger->hasTag($testTag)); - - \OC_User::setUserId($this->user->getUID()); - \OCP\Share::shareItem('test', 1, \OCP\Share::SHARE_TYPE_USER, $otherUserId, \OCP\Constants::PERMISSION_READ); - - \OC_User::setUserId($otherUserId); - $otherTagger = $otherTagMgr->load('test', [], true); // Update tags, load shared ones. - $this->assertTrue($otherTagger->hasTag($testTag)); - $this->assertContains(1, $otherTagger->getIdsForTag($testTag)); - } } From 152ef00240cd186e49e04938ddcc1c6c54415ae2 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 10 Oct 2018 18:40:47 +0200 Subject: [PATCH 20/21] Remove more obsolete legacy sharing code --- lib/private/Share/Share.php | 271 ---------------------------------- tests/lib/Share/ShareTest.php | 1 - 2 files changed, 272 deletions(-) diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 87159c7cae9e..06da6d48cc0c 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -432,10 +432,6 @@ protected static function unshareItem(array $item, $newParent = null) { $deletedShares[] = $hookParams; $hookParams['deletedShares'] = $deletedShares; \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams); - if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) { - list(, $remote) = Helper::splitUserRemote($item['share_with']); - self::sendRemoteUnshare($remote, $item['id'], $item['token']); - } } /** @@ -455,21 +451,6 @@ public static function isResharingAllowed() { return self::$isResharingAllowed; } - /** - * Get a list of collection item types for the specified item type - * @param string $itemType - * @return array - */ - private static function getCollectionItemTypes($itemType) { - $collectionTypes = [$itemType]; - // Return array if collections were found or the item type is a - // collection itself - collections can be inside collections - if (\count($collectionTypes) > 0) { - return $collectionTypes; - } - return false; - } - /** * In case a password protected link is not yet authenticated this function will return false * @@ -499,94 +480,6 @@ public static function checkPasswordProtectedShare(array $linkItem) { return false; } - /** - * construct select statement - * @param int $format - * @param string $uidOwner - * @return string select statement - */ - private static function createSelectStatement($format, $uidOwner = null) { - $select = '*'; - if ($format == self::FORMAT_STATUSES) { - $select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`'; - } else { - if (isset($uidOwner)) { - $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,' - . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`'; - } - } - return $select; - } - - /** - * transform db results - * @param array $row result - */ - private static function transformDBResults(&$row) { - if (isset($row['id'])) { - $row['id'] = (int) $row['id']; - } - if (isset($row['share_type'])) { - $row['share_type'] = (int) $row['share_type']; - } - if (isset($row['parent'])) { - $row['parent'] = (int) $row['parent']; - } - if (isset($row['file_parent'])) { - $row['file_parent'] = (int) $row['file_parent']; - } - if (isset($row['file_source'])) { - $row['file_source'] = (int) $row['file_source']; - } - if (isset($row['permissions'])) { - $row['permissions'] = (int) $row['permissions']; - } - if (isset($row['storage'])) { - $row['storage'] = (int) $row['storage']; - } - if (isset($row['stime'])) { - $row['stime'] = (int) $row['stime']; - } - if (isset($row['expiration']) && $row['share_type'] !== self::SHARE_TYPE_LINK) { - // discard expiration date for non-link shares, which might have been - // set by ancient bugs - $row['expiration'] = null; - } - } - - /** - * format result - * @param array $items result - * @param string $column is it a file share or a general share ('file_target' or 'item_target') - * @param \OCP\Share_Backend $backend sharing backend - * @param int $format - * @param array $parameters additional format parameters - * @return array format result - */ - private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE, $parameters = null) { - if ($format === self::FORMAT_NONE) { - return $items; - } elseif ($format === self::FORMAT_STATUSES) { - $statuses = []; - foreach ($items as $item) { - if ($item['share_type'] === self::SHARE_TYPE_LINK) { - if ($item['uid_initiator'] !== \OC::$server->getUserSession()->getUser()->getUID()) { - continue; - } - $statuses[$item[$column]]['link'] = true; - } elseif (!isset($statuses[$item[$column]])) { - $statuses[$item[$column]]['link'] = false; - } - if (!empty($item['file_target'])) { - $statuses[$item[$column]]['path'] = $item['path']; - } - } - return $statuses; - } else { - return null; - } - } - /** * remove protocol from URL * @@ -603,170 +496,6 @@ public static function removeProtocolFromUrl($url) { return $url; } - /** - * try http post first with https and then with http as a fallback - * - * @param string $remoteDomain - * @param string $urlSuffix - * @param array $fields post parameters - * @return array - */ - private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) { - $allowHttpFallback = \OC::$server->getConfig()->getSystemValue('sharing.federation.allowHttpFallback', false) === true; - // Always try https first - $protocol = 'https://'; - $discoveryManager = new DiscoveryManager( - \OC::$server->getMemCacheFactory(), - \OC::$server->getHTTPClientService() - ); - - $endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain); - // Try HTTPS - $result = \OC::$server->getHTTPHelper()->post( - $protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, - $fields); - - if ($result['success'] === true) { - // Return if https worked - return $result; - } elseif ($result['success'] === false && $allowHttpFallback) { - // If https failed and we can try http - try that - $protocol = 'http://'; - $result = \OC::$server->getHTTPHelper()->post( - $protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, - $fields); - return $result; - } else { - // Else we just return the failure - return $result; - } - } - - /** - * send server-to-server share to remote server - * - * @param string $token - * @param string $shareWith - * @param string $name - * @param int $remote_id - * @param string $owner - * @return bool - */ - private static function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) { - list($user, $remote) = Helper::splitUserRemote($shareWith); - - if ($user && $remote) { - $url = $remote; - - $local = \OC::$server->getURLGenerator()->getAbsoluteURL('/'); - - $fields = [ - 'shareWith' => $user, - 'token' => $token, - 'name' => $name, - 'remoteId' => $remote_id, - 'owner' => $owner, - 'remote' => $local, - ]; - - $url = self::removeProtocolFromUrl($url); - $result = self::tryHttpPostToShareEndpoint($url, '', $fields); - $status = \json_decode($result['result'], true); - - if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) { - \OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]); - return true; - } - } - - return false; - } - - /** - * send server-to-server unshare to remote server - * - * @param string $remote url - * @param int $id share id - * @param string $token - * @return bool - */ - private static function sendRemoteUnshare($remote, $id, $token) { - $url = \rtrim($remote, '/'); - $fields = ['token' => $token, 'format' => 'json']; - $url = self::removeProtocolFromUrl($url); - $result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields); - $status = \json_decode($result['result'], true); - - return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)); - } - - /** - * @param IConfig $config - * @return bool - */ - public static function enforcePassword(IConfig $config) { - $enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no'); - return ($enforcePassword === "yes") ? true : false; - } - - /** - * Get all share entries, including non-unique group items - * - * @param string $owner - * @return array - */ - public static function getAllSharesForOwner($owner) { - $query = 'SELECT * FROM `*PREFIX*share` WHERE `uid_owner` = ?'; - $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$owner]); - return $result->fetchAll(); - } - - /** - * Get all share entries, including non-unique group items for a file - * - * @param int $id - * @return array - */ - public static function getAllSharesForFileId($id) { - $query = 'SELECT * FROM `*PREFIX*share` WHERE `file_source` = ?'; - $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$id]); - return $result->fetchAll(); - } - - /** - * @param string $password - * @throws \Exception - */ - private static function verifyPassword($password) { - $accepted = true; - $message = ''; - \OCP\Util::emitHook('\OC\Share', 'verifyPassword', [ - 'password' => $password, - 'accepted' => &$accepted, - 'message' => &$message - ]); - - if (!$accepted) { - throw new \Exception($message); - } - - \OC::$server->getEventDispatcher()->dispatch( - 'OCP\Share::validatePassword', - new GenericEvent(null, ['password' => $password]) - ); - } - - /** - * @param $user - * @return Group[] - */ - private static function getGroupsForUser($user) { - $groups = \OC::$server->getGroupManager()->getUserIdGroups($user, 'sharing'); - return \array_values(\array_map(function (Group $g) { - return $g->getGID(); - }, $groups)); - } - /** * @param $group * @return mixed diff --git a/tests/lib/Share/ShareTest.php b/tests/lib/Share/ShareTest.php index 4b3d0ba422fd..ed382f1fdd07 100644 --- a/tests/lib/Share/ShareTest.php +++ b/tests/lib/Share/ShareTest.php @@ -193,4 +193,3 @@ public function urls() { ]; } } - From 6f33db43892b51b1caf0291847e47786893c2f85 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 18 Oct 2018 14:41:10 +0200 Subject: [PATCH 21/21] Share panel read setting from config directly Remove shareWithGroupMembersOnly helper and read from app config directly. --- settings/Panels/Helper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings/Panels/Helper.php b/settings/Panels/Helper.php index 76e12b3daa60..450146fb644a 100644 --- a/settings/Panels/Helper.php +++ b/settings/Panels/Helper.php @@ -35,7 +35,8 @@ public function getAdminForms() { } public function shareWithGroupMembersOnly() { - return \OC\Share\Share::shareWithGroupMembersOnly(); + $value = \OC::$server->getAppConfig()->getValue('core', 'shareapi_only_share_with_group_members', 'no'); + return ($value === 'yes') ? true : false; } public function findBinaryPath($path) {