Merge pull request #12749 from owncloud/server2server-sharing-ng
server to server sharing next generation
This commit is contained in:
commit
8164415b45
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
namespace OCA\Files_Encryption;
|
namespace OCA\Files_Encryption;
|
||||||
|
|
||||||
use OC\Files\Filesystem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for hook specific logic
|
* Class for hook specific logic
|
||||||
*/
|
*/
|
||||||
|
@ -364,15 +362,16 @@ class Hooks {
|
||||||
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
|
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
|
||||||
|
|
||||||
$view = new \OC\Files\View('/');
|
$view = new \OC\Files\View('/');
|
||||||
$userId = \OCP\User::getUser();
|
$userId = $params['uidOwner'];
|
||||||
|
$userView = new \OC\Files\View('/' . $userId . '/files');
|
||||||
$util = new Util($view, $userId);
|
$util = new Util($view, $userId);
|
||||||
$path = \OC\Files\Filesystem::getPath($params['fileSource']);
|
$path = $userView->getPath($params['fileSource']);
|
||||||
|
|
||||||
// for group shares get a list of the group members
|
// for group shares get a list of the group members
|
||||||
if ($params['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) {
|
if ($params['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) {
|
||||||
$userIds = \OC_Group::usersInGroup($params['shareWith']);
|
$userIds = \OC_Group::usersInGroup($params['shareWith']);
|
||||||
} else {
|
} else {
|
||||||
if ($params['shareType'] === \OCP\Share::SHARE_TYPE_LINK) {
|
if ($params['shareType'] === \OCP\Share::SHARE_TYPE_LINK || $params['shareType'] === \OCP\Share::SHARE_TYPE_REMOTE) {
|
||||||
$userIds = array($util->getPublicShareKeyId());
|
$userIds = array($util->getPublicShareKeyId());
|
||||||
} else {
|
} else {
|
||||||
$userIds = array($params['shareWith']);
|
$userIds = array($params['shareWith']);
|
||||||
|
@ -619,8 +618,8 @@ class Hooks {
|
||||||
|
|
||||||
// check if the user still has access to the file, otherwise delete share key
|
// check if the user still has access to the file, otherwise delete share key
|
||||||
$sharingUsers = \OCP\Share::getUsersSharingFile($path, $user);
|
$sharingUsers = \OCP\Share::getUsersSharingFile($path, $user);
|
||||||
if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) {
|
if (!in_array($user, $sharingUsers['users'])) {
|
||||||
Keymanager::delShareKey($view, array(\OCP\User::getUser()), $keyPath, $owner, $ownerPath);
|
Keymanager::delShareKey($view, array($user), $keyPath, $owner, $ownerPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1207,13 +1207,7 @@ class Util {
|
||||||
|
|
||||||
// handle public access
|
// handle public access
|
||||||
if ($this->isPublic) {
|
if ($this->isPublic) {
|
||||||
$filename = $path;
|
return array($this->userId, $path);
|
||||||
$fileOwnerUid = $this->userId;
|
|
||||||
|
|
||||||
return array(
|
|
||||||
$fileOwnerUid,
|
|
||||||
$filename
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Check that UID is valid
|
// Check that UID is valid
|
||||||
|
|
|
@ -115,6 +115,91 @@ class Share extends TestCase {
|
||||||
parent::tearDownAfterClass();
|
parent::tearDownAfterClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @medium
|
||||||
|
*/
|
||||||
|
function testDeclineServer2ServerShare() {
|
||||||
|
|
||||||
|
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$certificateManager = $this->getMock('\OCP\ICertificateManager');
|
||||||
|
$httpHelperMock = $this->getMockBuilder('\OC\HTTPHelper')
|
||||||
|
->setConstructorArgs(array($config, $certificateManager))
|
||||||
|
->getMock();
|
||||||
|
$httpHelperMock->expects($this->once())->method('post')->with($this->anything())->will($this->returnValue(true));
|
||||||
|
|
||||||
|
self::loginHelper(self::TEST_ENCRYPTION_SHARE_USER1);
|
||||||
|
|
||||||
|
// save file with content
|
||||||
|
$cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort);
|
||||||
|
|
||||||
|
// test that data was successfully written
|
||||||
|
$this->assertTrue(is_int($cryptedFile));
|
||||||
|
|
||||||
|
// get the file info from previous created file
|
||||||
|
$fileInfo = $this->view->getFileInfo(
|
||||||
|
'/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
|
||||||
|
|
||||||
|
|
||||||
|
// share the file
|
||||||
|
$token = \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, '', \OCP\Constants::PERMISSION_ALL);
|
||||||
|
$this->assertTrue(is_string($token));
|
||||||
|
|
||||||
|
$publicShareKeyId = \OC::$server->getConfig()->getAppValue('files_encryption', 'publicShareKeyId');
|
||||||
|
|
||||||
|
// check if share key for public exists
|
||||||
|
$this->assertTrue($this->view->file_exists(
|
||||||
|
'/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/keys/'
|
||||||
|
. $this->filename . '/' . $publicShareKeyId . '.shareKey'));
|
||||||
|
|
||||||
|
// manipulate share
|
||||||
|
$query = \OC::$server->getDatabaseConnection()->prepare('UPDATE `*PREFIX*share` SET `share_type` = ?, `share_with` = ? WHERE `token`=?');
|
||||||
|
$this->assertTrue($query->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, 'foo@bar', $token)));
|
||||||
|
|
||||||
|
// check if share key not exists
|
||||||
|
$this->assertTrue($this->view->file_exists(
|
||||||
|
'/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/keys/'
|
||||||
|
. $this->filename . '/' . $publicShareKeyId . '.shareKey'));
|
||||||
|
|
||||||
|
|
||||||
|
$query = \OC::$server->getDatabaseConnection()->prepare('SELECT * FROM `*PREFIX*share` WHERE `token`=?');
|
||||||
|
$query->execute(array($token));
|
||||||
|
|
||||||
|
$share = $query->fetch();
|
||||||
|
|
||||||
|
$this->registerHttpHelper($httpHelperMock);
|
||||||
|
$_POST['token'] = $token;
|
||||||
|
$s2s = new \OCA\Files_Sharing\API\Server2Server();
|
||||||
|
$s2s->declineShare(array('id' => $share['id']));
|
||||||
|
$this->restoreHttpHelper();
|
||||||
|
|
||||||
|
$this->assertFalse($this->view->file_exists(
|
||||||
|
'/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/keys/'
|
||||||
|
. $this->filename . '/' . $publicShareKeyId . '.shareKey'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an http helper mock for testing purposes.
|
||||||
|
* @param $httpHelper http helper mock
|
||||||
|
*/
|
||||||
|
private function registerHttpHelper($httpHelper) {
|
||||||
|
$this->oldHttpHelper = \OC::$server->query('HTTPHelper');
|
||||||
|
\OC::$server->registerService('HTTPHelper', function ($c) use ($httpHelper) {
|
||||||
|
return $httpHelper;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the original http helper
|
||||||
|
*/
|
||||||
|
private function restoreHttpHelper() {
|
||||||
|
$oldHttpHelper = $this->oldHttpHelper;
|
||||||
|
\OC::$server->registerService('HTTPHelper', function ($c) use ($oldHttpHelper) {
|
||||||
|
return $oldHttpHelper;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @medium
|
* @medium
|
||||||
|
|
|
@ -34,7 +34,8 @@ $externalManager = new \OCA\Files_Sharing\External\Manager(
|
||||||
\OC::$server->getDatabaseConnection(),
|
\OC::$server->getDatabaseConnection(),
|
||||||
\OC\Files\Filesystem::getMountManager(),
|
\OC\Files\Filesystem::getMountManager(),
|
||||||
\OC\Files\Filesystem::getLoader(),
|
\OC\Files\Filesystem::getLoader(),
|
||||||
\OC::$server->getUserSession()
|
\OC::$server->getUserSession(),
|
||||||
|
\OC::$server->getHTTPHelper()
|
||||||
);
|
);
|
||||||
|
|
||||||
$name = OCP\Files::buildNotExistingFileName('/', $name);
|
$name = OCP\Files::buildNotExistingFileName('/', $name);
|
||||||
|
@ -44,7 +45,7 @@ if (substr($remote, 0, 5) === 'https' and !OC_Util::getUrlContent($remote)) {
|
||||||
\OCP\JSON::error(array('data' => array('message' => $l->t("Invalid or untrusted SSL certificate"))));
|
\OCP\JSON::error(array('data' => array('message' => $l->t("Invalid or untrusted SSL certificate"))));
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
$mount = $externalManager->addShare($remote, $token, $password, $name, $owner);
|
$mount = $externalManager->addShare($remote, $token, $password, $name, $owner, true);
|
||||||
/**
|
/**
|
||||||
* @var \OCA\Files_Sharing\External\Storage $storage
|
* @var \OCA\Files_Sharing\External\Storage $storage
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Server2Server {
|
||||||
public function createShare($params) {
|
public function createShare($params) {
|
||||||
|
|
||||||
if (!$this->isS2SEnabled(true)) {
|
if (!$this->isS2SEnabled(true)) {
|
||||||
return \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
return new \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
|
$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
|
||||||
|
@ -42,7 +42,7 @@ class Server2Server {
|
||||||
$name = isset($_POST['name']) ? $_POST['name'] : null;
|
$name = isset($_POST['name']) ? $_POST['name'] : null;
|
||||||
$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
|
$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
|
||||||
$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
|
$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
|
||||||
$remoteId = isset($_POST['remote_id']) ? (int)$_POST['remote_id'] : null;
|
$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
|
||||||
|
|
||||||
if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
|
if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
|
||||||
|
|
||||||
|
@ -56,19 +56,28 @@ class Server2Server {
|
||||||
|
|
||||||
\OC_Util::setupFS($shareWith);
|
\OC_Util::setupFS($shareWith);
|
||||||
|
|
||||||
$mountPoint = \OC\Files\Filesystem::normalizePath('/' . $name);
|
$externalManager = new \OCA\Files_Sharing\External\Manager(
|
||||||
|
\OC::$server->getDatabaseConnection(),
|
||||||
|
\OC\Files\Filesystem::getMountManager(),
|
||||||
|
\OC\Files\Filesystem::getLoader(),
|
||||||
|
\OC::$server->getUserSession(),
|
||||||
|
\OC::$server->getHTTPHelper());
|
||||||
|
|
||||||
$name = \OCP\Files::buildNotExistingFileName('/', $name);
|
$name = \OCP\Files::buildNotExistingFileName('/', $name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
\OCA\Files_Sharing\Helper::addServer2ServerShare($remote, $token, $name, $mountPoint, $owner, $shareWith, '', $remoteId);
|
$externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
|
||||||
|
|
||||||
|
$user = $owner . '@' . $this->cleanupRemote($remote);
|
||||||
|
|
||||||
\OC::$server->getActivityManager()->publishActivity(
|
\OC::$server->getActivityManager()->publishActivity(
|
||||||
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($owner), '', array(),
|
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($user), '', array(),
|
||||||
'', '', $shareWith, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::PRIORITY_LOW);
|
'', '', $shareWith, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::PRIORITY_LOW);
|
||||||
|
|
||||||
return new \OC_OCS_Result();
|
return new \OC_OCS_Result();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return new \OC_OCS_Result(null, 500, 'server can not add remote share, ' . $e->getMessage());
|
\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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +93,7 @@ class Server2Server {
|
||||||
public function acceptShare($params) {
|
public function acceptShare($params) {
|
||||||
|
|
||||||
if (!$this->isS2SEnabled()) {
|
if (!$this->isS2SEnabled()) {
|
||||||
return \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
return new \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $params['id'];
|
$id = $params['id'];
|
||||||
|
@ -111,7 +120,7 @@ class Server2Server {
|
||||||
public function declineShare($params) {
|
public function declineShare($params) {
|
||||||
|
|
||||||
if (!$this->isS2SEnabled()) {
|
if (!$this->isS2SEnabled()) {
|
||||||
return \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
return new \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $params['id'];
|
$id = $params['id'];
|
||||||
|
@ -142,7 +151,7 @@ class Server2Server {
|
||||||
public function unshare($params) {
|
public function unshare($params) {
|
||||||
|
|
||||||
if (!$this->isS2SEnabled()) {
|
if (!$this->isS2SEnabled()) {
|
||||||
return \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
return new \OC_OCS_Result(null, 503, 'Server does not support server-to-server sharing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $params['id'];
|
$id = $params['id'];
|
||||||
|
@ -154,7 +163,9 @@ class Server2Server {
|
||||||
|
|
||||||
if ($token && $id && !empty($share)) {
|
if ($token && $id && !empty($share)) {
|
||||||
|
|
||||||
$owner = $share['owner'] . '@' . $share['remote'];
|
$remote = $this->cleanupRemote($share['remote']);
|
||||||
|
|
||||||
|
$owner = $share['owner'] . '@' . $remote;
|
||||||
$mountpoint = $share['mountpoint'];
|
$mountpoint = $share['mountpoint'];
|
||||||
$user = $share['user'];
|
$user = $share['user'];
|
||||||
|
|
||||||
|
@ -162,13 +173,19 @@ class Server2Server {
|
||||||
$query->execute(array($id, $token));
|
$query->execute(array($id, $token));
|
||||||
|
|
||||||
\OC::$server->getActivityManager()->publishActivity(
|
\OC::$server->getActivityManager()->publishActivity(
|
||||||
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_DECLINED, array($owner, $mountpoint), '', array(),
|
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_UNSHARED, array($owner, $mountpoint), '', array(),
|
||||||
'', '', $user, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::PRIORITY_MEDIUM);
|
'', '', $user, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::PRIORITY_MEDIUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new \OC_OCS_Result();
|
return new \OC_OCS_Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function cleanupRemote($remote) {
|
||||||
|
$remote = substr($remote, strpos($remote, '://') + 3);
|
||||||
|
|
||||||
|
return rtrim($remote, '/');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get share
|
* get share
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\Files_Sharing\AppInfo;
|
||||||
|
|
||||||
|
use OCA\Files_Sharing\Application;
|
||||||
|
|
||||||
|
$application = new Application();
|
||||||
|
$application->registerRoutes($this, [
|
||||||
|
'resources' => [
|
||||||
|
'ExternalShares' => ['url' => '/api/externalShares'],
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
/** @var $this \OCP\Route\IRouter */
|
/** @var $this \OCP\Route\IRouter */
|
||||||
$this->create('core_ajax_public_preview', '/publicpreview')->action(
|
$this->create('core_ajax_public_preview', '/publicpreview')->action(
|
||||||
function() {
|
function() {
|
||||||
|
@ -16,31 +27,32 @@ $this->create('sharing_external_add', '/external')
|
||||||
->actionInclude('files_sharing/ajax/external.php');
|
->actionInclude('files_sharing/ajax/external.php');
|
||||||
$this->create('sharing_external_test_remote', '/testremote')
|
$this->create('sharing_external_test_remote', '/testremote')
|
||||||
->actionInclude('files_sharing/ajax/testremote.php');
|
->actionInclude('files_sharing/ajax/testremote.php');
|
||||||
|
|
||||||
// OCS API
|
// OCS API
|
||||||
|
|
||||||
//TODO: SET: mail notification, waiting for PR #4689 to be accepted
|
//TODO: SET: mail notification, waiting for PR #4689 to be accepted
|
||||||
|
|
||||||
OC_API::register('get',
|
\OC_API::register('get',
|
||||||
'/apps/files_sharing/api/v1/shares',
|
'/apps/files_sharing/api/v1/shares',
|
||||||
array('\OCA\Files_Sharing\API\Local', 'getAllShares'),
|
array('\OCA\Files_Sharing\API\Local', 'getAllShares'),
|
||||||
'files_sharing');
|
'files_sharing');
|
||||||
|
|
||||||
OC_API::register('post',
|
\OC_API::register('post',
|
||||||
'/apps/files_sharing/api/v1/shares',
|
'/apps/files_sharing/api/v1/shares',
|
||||||
array('\OCA\Files_Sharing\API\Local', 'createShare'),
|
array('\OCA\Files_Sharing\API\Local', 'createShare'),
|
||||||
'files_sharing');
|
'files_sharing');
|
||||||
|
|
||||||
OC_API::register('get',
|
\OC_API::register('get',
|
||||||
'/apps/files_sharing/api/v1/shares/{id}',
|
'/apps/files_sharing/api/v1/shares/{id}',
|
||||||
array('\OCA\Files_Sharing\API\Local', 'getShare'),
|
array('\OCA\Files_Sharing\API\Local', 'getShare'),
|
||||||
'files_sharing');
|
'files_sharing');
|
||||||
|
|
||||||
OC_API::register('put',
|
\OC_API::register('put',
|
||||||
'/apps/files_sharing/api/v1/shares/{id}',
|
'/apps/files_sharing/api/v1/shares/{id}',
|
||||||
array('\OCA\Files_Sharing\API\Local', 'updateShare'),
|
array('\OCA\Files_Sharing\API\Local', 'updateShare'),
|
||||||
'files_sharing');
|
'files_sharing');
|
||||||
|
|
||||||
OC_API::register('delete',
|
\OC_API::register('delete',
|
||||||
'/apps/files_sharing/api/v1/shares/{id}',
|
'/apps/files_sharing/api/v1/shares/{id}',
|
||||||
array('\OCA\Files_Sharing\API\Local', 'deleteShare'),
|
array('\OCA\Files_Sharing\API\Local', 'deleteShare'),
|
||||||
'files_sharing');
|
'files_sharing');
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
namespace OCA\Files_Sharing;
|
namespace OCA\Files_Sharing;
|
||||||
|
|
||||||
use OC\AppFramework\Utility\SimpleContainer;
|
use OC\AppFramework\Utility\SimpleContainer;
|
||||||
|
use OCA\Files_Sharing\Controllers\ExternalSharesController;
|
||||||
use OCA\Files_Sharing\Controllers\ShareController;
|
use OCA\Files_Sharing\Controllers\ShareController;
|
||||||
use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
|
use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
|
||||||
use \OCP\AppFramework\App;
|
use \OCP\AppFramework\App;
|
||||||
|
@ -44,6 +45,14 @@ class Application extends App {
|
||||||
$c->query('ServerContainer')->getLogger()
|
$c->query('ServerContainer')->getLogger()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
$container->registerService('ExternalSharesController', function(SimpleContainer $c) {
|
||||||
|
return new ExternalSharesController(
|
||||||
|
$c->query('AppName'),
|
||||||
|
$c->query('Request'),
|
||||||
|
$c->query('IsIncomingShareEnabled'),
|
||||||
|
$c->query('ExternalManager')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core class wrappers
|
* Core class wrappers
|
||||||
|
@ -54,6 +63,18 @@ class Application extends App {
|
||||||
$container->registerService('URLGenerator', function(SimpleContainer $c) {
|
$container->registerService('URLGenerator', function(SimpleContainer $c) {
|
||||||
return $c->query('ServerContainer')->getUrlGenerator();
|
return $c->query('ServerContainer')->getUrlGenerator();
|
||||||
});
|
});
|
||||||
|
$container->registerService('IsIncomingShareEnabled', function(SimpleContainer $c) {
|
||||||
|
return Helper::isIncomingServer2serverShareEnabled();
|
||||||
|
});
|
||||||
|
$container->registerService('ExternalManager', function(SimpleContainer $c) {
|
||||||
|
return new \OCA\Files_Sharing\External\Manager(
|
||||||
|
\OC::$server->getDatabaseConnection(),
|
||||||
|
\OC\Files\Filesystem::getMountManager(),
|
||||||
|
\OC\Files\Filesystem::getLoader(),
|
||||||
|
\OC::$server->getUserSession(),
|
||||||
|
\OC::$server->getHTTPHelper()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware
|
* Middleware
|
||||||
|
|
|
@ -8,16 +8,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
(function () {
|
(function () {
|
||||||
var addExternalShare = function (remote, token, owner, name, password) {
|
|
||||||
return $.post(OC.generateUrl('apps/files_sharing/external'), {
|
|
||||||
remote: remote,
|
|
||||||
token: token,
|
|
||||||
owner: owner,
|
|
||||||
name: name,
|
|
||||||
password: password
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows "add external share" dialog.
|
* Shows "add external share" dialog.
|
||||||
*
|
*
|
||||||
|
@ -27,20 +17,12 @@
|
||||||
* @param {String} token authentication token
|
* @param {String} token authentication token
|
||||||
* @param {bool} passwordProtected true if the share is password protected
|
* @param {bool} passwordProtected true if the share is password protected
|
||||||
*/
|
*/
|
||||||
OCA.Sharing.showAddExternalDialog = function (remote, token, owner, name, passwordProtected) {
|
OCA.Sharing.showAddExternalDialog = function (share, passwordProtected, callback) {
|
||||||
|
var remote = share.remote;
|
||||||
|
var owner = share.owner;
|
||||||
|
var name = share.name;
|
||||||
var remoteClean = (remote.substr(0, 8) === 'https://') ? remote.substr(8) : remote.substr(7);
|
var remoteClean = (remote.substr(0, 8) === 'https://') ? remote.substr(8) : remote.substr(7);
|
||||||
var callback = function (add, password) {
|
|
||||||
password = password || '';
|
|
||||||
if (add) {
|
|
||||||
addExternalShare(remote, token, owner, name, password).then(function (result) {
|
|
||||||
if (result.status === 'error') {
|
|
||||||
OC.Notification.show(result.data.message);
|
|
||||||
} else {
|
|
||||||
FileList.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!passwordProtected) {
|
if (!passwordProtected) {
|
||||||
OC.dialogs.confirm(
|
OC.dialogs.confirm(
|
||||||
t(
|
t(
|
||||||
|
@ -49,7 +31,9 @@
|
||||||
{name: name, owner: owner, remote: remoteClean}
|
{name: name, owner: owner, remote: remoteClean}
|
||||||
),
|
),
|
||||||
t('files_sharing','Remote share'),
|
t('files_sharing','Remote share'),
|
||||||
callback,
|
function (result) {
|
||||||
|
callback(result, share);
|
||||||
|
},
|
||||||
true
|
true
|
||||||
).then(this._adjustDialog);
|
).then(this._adjustDialog);
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +44,9 @@
|
||||||
{name: name, owner: owner, remote: remoteClean}
|
{name: name, owner: owner, remote: remoteClean}
|
||||||
),
|
),
|
||||||
t('files_sharing','Remote share'),
|
t('files_sharing','Remote share'),
|
||||||
callback,
|
function (result) {
|
||||||
|
callback(result, share);
|
||||||
|
},
|
||||||
true,
|
true,
|
||||||
t('files_sharing','Remote share password'),
|
t('files_sharing','Remote share password'),
|
||||||
true
|
true
|
||||||
|
@ -82,17 +68,66 @@ $(document).ready(function () {
|
||||||
// FIXME: HACK: do not init when running unit tests, need a better way
|
// FIXME: HACK: do not init when running unit tests, need a better way
|
||||||
if (!window.TESTING && OCA.Files) {// only run in the files app
|
if (!window.TESTING && OCA.Files) {// only run in the files app
|
||||||
var params = OC.Util.History.parseUrlQuery();
|
var params = OC.Util.History.parseUrlQuery();
|
||||||
|
|
||||||
|
//manually add server-to-server share
|
||||||
if (params.remote && params.token && params.owner && params.name) {
|
if (params.remote && params.token && params.owner && params.name) {
|
||||||
|
|
||||||
|
var callbackAddShare = function(result, share) {
|
||||||
|
var password = share.password || '';
|
||||||
|
if (result) {
|
||||||
|
//$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id});
|
||||||
|
$.post(OC.generateUrl('apps/files_sharing/external'), {
|
||||||
|
remote: share.remote,
|
||||||
|
token: share.token,
|
||||||
|
owner: share.owner,
|
||||||
|
name: share.name,
|
||||||
|
password: password}, function(result) {
|
||||||
|
if (result.status === 'error') {
|
||||||
|
OC.Notification.show(result.data.message);
|
||||||
|
} else {
|
||||||
|
FileList.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// clear hash, it is unlikely that it contain any extra parameters
|
// clear hash, it is unlikely that it contain any extra parameters
|
||||||
location.hash = '';
|
location.hash = '';
|
||||||
params.passwordProtected = parseInt(params.protected, 10) === 1;
|
params.passwordProtected = parseInt(params.protected, 10) === 1;
|
||||||
OCA.Sharing.showAddExternalDialog(
|
OCA.Sharing.showAddExternalDialog(
|
||||||
params.remote,
|
params,
|
||||||
params.token,
|
params.passwordProtected,
|
||||||
params.owner,
|
callbackAddShare
|
||||||
params.name,
|
|
||||||
params.passwordProtected
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// check for new server-to-server shares which need to be approved
|
||||||
|
$.get(OC.generateUrl('/apps/files_sharing/api/externalShares'),
|
||||||
|
{},
|
||||||
|
function(shares) {
|
||||||
|
var index;
|
||||||
|
for (index = 0; index < shares.length; ++index) {
|
||||||
|
OCA.Sharing.showAddExternalDialog(
|
||||||
|
shares[index],
|
||||||
|
false,
|
||||||
|
function(result, share) {
|
||||||
|
if (result) {
|
||||||
|
// Accept
|
||||||
|
$.post(OC.generateUrl('/apps/files_sharing/api/externalShares'), {id: share.id});
|
||||||
|
FileList.reload();
|
||||||
|
} else {
|
||||||
|
// Delete
|
||||||
|
$.ajax({
|
||||||
|
url: OC.generateUrl('/apps/files_sharing/api/externalShares/'+share.id),
|
||||||
|
type: 'DELETE'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -98,7 +98,7 @@ class Activity implements \OCP\Activity\IExtension {
|
||||||
case self::SUBJECT_REMOTE_SHARE_DECLINED:
|
case self::SUBJECT_REMOTE_SHARE_DECLINED:
|
||||||
return $l->t('%1$s declined remote share %2$s', $params)->__toString();
|
return $l->t('%1$s declined remote share %2$s', $params)->__toString();
|
||||||
case self::SUBJECT_REMOTE_SHARE_UNSHARED:
|
case self::SUBJECT_REMOTE_SHARE_UNSHARED:
|
||||||
return $l->t('%1$s unshared %2$s', $params)->__toString();
|
return $l->t('%1$s unshared %2$s from you', $params)->__toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} elseif ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_REMOTE) {
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Lukas Reschke <lukas@owncloud.com>
|
||||||
|
* @copyright 2014 Lukas Reschke
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Files_Sharing\Controllers;
|
||||||
|
|
||||||
|
use OC;
|
||||||
|
use OCP;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ExternalSharesController
|
||||||
|
*
|
||||||
|
* @package OCA\Files_Sharing\Controllers
|
||||||
|
*/
|
||||||
|
class ExternalSharesController extends Controller {
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $incomingShareEnabled;
|
||||||
|
/** @var \OCA\Files_Sharing\External\Manager */
|
||||||
|
private $externalManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $appName
|
||||||
|
* @param IRequest $request
|
||||||
|
* @param \OCA\Files_Sharing\External\Manager $externalManager
|
||||||
|
*/
|
||||||
|
public function __construct($appName,
|
||||||
|
IRequest $request,
|
||||||
|
$incomingShareEnabled,
|
||||||
|
\OCA\Files_Sharing\External\Manager $externalManager) {
|
||||||
|
parent::__construct($appName, $request);
|
||||||
|
$this->incomingShareEnabled = $incomingShareEnabled;
|
||||||
|
$this->externalManager = $externalManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function index() {
|
||||||
|
$shares = [];
|
||||||
|
if ($this->incomingShareEnabled) {
|
||||||
|
$shares = $this->externalManager->getOpenShares();
|
||||||
|
}
|
||||||
|
return new JSONResponse($shares);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function create($id) {
|
||||||
|
if ($this->incomingShareEnabled) {
|
||||||
|
$this->externalManager->acceptShare($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JSONResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* @param $id
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function destroy($id) {
|
||||||
|
if ($this->incomingShareEnabled) {
|
||||||
|
$this->externalManager->declineShare($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JSONResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,11 @@ class Manager {
|
||||||
*/
|
*/
|
||||||
private $userSession;
|
private $userSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \OC\HTTPHelper
|
||||||
|
*/
|
||||||
|
private $httpHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \OCP\IDBConnection $connection
|
* @param \OCP\IDBConnection $connection
|
||||||
* @param \OC\Files\Mount\Manager $mountManager
|
* @param \OC\Files\Mount\Manager $mountManager
|
||||||
|
@ -40,19 +45,30 @@ class Manager {
|
||||||
* @param \OC\Files\Storage\StorageFactory $storageLoader
|
* @param \OC\Files\Storage\StorageFactory $storageLoader
|
||||||
*/
|
*/
|
||||||
public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
|
public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
|
||||||
\OC\Files\Storage\StorageFactory $storageLoader, \OC\User\Session $userSession) {
|
\OC\Files\Storage\StorageFactory $storageLoader, \OC\User\Session $userSession, \OC\HTTPHelper $httpHelper) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
$this->mountManager = $mountManager;
|
$this->mountManager = $mountManager;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
$this->storageLoader = $storageLoader;
|
$this->storageLoader = $storageLoader;
|
||||||
|
$this->httpHelper = $httpHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addShare($remote, $token, $password, $name, $owner) {
|
public function addShare($remote, $token, $password, $name, $owner, $accepted=false, $user = null, $remoteId = -1) {
|
||||||
$user = $this->userSession->getUser();
|
|
||||||
if ($user) {
|
|
||||||
$mountPoint = Filesystem::normalizePath('/' . $name);
|
|
||||||
\OCA\Files_Sharing\Helper::addServer2ServerShare($remote, $token, $name, $mountPoint, $owner, $user->getUID(), $password, -1, true);
|
|
||||||
|
|
||||||
|
$user = $user ? $user: $this->userSession->getUser()->getUID();
|
||||||
|
$accepted = $accepted ? 1 : 0;
|
||||||
|
|
||||||
|
$mountPoint = Filesystem::normalizePath('/' . $name);
|
||||||
|
|
||||||
|
$query = $this->connection->prepare('
|
||||||
|
INSERT INTO `*PREFIX*share_external`
|
||||||
|
(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
');
|
||||||
|
$hash = md5($mountPoint);
|
||||||
|
$query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId));
|
||||||
|
|
||||||
|
if ($accepted) {
|
||||||
$options = array(
|
$options = array(
|
||||||
'remote' => $remote,
|
'remote' => $remote,
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
|
@ -87,12 +103,85 @@ class Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get share
|
||||||
|
*
|
||||||
|
* @param int $id share id
|
||||||
|
* @return mixed share of false
|
||||||
|
*/
|
||||||
|
private function getShare($id) {
|
||||||
|
$getShare = $this->connection->prepare('
|
||||||
|
SELECT `remote`, `share_token`
|
||||||
|
FROM `*PREFIX*share_external`
|
||||||
|
WHERE `id` = ? AND `user` = ?');
|
||||||
|
$result = $getShare->execute(array($id, $this->userSession->getUser()->getUID()));
|
||||||
|
|
||||||
|
return $result ? $getShare->fetch() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* accept server-to-server share
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public function acceptShare($id) {
|
||||||
|
|
||||||
|
$share = $this->getShare($id);
|
||||||
|
|
||||||
|
if ($share) {
|
||||||
|
$acceptShare = $this->connection->prepare('
|
||||||
|
UPDATE `*PREFIX*share_external`
|
||||||
|
SET `accepted` = ?
|
||||||
|
WHERE `id` = ? AND `user` = ?');
|
||||||
|
$acceptShare->execute(array(1, $id, $this->userSession->getUser()->getUID()));
|
||||||
|
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'accept');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decline server-to-server share
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public function declineShare($id) {
|
||||||
|
|
||||||
|
$share = $this->getShare($id);
|
||||||
|
|
||||||
|
if ($share) {
|
||||||
|
$removeShare = $this->connection->prepare('
|
||||||
|
DELETE FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?');
|
||||||
|
$removeShare->execute(array($id, $this->userSession->getUser()->getUID()));
|
||||||
|
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'decline');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inform remote server whether server-to-server share was accepted/declined
|
||||||
|
*
|
||||||
|
* @param string $remote
|
||||||
|
* @param string $token
|
||||||
|
* @param int $id
|
||||||
|
* @param string $feedback
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private function sendFeedbackToRemote($remote, $token, $id, $feedback) {
|
||||||
|
|
||||||
|
$url = $remote . \OCP\Share::BASE_PATH_TO_SHARE_API . '/' . $id . '/' . $feedback . '?format=' . \OCP\Share::RESPONSE_FORMAT;
|
||||||
|
$fields = array('token' => $token);
|
||||||
|
|
||||||
|
$result = $this->httpHelper->post($url, $fields);
|
||||||
|
$status = json_decode($result['result'], true);
|
||||||
|
|
||||||
|
return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
|
||||||
|
}
|
||||||
|
|
||||||
public static function setup() {
|
public static function setup() {
|
||||||
$externalManager = new \OCA\Files_Sharing\External\Manager(
|
$externalManager = new \OCA\Files_Sharing\External\Manager(
|
||||||
\OC::$server->getDatabaseConnection(),
|
\OC::$server->getDatabaseConnection(),
|
||||||
\OC\Files\Filesystem::getMountManager(),
|
\OC\Files\Filesystem::getMountManager(),
|
||||||
\OC\Files\Filesystem::getLoader(),
|
\OC\Files\Filesystem::getLoader(),
|
||||||
\OC::$server->getUserSession()
|
\OC::$server->getUserSession(),
|
||||||
|
\OC::$server->getHTTPHelper()
|
||||||
);
|
);
|
||||||
$externalManager->setupMounts();
|
$externalManager->setupMounts();
|
||||||
}
|
}
|
||||||
|
@ -151,6 +240,18 @@ class Manager {
|
||||||
$user = $this->userSession->getUser();
|
$user = $this->userSession->getUser();
|
||||||
$mountPoint = $this->stripPath($mountPoint);
|
$mountPoint = $this->stripPath($mountPoint);
|
||||||
$hash = md5($mountPoint);
|
$hash = md5($mountPoint);
|
||||||
|
|
||||||
|
$getShare = $this->connection->prepare('
|
||||||
|
SELECT `remote`, `share_token`, `remote_id`
|
||||||
|
FROM `*PREFIX*share_external`
|
||||||
|
WHERE `mountpoint_hash` = ? AND `user` = ?');
|
||||||
|
$result = $getShare->execute(array($hash, $user->getUID()));
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
$share = $getShare->fetch();
|
||||||
|
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
|
||||||
|
}
|
||||||
|
|
||||||
$query = $this->connection->prepare('
|
$query = $this->connection->prepare('
|
||||||
DELETE FROM `*PREFIX*share_external`
|
DELETE FROM `*PREFIX*share_external`
|
||||||
WHERE `mountpoint_hash` = ?
|
WHERE `mountpoint_hash` = ?
|
||||||
|
@ -158,4 +259,17 @@ class Manager {
|
||||||
');
|
');
|
||||||
return (bool)$query->execute(array($hash, $user->getUID()));
|
return (bool)$query->execute(array($hash, $user->getUID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a list of shares which are not yet accepted by the user
|
||||||
|
*
|
||||||
|
* @return array list of open server-to-server shares
|
||||||
|
*/
|
||||||
|
public function getOpenShares() {
|
||||||
|
$openShares = $this->connection->prepare('SELECT * FROM `*PREFIX*share_external` WHERE `accepted` = ? AND `user` = ?');
|
||||||
|
$result = $openShares->execute(array(0, $this->userSession->getUser()->getUID()));
|
||||||
|
|
||||||
|
return $result ? $openShares->fetchAll() : array();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
namespace OCA\Files_Sharing;
|
namespace OCA\Files_Sharing;
|
||||||
|
|
||||||
use OC_Config;
|
|
||||||
|
|
||||||
class Helper {
|
class Helper {
|
||||||
|
|
||||||
public static function registerHooks() {
|
public static function registerHooks() {
|
||||||
|
@ -20,30 +18,6 @@ class Helper {
|
||||||
\OCP\Util::connectHook('OCP\Share', 'post_unshareFromSelf', '\OC\Files\Cache\Shared_Updater', 'postUnshareFromSelfHook');
|
\OCP\Util::connectHook('OCP\Share', 'post_unshareFromSelf', '\OC\Files\Cache\Shared_Updater', 'postUnshareFromSelfHook');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* add server-to-server share to database
|
|
||||||
*
|
|
||||||
* @param string $remote
|
|
||||||
* @param string $token
|
|
||||||
* @param string $name
|
|
||||||
* @param string $mountPoint
|
|
||||||
* @param string $owner
|
|
||||||
* @param string $user
|
|
||||||
* @param string $password
|
|
||||||
* @param int $remoteId
|
|
||||||
* @param bool $accepted
|
|
||||||
*/
|
|
||||||
public static function addServer2ServerShare($remote, $token, $name, $mountPoint, $owner, $user, $password='', $remoteId=-1, $accepted = false) {
|
|
||||||
$accepted = $accepted ? 1 : 0;
|
|
||||||
$query = \OCP\DB::prepare('
|
|
||||||
INSERT INTO `*PREFIX*share_external`
|
|
||||||
(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
');
|
|
||||||
$hash = md5($mountPoint);
|
|
||||||
$query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the filesystem and user for public sharing
|
* Sets up the filesystem and user for public sharing
|
||||||
* @param string $token string share token
|
* @param string $token string share token
|
||||||
|
@ -89,7 +63,7 @@ class Helper {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($linkItem['share_with'])) {
|
if (isset($linkItem['share_with']) && (int)$linkItem['share_type'] === \OCP\Share::SHARE_TYPE_LINK) {
|
||||||
if (!self::authenticate($linkItem, $password)) {
|
if (!self::authenticate($linkItem, $password)) {
|
||||||
\OC_Response::setStatus(403);
|
\OC_Response::setStatus(403);
|
||||||
\OCP\JSON::error(array('success' => false));
|
\OCP\JSON::error(array('success' => false));
|
||||||
|
|
|
@ -159,6 +159,20 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if server2server share is enabled
|
||||||
|
*
|
||||||
|
* @param int $shareType
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isShareTypeAllowed($shareType) {
|
||||||
|
if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
|
||||||
|
return \OCA\Files_Sharing\Helper::isOutgoingServer2serverShareEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resolve reshares to return the correct source item
|
* resolve reshares to return the correct source item
|
||||||
* @param array $source
|
* @param array $source
|
||||||
|
|
|
@ -161,7 +161,10 @@ class Shared_Updater {
|
||||||
*/
|
*/
|
||||||
static public function postUnshareHook($params) {
|
static public function postUnshareHook($params) {
|
||||||
|
|
||||||
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
|
// only update etags for file/folders shared to local users/groups
|
||||||
|
if (($params['itemType'] === 'file' || $params['itemType'] === 'folder') &&
|
||||||
|
$params['shareType'] !== \OCP\Share::SHARE_TYPE_LINK &&
|
||||||
|
$params['shareType'] !== \OCP\Share::SHARE_TYPE_REMOTE) {
|
||||||
|
|
||||||
$deletedShares = isset($params['deletedShares']) ? $params['deletedShares'] : array();
|
$deletedShares = isset($params['deletedShares']) ? $params['deletedShares'] : array();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,16 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
||||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||||
\OCP\Share::registerBackend('test', 'Test_Share_Backend');
|
\OCP\Share::registerBackend('test', 'Test_Share_Backend');
|
||||||
|
|
||||||
|
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$certificateManager = $this->getMock('\OCP\ICertificateManager');
|
||||||
|
$httpHelperMock = $this->getMockBuilder('\OC\HTTPHelper')
|
||||||
|
->setConstructorArgs(array($config, $certificateManager))
|
||||||
|
->getMock();
|
||||||
|
$httpHelperMock->expects($this->any())->method('post')->with($this->anything())->will($this->returnValue(true));
|
||||||
|
|
||||||
|
$this->registerHttpHelper($httpHelperMock);
|
||||||
|
|
||||||
$this->s2s = new \OCA\Files_Sharing\API\Server2Server();
|
$this->s2s = new \OCA\Files_Sharing\API\Server2Server();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +55,32 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
||||||
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external`');
|
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external`');
|
||||||
$query->execute();
|
$query->execute();
|
||||||
|
|
||||||
|
$this->restoreHttpHelper();
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an http helper mock for testing purposes.
|
||||||
|
* @param $httpHelper http helper mock
|
||||||
|
*/
|
||||||
|
private function registerHttpHelper($httpHelper) {
|
||||||
|
$this->oldHttpHelper = \OC::$server->query('HTTPHelper');
|
||||||
|
\OC::$server->registerService('HTTPHelper', function ($c) use ($httpHelper) {
|
||||||
|
return $httpHelper;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the original http helper
|
||||||
|
*/
|
||||||
|
private function restoreHttpHelper() {
|
||||||
|
$oldHttpHelper = $this->oldHttpHelper;
|
||||||
|
\OC::$server->registerService('HTTPHelper', function ($c) use ($oldHttpHelper) {
|
||||||
|
return $oldHttpHelper;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @medium
|
* @medium
|
||||||
*/
|
*/
|
||||||
|
@ -58,7 +91,7 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
||||||
$_POST['name'] = 'name';
|
$_POST['name'] = 'name';
|
||||||
$_POST['owner'] = 'owner';
|
$_POST['owner'] = 'owner';
|
||||||
$_POST['shareWith'] = self::TEST_FILES_SHARING_API_USER2;
|
$_POST['shareWith'] = self::TEST_FILES_SHARING_API_USER2;
|
||||||
$_POST['remote_id'] = 1;
|
$_POST['remoteId'] = 1;
|
||||||
|
|
||||||
$result = $this->s2s->createShare(null);
|
$result = $this->s2s->createShare(null);
|
||||||
|
|
||||||
|
@ -81,10 +114,10 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
|
||||||
function testDeclineShare() {
|
function testDeclineShare() {
|
||||||
$dummy = \OCP\DB::prepare('
|
$dummy = \OCP\DB::prepare('
|
||||||
INSERT INTO `*PREFIX*share`
|
INSERT INTO `*PREFIX*share`
|
||||||
(`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`)
|
(`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
');
|
');
|
||||||
$dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token'));
|
$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`');
|
$verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
|
||||||
$result = $verify->execute();
|
$result = $verify->execute();
|
||||||
|
|
|
@ -309,6 +309,21 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allow user to add unknown remote addresses for server-to-server share
|
||||||
|
$backend = \OCP\Share::getBackend($_GET['itemType']);
|
||||||
|
if ($backend->isShareTypeAllowed(\OCP\Share::SHARE_TYPE_REMOTE)) {
|
||||||
|
if (substr_count($_GET['search'], '@') === 1) {
|
||||||
|
$shareWith[] = array(
|
||||||
|
'label' => $_GET['search'],
|
||||||
|
'value' => array(
|
||||||
|
'shareType' => \OCP\Share::SHARE_TYPE_REMOTE,
|
||||||
|
'shareWith' => $_GET['search']
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$sorter = new \OC\Share\SearchResultSorter($_GET['search'],
|
$sorter = new \OC\Share\SearchResultSorter($_GET['search'],
|
||||||
'label',
|
'label',
|
||||||
new \OC\Log());
|
new \OC\Log());
|
||||||
|
|
|
@ -8,6 +8,7 @@ OC.Share={
|
||||||
SHARE_TYPE_GROUP:1,
|
SHARE_TYPE_GROUP:1,
|
||||||
SHARE_TYPE_LINK:3,
|
SHARE_TYPE_LINK:3,
|
||||||
SHARE_TYPE_EMAIL:4,
|
SHARE_TYPE_EMAIL:4,
|
||||||
|
SHARE_TYPE_REMOTE:6,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regular expression for splitting parts of remote share owners:
|
* Regular expression for splitting parts of remote share owners:
|
||||||
|
@ -443,10 +444,14 @@ OC.Share={
|
||||||
} else {
|
} else {
|
||||||
if (share.collection) {
|
if (share.collection) {
|
||||||
OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, share.collection);
|
OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, share.collection);
|
||||||
|
} else {
|
||||||
|
if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
|
OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE, share.mail_send, false);
|
||||||
} else {
|
} else {
|
||||||
OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, false);
|
OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (share.expiration != null) {
|
if (share.expiration != null) {
|
||||||
OC.Share.showExpirationDate(share.expiration, share.stime);
|
OC.Share.showExpirationDate(share.expiration, share.stime);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +460,7 @@ OC.Share={
|
||||||
$('#shareWith').autocomplete({minLength: 2, delay: 750, source: function(search, response) {
|
$('#shareWith').autocomplete({minLength: 2, delay: 750, source: function(search, response) {
|
||||||
var $loading = $('#dropdown .shareWithLoading');
|
var $loading = $('#dropdown .shareWithLoading');
|
||||||
$loading.removeClass('hidden');
|
$loading.removeClass('hidden');
|
||||||
$.get(OC.filePath('core', 'ajax', 'share.php'), { fetch: 'getShareWith', search: search.term.trim(), itemShares: OC.Share.itemShares }, function(result) {
|
$.get(OC.filePath('core', 'ajax', 'share.php'), { fetch: 'getShareWith', search: search.term.trim(), itemShares: OC.Share.itemShares, itemType: itemType }, function(result) {
|
||||||
$loading.addClass('hidden');
|
$loading.addClass('hidden');
|
||||||
if (result.status == 'success' && result.data.length > 0) {
|
if (result.status == 'success' && result.data.length > 0) {
|
||||||
$( "#shareWith" ).autocomplete( "option", "autoFocus", true );
|
$( "#shareWith" ).autocomplete( "option", "autoFocus", true );
|
||||||
|
@ -484,6 +489,9 @@ OC.Share={
|
||||||
// Default permissions are Edit (CRUD) and Share
|
// Default permissions are Edit (CRUD) and Share
|
||||||
// Check if these permissions are possible
|
// Check if these permissions are possible
|
||||||
var permissions = OC.PERMISSION_READ;
|
var permissions = OC.PERMISSION_READ;
|
||||||
|
if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
|
permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_READ;
|
||||||
|
} else {
|
||||||
if (possiblePermissions & OC.PERMISSION_UPDATE) {
|
if (possiblePermissions & OC.PERMISSION_UPDATE) {
|
||||||
permissions = permissions | OC.PERMISSION_UPDATE;
|
permissions = permissions | OC.PERMISSION_UPDATE;
|
||||||
}
|
}
|
||||||
|
@ -496,7 +504,7 @@ OC.Share={
|
||||||
if (oc_appconfig.core.resharingAllowed && (possiblePermissions & OC.PERMISSION_SHARE)) {
|
if (oc_appconfig.core.resharingAllowed && (possiblePermissions & OC.PERMISSION_SHARE)) {
|
||||||
permissions = permissions | OC.PERMISSION_SHARE;
|
permissions = permissions | OC.PERMISSION_SHARE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var $input = $(this);
|
var $input = $(this);
|
||||||
var $loading = $dropDown.find('.shareWithLoading');
|
var $loading = $dropDown.find('.shareWithLoading');
|
||||||
|
@ -507,7 +515,11 @@ OC.Share={
|
||||||
OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, function() {
|
OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, function() {
|
||||||
$input.prop('disabled', false);
|
$input.prop('disabled', false);
|
||||||
$loading.addClass('hidden');
|
$loading.addClass('hidden');
|
||||||
OC.Share.addShareWith(shareType, shareWith, selected.item.label, permissions, possiblePermissions);
|
var posPermissions = possiblePermissions;
|
||||||
|
if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
|
posPermissions = permissions;
|
||||||
|
}
|
||||||
|
OC.Share.addShareWith(shareType, shareWith, selected.item.label, permissions, posPermissions);
|
||||||
$('#shareWith').val('');
|
$('#shareWith').val('');
|
||||||
$('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
|
$('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
|
||||||
OC.Share.updateIcon(itemType, itemSource);
|
OC.Share.updateIcon(itemType, itemSource);
|
||||||
|
@ -518,13 +530,18 @@ OC.Share={
|
||||||
// customize internal _renderItem function to display groups and users differently
|
// customize internal _renderItem function to display groups and users differently
|
||||||
.data("ui-autocomplete")._renderItem = function( ul, item ) {
|
.data("ui-autocomplete")._renderItem = function( ul, item ) {
|
||||||
var insert = $( "<a>" );
|
var insert = $( "<a>" );
|
||||||
var text = (item.value.shareType == 1)? item.label + ' ('+t('core', 'group')+')' : item.label;
|
var text = item.label;
|
||||||
|
if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||||
|
text = text + ' ('+t('core', 'group')+')';
|
||||||
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
|
text = text + ' ('+t('core', 'remote')+')';
|
||||||
|
}
|
||||||
insert.text( text );
|
insert.text( text );
|
||||||
if(item.value.shareType == 1) {
|
if(item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||||
insert = insert.wrapInner('<strong></strong>');
|
insert = insert.wrapInner('<strong></strong>');
|
||||||
}
|
}
|
||||||
return $( "<li>" )
|
return $( "<li>" )
|
||||||
.addClass((item.value.shareType == 1)?'group':'user')
|
.addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP)?'group':'user')
|
||||||
.append( insert )
|
.append( insert )
|
||||||
.appendTo( ul );
|
.appendTo( ul );
|
||||||
};
|
};
|
||||||
|
@ -585,9 +602,12 @@ OC.Share={
|
||||||
share_with_displayname: shareWithDisplayName,
|
share_with_displayname: shareWithDisplayName,
|
||||||
permissions: permissions
|
permissions: permissions
|
||||||
};
|
};
|
||||||
if (shareType === 1) {
|
if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
||||||
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')';
|
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')';
|
||||||
}
|
}
|
||||||
|
if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
|
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'remote') + ')';
|
||||||
|
}
|
||||||
if (!OC.Share.itemShares[shareType]) {
|
if (!OC.Share.itemShares[shareType]) {
|
||||||
OC.Share.itemShares[shareType] = [];
|
OC.Share.itemShares[shareType] = [];
|
||||||
}
|
}
|
||||||
|
@ -627,7 +647,7 @@ OC.Share={
|
||||||
html += '<a href="#" class="unshare"><img class="svg" alt="'+t('core', 'Unshare')+'" title="'+t('core', 'Unshare')+'" src="'+OC.imagePath('core', 'actions/delete')+'"/></a>';
|
html += '<a href="#" class="unshare"><img class="svg" alt="'+t('core', 'Unshare')+'" title="'+t('core', 'Unshare')+'" src="'+OC.imagePath('core', 'actions/delete')+'"/></a>';
|
||||||
html += '<span class="username">' + escapeHTML(shareWithDisplayName) + '</span>';
|
html += '<span class="username">' + escapeHTML(shareWithDisplayName) + '</span>';
|
||||||
var mailNotificationEnabled = $('input:hidden[name=mailNotificationEnabled]').val();
|
var mailNotificationEnabled = $('input:hidden[name=mailNotificationEnabled]').val();
|
||||||
if (mailNotificationEnabled === 'yes') {
|
if (mailNotificationEnabled === 'yes' && shareType !== OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
var checked = '';
|
var checked = '';
|
||||||
if (mailSend === '1') {
|
if (mailSend === '1') {
|
||||||
checked = 'checked';
|
checked = 'checked';
|
||||||
|
@ -640,7 +660,9 @@ OC.Share={
|
||||||
if (possiblePermissions & OC.PERMISSION_CREATE || possiblePermissions & OC.PERMISSION_UPDATE || possiblePermissions & OC.PERMISSION_DELETE) {
|
if (possiblePermissions & OC.PERMISSION_CREATE || possiblePermissions & OC.PERMISSION_UPDATE || possiblePermissions & OC.PERMISSION_DELETE) {
|
||||||
html += '<input id="canEdit-'+escapeHTML(shareWith)+'" type="checkbox" name="edit" class="permissions" '+editChecked+' /><label for="canEdit-'+escapeHTML(shareWith)+'">'+t('core', 'can edit')+'</label>';
|
html += '<input id="canEdit-'+escapeHTML(shareWith)+'" type="checkbox" name="edit" class="permissions" '+editChecked+' /><label for="canEdit-'+escapeHTML(shareWith)+'">'+t('core', 'can edit')+'</label>';
|
||||||
}
|
}
|
||||||
|
if (shareType !== OC.Share.SHARE_TYPE_REMOTE) {
|
||||||
showCrudsButton = '<a href="#" class="showCruds"><img class="svg" alt="'+t('core', 'access control')+'" src="'+OC.imagePath('core', 'actions/triangle-s')+'"/></a>';
|
showCrudsButton = '<a href="#" class="showCruds"><img class="svg" alt="'+t('core', 'access control')+'" src="'+OC.imagePath('core', 'actions/triangle-s')+'"/></a>';
|
||||||
|
}
|
||||||
html += '<div class="cruds" style="display:none;">';
|
html += '<div class="cruds" style="display:none;">';
|
||||||
if (possiblePermissions & OC.PERMISSION_CREATE) {
|
if (possiblePermissions & OC.PERMISSION_CREATE) {
|
||||||
html += '<input id="canCreate-' + escapeHTML(shareWith) + '" type="checkbox" name="create" class="permissions" ' + createChecked + ' data-permissions="' + OC.PERMISSION_CREATE + '"/><label for="canCreate-' + escapeHTML(shareWith) + '">' + t('core', 'create') + '</label>';
|
html += '<input id="canCreate-' + escapeHTML(shareWith) + '" type="checkbox" name="create" class="permissions" ' + createChecked + ' data-permissions="' + OC.PERMISSION_CREATE + '"/><label for="canCreate-' + escapeHTML(shareWith) + '">' + t('core', 'create') + '</label>';
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
namespace OC;
|
namespace OC;
|
||||||
|
|
||||||
use \OCP\IConfig;
|
use OCP\IConfig;
|
||||||
|
use OCP\ICertificateManager;
|
||||||
|
|
||||||
class HTTPHelper {
|
class HTTPHelper {
|
||||||
const USER_AGENT = 'ownCloud Server Crawler';
|
const USER_AGENT = 'ownCloud Server Crawler';
|
||||||
|
@ -16,11 +17,15 @@ class HTTPHelper {
|
||||||
/** @var \OCP\IConfig */
|
/** @var \OCP\IConfig */
|
||||||
private $config;
|
private $config;
|
||||||
|
|
||||||
|
/** @var \OC\Security\CertificateManager */
|
||||||
|
private $certificateManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \OCP\IConfig $config
|
* @param \OCP\IConfig $config
|
||||||
*/
|
*/
|
||||||
public function __construct(IConfig $config) {
|
public function __construct(IConfig $config, ICertificateManager $certificateManager) {
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
$this->certificateManager = $certificateManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,4 +181,50 @@ class HTTPHelper {
|
||||||
return $location;
|
return $location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create string of parameters for post request
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function assemblePostParameters(array $parameters) {
|
||||||
|
$parameterString = '';
|
||||||
|
foreach ($parameters as $key => $value) {
|
||||||
|
$parameterString .= $key . '=' . urlencode($value) . '&';
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtrim($parameterString, '&');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send http post request
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param array $fields data send by the request
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function post($url, array $fields) {
|
||||||
|
|
||||||
|
$fieldsString = $this->assemblePostParameters($fields);
|
||||||
|
|
||||||
|
$certBundle = $this->certificateManager->getCertificateBundle();
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, count($fields));
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $fieldsString);
|
||||||
|
if (is_readable($certBundle)) {
|
||||||
|
curl_setopt($ch, CURLOPT_CAINFO, $certBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = curl_exec($ch);
|
||||||
|
$success = $result ? true : false;
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return array('success' => $success, 'result' => $result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class CertificateManager implements ICertificateManager {
|
||||||
* @return \OCP\ICertificate[]
|
* @return \OCP\ICertificate[]
|
||||||
*/
|
*/
|
||||||
public function listCertificates() {
|
public function listCertificates() {
|
||||||
$path = $this->user->getHome() . '/files_external/uploads/';
|
$path = $this->getPathToCertificates() . 'uploads/';
|
||||||
if (!is_dir($path)) {
|
if (!is_dir($path)) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class CertificateManager implements ICertificateManager {
|
||||||
* create the certificate bundle of all trusted certificated
|
* create the certificate bundle of all trusted certificated
|
||||||
*/
|
*/
|
||||||
protected function createCertificateBundle() {
|
protected function createCertificateBundle() {
|
||||||
$path = $this->user->getHome() . '/files_external/';
|
$path = $this->getPathToCertificates();
|
||||||
$certs = $this->listCertificates();
|
$certs = $this->listCertificates();
|
||||||
|
|
||||||
$fh_certs = fopen($path . '/rootcerts.crt', 'w');
|
$fh_certs = fopen($path . '/rootcerts.crt', 'w');
|
||||||
|
@ -86,7 +86,7 @@ class CertificateManager implements ICertificateManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dir = $this->user->getHome() . '/files_external/uploads/';
|
$dir = $this->getPathToCertificates() . 'uploads/';
|
||||||
if (!file_exists($dir)) {
|
if (!file_exists($dir)) {
|
||||||
//path might not exist (e.g. non-standard OC_User::getHome() value)
|
//path might not exist (e.g. non-standard OC_User::getHome() value)
|
||||||
//in this case create full path using 3rd (recursive=true) parameter.
|
//in this case create full path using 3rd (recursive=true) parameter.
|
||||||
|
@ -116,7 +116,7 @@ class CertificateManager implements ICertificateManager {
|
||||||
if (!Filesystem::isValidPath($name)) {
|
if (!Filesystem::isValidPath($name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$path = $this->user->getHome() . '/files_external/uploads/';
|
$path = $this->getPathToCertificates() . 'uploads/';
|
||||||
if (file_exists($path . $name)) {
|
if (file_exists($path . $name)) {
|
||||||
unlink($path . $name);
|
unlink($path . $name);
|
||||||
$this->createCertificateBundle();
|
$this->createCertificateBundle();
|
||||||
|
@ -130,6 +130,12 @@ class CertificateManager implements ICertificateManager {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getCertificateBundle() {
|
public function getCertificateBundle() {
|
||||||
return $this->user->getHome() . '/files_external/rootcerts.crt';
|
return $this->getPathToCertificates() . 'rootcerts.crt';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPathToCertificates() {
|
||||||
|
$path = $this->user ? $this->user->getHome() . '/files_external/' : '/files_external/';
|
||||||
|
|
||||||
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ class Server extends SimpleContainer implements IServerContainer {
|
||||||
});
|
});
|
||||||
$this->registerService('HTTPHelper', function (Server $c) {
|
$this->registerService('HTTPHelper', function (Server $c) {
|
||||||
$config = $c->getConfig();
|
$config = $c->getConfig();
|
||||||
return new HTTPHelper($config);
|
return new HTTPHelper($config, new \OC\Security\CertificateManager($c->getUserSession()->getUser()));
|
||||||
});
|
});
|
||||||
$this->registerService('EventLogger', function (Server $c) {
|
$this->registerService('EventLogger', function (Server $c) {
|
||||||
if (defined('DEBUG') and DEBUG) {
|
if (defined('DEBUG') and DEBUG) {
|
||||||
|
|
|
@ -34,8 +34,12 @@ class Constants {
|
||||||
const FORMAT_STATUSES = -2;
|
const FORMAT_STATUSES = -2;
|
||||||
const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it
|
const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it
|
||||||
|
|
||||||
|
const RESPONSE_FORMAT = 'json'; // default resonse format for ocs calls
|
||||||
|
|
||||||
const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
|
const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
|
||||||
|
|
||||||
|
const BASE_PATH_TO_SHARE_API = '/ocs/v1.php/cloud/shares';
|
||||||
|
|
||||||
protected static $shareTypeUserAndGroups = -1;
|
protected static $shareTypeUserAndGroups = -1;
|
||||||
protected static $shareTypeGroupUserUnique = 2;
|
protected static $shareTypeGroupUserUnique = 2;
|
||||||
protected static $backends = array();
|
protected static $backends = array();
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Helper extends \OC\Share\Constants {
|
||||||
public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
|
public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
|
||||||
// FIXME: $uidOwner and $groupParent seems to be unused
|
// FIXME: $uidOwner and $groupParent seems to be unused
|
||||||
$backend = \OC\Share\Share::getBackend($itemType);
|
$backend = \OC\Share\Share::getBackend($itemType);
|
||||||
if ($shareType == self::SHARE_TYPE_LINK) {
|
if ($shareType === self::SHARE_TYPE_LINK || $shareType === self::SHARE_TYPE_REMOTE) {
|
||||||
if (isset($suggestedTarget)) {
|
if (isset($suggestedTarget)) {
|
||||||
return $suggestedTarget;
|
return $suggestedTarget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -503,9 +503,19 @@ class Share extends \OC\Share\Constants {
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null) {
|
public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null) {
|
||||||
|
|
||||||
|
$backend = self::getBackend($itemType);
|
||||||
|
$l = \OC::$server->getL10N('lib');
|
||||||
|
|
||||||
|
if ($backend->isShareTypeAllowed($shareType) === false) {
|
||||||
|
$message = 'Sharing %s failed, because the backend does not allow shares from type %i';
|
||||||
|
$message_t = $l->t('Sharing %s failed, because the backend does not allow shares from type %i', array($itemSourceName, $shareType));
|
||||||
|
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareType), \OC_Log::ERROR);
|
||||||
|
throw new \Exception($message_t);
|
||||||
|
}
|
||||||
|
|
||||||
$uidOwner = \OC_User::getUser();
|
$uidOwner = \OC_User::getUser();
|
||||||
$shareWithinGroupOnly = self::shareWithGroupMembersOnly();
|
$shareWithinGroupOnly = self::shareWithGroupMembersOnly();
|
||||||
$l = \OC::$server->getL10N('lib');
|
|
||||||
|
|
||||||
if (is_null($itemSourceName)) {
|
if (is_null($itemSourceName)) {
|
||||||
$itemSourceName = $itemSource;
|
$itemSourceName = $itemSource;
|
||||||
|
@ -681,6 +691,25 @@ class Share extends \OC\Share\Constants {
|
||||||
$message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName));
|
$message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName));
|
||||||
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR);
|
\OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR);
|
||||||
throw new \Exception($message_t);
|
throw new \Exception($message_t);
|
||||||
|
} else if ($shareType === self::SHARE_TYPE_REMOTE) {
|
||||||
|
$token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER .
|
||||||
|
\OCP\Security\ISecureRandom::CHAR_DIGITS);
|
||||||
|
|
||||||
|
$shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName);
|
||||||
|
|
||||||
|
$send = false;
|
||||||
|
if ($shareId) {
|
||||||
|
$send = self::sendRemoteShare($token, $shareWith, $itemSourceName, $shareId, $uidOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($send === false) {
|
||||||
|
$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
|
||||||
|
self::unshare($itemType, $itemSource, $shareType, $shareWith, $currentUser);
|
||||||
|
$message_t = $l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', array($itemSourceName, $shareWith));
|
||||||
|
throw new \Exception($message_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $send;
|
||||||
} else {
|
} else {
|
||||||
// Future share types need to include their own conditions
|
// Future share types need to include their own conditions
|
||||||
$message = 'Share type %s is not valid for %s';
|
$message = 'Share type %s is not valid for %s';
|
||||||
|
@ -690,7 +719,9 @@ class Share extends \OC\Share\Constants {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the item into the database
|
// Put the item into the database
|
||||||
return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate);
|
$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate);
|
||||||
|
|
||||||
|
return $result ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1124,6 +1155,10 @@ class Share extends \OC\Share\Constants {
|
||||||
$deletedShares[] = $hookParams;
|
$deletedShares[] = $hookParams;
|
||||||
$hookParams['deletedShares'] = $deletedShares;
|
$hookParams['deletedShares'] = $deletedShares;
|
||||||
\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
|
\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
|
||||||
|
if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
|
||||||
|
$urlParts = explode('@', $item['share_with'], 2);
|
||||||
|
self::sendRemoteUnshare($urlParts[1], $item['id'], $item['token']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1702,7 +1737,7 @@ class Share extends \OC\Share\Constants {
|
||||||
* @param string $itemSourceName name of the source item (optional)
|
* @param string $itemSourceName name of the source item (optional)
|
||||||
* @param \DateTime $expirationDate (optional)
|
* @param \DateTime $expirationDate (optional)
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @return boolean Returns true on success or false on failure
|
* @return mixed id of the new share or false
|
||||||
*/
|
*/
|
||||||
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
|
||||||
$permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) {
|
$permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) {
|
||||||
|
@ -1857,8 +1892,9 @@ class Share extends \OC\Share\Constants {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$id = false;
|
||||||
if ($isGroupShare) {
|
if ($isGroupShare) {
|
||||||
self::insertShare($queriesToExecute['groupShare']);
|
$id = self::insertShare($queriesToExecute['groupShare']);
|
||||||
// Save this id, any extra rows for this group share will need to reference it
|
// Save this id, any extra rows for this group share will need to reference it
|
||||||
$parent = \OC_DB::insertid('*PREFIX*share');
|
$parent = \OC_DB::insertid('*PREFIX*share');
|
||||||
unset($queriesToExecute['groupShare']);
|
unset($queriesToExecute['groupShare']);
|
||||||
|
@ -1866,7 +1902,7 @@ class Share extends \OC\Share\Constants {
|
||||||
|
|
||||||
foreach ($queriesToExecute as $shareQuery) {
|
foreach ($queriesToExecute as $shareQuery) {
|
||||||
$shareQuery['parent'] = $parent;
|
$shareQuery['parent'] = $parent;
|
||||||
self::insertShare($shareQuery);
|
$id = self::insertShare($shareQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
$postHookData = array(
|
$postHookData = array(
|
||||||
|
@ -1889,7 +1925,7 @@ class Share extends \OC\Share\Constants {
|
||||||
\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
|
\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return $id ? $id : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
|
private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
|
||||||
|
@ -1983,6 +2019,11 @@ class Share extends \OC\Share\Constants {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param array $shareData
|
||||||
|
* @return mixed false in case of a failure or the id of the new share
|
||||||
|
*/
|
||||||
private static function insertShare(array $shareData)
|
private static function insertShare(array $shareData)
|
||||||
{
|
{
|
||||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
|
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
|
||||||
|
@ -2002,7 +2043,30 @@ class Share extends \OC\Share\Constants {
|
||||||
$query->bindValue(11, $shareData['token']);
|
$query->bindValue(11, $shareData['token']);
|
||||||
$query->bindValue(12, $shareData['parent']);
|
$query->bindValue(12, $shareData['parent']);
|
||||||
$query->bindValue(13, $shareData['expiration'], 'datetime');
|
$query->bindValue(13, $shareData['expiration'], 'datetime');
|
||||||
$query->execute();
|
$result = $query->execute();
|
||||||
|
|
||||||
|
$id = false;
|
||||||
|
if ($result) {
|
||||||
|
$id = \OC::$server->getDatabaseConnection()->lastInsertId();
|
||||||
|
// Fallback, if lastInterId() doesn't work we need to perform a select
|
||||||
|
// to get the ID (seems to happen sometimes on Oracle)
|
||||||
|
if (!$id) {
|
||||||
|
$getId = \OC_DB::prepare('
|
||||||
|
SELECT `id`
|
||||||
|
FROM`*PREFIX*share`
|
||||||
|
WHERE `uid_owner` = ? AND `item_target` = ? AND `item_source` = ? AND `stime` = ?
|
||||||
|
');
|
||||||
|
$r = $getId->execute(array($shareData['uidOwner'], $shareData['itemTarget'], $shareData['itemSource'], $shareData['shareTime']));
|
||||||
|
if ($r) {
|
||||||
|
$row = $r->fetchRow();
|
||||||
|
$id = $row['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Delete all shares with type SHARE_TYPE_LINK
|
* Delete all shares with type SHARE_TYPE_LINK
|
||||||
|
@ -2150,6 +2214,99 @@ class Share extends \OC\Share\Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove protocol from URL
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function removeProtocolFromUrl($url) {
|
||||||
|
if (strpos($url, 'https://') === 0) {
|
||||||
|
return substr($url, strlen('https://'));
|
||||||
|
} else if (strpos($url, 'http://') === 0) {
|
||||||
|
return substr($url, strlen('http://'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try http post first with https and then with http as a fallback
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param array $fields post parameters
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function tryHttpPost($url, $fields) {
|
||||||
|
$protocol = 'https://';
|
||||||
|
$success = false;
|
||||||
|
$try = 0;
|
||||||
|
while ($success === false && $try < 2) {
|
||||||
|
$result = \OC::$server->getHTTPHelper()->post($protocol . $url, $fields);
|
||||||
|
$success = $result['success'];
|
||||||
|
$try++;
|
||||||
|
$protocol = 'http://';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send server-to-server share to remote server
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @param string $shareWith
|
||||||
|
* @param string $name
|
||||||
|
* @param int $remote_id
|
||||||
|
* @param string $owner
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) {
|
||||||
|
|
||||||
|
list($user, $remote) = explode('@', $shareWith, 2);
|
||||||
|
|
||||||
|
if ($user && $remote) {
|
||||||
|
$url = $remote . self::BASE_PATH_TO_SHARE_API . '?format=' . self::RESPONSE_FORMAT;
|
||||||
|
|
||||||
|
$local = \OC::$server->getURLGenerator()->getAbsoluteURL('');
|
||||||
|
|
||||||
|
$fields = array(
|
||||||
|
'shareWith' => $user,
|
||||||
|
'token' => $token,
|
||||||
|
'name' => $name,
|
||||||
|
'remoteId' => $remote_id,
|
||||||
|
'owner' => $owner,
|
||||||
|
'remote' => $local,
|
||||||
|
);
|
||||||
|
|
||||||
|
$url = self::removeProtocolFromUrl($url);
|
||||||
|
$result = self::tryHttpPost($url, $fields);
|
||||||
|
$status = json_decode($result['result'], true);
|
||||||
|
|
||||||
|
return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send server-to-server unshare to remote server
|
||||||
|
*
|
||||||
|
* @param string remote url
|
||||||
|
* @param int $id share id
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function sendRemoteUnshare($remote, $id, $token) {
|
||||||
|
$url = $remote . self::BASE_PATH_TO_SHARE_API . '/' . $id . '/unshare?format=' . self::RESPONSE_FORMAT;
|
||||||
|
$fields = array('token' => $token, 'format' => 'json');
|
||||||
|
$result = self::tryHttpPost($url, $fields);
|
||||||
|
$status = json_decode($result['result'], true);
|
||||||
|
|
||||||
|
return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if user can only share with group members
|
* check if user can only share with group members
|
||||||
* @return bool
|
* @return bool
|
||||||
|
|
|
@ -65,4 +65,16 @@ interface Share_Backend {
|
||||||
*/
|
*/
|
||||||
public function formatItems($items, $format, $parameters = null);
|
public function formatItems($items, $format, $parameters = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given share type is allowd by the back-end
|
||||||
|
*
|
||||||
|
* @param int $shareType share type
|
||||||
|
* @return boolean
|
||||||
|
*
|
||||||
|
* The back-end can enable/disable specific share types. Just return true if
|
||||||
|
* the back-end doesn't provide any specific settings for it and want to allow
|
||||||
|
* all share types defined by the share API
|
||||||
|
*/
|
||||||
|
public function isShareTypeAllowed($shareType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,9 @@ class InfoParser extends \PHPUnit_Framework_TestCase {
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$certificateManager = $this->getMock('\OCP\ICertificateManager');
|
||||||
$httpHelper = $this->getMockBuilder('\OC\HTTPHelper')
|
$httpHelper = $this->getMockBuilder('\OC\HTTPHelper')
|
||||||
->setConstructorArgs(array($config))
|
->setConstructorArgs(array($config, $certificateManager))
|
||||||
->setMethods(array('getHeaders'))
|
->setMethods(array('getHeaders'))
|
||||||
->getMock();
|
->getMock();
|
||||||
$urlGenerator = $this->getMockBuilder('\OCP\IURLGenerator')
|
$urlGenerator = $this->getMockBuilder('\OCP\IURLGenerator')
|
||||||
|
|
|
@ -12,14 +12,17 @@ class TestHTTPHelper extends \Test\TestCase {
|
||||||
private $config;
|
private $config;
|
||||||
/** @var \OC\HTTPHelper */
|
/** @var \OC\HTTPHelper */
|
||||||
private $httpHelperMock;
|
private $httpHelperMock;
|
||||||
|
/** @var \OC\Security\CertificateManager */
|
||||||
|
private $certificateManager;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->config = $this->getMockBuilder('\OCP\IConfig')
|
$this->config = $this->getMockBuilder('\OCP\IConfig')
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->certificateManager = $this->getMock('\OCP\ICertificateManager');
|
||||||
$this->httpHelperMock = $this->getMockBuilder('\OC\HTTPHelper')
|
$this->httpHelperMock = $this->getMockBuilder('\OC\HTTPHelper')
|
||||||
->setConstructorArgs(array($this->config))
|
->setConstructorArgs(array($this->config, $this->certificateManager))
|
||||||
->setMethods(array('getHeaders'))
|
->setMethods(array('getHeaders'))
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
@ -87,4 +90,23 @@ class TestHTTPHelper extends \Test\TestCase {
|
||||||
$this->assertSame($expected, $this->httpHelperMock->isHTTPURL($url));
|
$this->assertSame($expected, $this->httpHelperMock->isHTTPURL($url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider postParameters
|
||||||
|
*/
|
||||||
|
public function testassemblePostParameters($parameterList, $expectedResult) {
|
||||||
|
$helper = \OC::$server->getHTTPHelper();
|
||||||
|
$result = \Test_Helper::invokePrivate($helper, 'assemblePostParameters', array($parameterList));
|
||||||
|
$this->assertSame($expectedResult, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postParameters() {
|
||||||
|
return array(
|
||||||
|
array(array('k1' => 'v1'), 'k1=v1'),
|
||||||
|
array(array('k1' => 'v1', 'k2' => 'v2'), 'k1=v1&k2=v2'),
|
||||||
|
array(array(), ''),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,4 +84,8 @@ class Test_Share_Backend implements OCP\Share_Backend {
|
||||||
return $testItems;
|
return $testItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isShareTypeAllowed($shareType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -848,6 +848,23 @@ class Test_Share extends \Test\TestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider urls
|
||||||
|
*/
|
||||||
|
function testRemoveProtocolFromUrl($url, $expectedResult) {
|
||||||
|
$share = new \OC\Share\Share();
|
||||||
|
$result = \Test_Helper::invokePrivate($share, 'removeProtocolFromUrl', array($url));
|
||||||
|
$this->assertSame($expectedResult, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function urls() {
|
||||||
|
return array(
|
||||||
|
array('http://owncloud.org', 'owncloud.org'),
|
||||||
|
array('https://owncloud.org', 'owncloud.org'),
|
||||||
|
array('owncloud.org', 'owncloud.org'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataProviderTestGroupItems
|
* @dataProvider dataProviderTestGroupItems
|
||||||
* @param type $ungrouped
|
* @param type $ungrouped
|
||||||
|
|
|
@ -93,14 +93,14 @@ class UpdaterTest extends \Test\TestCase {
|
||||||
->getMock()
|
->getMock()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$certificateManager = $this->getMock('\OCP\ICertificateManager');
|
||||||
$mockedHTTPHelper = $this->getMockBuilder('\OC\HTTPHelper')
|
$mockedHTTPHelper = $this->getMockBuilder('\OC\HTTPHelper')
|
||||||
->setConstructorArgs(array(\OC::$server->getConfig()))
|
->setConstructorArgs(array(\OC::$server->getConfig(), $certificateManager))
|
||||||
->getMock()
|
->getMock()
|
||||||
;
|
;
|
||||||
|
|
||||||
$mockedHTTPHelper->method('getUrlContent')
|
$mockedHTTPHelper->expects($this->once())->method('getUrlContent')->will($this->returnValue($content));
|
||||||
->willReturn($content)
|
|
||||||
;
|
|
||||||
return new Updater($mockedHTTPHelper, $mockedAppConfig);
|
return new Updater($mockedHTTPHelper, $mockedAppConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue