Merge remote branch 'schmittjoh/security'

* schmittjoh/security:
  [SecurityBundle] fixed a regression
  [SecurityBundle] re-use local variable
  [SecurityBundle] added validation for check paths
  [SecurityBundle] added user_providers option for remember_me
  [Security/Core] added missing method to interface
This commit is contained in:
Fabien Potencier 2011-06-01 16:03:02 +02:00
commit 4b86b15105
5 changed files with 55 additions and 4 deletions

View File

@ -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[] = $name;
}
$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)

View File

@ -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;
@ -90,6 +88,12 @@ class RememberMeFactory implements SecurityFactoryInterface
;
}
}
if ($config['user_providers']) {
$userProviders = array();
foreach ($config['user_providers'] as $providerName) {
$userProviders[] = new Reference('security.user.provider.concrete.'.$providerName);
}
}
if (count($userProviders) === 0) {
throw new \RuntimeException('You must configure at least one remember-me aware listener (such as form-login) for each firewall that has remember-me enabled.');
}
@ -115,11 +119,18 @@ class RememberMeFactory implements SecurityFactoryInterface
public function addConfiguration(NodeDefinition $node)
{
$node->fixXmlConfig('user_provider');
$builder = $node->children();
$builder
->scalarNode('key')->isRequired()->cannotBeEmpty()->end()
->scalarNode('token_provider')->end()
->arrayNode('user_providers')
->beforeNormalization()
->ifString()->then(function($v) { return array($v); })
->end()
->prototype('scalar')->end()
->end()
;
foreach ($this->options as $name => $value) {

View File

@ -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);

View File

@ -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;
}

View File

@ -19,6 +19,12 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe;
*/
interface PersistentTokenInterface
{
/**
* Returns the class of the user
* @return string
*/
function getClass();
/**
* Returns the username
* @return string