2016-04-09 11:04:14 +03:00
|
|
|
<?php
|
2018-09-02 14:08:49 +03:00
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
2016-04-09 11:04:14 +03:00
|
|
|
namespace GraphQL\Tests\Validator;
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
use GraphQL\Error\Error;
|
2016-10-21 12:39:57 +03:00
|
|
|
use GraphQL\Error\FormattedError;
|
2016-04-09 11:04:14 +03:00
|
|
|
use GraphQL\Language\Parser;
|
|
|
|
use GraphQL\Type\Introspection;
|
|
|
|
use GraphQL\Validator\DocumentValidator;
|
2018-08-07 01:35:37 +03:00
|
|
|
use GraphQL\Validator\Rules\QuerySecurityRule;
|
2018-07-29 18:43:10 +03:00
|
|
|
use PHPUnit\Framework\TestCase;
|
2018-09-02 14:08:49 +03:00
|
|
|
use function array_map;
|
2016-04-09 11:04:14 +03:00
|
|
|
|
2018-07-29 18:43:10 +03:00
|
|
|
abstract class QuerySecurityTestCase extends TestCase
|
2016-04-09 11:04:14 +03:00
|
|
|
{
|
|
|
|
/**
|
2018-09-02 14:08:49 +03:00
|
|
|
* @expectedException \InvalidArgumentException
|
|
|
|
* @expectedExceptionMessage argument must be greater or equal to 0.
|
2016-04-09 11:04:14 +03:00
|
|
|
*/
|
2018-09-02 14:08:49 +03:00
|
|
|
public function testMaxQueryDepthMustBeGreaterOrEqualTo0() : void
|
|
|
|
{
|
|
|
|
$this->getRule(-1);
|
|
|
|
}
|
2016-04-09 11:04:14 +03:00
|
|
|
|
|
|
|
/**
|
2018-09-02 14:08:49 +03:00
|
|
|
* @param int $max
|
2016-04-09 11:04:14 +03:00
|
|
|
*
|
2018-09-02 14:08:49 +03:00
|
|
|
* @return QuerySecurityRule
|
2016-04-09 11:04:14 +03:00
|
|
|
*/
|
2018-09-02 14:08:49 +03:00
|
|
|
abstract protected function getRule($max);
|
2016-04-09 11:04:14 +03:00
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
protected function assertIntrospectionQuery($maxExpected)
|
2016-04-09 11:04:14 +03:00
|
|
|
{
|
2018-09-02 14:08:49 +03:00
|
|
|
$query = Introspection::getIntrospectionQuery();
|
|
|
|
|
|
|
|
$this->assertMaxValue($query, $maxExpected);
|
2016-04-09 11:04:14 +03:00
|
|
|
}
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
protected function assertMaxValue($query, $maxExpected)
|
2016-04-09 11:04:14 +03:00
|
|
|
{
|
2018-09-02 14:08:49 +03:00
|
|
|
$this->assertDocumentValidator($query, $maxExpected);
|
|
|
|
$newMax = $maxExpected - 1;
|
|
|
|
if ($newMax === QuerySecurityRule::DISABLED) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$this->assertDocumentValidator($query, $newMax, [$this->createFormattedError($newMax, $maxExpected)]);
|
2016-04-09 11:04:14 +03:00
|
|
|
}
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
/**
|
|
|
|
* @param string $queryString
|
|
|
|
* @param int $max
|
|
|
|
* @param string[][] $expectedErrors
|
|
|
|
* @return Error[]
|
|
|
|
*/
|
|
|
|
protected function assertDocumentValidator($queryString, $max, array $expectedErrors = []) : array
|
2016-04-09 11:04:14 +03:00
|
|
|
{
|
|
|
|
$errors = DocumentValidator::validate(
|
|
|
|
QuerySecuritySchema::buildSchema(),
|
|
|
|
Parser::parse($queryString),
|
|
|
|
[$this->getRule($max)]
|
|
|
|
);
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
$this->assertEquals($expectedErrors, array_map([Error::class, 'formatError'], $errors), $queryString);
|
2016-04-09 11:04:14 +03:00
|
|
|
|
|
|
|
return $errors;
|
|
|
|
}
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
protected function createFormattedError($max, $count, $locations = [])
|
2016-04-09 11:04:14 +03:00
|
|
|
{
|
2018-09-02 14:08:49 +03:00
|
|
|
return FormattedError::create($this->getErrorMessage($max, $count), $locations);
|
2016-04-09 11:04:14 +03:00
|
|
|
}
|
|
|
|
|
2018-09-02 14:08:49 +03:00
|
|
|
/**
|
|
|
|
* @param int $max
|
|
|
|
* @param int $count
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
abstract protected function getErrorMessage($max, $count);
|
|
|
|
|
2016-04-09 11:04:14 +03:00
|
|
|
protected function assertIntrospectionTypeMetaFieldQuery($maxExpected)
|
|
|
|
{
|
|
|
|
$query = '
|
|
|
|
{
|
|
|
|
__type(name: "Human") {
|
|
|
|
name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
';
|
|
|
|
|
|
|
|
$this->assertMaxValue($query, $maxExpected);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function assertTypeNameMetaFieldQuery($maxExpected)
|
|
|
|
{
|
|
|
|
$query = '
|
|
|
|
{
|
|
|
|
human {
|
|
|
|
__typename
|
|
|
|
firstName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
';
|
|
|
|
$this->assertMaxValue($query, $maxExpected);
|
|
|
|
}
|
|
|
|
}
|