/** * 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."); } }
/** * 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); }
public function __invoke(\DateTime $now) { $this->method->invoke($this->object); $this->timestampStorage->setTaskName($this->getName()); $this->timestampStorage->saveRunTime($now); $this->timestampStorage->setTaskName(); }
/** * @param Method $element * @throws \Flame\Rest\Security\ForbiddenRequestException */ public function authenticate(Method $element) { $user = (array) $element->getAnnotation('User'); if (in_array('loggedIn', $user)) { if (!$this->user->isLoggedIn()) { throw new ForbiddenRequestException('Please sign in.'); } } }
/** * @param Method $method * @param $secured * @return null|string */ protected function getSchemaOfResource(Method $method, $secured) { $ret = isset($secured['resource']) ? $secured['resource'] : NULL; if (!$ret) { $s = $method->getDeclaringClass()->getAnnotation('secured'); $ret = isset($s['resource']) ? $s['resource'] : $method->getDeclaringClass()->getName(); } return $ret; }
/** * Validates, if argument has its annotation and converts it to defined type. * * @param mixed $argument * @param int $i * @return mixed * @throws InvalidEventArgumentDefinitionException * @throws InvalidEventArgumentTypeException * @throws InvalidEventArgumentValueException */ private function validateArgument($argument, $i) { $annotations = $this->annotations; if (!isset($annotations['param'][$i])) { throw new InvalidEventArgumentDefinitionException('Not all parameters have their own @param annotation at method ' . $this->method->getName() . '.'); } $annotation = $annotations['param'][$i]; return $this->convertToType($argument, $annotation); }
private function getMethodExpressionsToEvaluate(Method $method) { $annotation = $method->getAnnotation('Security'); if ($annotation) { if (!is_string($annotation)) { throw new \InvalidArgumentException('Security annotation must be simple string with expression.'); } return [new Expression($annotation)]; } return []; }
/** * @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; }
/** * @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, ); }
/** * Create definition statement for method * @param ServiceDefinition $definition * @param \Nette\Reflection\Method $method */ protected function autowireParams(ServiceDefinition $definition, \Nette\Reflection\Method $method) { $parameters = $method->getParameters(); foreach ($parameters as $num => $param) { /** @var \Nette\Reflection\Parameter $param */ if ($targetClass = $param->getClass()) { if ($targetClass->getName() === 'Kdyby\\Doctrine\\EntityDao' && !isset($definition->factory->arguments[$num])) { $annotations = $method->getAnnotations(); $entity = $this->getEntityName($param, $annotations); if ($definition->factory === NULL) { $definition->setFactory($definition->class); } $definition->factory->arguments[$num] = new \Nette\DI\Statement('@doctrine.dao', array($entity)); } } } }
/** * 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; }
private function addComponentFactories(array $factories) { $builder = $this->getContainerBuilder(); foreach ($factories as $component => $factory) { if (strpos($factory, '::') === FALSE) { $factory .= '::' . self::DEFAULT_FACTORY_METHOD; } if ($builder->hasDefinition($name = $this->prefix('registry.' . $component))) { $definition = $builder->getDefinition($name); } else { $definition = $builder->addDefinition($name)->addTag(self::TAG_COMPONENT_REGISTRY, $component)->setAutowired(FALSE); } list($class, $method) = explode('::', $factory); if (!Method::from($class, $method)->isStatic()) { $factory = '@' . $factory; } $definition->setFactory($factory); } }
/** * @author Jiří Šifalda * @param string * @return \Nette\Application\UI\Multiplier|\Nette\ComponentModel\IComponent */ protected function createComponent($name) { $method = 'createComponent' . ucfirst($name); if (method_exists($this, $method)) { $this->checkRequirements($this->getReflection()->getMethod($method)); if (\Nette\Reflection\Method::from($this, $method)->hasAnnotation('multiple')) { $presenter = $this; return new \Nette\Application\UI\Multiplier(function ($id) use($presenter, $method) { $defaultArgs = array($presenter, $id); return call_user_func_array(array($presenter, $method), $defaultArgs); }); # in PHP 5.4 factory for multiplied component can be protected # return new UI\Multiplier(function ($id) use ($name) { # return $this->$method($this, $id, $this->getDataset($name)); # }); } } return parent::createComponent($name); }
/** * @return Method|NULL */ public function getConstructor() { return ($ref = parent::getConstructor()) ? Method::from($this->getName(), $ref->getName()) : NULL; }
/** * Invokes function using named parameters. * @param array * @return mixed */ public function invokeNamedArgs($args) { return $this->invokeArgs(Method::combineArgs($this->getDefaultParameters(), $args)); }
/** * @param Property $prop * @throws MissingServiceException * @throws UnexpectedValueException */ private function resolveProperty(Property $prop) { $type = $this->resolveAnnotationClass($prop, $prop->getAnnotation('var'), 'var'); $metadata = ['value' => NULL, 'type' => $type]; if (($args = (array) $prop->getAnnotation('autowire')) && !empty($args['factory'])) { $factoryType = $this->resolveAnnotationClass($prop, $args['factory'], 'autowire'); if (!$this->findByTypeForProperty($factoryType)) { throw new MissingServiceException("Factory of type \"{$factoryType}\" not found for {$prop} in annotation @autowire.", $prop); } $factoryMethod = Method::from($factoryType, 'create'); $createsType = $this->resolveAnnotationClass($factoryMethod, $factoryMethod->getAnnotation('return'), 'return'); if ($createsType !== $type) { throw new UnexpectedValueException("The property {$prop} requires {$type}, but factory of type {$factoryType}, that creates {$createsType} was provided.", $prop); } unset($args['factory']); $metadata['arguments'] = array_values($args); $metadata['factory'] = $this->findByTypeForProperty($factoryType); } elseif (!$this->findByTypeForProperty($type)) { throw new MissingServiceException("Service of type \"{$type}\" not found for {$prop} in annotation @var.", $prop); } // unset property to pass control to __set() and __get() unset($this->{$prop->getName()}); $this->autowireProperties[$prop->getName()] = $metadata; }
/** * Generates link. If links points to @secure annotated signal handler method, additonal * parameter preventing changing parameters will be added. * * @param string * @param array|mixed $args * @return string */ public function link($destination, $args = array()) { if (!is_array($args)) { $args = func_get_args(); array_shift($args); } $link = parent::link($destination, $args); $lastRequest = $this->getPresenter()->getLastCreatedRequest(); // bad link if ($lastRequest === NULL) { return $link; } // not a signal if (substr($destination, -1) !== '!') { return $link; } // signal must lead to this presenter if ($this->getPresenter()->getName() !== $lastRequest->getPresenterName()) { return $link; } $destination = str_replace(':', '-', $destination); if (strpos($destination, '-') !== FALSE) { $pos = strrpos($destination, '-'); $signal = substr($destination, $pos + 1, -1); $component = substr($destination, 0, $pos); $component = $this->getComponent($component); } else { $signal = substr($destination, 0, -1); $component = $this; } // only components if (!$component instanceof PresenterComponent) { return $link; } $method = $component->formatSignalMethod($signal); $reflection = Method::from($component, $method); // does not have annotation if (!$reflection->hasAnnotation('secured')) { return $link; } $origParams = $lastRequest->getParameters(); $protectedParams = array(); foreach ($reflection->getParameters() as $param) { if ($param->isOptional()) { continue; } $protectedParams[$param->name] = $origParams[$component->getParameterId($param->name)]; } $uniqueId = $this->getUniqueId(); if (empty($uniqueId)) { $paramName = $component->getParameterId('__sec'); } else { $paramName = substr($component->getParameterId('__sec'), strlen($uniqueId) + 1); } $args[$paramName] = $this->createSecureHash($protectedParams); return parent::link($destination, $args); }
/** * @param $name * @return Nette\ComponentModel\IComponent * @throws Nette\UnexpectedValueException */ protected function createComponent($name) { $sl = $this->getComponentFactoriesLocator(); $ucName = ucfirst($name); $method = 'createComponent' . $ucName; if ($ucName !== $name && method_exists($this, $method)) { $methodReflection = new Method($this, $method); if ($methodReflection->getName() !== $method) { return; } $parameters = $methodReflection->getParameters(); $args = []; if (($first = reset($parameters)) && !$first->className) { $args[] = $name; } $args = Nette\DI\Helpers::autowireArguments($methodReflection, $args, $sl); $component = call_user_func_array([$this, $method], $args); if (!$component instanceof Nette\ComponentModel\IComponent && !isset($this->components[$name])) { throw new Nette\UnexpectedValueException("Method {$methodReflection} did not return or create the desired component."); } return $component; } }
/** * @param \Nette\Reflection\Method $element * @return bool */ protected function isMethodAllowed(\Nette\Reflection\Method $element) { $classRef = new \Nette\Application\UI\PresenterComponentReflection($element->class); $ref = ClassType::from($element->class); if (!$this->isPresenterAllowedCached($classRef)) { return FALSE; } $ref = $ref->getMethod($element->name); // is not secured if (!$ref->hasAnnotation('secured')) { return TRUE; } // resource & privilege $secured = $ref->getAnnotation('secured'); $resource = isset($secured['resource']) ? $secured['resource'] : NULL; if (!$resource) { $s = $classRef->getAnnotation('secured'); $resource = isset($s['resource']) ? $s['resource'] : $classRef->getNamespaceName(); } $privilege = isset($secured['privilege']) ? $secured['privilege'] : $element->name; if (!parent::isAllowed($resource, $privilege)) { return FALSE; } // roles if (isset($secured['roles'])) { $userRoles = $this->getRoles(); $roles = explode(',', $secured['roles']); array_walk($roles, function (&$val) { $val = trim($val); }); if (count(array_intersect($userRoles, $roles)) == 0) { return FALSE; } } // users if (isset($secured['users'])) { $users = explode(',', $secured['users']); array_walk($users, function (&$val) { $val = trim($val); }); $users = (array) $element->getAnnotation('User'); if (in_array($this->getId(), $users)) { return FALSE; } } return TRUE; }
getPersistentComponents($class=NULL){$class=$class===NULL?$this->getName():$class;$components=&self::$pcCache[$class];if($components!==NULL){return$components;}$components=array();if(is_subclass_of($class,'Nette\Application\UI\Presenter')){foreach(call_user_func(array($class,'getPersistentComponents'),$class)as$name=>$meta){if(is_string($meta)){$name=$meta;}$components[$name]=array('since'=>$class);}$components=$this->getPersistentComponents(get_parent_class($class))+$components;}return$components;}function hasCallableMethod($method){$class=$this->getName();$cache=&self::$mcCache[strtolower($class.':'.$method)];if($cache===NULL)try{$cache=FALSE;$rm=Nette\Reflection\Method::from($class,$method);$cache=$this->isInstantiable()&&$rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic();}catch(\ReflectionException$e){}return$cache;}static
public function testGetFailedExpression_evaluatorReturnsFalse_returnsExpressionThatFailed() { $request = \Mockery::mock(Request::class); $this->evaluator->shouldReceive('evaluate')->andReturn(false); $methodReflection = Method::from(TestDerivedClass::class, 'testMethod'); $result = $this->checker->checkRequirement($methodReflection, $request); $this->assertFalse($result); $this->assertEquals('method', (string) $this->checker->getFailedExpression()); }
/** * @param \MyTester\Job $job * @return string */ protected function runJob(Job $job) { $jobName = $this->getJobName(\Nette\Reflection\Method::from($job->callback[0], $job->callback[1])); Environment::$currentJob = $jobName; if (!$job->skip) { $this->setUp(); } $job->execute(); if (!$job->skip) { $this->tearDown(); } Environment::$currentJob = ""; switch ($job->result) { case "passed": return "."; break; case "skipped": return "s"; break; case "failed": return "F"; break; } return ""; }
/** * @return array */ public function getParameterNames() { return array_keys($this->method->getParameters()); }
/** * Gains possible return type from the `return` method annotation. * * @param string $className * @param string $methodName * @return array */ public static function getReturnTypes($className, $methodName) { $methodName = Method::from($className, $methodName); list($types) = preg_split('~\\s~', $methodName->getAnnotation('return'), 2); return explode('|', $types); }
/** * 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; }
/** * Is a method callable? It means class is instantiable and method has * public visibility, is non-static and non-abstract. * @param string method name * @return bool */ public function hasCallableMethod($method) { $class = $this->getName(); $cache =& self::$mcCache[strtolower($class . ':' . $method)]; if ($cache === NULL) { try { $cache = FALSE; $rm = Nette\Reflection\Method::from($class, $method); $cache = $this->isInstantiable() && $rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic(); } catch (\ReflectionException $e) { } } return $cache; }
/** * Checks if given method has a given annotation * * @param string $method * @param string $annotation * @return bool */ protected function hasMethodAnnotation($method, $annotation) { if (!$this->getReflection()->hasMethod($method)) { return FALSE; } $rm = Method::from($this->getReflection()->getName(), $method); return $rm->hasAnnotation($annotation); }
private function runDetectFormatMethod($route, $request) { $method = new Method($route, 'detectFormat'); $method->setAccessible(TRUE); return $method->invoke($route, $request); }
/** * Converts list of arguments to named parameters. * @param string class name * @param string method name * @param array arguments * @param array supplemental arguments * @return void * @throws InvalidLinkException */ private static function argsToParams($class, $method, &$args, $supplemental = array()) { static $cache; $params =& $cache[strtolower($class . ':' . $method)]; if ($params === NULL) { $params = Reflection\Method::from($class, $method)->getDefaultParameters(); } $i = 0; foreach ($params as $name => $def) { 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]; } else { continue; } if ($def === NULL) { if ((string) $args[$name] === '') { $args[$name] = NULL; // value transmit is unnecessary } } else { settype($args[$name], gettype($def)); if ($args[$name] === $def) { $args[$name] = NULL; } } } if (array_key_exists($i, $args)) { $method = Reflection\Method::from($class, $method)->getName(); throw new InvalidLinkException("Passed more parameters than method {$class}::{$method}() expects."); } }