/** * {@inheritdoc} */ public function isAllowed($role, $resource, $privilege) { if ($role instanceof IRole) { $role = $role->getRoleId(); } if (!$resource instanceof PresenterResource) { throw new \Ark8\Security\Exceptions\SkipException(sprintf('Resource must be instance of %s, %s given.', PresenterResource::class, gettype($resource))); } $request = $resource->getRequest(); $presenterName = $request->getPresenterName(); list($signal, $signalReceiver) = $this->getSignal($request); if (!$signal) { throw new \Ark8\Security\Exceptions\SkipException(sprintf('No signal sent.')); } $refClass = new PresenterComponentReflection($class = $this->presenterFactory->getPresenterClass($presenterName)); while ($name = array_shift($signalReceiver)) { $name = 'createComponent' . ucfirst($name); if (!$refClass->hasMethod($name)) { throw new \Nette\InvalidStateException(sprintf('Method %s::%s is not implemented.', $refClass->getName(), $name)); } $refMethod = $refClass->getMethod($name); if (!$refMethod->hasAnnotation('return')) { throw new \Nette\InvalidStateException(sprintf('Method %s::%s must have fully qualified return annotation.', $refClass->getName(), $name)); } $refClass = new ClassType($refMethod->getAnnotation('return')); } if (!$refClass->hasMethod($name = Presenter::formatSignalMethod($signal))) { throw new \Ark8\Security\Exceptions\SkipException(sprintf('Method %s::%s is not implemented.', $refClass->getName(), $name)); } $refMethod = $refClass->getMethod($name); if (!$refMethod->hasAnnotation($privilege)) { throw new \Ark8\Security\Exceptions\SkipException(sprintf('Method %s::%s does not have annotation %s.', $refClass->getName(), $name, $privilege)); } return in_array($role, preg_split('#\\s+#', trim((string) $refMethod->getAnnotation($privilege)))); }