Pārlūkot izejas kodu

[SecurityBundle] added validation for check paths

Johannes M. Schmitt 14 gadi atpakaļ
vecāks
revīzija
6f8871d2d7

+ 30 - 0
src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php

@@ -11,6 +11,8 @@
 
 namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
 
+use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory;
+
 use Symfony\Component\Config\Definition\Builder\TreeBuilder;
 use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
 use Symfony\Component\Config\Definition\ConfigurationInterface;
@@ -242,6 +244,7 @@ class MainConfiguration implements ConfigurationInterface
             ->end()
         ;
 
+        $abstractFactoryKeys = array();
         foreach ($factories as $factoriesAtPosition) {
             foreach ($factoriesAtPosition as $factory) {
                 $name = str_replace('-', '_', $factory->getKey());
@@ -249,9 +252,36 @@ class MainConfiguration implements ConfigurationInterface
                     ->canBeUnset()
                 ;
 
+                if ($factory instanceof AbstractFactory) {
+                    $abstractFactoryKeys[] = str_replace('-', '_', $factory->getKey());
+                }
+
                 $factory->addConfiguration($factoryNode);
             }
         }
+
+        // check for unreachable check paths
+        $firewallNodeBuilder
+            ->end()
+            ->validate()
+                ->ifTrue(function($v) {
+                    return true === $v['security'] && isset($v['pattern']) && !isset($v['request_matcher']);
+                })
+                ->then(function($firewall) use($abstractFactoryKeys) {
+                    foreach ($abstractFactoryKeys as $k) {
+                        if (!isset($firewall[$k]['check_path'])) {
+                            continue;
+                        }
+
+                        if (!preg_match('#'.$firewall['pattern'].'#', $firewall[$k]['check_path'])) {
+                            throw new \Exception(sprintf('The check_path "%s" for login method "%s" is not matched by the firewall pattern "%s".', $firewall[$k]['check_path'], $k, $firewall['pattern']));
+                        }
+                    }
+
+                    return $firewall;
+                })
+            ->end()
+        ;
     }
 
     private function addProvidersSection(ArrayNodeDefinition $rootNode)

+ 0 - 2
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php

@@ -12,9 +12,7 @@
 namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
 
 use Symfony\Component\Config\Definition\Builder\NodeDefinition;
-
 use Symfony\Component\DependencyInjection\DefinitionDecorator;
-
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\DependencyInjection\Parameter;
 use Symfony\Component\DependencyInjection\ContainerBuilder;

+ 1 - 1
src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

@@ -387,7 +387,7 @@ class SecurityExtension extends Extension
         }
 
         if (false === $hasListeners) {
-            throw new \LogicException(sprintf('No authentication listener registered for pattern "%s".', isset($firewall['pattern']) ? $firewall['pattern'] : ''));
+            throw new \LogicException(sprintf('No authentication listener registered for firewall "%s".', $id));
         }
 
         return array($listeners, $defaultEntryPoint);

+ 5 - 1
src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php

@@ -39,10 +39,14 @@ class ExprBuilder
      *
      * @return ExprBuilder
      */
-    public function always()
+    public function always(\Closure $then = null)
     {
         $this->ifPart = function($v) { return true; };
 
+        if (null !== $then) {
+            $this->thenPart = $then;
+        }
+
         return $this;
     }