1212use Roave \BetterReflection \Reflection \ReflectionMethod ;
1313use Doctrine \Common \Annotations \Reader ;
1414use phpDocumentor \Reflection \Types \Integer ;
15+ use TheCodingMachine \GraphQL \Controllers \Annotations \Logged ;
1516use TheCodingMachine \GraphQL \Controllers \Annotations \Mutation ;
1617use TheCodingMachine \GraphQL \Controllers \Annotations \Query ;
18+ use TheCodingMachine \GraphQL \Controllers \Annotations \Right ;
19+ use TheCodingMachine \GraphQL \Controllers \Security \AuthenticationServiceInterface ;
20+ use TheCodingMachine \GraphQL \Controllers \Security \AuthorizationServiceInterface ;
1721use Youshido \GraphQL \Field \Field ;
1822use Youshido \GraphQL \Type \ListType \ListType ;
1923use Youshido \GraphQL \Type \NonNullType ;
@@ -43,16 +47,26 @@ class ControllerQueryProvider implements QueryProviderInterface
4347 * @var HydratorInterface
4448 */
4549 private $ hydrator ;
50+ /**
51+ * @var AuthenticationServiceInterface
52+ */
53+ private $ authenticationService ;
54+ /**
55+ * @var AuthorizationServiceInterface
56+ */
57+ private $ authorizationService ;
4658
4759 /**
4860 * @param object $controller
4961 */
50- public function __construct ($ controller , Reader $ annotationReader , TypeMapperInterface $ typeMapper , HydratorInterface $ hydrator )
62+ public function __construct ($ controller , Reader $ annotationReader , TypeMapperInterface $ typeMapper , HydratorInterface $ hydrator, AuthenticationServiceInterface $ authenticationService , AuthorizationServiceInterface $ authorizationService )
5163 {
5264 $ this ->controller = $ controller ;
5365 $ this ->annotationReader = $ annotationReader ;
5466 $ this ->typeMapper = $ typeMapper ;
5567 $ this ->hydrator = $ hydrator ;
68+ $ this ->authenticationService = $ authenticationService ;
69+ $ this ->authorizationService = $ authorizationService ;
5670 }
5771
5872 /**
@@ -84,7 +98,12 @@ private function getFieldsByAnnotations(string $annotationName): array
8498 $ standardPhpMethod = new \ReflectionMethod (get_class ($ this ->controller ), $ refMethod ->getName ());
8599 // First, let's check the "Query" annotation
86100 $ queryAnnotation = $ this ->annotationReader ->getMethodAnnotation ($ standardPhpMethod , $ annotationName );
101+
87102 if ($ queryAnnotation !== null ) {
103+ if (!$ this ->isAuthorized ($ standardPhpMethod )) {
104+ continue ;
105+ }
106+
88107 $ methodName = $ refMethod ->getName ();
89108
90109 $ args = $ this ->mapParameters ($ refMethod , $ standardPhpMethod );
@@ -98,6 +117,30 @@ private function getFieldsByAnnotations(string $annotationName): array
98117 return $ queryList ;
99118 }
100119
120+ /**
121+ * Checks the @Logged and @Right annotations.
122+ *
123+ * @param \ReflectionMethod $reflectionMethod
124+ * @return bool
125+ */
126+ private function isAuthorized (\ReflectionMethod $ reflectionMethod ) : bool
127+ {
128+ $ loggedAnnotation = $ this ->annotationReader ->getMethodAnnotation ($ reflectionMethod , Logged::class);
129+
130+ if ($ loggedAnnotation !== null && !$ this ->authenticationService ->isLogged ()) {
131+ return false ;
132+ }
133+
134+ $ rightAnnotation = $ this ->annotationReader ->getMethodAnnotation ($ reflectionMethod , Right::class);
135+ /** @var $rightAnnotation Right */
136+
137+ if ($ rightAnnotation !== null && !$ this ->authorizationService ->isAllowed ($ rightAnnotation ->getName ())) {
138+ return false ;
139+ }
140+
141+ return true ;
142+ }
143+
101144 /**
102145 * Note: there is a bug in $refMethod->allowsNull that forces us to use $standardRefMethod->allowsNull instead.
103146 *
@@ -183,7 +226,7 @@ private function toGraphQlType(Type $type): TypeInterface
183226 */
184227 private function typesWithoutNullable (array $ docBlockTypeHints ): array
185228 {
186- return array_filter ($ docBlockTypeHints , function ($ item ) {
229+ return array_filter ($ docBlockTypeHints , function ($ item ) {
187230 return !$ item instanceof Null_;
188231 });
189232 }
0 commit comments