Skip to content

Commit 3930120

Browse files
authored
Merge pull request #116 from cakephp/issue-115
Don't include host and protocol in redirect URLs
2 parents 0eebd1b + 97755dd commit 3930120

File tree

5 files changed

+106
-30
lines changed

5 files changed

+106
-30
lines changed

src/Middleware/UnauthorizedHandler/CakeRedirectHandler.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,17 @@ protected function getUrl(ServerRequestInterface $request, array $options): stri
6868
{
6969
$url = $options['url'];
7070
if ($options['queryParam'] !== null) {
71-
$url['?'][$options['queryParam']] = (string)$request->getUri();
71+
$uri = $request->getUri();
72+
/** @psalm-suppress NoInterfaceProperties */
73+
if (property_exists($uri, 'base')) {
74+
$uri = $uri->withPath($uri->base . $uri->getPath());
75+
}
76+
$redirect = $uri->getPath();
77+
if ($uri->getQuery()) {
78+
$redirect .= '?' . $uri->getQuery();
79+
}
80+
81+
$url['?'][$options['queryParam']] = $redirect;
7282
}
7383

7484
return Router::url($url);

src/Middleware/UnauthorizedHandler/RedirectHandler.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,16 @@ protected function getUrl(ServerRequestInterface $request, array $options): stri
100100
{
101101
$url = $options['url'];
102102
if ($options['queryParam'] !== null && $request->getMethod() === 'GET') {
103-
$query = urlencode($options['queryParam']) . '=' . urlencode($request->getRequestTarget());
103+
$uri = $request->getUri();
104+
/** @psalm-suppress NoInterfaceProperties */
105+
if (property_exists($uri, 'base')) {
106+
$uri = $uri->withPath($uri->base . $uri->getPath());
107+
}
108+
$redirect = $uri->getPath();
109+
if ($uri->getQuery()) {
110+
$redirect .= '?' . $uri->getQuery();
111+
}
112+
$query = urlencode($options['queryParam']) . '=' . urlencode($redirect);
104113
if (strpos($url, '?') !== false) {
105114
$query = '&' . $query;
106115
} else {

tests/TestCase/Middleware/UnauthorizedHandler/CakeRedirectHandlerTest.php

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818

1919
use Authorization\Exception\Exception;
2020
use Authorization\Middleware\UnauthorizedHandler\CakeRedirectHandler;
21-
use Cake\Http\ServerRequest;
21+
use Cake\Core\Configure;
22+
use Cake\Http\ServerRequestFactory;
2223
use Cake\Routing\Router;
2324
use Cake\TestSuite\TestCase;
2425

25-
/**
26-
* Description of CakeRedirectHandlerTest
27-
*/
2826
class CakeRedirectHandlerTest extends TestCase
2927
{
3028
public function setUp(): void
@@ -46,24 +44,27 @@ public function testHandleRedirectionDefault()
4644
$handler = new CakeRedirectHandler();
4745

4846
$exception = new Exception();
49-
$request = new ServerRequest();
50-
47+
$request = ServerRequestFactory::fromGlobals(
48+
['REQUEST_URI' => '/admin/dashboard']
49+
);
5150
$response = $handler->handle($exception, $request, [
5251
'exceptions' => [
5352
Exception::class,
5453
],
5554
]);
5655

5756
$this->assertEquals(302, $response->getStatusCode());
58-
$this->assertEquals('/login?redirect=http%3A%2F%2Flocalhost%2F', $response->getHeaderLine('Location'));
57+
$this->assertEquals('/login?redirect=%2Fadmin%2Fdashboard', $response->getHeaderLine('Location'));
5958
}
6059

6160
public function testHandleRedirectionNamed()
6261
{
6362
$handler = new CakeRedirectHandler();
6463

6564
$exception = new Exception();
66-
$request = new ServerRequest();
65+
$request = ServerRequestFactory::fromGlobals(
66+
['REQUEST_URI' => '/admin/dashboard']
67+
);
6768

6869
$response = $handler->handle($exception, $request, [
6970
'exceptions' => [
@@ -75,15 +76,17 @@ public function testHandleRedirectionNamed()
7576
]);
7677

7778
$this->assertEquals(302, $response->getStatusCode());
78-
$this->assertEquals('/login?redirect=http%3A%2F%2Flocalhost%2F', $response->getHeaderLine('Location'));
79+
$this->assertEquals('/login?redirect=%2Fadmin%2Fdashboard', $response->getHeaderLine('Location'));
7980
}
8081

8182
public function testHandleRedirectionWithQuery()
8283
{
8384
$handler = new CakeRedirectHandler();
8485

8586
$exception = new Exception();
86-
$request = new ServerRequest();
87+
$request = ServerRequestFactory::fromGlobals(
88+
['REQUEST_URI' => '/']
89+
);
8790

8891
$response = $handler->handle($exception, $request, [
8992
'exceptions' => [
@@ -98,15 +101,17 @@ public function testHandleRedirectionWithQuery()
98101
]);
99102

100103
$this->assertEquals(302, $response->getStatusCode());
101-
$this->assertEquals('/login?foo=bar&redirect=http%3A%2F%2Flocalhost%2F', $response->getHeaderLine('Location'));
104+
$this->assertEquals('/login?foo=bar&redirect=%2F', $response->getHeaderLine('Location'));
102105
}
103106

104107
public function testHandleRedirectionNoQuery()
105108
{
106109
$handler = new CakeRedirectHandler();
107110

108111
$exception = new Exception();
109-
$request = new ServerRequest();
112+
$request = ServerRequestFactory::fromGlobals(
113+
['REQUEST_URI' => '/']
114+
);
110115

111116
$response = $handler->handle($exception, $request, [
112117
'exceptions' => [
@@ -118,4 +123,30 @@ public function testHandleRedirectionNoQuery()
118123
$this->assertEquals(302, $response->getStatusCode());
119124
$this->assertEquals('/login', $response->getHeaderLine('Location'));
120125
}
126+
127+
public function testHandleRedirectWithBasePath()
128+
{
129+
$handler = new CakeRedirectHandler();
130+
$exception = new Exception();
131+
132+
Configure::write('App.base', '/basedir');
133+
$request = ServerRequestFactory::fromGlobals(
134+
['REQUEST_URI' => '/admin/dashboard']
135+
);
136+
137+
$response = $handler->handle($exception, $request, [
138+
'exceptions' => [
139+
Exception::class,
140+
],
141+
'url' => [
142+
'_name' => 'login',
143+
],
144+
]);
145+
146+
$this->assertEquals(302, $response->getStatusCode());
147+
$this->assertEquals(
148+
'/basedir/login?redirect=%2Fbasedir%2Fadmin%2Fdashboard',
149+
$response->getHeaderLine('Location')
150+
);
151+
}
121152
}

tests/TestCase/Middleware/UnauthorizedHandler/RedirectHandlerTest.php

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
use Authorization\Exception\Exception;
2020
use Authorization\Middleware\UnauthorizedHandler\RedirectHandler;
21-
use Cake\Http\ServerRequest;
21+
use Cake\Core\Configure;
22+
use Cake\Http\ServerRequestFactory;
2223
use Cake\TestSuite\TestCase;
2324

2425
class RedirectHandlerTest extends TestCase
@@ -28,9 +29,9 @@ public function testHandleRedirection()
2829
$handler = new RedirectHandler();
2930

3031
$exception = new Exception();
31-
$request = new ServerRequest([
32-
'environment' => ['REQUEST_METHOD' => 'GET'],
33-
]);
32+
$request = ServerRequestFactory::fromGlobals(
33+
['REQUEST_METHOD' => 'GET']
34+
);
3435

3536
$response = $handler->handle($exception, $request, [
3637
'exceptions' => [
@@ -47,13 +48,13 @@ public function testHandleRedirectionWithQuery()
4748
$handler = new RedirectHandler();
4849

4950
$exception = new Exception();
50-
$request = new ServerRequest([
51-
'environment' => [
51+
$request = ServerRequestFactory::fromGlobals(
52+
[
5253
'REQUEST_METHOD' => 'GET',
5354
'PATH_INFO' => '/path',
5455
'QUERY_STRING' => 'key=value',
55-
],
56-
]);
56+
]
57+
);
5758

5859
$response = $handler->handle($exception, $request, [
5960
'exceptions' => [
@@ -71,9 +72,9 @@ public function testHandleRedirectionNoQuery()
7172
$handler = new RedirectHandler();
7273

7374
$exception = new Exception();
74-
$request = new ServerRequest([
75-
'environment' => ['REQUEST_METHOD' => 'GET'],
76-
]);
75+
$request = ServerRequestFactory::fromGlobals(
76+
['REQUEST_METHOD' => 'GET']
77+
);
7778

7879
$response = $handler->handle($exception, $request, [
7980
'exceptions' => [
@@ -107,13 +108,13 @@ public function testHandleRedirectionIgnoreNonIdempotentMethods($method)
107108
$handler = new RedirectHandler();
108109

109110
$exception = new Exception();
110-
$request = new ServerRequest([
111-
'environment' => [
111+
$request = ServerRequestFactory::fromGlobals(
112+
[
112113
'REQUEST_METHOD' => $method,
113114
'PATH_INFO' => '/path',
114115
'QUERY_STRING' => 'key=value',
115-
],
116-
]);
116+
]
117+
);
117118

118119
$response = $handler->handle($exception, $request, [
119120
'exceptions' => [
@@ -126,12 +127,36 @@ public function testHandleRedirectionIgnoreNonIdempotentMethods($method)
126127
$this->assertEquals('/login?foo=bar', $response->getHeaderLine('Location'));
127128
}
128129

130+
public function testHandleRedirectWithBasePath()
131+
{
132+
$handler = new RedirectHandler();
133+
$exception = new Exception();
134+
135+
Configure::write('App.base', '/basedir');
136+
$request = ServerRequestFactory::fromGlobals(
137+
['REQUEST_URI' => '/path', 'REQUEST_METHOD' => 'GET']
138+
);
139+
140+
$response = $handler->handle($exception, $request, [
141+
'exceptions' => [
142+
Exception::class,
143+
],
144+
'url' => '/basedir/login',
145+
]);
146+
147+
$this->assertEquals(302, $response->getStatusCode());
148+
$this->assertEquals(
149+
'/basedir/login?redirect=%2Fbasedir%2Fpath',
150+
$response->getHeaderLine('Location')
151+
);
152+
}
153+
129154
public function testHandleException()
130155
{
131156
$handler = new RedirectHandler();
132157

133158
$exception = new Exception();
134-
$request = new ServerRequest();
159+
$request = ServerRequestFactory::fromGlobals(['REQUEST_URI' => '/']);
135160

136161
$this->expectException(Exception::class);
137162
$handler->handle($exception, $request);

tests/bootstrap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
Configure::write('debug', true);
4747
Configure::write('App', [
48+
'base' => '',
4849
'namespace' => 'TestApp',
4950
'encoding' => 'UTF-8',
5051
'paths' => [

0 commit comments

Comments
 (0)