Add path filter to OCS Share API ?shared_with_me=true

This allows all clients to quickly get the share info for a given path.
Instead of returning everything and filtering it then manually on the
client side.
This commit is contained in:
Roeland Jago Douma 2016-01-29 15:26:04 +01:00
parent 8ad45dad38
commit a24e7f6558
6 changed files with 109 additions and 31 deletions

View file

@ -329,9 +329,13 @@ class Share20OCS {
return new \OC_OCS_Result($share);
}
private function getSharedWithMe() {
$userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, -1, 0);
$groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, -1, 0);
/**
* @param \OCP\Files\File|\OCP\Files\Folder $node
* @return \OC_OCS_Result
*/
private function getSharedWithMe($node = null) {
$userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
$groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
$shares = array_merge($userShares, $groupShares);
@ -390,10 +394,6 @@ class Share20OCS {
$subfiles = $this->request->getParam('subfiles');
$path = $this->request->getParam('path', null);
if ($sharedWithMe === 'true') {
return $this->getSharedWithMe();
}
if ($path !== null) {
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
try {
@ -403,6 +403,10 @@ class Share20OCS {
}
}
if ($sharedWithMe === 'true') {
return $this->getSharedWithMe($path);
}
if ($subfiles === 'true') {
return $this->getSharesInDir($path);
}

View file

@ -518,16 +518,9 @@ class DefaultShareProvider implements IShareProvider {
}
/**
* Get shared with the given user
*
* @param IUser $user get shares where this user is the recipient
* @param int $shareType \OCP\Share::SHARE_TYPE_USER or \OCP\Share::SHARE_TYPE_GROUP are supported
* @param int $limit The maximum number of shares, -1 for all
* @param int $offset
* @return IShare[]
* @throws BackendError
* @inheritdoc
*/
public function getSharedWith(IUser $user, $shareType, $limit, $offset) {
public function getSharedWith(IUser $user, $shareType, $node, $limit, $offset) {
/** @var Share[] $shares */
$shares = [];
@ -549,6 +542,11 @@ class DefaultShareProvider implements IShareProvider {
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($user->getUID())));
// Filter by node if provided
if ($node !== null) {
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
}
$cursor = $qb->execute();
while($data = $cursor->fetch()) {
@ -581,9 +579,14 @@ class DefaultShareProvider implements IShareProvider {
$qb->setMaxResults($limit - count($shares));
}
// Filter by node if provided
if ($node !== null) {
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
}
$groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)));
$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)));
$qb->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
$groups,
IQueryBuilder::PARAM_STR_ARRAY

View file

@ -21,6 +21,7 @@
namespace OC\Share20;
use OCP\Files\Node;
use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OC\Share20\Exception\BackendError;
@ -722,18 +723,12 @@ class Manager implements IManager {
}
/**
* Get shares shared with $user.
*
* @param IUser $user
* @param int $shareType
* @param int $limit The maximum number of shares returned, -1 for all
* @param int $offset
* @return \OCP\Share\IShare[]
* @inheritdoc
*/
public function getSharedWith(IUser $user, $shareType, $limit = 50, $offset = 0) {
public function getSharedWith(IUser $user, $shareType, $node = null, $limit = 50, $offset = 0) {
$provider = $this->factory->getProviderForType($shareType);
return $provider->getSharedWith($user, $shareType, $limit, $offset);
return $provider->getSharedWith($user, $shareType, $node, $limit, $offset);
}
/**

View file

@ -88,15 +88,17 @@ interface IManager {
/**
* Get shares shared with $user.
* Filter by $node if provided
*
* @param IUser $user
* @param int $shareType
* @param File|Folder|null $node
* @param int $limit The maximum number of shares returned, -1 for all
* @param int $offset
* @return IShare[]
* @since 9.0.0
*/
public function getSharedWith(IUser $user, $shareType, $limit = 50, $offset = 0);
public function getSharedWith(IUser $user, $shareType, $node = null, $limit = 50, $offset = 0);
/**
* Retrieve a share by the share id

View file

@ -23,6 +23,7 @@ namespace OCP\Share;
use OC\Share20\Exception\ShareNotFound;
use OC\Share20\Exception\BackendError;
use OCP\Files\Node;
use OCP\IUser;
/**
@ -116,12 +117,13 @@ interface IShareProvider {
*
* @param IUser $user get shares where this user is the recipient
* @param int $shareType
* @param Node|null $node
* @param int $limit The max number of entries returned, -1 for all
* @param int $offset
* @return \OCP\Share\IShare[]
* @since 9.0.0
*/
public function getSharedWith(IUser $user, $shareType, $limit, $offset);
public function getSharedWith(IUser $user, $shareType, $node, $limit, $offset);
/**
* Get a share by token

View file

@ -824,7 +824,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf());
$this->rootFolder->method('getById')->with(42)->willReturn([$file]);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_USER, 1 , 0);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_USER, null, 1 , 0);
$this->assertCount(1, $share);
$share = $share[0];
@ -894,7 +894,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf());
$this->rootFolder->method('getById')->with(42)->willReturn([$file]);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_GROUP, 20 , 1);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_GROUP, null, 20 , 1);
$this->assertCount(1, $share);
$share = $share[0];
@ -979,7 +979,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf());
$this->rootFolder->method('getById')->with(42)->willReturn([$file]);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_GROUP, -1, 0);
$share = $this->provider->getSharedWith($user, \OCP\Share::SHARE_TYPE_GROUP, null, -1, 0);
$this->assertCount(1, $share);
$share = $share[0];
@ -992,6 +992,78 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->assertSame('userTarget', $share->getTarget());
}
public function testGetSharedWithUserWithNode() {
$this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1',
'file', 42, 'myTarget', 31, null, null, null);
$id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1',
'file', 43, 'myTarget', 31, null, null, null);
$user0 = $this->getMock('\OCP\IUser');
$user0->method('getUID')->willReturn('user0');
$user1 = $this->getMock('\OCP\IUser');
$user1->method('getUID')->willReturn('user1');
$this->userManager->method('get')->willReturnMap([
['user0', $user0],
['user1', $user1],
]);
$file = $this->getMock('\OCP\Files\File');
$file->method('getId')->willReturn(43);
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
$this->rootFolder->method('getById')->with(43)->willReturn([$file]);
$share = $this->provider->getSharedWith($user0, \OCP\Share::SHARE_TYPE_USER, $file, -1, 0);
$this->assertCount(1, $share);
$share = $share[0];
$this->assertEquals($id, $share->getId());
$this->assertSame($user0, $share->getSharedWith());
$this->assertSame($user1, $share->getShareOwner());
$this->assertSame($user1, $share->getSharedBy());
$this->assertSame($file, $share->getNode());
$this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType());
}
public function testGetSharedWithGroupWithNode() {
$this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1',
'file', 42, 'myTarget', 31, null, null, null);
$id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1',
'file', 43, 'myTarget', 31, null, null, null);
$user0 = $this->getMock('\OCP\IUser');
$user0->method('getUID')->willReturn('user0');
$user1 = $this->getMock('\OCP\IUser');
$user1->method('getUID')->willReturn('user1');
$this->userManager->method('get')->willReturnMap([
['user0', $user0],
['user1', $user1],
]);
$group0 = $this->getMock('\OCP\IGroup');
$group0->method('getGID')->willReturn('group0');
$this->groupManager->method('get')->with('group0')->willReturn($group0);
$this->groupManager->method('getUserGroups')->with($user0)->willReturn([$group0]);
$node = $this->getMock('\OCP\Files\Folder');
$node->method('getId')->willReturn(43);
$this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf());
$this->rootFolder->method('getById')->with(43)->willReturn([$node]);
$share = $this->provider->getSharedWith($user0, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
$this->assertCount(1, $share);
$share = $share[0];
$this->assertEquals($id, $share->getId());
$this->assertSame($group0, $share->getSharedWith());
$this->assertSame($user1, $share->getShareOwner());
$this->assertSame($user1, $share->getSharedBy());
$this->assertSame($node, $share->getNode());
$this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType());
}
public function testGetSharesBy() {
$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')