Browse Source

Add locking to modifying operation of the OCS Share API

Fixes #17243

This is done in the OCS Share API instead of the share manager since we
want lazy shares in general. However when doing modifying calls via the
OCS Share API it is fine to force real nodes.

* Updated unit tests to work with logging
tags/v9.1.0beta1
Roeland Jago Douma 8 years ago
parent
commit
62bc53143e
No account linked to committer's email address
2 changed files with 175 additions and 39 deletions
  1. 19
    2
      apps/files_sharing/api/share20ocs.php
  2. 156
    37
      apps/files_sharing/tests/api/share20ocstest.php

+ 19
- 2
apps/files_sharing/api/share20ocs.php View File

@@ -28,6 +28,7 @@ use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Files\IRootFolder;
use OCP\Lock\LockedException;
use OCP\Share;
use OCP\Share\IManager;

@@ -205,12 +206,20 @@ class Share20OCS {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
}

try {
$share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
} catch (LockedException $e) {
return new \OC_OCS_Result(null, 404, 'could not delete share');
}

if (!$this->canAccessShare($share)) {
return new \OC_OCS_Result(null, 404, $this->l->t('Could not delete share'));
}

$this->shareManager->deleteShare($share);

$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);

return new \OC_OCS_Result();
}

@@ -238,6 +247,7 @@ class Share20OCS {
}

$share->setNode($path);
$share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED);

// Parse permissions (if available)
$permissions = $this->request->getParam('permissions', null);
@@ -368,8 +378,11 @@ class Share20OCS {
return new \OC_OCS_Result(null, 403, $e->getMessage());
}

$share = $this->formatShare($share);
return new \OC_OCS_Result($share);
$output = $this->formatShare($share);

$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);

return new \OC_OCS_Result($output);
}

/**
@@ -512,6 +525,8 @@ class Share20OCS {
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)) {
return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
}
@@ -611,6 +626,8 @@ class Share20OCS {
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));
}


+ 156
- 37
apps/files_sharing/tests/api/share20ocstest.php View File

@@ -29,6 +29,7 @@ use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Files\IRootFolder;
use OCP\Lock\LockedException;

/**
* Class Share20OCSTest
@@ -137,8 +138,11 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testDeleteShare() {
$node = $this->getMock('\OCP\Files\File');

$share = $this->newShare();
$share->setSharedBy($this->currentUser->getUID());
$share->setSharedBy($this->currentUser->getUID())
->setNode($node);
$this->shareManager
->expects($this->once())
->method('getShareById')
@@ -149,10 +153,45 @@ class Share20OCSTest extends \Test\TestCase {
->method('deleteShare')
->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();
$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

@@ -526,7 +565,7 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareInvalidPermissions() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);

$this->request
@@ -548,6 +587,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-path')
->willReturn($path);

$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);

$expected = new \OC_OCS_Result(null, 404, 'invalid permissions');

$result = $this->ocs->createShare();
@@ -557,7 +600,7 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareUserNoShareWith() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);

$this->request
@@ -585,6 +628,10 @@ class Share20OCSTest extends \Test\TestCase {
->with('valid-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');

$result = $this->ocs->createShare();
@@ -594,7 +641,7 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareUserNoValidShareWith() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);

$this->request
@@ -625,6 +672,10 @@ class Share20OCSTest extends \Test\TestCase {

$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();

$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -632,9 +683,8 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareUser() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0));

$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([
@@ -677,15 +727,26 @@ class Share20OCSTest extends \Test\TestCase {

$this->userManager->method('userExists')->with('validUser')->willReturn(true);

$share->method('setNode')->with($path);
$share->method('setPermissions')
->with(
\OCP\Constants::PERMISSION_ALL &
~\OCP\Constants::PERMISSION_DELETE &
~\OCP\Constants::PERMISSION_CREATE);
$share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_USER);
$share->method('setSharedWith')->with('validUser');
$share->method('setSharedBy')->with('currentUser');
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$path->expects($this->once())
->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 &
~\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();
$result = $ocs->createShare();
@@ -695,7 +756,7 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareGroupNoValidShareWith() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$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');

$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);

$result = $this->ocs->createShare();

$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -734,9 +799,8 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareGroup() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);
$this->shareManager->method('createShare')->will($this->returnArgument(0));

$ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
->setConstructorArgs([
@@ -783,11 +847,22 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing')
->willReturn(true);

$share->method('setNode')->with($path);
$share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL);
$share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP);
$share->method('setSharedWith')->with('validGroup');
$share->method('setSharedBy')->with('currentUser');
$path->expects($this->once())
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$path->expects($this->once())
->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();
$result = $ocs->createShare();
@@ -797,7 +872,7 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testCreateShareGroupNotAllowed() {
$share = $this->getMock('\OCP\Share\IShare');
$share = $this->newShare();
$this->shareManager->method('newShare')->willReturn($share);

$this->request
@@ -832,9 +907,8 @@ class Share20OCSTest extends \Test\TestCase {
->method('allowGroupSharing')
->willReturn(false);

$share->method('setNode')->with($path);

$expected = new \OC_OCS_Result(null, 404, 'Group sharing is disabled by the administrator');

$result = $this->ocs->createShare();

$this->assertEquals($expected->getMeta(), $result->getMeta());
@@ -1154,7 +1228,13 @@ class Share20OCSTest extends \Test\TestCase {
}

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);

@@ -1166,10 +1246,16 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testUpdateNoParametersLink() {
$share = \OC::$server->getShareManager()->newShare();
$node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->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);

@@ -1181,10 +1267,16 @@ class Share20OCSTest extends \Test\TestCase {
}

public function testUpdateNoParametersOther() {
$share = \OC::$server->getShareManager()->newShare();
$node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->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);

@@ -1198,13 +1290,22 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareClear() {
$ocs = $this->mockFormatShare();

$share = \OC::$server->getShareManager()->newShare();
$node = $this->getMock('\OCP\Files\Folder');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->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
->method('getParam')
@@ -1364,13 +1465,22 @@ class Share20OCSTest extends \Test\TestCase {
$date = new \DateTime('2000-01-01');
$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)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->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
->method('getParam')
@@ -1398,13 +1508,15 @@ class Share20OCSTest extends \Test\TestCase {
public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
$ocs = $this->mockFormatShare();

$share = \OC::$server->getShareManager()->newShare();
$node = $this->getMock('\OCP\Files\File');
$share = $this->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->setExpirationDate(new \DateTime())
->setPermissions(\OCP\Constants::PERMISSION_ALL);
->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setNode($node);

$this->request
->method('getParam')
@@ -1412,6 +1524,13 @@ class Share20OCSTest extends \Test\TestCase {
['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->expects($this->once())->method('updateShare')->with(

Loading…
Cancel
Save