summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-01-15 00:50:25 +0100
committerGitHub <noreply@github.com>2018-01-15 00:50:25 +0100
commit3baa5fada8deee9f0d9e1a8e7d88c7d07c1c7e81 (patch)
treede52a10c8ddaf422b271e1fe52e09dcbfef787b5
parent4f30c2fbe43e0d6f24ba3bff881526b2b6c2747d (diff)
parentf2706cb57210fc75329dc1cd3541042562e9c94b (diff)
downloadnextcloud-server-3baa5fada8deee9f0d9e1a8e7d88c7d07c1c7e81.tar.gz
nextcloud-server-3baa5fada8deee9f0d9e1a8e7d88c7d07c1c7e81.zip
Merge pull request #7806 from nextcloud/fix-7805
Fix bug with proxies
-rw-r--r--core/Controller/ClientFlowLoginController.php13
-rw-r--r--tests/Core/Controller/ClientFlowLoginControllerTest.php123
2 files changed, 135 insertions, 1 deletions
diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php
index 7d6e79d39bc..0e7fbf892b6 100644
--- a/core/Controller/ClientFlowLoginController.php
+++ b/core/Controller/ClientFlowLoginController.php
@@ -315,7 +315,18 @@ class ClientFlowLoginController extends Controller {
$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/flow'));
}
- $serverPath = $this->request->getServerProtocol() . "://" . $this->request->getServerHost() . $serverPostfix;
+ $protocol = $this->request->getServerProtocol();
+
+ if ($protocol !== "https") {
+ $xForwardedProto = $this->request->getHeader('X-Forwarded-Proto');
+ $xForwardedSSL = $this->request->getHeader('X-Forwarded-Ssl');
+ if ($xForwardedProto === 'https' || $xForwardedSSL === 'on') {
+ $protocol = 'https';
+ }
+ }
+
+
+ $serverPath = $protocol . "://" . $this->request->getServerHost() . $serverPostfix;
$redirectUri = 'nc://login/server:' . $serverPath . '&user:' . urlencode($loginName) . '&password:' . urlencode($token);
}
diff --git a/tests/Core/Controller/ClientFlowLoginControllerTest.php b/tests/Core/Controller/ClientFlowLoginControllerTest.php
index 21673863223..0e048538223 100644
--- a/tests/Core/Controller/ClientFlowLoginControllerTest.php
+++ b/tests/Core/Controller/ClientFlowLoginControllerTest.php
@@ -587,4 +587,127 @@ class ClientFlowLoginControllerTest extends TestCase {
$expected = new Http\RedirectResponse('nc://login/server:http://example.com&user:MyLoginName&password:MyGeneratedToken');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
}
+
+ public function dataGeneratePasswordWithHttpsProxy() {
+ return [
+ [
+ [
+ ['X-Forwarded-Proto', 'http'],
+ ['X-Forwarded-Ssl', 'off'],
+ ],
+ 'http',
+ 'http',
+ ],
+ [
+ [
+ ['X-Forwarded-Proto', 'http'],
+ ['X-Forwarded-Ssl', 'off'],
+ ],
+ 'https',
+ 'https',
+ ],
+ [
+ [
+ ['X-Forwarded-Proto', 'https'],
+ ['X-Forwarded-Ssl', 'off'],
+ ],
+ 'http',
+ 'https',
+ ],
+ [
+ [
+ ['X-Forwarded-Proto', 'https'],
+ ['X-Forwarded-Ssl', 'on'],
+ ],
+ 'http',
+ 'https',
+ ],
+ [
+ [
+ ['X-Forwarded-Proto', 'http'],
+ ['X-Forwarded-Ssl', 'on'],
+ ],
+ 'http',
+ 'https',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGeneratePasswordWithHttpsProxy
+ * @param array $headers
+ * @param string $protocol
+ * @param string $expected
+ */
+ public function testGeneratePasswordWithHttpsProxy(array $headers, $protocol, $expected) {
+ $this->session
+ ->expects($this->once())
+ ->method('get')
+ ->with('client.flow.state.token')
+ ->willReturn('MyStateToken');
+ $this->session
+ ->expects($this->once())
+ ->method('remove')
+ ->with('client.flow.state.token');
+ $this->session
+ ->expects($this->once())
+ ->method('getId')
+ ->willReturn('SessionId');
+ $myToken = $this->createMock(IToken::class);
+ $myToken
+ ->expects($this->once())
+ ->method('getLoginName')
+ ->willReturn('MyLoginName');
+ $this->tokenProvider
+ ->expects($this->once())
+ ->method('getToken')
+ ->with('SessionId')
+ ->willReturn($myToken);
+ $this->tokenProvider
+ ->expects($this->once())
+ ->method('getPassword')
+ ->with($myToken, 'SessionId')
+ ->willReturn('MyPassword');
+ $this->random
+ ->expects($this->once())
+ ->method('generate')
+ ->with(72)
+ ->willReturn('MyGeneratedToken');
+ $user = $this->createMock(IUser::class);
+ $user
+ ->expects($this->once())
+ ->method('getUID')
+ ->willReturn('MyUid');
+ $this->userSession
+ ->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+ $this->tokenProvider
+ ->expects($this->once())
+ ->method('generateToken')
+ ->with(
+ 'MyGeneratedToken',
+ 'MyUid',
+ 'MyLoginName',
+ 'MyPassword',
+ 'unknown',
+ IToken::PERMANENT_TOKEN,
+ IToken::DO_NOT_REMEMBER
+ );
+ $this->request
+ ->expects($this->once())
+ ->method('getServerProtocol')
+ ->willReturn($protocol);
+ $this->request
+ ->expects($this->once())
+ ->method('getServerHost')
+ ->willReturn('example.com');
+ $this->request
+ ->expects($this->atLeastOnce())
+ ->method('getHeader')
+ ->willReturnMap($headers);
+
+ $expected = new Http\RedirectResponse('nc://login/server:' . $expected . '://example.com&user:MyLoginName&password:MyGeneratedToken');
+ $this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
+ }
}