mirror of
https://github.com/flarum/framework.git
synced 2025-02-22 09:36:42 +08:00
Add tests for CSRF token check
This commit is contained in:
parent
8061bfd74a
commit
e927254e99
181
tests/integration/api/csrf_protection/RequireCsrfTokenTest.php
Normal file
181
tests/integration/api/csrf_protection/RequireCsrfTokenTest.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Tests\integration\api\csrf_protection;
|
||||
|
||||
use Dflydev\FigCookies\SetCookie;
|
||||
use Flarum\Foundation\Application;
|
||||
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Tests\integration\TestCase;
|
||||
use Zend\Diactoros\CallbackStream;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
|
||||
class RequireCsrfTokenTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->prepareDatabase([
|
||||
'users' => [
|
||||
$this->adminUser(),
|
||||
],
|
||||
'groups' => [
|
||||
$this->adminGroup(),
|
||||
],
|
||||
'group_user' => [
|
||||
['user_id' => 1, 'group_id' => 1],
|
||||
],
|
||||
'group_permission' => [
|
||||
['permission' => 'viewUserList', 'group_id' => 3],
|
||||
],
|
||||
'access_tokens' => [
|
||||
['user_id' => 1, 'token' => 'superadmin', 'lifetime_seconds' => 30],
|
||||
],
|
||||
'settings' => [
|
||||
['key' => 'mail_driver', 'value' => 'smtp'],
|
||||
['key' => 'version', 'value' => Application::VERSION],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function error_when_doing_cookie_auth_without_csrf_token()
|
||||
{
|
||||
$auth = $this->server->handle(
|
||||
(new ServerRequest([], [], '/login', 'POST'))
|
||||
->withBody(new CallbackStream(function () {
|
||||
return '{"identification": "admin", "password": "password"}';
|
||||
}))
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
);
|
||||
|
||||
$cookies = array_reduce(
|
||||
$auth->getHeader('Set-Cookie'),
|
||||
function ($memo, $setCookieString) {
|
||||
$setCookie = SetCookie::fromSetCookieString($setCookieString);
|
||||
$memo[$setCookie->getName()] = $setCookie->getValue();
|
||||
return $memo;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$response = $this->server->handle(
|
||||
(new ServerRequest([], [], '/api/settings', 'POST'))
|
||||
->withBody(new CallbackStream(function () {
|
||||
return '{"mail_driver": "log"}';
|
||||
}))
|
||||
->withCookieParams($cookies)
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
);
|
||||
|
||||
// Response should be "HTTP 400 Bad Request"
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
|
||||
// The response body should contain proper error details
|
||||
$body = (string) $response->getBody();
|
||||
$this->assertJson($body);
|
||||
$this->assertEquals([
|
||||
'errors' => [
|
||||
['status' => '400', 'code' => 'csrf_token_mismatch'],
|
||||
],
|
||||
], json_decode($body, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function cookie_auth_succeeds_with_csrf_token()
|
||||
{
|
||||
$initial = $this->server->handle(
|
||||
(new ServerRequest([], [], '/', 'GET'))
|
||||
);
|
||||
|
||||
$token = $initial->getHeaderLine('X-CSRF-Token');
|
||||
$cookies = array_reduce(
|
||||
$initial->getHeader('Set-Cookie'),
|
||||
function ($memo, $setCookieString) {
|
||||
$setCookie = SetCookie::fromSetCookieString($setCookieString);
|
||||
$memo[$setCookie->getName()] = $setCookie->getValue();
|
||||
return $memo;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$auth = $this->server->handle(
|
||||
(new ServerRequest([], [], '/login', 'POST'))
|
||||
->withBody(new CallbackStream(function () {
|
||||
return '{"identification": "admin", "password": "password"}';
|
||||
}))
|
||||
->withCookieParams($cookies)
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->withHeader('X-CSRF-Token', $token)
|
||||
);
|
||||
|
||||
$token = $auth->getHeaderLine('X-CSRF-Token');
|
||||
$cookies = array_reduce(
|
||||
$auth->getHeader('Set-Cookie'),
|
||||
function ($memo, $setCookieString) {
|
||||
$setCookie = SetCookie::fromSetCookieString($setCookieString);
|
||||
$memo[$setCookie->getName()] = $setCookie->getValue();
|
||||
return $memo;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$response = $this->server->handle(
|
||||
(new ServerRequest([], [], '/api/settings', 'POST'))
|
||||
->withBody(new CallbackStream(function () {
|
||||
return '{"mail_driver": "log"}';
|
||||
}))
|
||||
->withCookieParams($cookies)
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->withHeader('X-CSRF-Token', $token)
|
||||
);
|
||||
|
||||
// Successful response?
|
||||
$this->assertEquals(204, $response->getStatusCode());
|
||||
|
||||
// Was the setting actually changed in the database?
|
||||
$this->assertEquals(
|
||||
'log',
|
||||
$this->database()->table('settings')->where('key', 'mail_driver')->first()->value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function master_api_token_does_not_need_csrf_token()
|
||||
{
|
||||
$response = $this->server->handle(
|
||||
(new ServerRequest([], [], '/api/settings', 'POST'))
|
||||
->withBody(new CallbackStream(function () {
|
||||
return '{"mail_driver": "log"}';
|
||||
}))
|
||||
->withHeader('Authorization', 'Token superadmin')
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
);
|
||||
|
||||
// Successful response?
|
||||
$this->assertEquals(204, $response->getStatusCode());
|
||||
|
||||
// Was the setting actually changed in the database?
|
||||
$this->assertEquals(
|
||||
'log',
|
||||
$this->database()->table('settings')->where('key', 'mail_driver')->first()->value
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user