Merge pull request #21841 from owncloud/share2_deletefromself
[Share 2.0] Add deleteFromSelf method
This commit is contained in:
commit
99e9c81c8b
|
@ -21,6 +21,7 @@
|
|||
namespace OC\Share20;
|
||||
|
||||
use OC\Share20\Exception\InvalidShare;
|
||||
use OC\Share20\Exception\ProviderException;
|
||||
use OC\Share20\Exception\ShareNotFound;
|
||||
use OC\Share20\Exception\BackendError;
|
||||
use OCP\Files\NotFoundException;
|
||||
|
@ -241,6 +242,84 @@ class DefaultShareProvider implements IShareProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshare a share from the recipient. If this is a group share
|
||||
* this means we need a special entry in the share db.
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param IUser $recipient
|
||||
* @throws BackendError
|
||||
* @throws ProviderException
|
||||
*/
|
||||
public function deleteFromSelf(IShare $share, IUser $recipient) {
|
||||
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
|
||||
|
||||
/** @var IGroup $group */
|
||||
$group = $share->getSharedWith();
|
||||
|
||||
if (!$group->inGroup($recipient)) {
|
||||
throw new ProviderException('Recipient not in receiving group');
|
||||
}
|
||||
|
||||
// Try to fetch user specific share
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
|
||||
->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient->getUID())))
|
||||
->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
|
||||
->execute();
|
||||
|
||||
$data = $stmt->fetch();
|
||||
|
||||
/*
|
||||
* Check if there already is a user specific group share.
|
||||
* If there is update it (if required).
|
||||
*/
|
||||
if ($data === false) {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$type = $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder';
|
||||
|
||||
//Insert new share
|
||||
$qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
|
||||
'share_with' => $qb->createNamedParameter($recipient->getUID()),
|
||||
'uid_owner' => $qb->createNamedParameter($share->getShareOwner()->getUID()),
|
||||
'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()->getUID()),
|
||||
'parent' => $qb->createNamedParameter($share->getId()),
|
||||
'item_type' => $qb->createNamedParameter($type),
|
||||
'item_source' => $qb->createNamedParameter($share->getPath()->getId()),
|
||||
'file_source' => $qb->createNamedParameter($share->getPath()->getId()),
|
||||
'file_target' => $qb->createNamedParameter($share->getTarget()),
|
||||
'permissions' => $qb->createNamedParameter(0),
|
||||
'stime' => $qb->createNamedParameter($share->getSharetime()),
|
||||
])->execute();
|
||||
|
||||
} else if ($data['permissions'] !== 0) {
|
||||
|
||||
// Update existing usergroup share
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->update('share')
|
||||
->set('permissions', $qb->createNamedParameter(0))
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
|
||||
->execute();
|
||||
}
|
||||
|
||||
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
|
||||
|
||||
if ($share->getSharedWith() !== $recipient) {
|
||||
throw new ProviderException('Recipient does not match');
|
||||
}
|
||||
|
||||
// We can just delete user and link shares
|
||||
$this->delete($share);
|
||||
} else {
|
||||
throw new ProviderException('Invalid shareType');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all shares by the given user. Sharetype and path can be used to filter.
|
||||
*
|
||||
|
|
|
@ -57,6 +57,15 @@ interface IShareProvider {
|
|||
*/
|
||||
public function delete(IShare $share);
|
||||
|
||||
/**
|
||||
* Unshare a file from self as recipient.
|
||||
* This may require special handling.
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param IUser $recipient
|
||||
*/
|
||||
public function deleteFromSelf(IShare $share, IUser $recipient);
|
||||
|
||||
/**
|
||||
* Get all shares by the given user
|
||||
*
|
||||
|
|
|
@ -606,6 +606,22 @@ class Manager {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unshare a file as the recipient.
|
||||
* This can be different from a regular delete for example when one of
|
||||
* the users in a groups deletes that share. But the provider should
|
||||
* handle this.
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param IUser $recipient
|
||||
*/
|
||||
public function deleteFromSelf(IShare $share, IUser $recipient) {
|
||||
list($providerId, $id) = $this->splitFullId($share->getId());
|
||||
$provider = $this->factory->getProvider($providerId);
|
||||
|
||||
$provider->deleteFromSelf($share, $recipient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shares shared by (initiated) by the provided user.
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
namespace Test\Share20;
|
||||
|
||||
use OC\Share20\Exception\ProviderException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IGroupManager;
|
||||
|
@ -1061,7 +1062,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
'share_with' => $qb->expr()->literal('sharedWith'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner'),
|
||||
'uid_initiator' => $qb->expr()->literal('shareOwner'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(42),
|
||||
'file_target' => $qb->expr()->literal('myTarget'),
|
||||
'permissions' => $qb->expr()->literal(13),
|
||||
|
@ -1076,7 +1077,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
'share_with' => $qb->expr()->literal('sharedWith'),
|
||||
'uid_owner' => $qb->expr()->literal('shareOwner'),
|
||||
'uid_initiator' => $qb->expr()->literal('sharedBy'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(42),
|
||||
'file_target' => $qb->expr()->literal('userTarget'),
|
||||
'permissions' => $qb->expr()->literal(0),
|
||||
|
@ -1123,4 +1124,301 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
$this->assertEquals(0, $share->getPermissions());
|
||||
$this->assertEquals('userTarget', $share->getTarget());
|
||||
}
|
||||
|
||||
public function testDeleteFromSelfGroupNoCustomShare() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
|
||||
'share_with' => $qb->expr()->literal('group'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2)
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$user2 = $this->getMock('\OCP\IUser');
|
||||
$user2->method('getUID')->willReturn('user2');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
['user2', $user2],
|
||||
]));
|
||||
|
||||
$group = $this->getMock('\OCP\IGroup');
|
||||
$group->method('getGID')->willReturn('group');
|
||||
$group->method('inGroup')->with($user2)->willReturn(true);
|
||||
$this->groupManager->method('get')->with('group')->willReturn($group);
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user2);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
|
||||
->execute();
|
||||
|
||||
$shares = $stmt->fetchAll();
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->assertCount(1, $shares);
|
||||
$share2 = $shares[0];
|
||||
$this->assertEquals($id, $share2['parent']);
|
||||
$this->assertEquals(0, $share2['permissions']);
|
||||
$this->assertEquals('user2', $share2['share_with']);
|
||||
}
|
||||
|
||||
public function testDeleteFromSelfGroupAlreadyCustomShare() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
|
||||
'share_with' => $qb->expr()->literal('group'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2)
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(2),
|
||||
'share_with' => $qb->expr()->literal('user2'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2),
|
||||
'parent' => $qb->expr()->literal($id),
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$user2 = $this->getMock('\OCP\IUser');
|
||||
$user2->method('getUID')->willReturn('user2');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
['user2', $user2],
|
||||
]));
|
||||
|
||||
$group = $this->getMock('\OCP\IGroup');
|
||||
$group->method('getGID')->willReturn('group');
|
||||
$group->method('inGroup')->with($user2)->willReturn(true);
|
||||
$this->groupManager->method('get')->with('group')->willReturn($group);
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user2);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
|
||||
->execute();
|
||||
|
||||
$shares = $stmt->fetchAll();
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->assertCount(1, $shares);
|
||||
$share2 = $shares[0];
|
||||
$this->assertEquals($id, $share2['parent']);
|
||||
$this->assertEquals(0, $share2['permissions']);
|
||||
$this->assertEquals('user2', $share2['share_with']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OC\Share20\Exception\ProviderException
|
||||
* @expectedExceptionMessage Recipient not in receiving group
|
||||
*/
|
||||
public function testDeleteFromSelfGroupUserNotInGroup() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
|
||||
'share_with' => $qb->expr()->literal('group'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2)
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$user2 = $this->getMock('\OCP\IUser');
|
||||
$user2->method('getUID')->willReturn('user2');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
['user2', $user2],
|
||||
]));
|
||||
|
||||
$group = $this->getMock('\OCP\IGroup');
|
||||
$group->method('getGID')->willReturn('group');
|
||||
$group->method('inGroup')->with($user2)->willReturn(false);
|
||||
$this->groupManager->method('get')->with('group')->willReturn($group);
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user2);
|
||||
}
|
||||
|
||||
public function testDeleteFromSelfUser() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
|
||||
'share_with' => $qb->expr()->literal('user2'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2)
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$user2 = $this->getMock('\OCP\IUser');
|
||||
$user2->method('getUID')->willReturn('user2');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
['user2', $user2],
|
||||
]));
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user2);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
|
||||
->execute();
|
||||
|
||||
$shares = $stmt->fetchAll();
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->assertCount(0, $shares);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OC\Share20\Exception\ProviderException
|
||||
* @expectedExceptionMessage Recipient does not match
|
||||
*/
|
||||
public function testDeleteFromSelfUserNotRecipient() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
|
||||
'share_with' => $qb->expr()->literal('user2'),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2)
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$user2 = $this->getMock('\OCP\IUser');
|
||||
$user2->method('getUID')->willReturn('user2');
|
||||
$user3 = $this->getMock('\OCP\IUser');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
['user2', $user2],
|
||||
]));
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OC\Share20\Exception\ProviderException
|
||||
* @expectedExceptionMessage Invalid shareType
|
||||
*/
|
||||
public function testDeleteFromSelfLink() {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$stmt = $qb->insert('share')
|
||||
->values([
|
||||
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK),
|
||||
'uid_owner' => $qb->expr()->literal('user1'),
|
||||
'uid_initiator' => $qb->expr()->literal('user1'),
|
||||
'item_type' => $qb->expr()->literal('file'),
|
||||
'file_source' => $qb->expr()->literal(1),
|
||||
'file_target' => $qb->expr()->literal('myTarget1'),
|
||||
'permissions' => $qb->expr()->literal(2),
|
||||
'token' => $qb->expr()->literal('token'),
|
||||
])->execute();
|
||||
$this->assertEquals(1, $stmt);
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$user1 = $this->getMock('\OCP\IUser');
|
||||
$user1->method('getUID')->willReturn('user1');
|
||||
$this->userManager->method('get')->will($this->returnValueMap([
|
||||
['user1', $user1],
|
||||
]));
|
||||
|
||||
$file = $this->getMock('\OCP\Files\File');
|
||||
$file->method('getId')->willReturn(1);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
|
||||
$this->rootFolder->method('getById')->with(1)->willReturn([$file]);
|
||||
|
||||
$share = $this->provider->getShareById($id);
|
||||
|
||||
$this->provider->deleteFromSelf($share, $user1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue