Skip to content

Commit 86e9500

Browse files
committed
Expression "object" should be available for mutation payload (#35)
* Expression "object" should be available for mutation payload * Locked webonyx/graphql-php to 0.6.0
1 parent a893b05 commit 86e9500

File tree

9 files changed

+143
-12
lines changed

9 files changed

+143
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ Expression | Description | Scope
761761
**request** | Refers to the current request. | Request
762762
**token** | Refers to the token which is currently in the security token storage. | Token
763763
**user** | Refers to the user which is currently in the security token storage. | Valid Token
764-
**object** | Refers to the value of the field for which access is being requested. For array `object` will be each item of the array. For Relay connection `object` will be the node of each connection edges. | only available for `config.fields.*.access` with query operation type.
764+
**object** | Refers to the value of the field for which access is being requested. For array `object` will be each item of the array. For Relay connection `object` will be the node of each connection edges. | only available for `config.fields.*.access` with query operation or mutation payload type.
765765
**value** | Resolver value | only available in resolve context
766766
**args** | Resolver args array | only available in resolve context
767767
**info** | Resolver GraphQL\Type\Definition\ResolveInfo Object | only available in resolve context

Resolver/Config/FieldsConfigSolution.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ private function resolveAccessAndWrapResolveCallback($expression, callable $reso
187187

188188
$info = $values['info'];
189189

190-
if ($info instanceof ResolveInfo && $info->operation->operation === 'mutation') {
190+
// operation is mutation and is mutation field
191+
if ($info instanceof ResolveInfo && $info->operation->operation === 'mutation' && $info->parentType === $info->schema->getMutationType()) {
191192
$checkAccess = $this->checkAccessCallback($expression, $values);
192193
$result = $checkAccess(null, $values) ? call_user_func_array($resolveCallback, $args) : null;
193194
} else {

Tests/Functional/Security/AccessTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Overblog\GraphQLBundle\Tests\Functional\Security;
1313

14+
use Overblog\GraphQLBundle\Tests\Functional\app\Mutation\SimpleMutationWithThunkFieldsMutation;
1415
use Overblog\GraphQLBundle\Tests\Functional\TestCase;
1516

1617
class AccessTest extends TestCase
@@ -37,6 +38,15 @@ class AccessTest extends TestCase
3738
}
3839
}
3940
}
41+
EOF;
42+
43+
private $simpleMutationWithThunkQuery = <<<EOF
44+
mutation M {
45+
simpleMutationWithThunkFields(input: {inputData: %d, clientMutationId: "bac"}) {
46+
result
47+
clientMutationId
48+
}
49+
}
4050
EOF;
4151

4252
public function testNotAuthenticatedUserAccessToUserName()
@@ -131,6 +141,72 @@ public function testUserAccessToUserIsEnabledWithExpressionLanguageEvaluationFai
131141
$this->assertResponse($this->userIsEnabledQuery, $expected, static::USER_ADMIN);
132142
}
133143

144+
public function testMutationAllowedUser()
145+
{
146+
$result = 123;
147+
148+
$expected = [
149+
'data' => [
150+
'simpleMutationWithThunkFields' => [
151+
'result' => $result,
152+
'clientMutationId' => 'bac',
153+
],
154+
],
155+
];
156+
157+
$this->assertResponse(sprintf($this->simpleMutationWithThunkQuery, $result), $expected, static::USER_ADMIN);
158+
$this->assertTrue(SimpleMutationWithThunkFieldsMutation::hasMutate(true));
159+
}
160+
161+
public function testMutationAllowedButNoRightsToDisplayPayload()
162+
{
163+
$expected = [
164+
'data' => [
165+
'simpleMutationWithThunkFields' => [
166+
'result' => null,
167+
'clientMutationId' => 'bac',
168+
],
169+
],
170+
'errors' => [
171+
[
172+
'message' => 'Access denied to this field.',
173+
'locations' => [
174+
[
175+
'line' => 3,
176+
'column' => 5,
177+
],
178+
],
179+
],
180+
],
181+
];
182+
183+
$this->assertResponse(sprintf($this->simpleMutationWithThunkQuery, 321), $expected, static::USER_ADMIN);
184+
$this->assertTrue(SimpleMutationWithThunkFieldsMutation::hasMutate(true));
185+
}
186+
187+
public function testMutationNotAllowedUser()
188+
{
189+
$expected = [
190+
'data' => [
191+
'simpleMutationWithThunkFields' => null,
192+
],
193+
'errors' => [
194+
[
195+
'message' => 'Access denied to this field.',
196+
'locations' => [
197+
[
198+
'line' => 2,
199+
'column' => 3,
200+
],
201+
],
202+
],
203+
],
204+
];
205+
206+
$this->assertResponse(sprintf($this->simpleMutationWithThunkQuery, 123), $expected, static::USER_RYAN);
207+
$this->assertFalse(SimpleMutationWithThunkFieldsMutation::hasMutate(true));
208+
}
209+
134210
private function expectedFailedUserRoles()
135211
{
136212
return [

Tests/Functional/app/Mutation/SimpleMutationWithThunkFieldsMutation.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,28 @@
1313

1414
class SimpleMutationWithThunkFieldsMutation
1515
{
16+
private static $hasMutate = false;
17+
18+
public static function hasMutate($reset = false)
19+
{
20+
$hasMutate = self::$hasMutate;
21+
22+
if ($reset) {
23+
static::resetHasMutate();
24+
}
25+
26+
return $hasMutate;
27+
}
28+
29+
public static function resetHasMutate()
30+
{
31+
self::$hasMutate = false;
32+
}
33+
1634
public function mutate($value)
1735
{
36+
self::$hasMutate = true;
37+
1838
return ['result' => $value['inputData']];
1939
}
2040
}

Tests/Functional/app/config/access/config.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
imports:
22
- { resource: ../config.yml }
33
- { resource: ../connection/services.yml }
4+
- { resource: ../mutation/services.yml }
45

56
overblog_graphql:
67
definitions:
78
schema:
8-
query: Query
9-
mutation: ~
9+
query: RootQuery
10+
mutation: RootMutation
1011
mappings:
1112
types:
1213
-

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
Query:
1+
RootQuery:
2+
type: object
3+
config:
4+
fields:
5+
user:
6+
type: User
7+
resolve: '@=resolver("query")'
8+
9+
Mutation:
210
type: object
311
config:
412
fields:
@@ -40,3 +48,28 @@ friendConnection:
4048
totalCount:
4149
type: Int
4250
resolve: '@=resolver("connection")'
51+
52+
#Mutation
53+
RootMutation:
54+
type: object
55+
config:
56+
fields:
57+
simpleMutationWithThunkFields:
58+
builder: Mutation
59+
access: "@=hasRole('ROLE_ADMIN')"
60+
builderConfig:
61+
inputType: simpleMutationWithThunkFieldsInput
62+
payloadType: simpleMutationWithThunkFieldsPayload
63+
mutateAndGetPayload: "@=mutation('simple_mutation_with_thunk_fields', [value])"
64+
65+
simpleMutationWithThunkFieldsInput:
66+
type: relay-mutation-input
67+
config:
68+
fields:
69+
inputData : { type: "Int" }
70+
71+
simpleMutationWithThunkFieldsPayload:
72+
type: relay-mutation-payload
73+
config:
74+
fields:
75+
result: { type: "Int", access: "@=object === 123" }

Tests/Functional/app/config/mutation/config.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
imports:
22
- { resource: ../config.yml }
3-
4-
services:
5-
overblog_graphql.test.mutation:
6-
class: Overblog\GraphQLBundle\Tests\Functional\app\Mutation\SimpleMutationWithThunkFieldsMutation
7-
tags:
8-
- { name: "overblog_graphql.mutation", alias: "simple_mutation_with_thunk_fields", method: "mutate" }
3+
- { resource: services.yml }
94

105
overblog_graphql:
116
definitions:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
overblog_graphql.test.mutation:
3+
class: Overblog\GraphQLBundle\Tests\Functional\app\Mutation\SimpleMutationWithThunkFieldsMutation
4+
tags:
5+
- { name: "overblog_graphql.mutation", alias: "simple_mutation_with_thunk_fields", method: "mutate" }

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"symfony/expression-language": "^2.7|^3.0",
2222
"symfony/options-resolver": "^2.7|^3.0",
2323
"doctrine/doctrine-cache-bundle": "^1.2",
24-
"webonyx/graphql-php": "^0.6.0",
24+
"webonyx/graphql-php": "0.6.0",
2525
"symfony/property-access": "^2.7|^3.0"
2626
},
2727
"suggest": {

0 commit comments

Comments
 (0)