Merge pull request #22989 from owncloud/lock_sharing_ops

Add locking to modifying operation of the OCS Share API
This commit is contained in:
Morris Jobke 2016-05-03 10:15:54 +02:00
commit 547830d97e
2 changed files with 222 additions and 43 deletions

View File

@ -28,11 +28,12 @@ use OCP\IRequest;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUser; use OCP\IUser;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Lock\LockedException;
use OCP\Share; use OCP\Share;
use OCP\Share\IManager; use OCP\Share\IManager;
use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\GenericShareException;
use OCP\Lock\ILockingProvider;
/** /**
* Class Share20OCS * Class Share20OCS
@ -205,12 +206,21 @@ class Share20OCS {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist')); return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
} }
try {
$share->getNode()->lock(ILockingProvider::LOCK_SHARED);
} catch (LockedException $e) {
return new \OC_OCS_Result(null, 404, 'could not delete share');
}
if (!$this->canAccessShare($share)) { if (!$this->canAccessShare($share)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Could not delete share')); return new \OC_OCS_Result(null, 404, $this->l->t('Could not delete share'));
} }
$this->shareManager->deleteShare($share); $this->shareManager->deleteShare($share);
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(); return new \OC_OCS_Result();
} }
@ -233,12 +243,18 @@ class Share20OCS {
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID()); $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
try { try {
$path = $userFolder->get($path); $path = $userFolder->get($path);
} catch (\OCP\Files\NotFoundException $e) { } catch (NotFoundException $e) {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist')); return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
} }
$share->setNode($path); $share->setNode($path);
try {
$share->getNode()->lock(ILockingProvider::LOCK_SHARED);
} catch (LockedException $e) {
return new \OC_OCS_Result(null, 404, 'Could not create share');
}
// Parse permissions (if available) // Parse permissions (if available)
$permissions = $this->request->getParam('permissions', null); $permissions = $this->request->getParam('permissions', null);
if ($permissions === null) { if ($permissions === null) {
@ -248,6 +264,7 @@ class Share20OCS {
} }
if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) { if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, 'invalid permissions'); return new \OC_OCS_Result(null, 404, 'invalid permissions');
} }
@ -275,17 +292,20 @@ class Share20OCS {
if ($shareType === \OCP\Share::SHARE_TYPE_USER) { if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
// Valid user is required to share // Valid user is required to share
if ($shareWith === null || !$this->userManager->userExists($shareWith)) { if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid user')); return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid user'));
} }
$share->setSharedWith($shareWith); $share->setSharedWith($shareWith);
$share->setPermissions($permissions); $share->setPermissions($permissions);
} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
if (!$this->shareManager->allowGroupSharing()) { if (!$this->shareManager->allowGroupSharing()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Group sharing is disabled by the administrator')); return new \OC_OCS_Result(null, 404, $this->l->t('Group sharing is disabled by the administrator'));
} }
// Valid group is required to share // Valid group is required to share
if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) { if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid group')); return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid group'));
} }
$share->setSharedWith($shareWith); $share->setSharedWith($shareWith);
@ -293,6 +313,7 @@ class Share20OCS {
} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) { } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
//Can we even share links? //Can we even share links?
if (!$this->shareManager->shareApiAllowLinks()) { if (!$this->shareManager->shareApiAllowLinks()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Public link sharing is disabled by the administrator')); return new \OC_OCS_Result(null, 404, $this->l->t('Public link sharing is disabled by the administrator'));
} }
@ -302,6 +323,7 @@ class Share20OCS {
*/ */
$existingShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0); $existingShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
if (!empty($existingShares)) { if (!empty($existingShares)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result($this->formatShare($existingShares[0])); return new \OC_OCS_Result($this->formatShare($existingShares[0]));
} }
@ -309,11 +331,13 @@ class Share20OCS {
if ($publicUpload === 'true') { if ($publicUpload === 'true') {
// Check if public upload is allowed // Check if public upload is allowed
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) { if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator')); return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
} }
// Public upload can only be set for folders // Public upload can only be set for folders
if ($path instanceof \OCP\Files\File) { if ($path instanceof \OCP\Files\File) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Public upload is only possible for publicly shared folders')); return new \OC_OCS_Result(null, 404, $this->l->t('Public upload is only possible for publicly shared folders'));
} }
@ -341,18 +365,21 @@ class Share20OCS {
$expireDate = $this->parseDate($expireDate); $expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate); $share->setExpirationDate($expireDate);
} catch (\Exception $e) { } catch (\Exception $e) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Invalid date, date format must be YYYY-MM-DD')); return new \OC_OCS_Result(null, 404, $this->l->t('Invalid date, date format must be YYYY-MM-DD'));
} }
} }
} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) { if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType])); return new \OC_OCS_Result(null, 403, $this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
} }
$share->setSharedWith($shareWith); $share->setSharedWith($shareWith);
$share->setPermissions($permissions); $share->setPermissions($permissions);
} else { } else {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Unknown share type')); return new \OC_OCS_Result(null, 400, $this->l->t('Unknown share type'));
} }
@ -363,13 +390,18 @@ class Share20OCS {
$share = $this->shareManager->createShare($share); $share = $this->shareManager->createShare($share);
} catch (GenericShareException $e) { } catch (GenericShareException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode(); $code = $e->getCode() === 0 ? 403 : $e->getCode();
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, $code, $e->getHint()); return new \OC_OCS_Result(null, $code, $e->getHint());
}catch (\Exception $e) { }catch (\Exception $e) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $e->getMessage()); return new \OC_OCS_Result(null, 403, $e->getMessage());
} }
$share = $this->formatShare($share); $output = $this->formatShare($share);
return new \OC_OCS_Result($share);
$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result($output);
} }
/** /**
@ -454,17 +486,28 @@ class Share20OCS {
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID()); $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
try { try {
$path = $userFolder->get($path); $path = $userFolder->get($path);
$path->lock(ILockingProvider::LOCK_SHARED);
} catch (\OCP\Files\NotFoundException $e) { } catch (\OCP\Files\NotFoundException $e) {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist')); return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
} catch (LockedException $e) {
return new \OC_OCS_Result(null, 404, $this->l->t('Could not lock path'));
} }
} }
if ($sharedWithMe === 'true') { if ($sharedWithMe === 'true') {
return $this->getSharedWithMe($path); $result = $this->getSharedWithMe($path);
if ($path !== null) {
$path->unlock(ILockingProvider::LOCK_SHARED);
}
return $result;
} }
if ($subfiles === 'true') { if ($subfiles === 'true') {
return $this->getSharesInDir($path); $result = $this->getSharesInDir($path);
if ($path !== null) {
$path->unlock(ILockingProvider::LOCK_SHARED);
}
return $result;
} }
if ($reshares === 'true') { if ($reshares === 'true') {
@ -494,6 +537,10 @@ class Share20OCS {
} }
} }
if ($path !== null) {
$path->unlock(ILockingProvider::LOCK_SHARED);
}
return new \OC_OCS_Result($formatted); return new \OC_OCS_Result($formatted);
} }
@ -512,7 +559,10 @@ class Share20OCS {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist')); return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
} }
$share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
if (!$this->canAccessShare($share)) { if (!$this->canAccessShare($share)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist')); return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
} }
@ -526,6 +576,7 @@ class Share20OCS {
*/ */
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) { if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given');
} }
@ -543,15 +594,18 @@ class Share20OCS {
if ($newPermissions !== null && if ($newPermissions !== null &&
$newPermissions !== \OCP\Constants::PERMISSION_READ && $newPermissions !== \OCP\Constants::PERMISSION_READ &&
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) { $newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links')); return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links'));
} }
if ($newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) { if ($newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) { if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator')); return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
} }
if (!($share->getNode() instanceof \OCP\Files\Folder)) { if (!($share->getNode() instanceof \OCP\Files\Folder)) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders')); return new \OC_OCS_Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders'));
} }
} }
@ -566,6 +620,7 @@ class Share20OCS {
try { try {
$expireDate = $this->parseDate($expireDate); $expireDate = $this->parseDate($expireDate);
} catch (\Exception $e) { } catch (\Exception $e) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $e->getMessage()); return new \OC_OCS_Result(null, 400, $e->getMessage());
} }
$share->setExpirationDate($expireDate); $share->setExpirationDate($expireDate);
@ -580,6 +635,7 @@ class Share20OCS {
} else { } else {
// For other shares only permissions is valid. // For other shares only permissions is valid.
if ($permissions === null) { if ($permissions === null) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Wrong or no update parameter given')); return new \OC_OCS_Result(null, 400, $this->l->t('Wrong or no update parameter given'));
} else { } else {
$permissions = (int)$permissions; $permissions = (int)$permissions;
@ -599,6 +655,7 @@ class Share20OCS {
} }
if ($share->getPermissions() & ~$maxPermissions) { if ($share->getPermissions() & ~$maxPermissions) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 404, $this->l->t('Cannot increase permissions')); return new \OC_OCS_Result(null, 404, $this->l->t('Cannot increase permissions'));
} }
} }
@ -608,9 +665,12 @@ class Share20OCS {
try { try {
$share = $this->shareManager->updateShare($share); $share = $this->shareManager->updateShare($share);
} catch (\Exception $e) { } catch (\Exception $e) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $e->getMessage()); return new \OC_OCS_Result(null, 400, $e->getMessage());
} }
$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result($this->formatShare($share)); return new \OC_OCS_Result($this->formatShare($share));
} }

View File

@ -29,6 +29,7 @@ use OCP\IRequest;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUser; use OCP\IUser;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Lock\LockedException;
/** /**
* Class Share20OCSTest * Class Share20OCSTest
@ -137,8 +138,11 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testDeleteShare() { public function testDeleteShare() {
$node = $this->getMock('\OCP\Files\File');
$share = $this->newShare(); $share = $this->newShare();
$share->setSharedBy($this->currentUser->getUID()); $share->setSharedBy($this->currentUser->getUID())
->setNode($node);
$this->shareManager $this->shareManager
->expects($this->once()) ->expects($this->once())
->method('getShareById') ->method('getShareById')
@ -149,10 +153,45 @@ class Share20OCSTest extends \Test\TestCase {
->method('deleteShare') ->method('deleteShare')
->with($share); ->with($share);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$node->expects($this->once())
->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$expected = new \OC_OCS_Result(); $expected = new \OC_OCS_Result();
$this->assertEquals($expected, $this->ocs->deleteShare(42)); $this->assertEquals($expected, $this->ocs->deleteShare(42));
} }
public function testDeleteShareLocked() {
$node = $this->getMock('\OCP\Files\File');
$share = $this->newShare();
$share->setSharedBy($this->currentUser->getUID())
->setNode($node);
$this->shareManager
->expects($this->once())
->method('getShareById')
->with('ocinternal:42')
->willReturn($share);
$this->shareManager
->expects($this->never())
->method('deleteShare')
->with($share);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED)
->will($this->throwException(new LockedException('mypath')));
$node->expects($this->never())
->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$expected = new \OC_OCS_Result(null, 404, 'could not delete share');
$this->assertEquals($expected, $this->ocs->deleteShare(42));
}
/* /*
* FIXME: Enable once we have a federated Share Provider * FIXME: Enable once we have a federated Share Provider
@ -526,7 +565,7 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareInvalidPermissions() { public function testCreateShareInvalidPermissions() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->request $this->request
@ -548,6 +587,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-path') ->with('valid-path')
->willReturn($path); ->willReturn($path);
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$expected = new \OC_OCS_Result(null, 404, 'invalid permissions'); $expected = new \OC_OCS_Result(null, 404, 'invalid permissions');
$result = $this->ocs->createShare(); $result = $this->ocs->createShare();
@ -557,7 +600,7 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareUserNoShareWith() { public function testCreateShareUserNoShareWith() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->request $this->request
@ -585,6 +628,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-path') ->with('valid-path')
->willReturn($path); ->willReturn($path);
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user'); $expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
$result = $this->ocs->createShare(); $result = $this->ocs->createShare();
@ -594,7 +641,7 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareUserNoValidShareWith() { public function testCreateShareUserNoValidShareWith() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->request $this->request
@ -625,6 +672,10 @@ class Share20OCSTest extends \Test\TestCase {
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user'); $expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$result = $this->ocs->createShare(); $result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta()); $this->assertEquals($expected->getMeta(), $result->getMeta());
@ -632,9 +683,8 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareUser() { public function testCreateShareUser() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0));
$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([ ->setConstructorArgs([
@ -677,15 +727,26 @@ class Share20OCSTest extends \Test\TestCase {
$this->userManager->method('userExists')->with('validUser')->willReturn(true); $this->userManager->method('userExists')->with('validUser')->willReturn(true);
$share->method('setNode')->with($path); $path->expects($this->once())
$share->method('setPermissions') ->method('lock')
->with( ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
\OCP\Constants::PERMISSION_ALL & $path->expects($this->once())
~\OCP\Constants::PERMISSION_DELETE & ->method('unlock')
~\OCP\Constants::PERMISSION_CREATE); ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_USER);
$share->method('setSharedWith')->with('validUser'); $this->shareManager->method('createShare')
$share->method('setSharedBy')->with('currentUser'); ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
return $share->getNode() === $path &&
$share->getPermissions() === (
\OCP\Constants::PERMISSION_ALL &
~\OCP\Constants::PERMISSION_DELETE &
~\OCP\Constants::PERMISSION_CREATE
) &&
$share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
$share->getSharedWith() === 'validUser' &&
$share->getSharedBy() === 'currentUser';
}))
->will($this->returnArgument(0));
$expected = new \OC_OCS_Result(); $expected = new \OC_OCS_Result();
$result = $ocs->createShare(); $result = $ocs->createShare();
@ -695,7 +756,7 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareGroupNoValidShareWith() { public function testCreateShareGroupNoValidShareWith() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0)); $this->shareManager->method('createShare')->will($this->returnArgument(0));
@ -727,6 +788,10 @@ class Share20OCSTest extends \Test\TestCase {
$expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user'); $expected = new \OC_OCS_Result(null, 404, 'Please specify a valid user');
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$result = $this->ocs->createShare(); $result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta()); $this->assertEquals($expected->getMeta(), $result->getMeta());
@ -734,9 +799,8 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareGroup() { public function testCreateShareGroup() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0));
$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([ ->setConstructorArgs([
@ -783,11 +847,22 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing') ->method('allowGroupSharing')
->willReturn(true); ->willReturn(true);
$share->method('setNode')->with($path); $path->expects($this->once())
$share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL); ->method('lock')
$share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP); ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$share->method('setSharedWith')->with('validGroup'); $path->expects($this->once())
$share->method('setSharedBy')->with('currentUser'); ->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('createShare')
->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
return $share->getNode() === $path &&
$share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
$share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
$share->getSharedWith() === 'validGroup' &&
$share->getSharedBy() === 'currentUser';
}))
->will($this->returnArgument(0));
$expected = new \OC_OCS_Result(); $expected = new \OC_OCS_Result();
$result = $ocs->createShare(); $result = $ocs->createShare();
@ -797,7 +872,7 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testCreateShareGroupNotAllowed() { public function testCreateShareGroupNotAllowed() {
$share = $this->getMock('\OCP\Share\IShare'); $share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share); $this->shareManager->method('newShare')->willReturn($share);
$this->request $this->request
@ -832,9 +907,8 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing') ->method('allowGroupSharing')
->willReturn(false); ->willReturn(false);
$share->method('setNode')->with($path);
$expected = new \OC_OCS_Result(null, 404, 'Group sharing is disabled by the administrator'); $expected = new \OC_OCS_Result(null, 404, 'Group sharing is disabled by the administrator');
$result = $this->ocs->createShare(); $result = $this->ocs->createShare();
$this->assertEquals($expected->getMeta(), $result->getMeta()); $this->assertEquals($expected->getMeta(), $result->getMeta());
@ -1154,7 +1228,13 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testUpdateShareCantAccess() { public function testUpdateShareCantAccess() {
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setNode($node);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@ -1166,10 +1246,16 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testUpdateNoParametersLink() { public function testUpdateNoParametersLink() {
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL) $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID()) ->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK); ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setNode($node);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@ -1181,10 +1267,16 @@ class Share20OCSTest extends \Test\TestCase {
} }
public function testUpdateNoParametersOther() { public function testUpdateNoParametersOther() {
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL) $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID()) ->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_GROUP); ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
->setNode($node);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
@ -1198,13 +1290,22 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareClear() { public function testUpdateLinkShareClear() {
$ocs = $this->mockFormatShare(); $ocs = $this->mockFormatShare();
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL) $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID()) ->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK) ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password') ->setPassword('password')
->setExpirationDate(new \DateTime()) ->setExpirationDate(new \DateTime())
->setPermissions(\OCP\Constants::PERMISSION_ALL); ->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setNode($node);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$node->expects($this->once())
->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->request $this->request
->method('getParam') ->method('getParam')
@ -1364,13 +1465,22 @@ class Share20OCSTest extends \Test\TestCase {
$date = new \DateTime('2000-01-01'); $date = new \DateTime('2000-01-01');
$date->setTime(0,0,0); $date->setTime(0,0,0);
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\File');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL) $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID()) ->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK) ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password') ->setPassword('password')
->setExpirationDate($date) ->setExpirationDate($date)
->setPermissions(\OCP\Constants::PERMISSION_ALL); ->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setNode($node);
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$node->expects($this->once())
->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->request $this->request
->method('getParam') ->method('getParam')
@ -1398,13 +1508,15 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareExpireDateDoesNotChangeOther() { public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
$ocs = $this->mockFormatShare(); $ocs = $this->mockFormatShare();
$share = \OC::$server->getShareManager()->newShare(); $node = $this->getMock('\OCP\Files\File');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL) $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID()) ->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK) ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password') ->setPassword('password')
->setExpirationDate(new \DateTime()) ->setExpirationDate(new \DateTime())
->setPermissions(\OCP\Constants::PERMISSION_ALL); ->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setNode($node);
$this->request $this->request
->method('getParam') ->method('getParam')
@ -1412,6 +1524,13 @@ class Share20OCSTest extends \Test\TestCase {
['expireDate', null, '2010-12-23'], ['expireDate', null, '2010-12-23'],
])); ]));
$node->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$node->expects($this->once())
->method('unlock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$this->shareManager->expects($this->once())->method('updateShare')->with( $this->shareManager->expects($this->once())->method('updateShare')->with(