From 2ef190a4fce0d0ab6173da1304ffaa35e95ede95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 19 Aug 2019 14:50:42 +0200 Subject: [PATCH] Classic share permissions can be set via share attributes now as well --- .../lib/Controller/Share20OcsController.php | 144 +++++++--- .../Controller/Share20OcsControllerTest.php | 268 ++++++++++++------ lib/public/Roles/AddRolesEvent.php | 1 - 3 files changed, 282 insertions(+), 131 deletions(-) diff --git a/apps/files_sharing/lib/Controller/Share20OcsController.php b/apps/files_sharing/lib/Controller/Share20OcsController.php index 4990c2cc31f7..3f743521aae8 100644 --- a/apps/files_sharing/lib/Controller/Share20OcsController.php +++ b/apps/files_sharing/lib/Controller/Share20OcsController.php @@ -21,9 +21,14 @@ namespace OCA\Files_Sharing\Controller; +use Exception; +use OC\Files\Filesystem; use OCP\Constants; use OC\OCS\Result; use OCP\AppFramework\OCSController; +use OCP\Defaults; +use OCP\Files\File; +use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\IConfig; @@ -134,6 +139,8 @@ private function getAdditionalUserInfo(IUser $user) { * @param bool $received whether it's formatting received shares * @return array * @throws NotFoundException In case the node can't be resolved. + * @throws \OCP\Files\InvalidPathException + * @throws \OCP\Files\StorageNotAvailableException */ protected function formatShare(IShare $share, $received = false) { $sharedBy = $this->userManager->get($share->getSharedBy()); @@ -176,7 +183,7 @@ protected function formatShare(IShare $share, $received = false) { $node = $nodes[0]; $result['path'] = $userFolder->getRelativePath($node->getPath()); - if ($node instanceof \OCP\Files\Folder) { + if ($node instanceof Folder) { $result['item_type'] = 'folder'; } else { $result['item_type'] = 'file'; @@ -274,6 +281,9 @@ public function getShare($id) { * * @param string $id * @return Result + * @throws LockedException + * @throws NotFoundException + * @throws ShareNotFound */ public function deleteShare($id) { if (!$this->shareManager->shareApiEnabled()) { @@ -309,6 +319,9 @@ public function deleteShare($id) { * @NoAdminRequired * * @return Result + * @throws LockedException + * @throws NotFoundException + * @throws \OCP\Files\InvalidPathException */ public function createShare() { $share = $this->shareManager->newShare(); @@ -344,7 +357,7 @@ public function createShare() { $shareType = (int)$this->request->getParam('shareType', '-1'); // Parse permissions (if available) - $permissions = $this->request->getParam('permissions', null); + $permissions = $this->getPermissionsFromRequest(); if ($permissions === null) { if ($shareType !== Share::SHARE_TYPE_LINK) { $permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL); @@ -423,7 +436,7 @@ public function createShare() { } // Public upload can only be set for folders - if ($path instanceof \OCP\Files\File) { + if ($path instanceof File) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 404, $this->l->t('Public upload is only possible for publicly shared folders')); } @@ -437,9 +450,9 @@ public function createShare() { Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE ); - } elseif ($permissions === \OCP\Constants::PERMISSION_CREATE || - $permissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) || - $permissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE)) { + } elseif ($permissions === Constants::PERMISSION_CREATE || + $permissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE) || + $permissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE)) { $share->setPermissions($permissions); } else { // because when "publicUpload" is passed usually no permissions are set, @@ -466,7 +479,7 @@ public function createShare() { try { $expireDate = $this->parseDate($expireDate); $share->setExpirationDate($expireDate); - } catch (\Exception $e) { + } catch (Exception $e) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 404, $this->l->t('Invalid date, date format must be YYYY-MM-DD')); } @@ -510,12 +523,12 @@ public function createShare() { $code = $e->getCode() === 0 ? 403 : $e->getCode(); $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, $code, $e->getHint()); - } catch (\Exception $e) { + } catch (Exception $e) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 403, $e->getMessage()); } - $share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); $formattedShareAfterCreate = $this->formatShare($share); @@ -523,7 +536,7 @@ public function createShare() { } /** - * @param \OCP\Files\File|\OCP\Files\Folder $node + * @param File|Folder $node * @param boolean $includeTags include tags in response * @param int|null $stateFilter state filter or empty for all, defaults to 0 (accepted) * @return Result @@ -569,11 +582,12 @@ private function getSharedWithMe($node = null, $includeTags, $stateFilter = 0) { } /** - * @param \OCP\Files\Folder $folder + * @param Folder $folder * @return Result + * @throws NotFoundException */ private function getSharesInDir($folder) { - if (!($folder instanceof \OCP\Files\Folder)) { + if (!($folder instanceof Folder)) { return new Result(null, 400, $this->l->t('Not a directory')); } @@ -614,6 +628,7 @@ private function getSharesInDir($folder) { * - Get all shares in a folder (?subfiles=true&path=..) * * @return Result + * @throws LockedException */ public function getShares() { if (!$this->shareManager->shareApiEnabled()) { @@ -632,7 +647,7 @@ public function getShares() { try { $path = $userFolder->get($path); $path->lock(ILockingProvider::LOCK_SHARED); - } catch (\OCP\Files\NotFoundException $e) { + } catch (NotFoundException $e) { return new Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist')); } catch (LockedException $e) { return new Result(null, 404, $this->l->t('Could not lock path')); @@ -706,6 +721,8 @@ public function getShares() { * * @param int $id * @return Result + * @throws LockedException + * @throws NotFoundException */ public function updateShare($id) { if (!$this->shareManager->shareApiEnabled()) { @@ -718,14 +735,14 @@ public function updateShare($id) { return new Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist')); } - $share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $share->getNode()->lock(ILockingProvider::LOCK_SHARED); if (!$this->canAccessShare($share)) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist')); } - $permissions = $this->request->getParam('permissions', null); + $permissions = $this->getPermissionsFromRequest(); $password = $this->request->getParam('password', null); $publicUpload = $this->request->getParam('publicUpload', null); $expireDate = $this->request->getParam('expireDate', null); @@ -775,7 +792,7 @@ public function updateShare($id) { return new Result(null, 403, $this->l->t('Public upload disabled by the administrator')); } - if (!($share->getNode() instanceof \OCP\Files\Folder)) { + if (!($share->getNode() instanceof Folder)) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders')); } @@ -790,7 +807,7 @@ public function updateShare($id) { return new Result(null, 403, $this->l->t('Public upload disabled by the administrator')); } - if (!($share->getNode() instanceof \OCP\Files\Folder)) { + if (!($share->getNode() instanceof Folder)) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders')); } @@ -810,7 +827,7 @@ public function updateShare($id) { } elseif ($expireDate !== null) { try { $expireDate = $this->parseDate($expireDate); - } catch (\Exception $e) { + } catch (Exception $e) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 400, $e->getMessage()); } @@ -841,12 +858,12 @@ public function updateShare($id) { $code = $e->getCode() === 0 ? 403 : $e->getCode(); $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, $code, $e->getHint()); - } catch (\Exception $e) { + } catch (Exception $e) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 400, $e->getMessage()); } - $share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result($this->formatShare($share)); } @@ -900,7 +917,7 @@ public function notifyRecipients($itemSource, $itemType, $shareType, $recipient) return $user->getUID() !== $this->userSession->getUser()->getUID(); }); - $defaults = new \OCP\Defaults(); + $defaults = new Defaults(); $mailNotification = new \OC\Share\MailNotifications( $this->shareManager, $this->userSession->getUser(), @@ -961,6 +978,8 @@ public function notifyRecipientsDisabled($itemSource, $itemType, $shareType, $re * @param $id * @param $state * @return Result + * @throws LockedException + * @throws NotFoundException */ private function updateShareState($id, $state) { $eventName = ''; @@ -982,7 +1001,7 @@ private function updateShareState($id, $state) { } $node = $share->getNode(); - $node->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $node->lock(ILockingProvider::LOCK_SHARED); // this checks that we are either the owner or recipient if (!$this->canAccessShare($share)) { @@ -1002,7 +1021,7 @@ private function updateShareState($id, $state) { $this->eventDispatcher->dispatch('share.after' . $eventName, new GenericEvent(null, ['share' => $share])); } // if there are no changes in the state, just return the share as if the change was successful - $node->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $node->unlock(ILockingProvider::LOCK_SHARED); return new Result([$this->formatShare($share, true)]); } @@ -1024,15 +1043,15 @@ private function updateShareState($id, $state) { $aShare->setTarget($share->getTarget()); $this->shareManager->updateShareForRecipient($aShare, $this->userSession->getUser()->getUID()); } - } catch (\Exception $e) { + } catch (Exception $e) { $share->getNode()->unlock(ILockingProvider::LOCK_SHARED); return new Result(null, 400, $e->getMessage()); } - $node->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED); + $node->unlock(ILockingProvider::LOCK_SHARED); // FIXME: needs public API! - \OC\Files\Filesystem::tearDown(); + Filesystem::tearDown(); // FIXME: trigger mount for user to make sure the new node is mounted already // before formatShare resolves it $this->rootFolder->getUserFolder($this->userSession->getUser()->getUID()); @@ -1057,18 +1076,18 @@ private function deduplicateShareTarget(IShare $share) { $parentDir = \dirname($share->getTarget()); if (!$userFolder->nodeExists($parentDir)) { $parentDir = Helper::getShareFolder(); - $pathAttempt = \OC\Files\Filesystem::normalizePath($parentDir . '/' . $share->getTarget()); + $pathAttempt = Filesystem::normalizePath($parentDir . '/' . $share->getTarget()); } else { - $pathAttempt = \OC\Files\Filesystem::normalizePath($share->getTarget()); + $pathAttempt = Filesystem::normalizePath($share->getTarget()); } $pathinfo = \pathinfo($pathAttempt); - $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; + $ext = isset($pathinfo['extension']) ? '.'.$pathinfo['extension'] : ''; $name = $pathinfo['filename']; $i = 2; while ($userFolder->nodeExists($pathAttempt)) { - $pathAttempt = \OC\Files\Filesystem::normalizePath($parentDir . '/' . $name . ' ('.$i.')' . $ext); + $pathAttempt = Filesystem::normalizePath($parentDir . '/' . $name . ' ('.$i.')' . $ext); $i++; } @@ -1119,18 +1138,18 @@ protected function canAccessShare(IShare $share) { * * @param string $expireDate * - * @throws \Exception + * @throws Exception * @return \DateTime */ private function parseDate($expireDate) { try { $date = new \DateTime($expireDate); - } catch (\Exception $e) { - throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); + } catch (Exception $e) { + throw new Exception('Invalid date. Format must be YYYY-MM-DD'); } if ($date === false) { - throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); + throw new Exception('Invalid date. Format must be YYYY-MM-DD'); } $date->setTime(0, 0, 0); @@ -1143,6 +1162,7 @@ private function parseDate($expireDate) { * not support this we need to check all backends. * * @param string $id + * @param null $recipient * @return IShare * @throws ShareNotFound */ @@ -1172,15 +1192,61 @@ private function setShareAttributes(IShare $share, $formattedShareAttributes) { $newShareAttributes = $this->shareManager->newShare()->newAttributes(); if ($formattedShareAttributes !== null) { foreach ($formattedShareAttributes as $formattedAttr) { - $newShareAttributes->setAttribute( - $formattedAttr['scope'], - $formattedAttr['key'], - (bool) \json_decode($formattedAttr['enabled']) - ); + $value = isset($formattedAttr['value']) ? $formattedAttr['value'] : null; + if (isset($formattedAttr['enabled'])) { + $value = (bool) \json_decode($formattedAttr['enabled']); + } + if ($value) { + $newShareAttributes->setAttribute( + $formattedAttr['scope'], + $formattedAttr['key'], + $value + ); + } } } $share->setAttributes($newShareAttributes); return $share; } + + /** + * @return mixed + */ + private function getPermissionsFromRequest() { + // int-based permissions are set -> use them + $permissions = $this->request->getParam('permissions', null); + if ($permissions !== null) { + return $permissions; + } + // have permissions been set via attributes? + $attributes = $this->request->getParam('attributes', null); + if ($attributes === null) { + return null; + } + $permission = 0; + foreach ($attributes as $attribute) { + if ($attribute['scope'] === 'ownCloud') { + $key = $attribute['key']; + $value = $attribute['value']; + if ($key === 'create' && $value === 'true') { + $permission |= Constants::PERMISSION_CREATE; + } + if ($key === 'read' && $value === 'true') { + $permission |= Constants::PERMISSION_READ; + } + if ($key === 'update' && $value === 'true') { + $permission |= Constants::PERMISSION_UPDATE; + } + if ($key === 'delete' && $value === 'true') { + $permission |= Constants::PERMISSION_DELETE; + } + if ($key === 'share' && $value === 'true') { + $permission |= Constants::PERMISSION_SHARE; + } + } + } + + return $permission; + } } diff --git a/apps/files_sharing/tests/Controller/Share20OcsControllerTest.php b/apps/files_sharing/tests/Controller/Share20OcsControllerTest.php index 0fe35dfcb73e..29b5fa9c4335 100644 --- a/apps/files_sharing/tests/Controller/Share20OcsControllerTest.php +++ b/apps/files_sharing/tests/Controller/Share20OcsControllerTest.php @@ -25,10 +25,11 @@ namespace OCA\Files_Sharing\Tests\API; use OC\OCS\Result; +use OC\Share\Constants; +use OC\Share20\Manager; use OCA\Files_Sharing\Controller\Share20OcsController; use OCA\Files_Sharing\Service\NotificationPublisher; use OCA\Files_Sharing\SharingBlacklist; -use OCP\Constants; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\IConfig; @@ -43,19 +44,18 @@ use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; use OCP\Share; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\GenericEvent; use Test\TestCase; use OCP\Files\Folder; use OCP\Files\Node; use OCP\Share\Exceptions\ShareNotFound; -use OCP\Share\IManager; -use OCP\Files\Cache\ICache; -use OCP\Files\File; -use OCA\Files_Sharing\External\Storage; use OCP\Share\IShare; use OCP\Share\IAttributes as IShareAttributes; -use OC\Files\Cache\Cache; +use OCP\Share\IManager; +use OCP\Files\File; +use OCP\Files\Storage; /** * Class Share20OcsControllerTest @@ -65,19 +65,19 @@ */ class Share20OcsControllerTest extends TestCase { - /** @var \OC\Share20\Manager | \PHPUnit\Framework\MockObject\MockObject */ + /** @var Manager | MockObject */ private $shareManager; - /** @var IGroupManager | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager | MockObject */ private $groupManager; - /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager | MockObject */ private $userManager; - /** @var IRequest | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IRequest | MockObject */ private $request; - /** @var IRootFolder | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IRootFolder | MockObject */ private $rootFolder; /** @var IURLGenerator */ @@ -105,7 +105,7 @@ class Share20OcsControllerTest extends TestCase { private $config; protected function setUp() { - $this->shareManager = $this->getMockBuilder('OCP\Share\IManager') + $this->shareManager = $this->getMockBuilder(IManager::class) ->disableOriginalConstructor() ->getMock(); $this->shareManager @@ -167,7 +167,7 @@ public function tearDown() { } /** - * @return Share20OcsController | \PHPUnit\Framework\MockObject\MockObject + * @return Share20OcsController | MockObject */ private function mockFormatShare() { return $this->getMockBuilder(Share20OcsController::class) @@ -241,7 +241,7 @@ public function testDeleteShareShareNotFound() { $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true); - $expected = new \OC\OCS\Result(null, 404, 'Wrong share ID, share doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong share ID, share doesn\'t exist'); $this->assertEquals($expected, $this->ocs->deleteShare(42)); } @@ -263,12 +263,12 @@ public function testDeleteShare() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $node->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $expected = new \OC\OCS\Result(); + $expected = new Result(); $this->assertEquals($expected, $this->ocs->deleteShare(42)); } @@ -290,13 +290,13 @@ public function testDeleteShareLocked() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED) + ->with(ILockingProvider::LOCK_SHARED) ->will($this->throwException(new LockedException('mypath'))); $node->expects($this->never()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $expected = new \OC\OCS\Result(null, 404, 'could not delete share'); + $expected = new Result(null, 404, 'could not delete share'); $this->assertEquals($expected, $this->ocs->deleteShare(42)); } @@ -597,7 +597,7 @@ public function testGetShare(\OCP\Share\IShare $share, array $result) { ['group', $group], ])); - $expected = new \OC\OCS\Result([$result]); + $expected = new Result([$result]); $this->assertEquals($expected->getData(), $ocs->getShare($share->getId())->getData()); } @@ -613,7 +613,7 @@ public function testGetShareInvalidNode() { ->with('ocinternal:42') ->willReturn($share); - $expected = new \OC\OCS\Result(null, 404, 'Wrong share ID, share doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong share ID, share doesn\'t exist'); $this->assertEquals($expected->getMeta(), $this->ocs->getShare(42)->getMeta()); } @@ -684,7 +684,7 @@ public function testCanAccessShare() { } public function testCreateShareNoPath() { - $expected = new \OC\OCS\Result(null, 404, 'Please specify a file or folder path'); + $expected = new Result(null, 404, 'Please specify a file or folder path'); $result = $this->ocs->createShare(); @@ -710,7 +710,7 @@ public function testCreateShareInvalidPath() { ->with('invalid-path') ->will($this->throwException(new \OCP\Files\NotFoundException())); - $expected = new \OC\OCS\Result(null, 404, 'Wrong path, file/folder doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong path, file/folder doesn\'t exist'); $result = $this->ocs->createShare(); @@ -749,9 +749,9 @@ public function testCreateShareUserNoShareWith() { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $expected = new \OC\OCS\Result(null, 404, 'Please specify a valid user'); + $expected = new Result(null, 404, 'Please specify a valid user'); $result = $this->ocs->createShare(); @@ -789,11 +789,11 @@ public function testCreateShareUserNoValidShareWith() { ->with('valid-path') ->willReturn($path); - $expected = new \OC\OCS\Result(null, 404, 'Please specify a valid user'); + $expected = new Result(null, 404, 'Please specify a valid user'); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $result = $this->ocs->createShare(); @@ -811,12 +811,12 @@ public function testCreateShareUser() { $this->request ->method('getParam') - ->will($this->returnValueMap([ + ->willReturnMap([ ['path', null, 'valid-path'], ['permissions', null, \OCP\Constants::PERMISSION_ALL], ['shareType', $this->any(), Share::SHARE_TYPE_USER], ['shareWith', null, 'validUser'], - ])); + ]); $userFolder = $this->createMock('\OCP\Files\Folder'); $this->rootFolder->expects($this->once()) @@ -839,10 +839,10 @@ public function testCreateShareUser() { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $path->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { @@ -856,7 +856,7 @@ public function testCreateShareUser() { })) ->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(); + $expected = new Result(); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -894,11 +894,11 @@ public function testCreateShareGroupNoValidShareWith() { ->with('valid-path') ->willReturn($path); - $expected = new \OC\OCS\Result(null, 404, 'Please specify a valid user'); + $expected = new Result(null, 404, 'Please specify a valid user'); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $result = $this->ocs->createShare(); @@ -946,7 +946,7 @@ public function testCreateShareGroupBlacklisted() { $this->sharingBlacklist->method('isGroupBlacklisted')->willReturn(true); - $expected = new \OC\OCS\Result(null, 403, 'The group is blacklisted for sharing'); + $expected = new Result(null, 403, 'The group is blacklisted for sharing'); $result = $this->ocs->createShare(); @@ -997,10 +997,10 @@ public function testCreateShareGroup() { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $path->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { @@ -1014,7 +1014,7 @@ public function testCreateShareGroup() { $this->sharingBlacklist->method('isGroupBlacklisted')->willReturn(false); - $expected = new \OC\OCS\Result(); + $expected = new Result(); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1057,7 +1057,7 @@ public function testCreateShareGroupNotAllowed() { ->method('allowGroupSharing') ->willReturn(false); - $expected = new \OC\OCS\Result(null, 404, 'Group sharing is disabled by the administrator'); + $expected = new Result(null, 404, 'Group sharing is disabled by the administrator'); $result = $this->ocs->createShare(); @@ -1084,7 +1084,7 @@ public function testCreateShareLinkNoLinksAllowed() { $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); - $expected = new \OC\OCS\Result(null, 404, 'Public link sharing is disabled by the administrator'); + $expected = new Result(null, 404, 'Public link sharing is disabled by the administrator'); $result = $this->ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1112,7 +1112,7 @@ public function testCreateShareLinkNoPublicUpload() { $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); $this->shareManager->method('shareApiAllowLinks')->willReturn(true); - $expected = new \OC\OCS\Result(null, 403, 'Public upload disabled by the administrator'); + $expected = new Result(null, 403, 'Public upload disabled by the administrator'); $result = $this->ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1141,7 +1141,7 @@ public function testCreateShareLinkPublicUploadFile() { $this->shareManager->method('shareApiAllowLinks')->willReturn(true); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); - $expected = new \OC\OCS\Result(null, 404, 'Public upload is only possible for publicly shared folders'); + $expected = new Result(null, 404, 'Public upload is only possible for publicly shared folders'); $result = $this->ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1185,7 +1185,7 @@ public function testCreateShareLinkPublicUploadFolder() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1229,7 +1229,7 @@ public function testCreateShareLinkReadWritePermissions() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1273,7 +1273,7 @@ public function testCreateShareLinkCreateOnlyFolder() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1306,7 +1306,7 @@ public function testCreateShareLinkCreateOnlyFolderPublicUploadDisabled() { $this->shareManager->method('shareApiAllowLinks')->willReturn(true); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false); - $expected = new \OC\OCS\Result(null, 403, 'Public upload disabled by the administrator'); + $expected = new Result(null, 403, 'Public upload disabled by the administrator'); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1349,7 +1349,7 @@ public function testCreateShareLinkDefaultPerms() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1393,7 +1393,7 @@ public function testCreateShareLinkPassword() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1440,7 +1440,7 @@ public function testCreateShareValidExpireDate() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1473,7 +1473,7 @@ public function testCreateShareInvalidExpireDate() { $this->shareManager->method('shareApiAllowLinks')->willReturn(true); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); - $expected = new \OC\OCS\Result(null, 404, 'Invalid date, date format must be YYYY-MM-DD'); + $expected = new Result(null, 404, 'Invalid date, date format must be YYYY-MM-DD'); $result = $ocs->createShare(); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1537,11 +1537,11 @@ public function testUpdateShareCantAccess() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); - $expected = new \OC\OCS\Result(null, 404, 'Wrong share ID, share doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong share ID, share doesn\'t exist'); $result = $this->ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1558,11 +1558,11 @@ public function testUpdateNoParametersLink() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); - $expected = new \OC\OCS\Result(null, 400, 'Wrong or no update parameter given'); + $expected = new Result(null, 400, 'Wrong or no update parameter given'); $result = $this->ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1579,11 +1579,11 @@ public function testUpdateNoParametersOther() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); - $expected = new \OC\OCS\Result(null, 400, 'Wrong or no update parameter given'); + $expected = new Result(null, 400, 'Wrong or no update parameter given'); $result = $this->ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1612,10 +1612,10 @@ public function testUpdateLinkShareClear() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $node->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->request ->method('getParam') @@ -1635,7 +1635,7 @@ public function testUpdateLinkShareClear() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1682,7 +1682,7 @@ public function testUpdateLinkShareSet() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1733,7 +1733,7 @@ public function testUpdateLinkShareEnablePublicUpload($params) { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1768,7 +1768,7 @@ public function testUpdateLinkShareInvalidDate() { $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); - $expected = new \OC\OCS\Result(null, 400, 'Invalid date. Format must be YYYY-MM-DD'); + $expected = new Result(null, 400, 'Invalid date. Format must be YYYY-MM-DD'); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1816,7 +1816,7 @@ public function testUpdateLinkSharePublicUploadNotAllowed($params) { $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false); - $expected = new \OC\OCS\Result(null, 403, 'Public upload disabled by the administrator'); + $expected = new Result(null, 403, 'Public upload disabled by the administrator'); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1845,7 +1845,7 @@ public function testUpdateLinkSharePublicUploadOnFile() { $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); - $expected = new \OC\OCS\Result(null, 400, 'Public upload is only possible for publicly shared folders'); + $expected = new Result(null, 400, 'Public upload is only possible for publicly shared folders'); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1870,10 +1870,10 @@ public function testUpdateLinkSharePasswordDoesNotChangeOther() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $node->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->request ->method('getParam') @@ -1891,7 +1891,7 @@ public function testUpdateLinkSharePasswordDoesNotChangeOther() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1919,10 +1919,10 @@ public function testUpdateLinkShareExpireDateDoesNotChangeOther() { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $node->expects($this->once()) ->method('unlock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); @@ -1937,7 +1937,7 @@ public function testUpdateLinkShareExpireDateDoesNotChangeOther() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -1984,7 +1984,7 @@ public function testUpdateLinkSharePublicUploadDoesNotChangeOther() { }) )->will($this->returnArgument(0)); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2032,7 +2032,7 @@ public function testUpdateLinkSharePermissions() { $this->shareManager->method('getSharedWith')->willReturn([]); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2074,7 +2074,7 @@ public function testUpdateLinkShareCreateOnly() { $this->shareManager->method('getSharedWith')->willReturn([]); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2106,7 +2106,7 @@ public function testUpdateLinkShareInvalidPermissions() { $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); - $expected = new \OC\OCS\Result(null, 400, 'Can\'t change permissions for public share links'); + $expected = new Result(null, 400, 'Can\'t change permissions for public share links'); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2141,7 +2141,7 @@ public function testUpdateOtherPermissions() { $this->shareManager->method('getSharedWith')->willReturn([]); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2178,7 +2178,7 @@ public function testUpdateLinkShareNameAlone() { $this->shareManager->method('getSharedWith')->willReturn([]); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2217,7 +2217,7 @@ public function testUpdateLinkShareKeepNameWhenNotSpecified() { $this->shareManager->method('getSharedWith')->willReturn([]); - $expected = new \OC\OCS\Result(null); + $expected = new Result(null); $result = $ocs->updateShare(42); $this->assertEquals($expected->getMeta(), $result->getMeta()); @@ -2643,7 +2643,7 @@ public function getOcsDisabledAPI() { public function testGetShareApiDisabled() { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(null, 404, 'Share API is disabled'); + $expected = new Result(null, 404, 'Share API is disabled'); $result = $ocs->getShare('my:id'); $this->assertEquals($expected, $result); @@ -2652,7 +2652,7 @@ public function testGetShareApiDisabled() { public function testDeleteShareApiDisabled() { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(null, 404, 'Share API is disabled'); + $expected = new Result(null, 404, 'Share API is disabled'); $result = $ocs->deleteShare('my:id'); $this->assertEquals($expected, $result); @@ -2661,7 +2661,7 @@ public function testDeleteShareApiDisabled() { public function testCreateShareApiDisabled() { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(null, 404, 'Share API is disabled'); + $expected = new Result(null, 404, 'Share API is disabled'); $result = $ocs->createShare(); $this->assertEquals($expected, $result); @@ -2670,7 +2670,7 @@ public function testCreateShareApiDisabled() { public function testGetSharesApiDisabled() { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(); + $expected = new Result(); $result = $ocs->getShares(); $this->assertEquals($expected, $result); @@ -2679,7 +2679,7 @@ public function testGetSharesApiDisabled() { public function testUpdateShareApiDisabled() { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(null, 404, 'Share API is disabled'); + $expected = new Result(null, 404, 'Share API is disabled'); $result = $ocs->updateShare('my:id'); $this->assertEquals($expected, $result); @@ -3263,7 +3263,7 @@ public function testAcceptRejectShareMultiple($method, $target, $targetExists, $ public function testAcceptRejectShareApiDisabled($method, $target, $targetExists, $expectedState) { $ocs = $this->getOcsDisabledAPI(); - $expected = new \OC\OCS\Result(null, 404, 'Share API is disabled'); + $expected = new Result(null, 404, 'Share API is disabled'); $result = $ocs->$method(123); $this->assertEquals($expected, $result); @@ -3301,7 +3301,7 @@ public function testAcceptRejectShareInvalidId($method, $target, $targetExists, $this->shareManager->expects($this->never()) ->method('updateShareForRecipient'); - $expected = new \OC\OCS\Result(null, 404, 'Wrong share ID, share doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong share ID, share doesn\'t exist'); $result = $this->ocs->$method(123); $this->assertEquals($expected, $result); @@ -3322,7 +3322,7 @@ public function testAcceptRejectShareAccessDenied($method, $target, $targetExist $this->shareManager->expects($this->never()) ->method('updateShareForRecipient'); - $expected = new \OC\OCS\Result(null, 404, 'Wrong share ID, share doesn\'t exist'); + $expected = new Result(null, 404, 'Wrong share ID, share doesn\'t exist'); $result = $this->ocs->$method(123); $this->assertEquals($expected, $result); @@ -3344,7 +3344,7 @@ public function testAcceptRejectShareAccessNotRecipient($method, $target, $targe $userShare->setShareOwner('currentUser'); - $expected = new \OC\OCS\Result(null, 403, 'Only recipient can change accepted state'); + $expected = new Result(null, 403, 'Only recipient can change accepted state'); $result = $this->ocs->$method(123); $this->assertEquals($expected, $result); @@ -3374,12 +3374,12 @@ public function testAcceptRejectShareOperationError($method, $target, $targetExi $this->shareManager->expects($this->exactly(2)) ->method('getSharedWith') - ->will($this->returnValueMap([ + ->willReturnMap([ ['currentUser', Share::SHARE_TYPE_USER, $userShare->getNode(), -1, 0, [$userShare]], ['currentUser', Share::SHARE_TYPE_GROUP, $userShare->getNode(), -1, 0, []] - ])); + ]); - $userFolder = $this->createMock('OCP\Files\Folder'); + $userFolder = $this->createMock(Folder::class); if ($method === 'acceptShare') { $userFolder->expects($this->at(0)) ->method('nodeExists') @@ -3399,9 +3399,95 @@ public function testAcceptRejectShareOperationError($method, $target, $targetExi ->with($this->currentUser->getUID()) ->willReturn($userFolder); - $expected = new \OC\OCS\Result(null, 400, 'operation error'); + $expected = new Result(null, 400, 'operation error'); $result = $this->ocs->$method(123); $this->assertEquals($expected, $result); } + + /** + * @dataProvider providesShareAttributes + */ + public function testPermissionsViaAttributes($expectedPermission, $attributes) { + $share = $this->newShare(); + $this->shareManager->method('newShare')->willReturn($share); + + $share->setShareOwner('shareOwner'); + + $ocs = $this->mockFormatShare(); + $ocs->expects(self::once())->method('formatShare')->willReturnCallback(static function (IShare $share) { + return [ + 'permissions' => $share->getPermissions(), + 'attributes' => $share->getAttributes() + ]; + }); + + $this->request + ->method('getParam') + ->willReturnMap([ + ['path', null, 'valid-path'], + ['permissions', null, null], + ['attributes', null, $attributes], + ['shareType', $this->any(), Share::SHARE_TYPE_USER], + ['shareWith', null, 'validUser'], + ]); + + $userFolder = $this->createMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->createMock('\OCP\Files\File'); + $storage = $this->createMock('OCP\Files\Storage'); + $storage->method('instanceOfStorage') + ->with('OCA\Files_Sharing\External\Storage') + ->willReturn(false); + $path->method('getStorage')->willReturn($storage); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $this->userManager->method('userExists')->with('validUser')->willReturn(true); + + $path->expects($this->once()) + ->method('lock') + ->with(ILockingProvider::LOCK_SHARED); + $path->expects($this->once()) + ->method('unlock') + ->with(ILockingProvider::LOCK_SHARED); + + $this->shareManager->method('createShare')->will($this->returnArgument(0)); + + $result = $ocs->createShare(); + + $this->assertEquals($expectedPermission, $result->getData()['permissions']); + } + + public function providesShareAttributes() { + return [ + [ + \OCP\Constants::PERMISSION_READ, [ + ['scope' => 'ownCloud', 'key' => 'read', 'value' => 'true'] + ] + ], + [ + \OCP\Constants::PERMISSION_ALL, [ + ['scope' => 'ownCloud', 'key' => 'create', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'read', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'update', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'delete', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'share', 'value' => 'true'], + ] + ], + [ + \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE , [ + ['scope' => 'ownCloud', 'key' => 'create', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'read', 'value' => 'true'], + ['scope' => 'ownCloud', 'key' => 'share', 'value' => 'true'], + ] + ], + ]; + } } diff --git a/lib/public/Roles/AddRolesEvent.php b/lib/public/Roles/AddRolesEvent.php index fc875ba8034b..9622a243cf25 100644 --- a/lib/public/Roles/AddRolesEvent.php +++ b/lib/public/Roles/AddRolesEvent.php @@ -50,4 +50,3 @@ public function getRoles() { return \array_values($this->roles); } } -