8000 Merge branch '2.8' into 3.2 · symfony/symfony@f296648 · GitHub
[go: up one dir, main page]

Skip to content

Commit f296648

Browse files
committed
Merge branch '2.8' into 3.2
* 2.8: Fixed pathinfo calculation for requests starting with a question mark. [Security] simplify the SwitchUserListenerTest
2 parents 04fcac7 + 89bb895 commit f296648

File tree

4 files changed

+122
-150
lines changed

4 files changed

+122
-150
lines changed

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,6 +1774,9 @@ protected function prepareBaseUrl()
17741774

17751775
// Does the baseUrl have anything in common with the request_uri?
17761776
$requestUri = $this->getRequestUri();
1777+
if ($requestUri !== '' && $requestUri[0] !== '/') {
1778+
$requestUri = '/'.$requestUri;
1779+
}
17771780

17781781
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
17791782
// full $baseUrl matches
@@ -1846,9 +1849,12 @@ protected function preparePathInfo()
18461849
}
18471850

18481851
// Remove the query string from REQUEST_URI
1849-
if ($pos = strpos($requestUri, '?')) {
1852+
if (false !== $pos = strpos($requestUri, '?')) {
18501853
$requestUri = substr($requestUri, 0, $pos);
18511854
}
1855+
if ($requestUri !== '' && $requestUri[0] !== '/') {
1856+
$requestUri = '/'.$requestUri;
1857+
}
18521858

18531859
$pathInfo = substr($requestUri, strlen($baseUrl));
18541860
if (null !== $baseUrl && (false === $pathInfo || '' === $pathInfo)) {

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,12 @@ public function testGetPathInfo()
12811281
$request->initialize(array(), array(), array(), array(), array(), $server);
12821282

12831283
$this->assertEquals('/path%20test/info', $request->getPathInfo());
1284+
1285+
$server = array();
1286+
$server['REQUEST_URI'] = '?a=b';
1287+
$request->initialize(array(), array(), array(), array(), array(), $server);
1288+
1289+
$this->assertEquals('/', $request->getPathInfo());
12841290
}
12851291

12861292
public function testGetParameterPrecedence()
@@ -2110,6 +2116,61 @@ public function methodCacheableProvider()
21102116
array('CONNECT', false),
21112117
);
21122118
}
2119+
2120+
public function nonstandardRequestsData()
2121+
{
2122+
return array(
2123+
array('', '', '/', 'http://host:8080/', ''),
2124+
array('/', '', '/', 'http://host:8080/', ''),
2125+
2126+
array('hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2127+
array('/hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2128+
2129+
array('', 'a=b', '/', 'http://host:8080/?a=b'),
2130+
array('?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2131+
array('/?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2132+
2133+
array('x', 'a=b', '/x', 'http://host:8080/x?a=b'),
2134+
array('x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2135+
array('/x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2136+
2137+
array('hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2138+
array('/hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2139+
2140+
array('hello/app.php/x', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2141+
array('hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2142+
array('/hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2143+
);
2144+
}
2145+
2146+
/**
2147+
* @dataProvider nonstandardRequestsData
2148+
*/
2149+
public function testNonstandardRequests($requestUri, $queryString, $expectedPathInfo, $expectedUri, $expectedBasePath = '', $expectedBaseUrl = null)
2150+
{
2151+
if (null === $expectedBaseUrl) {
2152+
$expectedBaseUrl = $expectedBasePath;
2153+
}
2154+
2155+
$server = array(
2156+
'HTTP_HOST' => 'host:8080',
2157+
'SERVER_PORT' => '8080',
2158+
'QUERY_STRING' => $queryString,
2159+
'PHP_SELF' => '/hello/app.php',
2160+
'SCRIPT_FILENAME' => '/some/path/app.php',
2161+
'REQUEST_URI' => $requestUri,
2162+
);
2163+
2164+
$request = new Request(array(), array(), array(), array(), array(), $server);
2165+
2166+
$this->assertEquals($expectedPathInfo, $request->getPathInfo());
2167+
$this->assertEquals($expectedUri, $request->getUri());
2168+
$this->assertEquals($queryString, $request->getQueryString());
2169+
$this->assertEquals(8080, $request->getPort());
2170+
$this->assertEquals('host:8080', $request->getHttpHost());
2171+
$this->assertEquals($expectedBaseUrl, $request->getBaseUrl());
2172+
$this->assertEquals($expectedBasePath, $request->getBasePath());
2173+
}
21132174
}
21142175

21152176
class RequestContentProxy extends Request

src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php

Lines changed: 53 additions & 148 deletions
< 10000 td data-grid-cell-id="diff-61ad3ec1a3806e0a56b2c30cf658e4b261ddb675a10f2bd5e9054baabd0f2065-170-132-2" data-line-anchor="diff-61ad3ec1a3806e0a56b2c30cf658e4b261ddb675a10f2bd5e9054baabd0f2065L170" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-deletionLine-bgColor, var(--diffBlob-deletion-bgColor-line));padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell left-side-diff-cell border-right left-side">-
$originalToken
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
namespace Symfony\Component\Security\Http\Tests\Firewall;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
17+
use Symfony\Component\HttpKernel\HttpKernelInterface;
18+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
19+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
20+
use Symfony\Component\Security\Core\Role\SwitchUserRole;
21+
use Symfony\Component\Security\Core\User\User;
1522
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
1623
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
1724
use Symfony\Component\Security\Http\SecurityEvents;
@@ -32,14 +39,12 @@ class SwitchUserListenerTest extends TestCase
3239

3340
protected function setUp()
3441
{
35-
$this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
42+
$this->tokenStorage = new TokenStorage();
3643
$this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
3744
$this->userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
3845
$this->accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
39-
$this->request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
40-
$this->request->query = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag')->getMock();
41-
$this->request->server = $this->getMockBuilder('Symfony\Component\HttpFoundation\ServerBag')->getMock();
42-
$this->event = $this->getEvent($this->request);
46+
$this->request = new Request();
47+
$this->event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $this->request, HttpKernelInterface::MASTER_REQUEST);
4348
}
4449

4550
/**
@@ -53,54 +58,42 @@ public function testProviderKeyIsRequired()
5358

5459
public function testEventIsIgnoredIfUsernameIsNotPassedWithTheRequest()
5560
{
56-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue(null));
57-
58-
$this->event->expects($this->never())->method('setResponse');
59-
$this->tokenStorage->expects($this->never())->method('setToken');
60-
6161
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
6262
$listener->handle($this->event);
63+
64+
$this->assertNull($this->event->getResponse());
65+
$this->assertNull($this->tokenStorage->getToken());
6366
}
6467

6568
/**
6669
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
6770
*/
6871
public function testExitUserThrowsAuthenticationExceptionIfOriginalTokenCannotBeFound()
6972
{
70-
$token = $this->getToken(array($this->getMockBuilder('Symfony\Component\Security\Core\Role\RoleInterface')->getMock()));
73+
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
7174

72-
$this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
73-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit'));
75+
$this->tokenStorage->setToken($token);
76+
$this->request->query->set('_switch_user', '_exit');
7477

7578
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
7679
$listener->handle($this->event);
7780
}
7881

7982
public function testExitUserUpdatesToken()
8083
{
81-
$originalToken = $this->getToken();
82-
$role = $this->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole')
83-
->disableOriginalConstructor()
84-
->getMock();
85-
$role->expects($this->any())->method('getSource')->will($this->returnValue($originalToken));
86-
87-
$this->tokenStorage->expects($this->any())
88-
->method('getToken')
89-
->will($this->returnValue($this->getToken(array($role))));
90-
91-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit'));
92-
$this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
93-
$this->request->query->expects($this->once())->method('remove', '_switch_user');
94-
$this->request->query->expects($this->any())->method('all')->will($this->returnValue(array()));
95-
$this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', '');
96-
97-
$this->tokenStorage->expects($this->once())
98-
->method('setToken')->with($originalToken);
99-
$this->event->expects($this->once())
100-
->method('setResponse')->with($this->isInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse'));
84+
$originalToken = new UsernamePasswordToken('username', '', 'key', array());
85+
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
86+
87+
$this->request->query->set('_switch_user', '_exit');
10188

10289
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
10390
$listener->handle($this->event);
91+
92+
$this->assertSame(array(), $this->request->query->all());
93+
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
94+
$this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $this->event->getResponse());
95+
$this->assertSame($this->request->getUri(), $this->event->getResponse()->getTargetUrl());
96+
$this->assertSame($originalToken, $this->tokenStorage->getToken());
10497
}
10598

10699
public function testExitUserDispatchesEventWithRefreshedUser()
@@ -113,38 +106,9 @@ public function testExitUserDispatchesEventWithRefreshedUser()
113106
->method('refreshUser')
114107
->with($originalUser)
115108
->willReturn($refreshedUser);
116-
$originalToken = $this->getToken();
117-
$originalToken
118-
->expects($this->any())
119-
->method('getUser')
120-
->willReturn($originalUser);
121-
$role = $this
122-
->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole')
123-
->disableOriginalConstructor()
124-
->getMock();
125-
$role->expects($this->any())->method('getSource')->willReturn($originalToken);
126-
$this
127-
->tokenStorage
128-
->expects($this->any())
129-
->method('getToken')
130-
->willReturn($this->getToken(array($role)));
131-
$this
132-
->request
133-
->expects($this->any())
134-
->method('get')
135-
->with('_switch_user')
136-
->willReturn('_exit');
137-
$this
138-
->request
139-
->expects($this->any())
140-
->method('getUri')
141-
->willReturn('/');
142-
$this
143-
->request
144-
->query
145-
->expects($this->any())
146-
->method('all')
147-
->will($this->returnValue(array()));
109+
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
110+
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
111+
$this->request->query->set('_switch_user', '_exit');
148112

149113
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
150114
$dispatcher
@@ -166,41 +130,9 @@ public function testExitUserDoesNotDispatchEventWithStringUser()
166130
->userProvider
167131
->expects($this->never())
168132
->method('refreshUser');
169-
$originalToken = $this->getToken();
170
171-
->expects($this->any())
172-
->method('getUser')
173-
->willReturn($originalUser);
174-
$role = $this
175-
->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole')
176-
->disableOriginalConstructor()
177-
->getMock();
178-
$role
179-
->expects($this->any())
180-
->method('getSource')
181-
->willReturn($originalToken);
182-
$this
183-
->tokenStorage
184-
->expects($this->any())
185-
->method('getToken')
186-
->willReturn($this->getToken(array($role)));
187-
$this
188-
->request
189-
->expects($this->any())
190-
->method('get')
191-
->with('_switch_user')
192-
->willReturn('_exit');
193-
$this
194-
->request
195-
->query
196-
->expects($this->any())
197-
->method('all')
198-
->will($this->returnValue(array()));
199-
$this
200-
->request
201-
->expects($this->any())
202-
->method('getUri')
203-
->willReturn('/');
133+
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
134+
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
135+
$this->request->query->set('_switch_user', '_exit');
204136

205137
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
206138
$dispatcher
@@ -217,10 +149,10 @@ public function testExitUserDoesNotDispatchEventWithStringUser()
217149
*/
218150
public function testSwitchUserIsDisallowed()
219151
{
220-
$token = $this->getToken(array($this->getMockBuilder('Symfony\Component\Security\Core\Role\RoleInterface')->getMock()));
152+
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
221153

222-
$this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
223-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
154+
$this->tokenStorage->setToken($token);
155+
$this->request->query->set('_switch_user', 'kuba');
224156

225157
$this->accessDecisionManager->expects($this->once())
226158
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
@@ -232,17 +164,11 @@ public function testSwitchUserIsDisallowed()
232164

233165
public function testSwitchUser()
234166
{
235-
$token = $this->getToken(array($this->getMockBuilder('Symfony\Component\Security\Core\Role\RoleInterface')->getMock()));
236-
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
237-
$user->expects($this->any())->method('getRoles')->will($this->returnValue(array()));
167+
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
168+
$user = new User('username', 'password', array());
238169

239-
$this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
240-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
241-
$this->request->query->expects($this->once())->method('remove', '_switch_user');
242-
$this->request->query->expects($this->any())->method('all')->will($this->returnValue(array()));
243-
244-
$this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
245-
$this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', '');
170+
$this->tokenStorage->setToken($token);
171+
$this->request->query->set('_switch_user', 'kuba');
246172

247173
$this->accessDecisionManager->expects($this->once())
248174
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
@@ -253,25 +179,26 @@ public function testSwitchUser()
253179
->will($this->returnValue($user));
254180
$this->userChecker->expects($this->once())
255181
->method('checkPostAuth')->with($user);
256-
$this->tokenStorage->expects($this->once())
257-
->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'));
258182

259183
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
260184
$listener->handle($this->event);
185+
186+
$this->assertSame(array(), $this->request->query->all());
187+
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
188+
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
261189
}
262190

263191
public function testSwitchUserKeepsOtherQueryStringParameters()
264192
{
265-
$token = $this->getToken(array($this->getMockBuilder('Symfony\Component\Security\Core\Role\RoleInterface')->getMock()));
266-
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
267-
$user->expects($this->any())->method('getRoles')->will($this->returnValue(array()));
193+
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
194+
$user = new User('username', 'password', array());
268195

269-
$this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
270-
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
271-
$this->request->query->expects($this->once())->method('remove', '_switch_user');
272-
$this->request->query->expects($this->any())->method('all')->will($this->returnValue(array('page' => 3, 'section' => 2)));
273-
$this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
274-
$this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', 'page=3&section=2');
196+
$this->tokenStorage->setToken($token);
197+
$this->request->query->replace(array(
198+
'_switch_user' => 'kuba',
199+
'page' => 3,
200+
'section' => 2,
201+
));
275202

276203
$this->accessDecisionManager->expects($this->once())
277204
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
@@ -282,33 +209,11 @@ public function testSwitchUserKeepsOtherQueryStringParameters()
282209
->will($this->returnValue($user));
283210
$this->userChecker->expects($this->once())
284211
->method('checkPostAuth')->with($user);
285-
$this->tokenStorage->expects($this->once())
286-
->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'));
287212

288213
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
289214
$listener->handle($this->event);
290-
}
291-
292-
private function getEvent($request)
293-
{
294-
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
295-
->disableOriginalConstructor()
296-
->getMock();
297-
298-
$event->expects($this->any())
299-
->method('getRequest')
300-
->will($this->returnValue($request));
301-
302-
return $event;
303-
}
304-
305-
private function getToken(array $roles = array())
306-
{
307-
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
308-
$token->expects($this->any())
309-
->method('getRoles')
310-
->will($this->returnValue($roles));
311215

312-
return $token;
216+
$this->assertSame('page=3&section=2', $this->request->server->get('QUERY_STRING'));
217+
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
313218
}
314219
}

0 commit comments

Comments
 (0)
0