Example #1
0
 public function convertMethodAnnotations(\ReflectionMethod $method, array $annotations)
 {
     $parameters = array();
     foreach ($method->getParameters() as $index => $parameter) {
         $parameters[$parameter->getName()] = $index;
     }
     $methodMetadata = new MethodMetadata($method->getDeclaringClass()->getName(), $method->getName());
     foreach ($annotations as $annotation) {
         if ($annotation instanceof Secure) {
             $methodMetadata->roles = $annotation->roles;
         } else {
             if ($annotation instanceof SecureParam) {
                 if (!isset($parameters[$annotation->name])) {
                     throw new \InvalidArgumentException(sprintf('The parameter "%s" does not exist for method "%s".', $annotation->name, $method->getName()));
                 }
                 $methodMetadata->addParamPermissions($parameters[$annotation->name], $annotation->permissions);
             } else {
                 if ($annotation instanceof SecureReturn) {
                     $methodMetadata->returnPermissions = $annotation->permissions;
                 } else {
                     if ($annotation instanceof SatisfiesParentSecurityPolicy) {
                         $methodMetadata->satisfiesParentSecurityPolicy = true;
                     } else {
                         if ($annotation instanceof RunAs) {
                             $methodMetadata->runAsRoles = $annotation->roles;
                         }
                     }
                 }
             }
         }
     }
     return $methodMetadata;
 }
 private function getMethodSecurityMetadata(MethodMetadata $method)
 {
     $metadata = var_export($method->getAsArray(), true);
     $staticReplaces = array("\n" => '', 'array (' => 'array(');
     $metadata = strtr($metadata, $staticReplaces);
     $regexReplaces = array('/\\s+/' => ' ', '/\\(\\s+/' => '(', '/[0-9]+\\s+=>\\s+/' => '', '/,\\s*\\)/' => ')');
     $metadata = preg_replace(array_keys($regexReplaces), array_values($regexReplaces), $metadata);
     return $metadata;
 }
 private function convertMethodAnnotations(\ReflectionMethod $method, array $annotations, PreAuthorize $classPreAuthorize = null)
 {
     $parameters = array();
     foreach ($method->getParameters() as $index => $parameter) {
         $parameters[$parameter->getName()] = $index;
     }
     $methodMetadata = new MethodMetadata($method->class, $method->name);
     $hasSecurityMetadata = $hasPreRestrictions = false;
     foreach ($annotations as $annotation) {
         if ($annotation instanceof Secure) {
             $methodMetadata->roles = $annotation->roles;
             $hasSecurityMetadata = $hasPreRestrictions = true;
         } elseif ($annotation instanceof PreAuthorize) {
             $methodMetadata->roles = array(new Expression($annotation->expr));
             $hasSecurityMetadata = $hasPreRestrictions = true;
         } elseif ($annotation instanceof SecureParam) {
             if (!isset($parameters[$annotation->name])) {
                 throw new InvalidArgumentException(sprintf('The parameter "%s" does not exist for method "%s".', $annotation->name, $method->name));
             }
             $methodMetadata->addParamPermissions($parameters[$annotation->name], $annotation->permissions);
             $hasSecurityMetadata = $hasPreRestrictions = true;
         } elseif ($annotation instanceof SecureReturn) {
             $methodMetadata->returnPermissions = $annotation->permissions;
             $hasSecurityMetadata = true;
         } elseif ($annotation instanceof SatisfiesParentSecurityPolicy) {
             $methodMetadata->satisfiesParentSecurityPolicy = true;
             $hasSecurityMetadata = true;
         } elseif ($annotation instanceof RunAs) {
             $methodMetadata->runAsRoles = $annotation->roles;
             $hasSecurityMetadata = true;
         }
     }
     // We use the following conditions to determine whether we should apply
     // a class-level @PreAuthorize annotation:
     //
     //    - No other authorization that runs before the method invocation
     //      must be configured. @Secure, @SecureParam, @PreAuthorize must
     //      not be present; @SecureReturn would be fine though.
     //
     //    - The method must be public, or alternatively publicOnly on
     //      @PreAuthorize must be set to false.
     if (!$hasPreRestrictions && $classPreAuthorize && (!$classPreAuthorize->publicOnly || !$method->isProtected())) {
         $methodMetadata->roles = array(new Expression($classPreAuthorize->expr));
         $hasSecurityMetadata = true;
     }
     return $hasSecurityMetadata ? $methodMetadata : null;
 }
Example #4
0
 private function normalizeMetadata()
 {
     $secureMethods = array();
     foreach ($this->metadata->classMetadata as $class) {
         if ($class->reflection->isFinal()) {
             throw new \RuntimeException('Final classes cannot be secured.');
         }
         foreach ($class->methodMetadata as $name => $method) {
             if ($method->reflection->isStatic() || $method->reflection->isFinal()) {
                 throw new \RuntimeException('Annotations cannot be defined on final, or static methods.');
             }
             if (!isset($secureMethods[$name])) {
                 $this->metadata->addMethodMetadata($method);
                 $secureMethods[$name] = $method;
             } else {
                 if ($method->reflection->isAbstract()) {
                     $secureMethods[$name]->merge($method);
                 } else {
                     if (false === $secureMethods[$name]->satisfiesParentSecurityPolicy && $method->reflection->getDeclaringClass()->getName() !== $secureMethods[$name]->reflection->getDeclaringClass()->getName()) {
                         throw new \RuntimeException(sprintf('Unresolved security metadata conflict for method "%s::%s" in "%s". Please copy the respective annotations, and add @SatisfiesParentSecurityPolicy to the child method.', $secureMethods[$name]->reflection->getDeclaringClass()->getName(), $name, $secureMethods[$name]->reflection->getDeclaringClass()->getFileName()));
                     }
                 }
             }
         }
     }
     foreach ($secureMethods as $name => $method) {
         if ($method->reflection->isAbstract()) {
             $previous = null;
             $abstractClass = $method->reflection->getDeclaringClass()->getName();
             foreach ($this->hierarchy as $refClass) {
                 if ($abstractClass === ($fqcn = $refClass->getName())) {
                     $methodMetadata = new MethodMetadata($previous->getName(), $name);
                     $methodMetadata->merge($method);
                     $this->metadata->addMethodMetadata($methodMetadata);
                     continue 2;
                 }
                 if (!$refClass->isInterface() && $this->hasMethod($refClass, $name)) {
                     $previous = $refClass;
                 }
             }
         }
     }
 }