This repository has been archived by the owner on Jun 29, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
|
||
namespace Yiisoft\Yii\Web\Tests\Middleware; | ||
|
||
use Nyholm\Psr7\Factory\Psr17Factory; | ||
use Nyholm\Psr7\Response; | ||
use Nyholm\Psr7\ServerRequest; | ||
use PHPUnit\Framework\MockObject\MockObject; | ||
use PHPUnit\Framework\TestCase; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
use Yiisoft\Router\Method; | ||
use Yiisoft\Security\Random; | ||
use Yiisoft\Security\TokenMasker; | ||
use Yiisoft\Yii\Web\Middleware\Csrf; | ||
use Yiisoft\Yii\Web\Session\SessionInterface; | ||
|
||
final class CsrfTest extends TestCase | ||
{ | ||
private const PARAM_NAME = 'csrf'; | ||
|
||
public function testProcessIsValidTokenWithRequest() | ||
{ | ||
$token = $this->generateToken(); | ||
$middleware = $this->createCsrfMiddlewareWithToken($token); | ||
$response = $middleware->process($this->createPostServerRequestWithBodyToken($token), $this->createRequestHandler()); | ||
$this->assertEquals(200, $response->getStatusCode()); | ||
} | ||
|
||
|
||
public function testProcessIsValidTokenWithHeaders() | ||
{ | ||
$token = $this->generateToken(); | ||
$middleware = $this->createCsrfMiddlewareWithToken($token); | ||
$response = $middleware->process($this->createPostServerRequestWithHeaderToken($token), $this->createRequestHandler()); | ||
$this->assertEquals(200, $response->getStatusCode()); | ||
} | ||
|
||
public function testProcessIsAllowMethod() | ||
{ | ||
$middleware = $this->createCsrfMiddlewareWithToken(''); | ||
$response = $middleware->process($this->createServerRequest(Method::GET), $this->createRequestHandler()); | ||
$this->assertEquals(200, $response->getStatusCode()); | ||
} | ||
|
||
public function testProcessInvalidToken() | ||
{ | ||
$middleware = $this->createCsrfMiddlewareWithToken($this->generateToken()); | ||
$response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler()); | ||
$this->assertEquals(400, $response->getStatusCode()); | ||
} | ||
|
||
|
||
public function testProcessEmptyTokenInSession() | ||
{ | ||
$middleware = $this->createCsrfMiddlewareWithToken(''); | ||
$response = $middleware->process($this->createPostServerRequestWithBodyToken($this->generateToken()), $this->createRequestHandler()); | ||
$this->assertEquals(400, $response->getStatusCode()); | ||
} | ||
|
||
|
||
public function testProcessEmptyTokenInRequest() | ||
{ | ||
$middleware = $this->createCsrfMiddlewareWithToken($this->generateToken()); | ||
$response = $middleware->process($this->createServerRequest(), $this->createRequestHandler()); | ||
$this->assertEquals(400, $response->getStatusCode()); | ||
} | ||
|
||
|
||
private function createServerRequest(string $method = Method::POST, array $bodyParams = [], array $headParams = []): ServerRequestInterface | ||
{ | ||
$request = new ServerRequest($method, '/', $headParams); | ||
return $request->withParsedBody($bodyParams); | ||
} | ||
|
||
private function createPostServerRequestWithBodyToken(string $token): ServerRequestInterface | ||
{ | ||
return $this->createServerRequest(Method::POST, [ | ||
self::PARAM_NAME => TokenMasker::mask($token), | ||
]); | ||
} | ||
|
||
private function createPostServerRequestWithHeaderToken(string $token): ServerRequestInterface | ||
{ | ||
return $this->createServerRequest(Method::POST, [], [ | ||
Csrf::HEADER_NAME => TokenMasker::mask($token), | ||
]); | ||
} | ||
|
||
private function createRequestHandler(): RequestHandlerInterface | ||
{ | ||
return new class implements RequestHandlerInterface | ||
{ | ||
public function handle(ServerRequestInterface $request): ResponseInterface | ||
{ | ||
return new Response(200); | ||
} | ||
}; | ||
} | ||
|
||
private function createSessionMock(string $returnToken) | ||
{ | ||
/** | ||
* @var SessionInterface|MockObject $sessionMock | ||
*/ | ||
$sessionMock = $this->createMock(SessionInterface::class); | ||
|
||
$sessionMock | ||
->expects($this->once()) | ||
->method('get') | ||
->willReturn($returnToken); | ||
|
||
return $sessionMock; | ||
} | ||
|
||
|
||
private function createCsrfMiddlewareWithToken(string $token): Csrf | ||
{ | ||
$middleware = new Csrf(new Psr17Factory(), $this->createSessionMock($token)); | ||
$middleware->setName(self::PARAM_NAME); | ||
|
||
return $middleware; | ||
} | ||
|
||
private function generateToken(): string | ||
{ | ||
return Random::string(); | ||
} | ||
} |