Browse Source

The new sharing code now handles deletion

OCS -> ShareManager -> DefaultShareProvider
tags/v9.0beta1
Roeland Jago Douma 8 years ago
parent
commit
6624fa212a

+ 10
- 3
apps/files_sharing/api/ocssharewrapper.php View File

@@ -22,8 +22,11 @@ namespace OCA\Files_Sharing\API;

class OCSShareWrapper {

/**
* @return Share20OCS
*/
private function getShare20OCS() {
return new share20OCS(new \OC\Share20\Manager(
return new Share20OCS(new \OC\Share20\Manager(
\OC::$server->getUserSession()->getUser(),
\OC::$server->getUserManager(),
\OC::$server->getGroupManager(),
@@ -31,7 +34,10 @@ class OCSShareWrapper {
\OC::$server->getAppConfig(),
\OC::$server->getUserFolder(),
new \OC\Share20\DefaultShareProvider(
\OC::$server->getDatabaseConnection()
\OC::$server->getDatabaseConnection(),
\OC::$server->getUserManager(),
\OC::$server->getGroupManager(),
\OC::$server->getUserFolder()
)
),
\OC::$server->getGroupManager(),
@@ -57,6 +63,7 @@ class OCSShareWrapper {
}

public function deleteShare($params) {
return \OCA\Files_Sharing\API\Local::deleteShare($params);
$id = (int)$params['id'];
return $this->getShare20OCS()->deleteShare($id);
}
}

+ 73
- 0
apps/files_sharing/api/share20ocs.php View File

@@ -0,0 +1,73 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_Sharing\API;

class Share20OCS {

/** @var OC\Share20\Manager */
private $shareManager;

/** @var OCP\IGroupManager */
private $groupManager;

/** @var OCP\IUserManager */
private $userManager;

/** @var OCP\IRequest */
private $request;

/** @var OCP\Files\Folder */
private $userFolder;

public function __construct(\OC\Share20\Manager $shareManager,
\OCP\IGroupManager $groupManager,
\OCP\IUserManager $userManager,
\OCP\IRequest $request,
\OCP\Files\Folder $userFolder) {
$this->shareManager = $shareManager;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->request = $request;
$this->userFolder = $userFolder;
}

/**
* Delete a share
*
* @param int $id
* @return \OC_OCS_Result
*/
public function deleteShare($id) {
try {
$share = $this->shareManager->getShareById($id);
} catch (\OC\Share20\Exception\ShareNotFound $e) {
return new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
}

try {
$this->shareManager->deleteShare($share);
} catch (\OC\Share20\Exception\BackendError $e) {
return new \OC_OCS_Result(null, 404, 'could not delete share');
}

return new \OC_OCS_Result();
}
}

+ 113
- 0
apps/files_sharing/tests/api/share20ocstest.php View File

@@ -0,0 +1,113 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_Sharing\Tests\API;

use OCA\Files_Sharing\API\Share20OCS;

class Share20OCSTest extends \Test\TestCase {

/** @var OC\Share20\Manager */
private $shareManager;

/** @var OCP\IGroupManager */
private $groupManager;

/** @var OCP\IUserManager */
private $userManager;

/** @var OCP\IRequest */
private $request;

/** @var OCP\Files\Folder */
private $userFolder;

/** @var OCS */
private $ocs;

protected function setUp() {
$this->shareManager = $this->getMockBuilder('OC\Share20\Manager')
->disableOriginalConstructor()
->getMock();
$this->groupManager = $this->getMockBuilder('OCP\IGroupManager')
->disableOriginalConstructor()
->getMock();
$this->userManager = $this->getMockBuilder('OCP\IUserManager')
->disableOriginalConstructor()
->getMock();
$this->request = $this->getMockBuilder('OCP\IRequest')
->disableOriginalConstructor()
->getMock();
$this->userFolder = $this->getMockBuilder('OCP\Files\Folder')
->disableOriginalConstructor()
->getMock();

$this->ocs = new Share20OCS($this->shareManager,
$this->groupManager,
$this->userManager,
$this->request,
$this->userFolder);
}

public function testDeleteShareShareNotFound() {
$this->shareManager
->expects($this->once())
->method('getShareById')
->with(42)
->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));

$expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
$this->assertEquals($expected, $this->ocs->deleteShare(42));
}

public function testDeleteShareCouldNotDelete() {
$share = $this->getMock('OC\Share20\IShare');
$this->shareManager
->expects($this->once())
->method('getShareById')
->with(42)
->willReturn($share);
$this->shareManager
->expects($this->once())
->method('deleteShare')
->with($share)
->will($this->throwException(new \OC\Share20\Exception\BackendError()));


$expected = new \OC_OCS_Result(null, 404, 'could not delete share');
$this->assertEquals($expected, $this->ocs->deleteShare(42));
}

public function testDeleteShare() {
$share = $this->getMock('OC\Share20\IShare');
$this->shareManager
->expects($this->once())
->method('getShareById')
->with(42)
->willReturn($share);
$this->shareManager
->expects($this->once())
->method('deleteShare')
->with($share);

$expected = new \OC_OCS_Result();
$this->assertEquals($expected, $this->ocs->deleteShare(42));
}
}

+ 248
- 0
lib/private/share20/defaultshareprovider.php View File

@@ -0,0 +1,248 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Share20;

use OC\Share20\Exception\ShareNotFound;
use OC\Share20\Exception\BackendError;
use OCP\IUser;

class DefaultShareProvider implements IShareProvider {

/** @var \OCP\IDBConnection */
private $dbConn;

/** @var \OCP\IUserManager */
private $userManager;

/** @var \OCP\IGroupManager */
private $groupManager;

/** @var \OCP\Files\Folder */
private $userFolder;

public function __construct(\OCP\IDBConnection $connection,
\OCP\IUserManager $userManager,
\OCP\IGroupManager $groupManager,
\OCP\Files\Folder $userFolder) {
$this->dbConn = $connection;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->userFolder = $userFolder;
}

/**
* Share a path
*
* @param Share $share
* @return Share The share object
*/
public function create(Share $share) {
throw new \Exception();
}

/**
* Update a share
*
* @param Share $share
* @return Share The share object
*/
public function update(Share $share) {
throw new \Exception();
}

/**
* Get all childre of this share
*
* @param IShare $share
* @return IShare[]
*/
private function getChildren(IShare $share) {
$children = [];

$qb = $this->dbConn->getQueryBuilder();
$qb->select('*')
->from('share')
->where($qb->expr()->eq('parent', $qb->createParameter('parent')))
->setParameter(':parent', $share->getId());

$cursor = $qb->execute();
while($data = $cursor->fetch()) {
$children[] = $this->createShare($data);
}
$cursor->closeCursor();

return $children;
}

/**
* Delete all the children of this share
*
* @param IShare $share
*/
protected function deleteChildren(IShare $share) {
foreach($this->getChildren($share) as $child) {
$this->delete($child);
}
}

/**
* Delete a share
*
* @param Share $share
* @throws BackendError
*/
public function delete(IShare $share) {
$this->deleteChildren($share);

$qb = $this->dbConn->getQueryBuilder();

$qb->delete('share')
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter(':id', $share->getId());
try {
$qb->execute();
} catch (\Exception $e) {
throw new BackendError();
}
}

/**
* Get all shares by the given user
*
* @param IUser $user
* @param int $shareType
* @param int $offset
* @param int $limit
* @return Share[]
*/
public function getShares(IUser $user, $shareType, $offset, $limit) {
throw new \Exception();
}

/**
* Get share by id
*
* @param int $id
* @return IShare
* @throws ShareNotFound
*/
public function getShareById($id) {
$qb = $this->dbConn->getQueryBuilder();

$qb->select('*')
->from('share')
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter(':id', $id);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();

if ($data === false) {
throw new ShareNotFound();
}

$share = $this->createShare($data);

return $share;
}

/**
* Get shares for a given path
*
* @param \OCP\Files\Node $path
* @param Share[]
*/
public function getSharesByPath(\OCP\IUser $user, \OCP\Files\Node $path) {
throw new \Exception();
}

/**
* Get shared with the given user
*
* @param IUser $user
* @param int $shareType
* @param Share
*/
public function getSharedWithMe(IUser $user, $shareType = null) {
throw new \Exception();
}

/**
* Get a share by token and if present verify the password
*
* @param string $token
* @param string $password
* @param Share
*/
public function getShareByToken($token, $password = null) {
throw new \Exception();
}
/**
* Create a share object from an database row
*
* @param mixed[] $data
* @return Share
*/
private function createShare($data) {
$share = new Share();
$share->setId((int)$data['id'])
->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions']);

if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
$share->setSharedWith($this->userManager->get($data['share_with']));
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$share->setSharedWith($this->groupManager->get($data['share_with']));
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
/*
* TODO: Clean this up, this should be set as password not sharedWith
*/
$share->setSharedWith($data['share_with']);
$share->setToken($data['token']);
} else {
$share->setSharedWith($data['share_with']);
}

$share->setSharedBy($this->userManager->get($data['uid_owner']));

// TODO: getById can return an array. How to handle this properly??
$path = $this->userFolder->getById($data['file_source']);
$path = $path[0];
$share->setPath($path);

$owner = $path->getStorage()->getOwner('.');
if ($owner !== false) {
$share->setShareOwner($this->userManager->get($owner));
}

if ($data['expiration'] !== null) {
$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
$share->setExpirationDate($expiration);
}

return $share;
}


}

+ 25
- 0
lib/private/share20/exception/backenderror.php View File

@@ -0,0 +1,25 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Share20\Exception;

class BackendError extends \Exception {

}

+ 25
- 0
lib/private/share20/exception/sharenotfound.php View File

@@ -0,0 +1,25 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Share20\Exception;

class ShareNotFound extends \Exception {

}

+ 149
- 0
lib/private/share20/ishare.php View File

@@ -0,0 +1,149 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Share20;

use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\Node;
use OCP\IUser;
use OCP\IGroup;

interface IShare {

/**
* Get the id of the share
*
* @return string
*/
public function getId();

/**
* Set the path of this share
*
* @param File|Folder $path
* @return Share The modified object
*/
public function setPath(Node $path);

/**
* Get the path of this share for the current user
*
* @return File|Folder
*/
public function getPath();

/**
* Set the shareType
*
* @param int $shareType
* @return Share The modified object
*/
public function setShareType($shareType);

/**
* Get the shareType
*
* @return int
*/
public function getShareType();

/**
* Set the receiver of this share
*
* @param IUser|IGroup|string
* @return Share The modified object
*/
public function setSharedWith($sharedWith);

/**
* Get the receiver of this share
*
* @return IUser|IGroup|string
*/
public function getSharedWith();

/**
* Set the permissions
*
* @param int $permissions
* @return Share The modified object
*/
public function setPermissions($permissions);

/**
* Get the share permissions
*
* @return int
*/
public function getPermissions();

/**
* Set the expiration date
*
* @param \DateTime $expireDate
* @return Share The modified object
*/
public function setExpirationDate(\DateTime $expireDate);

/**
* Get the share expiration date
*
* @return \DateTime
*/
public function getExpirationDate();

/**
* Get share sharer
*
* @return IUser|string
*/
public function getSharedBy();

/**
* Get the original share owner (who owns the path)
*
* @return IUser|string
*/
public function getShareOwner();

/**
* Set the password
*
* @param string $password
*
* @return Share The modified object
*/
public function setPassword($password);

/**
* Get the token
*
* @return string
*/
public function getToken();

/**
* Get the parent it
*
* @return int
*/
public function getParent();
}

+ 6
- 2
lib/private/share20/ishareprovider.php View File

@@ -20,6 +20,8 @@
*/
namespace OC\Share20;

use OC\Share20\Exception\ShareNotFound;
use OC\Share20\Exception\BackendError;
use OCP\IUser;

interface IShareProvider {
@@ -44,8 +46,9 @@ interface IShareProvider {
* Delete a share
*
* @param Share $share
* @throws BackendError
*/
public function delete(Share $share);
public function delete(IShare $share);

/**
* Get all shares by the given user
@@ -62,7 +65,8 @@ interface IShareProvider {
* Get share by id
*
* @param int $id
* @return Share
* @return IShare
* @throws ShareNotFound
*/
public function getShareById($id);


+ 21
- 53
lib/private/share20/manager.php View File

@@ -28,8 +28,7 @@ use OCP\IUser;
use OCP\ILogger;
use OCP\Files\Folder;

use OC\Share20\Exceptions\ShareNotFoundException;
use OC\Share20\Exception\PreconditionFailed;
use OC\Share20\Exception\ShareNotFound;

/**
* This class is the communication hub for all sharing related operations.
@@ -39,12 +38,7 @@ class Manager {
/**
* @var IShareProvider[]
*/
private $shareProviders;

/**
* @var string[]
*/
private $shareTypeToProviderId;
private $defaultProvider;

/** @var IUser */
private $currentUser;
@@ -79,47 +73,7 @@ class Manager {
$this->userFolder = $userFolder;

// TEMP SOLUTION JUST TO GET STARTED
$this->shareProviders['ocdef'] = $defaultProvider;
$this->shareTypeToProviderId = [
\OCP\Share::SHARE_TYPE_USER => 'ocdef',
\OCP\Share::SHARE_TYPE_GROUP => 'ocdef',
\OCP\Share::SHARE_TYPE_LINK => 'ocdef',
];

// TODO: Get storage share provider from primary storage
}

/**
* Get a ShareProvider
*
* @param string $id
* @return IShareProvider
*/
private function getShareProvider($id) {
if (!isset($this->shareProviders[$id])) {
//Throw exception;
}

// Check if we have instanciated this provider yet
if (!($this->shareProviders[$id] instanceOf \OC\Share20\IShareProvider)) {
throw new \Exception();
}

return $this->shareProviders[$id];
}

/**
* Get shareProvider based on shareType
*
* @param int $shareType
* @return IShareProvider
*/
private function getShareProviderByType($shareType) {
if (!isset($this->shareTypeToProviderId[$shareType])) {
//Throw exception
}

return $this->getShareProvider($this->shareTypeToProviderId[$shareType]);
$this->defaultProvider = $defaultProvider;
}

/**
@@ -146,9 +100,15 @@ class Manager {
* Delete a share
*
* @param Share $share
* @throws ShareNotFound
* @throws \OC\Share20\Exception\BackendError
*/
public function deleteShare(Share $share) {
throw new \Exception();
public function deleteShare(IShare $share) {
if ($share->getId() === null) {
throw new ShareNotFound();
}

$this->defaultProvider->delete($share);
}

/**
@@ -168,10 +128,18 @@ class Manager {
* @param string $id
* @return Share
*
* @throws ShareNotFoundException
* @throws ShareNotFound
*/
public function getShareById($id) {
throw new \Exception();
$share = $this->defaultProvider->getShareById($id);

if ($share->getSharedWith() !== $this->currentUser &&
$share->getSharedBy() !== $this->currentUser &&
$share->getShareOwner() !== $this->currentUser) {
throw new ShareNotFound();
}

return $share;
}

/**

+ 58
- 48
lib/private/share20/share.php View File

@@ -24,13 +24,10 @@ use OCP\Files\Node;
use OCP\IUser;
use OCP\IGroup;

class Share {
class Share implements IShare {

/** @var string */
private $internalId;

/** @var string */
private $providerId;
private $id;

/** @var Node */
private $path;
@@ -39,7 +36,7 @@ class Share {
private $shareType;

/** @var IUser|IGroup|string */
private $shareWith;
private $sharedWith;

/** @var IUser|string */
private $sharedBy;
@@ -56,57 +53,30 @@ class Share {
/** @var string */
private $password;

/**
* Set the id of the ShareProvider
* Should only be used by the share manager
*
* @param string $providerId
* @return Share The modified object
*/
public function setProviderId($providerId) {
$this->providerId = $providerId;
return $this;
}
/** @var string */
private $token;

/**
* Get the id of the ShareProvider
*
* @return string
*/
public function getProviderId() {
return $this->providerId;
}
/** @var int */
private $parent;

/**
* Set the internal (to the provider) share id
* Should only be used by the share provider
* Set the id of the share
*
* @param string $id
* @param int id
* @return Share The modified object
*/
public function setInternalId($id) {
$this->internalId = $id;
public function setId($id) {
$this->id = $id;
return $this;
}

/**
* Get the internal (to the provider) share id
* Should only be used by the share provider
*
* @return string
*/
public function getInternalId() {
return $this->internalId;
}

/**
* Get the id of the share
*
* @return string
*/
public function getId() {
//TODO $id should be set as well as $providerId
return $this->providerId . ':' . $this->internalId;
return $this->id;
}

/**
@@ -150,23 +120,23 @@ class Share {
}

/**
* Set the shareWith
* Set the receiver of this share
*
* @param IUser|IGroup|string
* @return Share The modified object
*/
public function setShareWith($shareWith) {
$this->shareWith = $shareWith;
public function setSharedWith($sharedWith) {
$this->sharedWith = $sharedWith;
return $this;
}

/**
* Get the shareWith
* Get the receiver of this share
*
* @return IUser|IGroup|string
*/
public function getShareWith() {
return $this->shareWith;
public function getSharedWith() {
return $this->sharedWith;
}

/**
@@ -282,4 +252,44 @@ class Share {
public function getPassword($password) {
return $this->password;
}

/**
* Set the token
*
* @param string $token
* @return Share The modified object
*/
public function setToken($token) {
$this->token = $token;
return $this;
}

/**
* Get the token
*
* @return string
*/
public function getToken() {
return $this->token;
}

/**
* Set the parent id of this share
*
* @param int $parent
* @return Share The modified object
*/
public function setParent($parent) {
$this->parent = $parent;
return $this;
}

/**
* Get the parent id of this share
*
* @return int
*/
public function getParent() {
return $this->parent;
}
}

+ 543
- 0
tests/lib/share20/defaultshareprovidertest.php View File

@@ -0,0 +1,543 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace Test\Share20;

use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\IGroupManager;
use OCP\Files\Folder;
use OC\Share20\DefaultShareProvider;

class DefaultShareProviderTest extends \Test\TestCase {

/** @var IDBConnection */
protected $dbConn;

/** @var IUserManager */
protected $userManager;

/** @var IGroupManager */
protected $groupManager;

/** @var Folder */
protected $userFolder;

/** @var DefaultShareProvider */
protected $provider;

public function setUp() {
$this->dbConn = \OC::$server->getDatabaseConnection();
$this->userManager = $this->getMock('OCP\IUserManager');
$this->groupManager = $this->getMock('OCP\IGroupManager');
$this->userFolder = $this->getMock('OCP\Files\Folder');

//Empty share table
$this->dbConn->getQueryBuilder()->delete('share')->execute();

$this->provider = new DefaultShareProvider(
$this->dbConn,
$this->userManager,
$this->groupManager,
$this->userFolder
);
}

public function tearDown() {
$this->dbConn->getQueryBuilder()->delete('share')->execute();
}

/**
* @expectedException OC\Share20\Exception\ShareNotFound
*/
public function testGetShareByIdNotExist() {
$this->provider->getShareById(1);
}

public function testGetShareByIdUserShare() {
$qb = $this->dbConn->getQueryBuilder();

$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedWith = $this->getMock('OCP\IUser');
$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedWith', $sharedWith],
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);

$this->assertEquals(1, $share->getId());
$this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType());
$this->assertEquals($sharedWith, $share->getSharedWith());
$this->assertEquals($sharedBy, $share->getSharedBy());
$this->assertEquals($shareOwner, $share->getShareOwner());
$this->assertEquals($path, $share->getPath());
$this->assertEquals(13, $share->getPermissions());
$this->assertEquals(null, $share->getToken());
$this->assertEquals(null, $share->getExpirationDate());
}

public function testGetShareByIdGroupShare() {
$qb = $this->dbConn->getQueryBuilder();

$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedWith = $this->getMock('OCP\IGroup');
$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));
$this->groupManager
->expects($this->once())
->method('get')
->with('sharedWith')
->willReturn($sharedWith);

$share = $this->provider->getShareById(1);

$this->assertEquals(1, $share->getId());
$this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType());
$this->assertEquals($sharedWith, $share->getSharedWith());
$this->assertEquals($sharedBy, $share->getSharedBy());
$this->assertEquals($shareOwner, $share->getShareOwner());
$this->assertEquals($path, $share->getPath());
$this->assertEquals(13, $share->getPermissions());
$this->assertEquals(null, $share->getToken());
$this->assertEquals(null, $share->getExpirationDate());
}

public function testGetShareByIdLinkShare() {
$qb = $this->dbConn->getQueryBuilder();

$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
'token' => $qb->expr()->literal('token'),
'expiration' => $qb->expr()->literal('2000-01-02 00:00:00'),
]);
$qb->execute();

$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);

$this->assertEquals(1, $share->getId());
$this->assertEquals(\OCP\Share::SHARE_TYPE_LINK, $share->getShareType());
$this->assertEquals('sharedWith', $share->getSharedWith());
$this->assertEquals($sharedBy, $share->getSharedBy());
$this->assertEquals($shareOwner, $share->getShareOwner());
$this->assertEquals($path, $share->getPath());
$this->assertEquals(13, $share->getPermissions());
$this->assertEquals('token', $share->getToken());
$this->assertEquals(\DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 00:00:00'), $share->getExpirationDate());
}

public function testGetShareByIdRemoteShare() {
$qb = $this->dbConn->getQueryBuilder();

$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_REMOTE),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);

$this->assertEquals(1, $share->getId());
$this->assertEquals(\OCP\Share::SHARE_TYPE_REMOTE, $share->getShareType());
$this->assertEquals('sharedWith', $share->getSharedWith());
$this->assertEquals($sharedBy, $share->getSharedBy());
$this->assertEquals($shareOwner, $share->getShareOwner());
$this->assertEquals($path, $share->getPath());
$this->assertEquals(13, $share->getPermissions());
$this->assertEquals(null, $share->getToken());
$this->assertEquals(null, $share->getExpirationDate());
}

public function testDeleteSingleShare() {
$qb = $this->dbConn->getQueryBuilder();

$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedWith = $this->getMock('OCP\IUser');
$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedWith', $sharedWith],
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);
$this->provider->delete($share);

$qb = $this->dbConn->getQueryBuilder();
$qb->select('*')
->from('share');

$cursor = $qb->execute();
$result = $cursor->fetchAll();
$cursor->closeCursor();

$this->assertEmpty($result);
}

public function testDeleteSingleShareKeepOther() {
$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->values([
'id' => $qb->expr()->literal(2),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();


$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->once())
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->once())
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->once())
->method('getById')
->with(42)
->willReturn([$path]);

$sharedWith = $this->getMock('OCP\IUser');
$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedWith', $sharedWith],
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);
$this->provider->delete($share);

$qb = $this->dbConn->getQueryBuilder();
$qb->select('*')
->from('share');

$cursor = $qb->execute();
$result = $cursor->fetchAll();
$cursor->closeCursor();

$this->assertCount(1, $result);
}

public function testDeleteNestedShares() {
$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->values([
'id' => $qb->expr()->literal(1),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith'),
'uid_owner' => $qb->expr()->literal('sharedBy'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
]);
$qb->execute();

$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->values([
'id' => $qb->expr()->literal(2),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith2'),
'uid_owner' => $qb->expr()->literal('sharedBy2'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
'parent' => $qb->expr()->literal(1),
]);
$qb->execute();

$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->values([
'id' => $qb->expr()->literal(3),
'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('sharedWith2'),
'uid_owner' => $qb->expr()->literal('sharedBy2'),
'file_source' => $qb->expr()->literal(42),
'permissions' => $qb->expr()->literal(13),
'parent' => $qb->expr()->literal(2),
]);
$qb->execute();


$storage = $this->getMock('OC\Files\Storage\Storage');
$storage
->expects($this->exactly(3))
->method('getOwner')
->willReturn('shareOwner');
$path = $this->getMock('OCP\Files\Node');
$path
->expects($this->exactly(3))
->method('getStorage')
->wilLReturn($storage);
$this->userFolder
->expects($this->exactly(3))
->method('getById')
->with(42)
->willReturn([$path]);

$sharedWith = $this->getMock('OCP\IUser');
$sharedBy = $this->getMock('OCP\IUser');
$shareOwner = $this->getMock('OCP\IUser');
$this->userManager
->method('get')
->will($this->returnValueMap([
['sharedWith', $sharedWith],
['sharedBy', $sharedBy],
['shareOwner', $shareOwner],
]));

$share = $this->provider->getShareById(1);
$this->provider->delete($share);

$qb = $this->dbConn->getQueryBuilder();
$qb->select('*')
->from('share');

$cursor = $qb->execute();
$result = $cursor->fetchAll();
$cursor->closeCursor();

$this->assertEmpty($result);
}

/**
* @expectedException \OC\Share20\Exception\BackendError
*/
public function testDeleteFails() {
$share = $this->getMock('OC\Share20\IShare');
$expr = $this->getMock('OCP\DB\QueryBuilder\IExpressionBuilder');
$qb = $this->getMock('OCP\DB\QueryBuilder\IQueryBuilder');
$qb->expects($this->once())
->method('delete')
->will($this->returnSelf());
$qb->expects($this->once())
->method('expr')
->willReturn($expr);
$qb->expects($this->once())
->method('where')
->will($this->returnSelf());
$qb->expects($this->once())
->method('setParameter')
->will($this->returnSelf());
$qb->expects($this->once())
->method('execute')
->will($this->throwException(new \Exception));

$db = $this->getMock('OCP\IDBConnection');
$db->expects($this->once())
->method('getQueryBuilder')
->with()
->willReturn($qb);

$provider = $this->getMockBuilder('OC\Share20\DefaultShareProvider')
->setConstructorArgs([
$db,
$this->userManager,
$this->groupManager,
$this->userFolder,
]
)
->setMethods(['deleteChildren'])
->getMock();
$provider
->expects($this->once())
->method('deleteChildren')
->with($share);

$provider->delete($share);
}

}

+ 198
- 0
tests/lib/share20/managertest.php View File

@@ -0,0 +1,198 @@
<?php
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace Test\Share20;

use OC\Share20\Manager;
use OC\Share20\Exception;


use OCP\IUser;
use OCP\IUserManager;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IAppConfig;
use OCP\Files\Folder;
use OCP\Share20\IShareProvider;

class ManagerTest extends \Test\TestCase {

/** @var Manager */
protected $manager;

/** @var IUser */
protected $user;

/** @var IUserManager */
protected $userManager;

/** @var IGroupManager */
protected $groupManager;

/** @var ILogger */
protected $logger;

/** @var IAppConfig */
protected $appConfig;

/** @var Folder */
protected $userFolder;

/** @var IShareProvider */
protected $defaultProvider;

public function setUp() {
$this->user = $this->getMock('\OCP\IUser');
$this->userManager = $this->getMock('\OCP\IUserManager');
$this->groupManager = $this->getMock('\OCP\IGroupManager');
$this->logger = $this->getMock('\OCP\ILogger');
$this->appConfig = $this->getMock('\OCP\IAppConfig');
$this->userFolder = $this->getMock('\OCP\Files\Folder');
$this->defaultProvider = $this->getMock('\OC\Share20\IShareProvider');

$this->manager = new Manager(
$this->user,
$this->userManager,
$this->groupManager,
$this->logger,
$this->appConfig,
$this->userFolder,
$this->defaultProvider
);
}

/**
* @expectedException OC\Share20\Exception\ShareNotFound
*/
public function testDeleteNoShareId() {
$share = $this->getMock('\OC\Share20\IShare');

$share
->expects($this->once())
->method('getId')
->with()
->willReturn(null);

$this->manager->deleteShare($share);
}

public function testDelete() {
$share = $this->getMock('\OC\Share20\IShare');

$share
->expects($this->once())
->method('getId')
->with()
->willReturn(42);
$this->defaultProvider
->expects($this->once())
->method('delete')
->with($share);

$this->manager->deleteShare($share);
}

/**
* @expectedException OC\Share20\Exception\ShareNotFound
*/
public function testGetShareByIdNotFoundInBackend() {
$this->defaultProvider
->expects($this->once())
->method('getShareById')
->with(42)
->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));

$this->manager->getShareById(42);
}

/**
* @expectedException OC\Share20\Exception\ShareNotFound
*/
public function testGetShareByIdNotAuthorized() {
$otherUser1 = $this->getMock('\OCP\IUser');
$otherUser2 = $this->getMock('\OCP\IUser');
$otherUser3 = $this->getMock('\OCP\IUser');

$share = $this->getMock('\OC\Share20\IShare');
$share
->expects($this->once())
->method('getSharedWith')
->with()
->willReturn($otherUser1);
$share
->expects($this->once())
->method('getSharedBy')
->with()
->willReturn($otherUser2);
$share
->expects($this->once())
->method('getShareOwner')
->with()
->willReturn($otherUser3);

$this->defaultProvider
->expects($this->once())
->method('getShareById')
->with(42)
->willReturn($share);

$this->manager->getShareById(42);
}

public function dataGetShareById() {
return [
['getSharedWith'],
['getSharedBy'],
['getShareOwner'],
];
}

/**
* @dataProvider dataGetShareById
*/
public function testGetShareById($currentUserIs) {
$otherUser1 = $this->getMock('\OCP\IUser');
$otherUser2 = $this->getMock('\OCP\IUser');
$otherUser3 = $this->getMock('\OCP\IUser');

$share = $this->getMock('\OC\Share20\IShare');
$share
->method('getSharedWith')
->with()
->willReturn($currentUserIs === 'getSharedWith' ? $this->user : $otherUser1);
$share
->method('getSharedBy')
->with()
->willReturn($currentUserIs === 'getSharedBy' ? $this->user : $otherUser2);
$share
->method('getShareOwner')
->with()
->willReturn($currentUserIs === 'getShareOwner' ? $this->user : $otherUser3);

$this->defaultProvider
->expects($this->once())
->method('getShareById')
->with(42)
->willReturn($share);

$this->assertEquals($share, $this->manager->getShareById(42));
}
}

Loading…
Cancel
Save