Symfony 5 - Panther : invalid cookie domain - php

I'm trying to use Panther for PhpUnit Tests in my Symfony 5 application.
When I try to log an user, like this :
$client = static::createPantherClient();
/** #var User $user */
$user = $this->getSuperAdminAccount();
$session = self::$container->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$session->set('_security_main', serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$client->getCookieJar()->set($cookie);
when I run the test, I get:
Panther Facebook\WebDriver\Exception\InvalidCookieDomainException :
invalid cookie domain
Can someone help me please ?

if anyone has the same problem, I found a solution on Github : https://github.com/symfony/panther/issues/283#issuecomment-674524048
Just request domain before adding a cookie :
$client->request('GET', 'https://www.google.com/');
$client->getCookieJar()->set(new Cookie('my_cookie', 'hello', domain: '.google.com'));
$client->request('GET', 'https://www.google.com/');

Related

why in Symfony $this->tokenStorage->getToken(); returns null in prod?

i tried to figure out why my user in dev is logged in and in prod not. Its the same code in dev like in prod and i have no idea why i get no user in prod.
my authentication looks like this:
$token = new UsernamePasswordToken($user, 'main', $user->getRoles());
$event = new InteractiveLoginEvent($request, $token);
$this->tokenStorage->setToken($token);
$this->container->get('security.token_storage')->setToken($token);
//dd($this->tokenStorage->getToken()); returns my user in dev and prod
$this->session->set('_security_main', serialize($jwt));
after this i have a method checkIfUserLoggedIn():
$token = $this->tokenStorage->getToken(); //returns user in dev and null in prod
$user = null;
if(null == $token)
{
//...
}
Do you have any idea whats wrong in here or where i can take to look to find out more about this?
The Regularly Login doesnt work too in prod, but this is a bug in csrf and prod. csrf invalid.

Symfony Panther authentication seems not to be taken into account

I am using Symfony Panther for some testing.
When I want to log a User like this :
protected function setUpPanther()
{
$client = static::createPantherClient(['readinessPath' => '/error']);
$client->manage()->window()->maximize();
$this->client = $client;
}
protected function loginPantherClient(Client $client, User $user)
{
$client->request('GET', '/error');
$session = self::$container->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$session->set('_security_main', serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$client->getCookieJar()->set($cookie);
}
public function testUpdateProductDetails()
{
$this->setUpPanther();
$admin = $this->getSuperAdminAccount();
$this->loginPantherClient($this->client, $admin);
$this->client->request('GET', '/');
$this->assertSelectorExists('div.form-group');
}
A strange phenomenon occurs.
My client goes to the error page to initialize the cookie (required)
And here I have the impression that the authentication of my client is not taken into account, because if you look closely, in my test, I then make a request on
$this->client->request('GET', '/');
But instead of redirecting me to the requested page, it redirects me to / login, as if during the request, the user was not authenticated, and therefore, was redirected to the login page, while in my code, I authenticate the user before
Has someone already had this problem ?
Try to return client from loginPantherClient function:
protected function loginPantherClient(Client $client, User $user)
{
$client->request('GET', '/error');
$session = self::$container->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$session->set('_security_main', serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$client->getCookieJar()->set($cookie);
return $client;
}
public function testUpdateProductDetails()
{
$this->setUpPanther();
$admin = $this->getSuperAdminAccount();
$this->client = $this->loginPantherClient($this->client, $admin);
$this->client->request('GET', '/');
$this->assertSelectorExists('div.form-group');
}
or remove from loginPantherClient function $client argument:
protected function loginPantherClient(User $user)
{
$this->client->request('GET', '/error');
$session = self::$container->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$session->set('_security_main', serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
public function testUpdateProductDetails()
{
$this->setUpPanther();
$admin = $this->getSuperAdminAccount();
$this->loginPantherClient($admin);
$this->client->request('GET', '/');
$this->assertSelectorExists('div.form-group');
}

Testing with sessions in symfony

Accoring to documentation I'm trying to mock session in my PHPUnit test:
public function testAction()
{
$session = new Session(new MockArraySessionStorage());
$session->set('abc', 'xyz');
$client = static::createClient();
$client->getContainer()->set('session', $session);
$client->request('GET', '/');
}
And in my controller I trying to get session value:
public function mainAction()
{
$session = $this->get('session');
var_dump($session->get('abc'), $session->all());die; //returns null and []
}
Why this stuff doesn't work?
I believe it's because the session is resolved with the cookie, and you don't set the cookie who link the session to the client.
You should add:
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
There is a full example to log in a user:
$session = $this->_container->get('session');
$user = $this->_em->getRepository('UserBundle:User')
->findOneByEmail($email);
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$session->set('_security_<security_context>', serialize($token));
$session->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
Hope it help

How to test Symfony2 api with DunglasAngularCsrfBundle

I use Symfony2 with DunglasAngularCsrfBundle and when i run my PHpunit test it get error {"code":403,"message":"Bad CSRF token."}
If auth user with http basic
self::$user_client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'user1#mail.com',
'PHP_AUTH_PW' => 'user1',
'HTTP_HOST' => static::getHost()
));
This condition return false in EventListener\AngularCsrfValidationListener
if (!$value || !$this->angularCsrfTokenManager->isTokenValid($value)) {
throw new AccessDeniedHttpException('Bad CSRF token.');
}
generated token in test not equal, i try another auth like this:
protected function logIn($email)
{
$this->client = static::createClient();
$user = $this->client->getContainer()
->get('doctrine')
->getManager()
->getRepository('UserBundle:User')
->findOneByEmail($email);
$providerKey = static::$kernel->getContainer()->getParameter('fos_user.firewall_name');
$token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
$session = $this->client->getContainer()->get('session');
$session->set('_security_'.$providerKey, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
token not created. Return false in Symfony\Component\Security\Csrf\CsrfTokenManager::isTokenValid:
$this->storage->hasToken($token->getId())
Please help to resolve this issue, thanks
Solved
self::$client->request('GET', '/')
set token in cookie

webtests symfony 2.5 with Fosuserbundle

I try make test with authentication fosuserbundle, but still is fail, i find solution for symfony 2.3 but it doesn't works
https://gist.github.com/deltaepsilon/6391565
i also try create client by two funcitons
protected function createAuthorizedClient2()
{
$client = static::createClient();
$container = $client->getContainer();
$session = $container->get('session');
/** #var $userManager \FOS\UserBundle\Doctrine\UserManager */
$userManager = $container->get('fos_user.user_manager');
/** #var $loginManager \FOS\UserBundle\Security\LoginManager */
$loginManager = $container->get('fos_user.security.login_manager');
$firewallName = $container->getParameter('fos_user.firewall_name');
$user = $userManager->findUserBy(array('username' => 'admin'));
$loginManager->loginUser($firewallName, $user);
// save the login token into the session and put it in a cookie
$container->get('session')->set('_security_' . $firewallName, serialize($container->get('security.context')->getToken()));
$container->get('session')->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
return $client;
}
protected function createAuthorizedClient()
{
$client = static::createClient();
$container = static::$kernel->getContainer();
$session = $container->get('session');
$person = self::$kernel->getContainer()->get('doctrine')->getRepository('BergUserDataBundle:UserLogin')->findOneByUsername('admin');
$token = new UsernamePasswordToken($person, null, 'main', $person->getRoles());
$session->set('_security_main', serialize($token));
$session->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
return $client;
}
This is no longer the recommended way of testing with an authenticated client.
The new recommended way is much simpler - to submit plain old HTTP credentials and then tell your test environment firewall to authenticate via this method instead of the FOS User Provider.
See http://symfony.com/doc/current/cookbook/testing/http_authentication.html

Categories