use https by default if no protocol is given. Only use unsecure connection if it is explicitely given

Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
This commit is contained in:
Bjoern Schiessle 2016-11-02 10:44:55 +01:00
parent 42b0a0d2af
commit 76b1dee499
No known key found for this signature in database
GPG Key ID: 2378A753E2BF04F6
4 changed files with 65 additions and 37 deletions

View File

@ -160,6 +160,22 @@ class AddressHandler {
return $url; return $url;
} }
/**
* check if the url contain the protocol (http or https)
*
* @param string $url
* @return bool
*/
public function urlContainProtocol($url) {
if (strpos($url, 'https://') === 0 ||
strpos($url, 'http://') === 0) {
return true;
}
return false;
}
/** /**
* Strips away a potential file names and trailing slashes: * Strips away a potential file names and trailing slashes:
* - http://localhost * - http://localhost

View File

@ -84,7 +84,6 @@ class Notifications {
list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith); list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
if ($user && $remote) { if ($user && $remote) {
$url = $remote;
$local = $this->addressHandler->generateRemoteURL(); $local = $this->addressHandler->generateRemoteURL();
$fields = array( $fields = array(
@ -99,8 +98,7 @@ class Notifications {
'remote' => $local, 'remote' => $local,
); );
$url = $this->addressHandler->removeProtocolFromUrl($url); $result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
$result = $this->tryHttpPostToShareEndpoint($url, '', $fields);
$status = json_decode($result['result'], true); $status = json_decode($result['result'], true);
if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) { if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) {
@ -135,8 +133,7 @@ class Notifications {
'remoteId' => $shareId 'remoteId' => $shareId
); );
$url = $this->addressHandler->removeProtocolFromUrl($remote); $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
$result = $this->tryHttpPostToShareEndpoint(rtrim($url, '/'), '/' . $id . '/reshare', $fields);
$status = json_decode($result['result'], true); $status = json_decode($result['result'], true);
$httpRequestSuccessful = $result['success']; $httpRequestSuccessful = $result['success'];
@ -193,7 +190,7 @@ class Notifications {
/** /**
* forward accept reShare to remote server * forward accept reShare to remote server
* *
* @param string $remote * @param string $remote
* @param int $remoteId * @param int $remoteId
* @param string $token * @param string $token
@ -231,8 +228,7 @@ class Notifications {
$fields[$key] = $value; $fields[$key] = $value;
} }
$url = $this->addressHandler->removeProtocolFromUrl($remote); $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields);
$result = $this->tryHttpPostToShareEndpoint(rtrim($url, '/'), '/' . $remoteId . '/' . $action, $fields);
$status = json_decode($result['result'], true); $status = json_decode($result['result'], true);
if ($result['success'] && if ($result['success'] &&
@ -270,7 +266,8 @@ class Notifications {
} }
/** /**
* try http post first with https and then with http as a fallback * try http post with the given protocol, if no protocol is given we pick
* the secure one (https)
* *
* @param string $remoteDomain * @param string $remoteDomain
* @param string $urlSuffix * @param string $urlSuffix
@ -280,33 +277,31 @@ class Notifications {
*/ */
protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) { protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
$client = $this->httpClientService->newClient(); $client = $this->httpClientService->newClient();
$protocol = 'https://';
if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
$remoteDomain = 'https://' . $remoteDomain;
}
$result = [ $result = [
'success' => false, 'success' => false,
'result' => '', 'result' => '',
]; ];
$try = 0;
while ($result['success'] === false && $try < 2) { $endpoint = $this->discoveryManager->getShareEndpoint($remoteDomain);
$endpoint = $this->discoveryManager->getShareEndpoint($protocol . $remoteDomain); try {
try { $response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
$response = $client->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [ 'body' => $fields,
'body' => $fields, 'timeout' => 10,
'timeout' => 10, 'connect_timeout' => 10,
'connect_timeout' => 10, ]);
]); $result['result'] = $response->getBody();
$result['result'] = $response->getBody(); $result['success'] = true;
$result['success'] = true; } catch (\Exception $e) {
break; // if flat re-sharing is not supported by the remote server
} catch (\Exception $e) { // we re-throw the exception and fall back to the old behaviour.
// if flat re-sharing is not supported by the remote server // (flat re-shares has been introduced in Nextcloud 9.1)
// we re-throw the exception and fall back to the old behaviour. if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
// (flat re-shares has been introduced in Nextcloud 9.1) throw $e;
if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
throw $e;
}
$try++;
$protocol = 'http://';
} }
} }

View File

@ -177,6 +177,26 @@ class AddressHandlerTest extends \Test\TestCase {
]; ];
} }
/**
* @dataProvider dataTestUrlContainProtocol
*
* @param string $url
* @param bool $expectedResult
*/
public function testUrlContainProtocol($url, $expectedResult) {
$result = $this->addressHandler->urlContainProtocol($url);
$this->assertSame($expectedResult, $result);
}
public function dataTestUrlContainProtocol() {
return [
['http://nextcloud.com', true],
['https://nextcloud.com', true],
['nextcloud.com', false],
['httpserver.com', false],
];
}
/** /**
* @dataProvider dataTestFixRemoteUrl * @dataProvider dataTestFixRemoteUrl
* *

View File

@ -58,7 +58,7 @@ class NotificationsTest extends \Test\TestCase {
/** /**
* get instance of Notifications class * get instance of Notifications class
* *
* @param array $mockedMethods methods which should be mocked * @param array $mockedMethods methods which should be mocked
* @return Notifications | \PHPUnit_Framework_MockObject_MockObject * @return Notifications | \PHPUnit_Framework_MockObject_MockObject
*/ */
@ -81,7 +81,7 @@ class NotificationsTest extends \Test\TestCase {
] ]
)->setMethods($mockedMethods)->getMock(); )->setMethods($mockedMethods)->getMock();
} }
return $instance; return $instance;
} }
@ -94,7 +94,7 @@ class NotificationsTest extends \Test\TestCase {
* @param bool $expected * @param bool $expected
*/ */
public function testSendUpdateToRemote($try, $httpRequestResult, $expected) { public function testSendUpdateToRemote($try, $httpRequestResult, $expected) {
$remote = 'remote'; $remote = 'http://remote';
$id = 42; $id = 42;
$timestamp = 63576; $timestamp = 63576;
$token = 'token'; $token = 'token';
@ -106,9 +106,6 @@ class NotificationsTest extends \Test\TestCase {
->with($remote, '/'.$id.'/unshare', ['token' => $token, 'data1Key' => 'data1Value']) ->with($remote, '/'.$id.'/unshare', ['token' => $token, 'data1Key' => 'data1Value'])
->willReturn($httpRequestResult); ->willReturn($httpRequestResult);
$this->addressHandler->expects($this->once())->method('removeProtocolFromUrl')
->with($remote)->willReturn($remote);
// only add background job on first try // only add background job on first try
if ($try === 0 && $expected === false) { if ($try === 0 && $expected === false) {
$this->jobList->expects($this->once())->method('add') $this->jobList->expects($this->once())->method('add')