Skip to content

Commit dfae362

Browse files
authored
Merge pull request #389 from mcg-web/fix-acl-with-array
Fix acl with array
2 parents daefb71 + 84371c7 commit dfae362

File tree

4 files changed

+75
-8
lines changed

4 files changed

+75
-8
lines changed

.travis.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ matrix:
2323
- php: hhvm
2424
- php: nightly
2525
allow_failures:
26+
- php: hhvm
2627
- php: nightly
2728

2829
cache:
@@ -35,8 +36,11 @@ before_install:
3536
- composer selfupdate
3637
- if [ $SYMFONY_VERSION ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" "symfony/framework-bundle:${SYMFONY_VERSION}" --dev --no-update; fi;
3738
- if [ $GRAPHQLPHP_VERSION ]; then composer require "webonyx/graphql-php:${GRAPHQLPHP_VERSION}" --dev --no-update; fi;
39+
- echo "memory_limit=3072M" >> "$HOME/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini"
3840

39-
install: composer update --prefer-source --no-interaction --optimize-autoloader
41+
install:
42+
- composer update --prefer-source --no-interaction --optimize-autoloader
43+
- echo "memory_limit=256M" >> "$HOME/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini"
4044

4145
script:
4246
- bin/phpunit --debug $( if [ $TEST_COVERAGE = true ]; then echo "-d xdebug.max_nesting_level=1000 --coverage-clover=build/logs/clover.xml"; fi; )

Resolver/AccessResolver.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use GraphQL\Executor\Promise\Adapter\SyncPromise;
1515
use GraphQL\Executor\Promise\Promise;
1616
use GraphQL\Executor\Promise\PromiseAdapter;
17+
use GraphQL\Type\Definition\ListOfType;
18+
use GraphQL\Type\Definition\ResolveInfo;
1719
use Overblog\GraphQLBundle\Error\UserError;
1820
use Overblog\GraphQLBundle\Error\UserWarning;
1921
use Overblog\GraphQLBundle\Relay\Connection\Output\Connection;
@@ -66,13 +68,13 @@ function ($result) use ($accessChecker, $resolveArgs) {
6668

6769
private function processFilter($result, $accessChecker, $resolveArgs)
6870
{
69-
if (is_array($result)) {
70-
$result = array_map(
71-
function ($object) use ($accessChecker, $resolveArgs) {
72-
return $this->hasAccess($accessChecker, $object, $resolveArgs) ? $object : null;
73-
},
74-
$result
75-
);
71+
/** @var ResolveInfo $resolveInfo */
72+
$resolveInfo = $resolveArgs[3];
73+
74+
if (self::isIterable($result) && $resolveInfo->returnType instanceof ListOfType) {
75+
foreach ($result as $i => $object) {
76+
$result[$i] = $this->hasAccess($accessChecker, $object, $resolveArgs) ? $object : null;
77+
}
7678
} elseif ($result instanceof Connection) {
7779
$result->edges = array_map(
7880
function (Edge $edge) use ($accessChecker, $resolveArgs) {
@@ -96,4 +98,18 @@ private function hasAccess(callable $accessChecker, $object, array $resolveArgs
9698

9799
return $access;
98100
}
101+
102+
/**
103+
* @param mixed $data
104+
*
105+
* @return bool
106+
*/
107+
private static function isIterable($data)
108+
{
109+
if (function_exists('is_iterable')) {
110+
return \is_iterable($data);
111+
} else {
112+
return \is_array($data) || (\is_object($data) && ($data instanceof \Traversable));
113+
}
114+
}
99115
}

Tests/Functional/App/config/access/mapping/access.types.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ RootQuery:
66
user:
77
type: User
88
resolve: '@=resolver("query")'
9+
youShallNotSeeThisUnauthenticated:
10+
type: SecureField
11+
access: '@=isFullyAuthenticated()'
12+
resolve: '@=[]'
913

1014
Mutation:
1115
type: object
@@ -47,6 +51,17 @@ User:
4751
interfaces: [Human]
4852
isTypeOf: true
4953

54+
SecureField:
55+
type: object
56+
config:
57+
fields:
58+
secretValue:
59+
type: String!
60+
resolve: 'top secret'
61+
youAreAuthenticated:
62+
type: Boolean!
63+
resolve: '@=isFullyAuthenticated()'
64+
5065
friendConnection:
5166
type: relay-connection
5267
config:

Tests/Functional/Security/AccessTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,38 @@ public function testNotAuthenticatedUserAccessToUserName()
9696
$this->assertResponse($this->userNameQuery, $expected, static::ANONYMOUS_USER, 'access');
9797
}
9898

99+
public function testNonAuthenticatedUserAccessSecuredFieldWhichInitiallyResolvesToArray()
100+
{
101+
$expected = [
102+
'data' => [
103+
'youShallNotSeeThisUnauthenticated' => null,
104+
],
105+
'extensions' => [
106+
'warnings' => [
107+
[
108+
'message' => 'Access denied to this field.',
109+
'locations' => [
110+
[
111+
'line' => 2,
112+
'column' => 3,
113+
],
114+
],
115+
'path' => ['youShallNotSeeThisUnauthenticated'],
116+
],
117+
],
118+
],
119+
];
120+
$query = <<<'EOF'
121+
{
122+
youShallNotSeeThisUnauthenticated {
123+
secretValue
124+
youAreAuthenticated
125+
}
126+
}
127+
EOF;
128+
$this->assertResponse($query, $expected, static::ANONYMOUS_USER, 'access');
129+
}
130+
99131
public function testFullyAuthenticatedUserAccessToUserName()
100132
{
101133
$expected = [

0 commit comments

Comments
 (0)