/**
  * 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.");
     }
 }
Esempio n. 2
0
 /**
  * Converts list of arguments to named parameters.
  * @param  string  class name
  * @param  string  method name
  * @param  array   arguments
  * @param  array   supplemental arguments
  * @param  ReflectionParameter[]  missing arguments
  * @return void
  * @throws InvalidLinkException
  * @internal
  */
 public static function argsToParams($class, $method, &$args, $supplemental = [], &$missing = [])
 {
     $i = 0;
     $rm = new \ReflectionMethod($class, $method);
     foreach ($rm->getParameters() as $param) {
         list($type, $isClass) = ComponentReflection::getParameterType($param);
         $name = $param->getName();
         if (array_key_exists($i, $args)) {
             $args[$name] = $args[$i];
             unset($args[$i]);
             $i++;
         } elseif (array_key_exists($name, $args)) {
             // continue with process
         } elseif (array_key_exists($name, $supplemental)) {
             $args[$name] = $supplemental[$name];
         }
         if (!isset($args[$name])) {
             if (!$param->isDefaultValueAvailable() && !$param->allowsNull() && $type !== 'NULL' && $type !== 'array') {
                 $missing[] = $param;
                 unset($args[$name]);
             }
             continue;
         }
         if (!ComponentReflection::convertType($args[$name], $type, $isClass)) {
             throw new InvalidLinkException(sprintf('Argument $%s passed to %s() must be %s, %s given.', $name, $rm->getDeclaringClass()->getName() . '::' . $rm->getName(), $type === 'NULL' ? 'scalar' : $type, is_object($args[$name]) ? get_class($args[$name]) : gettype($args[$name])));
         }
         $def = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : NULL;
         if ($args[$name] === $def || $def === NULL && $args[$name] === '') {
             $args[$name] = NULL;
             // value transmit is unnecessary
         }
     }
     if (array_key_exists($i, $args)) {
         throw new InvalidLinkException("Passed more parameters than method {$class}::{$rm->getName()}() expects.");
     }
 }