From c4d72c52a4dd9fb0b9384dfcc538ab9f16ddfc6f Mon Sep 17 00:00:00 2001 From: Andriy Komm Date: Thu, 20 Sep 2018 18:04:36 +0200 Subject: [PATCH 1/4] Testcase for #387 --- .../config/access/mapping/access.types.yml | 15 +++++++++ tests/Functional/Security/AccessTest.php | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/tests/Functional/App/config/access/mapping/access.types.yml b/tests/Functional/App/config/access/mapping/access.types.yml index 7836bbf68..5be91d1c2 100644 --- a/tests/Functional/App/config/access/mapping/access.types.yml +++ b/tests/Functional/App/config/access/mapping/access.types.yml @@ -6,6 +6,10 @@ RootQuery: user: type: User resolve: '@=resolver("query")' + youShallNotSeeThisUnauthenticated: + type: SecureField + access: '@=isFullyAuthenticated()' + resolve: '@=[]' Mutation: type: object @@ -48,6 +52,17 @@ User: interfaces: [Human] isTypeOf: true +SecureField: + type: object + config: + fields: + secretValue: + type: String! + resolve: 'top secret' + youAreAuthenticated: + type: Boolean! + resolve: '@=isFullyAuthenticated()' + friendConnection: type: relay-connection config: diff --git a/tests/Functional/Security/AccessTest.php b/tests/Functional/Security/AccessTest.php index 27d820f26..36520667f 100644 --- a/tests/Functional/Security/AccessTest.php +++ b/tests/Functional/Security/AccessTest.php @@ -91,6 +91,39 @@ public function testNotAuthenticatedUserAccessToUserName(): void $this->assertResponse($this->userNameQuery, $expected, static::ANONYMOUS_USER, 'access'); } + public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolvesToArray() + { + $expected = [ + 'data' => [ + 'youShallNotSeeThisUnauthenticated' => null, + ], + 'extensions' => [ + 'warnings' => [ + 'message' => 'Access denied to this field.', + 'locations' => [ + [ + 'line' => 3, + 'column' => 5, + ], + ], + 'path' => ['youShallNotSeeThisUnauthenticated'], + 'category' => 'user', + ], + ], + ]; + + $query = <<<'EOF' +{ + youShallNotSeeThisUnauthenticated { + secretValue + youAreAuthenticated + } +} +EOF; + + $this->assertResponse($query, $expected, static::ANONYMOUS_USER, 'access'); + } + public function testFullyAuthenticatedUserAccessToUserName(): void { $expected = [ From 4cc3ba7b7fa707f278320f3dea47627b25fd027a Mon Sep 17 00:00:00 2001 From: Andriy Komm Date: Thu, 20 Sep 2018 18:11:42 +0200 Subject: [PATCH 2/4] Testcase for #387 expected line numbers fix --- tests/Functional/Security/AccessTest.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/Functional/Security/AccessTest.php b/tests/Functional/Security/AccessTest.php index 36520667f..ce27bff8b 100644 --- a/tests/Functional/Security/AccessTest.php +++ b/tests/Functional/Security/AccessTest.php @@ -99,15 +99,17 @@ public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolves ], 'extensions' => [ 'warnings' => [ - 'message' => 'Access denied to this field.', - 'locations' => [ - [ - 'line' => 3, - 'column' => 5, + [ + 'message' => 'Access denied to this field.', + 'locations' => [ + [ + 'line' => 2, + 'column' => 3, + ], ], - ], - 'path' => ['youShallNotSeeThisUnauthenticated'], - 'category' => 'user', + 'path' => ['youShallNotSeeThisUnauthenticated'], + 'category' => 'user', + ] ], ], ]; From b9badcafa6573b865d5b72960f6e0a578a5b24af Mon Sep 17 00:00:00 2001 From: Andriy Komm Date: Thu, 20 Sep 2018 18:46:02 +0200 Subject: [PATCH 3/4] Fix for #387 --- src/Resolver/AccessResolver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Resolver/AccessResolver.php b/src/Resolver/AccessResolver.php index 3ce0de708..7eb7d999c 100644 --- a/src/Resolver/AccessResolver.php +++ b/src/Resolver/AccessResolver.php @@ -7,6 +7,8 @@ use GraphQL\Executor\Promise\Adapter\SyncPromise; use GraphQL\Executor\Promise\Promise; use GraphQL\Executor\Promise\PromiseAdapter; +use GraphQL\Type\Definition\ListOfType; +use GraphQL\Type\Definition\ResolveInfo; use Overblog\GraphQLBundle\Error\UserError; use Overblog\GraphQLBundle\Error\UserWarning; use Overblog\GraphQLBundle\Relay\Connection\Output\Connection; @@ -59,7 +61,9 @@ function ($result) use ($accessChecker, $resolveArgs) { private function processFilter($result, $accessChecker, $resolveArgs) { - if (\is_array($result)) { + /** @var ResolveInfo $resolveInfo */ + $resolveInfo = $resolveArgs[3]; + if (\is_array($result) && $resolveInfo->returnType instanceof ListOfType) { $result = \array_map( function ($object) use ($accessChecker, $resolveArgs) { return $this->hasAccess($accessChecker, $object, $resolveArgs) ? $object : null; From 21a51d25a33a361de361e9ff933b15ab2b5d3a6f Mon Sep 17 00:00:00 2001 From: Andriy Komm Date: Thu, 20 Sep 2018 19:35:03 +0200 Subject: [PATCH 4/4] CS fix --- tests/Functional/Security/AccessTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/Security/AccessTest.php b/tests/Functional/Security/AccessTest.php index ce27bff8b..385a5d07a 100644 --- a/tests/Functional/Security/AccessTest.php +++ b/tests/Functional/Security/AccessTest.php @@ -91,7 +91,7 @@ public function testNotAuthenticatedUserAccessToUserName(): void $this->assertResponse($this->userNameQuery, $expected, static::ANONYMOUS_USER, 'access'); } - public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolvesToArray() + public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolvesToArray(): void { $expected = [ 'data' => [ @@ -109,7 +109,7 @@ public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolves ], 'path' => ['youShallNotSeeThisUnauthenticated'], 'category' => 'user', - ] + ], ], ], ];