diff --git a/_config/config.yml b/_config/config.yml index 49f8a4e10..c650ee822 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -1,12 +1,6 @@ --- Name: graphqlconfig --- -# Minimum fields that any type will expose. Useful for implicitly -# created types, e.g. exposing a has_one. -SilverStripe\GraphQL\Scaffolding\Scaffolders\DataObjectScaffolder: - default_fields: - ID: ID - # Define the type parsers SilverStripe\Core\Injector\Injector: SilverStripe\GraphQL\Scaffolding\Interfaces\TypeParserInterface.string: @@ -30,11 +24,3 @@ SilverStripe\ORM\FieldType\DBPrimaryKey: SilverStripe\ORM\FieldType\DBForeignKey: graphql_type: ID -## CORS default config -SilverStripe\GraphQL\Controller: - cors: - Enabled: false # Off by default - Allow-Origin: # Deny all by default - Allow-Headers: 'Authorization, Content-Type' - Allow-Methods: 'GET, POST, OPTIONS' - Max-Age: 86400 # 86,400 seconds = 1 day. diff --git a/src/Controller.php b/src/Controller.php index 748275f85..9b498f896 100644 --- a/src/Controller.php +++ b/src/Controller.php @@ -2,15 +2,16 @@ namespace SilverStripe\GraphQL; +use Exception; use SilverStripe\Control\Controller as BaseController; +use SilverStripe\Control\Director; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse; use SilverStripe\Core\Config\Config; -use SilverStripe\Control\Director; use SilverStripe\GraphQL\Auth\Handler; -use SilverStripe\Versioned\Versioned; -use Exception; +use SilverStripe\Security\Member; use SilverStripe\Security\Permission; +use SilverStripe\Versioned\Versioned; /** * Top level controller for handling graphql requests. @@ -19,6 +20,20 @@ */ class Controller extends BaseController { + /** + * Cors default config + * + * @config + * @var array + */ + private static $cors = [ + 'Enabled' => false, // Off by default + 'Allow-Origin' => [], // List of all allowed origins; Deny by default + 'Allow-Headers' => 'Authorization, Content-Type', + 'Allow-Methods' => 'GET, POST, OPTIONS', + 'Max-Age' => 86400, // 86,400 seconds = 1 day. + ]; + /** * @var Manager */ @@ -39,56 +54,22 @@ public function index(HTTPRequest $request) // Check for a possible CORS preflight request and handle if necessary // Refer issue 66: https://github.com/silverstripe/silverstripe-graphql/issues/66 - $corsConfig = Config::inst()->get(self::class, 'cors'); - $corsEnabled = true; // Default to have CORS turned on. - - if ($corsConfig && isset($corsConfig['Enabled']) && !$corsConfig['Enabled']) { - // Dev has turned off CORS - $corsEnabled = false; - } - if ($corsEnabled && $request->httpMethod() == 'OPTIONS') { - // CORS config is enabled and the request is an OPTIONS pre-flight. - // Process the CORS config and add appropriate headers. - $response = new HTTPResponse(); - return $this->addCorsHeaders($request, $response); - } elseif (!$corsEnabled && $request->httpMethod() == 'OPTIONS') { - // CORS is disabled but we have received an OPTIONS request. This is not a valid request method in this - // situation. Return a 405 Method Not Allowed response. - return $this->httpError(405, "Method Not Allowed"); - } - - $contentType = $request->getHeader('Content-Type') ?: $request->getHeader('content-type'); - $isJson = preg_match('#^application/json\b#', $contentType); - if ($isJson) { - $rawBody = $request->getBody(); - $data = json_decode($rawBody ?: '', true); - $query = isset($data['query']) ? $data['query'] : null; - $variables = isset($data['variables']) ? (array) $data['variables'] : null; - } else { - $query = $request->requestVar('query'); - $variables = json_decode($request->requestVar('variables'), true); + if ($request->httpMethod() === 'OPTIONS') { + return $this->handleOptions($request); } - $this->setManager($manager = $this->getManager()); - + // Main query handling try { - // Check authentication - $member = $this->getAuthHandler()->requireAuthentication($request); + $manager = $this->getManager(); + + // Check and validate user for this request + $member = $this->getRequestUser($request); if ($member) { $manager->setMember($member); } - // Check authorisation - $permissions = $request->param('Permissions'); - if ($permissions) { - if (!$member) { - throw new Exception("Authentication required"); - } - $allowed = Permission::checkMember($member, $permissions); - if (!$allowed) { - throw new Exception("Not authorised"); - } - } + // Parse input + list($query, $variables) = $this->getRequestQueryVariables($request); // Run query $result = $manager->query($query, $variables); @@ -123,16 +104,18 @@ public function getManager() // Get a service rather than an instance (to allow procedural configuration) $config = Config::inst()->get(static::class, 'schema'); $manager = Manager::createFromConfig($config); - + $this->setManager($manager); return $manager; } /** * @param Manager $manager + * @return $this */ public function setManager($manager) { $this->manager = $manager; + return $this; } /** @@ -155,45 +138,157 @@ public function getAuthHandler() public function addCorsHeaders(HTTPRequest $request, HTTPResponse $response) { $corsConfig = Config::inst()->get(static::class, 'cors'); + + // If CORS is disabled don't add the extra headers. Simply return the response untouched. if (empty($corsConfig['Enabled'])) { - // If CORS is disabled don't add the extra headers. Simply return the response untouched. return $response; } - // Allow Origins header. - if (is_string($corsConfig['Allow-Origin'])) { - $allowedOrigins = [$corsConfig['Allow-Origin']]; - } else { - $allowedOrigins = $corsConfig['Allow-Origin']; - } - if (!empty($allowedOrigins)) { - $origin = $request->getHeader('Origin'); - if ($origin) { - $originAuthorised = false; - foreach ($allowedOrigins as $allowedOrigin) { - if ($allowedOrigin == $origin || $allowedOrigin === '*') { - $response->addHeader("Access-Control-Allow-Origin", $origin); - $originAuthorised = true; - break; - } - } - - if (!$originAuthorised) { - return $this->httpError(403, "Access Forbidden"); - } - } else { - // No Origin header present in Request. - return $this->httpError(403, "Access Forbidden"); - } - } else { - // No allowed origins, ergo all origins forbidden. - return $this->httpError(403, "Access Forbidden"); + // Calculate origin + $origin = $this->getRequestOrigin($request); + + // Check if valid + $allowedOrigins = (array)$corsConfig['Allow-Origin']; + $originAuthorised = $this->validateOrigin($origin, $allowedOrigins); + if (!$originAuthorised) { + $this->httpError(403, "Access Forbidden"); } + $response->addHeader('Access-Control-Allow-Origin', $origin); $response->addHeader('Access-Control-Allow-Headers', $corsConfig['Allow-Headers']); $response->addHeader('Access-Control-Allow-Methods', $corsConfig['Allow-Methods']); $response->addHeader('Access-Control-Max-Age', $corsConfig['Max-Age']); return $response; } + + /** + * Validate an origin matches a set of allowed origins + * + * @param string $origin Origin string + * @param array $allowedOrigins List of allowed origins + * @return bool + */ + protected function validateOrigin($origin, $allowedOrigins) + { + if (empty($allowedOrigins) || empty($origin)) { + return false; + } + foreach ($allowedOrigins as $allowedOrigin) { + if ($allowedOrigin === '*') { + return true; + } + if (strcasecmp($allowedOrigin, $origin) === 0) { + return true; + } + } + return false; + } + + /** + * Get (or infer) value of Origin header + * + * @param HTTPRequest $request + * @return string|null + */ + protected function getRequestOrigin(HTTPRequest $request) + { + // Prefer Origin header + $origin = $request->getHeader('Origin'); + if ($origin) { + return $origin; + } + + // Check referer + $referer = $request->getHeader('Referer'); + if ($referer) { + // Extract protocol, hostname, and port + $refererParts = parse_url($referer); + if (!$refererParts) { + return null; + } + // Rebuild + $origin = $refererParts['scheme'] . '://' . $refererParts['host']; + if (isset($refererParts['port'])) { + $origin .= ':' . $refererParts['port']; + } + return $origin; + } + + return null; + } + + /** + * Response for HTTP OPTIONS request + * + * @param HTTPRequest $request + * @return HTTPResponse + */ + protected function handleOptions(HTTPRequest $request) + { + $response = HTTPResponse::create(); + $corsConfig = Config::inst()->get(self::class, 'cors'); + if ($corsConfig['Enabled']) { + // CORS config is enabled and the request is an OPTIONS pre-flight. + // Process the CORS config and add appropriate headers. + $this->addCorsHeaders($request, $response); + } else { + // CORS is disabled but we have received an OPTIONS request. This is not a valid request method in this + // situation. Return a 405 Method Not Allowed response. + $this->httpError(405, "Method Not Allowed"); + } + return $response; + } + + /** + * Parse query and variables from the given request + * + * @param HTTPRequest $request + * @return array Array containing query and variables as a pair + */ + protected function getRequestQueryVariables(HTTPRequest $request) + { + $contentType = $request->getHeader('content-type'); + $isJson = preg_match('#^application/json\b#', $contentType); + if ($isJson) { + $rawBody = $request->getBody(); + $data = json_decode($rawBody ?: '', true); + $query = isset($data['query']) ? $data['query'] : null; + $variables = isset($data['variables']) ? (array)$data['variables'] : null; + } else { + $query = $request->requestVar('query'); + $variables = json_decode($request->requestVar('variables'), true); + } + return [$query, $variables]; + } + + /** + * Get user and validate for this request + * + * @param HTTPRequest $request + * @return Member + */ + protected function getRequestUser(HTTPRequest $request) + { + // Check authentication + $member = $this->getAuthHandler()->requireAuthentication($request); + + // Check authorisation + $permissions = $request->param('Permissions'); + if (!$permissions) { + return $member; + } + + // If permissions requested require authentication + if (!$member) { + throw new Exception("Authentication required"); + } + + // Check authorisation for this member + $allowed = Permission::checkMember($member, $permissions); + if (!$allowed) { + throw new Exception("Not authorised"); + } + return $member; + } } diff --git a/src/Manager.php b/src/Manager.php index 8d67154db..7ea346bc6 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -2,7 +2,7 @@ namespace SilverStripe\GraphQL; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use GraphQL\Executor\ExecutionResult; use GraphQL\Language\SourceLocation; use GraphQL\Schema; diff --git a/src/Scaffolding/Scaffolders/DataObjectScaffolder.php b/src/Scaffolding/Scaffolders/DataObjectScaffolder.php index 2d5d19ce8..eeb80a388 100644 --- a/src/Scaffolding/Scaffolders/DataObjectScaffolder.php +++ b/src/Scaffolding/Scaffolders/DataObjectScaffolder.php @@ -2,27 +2,27 @@ namespace SilverStripe\GraphQL\Scaffolding\Scaffolders; -use Doctrine\Instantiator\Exception\InvalidArgumentException; use Exception; -use SilverStripe\ORM\DataList; -use SilverStripe\ORM\DataObject; -use SilverStripe\ORM\ArrayList; -use SilverStripe\ORM\SS_List; -use SilverStripe\View\ArrayData; -use SilverStripe\ORM\DataObjectInterface; -use SilverStripe\ORM\FieldType\DBField; -use SilverStripe\GraphQL\Manager; use GraphQL\Type\Definition\ObjectType; -use SilverStripe\GraphQL\Scaffolding\Util\OperationList; -use SilverStripe\GraphQL\Scaffolding\Util\ScaffoldingUtil; -use SilverStripe\GraphQL\Scaffolding\Traits\DataObjectTypeTrait; -use SilverStripe\Core\Config\Config; +use InvalidArgumentException; use SilverStripe\Core\ClassInfo; -use SilverStripe\GraphQL\Scaffolding\Traits\Chainable; +use SilverStripe\Core\Config\Config; +use SilverStripe\GraphQL\Manager; +use SilverStripe\GraphQL\Scaffolding\Interfaces\ConfigurationApplier; use SilverStripe\GraphQL\Scaffolding\Interfaces\ManagerMutatorInterface; use SilverStripe\GraphQL\Scaffolding\Interfaces\ScaffolderInterface; +use SilverStripe\GraphQL\Scaffolding\Traits\Chainable; +use SilverStripe\GraphQL\Scaffolding\Traits\DataObjectTypeTrait; +use SilverStripe\GraphQL\Scaffolding\Util\OperationList; +use SilverStripe\GraphQL\Scaffolding\Util\ScaffoldingUtil; use SilverStripe\ORM\ArrayLib; -use SilverStripe\GraphQL\Scaffolding\Interfaces\ConfigurationApplier; +use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DataObject; +use SilverStripe\ORM\DataObjectInterface; +use SilverStripe\ORM\FieldType\DBField; +use SilverStripe\ORM\SS_List; +use SilverStripe\View\ArrayData; /** * Scaffolds a DataObjectTypeCreator. @@ -32,6 +32,17 @@ class DataObjectScaffolder implements ManagerMutatorInterface, ScaffolderInterfa use DataObjectTypeTrait; use Chainable; + /** + * Minimum fields that any type will expose. Useful for implicitly + * created types, e.g. exposing a has_one. + * + * @config + * @var array + */ + private static $default_fields = [ + 'ID' => 'ID', + ]; + /** * @var ArrayList */ diff --git a/src/Scaffolding/Scaffolders/OperationScaffolder.php b/src/Scaffolding/Scaffolders/OperationScaffolder.php index 6fa665977..53e09a6f2 100644 --- a/src/Scaffolding/Scaffolders/OperationScaffolder.php +++ b/src/Scaffolding/Scaffolders/OperationScaffolder.php @@ -2,7 +2,7 @@ namespace SilverStripe\GraphQL\Scaffolding\Scaffolders; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Interfaces\ResolverInterface; use SilverStripe\Core\Injector\Injector; use SilverStripe\GraphQL\Scaffolding\Traits\Chainable; diff --git a/src/Scaffolding/Scaffolders/QueryScaffolder.php b/src/Scaffolding/Scaffolders/QueryScaffolder.php index 578bef7d6..d3e3508bf 100644 --- a/src/Scaffolding/Scaffolders/QueryScaffolder.php +++ b/src/Scaffolding/Scaffolders/QueryScaffolder.php @@ -8,7 +8,7 @@ use SilverStripe\GraphQL\Pagination\Connection; use SilverStripe\GraphQL\Scaffolding\Interfaces\ManagerMutatorInterface; use SilverStripe\GraphQL\Scaffolding\Interfaces\ScaffolderInterface; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; /** * Scaffolds a GraphQL query field. diff --git a/src/Scaffolding/Scaffolders/SchemaScaffolder.php b/src/Scaffolding/Scaffolders/SchemaScaffolder.php index fb347399d..66f64319c 100644 --- a/src/Scaffolding/Scaffolders/SchemaScaffolder.php +++ b/src/Scaffolding/Scaffolders/SchemaScaffolder.php @@ -4,7 +4,7 @@ use League\Flysystem\Exception; use SilverStripe\Core\Injector\Injector; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Manager; use SilverStripe\GraphQL\Scaffolding\Extensions\TypeCreatorExtension; use SilverStripe\GraphQL\Scaffolding\Interfaces\CRUDInterface; diff --git a/src/Scaffolding/Util/ArrayTypeParser.php b/src/Scaffolding/Util/ArrayTypeParser.php index 9d5b64567..ec38f3dbb 100644 --- a/src/Scaffolding/Util/ArrayTypeParser.php +++ b/src/Scaffolding/Util/ArrayTypeParser.php @@ -3,7 +3,7 @@ namespace SilverStripe\GraphQL\Scaffolding\Util; use GraphQL\Type\Definition\Type; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\ORM\ArrayLib; use GraphQL\Type\Definition\ObjectType; use SilverStripe\GraphQL\Scaffolding\Interfaces\TypeParserInterface; diff --git a/src/Scaffolding/Util/OperationList.php b/src/Scaffolding/Util/OperationList.php index 4ed3d3ac8..c0a64ff18 100644 --- a/src/Scaffolding/Util/OperationList.php +++ b/src/Scaffolding/Util/OperationList.php @@ -5,7 +5,7 @@ use SilverStripe\GraphQL\Scaffolding\Interfaces\CRUDInterface; use SilverStripe\GraphQL\Scaffolding\Scaffolders\OperationScaffolder; use SilverStripe\ORM\ArrayList; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; /** * An array list designed to work with OperationScaffolders diff --git a/src/Scaffolding/Util/StringTypeParser.php b/src/Scaffolding/Util/StringTypeParser.php index 616ec6cd6..8258b8e61 100644 --- a/src/Scaffolding/Util/StringTypeParser.php +++ b/src/Scaffolding/Util/StringTypeParser.php @@ -3,7 +3,7 @@ namespace SilverStripe\GraphQL\Scaffolding\Util; use GraphQL\Type\Definition\Type; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Interfaces\TypeParserInterface; use SilverStripe\Core\Injector\Injectable; diff --git a/tests/ControllerTest.php b/tests/ControllerTest.php index ebced98de..e260345c9 100644 --- a/tests/ControllerTest.php +++ b/tests/ControllerTest.php @@ -186,7 +186,7 @@ public function testAddCorsHeadersOriginAllowed() { Config::modify()->set(Controller::class, 'cors', [ 'Enabled' => true, - 'Allow-Origin' => 'localhost', + 'Allow-Origin' => 'http://localhost', 'Allow-Headers' => 'Authorization, Content-Type', 'Allow-Methods' => 'GET, POST, OPTIONS', 'Max-Age' => 86400 @@ -194,7 +194,7 @@ public function testAddCorsHeadersOriginAllowed() $controller = new Controller(); $request = new HTTPRequest('GET', ''); - $request->addHeader('Origin', 'localhost'); + $request->addHeader('Origin', 'http://localhost'); $response = new HTTPResponse(); $response = $controller->addCorsHeaders($request, $response); @@ -202,12 +202,86 @@ public function testAddCorsHeadersOriginAllowed() $this->assertEquals('200', $response->getStatusCode()); // Check returned headers. A valid origin should return 4 headers. - $this->assertEquals('localhost', $response->getHeader('Access-Control-Allow-Origin')); + $this->assertEquals('http://localhost', $response->getHeader('Access-Control-Allow-Origin')); + $this->assertEquals('Authorization, Content-Type', $response->getHeader('Access-Control-Allow-Headers')); + $this->assertEquals('GET, POST, OPTIONS', $response->getHeader('Access-Control-Allow-Methods')); + $this->assertEquals(86400, $response->getHeader('Access-Control-Max-Age')); + } + + public function testAddCorsHeadersRefererAllowed() + { + Config::modify()->set(Controller::class, 'cors', [ + 'Enabled' => true, + 'Allow-Origin' => 'http://localhost', + 'Allow-Headers' => 'Authorization, Content-Type', + 'Allow-Methods' => 'GET, POST, OPTIONS', + 'Max-Age' => 86400 + ]); + + $controller = new Controller(); + $request = new HTTPRequest('GET', ''); + $request->addHeader('Referer', 'http://localhost/some-url/?bob=1'); + $response = new HTTPResponse(); + $response = $controller->addCorsHeaders($request, $response); + + $this->assertTrue($response instanceof HTTPResponse); + $this->assertEquals('200', $response->getStatusCode()); + + // Check returned headers. A valid origin should return 4 headers. + $this->assertEquals('http://localhost', $response->getHeader('Access-Control-Allow-Origin')); + $this->assertEquals('Authorization, Content-Type', $response->getHeader('Access-Control-Allow-Headers')); + $this->assertEquals('GET, POST, OPTIONS', $response->getHeader('Access-Control-Allow-Methods')); + $this->assertEquals(86400, $response->getHeader('Access-Control-Max-Age')); + } + + public function testAddCorsHeadersRefererPortAllowed() + { + Config::modify()->set(Controller::class, 'cors', [ + 'Enabled' => true, + 'Allow-Origin' => 'http://localhost:8181', + 'Allow-Headers' => 'Authorization, Content-Type', + 'Allow-Methods' => 'GET, POST, OPTIONS', + 'Max-Age' => 86400 + ]); + + $controller = new Controller(); + $request = new HTTPRequest('GET', ''); + $request->addHeader('Referer', 'http://localhost:8181/some-url/?bob=1'); + $response = new HTTPResponse(); + $response = $controller->addCorsHeaders($request, $response); + + $this->assertTrue($response instanceof HTTPResponse); + $this->assertEquals('200', $response->getStatusCode()); + + // Check returned headers. A valid origin should return 4 headers. + $this->assertEquals('http://localhost:8181', $response->getHeader('Access-Control-Allow-Origin')); $this->assertEquals('Authorization, Content-Type', $response->getHeader('Access-Control-Allow-Headers')); $this->assertEquals('GET, POST, OPTIONS', $response->getHeader('Access-Control-Allow-Methods')); $this->assertEquals(86400, $response->getHeader('Access-Control-Max-Age')); } + /** + * Test fail on referer port + */ + public function testAddCorsHeadersRefererPortDisallowed() + { + $this->expectException(HTTPResponse_Exception::class); + + Config::modify()->set(Controller::class, 'cors', [ + 'Enabled' => true, + 'Allow-Origin' => 'http://localhost:9090', + 'Allow-Headers' => 'Authorization, Content-Type', + 'Allow-Methods' => 'GET, POST, OPTIONS', + 'Max-Age' => 86400 + ]); + + $controller = new Controller(); + $request = new HTTPRequest('GET', ''); + $request->addHeader('Referer', 'http://localhost:8080/some-url/?bob=1'); + $response = new HTTPResponse(); + $controller->addCorsHeaders($request, $response); + } + public function testAddCorsHeadersOriginAllowedWildcard() { Controller::config()->set('cors', [ @@ -244,18 +318,16 @@ public function testAddCorsHeadersOriginMissing() $controller = new Controller(); $request = new HTTPRequest('GET', ''); $response = new HTTPResponse(); - $response = $controller->addCorsHeaders($request, $response); - - $this->assertTrue($response instanceof HTTPResponse); - $this->assertEquals('403', $response->getStatusCode()); + $controller->addCorsHeaders($request, $response); } /** - * {@inheritDoc} - * @expectedException \SilverStripe\Control\HTTPResponse_Exception + * HTTP OPTIONS without cors should error */ public function testAddCorsHeadersResponseCORSDisabled() { + $this->expectException(HTTPResponse_Exception::class); + Config::modify()->set(Controller::class, 'cors', [ 'Enabled' => false ]); @@ -263,10 +335,7 @@ public function testAddCorsHeadersResponseCORSDisabled() $controller = new Controller(); $request = new HTTPRequest('OPTIONS', ''); $request->addHeader('Origin', 'localhost'); - $response = $controller->index($request); - - $this->assertTrue($response instanceof HTTPResponse); - $this->assertEquals('405', $response->getStatusCode()); + $controller->index($request); } protected function getType(Manager $manager) diff --git a/tests/Scaffolding/Scaffolders/DataObjectScaffolderTest.php b/tests/Scaffolding/Scaffolders/DataObjectScaffolderTest.php index c37c41922..03a97abdc 100644 --- a/tests/Scaffolding/Scaffolders/DataObjectScaffolderTest.php +++ b/tests/Scaffolding/Scaffolders/DataObjectScaffolderTest.php @@ -12,7 +12,7 @@ use SilverStripe\GraphQL\Tests\Fake\FakeSiteTree; use SilverStripe\GraphQL\Tests\Fake\FakePage; use SilverStripe\GraphQL\Tests\Fake\FakeRedirectorPage; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Scaffolders\SchemaScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\QueryScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\CRUD\Create; diff --git a/tests/Scaffolding/Scaffolders/OperationScaffolderTest.php b/tests/Scaffolding/Scaffolders/OperationScaffolderTest.php index 37cf454f2..ea9d4ec1b 100644 --- a/tests/Scaffolding/Scaffolders/OperationScaffolderTest.php +++ b/tests/Scaffolding/Scaffolders/OperationScaffolderTest.php @@ -6,7 +6,7 @@ use SilverStripe\GraphQL\Tests\Fake\DataObjectFake; use SilverStripe\GraphQL\Tests\Fake\OperationScaffolderFake; use SilverStripe\GraphQL\Tests\Fake\FakeResolver; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Scaffolders\SchemaScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\OperationScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\ArgumentScaffolder; diff --git a/tests/Scaffolding/Scaffolders/QueryScaffolderTest.php b/tests/Scaffolding/Scaffolders/QueryScaffolderTest.php index 3f720b172..4016cf308 100644 --- a/tests/Scaffolding/Scaffolders/QueryScaffolderTest.php +++ b/tests/Scaffolding/Scaffolders/QueryScaffolderTest.php @@ -4,7 +4,7 @@ use SilverStripe\GraphQL\Manager; use SilverStripe\Dev\SapphireTest; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Scaffolders\QueryScaffolder; use GraphQL\Type\Definition\ObjectType; diff --git a/tests/Scaffolding/Scaffolders/SchemaScaffolderTest.php b/tests/Scaffolding/Scaffolders/SchemaScaffolderTest.php index cded93421..4d1d07d5d 100644 --- a/tests/Scaffolding/Scaffolders/SchemaScaffolderTest.php +++ b/tests/Scaffolding/Scaffolders/SchemaScaffolderTest.php @@ -12,7 +12,7 @@ use SilverStripe\GraphQL\Tests\Fake\FakePage; use SilverStripe\GraphQL\Tests\Fake\FakeRedirectorPage; use SilverStripe\GraphQL\Tests\Fake\FakeInt; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Scaffolders\SchemaScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\QueryScaffolder; use SilverStripe\GraphQL\Scaffolding\Scaffolders\MutationScaffolder; diff --git a/tests/Scaffolding/Util/ArrayTypeParserTest.php b/tests/Scaffolding/Util/ArrayTypeParserTest.php index dd53dd082..bcf500180 100644 --- a/tests/Scaffolding/Util/ArrayTypeParserTest.php +++ b/tests/Scaffolding/Util/ArrayTypeParserTest.php @@ -7,7 +7,7 @@ use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\StringType; use SilverStripe\Dev\SapphireTest; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Util\ArrayTypeParser; /** diff --git a/tests/Scaffolding/Util/OperationListTest.php b/tests/Scaffolding/Util/OperationListTest.php index cf88f60e6..3ed925e89 100644 --- a/tests/Scaffolding/Util/OperationListTest.php +++ b/tests/Scaffolding/Util/OperationListTest.php @@ -3,7 +3,7 @@ namespace SilverStripe\GraphQL\Tests\Util; use SilverStripe\Dev\SapphireTest; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Scaffolders\MutationScaffolder; use SilverStripe\GraphQL\Scaffolding\Util\OperationList; diff --git a/tests/Scaffolding/Util/StringTypeParserTest.php b/tests/Scaffolding/Util/StringTypeParserTest.php index a2d8dce29..aadbf499d 100644 --- a/tests/Scaffolding/Util/StringTypeParserTest.php +++ b/tests/Scaffolding/Util/StringTypeParserTest.php @@ -3,7 +3,7 @@ namespace SilverStripe\GraphQL\Tests\Util; use SilverStripe\Dev\SapphireTest; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use SilverStripe\GraphQL\Scaffolding\Util\StringTypeParser; use GraphQL\Type\Definition\StringType;