Skip to content

Commit dbd1620

Browse files
Merge pull request #7859 from nextcloud/master-7806
Fix bug with proxies
2 parents 0023cb1 + 7789fbd commit dbd1620

File tree

2 files changed

+135
-1
lines changed

2 files changed

+135
-1
lines changed

core/Controller/ClientFlowLoginController.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,18 @@ public function generateAppPassword($stateToken,
315315
$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/flow'));
316316
}
317317

318-
$serverPath = $this->request->getServerProtocol() . "://" . $this->request->getServerHost() . $serverPostfix;
318+
$protocol = $this->request->getServerProtocol();
319+
320+
if ($protocol !== "https") {
321+
$xForwardedProto = $this->request->getHeader('X-Forwarded-Proto');
322+
$xForwardedSSL = $this->request->getHeader('X-Forwarded-Ssl');
323+
if ($xForwardedProto === 'https' || $xForwardedSSL === 'on') {
324+
$protocol = 'https';
325+
}
326+
}
327+
328+
329+
$serverPath = $protocol . "://" . $this->request->getServerHost() . $serverPostfix;
319330
$redirectUri = 'nc://login/server:' . $serverPath . '&user:' . urlencode($loginName) . '&password:' . urlencode($token);
320331
}
321332

tests/Core/Controller/ClientFlowLoginControllerTest.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,4 +587,127 @@ public function testGeneratePasswordWithoutPassword() {
587587
$expected = new Http\RedirectResponse('nc://login/server:http://example.com&user:MyLoginName&password:MyGeneratedToken');
588588
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
589589
}
590+
591+
public function dataGeneratePasswordWithHttpsProxy() {
592+
return [
593+
[
594+
[
595+
['X-Forwarded-Proto', 'http'],
596+
['X-Forwarded-Ssl', 'off'],
597+
],
598+
'http',
599+
'http',
600+
],
601+
[
602+
[
603+
['X-Forwarded-Proto', 'http'],
604+
['X-Forwarded-Ssl', 'off'],
605+
],
606+
'https',
607+
'https',
608+
],
609+
[
610+
[
611+
['X-Forwarded-Proto', 'https'],
612+
['X-Forwarded-Ssl', 'off'],
613+
],
614+
'http',
615+
'https',
616+
],
617+
[
618+
[
619+
['X-Forwarded-Proto', 'https'],
620+
['X-Forwarded-Ssl', 'on'],
621+
],
622+
'http',
623+
'https',
624+
],
625+
[
626+
[
627+
['X-Forwarded-Proto', 'http'],
628+
['X-Forwarded-Ssl', 'on'],
629+
],
630+
'http',
631+
'https',
632+
],
633+
];
634+
}
635+
636+
/**
637+
* @dataProvider dataGeneratePasswordWithHttpsProxy
638+
* @param array $headers
639+
* @param string $protocol
640+
* @param string $expected
641+
*/
642+
public function testGeneratePasswordWithHttpsProxy(array $headers, $protocol, $expected) {
643+
$this->session
644+
->expects($this->once())
645+
->method('get')
646+
->with('client.flow.state.token')
647+
->willReturn('MyStateToken');
648+
$this->session
649+
->expects($this->once())
650+
->method('remove')
651+
->with('client.flow.state.token');
652+
$this->session
653+
->expects($this->once())
654+
->method('getId')
655+
->willReturn('SessionId');
656+
$myToken = $this->createMock(IToken::class);
657+
$myToken
658+
->expects($this->once())
659+
->method('getLoginName')
660+
->willReturn('MyLoginName');
661+
$this->tokenProvider
662+
->expects($this->once())
663+
->method('getToken')
664+
->with('SessionId')
665+
->willReturn($myToken);
666+
$this->tokenProvider
667+
->expects($this->once())
668+
->method('getPassword')
669+
->with($myToken, 'SessionId')
670+
->willReturn('MyPassword');
671+
$this->random
672+
->expects($this->once())
673+
->method('generate')
674+
->with(72)
675+
->willReturn('MyGeneratedToken');
676+
$user = $this->createMock(IUser::class);
677+
$user
678+
->expects($this->once())
679+
->method('getUID')
680+
->willReturn('MyUid');
681+
$this->userSession
682+
->expects($this->once())
683+
->method('getUser')
684+
->willReturn($user);
685+
$this->tokenProvider
686+
->expects($this->once())
687+
->method('generateToken')
688+
->with(
689+
'MyGeneratedToken',
690+
'MyUid',
691+
'MyLoginName',
692+
'MyPassword',
693+
'unknown',
694+
IToken::PERMANENT_TOKEN,
695+
IToken::DO_NOT_REMEMBER
696+
);
697+
$this->request
698+
->expects($this->once())
699+
->method('getServerProtocol')
700+
->willReturn($protocol);
701+
$this->request
702+
->expects($this->once())
703+
->method('getServerHost')
704+
->willReturn('example.com');
705+
$this->request
706+
->expects($this->atLeastOnce())
707+
->method('getHeader')
708+
->willReturnMap($headers);
709+
710+
$expected = new Http\RedirectResponse('nc://login/server:' . $expected . '://example.com&user:MyLoginName&password:MyGeneratedToken');
711+
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
712+
}
590713
}

0 commit comments

Comments
 (0)