Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ public function onKernelResponse(FilterResponseEvent $event)

if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) {
$params = session_get_cookie_params();

foreach ($event->getResponse()->headers->getCookies() as $cookie) {
if ($session->getName() === $cookie->getName() && $params['path'] === $cookie->getPath() && $params['domain'] == $cookie->getDomain()) {
return;
}
}

$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
$this->sessionId = $session->getId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ public function testEmptySessionWithNewSessionIdDoesSendCookie()
$this->assertNotEmpty($response->headers->getCookies());
}

/**
* @dataProvider anotherCookieProvider
*/
public function testSessionWithNewSessionIdAndNewCookieDoesNotSendAnotherCookie($existing, array $expected)
{
$this->sessionHasBeenStarted();
$this->sessionIsEmpty();
$this->fixSessionId('456');

$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);

$response = new Response('', 200, array('Set-Cookie' => $existing));

$response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST, $response);

$this->assertSame($expected, $response->headers->get('Set-Cookie', null, false));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really clear to me what this PR for. You state that it is to make it compatible with the CookieClearingLogoutHandler, but then I would expect a test that shows that no cookies are sent. However, you've added no tests that show this.

Furthermore, I doubt if this fix is the correct way to do it. It feels like it's battling symptoms instead of the root problem, but I can't quite lay my finger on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still expect the original cookie to be sent (ie the one set by CookieClearingLogoutHandler).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the CookieClearingLogoutHandler doesn't set cookies, it removes cookies. That's the whole point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To 'remove' a cookie you have to set a new expired one, hence:

public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true)
{
$this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly));
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aaah, check, I get it now.

In that case, LGTM

}

public function anotherCookieProvider()
{
return array(
'same' => array('MOCKSESSID=789; path=/', array('MOCKSESSID=789; path=/')),
'different domain' => array('MOCKSESSID=789; path=/; domain=example.com', array('MOCKSESSID=789; path=/; domain=example.com', 'MOCKSESSID=456; path=/')),
'different path' => array('MOCKSESSID=789; path=/foo', array('MOCKSESSID=789; path=/foo', 'MOCKSESSID=456; path=/')),
);
}

public function testUnstartedSessionIsNotSave()
{
$this->sessionHasNotBeenStarted();
Expand All @@ -123,10 +153,10 @@ public function testDoesNotImplementServiceSubscriberInterface()
$this->assertFalse(is_subclass_of(TestSessionListener::class, ServiceSubscriberInterface::class, 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford'));
}

private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST)
private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, Response $response = null)
{
$request->setSession($this->session);
$response = new Response();
$response = $response ?: new Response();
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$event = new FilterResponseEvent($kernel, $request, $type, $response);

Expand Down