use share initiator as fall back to access the file

in case of federated re-shares the owner can be a remote user.
Therefore we can't always use to owner to access the local file
This commit is contained in:
Björn Schießle 2016-05-11 20:48:27 +02:00
parent 81e3787f9c
commit 7b25839bd5
No known key found for this signature in database
GPG key ID: 2378A753E2BF04F6
12 changed files with 111 additions and 24 deletions

View file

@ -81,7 +81,8 @@ class Application extends App {
\OC::$server->getL10N('federatedfilesharing'), \OC::$server->getL10N('federatedfilesharing'),
\OC::$server->getLogger(), \OC::$server->getLogger(),
\OC::$server->getLazyRootFolder(), \OC::$server->getLazyRootFolder(),
\OC::$server->getConfig() \OC::$server->getConfig(),
\OC::$server->getUserManager()
); );
} }

View file

@ -23,13 +23,12 @@
namespace OCA\FederatedFileSharing; namespace OCA\FederatedFileSharing;
use OC\Files\View;
use OC\Share20\Share; use OC\Share20\Share;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\IAppConfig;
use OCP\IConfig; use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
use OCP\IUserManager;
use OCP\Share\IShare; use OCP\Share\IShare;
use OCP\Share\IShareProvider; use OCP\Share\IShareProvider;
use OC\Share20\Exception\InvalidShare; use OC\Share20\Exception\InvalidShare;
@ -74,6 +73,9 @@ class FederatedShareProvider implements IShareProvider {
/** @var string */ /** @var string */
private $externalShareTable = 'share_external'; private $externalShareTable = 'share_external';
/** @var IUserManager */
private $userManager;
/** /**
* DefaultShareProvider constructor. * DefaultShareProvider constructor.
* *
@ -85,6 +87,7 @@ class FederatedShareProvider implements IShareProvider {
* @param ILogger $logger * @param ILogger $logger
* @param IRootFolder $rootFolder * @param IRootFolder $rootFolder
* @param IConfig $config * @param IConfig $config
* @param IUserManager $userManager
*/ */
public function __construct( public function __construct(
IDBConnection $connection, IDBConnection $connection,
@ -94,7 +97,8 @@ class FederatedShareProvider implements IShareProvider {
IL10N $l10n, IL10N $l10n,
ILogger $logger, ILogger $logger,
IRootFolder $rootFolder, IRootFolder $rootFolder,
IConfig $config IConfig $config,
IUserManager $userManager
) { ) {
$this->dbConnection = $connection; $this->dbConnection = $connection;
$this->addressHandler = $addressHandler; $this->addressHandler = $addressHandler;
@ -104,6 +108,7 @@ class FederatedShareProvider implements IShareProvider {
$this->logger = $logger; $this->logger = $logger;
$this->rootFolder = $rootFolder; $this->rootFolder = $rootFolder;
$this->config = $config; $this->config = $config;
$this->userManager = $userManager;
} }
/** /**
@ -699,7 +704,7 @@ class FederatedShareProvider implements IShareProvider {
*/ */
private function createShare($data) { private function createShare($data) {
$share = new Share($this->rootFolder); $share = new Share($this->rootFolder, $this->userManager);
$share->setId((int)$data['id']) $share->setId((int)$data['id'])
->setShareType((int)$data['share_type']) ->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions']) ->setPermissions((int)$data['permissions'])

View file

@ -30,6 +30,7 @@ use OCP\IConfig;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\IL10N; use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
use OCP\IUserManager;
use OCP\Share\IManager; use OCP\Share\IManager;
/** /**
@ -56,6 +57,8 @@ class FederatedShareProviderTest extends \Test\TestCase {
protected $rootFolder; protected $rootFolder;
/** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */
protected $config; protected $config;
/** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
protected $userManager;
/** @var IManager */ /** @var IManager */
protected $shareManager; protected $shareManager;
@ -81,7 +84,9 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->logger = $this->getMock('OCP\ILogger'); $this->logger = $this->getMock('OCP\ILogger');
$this->rootFolder = $this->getMock('OCP\Files\IRootFolder'); $this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
$this->config = $this->getMock('OCP\IConfig'); $this->config = $this->getMock('OCP\IConfig');
$this->addressHandler = new AddressHandler(\OC::$server->getURLGenerator(), $this->l); $this->userManager = $this->getMock('OCP\IUserManager');
//$this->addressHandler = new AddressHandler(\OC::$server->getURLGenerator(), $this->l);
$this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')->disableOriginalConstructor()->getMock();
$this->userManager->expects($this->any())->method('userExists')->willReturn(true); $this->userManager->expects($this->any())->method('userExists')->willReturn(true);
@ -93,7 +98,8 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->l, $this->l,
$this->logger, $this->logger,
$this->rootFolder, $this->rootFolder,
$this->config $this->config,
$this->userManager
); );
$this->shareManager = \OC::$server->getShareManager(); $this->shareManager = \OC::$server->getShareManager();
@ -120,6 +126,11 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
->willReturn('http://localhost/');
$this->addressHandler->expects($this->any())->method('splitUserRemote')
->willReturn(['user', 'server.com']);
$this->notifications->expects($this->once()) $this->notifications->expects($this->once())
->method('sendRemoteShare') ->method('sendRemoteShare')
->with( ->with(
@ -186,6 +197,11 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
->willReturn('http://localhost/');
$this->addressHandler->expects($this->any())->method('splitUserRemote')
->willReturn(['user', 'server.com']);
$this->notifications->expects($this->once()) $this->notifications->expects($this->once())
->method('sendRemoteShare') ->method('sendRemoteShare')
->with( ->with(
@ -233,7 +249,10 @@ class FederatedShareProviderTest extends \Test\TestCase {
$node->method('getId')->willReturn(42); $node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile'); $node->method('getName')->willReturn('myFile');
$shareWith = 'sharedBy@' . $this->addressHandler->generateRemoteURL(); $this->addressHandler->expects($this->any())->method('compareAddresses')
->willReturn(true);
$shareWith = 'sharedBy@localhost';
$share->setSharedWith($shareWith) $share->setSharedWith($shareWith)
->setSharedBy('sharedBy') ->setSharedBy('sharedBy')
@ -269,6 +288,10 @@ class FederatedShareProviderTest extends \Test\TestCase {
$node->method('getId')->willReturn(42); $node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile'); $node->method('getName')->willReturn('myFile');
$this->addressHandler->expects($this->any())->method('splitUserRemote')
->willReturn(['user', 'server.com']);
$share->setSharedWith('user@server.com') $share->setSharedWith('user@server.com')
->setSharedBy('sharedBy') ->setSharedBy('sharedBy')
->setShareOwner('shareOwner') ->setShareOwner('shareOwner')
@ -277,6 +300,9 @@ class FederatedShareProviderTest extends \Test\TestCase {
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
->willReturn('http://localhost/');
$this->notifications->expects($this->once()) $this->notifications->expects($this->once())
->method('sendRemoteShare') ->method('sendRemoteShare')
->with( ->with(
@ -328,6 +354,10 @@ class FederatedShareProviderTest extends \Test\TestCase {
$node->method('getId')->willReturn(42); $node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile'); $node->method('getName')->willReturn('myFile');
$this->addressHandler->expects($this->any())->method('splitUserRemote')
->willReturn(['user', 'server.com']);
$share->setSharedWith('user@server.com') $share->setSharedWith('user@server.com')
->setSharedBy($sharedBy) ->setSharedBy($sharedBy)
->setShareOwner($owner) ->setShareOwner($owner)
@ -335,6 +365,8 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setNode($node); ->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
->willReturn('http://localhost/');
$this->notifications->expects($this->once()) $this->notifications->expects($this->once())
->method('sendRemoteShare') ->method('sendRemoteShare')
@ -379,6 +411,12 @@ class FederatedShareProviderTest extends \Test\TestCase {
$node->method('getId')->willReturn(42); $node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile'); $node->method('getName')->willReturn('myFile');
$this->addressHandler->expects($this->at(0))->method('splitUserRemote')
->willReturn(['user', 'server.com']);
$this->addressHandler->expects($this->at(1))->method('splitUserRemote')
->willReturn(['user2', 'server.com']);
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->notifications $this->notifications
->method('sendRemoteShare') ->method('sendRemoteShare')
@ -485,6 +523,14 @@ class FederatedShareProviderTest extends \Test\TestCase {
$node->method('getId')->willReturn(42); $node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile'); $node->method('getName')->willReturn('myFile');
$this->addressHandler->expects($this->any())->method('splitUserRemote')
->willReturnCallback(function ($uid) {
if ($uid === 'user@server.com') {
return ['user', 'server.com'];
}
return ['user2', 'server.com'];
});
$this->tokenHandler->method('generateToken')->willReturn('token'); $this->tokenHandler->method('generateToken')->willReturn('token');
$this->notifications $this->notifications
->method('sendRemoteShare') ->method('sendRemoteShare')

View file

@ -99,7 +99,15 @@ class Share20OCS {
*/ */
protected function formatShare(\OCP\Share\IShare $share) { protected function formatShare(\OCP\Share\IShare $share) {
$sharedBy = $this->userManager->get($share->getSharedBy()); $sharedBy = $this->userManager->get($share->getSharedBy());
$shareOwner = $this->userManager->get($share->getShareOwner()); // for federated shares the owner can be a remote user, in this
// case we use the initiator
if ($this->userManager->userExists($share->getShareOwner())) {
$shareOwner = $this->userManager->get($share->getShareOwner());
$localUser = $share->getShareOwner();
} else {
$shareOwner = $this->userManager->get($share->getSharedBy());
$localUser = $share->getSharedBy();
}
$result = [ $result = [
'id' => $share->getId(), 'id' => $share->getId(),
'share_type' => $share->getShareType(), 'share_type' => $share->getShareType(),
@ -115,7 +123,7 @@ class Share20OCS {
]; ];
$node = $share->getNode(); $node = $share->getNode();
$result['path'] = $this->rootFolder->getUserFolder($share->getShareOwner())->getRelativePath($node->getPath()); $result['path'] = $this->rootFolder->getUserFolder($localUser)->getRelativePath($node->getPath());
if ($node instanceOf \OCP\Files\Folder) { if ($node instanceOf \OCP\Files\Folder) {
$result['item_type'] = 'folder'; $result['item_type'] = 'folder';
} else { } else {

View file

@ -82,6 +82,8 @@ class Share20OCSTest extends \Test\TestCase {
$this->currentUser = $this->getMock('OCP\IUser'); $this->currentUser = $this->getMock('OCP\IUser');
$this->currentUser->method('getUID')->willReturn('currentUser'); $this->currentUser->method('getUID')->willReturn('currentUser');
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
$this->l = $this->getMock('\OCP\IL10N'); $this->l = $this->getMock('\OCP\IL10N');
$this->l->method('t') $this->l->method('t')
->will($this->returnCallback(function($text, $parameters = []) { ->will($this->returnCallback(function($text, $parameters = []) {

View file

@ -733,7 +733,7 @@ class DefaultShareProvider implements IShareProvider {
* @throws InvalidShare * @throws InvalidShare
*/ */
private function createShare($data) { private function createShare($data) {
$share = new Share($this->rootFolder); $share = new Share($this->rootFolder, $this->userManager);
$share->setId((int)$data['id']) $share->setId((int)$data['id'])
->setShareType((int)$data['share_type']) ->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions']) ->setPermissions((int)$data['permissions'])

View file

@ -201,7 +201,12 @@ class Manager implements IManager {
} }
// And you can't share your rootfolder // And you can't share your rootfolder
if ($this->rootFolder->getUserFolder($share->getSharedBy())->getPath() === $share->getNode()->getPath()) { if ($this->userManager->userExists($share->getSharedBy())) {
$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
} else {
$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
}
if ($sharedPath === $share->getNode()->getPath()) {
throw new \InvalidArgumentException('You can\'t share your root folder'); throw new \InvalidArgumentException('You can\'t share your root folder');
} }
@ -713,7 +718,11 @@ class Manager implements IManager {
} }
if ($share->getPermissions() !== $originalShare->getPermissions()) { if ($share->getPermissions() !== $originalShare->getPermissions()) {
$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner()); if ($this->userManager->userExists($share->getShareOwner())) {
$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
} else {
$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
}
\OC_Hook::emit('OCP\Share', 'post_update_permissions', array( \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
'itemSource' => $share->getNode()->getId(), 'itemSource' => $share->getNode()->getId(),
@ -1107,7 +1116,7 @@ class Manager implements IManager {
* @return \OCP\Share\IShare; * @return \OCP\Share\IShare;
*/ */
public function newShare() { public function newShare() {
return new \OC\Share20\Share($this->rootFolder); return new \OC\Share20\Share($this->rootFolder, $this->userManager);
} }
/** /**

View file

@ -115,7 +115,8 @@ class ProviderFactory implements IProviderFactory {
$l, $l,
$this->serverContainer->getLogger(), $this->serverContainer->getLogger(),
$this->serverContainer->getLazyRootFolder(), $this->serverContainer->getLazyRootFolder(),
$this->serverContainer->getConfig() $this->serverContainer->getConfig(),
$this->serverContainer->getUserManager()
); );
} }

View file

@ -24,8 +24,7 @@ use OCP\Files\File;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Files\Node; use OCP\Files\Node;
use OCP\Files\NotFoundException; use OCP\Files\NotFoundException;
use OCP\IUser; use OCP\IUserManager;
use OCP\IGroup;
use OCP\Share\Exceptions\IllegalIDChangeException; use OCP\Share\Exceptions\IllegalIDChangeException;
class Share implements \OCP\Share\IShare { class Share implements \OCP\Share\IShare {
@ -68,8 +67,12 @@ class Share implements \OCP\Share\IShare {
/** @var IRootFolder */ /** @var IRootFolder */
private $rootFolder; private $rootFolder;
public function __construct(IRootFolder $rootFolder) { /** @var IUserManager */
private $userManager;
public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
$this->rootFolder = $rootFolder; $this->rootFolder = $rootFolder;
$this->userManager = $userManager;
} }
/** /**
@ -145,7 +148,13 @@ class Share implements \OCP\Share\IShare {
throw new NotFoundException(); throw new NotFoundException();
} }
$userFolder = $this->rootFolder->getUserFolder($this->shareOwner); // for federated shares the owner can be a remote user, in this
// case we use the initiator
if($this->userManager->userExists($this->shareOwner)) {
$userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
} else {
$userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
}
$nodes = $userFolder->getById($this->fileId); $nodes = $userFolder->getById($this->fileId);
if (empty($nodes)) { if (empty($nodes)) {

View file

@ -57,6 +57,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->groupManager = $this->getMock('OCP\IGroupManager'); $this->groupManager = $this->getMock('OCP\IGroupManager');
$this->rootFolder = $this->getMock('OCP\Files\IRootFolder'); $this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
//Empty share table //Empty share table
$this->dbConn->getQueryBuilder()->delete('share')->execute(); $this->dbConn->getQueryBuilder()->delete('share')->execute();
@ -587,7 +589,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
} }
public function testCreateUserShare() { public function testCreateUserShare() {
$share = new \OC\Share20\Share($this->rootFolder); $share = new \OC\Share20\Share($this->rootFolder, $this->userManager);
$shareOwner = $this->getMock('OCP\IUser'); $shareOwner = $this->getMock('OCP\IUser');
$shareOwner->method('getUID')->WillReturn('shareOwner'); $shareOwner->method('getUID')->WillReturn('shareOwner');
@ -635,7 +637,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
} }
public function testCreateGroupShare() { public function testCreateGroupShare() {
$share = new \OC\Share20\Share($this->rootFolder); $share = new \OC\Share20\Share($this->rootFolder, $this->userManager);
$shareOwner = $this->getMock('\OCP\IUser'); $shareOwner = $this->getMock('\OCP\IUser');
$shareOwner->method('getUID')->willReturn('shareOwner'); $shareOwner->method('getUID')->willReturn('shareOwner');
@ -683,7 +685,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
} }
public function testCreateLinkShare() { public function testCreateLinkShare() {
$share = new \OC\Share20\Share($this->rootFolder); $share = new \OC\Share20\Share($this->rootFolder, $this->userManager);
$shareOwner = $this->getMock('\OCP\IUser'); $shareOwner = $this->getMock('\OCP\IUser');
$shareOwner->method('getUID')->willReturn('shareOwner'); $shareOwner->method('getUID')->willReturn('shareOwner');

View file

@ -2283,6 +2283,9 @@ class ManagerTest extends \Test\TestCase {
} }
public function testUpdateShareUser() { public function testUpdateShareUser() {
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
$manager = $this->createManagerMock() $manager = $this->createManagerMock()
->setMethods([ ->setMethods([
'canShare', 'canShare',
@ -2567,4 +2570,4 @@ class DummyFactory implements IProviderFactory {
public function getProviderForType($shareType) { public function getProviderForType($shareType) {
return $this->provider; return $this->provider;
} }
} }

View file

@ -36,7 +36,8 @@ class ShareTest extends \Test\TestCase {
public function setUp() { public function setUp() {
$this->rootFolder = $this->getMock('\OCP\Files\IRootFolder'); $this->rootFolder = $this->getMock('\OCP\Files\IRootFolder');
$this->share = new \OC\Share20\Share($this->rootFolder); $this->userManager = $this->getMock('OCP\IUserManager');
$this->share = new \OC\Share20\Share($this->rootFolder, $this->userManager);
} }
/** /**