mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #24603 from owncloud/federated_reshare
flat federated re-share
This commit is contained in:
commit
5ba1add03c
29 changed files with 1607 additions and 471 deletions
|
|
@ -20,4 +20,21 @@
|
|||
*/
|
||||
|
||||
$app = new \OCA\FederatedFileSharing\AppInfo\Application('federatedfilesharing');
|
||||
|
||||
use OCA\FederatedFileSharing\Notifier;
|
||||
|
||||
$l = \OC::$server->getL10N('files_sharing');
|
||||
|
||||
$app->registerSettings();
|
||||
|
||||
$manager = \OC::$server->getNotificationManager();
|
||||
$manager->registerNotifier(function() {
|
||||
return new Notifier(
|
||||
\OC::$server->getL10NFactory()
|
||||
);
|
||||
}, function() use ($l) {
|
||||
return [
|
||||
'id' => 'files_sharing',
|
||||
'name' => $l->t('Federated sharing'),
|
||||
];
|
||||
});
|
||||
|
|
|
|||
41
apps/federatedfilesharing/appinfo/database.xml
Normal file
41
apps/federatedfilesharing/appinfo/database.xml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!--
|
||||
Keep a mapping of the share ID stored in the local oc_share table
|
||||
and the share ID stored in the remote servers oc_share table.
|
||||
This is needed in order to send updates in both directions between
|
||||
the servers (e.g. permissions change, unshare,...)
|
||||
-->
|
||||
|
||||
<database>
|
||||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
<charset>utf8</charset>
|
||||
<table>
|
||||
<name>*dbprefix*federated_reshares</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>share_id</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>remote_id</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
<comments>share ID at the remote server</comments>
|
||||
</field>
|
||||
<index>
|
||||
<name>share_id_index</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>share_id</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
</database>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<description>Provide federated file sharing across ownCloud servers</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Bjoern Schiessle, Roeland Jago Douma</author>
|
||||
<version>0.2.0</version>
|
||||
<version>0.3.0</version>
|
||||
<namespace>FederatedFileSharing</namespace>
|
||||
<category>other</category>
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ class Application extends App {
|
|||
\OC::$server->getL10N('federatedfilesharing'),
|
||||
\OC::$server->getLogger(),
|
||||
\OC::$server->getLazyRootFolder(),
|
||||
\OC::$server->getConfig()
|
||||
\OC::$server->getConfig(),
|
||||
\OC::$server->getUserManager()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,26 +32,26 @@ use OCP\BackgroundJob\IJobList;
|
|||
use OCP\ILogger;
|
||||
|
||||
/**
|
||||
* Class UnShare
|
||||
* Class RetryJob
|
||||
*
|
||||
* Background job to re-send the un-share notification to the remote server in
|
||||
* Background job to re-send update of federated re-shares to the remote server in
|
||||
* case the server was not available on the first try
|
||||
*
|
||||
* @package OCA\FederatedFileSharing\BackgroundJob
|
||||
*/
|
||||
class UnShare extends Job {
|
||||
class RetryJob extends Job {
|
||||
|
||||
/** @var bool */
|
||||
private $retainJob = true;
|
||||
|
||||
|
||||
/** @var Notifications */
|
||||
private $notifications;
|
||||
|
||||
/** @var int max number of attempts to send the un-share request */
|
||||
private $maxTry = 10;
|
||||
/** @var int max number of attempts to send the request */
|
||||
private $maxTry = 20;
|
||||
|
||||
/** @var int how much time should be between two tries (12 hours) */
|
||||
private $interval = 43200;
|
||||
/** @var int how much time should be between two tries (10 minutes) */
|
||||
private $interval = 600;
|
||||
|
||||
/**
|
||||
* UnShare constructor.
|
||||
|
|
@ -77,7 +77,7 @@ class UnShare extends Job {
|
|||
\OC::$server->getJobList()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,12 +99,14 @@ class UnShare extends Job {
|
|||
|
||||
protected function run($argument) {
|
||||
$remote = $argument['remote'];
|
||||
$id = (int)$argument['id'];
|
||||
$remoteId = $argument['remoteId'];
|
||||
$token = $argument['token'];
|
||||
$action = $argument['action'];
|
||||
$data = json_decode($argument['data'], true);
|
||||
$try = (int)$argument['try'] + 1;
|
||||
|
||||
$result = $this->notifications->sendRemoteUnShare($remote, $id, $token, $try);
|
||||
|
||||
$result = $this->notifications->sendUpdateToRemote($remote, $remoteId, $token, $action, $data, $try);
|
||||
|
||||
if ($result === true || $try > $this->maxTry) {
|
||||
$this->retainJob = false;
|
||||
}
|
||||
|
|
@ -117,11 +119,13 @@ class UnShare extends Job {
|
|||
* @param array $argument
|
||||
*/
|
||||
protected function reAddJob(IJobList $jobList, array $argument) {
|
||||
$jobList->add('OCA\FederatedFileSharing\BackgroundJob\UnShare',
|
||||
$jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
|
||||
[
|
||||
'remote' => $argument['remote'],
|
||||
'id' => $argument['id'],
|
||||
'remoteId' => $argument['remoteId'],
|
||||
'token' => $argument['token'],
|
||||
'data' => $argument['data'],
|
||||
'action' => $argument['action'],
|
||||
'try' => (int)$argument['try'] + 1,
|
||||
'lastRun' => time()
|
||||
]
|
||||
|
|
@ -25,10 +25,10 @@ namespace OCA\FederatedFileSharing;
|
|||
|
||||
use OC\Share20\Share;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\IShare;
|
||||
use OCP\Share\IShareProvider;
|
||||
use OC\Share20\Exception\InvalidShare;
|
||||
|
|
@ -70,6 +70,12 @@ class FederatedShareProvider implements IShareProvider {
|
|||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
/** @var string */
|
||||
private $externalShareTable = 'share_external';
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* DefaultShareProvider constructor.
|
||||
*
|
||||
|
|
@ -81,6 +87,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
* @param ILogger $logger
|
||||
* @param IRootFolder $rootFolder
|
||||
* @param IConfig $config
|
||||
* @param IUserManager $userManager
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $connection,
|
||||
|
|
@ -90,7 +97,8 @@ class FederatedShareProvider implements IShareProvider {
|
|||
IL10N $l10n,
|
||||
ILogger $logger,
|
||||
IRootFolder $rootFolder,
|
||||
IConfig $config
|
||||
IConfig $config,
|
||||
IUserManager $userManager
|
||||
) {
|
||||
$this->dbConnection = $connection;
|
||||
$this->addressHandler = $addressHandler;
|
||||
|
|
@ -100,6 +108,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
$this->logger = $logger;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->config = $config;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,10 +133,9 @@ class FederatedShareProvider implements IShareProvider {
|
|||
$shareWith = $share->getSharedWith();
|
||||
$itemSource = $share->getNodeId();
|
||||
$itemType = $share->getNodeType();
|
||||
$uidOwner = $share->getShareOwner();
|
||||
$permissions = $share->getPermissions();
|
||||
$sharedBy = $share->getSharedBy();
|
||||
|
||||
|
||||
/*
|
||||
* Check if file is not already shared with the remote user
|
||||
*/
|
||||
|
|
@ -151,31 +159,136 @@ class FederatedShareProvider implements IShareProvider {
|
|||
throw new \Exception($message_t);
|
||||
}
|
||||
|
||||
$token = $this->tokenHandler->generateToken();
|
||||
$share->setSharedWith($user . '@' . $remote);
|
||||
|
||||
$shareWith = $user . '@' . $remote;
|
||||
try {
|
||||
$remoteShare = $this->getShareFromExternalShareTable($share);
|
||||
} catch (ShareNotFound $e) {
|
||||
$remoteShare = null;
|
||||
}
|
||||
|
||||
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
|
||||
if ($remoteShare) {
|
||||
try {
|
||||
$uidOwner = $remoteShare['owner'] . '@' . $remoteShare['remote'];
|
||||
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, 'tmp_token_' . time());
|
||||
$share->setId($shareId);
|
||||
list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
|
||||
// remote share was create successfully if we get a valid token as return
|
||||
$send = is_string($token) && $token !== '';
|
||||
} catch (\Exception $e) {
|
||||
// fall back to old re-share behavior if the remote server
|
||||
// doesn't support flat re-shares (was introduced with ownCloud 9.1)
|
||||
$this->removeShareFromTable($share);
|
||||
$shareId = $this->createFederatedShare($share);
|
||||
}
|
||||
if ($send) {
|
||||
$this->updateSuccessfulReshare($shareId, $token);
|
||||
$this->storeRemoteId($shareId, $remoteId);
|
||||
} else {
|
||||
$this->removeShareFromTable($share);
|
||||
$message_t = $this->l->t('File is already shared with %s', [$shareWith]);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
|
||||
$send = $this->notifications->sendRemoteShare(
|
||||
$token,
|
||||
$shareWith,
|
||||
$share->getNode()->getName(),
|
||||
$shareId,
|
||||
$share->getSharedBy()
|
||||
);
|
||||
} else {
|
||||
$shareId = $this->createFederatedShare($share);
|
||||
}
|
||||
|
||||
$data = $this->getRawShare($shareId);
|
||||
$share = $this->createShare($data);
|
||||
return $this->createShareObject($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* create federated share and inform the recipient
|
||||
*
|
||||
* @param IShare $share
|
||||
* @return int
|
||||
* @throws ShareNotFound
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function createFederatedShare(IShare $share) {
|
||||
$token = $this->tokenHandler->generateToken();
|
||||
$shareId = $this->addShareToDB(
|
||||
$share->getNodeId(),
|
||||
$share->getNodeType(),
|
||||
$share->getSharedWith(),
|
||||
$share->getSharedBy(),
|
||||
$share->getShareOwner(),
|
||||
$share->getPermissions(),
|
||||
$token
|
||||
);
|
||||
$sharedByFederatedId = $share->getSharedBy();
|
||||
if ($this->userManager->userExists($sharedByFederatedId)) {
|
||||
$sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL();
|
||||
}
|
||||
$send = $this->notifications->sendRemoteShare(
|
||||
$token,
|
||||
$share->getSharedWith(),
|
||||
$share->getNode()->getName(),
|
||||
$shareId,
|
||||
$share->getShareOwner(),
|
||||
$share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(),
|
||||
$share->getSharedBy(),
|
||||
$sharedByFederatedId
|
||||
);
|
||||
|
||||
if ($send === false) {
|
||||
$this->delete($share);
|
||||
$data = $this->getRawShare($shareId);
|
||||
$share = $this->createShareObject($data);
|
||||
$this->removeShareFromTable($share);
|
||||
$message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.',
|
||||
[$share->getNode()->getName(), $shareWith]);
|
||||
[$share->getNode()->getName(), $share->getSharedWith()]);
|
||||
throw new \Exception($message_t);
|
||||
}
|
||||
|
||||
return $share;
|
||||
return $shareId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $shareWith
|
||||
* @param IShare $share
|
||||
* @param string $shareId internal share Id
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
|
||||
|
||||
$remoteShare = $this->getShareFromExternalShareTable($share);
|
||||
$token = $remoteShare['share_token'];
|
||||
$remoteId = $remoteShare['remote_id'];
|
||||
$remote = $remoteShare['remote'];
|
||||
|
||||
list($token, $remoteId) = $this->notifications->requestReShare(
|
||||
$token,
|
||||
$remoteId,
|
||||
$shareId,
|
||||
$remote,
|
||||
$shareWith,
|
||||
$share->getPermissions()
|
||||
);
|
||||
|
||||
return [$token, $remoteId];
|
||||
}
|
||||
|
||||
/**
|
||||
* get federated share from the share_external table but exclude mounted link shares
|
||||
*
|
||||
* @param IShare $share
|
||||
* @return array
|
||||
* @throws ShareNotFound
|
||||
*/
|
||||
protected function getShareFromExternalShareTable(IShare $share) {
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->select('*')->from($this->externalShareTable)
|
||||
->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
|
||||
->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
|
||||
$result = $query->execute()->fetchAll();
|
||||
|
||||
if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
throw new ShareNotFound('share not found in share_external table');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -234,9 +347,85 @@ class FederatedShareProvider implements IShareProvider {
|
|||
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
|
||||
->execute();
|
||||
|
||||
// send the updated permission to the owner/initiator, if they are not the same
|
||||
if ($share->getShareOwner() !== $share->getSharedBy()) {
|
||||
$this->sendPermissionUpdate($share);
|
||||
}
|
||||
|
||||
return $share;
|
||||
}
|
||||
|
||||
/**
|
||||
* send the updated permission to the owner/initiator, if they are not the same
|
||||
*
|
||||
* @param IShare $share
|
||||
* @throws ShareNotFound
|
||||
* @throws \OC\HintException
|
||||
*/
|
||||
protected function sendPermissionUpdate(IShare $share) {
|
||||
$remoteId = $this->getRemoteId($share);
|
||||
// if the local user is the owner we send the permission change to the initiator
|
||||
if ($this->userManager->userExists($share->getShareOwner())) {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
|
||||
} else { // ... if not we send the permission change to the owner
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
|
||||
}
|
||||
$this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* update successful reShare with the correct token
|
||||
*
|
||||
* @param int $shareId
|
||||
* @param string $token
|
||||
*/
|
||||
protected function updateSuccessfulReShare($shareId, $token) {
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->update('share')
|
||||
->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
|
||||
->set('token', $query->createNamedParameter($token))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* store remote ID in federated reShare table
|
||||
*
|
||||
* @param $shareId
|
||||
* @param $remoteId
|
||||
*/
|
||||
public function storeRemoteId($shareId, $remoteId) {
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->insert('federated_reshares')
|
||||
->values(
|
||||
[
|
||||
'share_id' => $query->createNamedParameter($shareId),
|
||||
'remote_id' => $query->createNamedParameter($remoteId),
|
||||
]
|
||||
);
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* get share ID on remote server for federated re-shares
|
||||
*
|
||||
* @param IShare $share
|
||||
* @return int
|
||||
* @throws ShareNotFound
|
||||
*/
|
||||
public function getRemoteId(IShare $share) {
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->select('remote_id')->from('federated_reshares')
|
||||
->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
|
||||
$data = $query->execute()->fetch();
|
||||
|
||||
if (!is_array($data) || !isset($data['remote_id'])) {
|
||||
throw new ShareNotFound();
|
||||
}
|
||||
|
||||
return (int)$data['remote_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
|
@ -266,7 +455,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
|
||||
$cursor = $qb->execute();
|
||||
while($data = $cursor->fetch()) {
|
||||
$children[] = $this->createShare($data);
|
||||
$children[] = $this->createShareObject($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
|
|
@ -274,18 +463,77 @@ class FederatedShareProvider implements IShareProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete a share
|
||||
* Delete a share (owner unShares the file)
|
||||
*
|
||||
* @param IShare $share
|
||||
*/
|
||||
public function delete(IShare $share) {
|
||||
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
|
||||
|
||||
$isOwner = false;
|
||||
|
||||
// if the local user is the owner we can send the unShare request directly...
|
||||
if ($this->userManager->userExists($share->getShareOwner())) {
|
||||
$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
|
||||
$this->revokeShare($share, true);
|
||||
$isOwner = true;
|
||||
} else { // ... if not we need to correct ID for the unShare request
|
||||
$remoteId = $this->getRemoteId($share);
|
||||
$this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
|
||||
$this->revokeShare($share, false);
|
||||
}
|
||||
|
||||
// send revoke notification to the other user, if initiator and owner are not the same user
|
||||
if ($share->getShareOwner() !== $share->getSharedBy()) {
|
||||
$remoteId = $this->getRemoteId($share);
|
||||
if ($isOwner) {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
|
||||
} else {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
|
||||
}
|
||||
$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
|
||||
}
|
||||
|
||||
$this->removeShareFromTable($share);
|
||||
}
|
||||
|
||||
/**
|
||||
* in case of a re-share we need to send the other use (initiator or owner)
|
||||
* a message that the file was unshared
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param bool $isOwner the user can either be the owner or the user who re-sahred it
|
||||
* @throws ShareNotFound
|
||||
* @throws \OC\HintException
|
||||
*/
|
||||
protected function revokeShare($share, $isOwner) {
|
||||
// also send a unShare request to the initiator, if this is a different user than the owner
|
||||
if ($share->getShareOwner() !== $share->getSharedBy()) {
|
||||
if ($isOwner) {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
|
||||
} else {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
|
||||
}
|
||||
$remoteId = $this->getRemoteId($share);
|
||||
$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove share from table
|
||||
*
|
||||
* @param IShare $share
|
||||
*/
|
||||
public function removeShareFromTable(IShare $share) {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
|
||||
$qb->execute();
|
||||
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
|
||||
$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
|
||||
$qb->delete('federated_reshares')
|
||||
->where($qb->expr()->eq('share_id', $qb->createNamedParameter($share->getId())));
|
||||
$qb->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -348,7 +596,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
$cursor = $qb->execute();
|
||||
$shares = [];
|
||||
while($data = $cursor->fetch()) {
|
||||
$shares[] = $this->createShare($data);
|
||||
$shares[] = $this->createShareObject($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
|
|
@ -375,7 +623,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
}
|
||||
|
||||
try {
|
||||
$share = $this->createShare($data);
|
||||
$share = $this->createShareObject($data);
|
||||
} catch (InvalidShare $e) {
|
||||
throw new ShareNotFound();
|
||||
}
|
||||
|
|
@ -400,7 +648,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
|
||||
$shares = [];
|
||||
while($data = $cursor->fetch()) {
|
||||
$shares[] = $this->createShare($data);
|
||||
$shares[] = $this->createShareObject($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
|
|
@ -439,7 +687,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
$cursor = $qb->execute();
|
||||
|
||||
while($data = $cursor->fetch()) {
|
||||
$shares[] = $this->createShare($data);
|
||||
$shares[] = $this->createShareObject($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
|
|
@ -470,7 +718,7 @@ class FederatedShareProvider implements IShareProvider {
|
|||
}
|
||||
|
||||
try {
|
||||
$share = $this->createShare($data);
|
||||
$share = $this->createShareObject($data);
|
||||
} catch (InvalidShare $e) {
|
||||
throw new ShareNotFound();
|
||||
}
|
||||
|
|
@ -512,9 +760,9 @@ class FederatedShareProvider implements IShareProvider {
|
|||
* @throws InvalidShare
|
||||
* @throws ShareNotFound
|
||||
*/
|
||||
private function createShare($data) {
|
||||
private function createShareObject($data) {
|
||||
|
||||
$share = new Share($this->rootFolder);
|
||||
$share = new Share($this->rootFolder, $this->userManager);
|
||||
$share->setId((int)$data['id'])
|
||||
->setShareType((int)$data['share_type'])
|
||||
->setPermissions((int)$data['permissions'])
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\FederatedFileSharing;
|
||||
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Http\Client\IClientService;
|
||||
|
||||
|
|
@ -67,9 +68,14 @@ class Notifications {
|
|||
* @param string $name
|
||||
* @param int $remote_id
|
||||
* @param string $owner
|
||||
* @param string $ownerFederatedId
|
||||
* @param string $sharedBy
|
||||
* @param string $sharedByFederatedId
|
||||
* @return bool
|
||||
* @throws \OC\HintException
|
||||
* @throws \OC\ServerNotAvailableException
|
||||
*/
|
||||
public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) {
|
||||
public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId) {
|
||||
|
||||
list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
|
||||
|
||||
|
|
@ -83,6 +89,9 @@ class Notifications {
|
|||
'name' => $name,
|
||||
'remoteId' => $remote_id,
|
||||
'owner' => $owner,
|
||||
'ownerFederatedId' => $ownerFederatedId,
|
||||
'sharedBy' => $sharedBy,
|
||||
'sharedByFederatedId' => $sharedByFederatedId,
|
||||
'remote' => $local,
|
||||
);
|
||||
|
||||
|
|
@ -100,35 +109,143 @@ class Notifications {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ask owner to re-share the file with the given user
|
||||
*
|
||||
* @param string $token
|
||||
* @param int $id remote Id
|
||||
* @param int $shareId internal share Id
|
||||
* @param string $remote remote address of the owner
|
||||
* @param string $shareWith
|
||||
* @param int $permission
|
||||
* @return bool
|
||||
* @throws \OC\HintException
|
||||
* @throws \OC\ServerNotAvailableException
|
||||
*/
|
||||
public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission) {
|
||||
|
||||
$fields = array(
|
||||
'shareWith' => $shareWith,
|
||||
'token' => $token,
|
||||
'permission' => $permission,
|
||||
'remoteId' => $shareId
|
||||
);
|
||||
|
||||
$url = $this->addressHandler->removeProtocolFromUrl($remote);
|
||||
$result = $this->tryHttpPostToShareEndpoint(rtrim($url, '/'), '/' . $id . '/reshare', $fields);
|
||||
$status = json_decode($result['result'], true);
|
||||
|
||||
$httpRequestSuccessful = $result['success'];
|
||||
$ocsCallSuccessful = $status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200;
|
||||
$validToken = isset($status['ocs']['data']['token']) && is_string($status['ocs']['data']['token']);
|
||||
$validRemoteId = isset($status['ocs']['data']['remoteId']);
|
||||
|
||||
if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
|
||||
return [
|
||||
$status['ocs']['data']['token'],
|
||||
(int)$status['ocs']['data']['remoteId']
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* send server-to-server unshare to remote server
|
||||
*
|
||||
* @param string $remote url
|
||||
* @param int $id share id
|
||||
* @param string $token
|
||||
* @param int $try how often did we already tried to send the un-share request
|
||||
* @return bool
|
||||
*/
|
||||
public function sendRemoteUnShare($remote, $id, $token, $try = 0) {
|
||||
$url = rtrim($remote, '/');
|
||||
$fields = array('token' => $token, 'format' => 'json');
|
||||
$url = $this->addressHandler->removeProtocolFromUrl($url);
|
||||
$result = $this->tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
|
||||
public function sendRemoteUnShare($remote, $id, $token) {
|
||||
$this->sendUpdateToRemote($remote, $id, $token, 'unshare');
|
||||
}
|
||||
|
||||
/**
|
||||
* send server-to-server unshare to remote server
|
||||
*
|
||||
* @param string $remote url
|
||||
* @param int $id share id
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
public function sendRevokeShare($remote, $id, $token) {
|
||||
$this->sendUpdateToRemote($remote, $id, $token, 'revoke');
|
||||
}
|
||||
|
||||
/**
|
||||
* send notification to remote server if the permissions was changed
|
||||
*
|
||||
* @param string $remote
|
||||
* @param int $remoteId
|
||||
* @param string $token
|
||||
* @param int $permissions
|
||||
* @return bool
|
||||
*/
|
||||
public function sendPermissionChange($remote, $remoteId, $token, $permissions) {
|
||||
$this->sendUpdateToRemote($remote, $remoteId, $token, 'permissions', ['permissions' => $permissions]);
|
||||
}
|
||||
|
||||
/**
|
||||
* forward accept reShare to remote server
|
||||
*
|
||||
* @param string $remote
|
||||
* @param int $remoteId
|
||||
* @param string $token
|
||||
*/
|
||||
public function sendAcceptShare($remote, $remoteId, $token) {
|
||||
$this->sendUpdateToRemote($remote, $remoteId, $token, 'accept');
|
||||
}
|
||||
|
||||
/**
|
||||
* forward decline reShare to remote server
|
||||
*
|
||||
* @param string $remote
|
||||
* @param int $remoteId
|
||||
* @param string $token
|
||||
*/
|
||||
public function sendDeclineShare($remote, $remoteId, $token) {
|
||||
$this->sendUpdateToRemote($remote, $remoteId, $token, 'decline');
|
||||
}
|
||||
|
||||
/**
|
||||
* inform remote server whether server-to-server share was accepted/declined
|
||||
*
|
||||
* @param string $remote
|
||||
* @param string $token
|
||||
* @param int $remoteId Share id on the remote host
|
||||
* @param string $action possible actions: accept, decline, unshare, revoke, permissions
|
||||
* @param array $data
|
||||
* @param int $try
|
||||
* @return boolean
|
||||
*/
|
||||
public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) {
|
||||
|
||||
$fields = array('token' => $token);
|
||||
foreach ($data as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
$url = $this->addressHandler->removeProtocolFromUrl($remote);
|
||||
$result = $this->tryHttpPostToShareEndpoint(rtrim($url, '/'), '/' . $remoteId . '/' . $action, $fields);
|
||||
$status = json_decode($result['result'], true);
|
||||
|
||||
if ($result['success'] &&
|
||||
($status['ocs']['meta']['statuscode'] === 100 ||
|
||||
if ($result['success'] &&
|
||||
($status['ocs']['meta']['statuscode'] === 100 ||
|
||||
$status['ocs']['meta']['statuscode'] === 200
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
} elseif ($try === 0) {
|
||||
// only add new job on first try
|
||||
$this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\UnShare',
|
||||
$this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
|
||||
[
|
||||
'remote' => $remote,
|
||||
'id' => $id,
|
||||
'remoteId' => $remoteId,
|
||||
'token' => $token,
|
||||
'action' => $action,
|
||||
'data' => json_encode($data),
|
||||
'try' => $try,
|
||||
'lastRun' => $this->getTimestamp()
|
||||
]
|
||||
|
|
@ -138,6 +255,7 @@ class Notifications {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return current timestamp
|
||||
*
|
||||
|
|
@ -154,6 +272,7 @@ class Notifications {
|
|||
* @param string $urlSuffix
|
||||
* @param array $fields post parameters
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
|
||||
$client = $this->httpClientService->newClient();
|
||||
|
|
@ -174,6 +293,12 @@ class Notifications {
|
|||
$result['success'] = true;
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
// if flat re-sharing is not supported by the remote server
|
||||
// we re-throw the exception and fall back to the old behaviour.
|
||||
// (flat re-shares has been introduced in ownCloud 9.1)
|
||||
if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
|
||||
throw $e;
|
||||
}
|
||||
$try++;
|
||||
$protocol = 'http://';
|
||||
}
|
||||
|
|
|
|||
580
apps/federatedfilesharing/lib/RequestHandler.php
Normal file
580
apps/federatedfilesharing/lib/RequestHandler.php
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Arthur Schiwon <blizzz@owncloud.com>
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, 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\FederatedFileSharing;
|
||||
|
||||
use OCA\Files_Sharing\Activity;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\Constants;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share;
|
||||
|
||||
/**
|
||||
* Class RequestHandler
|
||||
*
|
||||
* handles OCS Request to the federated share API
|
||||
*
|
||||
* @package OCA\FederatedFileSharing\API
|
||||
*/
|
||||
class RequestHandler {
|
||||
|
||||
/** @var FederatedShareProvider */
|
||||
private $federatedShareProvider;
|
||||
|
||||
/** @var IDBConnection */
|
||||
private $connection;
|
||||
|
||||
/** @var Share\IManager */
|
||||
private $shareManager;
|
||||
|
||||
/** @var IRequest */
|
||||
private $request;
|
||||
|
||||
/** @var Notifications */
|
||||
private $notifications;
|
||||
|
||||
/** @var AddressHandler */
|
||||
private $addressHandler;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var string */
|
||||
private $shareTable = 'share';
|
||||
|
||||
/**
|
||||
* Server2Server constructor.
|
||||
*
|
||||
* @param FederatedShareProvider $federatedShareProvider
|
||||
* @param IDBConnection $connection
|
||||
* @param Share\IManager $shareManager
|
||||
* @param IRequest $request
|
||||
* @param Notifications $notifications
|
||||
* @param AddressHandler $addressHandler
|
||||
* @param IUserManager $userManager
|
||||
*/
|
||||
public function __construct(FederatedShareProvider $federatedShareProvider,
|
||||
IDBConnection $connection,
|
||||
Share\IManager $shareManager,
|
||||
IRequest $request,
|
||||
Notifications $notifications,
|
||||
AddressHandler $addressHandler,
|
||||
IUserManager $userManager
|
||||
) {
|
||||
$this->federatedShareProvider = $federatedShareProvider;
|
||||
$this->connection = $connection;
|
||||
$this->shareManager = $shareManager;
|
||||
$this->request = $request;
|
||||
$this->notifications = $notifications;
|
||||
$this->addressHandler = $addressHandler;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function createShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled(true)) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
$name = isset($_POST['name']) ? $_POST['name'] : null;
|
||||
$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
|
||||
$sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
|
||||
$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
|
||||
$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
|
||||
$sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
|
||||
$ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
|
||||
|
||||
if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
|
||||
|
||||
if(!\OCP\Util::isValidFileName($name)) {
|
||||
return new \OC_OCS_Result(null, 400, 'The mountpoint name contains invalid characters.');
|
||||
}
|
||||
|
||||
// FIXME this should be a method in the user management instead
|
||||
\OCP\Util::writeLog('files_sharing', 'shareWith before, ' . $shareWith, \OCP\Util::DEBUG);
|
||||
\OCP\Util::emitHook(
|
||||
'\OCA\Files_Sharing\API\Server2Server',
|
||||
'preLoginNameUsedAsUserName',
|
||||
array('uid' => &$shareWith)
|
||||
);
|
||||
\OCP\Util::writeLog('files_sharing', 'shareWith after, ' . $shareWith, \OCP\Util::DEBUG);
|
||||
|
||||
if (!\OCP\User::userExists($shareWith)) {
|
||||
return new \OC_OCS_Result(null, 400, 'User does not exists');
|
||||
}
|
||||
|
||||
\OC_Util::setupFS($shareWith);
|
||||
|
||||
$discoveryManager = new DiscoveryManager(
|
||||
\OC::$server->getMemCacheFactory(),
|
||||
\OC::$server->getHTTPClientService()
|
||||
);
|
||||
$externalManager = new \OCA\Files_Sharing\External\Manager(
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC\Files\Filesystem::getMountManager(),
|
||||
\OC\Files\Filesystem::getLoader(),
|
||||
\OC::$server->getHTTPHelper(),
|
||||
\OC::$server->getNotificationManager(),
|
||||
$discoveryManager,
|
||||
$shareWith
|
||||
);
|
||||
|
||||
try {
|
||||
$externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
|
||||
$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
|
||||
|
||||
if ($ownerFederatedId === null) {
|
||||
$ownerFederatedId = $owner . '@' . $this->cleanupRemote($remote);
|
||||
}
|
||||
// if the owner of the share and the initiator are the same user
|
||||
// we also complete the federated share ID for the initiator
|
||||
if ($sharedByFederatedId === null && $owner === $sharedBy) {
|
||||
$sharedByFederatedId = $ownerFederatedId;
|
||||
}
|
||||
|
||||
\OC::$server->getActivityManager()->publishActivity(
|
||||
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($ownerFederatedId, trim($name, '/')), '', array(),
|
||||
'', '', $shareWith, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_LOW);
|
||||
|
||||
$urlGenerator = \OC::$server->getURLGenerator();
|
||||
|
||||
$notificationManager = \OC::$server->getNotificationManager();
|
||||
$notification = $notificationManager->createNotification();
|
||||
$notification->setApp('files_sharing')
|
||||
->setUser($shareWith)
|
||||
->setDateTime(new \DateTime())
|
||||
->setObject('remote_share', $shareId)
|
||||
->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
|
||||
|
||||
$declineAction = $notification->createAction();
|
||||
$declineAction->setLabel('decline')
|
||||
->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
|
||||
$notification->addAction($declineAction);
|
||||
|
||||
$acceptAction = $notification->createAction();
|
||||
$acceptAction->setLabel('accept')
|
||||
->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
|
||||
$notification->addAction($acceptAction);
|
||||
|
||||
$notificationManager->notify($notification);
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
} catch (\Exception $e) {
|
||||
\OCP\Util::writeLog('files_sharing', 'server can not add remote share, ' . $e->getMessage(), \OCP\Util::ERROR);
|
||||
return new \OC_OCS_Result(null, 500, 'internal server error, was not able to add share from ' . $remote);
|
||||
}
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result(null, 400, 'server can not add remote share, missing parameter');
|
||||
}
|
||||
|
||||
/**
|
||||
* create re-share on behalf of another user
|
||||
*
|
||||
* @param $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function reShare($params) {
|
||||
|
||||
$id = isset($params['id']) ? (int)$params['id'] : null;
|
||||
$token = $this->request->getParam('token', null);
|
||||
$shareWith = $this->request->getParam('shareWith', null);
|
||||
$permission = (int)$this->request->getParam('permission', null);
|
||||
$remoteId = (int)$this->request->getParam('remoteId', null);
|
||||
|
||||
if ($id === null ||
|
||||
$token === null ||
|
||||
$shareWith === null ||
|
||||
$permission === null ||
|
||||
$remoteId === null
|
||||
) {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$share = $this->federatedShareProvider->getShareById($id);
|
||||
} catch (Share\Exceptions\ShareNotFound $e) {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// don't allow to share a file back to the owner
|
||||
list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
|
||||
$owner = $share->getShareOwner();
|
||||
$currentServer = $this->addressHandler->generateRemoteURL();
|
||||
if ($this->addressHandler->compareAddresses($user, $remote,$owner , $currentServer)) {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
if ($this->verifyShare($share, $token)) {
|
||||
|
||||
// check if re-sharing is allowed
|
||||
if ($share->getPermissions() | ~Constants::PERMISSION_SHARE) {
|
||||
$share->setPermissions($share->getPermissions() & $permission);
|
||||
// the recipient of the initial share is now the initiator for the re-share
|
||||
$share->setSharedBy($share->getSharedWith());
|
||||
$share->setSharedWith($shareWith);
|
||||
try {
|
||||
$result = $this->federatedShareProvider->create($share);
|
||||
$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $remoteId);
|
||||
return new \OC_OCS_Result(['token' => $result->getToken(), 'remoteId' => $result->getId()]);
|
||||
} catch (\Exception $e) {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
} else {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* accept server-to-server share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function acceptShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = $params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
|
||||
try {
|
||||
$share = $this->federatedShareProvider->getShareById($id);
|
||||
} catch (Share\Exceptions\ShareNotFound $e) {
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
if ($this->verifyShare($share, $token)) {
|
||||
$this->executeAcceptShare($share);
|
||||
if ($share->getShareOwner() !== $share->getSharedBy()) {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
|
||||
$remoteId = $this->federatedShareProvider->getRemoteId($share);
|
||||
$this->notifications->sendAcceptShare($remote, $remoteId, $share->getToken());
|
||||
}
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
protected function executeAcceptShare(Share\IShare $share) {
|
||||
list($file, $link) = $this->getFile($this->getCorrectUid($share), $share->getNode()->getId());
|
||||
|
||||
$event = \OC::$server->getActivityManager()->generateEvent();
|
||||
$event->setApp(Activity::FILES_SHARING_APP)
|
||||
->setType(Activity::TYPE_REMOTE_SHARE)
|
||||
->setAffectedUser($this->getCorrectUid($share))
|
||||
->setSubject(Activity::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), basename($file)])
|
||||
->setObject('files', $share->getNode()->getId(), $file)
|
||||
->setLink($link);
|
||||
\OC::$server->getActivityManager()->publish($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* decline server-to-server share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function declineShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = (int)$params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
|
||||
try {
|
||||
$share = $this->federatedShareProvider->getShareById($id);
|
||||
} catch (Share\Exceptions\ShareNotFound $e) {
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
if($this->verifyShare($share, $token)) {
|
||||
if ($share->getShareOwner() !== $share->getSharedBy()) {
|
||||
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
|
||||
$remoteId = $this->federatedShareProvider->getRemoteId($share);
|
||||
$this->notifications->sendDeclineShare($remote, $remoteId, $share->getToken());
|
||||
}
|
||||
$this->executeDeclineShare($share);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
/**
|
||||
* delete declined share and create a activity
|
||||
*
|
||||
* @param Share\IShare $share
|
||||
*/
|
||||
protected function executeDeclineShare(Share\IShare $share) {
|
||||
$this->federatedShareProvider->removeShareFromTable($share);
|
||||
list($file, $link) = $this->getFile($this->getCorrectUid($share), $share->getNode()->getId());
|
||||
|
||||
$event = \OC::$server->getActivityManager()->generateEvent();
|
||||
$event->setApp(Activity::FILES_SHARING_APP)
|
||||
->setType(Activity::TYPE_REMOTE_SHARE)
|
||||
->setAffectedUser($this->getCorrectUid($share))
|
||||
->setSubject(Activity::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), basename($file)])
|
||||
->setObject('files', $share->getNode()->getId(), $file)
|
||||
->setLink($link);
|
||||
\OC::$server->getActivityManager()->publish($event);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check if we are the initiator or the owner of a re-share and return the correct UID
|
||||
*
|
||||
* @param Share\IShare $share
|
||||
* @return string
|
||||
*/
|
||||
protected function getCorrectUid(Share\IShare $share) {
|
||||
if($this->userManager->userExists($share->getShareOwner())) {
|
||||
return $share->getShareOwner();
|
||||
}
|
||||
|
||||
return $share->getSharedBy();
|
||||
}
|
||||
|
||||
/**
|
||||
* remove server-to-server share if it was unshared by the owner
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function unshare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = $params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
|
||||
$query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share_external` WHERE `remote_id` = ? AND `share_token` = ?');
|
||||
$query->execute(array($id, $token));
|
||||
$share = $query->fetchRow();
|
||||
|
||||
if ($token && $id && !empty($share)) {
|
||||
|
||||
$remote = $this->cleanupRemote($share['remote']);
|
||||
|
||||
$owner = $share['owner'] . '@' . $remote;
|
||||
$mountpoint = $share['mountpoint'];
|
||||
$user = $share['user'];
|
||||
|
||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external` WHERE `remote_id` = ? AND `share_token` = ?');
|
||||
$query->execute(array($id, $token));
|
||||
|
||||
if ($share['accepted']) {
|
||||
$path = trim($mountpoint, '/');
|
||||
} else {
|
||||
$path = trim($share['name'], '/');
|
||||
}
|
||||
|
||||
$notificationManager = \OC::$server->getNotificationManager();
|
||||
$notification = $notificationManager->createNotification();
|
||||
$notification->setApp('files_sharing')
|
||||
->setUser($share['user'])
|
||||
->setObject('remote_share', (int) $share['id']);
|
||||
$notificationManager->markProcessed($notification);
|
||||
|
||||
\OC::$server->getActivityManager()->publishActivity(
|
||||
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_UNSHARED, array($owner, $path), '', array(),
|
||||
'', '', $user, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_MEDIUM);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
private function cleanupRemote($remote) {
|
||||
$remote = substr($remote, strpos($remote, '://') + 3);
|
||||
|
||||
return rtrim($remote, '/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* federated share was revoked, either by the owner or the re-sharer
|
||||
*
|
||||
* @param $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function revoke($params) {
|
||||
$id = (int)$params['id'];
|
||||
$token = $this->request->getParam('token');
|
||||
|
||||
$share = $this->federatedShareProvider->getShareById($id);
|
||||
|
||||
if ($this->verifyShare($share, $token)) {
|
||||
$this->federatedShareProvider->removeShareFromTable($share);
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get share
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $token
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function getShare($id, $token) {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')->from($this->shareTable)
|
||||
->where($query->expr()->eq('token', $query->createNamedParameter($token)))
|
||||
->andWhere($query->expr()->eq('share_type', $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE)))
|
||||
->andWhere($query->expr()->eq('id', $query->createNamedParameter($id)));
|
||||
|
||||
$result = $query->execute()->fetchAll();
|
||||
|
||||
if (!empty($result) && isset($result[0])) {
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get file
|
||||
*
|
||||
* @param string $user
|
||||
* @param int $fileSource
|
||||
* @return array with internal path of the file and a absolute link to it
|
||||
*/
|
||||
private function getFile($user, $fileSource) {
|
||||
\OC_Util::setupFS($user);
|
||||
|
||||
try {
|
||||
$file = \OC\Files\Filesystem::getPath($fileSource);
|
||||
} catch (NotFoundException $e) {
|
||||
$file = null;
|
||||
}
|
||||
$args = \OC\Files\Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
|
||||
$link = \OCP\Util::linkToAbsolute('files', 'index.php', $args);
|
||||
|
||||
return array($file, $link);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check if server-to-server sharing is enabled
|
||||
*
|
||||
* @param bool $incoming
|
||||
* @return bool
|
||||
*/
|
||||
private function isS2SEnabled($incoming = false) {
|
||||
|
||||
$result = \OCP\App::isEnabled('files_sharing');
|
||||
|
||||
if ($incoming) {
|
||||
$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
|
||||
} else {
|
||||
$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if we got the right share
|
||||
*
|
||||
* @param Share\IShare $share
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
protected function verifyShare(Share\IShare $share, $token) {
|
||||
if (
|
||||
$share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
|
||||
$share->getToken() === $token
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* update share information to keep federated re-shares in sync
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function updatePermissions($params) {
|
||||
$id = (int)$params['id'];
|
||||
$token = $this->request->getParam('token', null);
|
||||
$permissions = $this->request->getParam('permissions', null);
|
||||
|
||||
try {
|
||||
$share = $this->federatedShareProvider->getShareById($id);
|
||||
} catch (Share\Exceptions\ShareNotFound $e) {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$validPermission = ctype_digit($permissions);
|
||||
$validToken = $this->verifyShare($share, $token);
|
||||
if ($validPermission && $validToken) {
|
||||
$this->updatePermissionsInDatabase($share, (int)$permissions);
|
||||
} else {
|
||||
return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
/**
|
||||
* update permissions in database
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param int $permissions
|
||||
*/
|
||||
protected function updatePermissionsInDatabase(IShare $share, $permissions) {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('share')
|
||||
->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
|
||||
->set('permissions', $query->createNamedParameter($permissions))
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Sharing;
|
||||
namespace OCA\FederatedFileSharing;
|
||||
|
||||
|
||||
use OCP\Notification\INotification;
|
||||
|
|
@ -54,9 +54,15 @@ class Notifier implements INotifier {
|
|||
// Deal with known subjects
|
||||
case 'remote_share':
|
||||
$params = $notification->getSubjectParameters();
|
||||
$notification->setParsedSubject(
|
||||
(string) $l->t('You received "/%2$s" as a remote share from %1$s', $params)
|
||||
);
|
||||
if ($params[0] !== $params[1] && $params[1] !== null) {
|
||||
$notification->setParsedSubject(
|
||||
(string) $l->t('You received "/%3$s" as a remote share from %1$s (on behalf of %2$s)', $params)
|
||||
);
|
||||
} else {
|
||||
$notification->setParsedSubject(
|
||||
(string)$l->t('You received "/%3$s" as a remote share from %1$s', $params)
|
||||
);
|
||||
}
|
||||
|
||||
// Deal with the actions for a known subject
|
||||
foreach ($notification->getActions() as $action) {
|
||||
|
|
@ -27,9 +27,8 @@ namespace OCA\FederatedFileSharing\Tests;
|
|||
use OCA\FederatedFileSharing\AddressHandler;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use Test\TestCase;
|
||||
|
||||
class AddressHandlerTest extends TestCase {
|
||||
class AddressHandlerTest extends \Test\TestCase {
|
||||
|
||||
/** @var AddressHandler */
|
||||
private $addressHandler;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@ use OCP\Http\Client\IClient;
|
|||
use OCP\Http\Client\IClientService;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use Test\TestCase;
|
||||
|
||||
class DiscoveryManagerTest extends TestCase {
|
||||
class DiscoveryManagerTest extends \Test\TestCase {
|
||||
/** @var ICache */
|
||||
private $cache;
|
||||
/** @var IClient */
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ use OCP\IConfig;
|
|||
use OCP\IDBConnection;
|
||||
use OCP\IL10N;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\IManager;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
* Class FederatedShareProviderTest
|
||||
|
|
@ -39,7 +39,7 @@ use Test\TestCase;
|
|||
* @package OCA\FederatedFileSharing\Tests
|
||||
* @group DB
|
||||
*/
|
||||
class FederatedShareProviderTest extends TestCase {
|
||||
class FederatedShareProviderTest extends \Test\TestCase {
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
|
@ -57,6 +57,8 @@ class FederatedShareProviderTest extends TestCase {
|
|||
protected $rootFolder;
|
||||
/** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $config;
|
||||
/** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
|
||||
/** @var IManager */
|
||||
protected $shareManager;
|
||||
|
|
@ -82,7 +84,11 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->logger = $this->getMock('OCP\ILogger');
|
||||
$this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
|
||||
$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->provider = new FederatedShareProvider(
|
||||
$this->connection,
|
||||
|
|
@ -92,7 +98,8 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->l,
|
||||
$this->logger,
|
||||
$this->rootFolder,
|
||||
$this->config
|
||||
$this->config,
|
||||
$this->userManager
|
||||
);
|
||||
|
||||
$this->shareManager = \OC::$server->getShareManager();
|
||||
|
|
@ -119,6 +126,11 @@ class FederatedShareProviderTest extends TestCase {
|
|||
|
||||
$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())
|
||||
->method('sendRemoteShare')
|
||||
->with(
|
||||
|
|
@ -126,7 +138,10 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->equalTo('user@server.com'),
|
||||
$this->equalTo('myFile'),
|
||||
$this->anything(),
|
||||
'sharedBy'
|
||||
'shareOwner',
|
||||
'shareOwner@http://localhost/',
|
||||
'sharedBy',
|
||||
'sharedBy@http://localhost/'
|
||||
)->willReturn(true);
|
||||
|
||||
$this->rootFolder->expects($this->never())->method($this->anything());
|
||||
|
|
@ -182,6 +197,11 @@ class FederatedShareProviderTest extends TestCase {
|
|||
|
||||
$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())
|
||||
->method('sendRemoteShare')
|
||||
->with(
|
||||
|
|
@ -189,7 +209,10 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->equalTo('user@server.com'),
|
||||
$this->equalTo('myFile'),
|
||||
$this->anything(),
|
||||
'sharedBy'
|
||||
'shareOwner',
|
||||
'shareOwner@http://localhost/',
|
||||
'sharedBy',
|
||||
'sharedBy@http://localhost/'
|
||||
)->willReturn(false);
|
||||
|
||||
$this->rootFolder->expects($this->once())
|
||||
|
|
@ -226,7 +249,10 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$node->method('getId')->willReturn(42);
|
||||
$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)
|
||||
->setSharedBy('sharedBy')
|
||||
|
|
@ -262,6 +288,10 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$node->method('getId')->willReturn(42);
|
||||
$node->method('getName')->willReturn('myFile');
|
||||
|
||||
|
||||
$this->addressHandler->expects($this->any())->method('splitUserRemote')
|
||||
->willReturn(['user', 'server.com']);
|
||||
|
||||
$share->setSharedWith('user@server.com')
|
||||
->setSharedBy('sharedBy')
|
||||
->setShareOwner('shareOwner')
|
||||
|
|
@ -270,6 +300,9 @@ class FederatedShareProviderTest extends TestCase {
|
|||
|
||||
$this->tokenHandler->method('generateToken')->willReturn('token');
|
||||
|
||||
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
|
||||
->willReturn('http://localhost/');
|
||||
|
||||
$this->notifications->expects($this->once())
|
||||
->method('sendRemoteShare')
|
||||
->with(
|
||||
|
|
@ -277,7 +310,10 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->equalTo('user@server.com'),
|
||||
$this->equalTo('myFile'),
|
||||
$this->anything(),
|
||||
'sharedBy'
|
||||
'shareOwner',
|
||||
'shareOwner@http://localhost/',
|
||||
'sharedBy',
|
||||
'sharedBy@http://localhost/'
|
||||
)->willReturn(true);
|
||||
|
||||
$this->rootFolder->expects($this->never())->method($this->anything());
|
||||
|
|
@ -291,20 +327,46 @@ class FederatedShareProviderTest extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public function testUpdate() {
|
||||
/**
|
||||
* @dataProvider datatTestUpdate
|
||||
*
|
||||
*/
|
||||
public function testUpdate($owner, $sharedBy) {
|
||||
|
||||
$this->provider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->connection,
|
||||
$this->addressHandler,
|
||||
$this->notifications,
|
||||
$this->tokenHandler,
|
||||
$this->l,
|
||||
$this->logger,
|
||||
$this->rootFolder,
|
||||
$this->config,
|
||||
$this->userManager
|
||||
]
|
||||
)->setMethods(['sendPermissionUpdate'])->getMock();
|
||||
|
||||
$share = $this->shareManager->newShare();
|
||||
|
||||
$node = $this->getMock('\OCP\Files\File');
|
||||
$node->method('getId')->willReturn(42);
|
||||
$node->method('getName')->willReturn('myFile');
|
||||
|
||||
|
||||
$this->addressHandler->expects($this->any())->method('splitUserRemote')
|
||||
->willReturn(['user', 'server.com']);
|
||||
|
||||
$share->setSharedWith('user@server.com')
|
||||
->setSharedBy('sharedBy')
|
||||
->setShareOwner('shareOwner')
|
||||
->setSharedBy($sharedBy)
|
||||
->setShareOwner($owner)
|
||||
->setPermissions(19)
|
||||
->setNode($node);
|
||||
|
||||
$this->tokenHandler->method('generateToken')->willReturn('token');
|
||||
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
|
||||
->willReturn('http://localhost/');
|
||||
|
||||
$this->notifications->expects($this->once())
|
||||
->method('sendRemoteShare')
|
||||
|
|
@ -313,9 +375,18 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->equalTo('user@server.com'),
|
||||
$this->equalTo('myFile'),
|
||||
$this->anything(),
|
||||
'sharedBy'
|
||||
$owner,
|
||||
$owner . '@http://localhost/',
|
||||
$sharedBy,
|
||||
$sharedBy . '@http://localhost/'
|
||||
)->willReturn(true);
|
||||
|
||||
if($owner === $sharedBy) {
|
||||
$this->provider->expects($this->never())->method('sendPermissionUpdate');
|
||||
} else {
|
||||
$this->provider->expects($this->once())->method('sendPermissionUpdate');
|
||||
}
|
||||
|
||||
$this->rootFolder->expects($this->never())->method($this->anything());
|
||||
|
||||
$share = $this->provider->create($share);
|
||||
|
|
@ -328,11 +399,24 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->assertEquals(1, $share->getPermissions());
|
||||
}
|
||||
|
||||
public function datatTestUpdate() {
|
||||
return [
|
||||
['sharedBy', 'shareOwner'],
|
||||
['shareOwner', 'shareOwner']
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetSharedBy() {
|
||||
$node = $this->getMock('\OCP\Files\File');
|
||||
$node->method('getId')->willReturn(42);
|
||||
$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->notifications
|
||||
->method('sendRemoteShare')
|
||||
|
|
@ -439,6 +523,14 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$node->method('getId')->willReturn(42);
|
||||
$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->notifications
|
||||
->method('sendRemoteShare')
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ use OCA\FederatedFileSharing\DiscoveryManager;
|
|||
use OCA\FederatedFileSharing\Notifications;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use Test\TestCase;
|
||||
|
||||
class NotificationsTest extends TestCase {
|
||||
class NotificationsTest extends \Test\TestCase {
|
||||
|
||||
/** @var AddressHandler | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $addressHandler;
|
||||
|
|
@ -85,14 +84,15 @@ class NotificationsTest extends TestCase {
|
|||
return $instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestSendRemoteUnShare
|
||||
* @dataProvider dataTestSendUpdateToRemote
|
||||
*
|
||||
* @param int $try
|
||||
* @param array $httpRequestResult
|
||||
* @param bool $expected
|
||||
*/
|
||||
public function testSendRemoteUnShare($try, $httpRequestResult, $expected) {
|
||||
public function testSendUpdateToRemote($try, $httpRequestResult, $expected) {
|
||||
$remote = 'remote';
|
||||
$id = 42;
|
||||
$timestamp = 63576;
|
||||
|
|
@ -102,20 +102,22 @@ class NotificationsTest extends TestCase {
|
|||
$instance->expects($this->any())->method('getTimestamp')->willReturn($timestamp);
|
||||
|
||||
$instance->expects($this->once())->method('tryHttpPostToShareEndpoint')
|
||||
->with($remote, '/'.$id.'/unshare', ['token' => $token, 'format' => 'json'])
|
||||
->with($remote, '/'.$id.'/unshare', ['token' => $token, 'data1Key' => 'data1Value'])
|
||||
->willReturn($httpRequestResult);
|
||||
|
||||
$this->addressHandler->expects($this->once())->method('removeProtocolFromUrl')
|
||||
->with($remote)->willReturn($remote);
|
||||
|
||||
|
||||
// only add background job on first try
|
||||
if ($try === 0 && $expected === false) {
|
||||
$this->jobList->expects($this->once())->method('add')
|
||||
->with(
|
||||
'OCA\FederatedFileSharing\BackgroundJob\UnShare',
|
||||
'OCA\FederatedFileSharing\BackgroundJob\RetryJob',
|
||||
[
|
||||
'remote' => $remote,
|
||||
'id' => $id,
|
||||
'remoteId' => $id,
|
||||
'action' => 'unshare',
|
||||
'data' => json_encode(['data1Key' => 'data1Value']),
|
||||
'token' => $token,
|
||||
'try' => $try,
|
||||
'lastRun' => $timestamp
|
||||
|
|
@ -124,14 +126,15 @@ class NotificationsTest extends TestCase {
|
|||
} else {
|
||||
$this->jobList->expects($this->never())->method('add');
|
||||
}
|
||||
|
||||
|
||||
$this->assertSame($expected,
|
||||
$instance->sendRemoteUnShare($remote, $id, $token, $try)
|
||||
$instance->sendUpdateToRemote($remote, $id, $token, 'unshare', ['data1Key' => 'data1Value'], $try)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function dataTestSendRemoteUnshare() {
|
||||
|
||||
|
||||
public function dataTestSendUpdateToRemote() {
|
||||
return [
|
||||
// test if background job is added correctly
|
||||
[0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], true],
|
||||
|
|
|
|||
|
|
@ -23,14 +23,22 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use OCA\Files_Sharing\Tests\TestCase;
|
||||
namespace OCA\FederatedFileSharing\Tests;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OCA\FederatedFileSharing\DiscoveryManager;
|
||||
use OCA\FederatedFileSharing\FederatedShareProvider;
|
||||
use OCA\FederatedFileSharing\RequestHandler;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
/**
|
||||
* Class Test_Files_Sharing_Api
|
||||
* Class RequestHandlerTest
|
||||
*
|
||||
* @package OCA\FederatedFileSharing\Tests
|
||||
* @group DB
|
||||
*/
|
||||
class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
||||
class RequestHandlerTest extends TestCase {
|
||||
|
||||
const TEST_FOLDER_NAME = '/folder_share_api_test';
|
||||
|
||||
|
|
@ -40,13 +48,25 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
private $connection;
|
||||
|
||||
/**
|
||||
* @var \OCA\Files_Sharing\API\Server2Server
|
||||
* @var RequestHandler
|
||||
*/
|
||||
private $s2s;
|
||||
|
||||
/** @var \OCA\FederatedFileSharing\FederatedShareProvider | PHPUnit_Framework_MockObject_MockObject */
|
||||
private $federatedShareProvider;
|
||||
|
||||
/** @var \OCA\FederatedFileSharing\Notifications | PHPUnit_Framework_MockObject_MockObject */
|
||||
private $notifications;
|
||||
|
||||
/** @var \OCA\FederatedFileSharing\AddressHandler | PHPUnit_Framework_MockObject_MockObject */
|
||||
private $addressHandler;
|
||||
|
||||
/** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $userManager;
|
||||
|
||||
/** @var IShare | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $share;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
|
|
@ -60,16 +80,33 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
->setConstructorArgs([$config, $clientService])
|
||||
->getMock();
|
||||
$httpHelperMock->expects($this->any())->method('post')->with($this->anything())->will($this->returnValue(true));
|
||||
$this->share = $this->getMock('\OCP\Share\IShare');
|
||||
$this->federatedShareProvider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->federatedShareProvider->expects($this->any())
|
||||
->method('isOutgoingServer2serverShareEnabled')->willReturn(true);
|
||||
$this->federatedShareProvider->expects($this->any())
|
||||
->method('isIncomingServer2serverShareEnabled')->willReturn(true);
|
||||
$this->federatedShareProvider->expects($this->any())->method('getShareById')
|
||||
->willReturn($this->share);
|
||||
|
||||
$this->notifications = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->userManager = $this->getMock('OCP\IUserManager');
|
||||
|
||||
$this->registerHttpHelper($httpHelperMock);
|
||||
|
||||
$this->s2s = new \OCA\Files_Sharing\API\Server2Server($this->federatedShareProvider);
|
||||
$this->s2s = new RequestHandler(
|
||||
$this->federatedShareProvider,
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC::$server->getShareManager(),
|
||||
\OC::$server->getRequest(),
|
||||
$this->notifications,
|
||||
$this->addressHandler,
|
||||
$this->userManager
|
||||
);
|
||||
|
||||
$this->connection = \OC::$server->getDatabaseConnection();
|
||||
}
|
||||
|
|
@ -78,6 +115,9 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external`');
|
||||
$query->execute();
|
||||
|
||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share`');
|
||||
$query->execute();
|
||||
|
||||
$this->restoreHttpHelper();
|
||||
|
||||
parent::tearDown();
|
||||
|
|
@ -135,28 +175,34 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
|
||||
|
||||
function testDeclineShare() {
|
||||
$dummy = \OCP\DB::prepare('
|
||||
INSERT INTO `*PREFIX*share`
|
||||
(`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
');
|
||||
$dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token', 'foo@bar'));
|
||||
|
||||
$verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
|
||||
$result = $verify->execute();
|
||||
$data = $result->fetchAll();
|
||||
$this->assertSame(1, count($data));
|
||||
$this->s2s = $this->getMockBuilder('\OCA\FederatedFileSharing\RequestHandler')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->federatedShareProvider,
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC::$server->getShareManager(),
|
||||
\OC::$server->getRequest(),
|
||||
$this->notifications,
|
||||
$this->addressHandler,
|
||||
$this->userManager
|
||||
]
|
||||
)->setMethods(['executeDeclineShare', 'verifyShare'])->getMock();
|
||||
|
||||
$this->s2s->expects($this->once())->method('executeDeclineShare');
|
||||
|
||||
$this->s2s->expects($this->any())->method('verifyShare')->willReturn(true);
|
||||
|
||||
$_POST['token'] = 'token';
|
||||
$this->s2s->declineShare(array('id' => $data[0]['id']));
|
||||
|
||||
$verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
|
||||
$result = $verify->execute();
|
||||
$data = $result->fetchAll();
|
||||
$this->assertEmpty($data);
|
||||
$this->s2s->declineShare(array('id' => 42));
|
||||
|
||||
}
|
||||
|
||||
function testDeclineShareMultiple() {
|
||||
function XtestDeclineShareMultiple() {
|
||||
|
||||
$this->share->expects($this->any())->method('verifyShare')->willReturn(true);
|
||||
|
||||
$dummy = \OCP\DB::prepare('
|
||||
INSERT INTO `*PREFIX*share`
|
||||
(`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`)
|
||||
|
|
@ -194,14 +240,14 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
function testDeleteUser($toDelete, $expected, $remainingUsers) {
|
||||
$this->createDummyS2SShares();
|
||||
|
||||
$discoveryManager = new \OCA\FederatedFileSharing\DiscoveryManager(
|
||||
$discoveryManager = new DiscoveryManager(
|
||||
\OC::$server->getMemCacheFactory(),
|
||||
\OC::$server->getHTTPClientService()
|
||||
);
|
||||
$manager = new OCA\Files_Sharing\External\Manager(
|
||||
$manager = new \OCA\Files_Sharing\External\Manager(
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC\Files\Filesystem::getMountManager(),
|
||||
\OC\Files\Filesystem::getLoader(),
|
||||
Filesystem::getMountManager(),
|
||||
Filesystem::getLoader(),
|
||||
\OC::$server->getHTTPHelper(),
|
||||
\OC::$server->getNotificationManager(),
|
||||
$discoveryManager,
|
||||
|
|
@ -260,4 +306,76 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
|||
$this->assertSame(10, count($dummyEntries));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestGetShare
|
||||
*
|
||||
* @param bool $found
|
||||
* @param bool $correctId
|
||||
* @param bool $correctToken
|
||||
*/
|
||||
public function testGetShare($found, $correctId, $correctToken) {
|
||||
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->getQueryBuilder();
|
||||
$stime = time();
|
||||
$query->insert('share')
|
||||
->values(
|
||||
[
|
||||
'share_type' => $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE),
|
||||
'uid_owner' => $query->createNamedParameter(self::TEST_FILES_SHARING_API_USER1),
|
||||
'uid_initiator' => $query->createNamedParameter(self::TEST_FILES_SHARING_API_USER2),
|
||||
'item_type' => $query->createNamedParameter('test'),
|
||||
'item_source' => $query->createNamedParameter('1'),
|
||||
'item_target' => $query->createNamedParameter('/1'),
|
||||
'file_source' => $query->createNamedParameter('1'),
|
||||
'file_target' => $query->createNamedParameter('/test.txt'),
|
||||
'permissions' => $query->createNamedParameter('1'),
|
||||
'stime' => $query->createNamedParameter($stime),
|
||||
'token' => $query->createNamedParameter('token'),
|
||||
'share_with' => $query->createNamedParameter('foo@bar'),
|
||||
]
|
||||
)->execute();
|
||||
$id = $query->getLastInsertId();
|
||||
|
||||
$expected = [
|
||||
'share_type' => (string)FederatedShareProvider::SHARE_TYPE_REMOTE,
|
||||
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
|
||||
'item_type' => 'test',
|
||||
'item_source' => '1',
|
||||
'item_target' => '/1',
|
||||
'file_source' => '1',
|
||||
'file_target' => '/test.txt',
|
||||
'permissions' => '1',
|
||||
'stime' => (string)$stime,
|
||||
'token' => 'token',
|
||||
'share_with' => 'foo@bar',
|
||||
'id' => (string)$id,
|
||||
'uid_initiator' => self::TEST_FILES_SHARING_API_USER2,
|
||||
'parent' => null,
|
||||
'accepted' => '0',
|
||||
'expiration' => null,
|
||||
'mail_send' => '0'
|
||||
];
|
||||
|
||||
$searchToken = $correctToken ? 'token' : 'wrongToken';
|
||||
$searchId = $correctId ? $id : -1;
|
||||
|
||||
$result = $this->invokePrivate($this->s2s, 'getShare', [$searchId, $searchToken]);
|
||||
|
||||
if ($found) {
|
||||
$this->assertEquals($expected, $result);
|
||||
} else {
|
||||
$this->assertSame(false, $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function dataTestGetShare() {
|
||||
return [
|
||||
[true, true, true],
|
||||
[false, false, true],
|
||||
[false, true, false],
|
||||
[false, false, false],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
132
apps/federatedfilesharing/tests/TestCase.php
Normal file
132
apps/federatedfilesharing/tests/TestCase.php
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||
* @author Roeland Jago Douma <rullzer@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, 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\FederatedFileSharing\Tests;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OCA\Files\Share;
|
||||
|
||||
/**
|
||||
* Class Test_Files_Sharing_Base
|
||||
*
|
||||
* @group DB
|
||||
*
|
||||
* Base class for sharing tests.
|
||||
*/
|
||||
abstract class TestCase extends \Test\TestCase {
|
||||
|
||||
const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
|
||||
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
// reset backend
|
||||
\OC_User::clearBackends();
|
||||
\OC_Group::clearBackends();
|
||||
|
||||
// create users
|
||||
$backend = new \Test\Util\User\Dummy();
|
||||
\OC_User::useBackend($backend);
|
||||
$backend->createUser(self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER1);
|
||||
$backend->createUser(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER2);
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
//login as user1
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass() {
|
||||
// cleanup users
|
||||
$user = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER1);
|
||||
if ($user !== null) {
|
||||
$user->delete();
|
||||
}
|
||||
$user = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER2);
|
||||
if ($user !== null) {
|
||||
$user->delete();
|
||||
}
|
||||
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_User::setUserId('');
|
||||
Filesystem::tearDown();
|
||||
|
||||
// reset backend
|
||||
\OC_User::clearBackends();
|
||||
\OC_User::useBackend('database');
|
||||
\OC_Group::clearBackends();
|
||||
\OC_Group::useBackend(new \OC_Group_Database());
|
||||
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param bool $create
|
||||
* @param bool $password
|
||||
*/
|
||||
protected static function loginHelper($user, $create = false, $password = false) {
|
||||
|
||||
if ($password === false) {
|
||||
$password = $user;
|
||||
}
|
||||
|
||||
if ($create) {
|
||||
\OC::$server->getUserManager()->createUser($user, $password);
|
||||
\OC_Group::createGroup('group');
|
||||
\OC_Group::addToGroup($user, 'group');
|
||||
}
|
||||
|
||||
self::resetStorage();
|
||||
|
||||
\OC_Util::tearDownFS();
|
||||
\OC::$server->getUserSession()->setUser(null);
|
||||
\OC\Files\Filesystem::tearDown();
|
||||
\OC::$server->getUserSession()->login($user, $password);
|
||||
\OC::$server->getUserFolder($user);
|
||||
|
||||
\OC_Util::setupFS($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* reset init status for the share storage
|
||||
*/
|
||||
protected static function resetStorage() {
|
||||
$storage = new \ReflectionClass('\OC\Files\Storage\Shared');
|
||||
$isInitialized = $storage->getProperty('initialized');
|
||||
$isInitialized->setAccessible(true);
|
||||
$isInitialized->setValue($storage, false);
|
||||
$isInitialized->setAccessible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,9 +26,8 @@ namespace OCA\FederatedFileSharing\Tests;
|
|||
|
||||
use OCA\FederatedFileSharing\TokenHandler;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Test\TestCase;
|
||||
|
||||
class TokenHandlerTest extends TestCase {
|
||||
class TokenHandlerTest extends \Test\TestCase {
|
||||
|
||||
/** @var TokenHandler */
|
||||
private $tokenHandler;
|
||||
|
|
|
|||
|
|
@ -1,325 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Arthur Schiwon <blizzz@owncloud.com>
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, 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;
|
||||
|
||||
use OCA\FederatedFileSharing\DiscoveryManager;
|
||||
use OCA\FederatedFileSharing\FederatedShareProvider;
|
||||
use OCA\Files_Sharing\Activity;
|
||||
use OCP\Files\NotFoundException;
|
||||
|
||||
class Server2Server {
|
||||
|
||||
/** @var FederatedShareProvider */
|
||||
private $federatedShareProvider;
|
||||
|
||||
|
||||
/**
|
||||
* Server2Server constructor.
|
||||
*
|
||||
* @param FederatedShareProvider $federatedShareProvider
|
||||
*/
|
||||
public function __construct(FederatedShareProvider $federatedShareProvider) {
|
||||
$this->federatedShareProvider = $federatedShareProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function createShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled(true)) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
$name = isset($_POST['name']) ? $_POST['name'] : null;
|
||||
$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
|
||||
$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
|
||||
$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
|
||||
|
||||
if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
|
||||
|
||||
if(!\OCP\Util::isValidFileName($name)) {
|
||||
return new \OC_OCS_Result(null, 400, 'The mountpoint name contains invalid characters.');
|
||||
}
|
||||
|
||||
// FIXME this should be a method in the user management instead
|
||||
\OCP\Util::writeLog('files_sharing', 'shareWith before, ' . $shareWith, \OCP\Util::DEBUG);
|
||||
\OCP\Util::emitHook(
|
||||
'\OCA\Files_Sharing\API\Server2Server',
|
||||
'preLoginNameUsedAsUserName',
|
||||
array('uid' => &$shareWith)
|
||||
);
|
||||
\OCP\Util::writeLog('files_sharing', 'shareWith after, ' . $shareWith, \OCP\Util::DEBUG);
|
||||
|
||||
if (!\OCP\User::userExists($shareWith)) {
|
||||
return new \OC_OCS_Result(null, 400, 'User does not exists');
|
||||
}
|
||||
|
||||
\OC_Util::setupFS($shareWith);
|
||||
|
||||
$discoveryManager = new DiscoveryManager(
|
||||
\OC::$server->getMemCacheFactory(),
|
||||
\OC::$server->getHTTPClientService()
|
||||
);
|
||||
$externalManager = new \OCA\Files_Sharing\External\Manager(
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC\Files\Filesystem::getMountManager(),
|
||||
\OC\Files\Filesystem::getLoader(),
|
||||
\OC::$server->getHTTPHelper(),
|
||||
\OC::$server->getNotificationManager(),
|
||||
$discoveryManager,
|
||||
$shareWith
|
||||
);
|
||||
|
||||
try {
|
||||
$externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
|
||||
$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
|
||||
|
||||
$user = $owner . '@' . $this->cleanupRemote($remote);
|
||||
|
||||
\OC::$server->getActivityManager()->publishActivity(
|
||||
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($user, trim($name, '/')), '', array(),
|
||||
'', '', $shareWith, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_LOW);
|
||||
|
||||
$urlGenerator = \OC::$server->getURLGenerator();
|
||||
|
||||
$notificationManager = \OC::$server->getNotificationManager();
|
||||
$notification = $notificationManager->createNotification();
|
||||
$notification->setApp('files_sharing')
|
||||
->setUser($shareWith)
|
||||
->setDateTime(new \DateTime())
|
||||
->setObject('remote_share', $shareId)
|
||||
->setSubject('remote_share', [$user, trim($name, '/')]);
|
||||
|
||||
$declineAction = $notification->createAction();
|
||||
$declineAction->setLabel('decline')
|
||||
->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
|
||||
$notification->addAction($declineAction);
|
||||
|
||||
$acceptAction = $notification->createAction();
|
||||
$acceptAction->setLabel('accept')
|
||||
->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
|
||||
$notification->addAction($acceptAction);
|
||||
|
||||
$notificationManager->notify($notification);
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
} catch (\Exception $e) {
|
||||
\OCP\Util::writeLog('files_sharing', 'server can not add remote share, ' . $e->getMessage(), \OCP\Util::ERROR);
|
||||
return new \OC_OCS_Result(null, 500, 'internal server error, was not able to add share from ' . $remote);
|
||||
}
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result(null, 400, 'server can not add remote share, missing parameter');
|
||||
}
|
||||
|
||||
/**
|
||||
* accept server-to-server share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function acceptShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = $params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
$share = self::getShare($id, $token);
|
||||
|
||||
if ($share) {
|
||||
list($file, $link) = self::getFile($share['uid_owner'], $share['file_source']);
|
||||
|
||||
$event = \OC::$server->getActivityManager()->generateEvent();
|
||||
$event->setApp(Activity::FILES_SHARING_APP)
|
||||
->setType(Activity::TYPE_REMOTE_SHARE)
|
||||
->setAffectedUser($share['uid_owner'])
|
||||
->setSubject(Activity::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share['share_with'], basename($file)])
|
||||
->setObject('files', $share['file_source'], $file)
|
||||
->setLink($link);
|
||||
\OC::$server->getActivityManager()->publish($event);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
/**
|
||||
* decline server-to-server share
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function declineShare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = $params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
|
||||
$share = $this->getShare($id, $token);
|
||||
|
||||
if ($share) {
|
||||
// userId must be set to the user who unshares
|
||||
\OCP\Share::unshare($share['item_type'], $share['item_source'], $share['share_type'], $share['share_with'], $share['uid_owner']);
|
||||
|
||||
list($file, $link) = $this->getFile($share['uid_owner'], $share['file_source']);
|
||||
|
||||
$event = \OC::$server->getActivityManager()->generateEvent();
|
||||
$event->setApp(Activity::FILES_SHARING_APP)
|
||||
->setType(Activity::TYPE_REMOTE_SHARE)
|
||||
->setAffectedUser($share['uid_owner'])
|
||||
->setSubject(Activity::SUBJECT_REMOTE_SHARE_DECLINED, [$share['share_with'], basename($file)])
|
||||
->setObject('files', $share['file_source'], $file)
|
||||
->setLink($link);
|
||||
\OC::$server->getActivityManager()->publish($event);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
/**
|
||||
* remove server-to-server share if it was unshared by the owner
|
||||
*
|
||||
* @param array $params
|
||||
* @return \OC_OCS_Result
|
||||
*/
|
||||
public function unshare($params) {
|
||||
|
||||
if (!$this->isS2SEnabled()) {
|
||||
return new \OC_OCS_Result(null, 503, 'Server does not support federated cloud sharing');
|
||||
}
|
||||
|
||||
$id = $params['id'];
|
||||
$token = isset($_POST['token']) ? $_POST['token'] : null;
|
||||
|
||||
$query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share_external` WHERE `remote_id` = ? AND `share_token` = ?');
|
||||
$query->execute(array($id, $token));
|
||||
$share = $query->fetchRow();
|
||||
|
||||
if ($token && $id && !empty($share)) {
|
||||
|
||||
$remote = $this->cleanupRemote($share['remote']);
|
||||
|
||||
$owner = $share['owner'] . '@' . $remote;
|
||||
$mountpoint = $share['mountpoint'];
|
||||
$user = $share['user'];
|
||||
|
||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external` WHERE `remote_id` = ? AND `share_token` = ?');
|
||||
$query->execute(array($id, $token));
|
||||
|
||||
if ($share['accepted']) {
|
||||
$path = trim($mountpoint, '/');
|
||||
} else {
|
||||
$path = trim($share['name'], '/');
|
||||
}
|
||||
|
||||
$notificationManager = \OC::$server->getNotificationManager();
|
||||
$notification = $notificationManager->createNotification();
|
||||
$notification->setApp('files_sharing')
|
||||
->setUser($share['user'])
|
||||
->setObject('remote_share', (int) $share['id']);
|
||||
$notificationManager->markProcessed($notification);
|
||||
|
||||
\OC::$server->getActivityManager()->publishActivity(
|
||||
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_UNSHARED, array($owner, $path), '', array(),
|
||||
'', '', $user, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_MEDIUM);
|
||||
}
|
||||
|
||||
return new \OC_OCS_Result();
|
||||
}
|
||||
|
||||
private function cleanupRemote($remote) {
|
||||
$remote = substr($remote, strpos($remote, '://') + 3);
|
||||
|
||||
return rtrim($remote, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* get share
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $token
|
||||
* @return array
|
||||
*/
|
||||
private function getShare($id, $token) {
|
||||
$query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `id` = ? AND `token` = ? AND `share_type` = ?');
|
||||
$query->execute(array($id, $token, \OCP\Share::SHARE_TYPE_REMOTE));
|
||||
$share = $query->fetchRow();
|
||||
|
||||
return $share;
|
||||
}
|
||||
|
||||
/**
|
||||
* get file
|
||||
*
|
||||
* @param string $user
|
||||
* @param int $fileSource
|
||||
* @return array with internal path of the file and a absolute link to it
|
||||
*/
|
||||
private function getFile($user, $fileSource) {
|
||||
\OC_Util::setupFS($user);
|
||||
|
||||
try {
|
||||
$file = \OC\Files\Filesystem::getPath($fileSource);
|
||||
} catch (NotFoundException $e) {
|
||||
$file = null;
|
||||
}
|
||||
$args = \OC\Files\Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
|
||||
$link = \OCP\Util::linkToAbsolute('files', 'index.php', $args);
|
||||
|
||||
return array($file, $link);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check if server-to-server sharing is enabled
|
||||
*
|
||||
* @param bool $incoming
|
||||
* @return bool
|
||||
*/
|
||||
private function isS2SEnabled($incoming = false) {
|
||||
|
||||
$result = \OCP\App::isEnabled('files_sharing');
|
||||
|
||||
if ($incoming) {
|
||||
$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
|
||||
} else {
|
||||
$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -99,7 +99,15 @@ class Share20OCS {
|
|||
*/
|
||||
protected function formatShare(\OCP\Share\IShare $share) {
|
||||
$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 = [
|
||||
'id' => $share->getId(),
|
||||
'share_type' => $share->getShareType(),
|
||||
|
|
@ -115,7 +123,7 @@ class Share20OCS {
|
|||
];
|
||||
|
||||
$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) {
|
||||
$result['item_type'] = 'folder';
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -103,15 +103,3 @@ if ($config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes') {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$manager = \OC::$server->getNotificationManager();
|
||||
$manager->registerNotifier(function() {
|
||||
return new \OCA\Files_Sharing\Notifier(
|
||||
\OC::$server->getL10NFactory()
|
||||
);
|
||||
}, function() use ($l) {
|
||||
return [
|
||||
'id' => 'files_sharing',
|
||||
'name' => $l->t('Federated sharing'),
|
||||
];
|
||||
});
|
||||
|
|
|
|||
36
apps/files_sharing/lib/external/manager.php
vendored
36
apps/files_sharing/lib/external/manager.php
vendored
|
|
@ -325,6 +325,10 @@ class Manager {
|
|||
}
|
||||
|
||||
public function removeShare($mountPoint) {
|
||||
|
||||
$mountPointObj = $this->mountManager->find($mountPoint);
|
||||
$id = $mountPointObj->getStorage()->getCache()->getId();
|
||||
|
||||
$mountPoint = $this->stripPath($mountPoint);
|
||||
$hash = md5($mountPoint);
|
||||
|
||||
|
|
@ -338,13 +342,43 @@ class Manager {
|
|||
$share = $getShare->fetch();
|
||||
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
|
||||
}
|
||||
$getShare->closeCursor();
|
||||
|
||||
$query = $this->connection->prepare('
|
||||
DELETE FROM `*PREFIX*share_external`
|
||||
WHERE `mountpoint_hash` = ?
|
||||
AND `user` = ?
|
||||
');
|
||||
return (bool)$query->execute(array($hash, $this->uid));
|
||||
$result = (bool)$query->execute(array($hash, $this->uid));
|
||||
|
||||
if($result) {
|
||||
$this->removeReShares($id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove re-shares from share table and mapping in the federated_reshares table
|
||||
*
|
||||
* @param $mountPointId
|
||||
*/
|
||||
protected function removeReShares($mountPointId) {
|
||||
$selectQuery = $this->connection->getQueryBuilder();
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$selectQuery->select('id')->from('share')
|
||||
->where($selectQuery->expr()->eq('file_source', $query->createNamedParameter($mountPointId)));
|
||||
$select = $selectQuery->getSQL();
|
||||
|
||||
|
||||
$query->delete('federated_reshares')
|
||||
->where($query->expr()->in('share_id', $query->createFunction('(' . $select . ')')));
|
||||
$query->execute();
|
||||
|
||||
$deleteReShares = $this->connection->getQueryBuilder();
|
||||
$deleteReShares->delete('share')
|
||||
->where($deleteReShares->expr()->eq('file_source', $deleteReShares->createNamedParameter($mountPointId)));
|
||||
$deleteReShares->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ class Share20OCSTest extends \Test\TestCase {
|
|||
$this->currentUser = $this->getMock('OCP\IUser');
|
||||
$this->currentUser->method('getUID')->willReturn('currentUser');
|
||||
|
||||
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
|
||||
|
||||
$this->l = $this->getMock('\OCP\IL10N');
|
||||
$this->l->method('t')
|
||||
->will($this->returnCallback(function($text, $parameters = []) {
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ class DefaultShareProvider implements IShareProvider {
|
|||
* @throws InvalidShare
|
||||
*/
|
||||
private function createShare($data) {
|
||||
$share = new Share($this->rootFolder);
|
||||
$share = new Share($this->rootFolder, $this->userManager);
|
||||
$share->setId((int)$data['id'])
|
||||
->setShareType((int)$data['share_type'])
|
||||
->setPermissions((int)$data['permissions'])
|
||||
|
|
|
|||
|
|
@ -201,7 +201,12 @@ class Manager implements IManager {
|
|||
}
|
||||
|
||||
// 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');
|
||||
}
|
||||
|
||||
|
|
@ -713,7 +718,11 @@ class Manager implements IManager {
|
|||
}
|
||||
|
||||
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(
|
||||
'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
|
||||
'itemSource' => $share->getNode()->getId(),
|
||||
|
|
@ -1107,7 +1116,7 @@ class Manager implements IManager {
|
|||
* @return \OCP\Share\IShare;
|
||||
*/
|
||||
public function newShare() {
|
||||
return new \OC\Share20\Share($this->rootFolder);
|
||||
return new \OC\Share20\Share($this->rootFolder, $this->userManager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ class ProviderFactory implements IProviderFactory {
|
|||
$l,
|
||||
$this->serverContainer->getLogger(),
|
||||
$this->serverContainer->getLazyRootFolder(),
|
||||
$this->serverContainer->getConfig()
|
||||
$this->serverContainer->getConfig(),
|
||||
$this->serverContainer->getUserManager()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ use OCP\Files\File;
|
|||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IUser;
|
||||
use OCP\IGroup;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\Exceptions\IllegalIDChangeException;
|
||||
|
||||
class Share implements \OCP\Share\IShare {
|
||||
|
|
@ -68,8 +67,12 @@ class Share implements \OCP\Share\IShare {
|
|||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
public function __construct(IRootFolder $rootFolder) {
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -145,7 +148,13 @@ class Share implements \OCP\Share\IShare {
|
|||
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);
|
||||
if (empty($nodes)) {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,25 @@ API::register(
|
|||
// Server-to-Server Sharing
|
||||
if (\OC::$server->getAppManager()->isEnabledForUser('files_sharing')) {
|
||||
$federatedSharingApp = new \OCA\FederatedFileSharing\AppInfo\Application('federatedfilesharing');
|
||||
$s2s = new \OCA\Files_Sharing\API\Server2Server($federatedSharingApp->getFederatedShareProvider());
|
||||
$addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
|
||||
\OC::$server->getURLGenerator(),
|
||||
\OC::$server->getL10N('federatedfilesharing')
|
||||
);
|
||||
$notification = new \OCA\FederatedFileSharing\Notifications(
|
||||
$addressHandler,
|
||||
\OC::$server->getHTTPClientService(),
|
||||
new \OCA\FederatedFileSharing\DiscoveryManager(\OC::$server->getMemCacheFactory(), \OC::$server->getHTTPClientService()),
|
||||
\OC::$server->getJobList()
|
||||
);
|
||||
$s2s = new OCA\FederatedFileSharing\RequestHandler(
|
||||
$federatedSharingApp->getFederatedShareProvider(),
|
||||
\OC::$server->getDatabaseConnection(),
|
||||
\OC::$server->getShareManager(),
|
||||
\OC::$server->getRequest(),
|
||||
$notification,
|
||||
$addressHandler,
|
||||
\OC::$server->getUserManager()
|
||||
);
|
||||
API::register('post',
|
||||
'/cloud/shares',
|
||||
array($s2s, 'createShare'),
|
||||
|
|
@ -108,6 +126,21 @@ if (\OC::$server->getAppManager()->isEnabledForUser('files_sharing')) {
|
|||
API::GUEST_AUTH
|
||||
);
|
||||
|
||||
API::register('post',
|
||||
'/cloud/shares/{id}/reshare',
|
||||
array($s2s, 'reShare'),
|
||||
'files_sharing',
|
||||
API::GUEST_AUTH
|
||||
);
|
||||
|
||||
API::register('post',
|
||||
'/cloud/shares/{id}/permissions',
|
||||
array($s2s, 'updatePermissions'),
|
||||
'files_sharing',
|
||||
API::GUEST_AUTH
|
||||
);
|
||||
|
||||
|
||||
API::register('post',
|
||||
'/cloud/shares/{id}/accept',
|
||||
array($s2s, 'acceptShare'),
|
||||
|
|
@ -128,4 +161,11 @@ if (\OC::$server->getAppManager()->isEnabledForUser('files_sharing')) {
|
|||
'files_sharing',
|
||||
API::GUEST_AUTH
|
||||
);
|
||||
|
||||
API::register('post',
|
||||
'/cloud/shares/{id}/revoke',
|
||||
array($s2s, 'revoke'),
|
||||
'files_sharing',
|
||||
API::GUEST_AUTH
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
$this->groupManager = $this->getMock('OCP\IGroupManager');
|
||||
$this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
|
||||
|
||||
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
|
||||
|
||||
//Empty share table
|
||||
$this->dbConn->getQueryBuilder()->delete('share')->execute();
|
||||
|
||||
|
|
@ -587,7 +589,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
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->method('getUID')->WillReturn('shareOwner');
|
||||
|
|
@ -635,7 +637,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
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->method('getUID')->willReturn('shareOwner');
|
||||
|
|
@ -683,7 +685,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
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->method('getUID')->willReturn('shareOwner');
|
||||
|
|
|
|||
|
|
@ -2283,6 +2283,9 @@ class ManagerTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function testUpdateShareUser() {
|
||||
|
||||
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
|
||||
|
||||
$manager = $this->createManagerMock()
|
||||
->setMethods([
|
||||
'canShare',
|
||||
|
|
@ -2567,4 +2570,4 @@ class DummyFactory implements IProviderFactory {
|
|||
public function getProviderForType($shareType) {
|
||||
return $this->provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ class ShareTest extends \Test\TestCase {
|
|||
|
||||
public function setUp() {
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue