Merge pull request #20222 from owncloud/federated_sharing_auto_complete
federated sharing auto-complete, first step
This commit is contained in:
commit
bf672d7e51
|
@ -12,6 +12,7 @@
|
||||||
!/apps/dav
|
!/apps/dav
|
||||||
!/apps/files
|
!/apps/files
|
||||||
!/apps/files_encryption
|
!/apps/files_encryption
|
||||||
|
!/apps/federation
|
||||||
!/apps/encryption
|
!/apps/encryption
|
||||||
!/apps/encryption_dummy
|
!/apps/encryption_dummy
|
||||||
!/apps/files_external
|
!/apps/files_external
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\API;
|
||||||
|
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\Security\ISecureRandom;
|
||||||
|
use OCP\Security\StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class OCSAuthAPI
|
||||||
|
*
|
||||||
|
* OCS API end-points to exchange shared secret between two connected ownClouds
|
||||||
|
*
|
||||||
|
* @package OCA\Federation\API
|
||||||
|
*/
|
||||||
|
class OCSAuthAPI {
|
||||||
|
|
||||||
|
/** @var IRequest */
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
/** @var ISecureRandom */
|
||||||
|
private $secureRandom;
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OCSAuthAPI constructor.
|
||||||
|
*
|
||||||
|
* @param IRequest $request
|
||||||
|
* @param ISecureRandom $secureRandom
|
||||||
|
* @param IJobList $jobList
|
||||||
|
* @param TrustedServers $trustedServers
|
||||||
|
* @param DbHandler $dbHandler
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
IRequest $request,
|
||||||
|
ISecureRandom $secureRandom,
|
||||||
|
IJobList $jobList,
|
||||||
|
TrustedServers $trustedServers,
|
||||||
|
DbHandler $dbHandler
|
||||||
|
) {
|
||||||
|
$this->request = $request;
|
||||||
|
$this->secureRandom = $secureRandom;
|
||||||
|
$this->jobList = $jobList;
|
||||||
|
$this->trustedServers = $trustedServers;
|
||||||
|
$this->dbHandler = $dbHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request received to ask remote server for a shared secret
|
||||||
|
*
|
||||||
|
* @return \OC_OCS_Result
|
||||||
|
*/
|
||||||
|
public function requestSharedSecret() {
|
||||||
|
|
||||||
|
$url = $this->request->getParam('url');
|
||||||
|
$token = $this->request->getParam('token');
|
||||||
|
|
||||||
|
if ($this->trustedServers->isTrustedServer($url) === false) {
|
||||||
|
return new \OC_OCS_Result(null, HTTP::STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if both server initiated the exchange of the shared secret the greater
|
||||||
|
// token wins
|
||||||
|
$localToken = $this->dbHandler->getToken($url);
|
||||||
|
if (strcmp($localToken, $token) > 0) {
|
||||||
|
return new \OC_OCS_Result(null, HTTP::STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->jobList->add(
|
||||||
|
'OCA\Federation\BackgroundJob\GetSharedSecret',
|
||||||
|
[
|
||||||
|
'url' => $url,
|
||||||
|
'token' => $token,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return new \OC_OCS_Result(null, Http::STATUS_OK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create shared secret and return it
|
||||||
|
*
|
||||||
|
* @return \OC_OCS_Result
|
||||||
|
*/
|
||||||
|
public function getSharedSecret() {
|
||||||
|
|
||||||
|
$url = $this->request->getParam('url');
|
||||||
|
$token = $this->request->getParam('token');
|
||||||
|
|
||||||
|
if (
|
||||||
|
$this->trustedServers->isTrustedServer($url) === false
|
||||||
|
|| $this->isValidToken($url, $token) === false
|
||||||
|
) {
|
||||||
|
return new \OC_OCS_Result(null, HTTP::STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sharedSecret = $this->secureRandom->getMediumStrengthGenerator()->generate(32);
|
||||||
|
|
||||||
|
$this->trustedServers->addSharedSecret($url, $sharedSecret);
|
||||||
|
// reset token after the exchange of the shared secret was successful
|
||||||
|
$this->dbHandler->addToken($url, '');
|
||||||
|
|
||||||
|
return new \OC_OCS_Result(['sharedSecret' => $sharedSecret], Http::STATUS_OK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isValidToken($url, $token) {
|
||||||
|
$storedToken = $this->dbHandler->getToken($url);
|
||||||
|
return StringUtils::equals($storedToken, $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Federation\AppInfo;
|
||||||
|
|
||||||
|
$app = new Application();
|
||||||
|
$app->registerSettings();
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Federation\AppInfo;
|
||||||
|
|
||||||
|
use OCA\Federation\API\OCSAuthAPI;
|
||||||
|
use OCA\Federation\Controller\AuthController;
|
||||||
|
use OCA\Federation\Controller\SettingsController;
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\Middleware\AddServerMiddleware;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\API;
|
||||||
|
use OCP\App;
|
||||||
|
use OCP\AppFramework\IAppContainer;
|
||||||
|
|
||||||
|
class Application extends \OCP\AppFramework\App {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $urlParams
|
||||||
|
*/
|
||||||
|
public function __construct($urlParams = array()) {
|
||||||
|
parent::__construct('federation', $urlParams);
|
||||||
|
$this->registerService();
|
||||||
|
$this->registerMiddleware();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register setting scripts
|
||||||
|
*/
|
||||||
|
public function registerSettings() {
|
||||||
|
App::registerAdmin('federation', 'settings/settings-admin');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerService() {
|
||||||
|
$container = $this->getContainer();
|
||||||
|
|
||||||
|
$container->registerService('addServerMiddleware', function(IAppContainer $c) {
|
||||||
|
return new AddServerMiddleware(
|
||||||
|
$c->getAppName(),
|
||||||
|
\OC::$server->getL10N($c->getAppName()),
|
||||||
|
\OC::$server->getLogger()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$container->registerService('DbHandler', function(IAppContainer $c) {
|
||||||
|
return new DbHandler(
|
||||||
|
\OC::$server->getDatabaseConnection(),
|
||||||
|
\OC::$server->getL10N($c->getAppName())
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$container->registerService('TrustedServers', function(IAppContainer $c) {
|
||||||
|
return new TrustedServers(
|
||||||
|
$c->query('DbHandler'),
|
||||||
|
\OC::$server->getHTTPClientService(),
|
||||||
|
\OC::$server->getLogger(),
|
||||||
|
\OC::$server->getJobList(),
|
||||||
|
\OC::$server->getSecureRandom(),
|
||||||
|
\OC::$server->getConfig()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$container->registerService('SettingsController', function (IAppContainer $c) {
|
||||||
|
$server = $c->getServer();
|
||||||
|
return new SettingsController(
|
||||||
|
$c->getAppName(),
|
||||||
|
$server->getRequest(),
|
||||||
|
$server->getL10N($c->getAppName()),
|
||||||
|
$c->query('TrustedServers')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerMiddleware() {
|
||||||
|
$container = $this->getContainer();
|
||||||
|
$container->registerMiddleware('addServerMiddleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register OCS API Calls
|
||||||
|
*/
|
||||||
|
public function registerOCSApi() {
|
||||||
|
|
||||||
|
$container = $this->getContainer();
|
||||||
|
$server = $container->getServer();
|
||||||
|
|
||||||
|
$auth = new OCSAuthAPI(
|
||||||
|
$server->getRequest(),
|
||||||
|
$server->getSecureRandom(),
|
||||||
|
$server->getJobList(),
|
||||||
|
$container->query('TrustedServers'),
|
||||||
|
$container->query('DbHandler')
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
API::register('get',
|
||||||
|
'/apps/federation/api/v1/shared-secret',
|
||||||
|
array($auth, 'getSharedSecret'),
|
||||||
|
'federation',
|
||||||
|
API::GUEST_AUTH
|
||||||
|
);
|
||||||
|
|
||||||
|
API::register('post',
|
||||||
|
'/apps/federation/api/v1/request-shared-secret',
|
||||||
|
array($auth, 'requestSharedSecret'),
|
||||||
|
'federation',
|
||||||
|
API::GUEST_AUTH
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<database>
|
||||||
|
<name>*dbname*</name>
|
||||||
|
<create>true</create>
|
||||||
|
<overwrite>false</overwrite>
|
||||||
|
<charset>utf8</charset>
|
||||||
|
<table>
|
||||||
|
<name>*dbprefix*trusted_servers</name>
|
||||||
|
<declaration>
|
||||||
|
<field>
|
||||||
|
<name>id</name>
|
||||||
|
<type>integer</type>
|
||||||
|
<default>0</default>
|
||||||
|
<notnull>true</notnull>
|
||||||
|
<autoincrement>1</autoincrement>
|
||||||
|
<length>4</length>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<name>url</name>
|
||||||
|
<type>text</type>
|
||||||
|
<notnull>true</notnull>
|
||||||
|
<length>512</length>
|
||||||
|
<comments>Url of trusted server</comments>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<name>url_hash</name>
|
||||||
|
<type>text</type>
|
||||||
|
<default></default>
|
||||||
|
<notnull>true</notnull>
|
||||||
|
<length>32</length>
|
||||||
|
<comments>md5 hash of the url without the protocol</comments>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<name>token</name>
|
||||||
|
<type>text</type>
|
||||||
|
<length>128</length>
|
||||||
|
<comments>toke used to exchange the shared secret</comments>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<name>shared_secret</name>
|
||||||
|
<type>text</type>
|
||||||
|
<length>256</length>
|
||||||
|
<comments>shared secret used to authenticate</comments>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<name>status</name>
|
||||||
|
<type>integer</type>
|
||||||
|
<length>4</length>
|
||||||
|
<notnull>true</notnull>
|
||||||
|
<default>2</default>
|
||||||
|
<comments>current status of the connection</comments>
|
||||||
|
</field>
|
||||||
|
<index>
|
||||||
|
<name>url_hash</name>
|
||||||
|
<unique>true</unique>
|
||||||
|
<field>
|
||||||
|
<name>url_hash</name>
|
||||||
|
<sorting>ascending</sorting>
|
||||||
|
</field>
|
||||||
|
</index>
|
||||||
|
</declaration>
|
||||||
|
</table>
|
||||||
|
</database>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<info>
|
||||||
|
<id>federation</id>
|
||||||
|
<name>Federation</name>
|
||||||
|
<description>ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing.</description>
|
||||||
|
<licence>AGPL</licence>
|
||||||
|
<author>Bjoern Schiessle</author>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<namespace>Federation</namespace>
|
||||||
|
<category>other</category>
|
||||||
|
<dependencies>
|
||||||
|
<owncloud min-version="9.0" />
|
||||||
|
</dependencies>
|
||||||
|
</info>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$application = new \OCA\Federation\AppInfo\Application();
|
||||||
|
|
||||||
|
$application->registerRoutes(
|
||||||
|
$this,
|
||||||
|
[
|
||||||
|
'routes' => [
|
||||||
|
[
|
||||||
|
'name' => 'Settings#addServer',
|
||||||
|
'url' => '/trusted-servers',
|
||||||
|
'verb' => 'POST'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Settings#removeServer',
|
||||||
|
'url' => '/trusted-servers/{id}',
|
||||||
|
'verb' => 'DELETE'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Settings#autoAddServers',
|
||||||
|
'url' => '/auto-add-servers',
|
||||||
|
'verb' => 'POST'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$application->registerOCSApi();
|
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\BackgroundJob;
|
||||||
|
|
||||||
|
use GuzzleHttp\Exception\ClientException;
|
||||||
|
use OC\BackgroundJob\JobList;
|
||||||
|
use OC\BackgroundJob\QueuedJob;
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\Http\Client\IClient;
|
||||||
|
use OCP\ILogger;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GetSharedSecret
|
||||||
|
*
|
||||||
|
* request shared secret from remote ownCloud
|
||||||
|
*
|
||||||
|
* @package OCA\Federation\Backgroundjob
|
||||||
|
*/
|
||||||
|
class GetSharedSecret extends QueuedJob{
|
||||||
|
|
||||||
|
/** @var IClient */
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var IURLGenerator */
|
||||||
|
private $urlGenerator;
|
||||||
|
|
||||||
|
/** @var TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var ILogger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
private $endPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret?format=json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RequestSharedSecret constructor.
|
||||||
|
*
|
||||||
|
* @param IClient $httpClient
|
||||||
|
* @param IURLGenerator $urlGenerator
|
||||||
|
* @param IJobList $jobList
|
||||||
|
* @param TrustedServers $trustedServers
|
||||||
|
* @param ILogger $logger
|
||||||
|
* @param DbHandler $dbHandler
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
IClient $httpClient = null,
|
||||||
|
IURLGenerator $urlGenerator = null,
|
||||||
|
IJobList $jobList = null,
|
||||||
|
TrustedServers $trustedServers = null,
|
||||||
|
ILogger $logger = null,
|
||||||
|
dbHandler $dbHandler = null
|
||||||
|
) {
|
||||||
|
$this->logger = $logger ? $logger : \OC::$server->getLogger();
|
||||||
|
$this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient();
|
||||||
|
$this->jobList = $jobList ? $jobList : \OC::$server->getJobList();
|
||||||
|
$this->urlGenerator = $urlGenerator ? $urlGenerator : \OC::$server->getURLGenerator();
|
||||||
|
$this->dbHandler = $dbHandler ? $dbHandler : new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation'));
|
||||||
|
if ($trustedServers) {
|
||||||
|
$this->trustedServers = $trustedServers;
|
||||||
|
} else {
|
||||||
|
$this->trustedServers = new TrustedServers(
|
||||||
|
$this->dbHandler,
|
||||||
|
\OC::$server->getHTTPClientService(),
|
||||||
|
\OC::$server->getLogger(),
|
||||||
|
$this->jobList,
|
||||||
|
\OC::$server->getSecureRandom(),
|
||||||
|
\OC::$server->getConfig()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run the job, then remove it from the joblist
|
||||||
|
*
|
||||||
|
* @param JobList $jobList
|
||||||
|
* @param ILogger $logger
|
||||||
|
*/
|
||||||
|
public function execute($jobList, ILogger $logger = null) {
|
||||||
|
$jobList->remove($this, $this->argument);
|
||||||
|
$target = $this->argument['url'];
|
||||||
|
// only execute if target is still in the list of trusted domains
|
||||||
|
if ($this->trustedServers->isTrustedServer($target)) {
|
||||||
|
$this->parentExecute($jobList, $logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call execute() method of parent
|
||||||
|
*
|
||||||
|
* @param JobList $jobList
|
||||||
|
* @param ILogger $logger
|
||||||
|
*/
|
||||||
|
protected function parentExecute($jobList, $logger) {
|
||||||
|
parent::execute($jobList, $logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function run($argument) {
|
||||||
|
$target = $argument['url'];
|
||||||
|
$source = $this->urlGenerator->getAbsoluteURL('/');
|
||||||
|
$source = rtrim($source, '/');
|
||||||
|
$token = $argument['token'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $this->httpClient->get(
|
||||||
|
$target . $this->endPoint,
|
||||||
|
[
|
||||||
|
'query' =>
|
||||||
|
[
|
||||||
|
'url' => $source,
|
||||||
|
'token' => $token
|
||||||
|
],
|
||||||
|
'timeout' => 3,
|
||||||
|
'connect_timeout' => 3,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$status = $result->getStatusCode();
|
||||||
|
|
||||||
|
} catch (ClientException $e) {
|
||||||
|
$status = $e->getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we received a unexpected response we try again later
|
||||||
|
if (
|
||||||
|
$status !== Http::STATUS_OK
|
||||||
|
&& $status !== Http::STATUS_FORBIDDEN
|
||||||
|
) {
|
||||||
|
$this->jobList->add(
|
||||||
|
'OCA\Federation\BackgroundJob\GetSharedSecret',
|
||||||
|
$argument
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// reset token if we received a valid response
|
||||||
|
$this->dbHandler->addToken($target, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status === Http::STATUS_OK) {
|
||||||
|
$body = $result->getBody();
|
||||||
|
$result = json_decode($body, true);
|
||||||
|
if (isset($result['ocs']['data']['sharedSecret'])) {
|
||||||
|
$this->trustedServers->addSharedSecret(
|
||||||
|
$target,
|
||||||
|
$result['ocs']['data']['sharedSecret']
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->logger->error(
|
||||||
|
'remote server "' . $target . '"" does not return a valid shared secret',
|
||||||
|
['app' => 'federation']
|
||||||
|
);
|
||||||
|
$this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\BackgroundJob;
|
||||||
|
|
||||||
|
|
||||||
|
use GuzzleHttp\Exception\ClientException;
|
||||||
|
use OC\BackgroundJob\JobList;
|
||||||
|
use OC\BackgroundJob\QueuedJob;
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\Http\Client\IClient;
|
||||||
|
use OCP\ILogger;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RequestSharedSecret
|
||||||
|
*
|
||||||
|
* Ask remote ownCloud to request a sharedSecret from this server
|
||||||
|
*
|
||||||
|
* @package OCA\Federation\Backgroundjob
|
||||||
|
*/
|
||||||
|
class RequestSharedSecret extends QueuedJob {
|
||||||
|
|
||||||
|
/** @var IClient */
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var IURLGenerator */
|
||||||
|
private $urlGenerator;
|
||||||
|
|
||||||
|
/** @var DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
private $endPoint = '/ocs/v2.php/apps/federation/api/v1/request-shared-secret?format=json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RequestSharedSecret constructor.
|
||||||
|
*
|
||||||
|
* @param IClient $httpClient
|
||||||
|
* @param IURLGenerator $urlGenerator
|
||||||
|
* @param IJobList $jobList
|
||||||
|
* @param TrustedServers $trustedServers
|
||||||
|
* @param DbHandler $dbHandler
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
IClient $httpClient = null,
|
||||||
|
IURLGenerator $urlGenerator = null,
|
||||||
|
IJobList $jobList = null,
|
||||||
|
TrustedServers $trustedServers = null,
|
||||||
|
dbHandler $dbHandler = null
|
||||||
|
) {
|
||||||
|
$this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient();
|
||||||
|
$this->jobList = $jobList ? $jobList : \OC::$server->getJobList();
|
||||||
|
$this->urlGenerator = $urlGenerator ? $urlGenerator : \OC::$server->getURLGenerator();
|
||||||
|
$this->dbHandler = $dbHandler ? $dbHandler : new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation'));
|
||||||
|
if ($trustedServers) {
|
||||||
|
$this->trustedServers = $trustedServers;
|
||||||
|
} else {
|
||||||
|
$this->trustedServers = new TrustedServers(
|
||||||
|
$this->dbHandler,
|
||||||
|
\OC::$server->getHTTPClientService(),
|
||||||
|
\OC::$server->getLogger(),
|
||||||
|
$this->jobList,
|
||||||
|
\OC::$server->getSecureRandom(),
|
||||||
|
\OC::$server->getConfig()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run the job, then remove it from the joblist
|
||||||
|
*
|
||||||
|
* @param JobList $jobList
|
||||||
|
* @param ILogger $logger
|
||||||
|
*/
|
||||||
|
public function execute($jobList, ILogger $logger = null) {
|
||||||
|
$jobList->remove($this, $this->argument);
|
||||||
|
$target = $this->argument['url'];
|
||||||
|
// only execute if target is still in the list of trusted domains
|
||||||
|
if ($this->trustedServers->isTrustedServer($target)) {
|
||||||
|
$this->parentExecute($jobList, $logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param JobList $jobList
|
||||||
|
* @param ILogger $logger
|
||||||
|
*/
|
||||||
|
protected function parentExecute($jobList, $logger) {
|
||||||
|
parent::execute($jobList, $logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function run($argument) {
|
||||||
|
|
||||||
|
$target = $argument['url'];
|
||||||
|
$source = $this->urlGenerator->getAbsoluteURL('/');
|
||||||
|
$source = rtrim($source, '/');
|
||||||
|
$token = $argument['token'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $this->httpClient->post(
|
||||||
|
$target . $this->endPoint,
|
||||||
|
[
|
||||||
|
'body' => [
|
||||||
|
'url' => $source,
|
||||||
|
'token' => $token,
|
||||||
|
],
|
||||||
|
'timeout' => 3,
|
||||||
|
'connect_timeout' => 3,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$status = $result->getStatusCode();
|
||||||
|
|
||||||
|
} catch (ClientException $e) {
|
||||||
|
$status = $e->getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we received a unexpected response we try again later
|
||||||
|
if (
|
||||||
|
$status !== Http::STATUS_OK
|
||||||
|
&& $status !== Http::STATUS_FORBIDDEN
|
||||||
|
) {
|
||||||
|
$this->jobList->add(
|
||||||
|
'OCA\Federation\BackgroundJob\RequestSharedSecret',
|
||||||
|
$argument
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status === Http::STATUS_FORBIDDEN) {
|
||||||
|
// clear token if remote server refuses to ask for shared secret
|
||||||
|
$this->dbHandler->addToken($target, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Federation\Controller;
|
||||||
|
|
||||||
|
use OC\HintException;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\IL10N;
|
||||||
|
use OCP\IRequest;
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsController extends Controller {
|
||||||
|
|
||||||
|
/** @var IL10N */
|
||||||
|
private $l;
|
||||||
|
|
||||||
|
/** @var TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $AppName
|
||||||
|
* @param IRequest $request
|
||||||
|
* @param IL10N $l10n
|
||||||
|
* @param TrustedServers $trustedServers
|
||||||
|
*/
|
||||||
|
public function __construct($AppName,
|
||||||
|
IRequest $request,
|
||||||
|
IL10N $l10n,
|
||||||
|
TrustedServers $trustedServers
|
||||||
|
) {
|
||||||
|
parent::__construct($AppName, $request);
|
||||||
|
$this->l = $l10n;
|
||||||
|
$this->trustedServers = $trustedServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add server to the list of trusted ownClouds
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return DataResponse
|
||||||
|
* @throws HintException
|
||||||
|
*/
|
||||||
|
public function addServer($url) {
|
||||||
|
$this->checkServer($url);
|
||||||
|
$id = $this->trustedServers->addServer($url);
|
||||||
|
|
||||||
|
return new DataResponse(
|
||||||
|
[
|
||||||
|
'url' => $url,
|
||||||
|
'id' => $id,
|
||||||
|
'message' => (string) $this->l->t('Server added to the list of trusted ownClouds')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add server to the list of trusted ownClouds
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return DataResponse
|
||||||
|
*/
|
||||||
|
public function removeServer($id) {
|
||||||
|
$this->trustedServers->removeServer($id);
|
||||||
|
return new DataResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enable/disable to automatically add servers to the list of trusted servers
|
||||||
|
* once a federated share was created and accepted successfully
|
||||||
|
*
|
||||||
|
* @param bool $autoAddServers
|
||||||
|
*/
|
||||||
|
public function autoAddServers($autoAddServers) {
|
||||||
|
$this->trustedServers->setAutoAddServers($autoAddServers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the server should be added to the list of trusted servers or not
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return bool
|
||||||
|
* @throws HintException
|
||||||
|
*/
|
||||||
|
protected function checkServer($url) {
|
||||||
|
if ($this->trustedServers->isTrustedServer($url) === true) {
|
||||||
|
$message = 'Server is already in the list of trusted servers.';
|
||||||
|
$hint = $this->l->t('Server is already in the list of trusted servers.');
|
||||||
|
throw new HintException($message, $hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->trustedServers->isOwnCloudServer($url) === false) {
|
||||||
|
$message = 'No ownCloud server found';
|
||||||
|
$hint = $this->l->t('No ownCloud server found');
|
||||||
|
throw new HintException($message, $hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ocFederationSettings p {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listOfTrustedServers li {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.removeTrustedServer {
|
||||||
|
display: none;
|
||||||
|
vertical-align:middle;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ocFederationAddServerButton {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listOfTrustedServers li:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listOfTrustedServers .status {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
// show input field to add a new trusted server
|
||||||
|
$("#ocFederationAddServer").on('click', function() {
|
||||||
|
$('#ocFederationAddServerButton').addClass('hidden');
|
||||||
|
$("#serverUrl").removeClass('hidden');
|
||||||
|
$("#serverUrl").focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
// add new trusted server
|
||||||
|
$("#serverUrl").keyup(function (e) {
|
||||||
|
if (e.keyCode === 13) { // add server on "enter"
|
||||||
|
var url = $('#serverUrl').val();
|
||||||
|
OC.msg.startSaving('#ocFederationAddServer .msg');
|
||||||
|
$.post(
|
||||||
|
OC.generateUrl('/apps/federation/trusted-servers'),
|
||||||
|
{
|
||||||
|
url: url
|
||||||
|
}
|
||||||
|
).done(function (data) {
|
||||||
|
$('#serverUrl').attr('value', '');
|
||||||
|
$('ul#listOfTrustedServers').prepend(
|
||||||
|
$('<li>')
|
||||||
|
.attr('id', data.id)
|
||||||
|
.attr('class', 'icon-delete')
|
||||||
|
.html('<span class="status indeterminate"></span>' + data.url)
|
||||||
|
);
|
||||||
|
OC.msg.finishedSuccess('#ocFederationAddServer .msg', data.message);
|
||||||
|
})
|
||||||
|
.fail(function (jqXHR) {
|
||||||
|
OC.msg.finishedError('#ocFederationAddServer .msg', JSON.parse(jqXHR.responseText).message);
|
||||||
|
});
|
||||||
|
} else if (e.keyCode === 27) { // hide input filed again in ESC
|
||||||
|
$('#ocFederationAddServerButton').toggleClass('hidden');
|
||||||
|
$("#serverUrl").toggleClass('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove trusted server from list
|
||||||
|
$( "#listOfTrustedServers" ).on('click', 'li', function() {
|
||||||
|
var id = $(this).attr('id');
|
||||||
|
var $this = $(this);
|
||||||
|
$.ajax({
|
||||||
|
url: OC.generateUrl('/apps/federation/trusted-servers/' + id),
|
||||||
|
type: 'DELETE',
|
||||||
|
success: function(response) {
|
||||||
|
$this.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#ocFederationSettings #autoAddServers").change(function() {
|
||||||
|
$.post(
|
||||||
|
OC.generateUrl('/apps/federation/auto-add-servers'),
|
||||||
|
{
|
||||||
|
autoAddServers: $(this).is(":checked")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,269 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation;
|
||||||
|
|
||||||
|
|
||||||
|
use OC\Files\Filesystem;
|
||||||
|
use OC\HintException;
|
||||||
|
use OCP\IDBConnection;
|
||||||
|
use OCP\IL10N;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DbHandler
|
||||||
|
*
|
||||||
|
* handles all database calls for the federation app
|
||||||
|
*
|
||||||
|
* @group DB
|
||||||
|
* @package OCA\Federation
|
||||||
|
*/
|
||||||
|
class DbHandler {
|
||||||
|
|
||||||
|
/** @var IDBConnection */
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/** @var IL10N */
|
||||||
|
private $l;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $dbTable = 'trusted_servers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IDBConnection $connection
|
||||||
|
* @param IL10N $il10n
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
IDBConnection $connection,
|
||||||
|
IL10N $il10n
|
||||||
|
) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->IL10N = $il10n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add server to the list of trusted ownCloud servers
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return int
|
||||||
|
* @throws HintException
|
||||||
|
*/
|
||||||
|
public function addServer($url) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->insert($this->dbTable)
|
||||||
|
->values(
|
||||||
|
[
|
||||||
|
'url' => $query->createParameter('url'),
|
||||||
|
'url_hash' => $query->createParameter('url_hash'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->setParameter('url', $url)
|
||||||
|
->setParameter('url_hash', $hash);
|
||||||
|
|
||||||
|
$result = $query->execute();
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
return (int)$this->connection->lastInsertId('*PREFIX*'.$this->dbTable);
|
||||||
|
} else {
|
||||||
|
$message = 'Internal failure, Could not add ownCloud as trusted server: ' . $url;
|
||||||
|
$message_t = $this->l->t('Could not add server');
|
||||||
|
throw new HintException($message, $message_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove server from the list of trusted ownCloud servers
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public function removeServer($id) {
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->delete($this->dbTable)
|
||||||
|
->where($query->expr()->eq('id', $query->createParameter('id')))
|
||||||
|
->setParameter('id', $id);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all trusted servers
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllServer() {
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->select(['url', 'id', 'status'])->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if server already exists in the database table
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function serverExists($url) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->select('url')->from($this->dbTable)
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
|
||||||
|
return !empty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write token to database. Token is used to exchange the secret
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param string $token
|
||||||
|
*/
|
||||||
|
public function addToken($url, $token) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->update($this->dbTable)
|
||||||
|
->set('token', $query->createParameter('token'))
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash)
|
||||||
|
->setParameter('token', $token);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get token stored in database
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getToken($url) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->select('token')->from($this->dbTable)
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash);
|
||||||
|
|
||||||
|
$result = $query->execute()->fetch();
|
||||||
|
return $result['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add shared Secret to database
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param string $sharedSecret
|
||||||
|
*/
|
||||||
|
public function addSharedSecret($url, $sharedSecret) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->update($this->dbTable)
|
||||||
|
->set('shared_secret', $query->createParameter('sharedSecret'))
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash)
|
||||||
|
->setParameter('sharedSecret', $sharedSecret);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get shared secret from database
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSharedSecret($url) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->select('shared_secret')->from($this->dbTable)
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash);
|
||||||
|
|
||||||
|
$result = $query->execute()->fetch();
|
||||||
|
return $result['shared_secret'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set server status
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param int $status
|
||||||
|
*/
|
||||||
|
public function setServerStatus($url, $status) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->update($this->dbTable)
|
||||||
|
->set('status', $query->createParameter('status'))
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash)
|
||||||
|
->setParameter('status', $status);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get server status
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getServerStatus($url) {
|
||||||
|
$hash = $this->hash($url);
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->select('status')->from($this->dbTable)
|
||||||
|
->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
|
||||||
|
->setParameter('url_hash', $hash);
|
||||||
|
|
||||||
|
$result = $query->execute()->fetch();
|
||||||
|
return (int)$result['status'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create hash from URL
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function hash($url) {
|
||||||
|
$normalized = $this->normalizeUrl($url);
|
||||||
|
return md5($normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* normalize URL, used to create the md5 hash
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function normalizeUrl($url) {
|
||||||
|
$normalized = $url;
|
||||||
|
|
||||||
|
if (strpos($url, 'https://') === 0) {
|
||||||
|
$normalized = substr($url, strlen('https://'));
|
||||||
|
} else if (strpos($url, 'http://') === 0) {
|
||||||
|
$normalized = substr($url, strlen('http://'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = Filesystem::normalizePath($normalized);
|
||||||
|
$normalized = trim($normalized, '/');
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,254 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\Http\Client\IClientService;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\ILogger;
|
||||||
|
use OCP\Security\ISecureRandom;
|
||||||
|
|
||||||
|
class TrustedServers {
|
||||||
|
|
||||||
|
/** after a user list was exchanged at least once successfully */
|
||||||
|
const STATUS_OK = 1;
|
||||||
|
/** waiting for shared secret or initial user list exchange */
|
||||||
|
const STATUS_PENDING = 2;
|
||||||
|
/** something went wrong, misconfigured server, software bug,... user interaction needed */
|
||||||
|
const STATUS_FAILURE = 3;
|
||||||
|
|
||||||
|
/** @var dbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var IClientService */
|
||||||
|
private $httpClientService;
|
||||||
|
|
||||||
|
/** @var ILogger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var ISecureRandom */
|
||||||
|
private $secureRandom;
|
||||||
|
|
||||||
|
/** @var IConfig */
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DbHandler $dbHandler
|
||||||
|
* @param IClientService $httpClientService
|
||||||
|
* @param ILogger $logger
|
||||||
|
* @param IJobList $jobList
|
||||||
|
* @param ISecureRandom $secureRandom
|
||||||
|
* @param IConfig $config
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
DbHandler $dbHandler,
|
||||||
|
IClientService $httpClientService,
|
||||||
|
ILogger $logger,
|
||||||
|
IJobList $jobList,
|
||||||
|
ISecureRandom $secureRandom,
|
||||||
|
IConfig $config
|
||||||
|
) {
|
||||||
|
$this->dbHandler = $dbHandler;
|
||||||
|
$this->httpClientService = $httpClientService;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->jobList = $jobList;
|
||||||
|
$this->secureRandom = $secureRandom;
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add server to the list of trusted ownCloud servers
|
||||||
|
*
|
||||||
|
* @param $url
|
||||||
|
* @return int server id
|
||||||
|
*/
|
||||||
|
public function addServer($url) {
|
||||||
|
$url = $this->updateProtocol($url);
|
||||||
|
$result = $this->dbHandler->addServer($url);
|
||||||
|
if ($result) {
|
||||||
|
$token = $this->secureRandom->getMediumStrengthGenerator()->generate(16);
|
||||||
|
$this->dbHandler->addToken($url, $token);
|
||||||
|
$this->jobList->add(
|
||||||
|
'OCA\Federation\BackgroundJob\RequestSharedSecret',
|
||||||
|
[
|
||||||
|
'url' => $url,
|
||||||
|
'token' => $token
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enable/disable to automatically add servers to the list of trusted servers
|
||||||
|
* once a federated share was created and accepted successfully
|
||||||
|
*
|
||||||
|
* @param bool $status
|
||||||
|
*/
|
||||||
|
public function setAutoAddServers($status) {
|
||||||
|
$value = $status ? '1' : '0';
|
||||||
|
$this->config->setAppValue('federation', 'autoAddServers', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return if we automatically add servers to the list of trusted servers
|
||||||
|
* once a federated share was created and accepted successfully
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getAutoAddServers() {
|
||||||
|
$value = $this->config->getAppValue('federation', 'autoAddServers', '1');
|
||||||
|
return $value === '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get shared secret for the given server
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSharedSecret($url) {
|
||||||
|
return $this->dbHandler->getSharedSecret($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add shared secret for the given server
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param $sharedSecret
|
||||||
|
*/
|
||||||
|
public function addSharedSecret($url, $sharedSecret) {
|
||||||
|
$this->dbHandler->addSharedSecret($url, $sharedSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove server from the list of trusted ownCloud servers
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public function removeServer($id) {
|
||||||
|
$this->dbHandler->removeServer($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all trusted servers
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getServers() {
|
||||||
|
return $this->dbHandler->getAllServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if given server is a trusted ownCloud server
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isTrustedServer($url) {
|
||||||
|
return $this->dbHandler->serverExists($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set server status
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param int $status
|
||||||
|
*/
|
||||||
|
public function setServerStatus($url, $status) {
|
||||||
|
$this->dbHandler->setServerStatus($url, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getServerStatus($url) {
|
||||||
|
return $this->dbHandler->getServerStatus($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if URL point to a ownCloud server
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isOwnCloudServer($url) {
|
||||||
|
$isValidOwnCloud = false;
|
||||||
|
$client = $this->httpClientService->newClient();
|
||||||
|
try {
|
||||||
|
$result = $client->get(
|
||||||
|
$url . '/status.php',
|
||||||
|
[
|
||||||
|
'timeout' => 3,
|
||||||
|
'connect_timeout' => 3,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if ($result->getStatusCode() === Http::STATUS_OK) {
|
||||||
|
$isValidOwnCloud = $this->checkOwnCloudVersion($result->getBody());
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error($e->getMessage(), ['app' => 'federation']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $isValidOwnCloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if ownCloud version is >= 9.0
|
||||||
|
*
|
||||||
|
* @param $statusphp
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function checkOwnCloudVersion($statusphp) {
|
||||||
|
$decoded = json_decode($statusphp, true);
|
||||||
|
if (!empty($decoded) && isset($decoded['version'])) {
|
||||||
|
return version_compare($decoded['version'], '9.0.0', '>=');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the URL contain a protocol, if not add https
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function updateProtocol($url) {
|
||||||
|
if (
|
||||||
|
strpos($url, 'https://') === 0
|
||||||
|
|| strpos($url, 'http://') === 0
|
||||||
|
) {
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'https://' . $url;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Federation\Middleware ;
|
||||||
|
|
||||||
|
use OC\HintException;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
use OCP\AppFramework\Middleware;
|
||||||
|
use OCP\IL10N;
|
||||||
|
use OCP\ILogger;
|
||||||
|
|
||||||
|
class AddServerMiddleware extends Middleware {
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $appName;
|
||||||
|
|
||||||
|
/** @var IL10N */
|
||||||
|
protected $l;
|
||||||
|
|
||||||
|
/** @var ILogger */
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
public function __construct($appName, IL10N $l, ILogger $logger) {
|
||||||
|
$this->appName = $appName;
|
||||||
|
$this->l = $l;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log error message and return a response which can be displayed to the user
|
||||||
|
*
|
||||||
|
* @param \OCP\AppFramework\Controller $controller
|
||||||
|
* @param string $methodName
|
||||||
|
* @param \Exception $exception
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function afterException($controller, $methodName, \Exception $exception) {
|
||||||
|
$this->logger->error($exception->getMessage(), ['app' => $this->appName]);
|
||||||
|
if ($exception instanceof HintException) {
|
||||||
|
$message = $exception->getHint();
|
||||||
|
} else {
|
||||||
|
$message = $this->l->t('Unknown error');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JSONResponse(
|
||||||
|
['message' => $message],
|
||||||
|
Http::STATUS_BAD_REQUEST
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
\OC_Util::checkAdminUser();
|
||||||
|
|
||||||
|
$template = new OCP\Template('federation', 'settings-admin');
|
||||||
|
|
||||||
|
$dbHandler = new \OCA\Federation\DbHandler(
|
||||||
|
\OC::$server->getDatabaseConnection(),
|
||||||
|
\OC::$server->getL10N('federation')
|
||||||
|
);
|
||||||
|
|
||||||
|
$trustedServers = new \OCA\Federation\TrustedServers(
|
||||||
|
$dbHandler,
|
||||||
|
\OC::$server->getHTTPClientService(),
|
||||||
|
\OC::$server->getLogger(),
|
||||||
|
\OC::$server->getJobList(),
|
||||||
|
\OC::$server->getSecureRandom(),
|
||||||
|
\OC::$server->getConfig()
|
||||||
|
);
|
||||||
|
|
||||||
|
$template->assign('trustedServers', $trustedServers->getServers());
|
||||||
|
$template->assign('autoAddServers', $trustedServers->getAutoAddServers());
|
||||||
|
|
||||||
|
return $template->fetchPage();
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/** @var array $_ */
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
|
||||||
|
/** @var OC_L10N $l */
|
||||||
|
script('federation', 'settings-admin');
|
||||||
|
style('federation', 'settings-admin')
|
||||||
|
?>
|
||||||
|
<div id="ocFederationSettings" class="section">
|
||||||
|
<h2><?php p($l->t('Federation')); ?></h2>
|
||||||
|
<em><?php p($l->t('ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing.')); ?></em>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<input id="autoAddServers" type="checkbox" class="checkbox" <?php if($_['autoAddServers']) p('checked'); ?> />
|
||||||
|
<label for="autoAddServers">Add server automatically once a federated share was created successfully</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Trusted ownCloud Servers</h3>
|
||||||
|
<p id="ocFederationAddServer">
|
||||||
|
<button id="ocFederationAddServerButton" class="">+ Add ownCloud server</button>
|
||||||
|
<input id="serverUrl" class="hidden" type="text" value="" placeholder="ownCloud Server" name="server_url"/>
|
||||||
|
<span class="msg"></span>
|
||||||
|
</p>
|
||||||
|
<ul id="listOfTrustedServers">
|
||||||
|
<?php foreach($_['trustedServers'] as $trustedServer) { ?>
|
||||||
|
<li id="<?php p($trustedServer['id']); ?>" class="icon-delete">
|
||||||
|
<?php if((int)$trustedServer['status'] === TrustedServers::STATUS_OK) { ?>
|
||||||
|
<span class="status success"></span>
|
||||||
|
<?php } elseif((int)$trustedServer['status'] === TrustedServers::STATUS_PENDING) { ?>
|
||||||
|
<span class="status indeterminate"></span>
|
||||||
|
<?php } else {?>
|
||||||
|
<span class="status error"></span>
|
||||||
|
<?php } ?>
|
||||||
|
<?php p($trustedServer['url']); ?>
|
||||||
|
</li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\API;
|
||||||
|
|
||||||
|
|
||||||
|
use OC\BackgroundJob\JobList;
|
||||||
|
use OCA\Federation\API\OCSAuthAPI;
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\Security\ISecureRandom;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class OCSAuthAPITest extends TestCase {
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IRequest */
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | ISecureRandom */
|
||||||
|
private $secureRandom;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | JobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var OCSAuthApi */
|
||||||
|
private $ocsAuthApi;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->request = $this->getMock('OCP\IRequest');
|
||||||
|
$this->secureRandom = $this->getMock('OCP\Security\ISecureRandom');
|
||||||
|
$this->trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->jobList = $this->getMockBuilder('OC\BackgroundJob\JobList')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->ocsAuthApi = new OCSAuthAPI(
|
||||||
|
$this->request,
|
||||||
|
$this->secureRandom,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->dbHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestRequestSharedSecret
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @param string $localToken
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
* @param int $expected
|
||||||
|
*/
|
||||||
|
public function testRequestSharedSecret($token, $localToken, $isTrustedServer, $expected) {
|
||||||
|
|
||||||
|
$url = 'url';
|
||||||
|
|
||||||
|
$this->request->expects($this->at(0))->method('getParam')->with('url')->willReturn($url);
|
||||||
|
$this->request->expects($this->at(1))->method('getParam')->with('token')->willReturn($token);
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isTrustedServer')->with($url)->willReturn($isTrustedServer);
|
||||||
|
$this->dbHandler->expects($this->any())
|
||||||
|
->method('getToken')->with($url)->willReturn($localToken);
|
||||||
|
|
||||||
|
if ($expected === Http::STATUS_OK) {
|
||||||
|
$this->jobList->expects($this->once())->method('add')
|
||||||
|
->with('OCA\Federation\BackgroundJob\GetSharedSecret', ['url' => $url, 'token' => $token]);
|
||||||
|
} else {
|
||||||
|
$this->jobList->expects($this->never())->method('add');
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->ocsAuthApi->requestSharedSecret();
|
||||||
|
$this->assertSame($expected, $result->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestRequestSharedSecret() {
|
||||||
|
return [
|
||||||
|
['token2', 'token1', true, Http::STATUS_OK],
|
||||||
|
['token1', 'token2', false, Http::STATUS_FORBIDDEN],
|
||||||
|
['token1', 'token2', true, Http::STATUS_FORBIDDEN],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestGetSharedSecret
|
||||||
|
*
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
* @param bool $isValidToken
|
||||||
|
* @param int $expected
|
||||||
|
*/
|
||||||
|
public function testGetSharedSecret($isTrustedServer, $isValidToken, $expected) {
|
||||||
|
|
||||||
|
$url = 'url';
|
||||||
|
$token = 'token';
|
||||||
|
|
||||||
|
$this->request->expects($this->at(0))->method('getParam')->with('url')->willReturn($url);
|
||||||
|
$this->request->expects($this->at(1))->method('getParam')->with('token')->willReturn($token);
|
||||||
|
|
||||||
|
/** @var OCSAuthAPI | \PHPUnit_Framework_MockObject_MockObject $ocsAuthApi */
|
||||||
|
$ocsAuthApi = $this->getMockBuilder('OCA\Federation\API\OCSAuthAPI')
|
||||||
|
->setConstructorArgs(
|
||||||
|
[
|
||||||
|
$this->request,
|
||||||
|
$this->secureRandom,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->dbHandler
|
||||||
|
]
|
||||||
|
)->setMethods(['isValidToken'])->getMock();
|
||||||
|
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isTrustedServer')->with($url)->willReturn($isTrustedServer);
|
||||||
|
$ocsAuthApi->expects($this->any())
|
||||||
|
->method('isValidToken')->with($url, $token)->willReturn($isValidToken);
|
||||||
|
|
||||||
|
if($expected === Http::STATUS_OK) {
|
||||||
|
$this->secureRandom->expects($this->once())->method('getMediumStrengthGenerator')
|
||||||
|
->willReturn($this->secureRandom);
|
||||||
|
$this->secureRandom->expects($this->once())->method('generate')->with(32)
|
||||||
|
->willReturn('secret');
|
||||||
|
$this->trustedServers->expects($this->once())
|
||||||
|
->method('addSharedSecret')->willReturn($url, 'secret');
|
||||||
|
$this->dbHandler->expects($this->once())
|
||||||
|
->method('addToken')->with($url, '');
|
||||||
|
} else {
|
||||||
|
$this->secureRandom->expects($this->never())->method('getMediumStrengthGenerator');
|
||||||
|
$this->secureRandom->expects($this->never())->method('generate');
|
||||||
|
$this->trustedServers->expects($this->never())->method('addSharedSecret');
|
||||||
|
$this->dbHandler->expects($this->never())->method('addToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $ocsAuthApi->getSharedSecret();
|
||||||
|
|
||||||
|
$this->assertSame($expected, $result->getStatusCode());
|
||||||
|
|
||||||
|
if ($expected === Http::STATUS_OK) {
|
||||||
|
$data = $result->getData();
|
||||||
|
$this->assertSame('secret', $data['sharedSecret']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestGetSharedSecret() {
|
||||||
|
return [
|
||||||
|
[true, true, Http::STATUS_OK],
|
||||||
|
[false, true, Http::STATUS_FORBIDDEN],
|
||||||
|
[true, false, Http::STATUS_FORBIDDEN],
|
||||||
|
[false, false, Http::STATUS_FORBIDDEN],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\BackgroundJob;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Federation\BackgroundJob\GetSharedSecret;
|
||||||
|
use OCA\Files_Sharing\Tests\TestCase;
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\Http\Client\IClient;
|
||||||
|
use OCP\Http\Client\IResponse;
|
||||||
|
use OCP\ILogger;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
|
||||||
|
class GetSharedSecretTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IClient */
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IURLGenerator */
|
||||||
|
private $urlGenerator;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | ILogger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IResponse */
|
||||||
|
private $response;
|
||||||
|
|
||||||
|
/** @var GetSharedSecret */
|
||||||
|
private $getSharedSecret;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->httpClient = $this->getMock('OCP\Http\Client\IClient');
|
||||||
|
$this->jobList = $this->getMock('OCP\BackgroundJob\IJobList');
|
||||||
|
$this->urlGenerator = $this->getMock('OCP\IURLGenerator');
|
||||||
|
$this->trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->logger = $this->getMock('OCP\ILogger');
|
||||||
|
$this->response = $this->getMock('OCP\Http\Client\IResponse');
|
||||||
|
|
||||||
|
$this->getSharedSecret = new GetSharedSecret(
|
||||||
|
$this->httpClient,
|
||||||
|
$this->urlGenerator,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->logger,
|
||||||
|
$this->dbHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestExecute
|
||||||
|
*
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
*/
|
||||||
|
public function testExecute($isTrustedServer) {
|
||||||
|
/** @var GetSharedSecret |\PHPUnit_Framework_MockObject_MockObject $getSharedSecret */
|
||||||
|
$getSharedSecret = $this->getMockBuilder('OCA\Federation\BackgroundJob\GetSharedSecret')
|
||||||
|
->setConstructorArgs(
|
||||||
|
[
|
||||||
|
$this->httpClient,
|
||||||
|
$this->urlGenerator,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->logger,
|
||||||
|
$this->dbHandler
|
||||||
|
]
|
||||||
|
)->setMethods(['parentExecute'])->getMock();
|
||||||
|
$this->invokePrivate($getSharedSecret, 'argument', [['url' => 'url']]);
|
||||||
|
|
||||||
|
$this->jobList->expects($this->once())->method('remove');
|
||||||
|
$this->trustedServers->expects($this->once())->method('isTrustedServer')
|
||||||
|
->with('url')->willReturn($isTrustedServer);
|
||||||
|
if ($isTrustedServer) {
|
||||||
|
$getSharedSecret->expects($this->once())->method('parentExecute');
|
||||||
|
} else {
|
||||||
|
$getSharedSecret->expects($this->never())->method('parentExecute');
|
||||||
|
}
|
||||||
|
|
||||||
|
$getSharedSecret->execute($this->jobList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestExecute() {
|
||||||
|
return [
|
||||||
|
[true],
|
||||||
|
[false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestRun
|
||||||
|
*
|
||||||
|
* @param int $statusCode
|
||||||
|
*/
|
||||||
|
public function testRun($statusCode) {
|
||||||
|
|
||||||
|
$target = 'targetURL';
|
||||||
|
$source = 'sourceURL';
|
||||||
|
$token = 'token';
|
||||||
|
|
||||||
|
$argument = ['url' => $target, 'token' => $token];
|
||||||
|
|
||||||
|
$this->urlGenerator->expects($this->once())->method('getAbsoluteURL')->with('/')
|
||||||
|
->willReturn($source);
|
||||||
|
$this->httpClient->expects($this->once())->method('get')
|
||||||
|
->with(
|
||||||
|
$target . '/ocs/v2.php/apps/federation/api/v1/shared-secret?format=json',
|
||||||
|
[
|
||||||
|
'query' =>
|
||||||
|
[
|
||||||
|
'url' => $source,
|
||||||
|
'token' => $token
|
||||||
|
],
|
||||||
|
'timeout' => 3,
|
||||||
|
'connect_timeout' => 3,
|
||||||
|
]
|
||||||
|
)->willReturn($this->response);
|
||||||
|
|
||||||
|
$this->response->expects($this->once())->method('getStatusCode')
|
||||||
|
->willReturn($statusCode);
|
||||||
|
|
||||||
|
if (
|
||||||
|
$statusCode !== Http::STATUS_OK
|
||||||
|
&& $statusCode !== Http::STATUS_FORBIDDEN
|
||||||
|
) {
|
||||||
|
$this->jobList->expects($this->once())->method('add')
|
||||||
|
->with('OCA\Federation\BackgroundJob\GetSharedSecret', $argument);
|
||||||
|
$this->dbHandler->expects($this->never())->method('addToken');
|
||||||
|
} else {
|
||||||
|
$this->dbHandler->expects($this->once())->method('addToken')->with($target, '');
|
||||||
|
$this->jobList->expects($this->never())->method('add');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($statusCode === Http::STATUS_OK) {
|
||||||
|
$this->response->expects($this->once())->method('getBody')
|
||||||
|
->willReturn('{"ocs":{"data":{"sharedSecret":"secret"}}}');
|
||||||
|
$this->trustedServers->expects($this->once())->method('addSharedSecret')
|
||||||
|
->with($target, 'secret');
|
||||||
|
} else {
|
||||||
|
$this->trustedServers->expects($this->never())->method('addSharedSecret');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->invokePrivate($this->getSharedSecret, 'run', [$argument]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestRun() {
|
||||||
|
return [
|
||||||
|
[Http::STATUS_OK],
|
||||||
|
[Http::STATUS_FORBIDDEN],
|
||||||
|
[Http::STATUS_CONFLICT],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\BackgroundJob;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Federation\BackgroundJob\RequestSharedSecret;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class RequestSharedSecretTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IClient */
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IURLGenerator */
|
||||||
|
private $urlGenerator;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IResponse */
|
||||||
|
private $response;
|
||||||
|
|
||||||
|
/** @var RequestSharedSecret */
|
||||||
|
private $requestSharedSecret;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->httpClient = $this->getMock('OCP\Http\Client\IClient');
|
||||||
|
$this->jobList = $this->getMock('OCP\BackgroundJob\IJobList');
|
||||||
|
$this->urlGenerator = $this->getMock('OCP\IURLGenerator');
|
||||||
|
$this->trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->response = $this->getMock('OCP\Http\Client\IResponse');
|
||||||
|
|
||||||
|
$this->requestSharedSecret = new RequestSharedSecret(
|
||||||
|
$this->httpClient,
|
||||||
|
$this->urlGenerator,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->dbHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestExecute
|
||||||
|
*
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
*/
|
||||||
|
public function testExecute($isTrustedServer) {
|
||||||
|
/** @var RequestSharedSecret |\PHPUnit_Framework_MockObject_MockObject $requestSharedSecret */
|
||||||
|
$requestSharedSecret = $this->getMockBuilder('OCA\Federation\BackgroundJob\RequestSharedSecret')
|
||||||
|
->setConstructorArgs(
|
||||||
|
[
|
||||||
|
$this->httpClient,
|
||||||
|
$this->urlGenerator,
|
||||||
|
$this->jobList,
|
||||||
|
$this->trustedServers,
|
||||||
|
$this->dbHandler
|
||||||
|
]
|
||||||
|
)->setMethods(['parentExecute'])->getMock();
|
||||||
|
$this->invokePrivate($requestSharedSecret, 'argument', [['url' => 'url']]);
|
||||||
|
|
||||||
|
$this->jobList->expects($this->once())->method('remove');
|
||||||
|
$this->trustedServers->expects($this->once())->method('isTrustedServer')
|
||||||
|
->with('url')->willReturn($isTrustedServer);
|
||||||
|
if ($isTrustedServer) {
|
||||||
|
$requestSharedSecret->expects($this->once())->method('parentExecute');
|
||||||
|
} else {
|
||||||
|
$requestSharedSecret->expects($this->never())->method('parentExecute');
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestSharedSecret->execute($this->jobList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestExecute() {
|
||||||
|
return [
|
||||||
|
[true],
|
||||||
|
[false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestRun
|
||||||
|
*
|
||||||
|
* @param int $statusCode
|
||||||
|
*/
|
||||||
|
public function testRun($statusCode) {
|
||||||
|
|
||||||
|
$target = 'targetURL';
|
||||||
|
$source = 'sourceURL';
|
||||||
|
$token = 'token';
|
||||||
|
|
||||||
|
$argument = ['url' => $target, 'token' => $token];
|
||||||
|
|
||||||
|
$this->urlGenerator->expects($this->once())->method('getAbsoluteURL')->with('/')
|
||||||
|
->willReturn($source);
|
||||||
|
$this->httpClient->expects($this->once())->method('post')
|
||||||
|
->with(
|
||||||
|
$target . '/ocs/v2.php/apps/federation/api/v1/request-shared-secret?format=json',
|
||||||
|
[
|
||||||
|
'body' =>
|
||||||
|
[
|
||||||
|
'url' => $source,
|
||||||
|
'token' => $token
|
||||||
|
],
|
||||||
|
'timeout' => 3,
|
||||||
|
'connect_timeout' => 3,
|
||||||
|
]
|
||||||
|
)->willReturn($this->response);
|
||||||
|
|
||||||
|
$this->response->expects($this->once())->method('getStatusCode')
|
||||||
|
->willReturn($statusCode);
|
||||||
|
|
||||||
|
if (
|
||||||
|
$statusCode !== Http::STATUS_OK
|
||||||
|
&& $statusCode !== Http::STATUS_FORBIDDEN
|
||||||
|
) {
|
||||||
|
$this->jobList->expects($this->once())->method('add')
|
||||||
|
->with('OCA\Federation\BackgroundJob\RequestSharedSecret', $argument);
|
||||||
|
$this->dbHandler->expects($this->never())->method('addToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($statusCode === Http::STATUS_FORBIDDEN) {
|
||||||
|
$this->jobList->expects($this->never())->method('add');
|
||||||
|
$this->dbHandler->expects($this->once())->method('addToken')->with($target, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->invokePrivate($this->requestSharedSecret, 'run', [$argument]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestRun() {
|
||||||
|
return [
|
||||||
|
[Http::STATUS_OK],
|
||||||
|
[Http::STATUS_FORBIDDEN],
|
||||||
|
[Http::STATUS_CONFLICT],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\Controller;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Federation\Controller\SettingsController;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class SettingsControllerTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var SettingsController */
|
||||||
|
private $controller;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IRequest */
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IL10N */
|
||||||
|
private $l10n;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCA\Federation\TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->request = $this->getMock('OCP\IRequest');
|
||||||
|
$this->l10n = $this->getMock('OCP\IL10N');
|
||||||
|
$this->trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->controller = new SettingsController(
|
||||||
|
'SettingsControllerTest',
|
||||||
|
$this->request,
|
||||||
|
$this->l10n,
|
||||||
|
$this->trustedServers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddServer() {
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isTrustedServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn(false);
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isOwnCloudServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$result = $this->controller->addServer('url');
|
||||||
|
$this->assertTrue($result instanceof DataResponse);
|
||||||
|
|
||||||
|
$data = $result->getData();
|
||||||
|
$this->assertSame(200, $result->getStatus());
|
||||||
|
$this->assertSame('url', $data['url']);
|
||||||
|
$this->assertArrayHasKey('id', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider checkServerFails
|
||||||
|
* @expectedException \OC\HintException
|
||||||
|
*
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
* @param bool $isOwnCloud
|
||||||
|
*/
|
||||||
|
public function testAddServerFail($isTrustedServer, $isOwnCloud) {
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isTrustedServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn($isTrustedServer);
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isOwnCloudServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn($isOwnCloud);
|
||||||
|
|
||||||
|
$this->controller->addServer('url');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRemoveServer() {
|
||||||
|
$this->trustedServers->expects($this->once())->method('removeServer')
|
||||||
|
->with('url');
|
||||||
|
$result = $this->controller->removeServer('url');
|
||||||
|
$this->assertTrue($result instanceof DataResponse);
|
||||||
|
$this->assertSame(200, $result->getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCheckServer() {
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isTrustedServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn(false);
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isOwnCloudServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->invokePrivate($this->controller, 'checkServer', ['url'])
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider checkServerFails
|
||||||
|
* @expectedException \OC\HintException
|
||||||
|
*
|
||||||
|
* @param bool $isTrustedServer
|
||||||
|
* @param bool $isOwnCloud
|
||||||
|
*/
|
||||||
|
public function testCheckServerFail($isTrustedServer, $isOwnCloud) {
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isTrustedServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn($isTrustedServer);
|
||||||
|
$this->trustedServers
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isOwnCloudServer')
|
||||||
|
->with('url')
|
||||||
|
->willReturn($isOwnCloud);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->invokePrivate($this->controller, 'checkServer', ['url'])
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* data to simulate checkServer fails
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function checkServerFails() {
|
||||||
|
return [
|
||||||
|
[true, true],
|
||||||
|
[false, false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\lib;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\IDBConnection;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group DB
|
||||||
|
*/
|
||||||
|
class DbHandlerTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $il10n;
|
||||||
|
|
||||||
|
/** @var IDBConnection */
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $dbTable = 'trusted_servers';
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->connection = \OC::$server->getDatabaseConnection();
|
||||||
|
$this->il10n = $this->getMock('OCP\IL10N');
|
||||||
|
|
||||||
|
$this->dbHandler = new DbHandler(
|
||||||
|
$this->connection,
|
||||||
|
$this->il10n
|
||||||
|
);
|
||||||
|
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertEmpty($result, 'we need to start with a empty trusted_servers table');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
$query = $this->connection->getQueryBuilder()->delete($this->dbTable);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddServer() {
|
||||||
|
$id = $this->dbHandler->addServer('server1');
|
||||||
|
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame('server1', $result[0]['url']);
|
||||||
|
$this->assertSame($id, (int)$result[0]['id']);
|
||||||
|
$this->assertSame(TrustedServers::STATUS_PENDING, (int)$result[0]['status']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRemove() {
|
||||||
|
$id1 = $this->dbHandler->addServer('server1');
|
||||||
|
$id2 = $this->dbHandler->addServer('server2');
|
||||||
|
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(2, count($result));
|
||||||
|
$this->assertSame('server1', $result[0]['url']);
|
||||||
|
$this->assertSame('server2', $result[1]['url']);
|
||||||
|
$this->assertSame($id1, (int)$result[0]['id']);
|
||||||
|
$this->assertSame($id2, (int)$result[1]['id']);
|
||||||
|
|
||||||
|
$this->dbHandler->removeServer($id2);
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame('server1', $result[0]['url']);
|
||||||
|
$this->assertSame($id1, (int)$result[0]['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAll() {
|
||||||
|
$id1 = $this->dbHandler->addServer('server1');
|
||||||
|
$id2 = $this->dbHandler->addServer('server2');
|
||||||
|
|
||||||
|
$result = $this->dbHandler->getAllServer();
|
||||||
|
$this->assertSame(2, count($result));
|
||||||
|
$this->assertSame('server1', $result[0]['url']);
|
||||||
|
$this->assertSame('server2', $result[1]['url']);
|
||||||
|
$this->assertSame($id1, (int)$result[0]['id']);
|
||||||
|
$this->assertSame($id2, (int)$result[1]['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestServerExists
|
||||||
|
*
|
||||||
|
* @param string $serverInTable
|
||||||
|
* @param string $checkForServer
|
||||||
|
* @param bool $expected
|
||||||
|
*/
|
||||||
|
public function testServerExists($serverInTable, $checkForServer, $expected) {
|
||||||
|
$this->dbHandler->addServer($serverInTable);
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->dbHandler->serverExists($checkForServer)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestServerExists() {
|
||||||
|
return [
|
||||||
|
['server1', 'server1', true],
|
||||||
|
['server1', 'http://server1', true],
|
||||||
|
['server1', 'server2', false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddToken() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame(null, $result[0]['token']);
|
||||||
|
$this->dbHandler->addToken('http://server1', 'token');
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame('token', $result[0]['token']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetToken() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$this->dbHandler->addToken('http://server1', 'token');
|
||||||
|
$this->assertSame('token',
|
||||||
|
$this->dbHandler->getToken('https://server1')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddSharedSecret() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame(null, $result[0]['shared_secret']);
|
||||||
|
$this->dbHandler->addSharedSecret('http://server1', 'secret');
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame('secret', $result[0]['shared_secret']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSharedSecret() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$this->dbHandler->addSharedSecret('http://server1', 'secret');
|
||||||
|
$this->assertSame('secret',
|
||||||
|
$this->dbHandler->getSharedSecret('https://server1')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetServerStatus() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame(TrustedServers::STATUS_PENDING, (int)$result[0]['status']);
|
||||||
|
$this->dbHandler->setServerStatus('http://server1', TrustedServers::STATUS_OK);
|
||||||
|
$query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable);
|
||||||
|
$result = $query->execute()->fetchAll();
|
||||||
|
$this->assertSame(1, count($result));
|
||||||
|
$this->assertSame(TrustedServers::STATUS_OK, (int)$result[0]['status']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetServerStatus() {
|
||||||
|
$this->dbHandler->addServer('server1');
|
||||||
|
$this->dbHandler->setServerStatus('http://server1', TrustedServers::STATUS_OK);
|
||||||
|
$this->assertSame(TrustedServers::STATUS_OK,
|
||||||
|
$this->dbHandler->getServerStatus('https://server1')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash should always be computed with the normalized URL
|
||||||
|
*
|
||||||
|
* @dataProvider dataTestHash
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param string $expected
|
||||||
|
*/
|
||||||
|
public function testHash($url, $expected) {
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->invokePrivate($this->dbHandler, 'hash', [$url])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestHash() {
|
||||||
|
return [
|
||||||
|
['server1', md5('server1')],
|
||||||
|
['http://server1', md5('server1')],
|
||||||
|
['https://server1', md5('server1')],
|
||||||
|
['http://server1/', md5('server1')],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestNormalizeUrl
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param string $expected
|
||||||
|
*/
|
||||||
|
public function testNormalizeUrl($url, $expected) {
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->invokePrivate($this->dbHandler, 'normalizeUrl', [$url])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestNormalizeUrl() {
|
||||||
|
return [
|
||||||
|
['owncloud.org', 'owncloud.org'],
|
||||||
|
['http://owncloud.org', 'owncloud.org'],
|
||||||
|
['https://owncloud.org', 'owncloud.org'],
|
||||||
|
['https://owncloud.org//mycloud', 'owncloud.org/mycloud'],
|
||||||
|
['https://owncloud.org/mycloud/', 'owncloud.org/mycloud'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,344 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\lib;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Federation\DbHandler;
|
||||||
|
use OCA\Federation\TrustedServers;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\Http\Client\IClient;
|
||||||
|
use OCP\Http\Client\IClientService;
|
||||||
|
use OCP\Http\Client\IResponse;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\ILogger;
|
||||||
|
use OCP\Security\ISecureRandom;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class TrustedServersTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var TrustedServers */
|
||||||
|
private $trustedServers;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | DbHandler */
|
||||||
|
private $dbHandler;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IClientService */
|
||||||
|
private $httpClientService;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IClient */
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IResponse */
|
||||||
|
private $response;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | ILogger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | ISecureRandom */
|
||||||
|
private $secureRandom;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | IConfig */
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->dbHandler = $this->getMockBuilder('\OCA\Federation\DbHandler')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->httpClientService = $this->getMock('OCP\Http\Client\IClientService');
|
||||||
|
$this->httpClient = $this->getMock('OCP\Http\Client\IClient');
|
||||||
|
$this->response = $this->getMock('OCP\Http\Client\IResponse');
|
||||||
|
$this->logger = $this->getMock('OCP\ILogger');
|
||||||
|
$this->jobList = $this->getMock('OCP\BackgroundJob\IJobList');
|
||||||
|
$this->secureRandom = $this->getMock('OCP\Security\ISecureRandom');
|
||||||
|
$this->config = $this->getMock('OCP\IConfig');
|
||||||
|
|
||||||
|
$this->trustedServers = new TrustedServers(
|
||||||
|
$this->dbHandler,
|
||||||
|
$this->httpClientService,
|
||||||
|
$this->logger,
|
||||||
|
$this->jobList,
|
||||||
|
$this->secureRandom,
|
||||||
|
$this->config
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTrueFalse
|
||||||
|
*
|
||||||
|
* @param bool $success
|
||||||
|
*/
|
||||||
|
public function testAddServer($success) {
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | TrustedServers $trustedServer */
|
||||||
|
$trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->setConstructorArgs(
|
||||||
|
[
|
||||||
|
$this->dbHandler,
|
||||||
|
$this->httpClientService,
|
||||||
|
$this->logger,
|
||||||
|
$this->jobList,
|
||||||
|
$this->secureRandom,
|
||||||
|
$this->config
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->setMethods(['normalizeUrl', 'updateProtocol'])
|
||||||
|
->getMock();
|
||||||
|
$trustedServers->expects($this->once())->method('updateProtocol')
|
||||||
|
->with('url')->willReturn('https://url');
|
||||||
|
$this->dbHandler->expects($this->once())->method('addServer')->with('https://url')
|
||||||
|
->willReturn($success);
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
$this->secureRandom->expects($this->once())->method('getMediumStrengthGenerator')
|
||||||
|
->willReturn($this->secureRandom);
|
||||||
|
$this->secureRandom->expects($this->once())->method('generate')
|
||||||
|
->willReturn('token');
|
||||||
|
$this->dbHandler->expects($this->once())->method('addToken')->with('https://url', 'token');
|
||||||
|
$this->jobList->expects($this->once())->method('add')
|
||||||
|
->with('OCA\Federation\BackgroundJob\RequestSharedSecret',
|
||||||
|
['url' => 'https://url', 'token' => 'token']);
|
||||||
|
} else {
|
||||||
|
$this->jobList->expects($this->never())->method('add');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame($success,
|
||||||
|
$trustedServers->addServer('url')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTrueFalse() {
|
||||||
|
return [
|
||||||
|
[true],
|
||||||
|
[false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTrueFalse
|
||||||
|
*
|
||||||
|
* @param bool $status
|
||||||
|
*/
|
||||||
|
public function testSetAutoAddServers($status) {
|
||||||
|
if ($status) {
|
||||||
|
$this->config->expects($this->once())->method('setAppValue')
|
||||||
|
->with('federation', 'autoAddServers', '1');
|
||||||
|
} else {
|
||||||
|
$this->config->expects($this->once())->method('setAppValue')
|
||||||
|
->with('federation', 'autoAddServers', '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->trustedServers->setAutoAddServers($status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestGetAutoAddServers
|
||||||
|
*
|
||||||
|
* @param string $status
|
||||||
|
* @param bool $expected
|
||||||
|
*/
|
||||||
|
public function testGetAutoAddServers($status, $expected) {
|
||||||
|
$this->config->expects($this->once())->method('getAppValue')
|
||||||
|
->with('federation', 'autoAddServers', '1')->willReturn($status);
|
||||||
|
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->trustedServers->getAutoAddServers($status)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestGetAutoAddServers() {
|
||||||
|
return [
|
||||||
|
['1', true],
|
||||||
|
['0', false]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddSharedSecret() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('addSharedSecret')
|
||||||
|
->with('url', 'secret');
|
||||||
|
$this->trustedServers->addSharedSecret('url', 'secret');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSharedSecret() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('getSharedSecret')
|
||||||
|
->with('url')->willReturn(true);
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->trustedServers->getSharedSecret('url')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRemoveServer() {
|
||||||
|
$id = 42;
|
||||||
|
$this->dbHandler->expects($this->once())->method('removeServer')->with($id);
|
||||||
|
$this->trustedServers->removeServer($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetServers() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('getAllServer')->willReturn(true);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->trustedServers->getServers()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testIsTrustedServer() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('serverExists')->with('url')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->trustedServers->isTrustedServer('url')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetServerStatus() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('setServerStatus')
|
||||||
|
->with('url', 'status');
|
||||||
|
$this->trustedServers->setServerStatus('url', 'status');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetServerStatus() {
|
||||||
|
$this->dbHandler->expects($this->once())->method('getServerStatus')
|
||||||
|
->with('url')->willReturn(true);
|
||||||
|
$this->assertTrue(
|
||||||
|
$this->trustedServers->getServerStatus('url')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestIsOwnCloudServer
|
||||||
|
*
|
||||||
|
* @param int $statusCode
|
||||||
|
* @param bool $isValidOwnCloudVersion
|
||||||
|
* @param bool $expected
|
||||||
|
*/
|
||||||
|
public function testIsOwnCloudServer($statusCode, $isValidOwnCloudVersion, $expected) {
|
||||||
|
|
||||||
|
$server = 'server1';
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | TrustedServers $trustedServer */
|
||||||
|
$trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
|
||||||
|
->setConstructorArgs(
|
||||||
|
[
|
||||||
|
$this->dbHandler,
|
||||||
|
$this->httpClientService,
|
||||||
|
$this->logger,
|
||||||
|
$this->jobList,
|
||||||
|
$this->secureRandom,
|
||||||
|
$this->config
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->setMethods(['checkOwnCloudVersion'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->httpClientService->expects($this->once())->method('newClient')
|
||||||
|
->willReturn($this->httpClient);
|
||||||
|
|
||||||
|
$this->httpClient->expects($this->once())->method('get')->with($server . '/status.php')
|
||||||
|
->willReturn($this->response);
|
||||||
|
|
||||||
|
$this->response->expects($this->once())->method('getStatusCode')
|
||||||
|
->willReturn($statusCode);
|
||||||
|
|
||||||
|
if ($statusCode === 200) {
|
||||||
|
$trustedServers->expects($this->once())->method('checkOwnCloudVersion')
|
||||||
|
->willReturn($isValidOwnCloudVersion);
|
||||||
|
} else {
|
||||||
|
$trustedServers->expects($this->never())->method('checkOwnCloudVersion');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$trustedServers->isOwnCloudServer($server)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestIsOwnCloudServer() {
|
||||||
|
return [
|
||||||
|
[200, true, true],
|
||||||
|
[200, false, false],
|
||||||
|
[404, true, false],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsOwnCloudServerFail() {
|
||||||
|
$server = 'server1';
|
||||||
|
|
||||||
|
$this->httpClientService->expects($this->once())->method('newClient')
|
||||||
|
->willReturn($this->httpClient);
|
||||||
|
|
||||||
|
$this->logger->expects($this->once())->method('error')
|
||||||
|
->with('simulated exception', ['app' => 'federation']);
|
||||||
|
|
||||||
|
$this->httpClient->expects($this->once())->method('get')->with($server . '/status.php')
|
||||||
|
->willReturnCallback(function () {
|
||||||
|
throw new \Exception('simulated exception');
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertFalse($this->trustedServers->isOwnCloudServer($server));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestCheckOwnCloudVersion
|
||||||
|
*
|
||||||
|
* @param $statusphp
|
||||||
|
* @param $expected
|
||||||
|
*/
|
||||||
|
public function testCheckOwnCloudVersion($statusphp, $expected) {
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->invokePrivate($this->trustedServers, 'checkOwnCloudVersion', [$statusphp])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestCheckOwnCloudVersion() {
|
||||||
|
return [
|
||||||
|
['{"version":"8.4.0"}', false],
|
||||||
|
['{"version":"9.0.0"}', true],
|
||||||
|
['{"version":"9.1.0"}', true]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestUpdateProtocol
|
||||||
|
* @param string $url
|
||||||
|
* @param string $expected
|
||||||
|
*/
|
||||||
|
public function testUpdateProtocol($url, $expected) {
|
||||||
|
$this->assertSame($expected,
|
||||||
|
$this->invokePrivate($this->trustedServers, 'updateProtocol', [$url])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestUpdateProtocol() {
|
||||||
|
return [
|
||||||
|
['http://owncloud.org', 'http://owncloud.org'],
|
||||||
|
['https://owncloud.org', 'https://owncloud.org'],
|
||||||
|
['owncloud.org', 'https://owncloud.org'],
|
||||||
|
['httpserver', 'https://httpserver'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Federation\Tests\Middleware;
|
||||||
|
|
||||||
|
|
||||||
|
use OC\HintException;
|
||||||
|
use OCA\Federation\Middleware\AddServerMiddleware;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class AddServerMiddlewareTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | ILogger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IL10N */
|
||||||
|
private $l10n;
|
||||||
|
|
||||||
|
/** @var AddServerMiddleware */
|
||||||
|
private $middleware;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject | Controller */
|
||||||
|
private $controller;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->logger = $this->getMock('OCP\ILogger');
|
||||||
|
$this->l10n = $this->getMock('OCP\IL10N');
|
||||||
|
$this->controller = $this->getMockBuilder('OCP\AppFramework\Controller')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->middleware = new AddServerMiddleware(
|
||||||
|
'AddServerMiddlewareTest',
|
||||||
|
$this->l10n,
|
||||||
|
$this->logger
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataTestAfterException
|
||||||
|
*
|
||||||
|
* @param \Exception $exception
|
||||||
|
* @param string $message
|
||||||
|
* @param string $hint
|
||||||
|
*/
|
||||||
|
public function testAfterException($exception, $message, $hint) {
|
||||||
|
|
||||||
|
$this->logger->expects($this->once())->method('error')
|
||||||
|
->with($message, ['app' => 'AddServerMiddlewareTest']);
|
||||||
|
|
||||||
|
$this->l10n->expects($this->any())->method('t')
|
||||||
|
->willReturnCallback(
|
||||||
|
function($message) {
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->middleware->afterException($this->controller, 'method', $exception);
|
||||||
|
|
||||||
|
$this->assertSame(Http::STATUS_BAD_REQUEST,
|
||||||
|
$result->getStatus()
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = $result->getData();
|
||||||
|
|
||||||
|
$this->assertSame($hint,
|
||||||
|
$data['message']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataTestAfterException() {
|
||||||
|
return [
|
||||||
|
[new HintException('message', 'hint'), 'message', 'hint'],
|
||||||
|
[new \Exception('message'), 'message', 'Unknown error'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,7 +32,8 @@
|
||||||
"user_ldap",
|
"user_ldap",
|
||||||
"user_shibboleth",
|
"user_shibboleth",
|
||||||
"windows_network_drive",
|
"windows_network_drive",
|
||||||
"password_policy"
|
"password_policy",
|
||||||
|
"federation"
|
||||||
],
|
],
|
||||||
"alwaysEnabled": [
|
"alwaysEnabled": [
|
||||||
"files",
|
"files",
|
||||||
|
|
|
@ -412,13 +412,13 @@ table.grid td.date{
|
||||||
.cronlog {
|
.cronlog {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
.cronstatus {
|
.status {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
.cronstatus.success {
|
.status.success {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -290,18 +290,18 @@ if ($_['cronErrors']) {
|
||||||
$relative_time = relative_modified_date($_['lastcron']);
|
$relative_time = relative_modified_date($_['lastcron']);
|
||||||
$absolute_time = OC_Util::formatDate($_['lastcron']);
|
$absolute_time = OC_Util::formatDate($_['lastcron']);
|
||||||
if (time() - $_['lastcron'] <= 3600): ?>
|
if (time() - $_['lastcron'] <= 3600): ?>
|
||||||
<span class="cronstatus success"></span>
|
<span class="status success"></span>
|
||||||
<span class="crondate" original-title="<?php p($absolute_time);?>">
|
<span class="crondate" original-title="<?php p($absolute_time);?>">
|
||||||
<?php p($l->t("Last cron job execution: %s.", [$relative_time]));?>
|
<?php p($l->t("Last cron job execution: %s.", [$relative_time]));?>
|
||||||
</span>
|
</span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<span class="cronstatus error"></span>
|
<span class="status error"></span>
|
||||||
<span class="crondate" original-title="<?php p($absolute_time);?>">
|
<span class="crondate" original-title="<?php p($absolute_time);?>">
|
||||||
<?php p($l->t("Last cron job execution: %s. Something seems wrong.", [$relative_time]));?>
|
<?php p($l->t("Last cron job execution: %s. Something seems wrong.", [$relative_time]));?>
|
||||||
</span>
|
</span>
|
||||||
<?php endif;
|
<?php endif;
|
||||||
else: ?>
|
else: ?>
|
||||||
<span class="cronstatus error"></span>
|
<span class="status error"></span>
|
||||||
<?php p($l->t("Cron was not executed yet!"));
|
<?php p($l->t("Cron was not executed yet!"));
|
||||||
endif; ?>
|
endif; ?>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -22,4 +22,4 @@ enableApp('encryption');
|
||||||
enableApp('user_ldap');
|
enableApp('user_ldap');
|
||||||
enableApp('files_versions');
|
enableApp('files_versions');
|
||||||
enableApp('provisioning_api');
|
enableApp('provisioning_api');
|
||||||
|
enableApp('federation');
|
||||||
|
|
Loading…
Reference in New Issue