symfony / panther

A browser testing and web crawling library for PHP and Symfony
MIT License
2.94k stars 222 forks source link

Using session/cookie for simulate authentification not working since SF 4.4.0 #275

Closed svacher closed 4 years ago

svacher commented 4 years ago

Hi,

I'm using Panther 0.6.0. for testing IHM (with Php-unit 8.5.0). When i'm using SF 4.3.x, no mather with authentification using session/cookie against SF guard. So, i have switched to SF 4.4.2 (problem is same with 4.4.0 and 4.4.1) and it doesn't look to work again.

Please, can you help me or someone as the same problem ? Thanks a lot.

See a piece of code : (based on https://symfony.com/doc/4.4/testing/http_authentication.html)

use Symfony\Component\Panther\Client as PantherClient;

class MyTest extends PantherTestCase
{
    /** @var PantherClient */
    protected $client;

    public function setUp(): void
    {
        parent::setUp();
        $this->client = static::createPantherClient();
        # This line is needed to have not error => Facebook\WebDriver\Exception\InvalidCookieDomainException: invalid cookie domain
        $this->client->request('GET', '/a-page-no-need-auth');
    }

    public function auth(string $username, array $roles = []): void
    {
        $user = new User($username);
        $token = new PostAuthenticationGuardToken($user, 'myProvider', $roles);

        static::bootKernel();
        $session = static::$container->get('session');  
        $session->set('_security_secured', serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }

    public function testAccessDenied(): void
    {
        $this->auth('user', ['ROLE_TEST']);
        $crawler = $this->client->request('GET', '/url-to-test');

        // tests...
    }
}
svacher commented 4 years ago

I think it's a UserProvider problem...

My logs says :

security.DEBUG: Cannot refresh token because user has changed. {"username":"user","provider":"App\\Security\\UserProvider\\UserProvider"} []

My code for this is :

/**
 * {@inheritdoc}
 */
public function refreshUser(UserInterface $user): UserInterface
{
    if (!$user instanceof User) {
        throw new UnsupportedUserException(\sprintf('Instances of "%s" are not supported.', \get_class($user)));
    }

    // Don't reload, get it from session tokenstorage !
    return $user;
}
svacher commented 4 years ago

Answer to myself : Roles must be set in user too... so in my piece of code, i must add $user->setRoles($roles); in auth function.

If it can help someone...