/** * @param string * @param string * @return array */ public static function parseAnnotations($class, $method = NULL) { if (strpos($class, '::') !== FALSE && !$method) { list($class, $method) = explode('::', $class); } $ref = new Reflection\Method($class, $method); $cRef = new Reflection\ClassType($class); $anntations = (array)$ref->getAnnotation('allowed'); $role = isset($anntations['role']) ? $anntations['role'] : ($ref->hasAnnotation('role') ? $ref->getAnnotation('role') : NULL); $resource = isset($anntations['resource']) ? $anntations['resource'] : ($ref->hasAnnotation('resource') ? $ref->getAnnotation('resource') : ($cRef->hasAnnotation('resource') ? $cRef->getAnnotation('resource') : NULL)); $privilege = isset($anntations['privilege']) ? $anntations['privilege'] : ($ref->hasAnnotation('privilege') ? $ref->getAnnotation('privilege') : NULL); return array( static::ROLE => $role, static::RESOURCE => $resource, static::PRIVILEGE => $privilege, ); }
/** * Request/URL factory. * @param Component base * @param string destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" * @param array array of arguments * @param string forward|redirect|link * @return string URL * @throws InvalidLinkException * @internal */ protected function createRequest($component, $destination, array $args, $mode) { if (!$component instanceof self || substr($destination, -1) === '!') { // check if signal must be secured $signal = strtr(rtrim($destination, '!'), ':', '-'); $method = $component->formatSignalMethod($signal); $signalMethodReflection = new Nette\Reflection\Method($component, $method); if (!$signalMethodReflection->hasAnnotation('secured')) { goto parent; } // gather args, create hash and append to args $namedArgs = $args; self::argsToParams($this, $method, $namedArgs); // convert indexed args to named args $protectedParams = array($component->getUniqueId()); foreach ($signalMethodReflection->getParameters() as $param) { if ($param->isOptional()) { continue; } if (isset($namedArgs[$component->getParameterId($param->name)])) { $protectedParams[$param->name] = $namedArgs[$component->getParameterId($param->name)]; } } $args['_sec'] = $this->getCsrfToken(get_class($component), $method, $protectedParams); } parent: return parent::createRequest($component, $destination, $args, $mode); }
/** * For @secured annotated signal handler methods checks if URL parameters has not been changed * * @param string $signal * @throws Nette\Application\UI\BadSignalException if there is no handler method or the security token does not match * @throws \LogicException if there is no redirect in a secured signal */ public function signalReceived($signal) { $method = $this->formatSignalMethod($signal); $secured = FALSE; if (method_exists($this, $method)) { $reflection = new Nette\Reflection\Method($this, $method); $secured = $reflection->hasAnnotation('secured'); if ($secured) { $params = array($this->getUniqueId()); if ($this->params) { foreach ($reflection->getParameters() as $param) { if ($param->isOptional()) { continue; } if (isset($this->params[$param->name])) { $params[$param->name] = $this->params[$param->name]; list($type, $isClass) = Nette\Application\UI\ComponentReflection::getParameterType($param); Nette\Application\UI\ComponentReflection::convertType($params[$param->name], $type, $isClass); } } } if (!isset($this->params['_sec']) || $this->params['_sec'] !== $this->getPresenter()->getCsrfToken(get_class($this), $method, $params)) { throw new Nette\Application\UI\BadSignalException("Invalid security token for signal '{$signal}' in class {$this->getReflection()->name}."); } } } parent::signalReceived($signal); if ($secured && !$this->getPresenter()->isAjax()) { throw new \LogicException("Secured signal '{$signal}' did not redirect. Possible csrf-token reveal by http referer header."); } }
/** * @param Method $reflection * @return array * * @throws InvalidArgumentException */ public function parse($reflection) { if (!$reflection instanceof Method) { throw new InvalidArgumentException('RouteAnnotation can be parsed only on method'); } $result = array(); foreach ($this->methods as $methodName => $methodFlag) { if ($reflection->hasAnnotation($methodName)) { $result[$methodFlag] = $reflection->getAnnotation($methodName); } } return $result; }
/** * Creates method list * (may take a time..) * * @return array */ public function createMethodList() { /** @var $robotLoader RobotLoader */ $robotLoader = $this->context->getService('robotLoader'); foreach ($robotLoader->getIndexedClasses() as $class => $file) { if (Strings::match($file, "~\\Nette~")) { continue; } $creflection = new Nette\Reflection\ClassType($class); foreach ($creflection->getMethods() as $method) { $mreflection = new Method($class, $method->getName()); if ($mreflection->hasAnnotation('cron')) { $m = new stdClass(); $m->name = $mreflection->getName(); $m->class = $mreflection->getDeclaringClass()->getName(); $m->annotations = $mreflection->getAnnotations(); $this->methods[] = $m; } } } return $this->methods; }
/** * Parse cronner values from annotations. * * @param \Nette\Reflection\Method $method * @return array */ public static function parseParameters(Method $method) { $taskName = NULL; if ($method->hasAnnotation(Parameters::TASK)) { $className = $method->getDeclaringClass()->getName(); $methodName = $method->getName(); $taskName = $className . ' - ' . $methodName; } $parameters = array(static::TASK => Parser::parseName($method->getAnnotation(Parameters::TASK)) ?: $taskName, static::PERIOD => $method->hasAnnotation(Parameters::PERIOD) ? Parser::parsePeriod($method->getAnnotation(Parameters::PERIOD)) : NULL, static::DAYS => $method->hasAnnotation(Parameters::DAYS) ? Parser::parseDays($method->getAnnotation(Parameters::DAYS)) : NULL, static::TIME => $method->hasAnnotation(Parameters::TIME) ? Parser::parseTimes($method->getAnnotation(Parameters::TIME)) : NULL); return $parameters; }
/** * Get name for a job * * @param \Nette\Reflection\Method $method * @return string */ protected function getJobName(\Nette\Reflection\Method $method) { if ($method->hasAnnotation("test")) { return (string) $method->getAnnotation("test"); } else { return $this->getSuitName() . "::" . $method->getName(); } }