Skip to content

Commit 4e52511

Browse files
committed
Exclude property from GraphQL filters
This allow to completely hide sensitive, both in GraphQL fields by excluding methods and GraphQL filters by excluding properties.
1 parent 0ec9aa2 commit 4e52511

File tree

4 files changed

+26
-17
lines changed

4 files changed

+26
-17
lines changed

src/Annotation/Exclude.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
namespace GraphQL\Doctrine\Annotation;
66

77
/**
8-
* Annotation used to exclude a method from GraphQL fields.
8+
* Annotation used to exclude a method from GraphQL fields, or a property from GraphQL filters.
99
*
1010
* This should be used to hide sensitive data such as passwords.
1111
*
1212
* @Annotation
13-
* @Target({"METHOD"})
13+
* @Target({"METHOD", "PROPERTY"})
1414
*/
1515
final class Exclude
1616
{

src/Factory/Type/FilterGroupConditionTypeFactory.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace GraphQL\Doctrine\Factory\Type;
66

7+
use GraphQL\Doctrine\Annotation\Exclude;
78
use GraphQL\Doctrine\Annotation\Filter;
89
use GraphQL\Doctrine\Annotation\Filters;
910

@@ -25,6 +26,7 @@
2526
use GraphQL\Type\Definition\LeafType;
2627
use GraphQL\Type\Definition\Type;
2728
use ReflectionClass;
29+
use ReflectionProperty;
2830

2931
/**
3032
* A factory to create an InputObjectType from a Doctrine entity to
@@ -60,6 +62,13 @@ public function create(string $className, string $typeName): Type
6062

6163
// Get all scalar fields
6264
foreach ($metadata->fieldMappings as $mapping) {
65+
66+
// Skip exclusion specified by user
67+
$property = $metadata->getReflectionProperty($mapping['fieldName']);
68+
if ($this->isExcluded($property)) {
69+
continue;
70+
}
71+
6372
if ($mapping['id'] ?? false) {
6473
$leafType = Type::id();
6574
} else {
@@ -275,4 +284,18 @@ private function getOperatorFieldName(string $className): string
275284

276285
return lcfirst($name);
277286
}
287+
288+
/**
289+
* Returns whether the property is excluded
290+
*
291+
* @param ReflectionProperty $property
292+
*
293+
* @return bool
294+
*/
295+
private function isExcluded(ReflectionProperty $property): bool
296+
{
297+
$exclude = $this->getAnnotationReader()->getPropertyAnnotation($property, Exclude::class);
298+
299+
return $exclude !== null;
300+
}
278301
}

tests/Blog/Model/User.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ final class User extends AbstractModel
3434
* @var string
3535
*
3636
* @ORM\Column(name="password", type="string", length=255)
37+
* @Api\Exclude
3738
*/
3839
private $password;
3940

tests/data/PostFilter.graphqls

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,6 @@ input UserFilterGroupCondition {
499499
creationDate: UserFilterGroupConditionCreationDate
500500
name: UserFilterGroupConditionName
501501
email: UserFilterGroupConditionEmail
502-
password: UserFilterGroupConditionPassword
503502
isAdministrator: UserFilterGroupConditionIsAdministrator
504503
id: UserFilterGroupConditionId
505504
posts: UserFilterGroupConditionPosts
@@ -593,20 +592,6 @@ input UserFilterGroupConditionName {
593592
group: GroupOperatorString
594593
}
595594

596-
"""Type to specify a condition on a specific field"""
597-
input UserFilterGroupConditionPassword {
598-
between: BetweenOperatorString
599-
equal: EqualOperatorString
600-
greater: GreaterOperatorString
601-
greaterOrEqual: GreaterOrEqualOperatorString
602-
in: InOperatorString
603-
less: LessOperatorString
604-
lessOrEqual: LessOrEqualOperatorString
605-
like: LikeOperatorString
606-
null: NullOperatorString
607-
group: GroupOperatorString
608-
}
609-
610595
"""Type to specify a condition on a specific field"""
611596
input UserFilterGroupConditionPosts {
612597
have: HaveOperatorID

0 commit comments

Comments
 (0)