Skip to content

Commit 62d1e92

Browse files
Stephan Wentzpl-github
authored andcommitted
feat: Add generateCsrfToken() for generating csrf tokens in request builder
1 parent 13a51a2 commit 62d1e92

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
"symfony/framework-bundle": "^5.4|^6.0",
3838
"symfony/http-client": "^6.0",
3939
"symfony/http-foundation": "^5.3.7|^6.0",
40+
"symfony/mime": "^6.2",
4041
"symfony/security-core": "^5.3|^6.0",
42+
"symfony/security-csrf": "^6.2",
4143
"thecodingmachine/phpstan-safe-rule": "^1.1",
4244
"thecodingmachine/phpstan-strict-rules": "^1.0"
4345
},

phpstan.neon.dist

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ parameters:
1818
- '#Method .* has parameter .* with null as default value#'
1919
- '#Method Brainbits\\FunctionalTestHelpers\\Tests\\.*Test::assertMatches.*Snapshot\(\) is protected, but since the containing class is final, it can be private.#'
2020
- '#Method Brainbits\\FunctionalTestHelpers\\Tests\\.*Test::setUpSnapshot\(\) is protected, but since the containing class is final, it can be private.#'
21-
- '#Method Brainbits\\FunctionalTestHelpers\\Tests\\ZipContents\\ZipContentsTraitTest::.* is protected, but since the containing class is final, it can be private#'
21+
- '#Method Brainbits\\FunctionalTestHelpers\\Tests\\Request\\RequestTraitTest::.*\(\) is protected, but since the containing class is final, it can be private#'
22+
- '#Method Brainbits\\FunctionalTestHelpers\\Tests\\ZipContents\\ZipContentsTraitTest::.*\(\) is protected, but since the containing class is final, it can be private#'
2223
ergebnis:
2324
classesAllowedToBeExtended:
2425
- Monolog\Handler\AbstractProcessingHandler

src/Request/RequestTrait.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
use PHPUnit\Framework\TestCase;
88
use Symfony\Component\BrowserKit\AbstractBrowser;
9+
use Symfony\Component\BrowserKit\Cookie;
910
use Symfony\Component\HttpFoundation\Response;
11+
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
1012

1113
use function method_exists;
1214
use function Safe\sprintf;
@@ -50,6 +52,44 @@ protected static function getRequestClient(): AbstractBrowser
5052
));
5153
}
5254

55+
final public function generateCsrfToken(string $tokenId): string
56+
{
57+
$client = self::getRequestClient();
58+
59+
$cookie = $client->getCookieJar()->get('MOCKSESSID');
60+
61+
// create a new session object
62+
$container = $client->getContainer();
63+
$session = $container->get('session.factory')->createSession();
64+
65+
if ($cookie) {
66+
// get the session id from the session cookie if it exists
67+
$session->setId($cookie->getValue());
68+
$session->start();
69+
} else {
70+
// or create a new session id and a session cookie
71+
$session->start();
72+
$session->save();
73+
74+
$sessionCookie = new Cookie(
75+
$session->getName(),
76+
$session->getId(),
77+
null,
78+
null,
79+
'localhost',
80+
);
81+
$client->getCookieJar()->set($sessionCookie);
82+
}
83+
84+
$container = $client->getContainer();
85+
$tokenGenerator = $container->get('security.csrf.token_generator');
86+
$csrfToken = $tokenGenerator->generateToken();
87+
$session->set(SessionTokenStorage::SESSION_NAMESPACE . '/' . $tokenId, $csrfToken);
88+
$session->save();
89+
90+
return $csrfToken;
91+
}
92+
5393
final protected function build(string $method, string $uri): RequestBuilder
5494
{
5595
if (method_exists($this, 'findUser')) {

tests/Request/RequestTraitTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Brainbits\FunctionalTestHelpers\Tests\Request;
6+
7+
use Brainbits\FunctionalTestHelpers\Request\RequestBuilder;
8+
use Brainbits\FunctionalTestHelpers\Request\RequestTrait;
9+
use PHPUnit\Framework\TestCase;
10+
use Symfony\Component\BrowserKit\HttpBrowser;
11+
use Symfony\Component\HttpClient\MockHttpClient;
12+
use Symfony\Component\HttpClient\Response\MockResponse;
13+
14+
/** @covers \Brainbits\FunctionalTestHelpers\Request\RequestBuilder */
15+
final class RequestTraitTest extends TestCase
16+
{
17+
use RequestTrait;
18+
19+
public function testBuildCreatesBuilder(): void
20+
{
21+
$builder = $this->build('POST', 'http://foo');
22+
23+
$this->assertInstanceOf(RequestBuilder::class, $builder);
24+
$this->assertSame('POST', $builder->getMethod());
25+
$this->assertSame('http://foo', $builder->getUri());
26+
}
27+
28+
public static function createClient(): HttpBrowser
29+
{
30+
return new HttpBrowser(new MockHttpClient([new MockResponse('foo')]));
31+
}
32+
}

0 commit comments

Comments
 (0)