/** * 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."); } }
/** * @return Nette\Application\IResponse */ public function run(Application\Request $request) { $this->request = $request; if ($this->httpRequest && $this->router && !$this->httpRequest->isAjax() && ($request->isMethod('get') || $request->isMethod('head'))) { $refUrl = clone $this->httpRequest->getUrl(); $url = $this->router->constructUrl($request, $refUrl->setPath($refUrl->getScriptPath())); if ($url !== NULL && !$this->httpRequest->getUrl()->isEqual($url)) { return new Responses\RedirectResponse($url, Http\IResponse::S301_MOVED_PERMANENTLY); } } $params = $request->getParameters(); if (!isset($params['callback'])) { throw new Application\BadRequestException('Parameter callback is missing.'); } $callback = $params['callback']; $reflection = Nette\Utils\Callback::toReflection(Nette\Utils\Callback::check($callback)); if ($this->context) { foreach ($reflection->getParameters() as $param) { if ($param->getClass()) { $params[$param->getName()] = $this->context->getByType($param->getClass()->getName(), FALSE); } } } $params['presenter'] = $this; $params = Application\UI\ComponentReflection::combineArgs($reflection, $params); $response = call_user_func_array($callback, $params); if (is_string($response)) { $response = [$response, []]; } if (is_array($response)) { list($templateSource, $templateParams) = $response; $response = $this->createTemplate()->setParameters($templateParams); if (!$templateSource instanceof \SplFileInfo) { $response->getLatte()->setLoader(new Latte\Loaders\StringLoader()); } $response->setFile($templateSource); } if ($response instanceof Application\UI\ITemplate) { return new Responses\TextResponse($response); } else { return $response; } }
/** * Returns an annotation value. * @param string * @return string|NULL */ public function getAnnotation($name) { $res = ComponentReflection::parseAnnotation($this, $name); return $res ? end($res) : NULL; }
/** * Returns array of persistent components. * This default implementation detects components by class-level annotation @persistent(cmp1, cmp2). * @return array */ public static function getPersistentComponents() { return (array) ComponentReflection::parseAnnotation(new \ReflectionClass(get_called_class()), 'persistent'); }
/** * Returns array of classes persistent parameters. They have public visibility and are non-static. * This default implementation detects persistent parameters by annotation @persistent. * @return array */ public static function getPersistentParams() { $rc = new \ReflectionClass(get_called_class()); $params = []; foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) { if (!$rp->isStatic() && ComponentReflection::parseAnnotation($rp, 'persistent')) { $params[] = $rp->getName(); } } return $params; }