merged branch stof/security_providers (PR #2454)
Commits -------d2195cc
Fixed phpdoc and updated the changelog9e41ff4
[SecurityBundle] Added a validation ruleb107a3f
[SecurityBundle] Refactored the configuration633f0e9
[DoctrineBundle] Moved the entity provider service to DoctrineBundle74732dc
[SecurityBundle] Added a way to extend the providers section of the config Discussion ---------- [WIP][SecurityBundle] Added a way to extend the providers section of the config Bug fix: no Feature addition: yes BC break: <del>no (for now)</del> yes Tests pass: yes This adds a way to extend the ``providers`` section of the security config so that other bundles can hook their stuff into it. An example is available in DoctrineBundle which is now responsible to handle the entity provider (<del>needs some cleanup as the service definition is still in SecurityBundle currently</del>). This will allow PropelBundle to provide a ``propel:`` provider for instance. In order to keep BC with the existing configuration for the in-memory and the chain providers, I had to allow using a prototyped node instead of forcing using an array node with childrens. This introduces some issues: - impossible to validate easily that a provider uses only one setup as prototyped node always have a default value (the empty array) - the ``getFixableKey`` method is needed in the interface to support the XML format by pluralizing the name. Here is my non-BC proposal for the configuration to clean this: ```yaml security: providers: first: memory: # BC break here by adding a level before the users users: joe: { password: foobar, roles: ROLE_USER } john: { password: foobarbaz, roles: ROLE_USER } second: entity: # this one is BC class: Acme\DemoBundle\Entity\User third: id: my_custom_provider # also BC fourth: chain: # BC break by adding a level before the providers providers: [first, second, third] ``` What do you think about it ? Do we need to keep the BC in the config of the bundle or no ? Btw note that the way to register the factories used by the firewall section should be refactored using the new way to provide extension points in the extensions (as done here) instead of relying on the end user to register factories, which would probably mean a BC break anyway. --------------------------------------------------------------------------- by lsmith77 at 2011/10/23 09:19:23 -0700 i don't think we should keep BC. the security config is complex as is .. having BC stuff in there will just make it even harder and confusing. --------------------------------------------------------------------------- by willdurand at 2011/10/23 09:41:25 -0700 Is the security component tagged with `@api` ? So basically, we just have to create a factory (`ModelFactory` for instance) and to register it in the `security` extension, right ? Seems quite simple to extend and much better than the hardcoded version… Why did you call the method to pluralize a key `getFixableKey` ? --------------------------------------------------------------------------- by beberlei at 2011/10/23 14:48:26 -0700 Changing security config will introduce risk for users. We should avoid that --------------------------------------------------------------------------- by stof at 2011/10/23 15:34:47 -0700 @beberlei as the config is validated, it will simply give them an exception during the loading of the config if they don't update their config. --------------------------------------------------------------------------- by stof at 2011/10/24 01:01:42 -0700 @schmittjoh @fabpot Could you give your mind about it ? --------------------------------------------------------------------------- by stof at 2011/10/31 17:08:12 -0700 @fabpot @schmittjoh ping --------------------------------------------------------------------------- by stof at 2011/11/11 14:08:18 -0800 I updated the PR by implementing my proposal as the latest IRC meeting agreed that we don't need to keep the BC for this change. This allows to add the validation rule now. --------------------------------------------------------------------------- by stof at 2011/11/16 11:16:06 -0800 @fabpot ping --------------------------------------------------------------------------- by fabpot at 2011/11/16 22:29:05 -0800 @stof: Before merging, you must also add information about how to upgrade in the CHANGELOG-2.1.md file. --------------------------------------------------------------------------- by stof at 2011/11/17 00:01:23 -0800 @fabpot done
This commit is contained in:
commit
ec2c81bc84
@ -39,6 +39,33 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||
* [BC BREAK] The Firewall listener is now registered after the Router one.
|
||||
It means that specific Firewall URLs (like /login_check and /logout must now have proper
|
||||
route defined in your routing configuration)
|
||||
|
||||
* [BC BREAK] refactored the user provider configuration. The configuration changed for the chain provider and the memory provider:
|
||||
|
||||
Before:
|
||||
|
||||
security:
|
||||
providers:
|
||||
my_chain_provider:
|
||||
providers: [my_memory_provider, my_doctrine_provider]
|
||||
my_memory_provider:
|
||||
users:
|
||||
toto: { password: foobar, roles: [ROLE_USER] }
|
||||
foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
|
||||
|
||||
After:
|
||||
|
||||
security:
|
||||
providers:
|
||||
my_chain_provider:
|
||||
chain:
|
||||
providers: [my_memory_provider, my_doctrine_provider]
|
||||
my_memory_provider:
|
||||
memory:
|
||||
users:
|
||||
toto: { password: foobar, roles: [ROLE_USER] }
|
||||
foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
|
||||
|
||||
* added a validator for the user password
|
||||
|
||||
### SwiftmailerBundle
|
||||
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\DoctrineBundle\DependencyInjection\Security\UserProvider;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* EntityFactory creates services for Doctrine user provider.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class EntityFactory implements UserProviderFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, $id, $config)
|
||||
{
|
||||
$container
|
||||
->setDefinition($id, new DefinitionDecorator('doctrine.orm.security.user.provider'))
|
||||
->addArgument($config['class'])
|
||||
->addArgument($config['property'])
|
||||
;
|
||||
}
|
||||
|
||||
public function getKey()
|
||||
{
|
||||
return 'entity';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeDefinition $node)
|
||||
{
|
||||
$node
|
||||
->children()
|
||||
->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
|
||||
->scalarNode('property')->defaultNull()->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace Symfony\Bundle\DoctrineBundle;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Bundle\DoctrineBundle\DependencyInjection\Compiler\RegisterEventListenersAndSubscribersPass;
|
||||
use Symfony\Bundle\DoctrineBundle\DependencyInjection\Security\UserProvider\EntityFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
@ -29,6 +30,9 @@ class DoctrineBundle extends Bundle
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
|
||||
if ($container->hasExtension('security')) {
|
||||
$container->getExtension('security')->addUserProviderFactory(new EntityFactory());
|
||||
}
|
||||
}
|
||||
|
||||
public function boot()
|
||||
|
@ -34,6 +34,9 @@
|
||||
<!-- validator -->
|
||||
<parameter key="doctrine.orm.validator.unique.class">Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator</parameter>
|
||||
<parameter key="doctrine.orm.validator_initializer.class">Symfony\Bridge\Doctrine\Validator\DoctrineInitializer</parameter>
|
||||
|
||||
<!-- security -->
|
||||
<parameter key="doctrine.orm.security.user.provider.class">Symfony\Bridge\Doctrine\Security\User\EntityUserProvider</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
@ -69,5 +72,10 @@
|
||||
<tag name="validator.initializer" />
|
||||
<argument type="service" id="doctrine" />
|
||||
</service>
|
||||
|
||||
<!-- security -->
|
||||
<service id="doctrine.orm.security.user.provider" class="%doctrine.orm.security.user.provider.class%" abstract="true" public="false">
|
||||
<argument type="service" id="doctrine.orm.entity_manager" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -31,15 +31,18 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
class MainConfiguration implements ConfigurationInterface
|
||||
{
|
||||
private $factories;
|
||||
private $userProviderFactories;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $factories
|
||||
* @param array $userProviderFactories
|
||||
*/
|
||||
public function __construct(array $factories)
|
||||
public function __construct(array $factories, array $userProviderFactories)
|
||||
{
|
||||
$this->factories = $factories;
|
||||
$this->userProviderFactories = $userProviderFactories;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,7 +290,7 @@ class MainConfiguration implements ConfigurationInterface
|
||||
|
||||
private function addProvidersSection(ArrayNodeDefinition $rootNode)
|
||||
{
|
||||
$rootNode
|
||||
$providerNodeBuilder = $rootNode
|
||||
->fixXmlConfig('provider')
|
||||
->children()
|
||||
->arrayNode('providers')
|
||||
@ -296,15 +299,12 @@ class MainConfiguration implements ConfigurationInterface
|
||||
->requiresAtLeastOneElement()
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
;
|
||||
|
||||
$providerNodeBuilder
|
||||
->children()
|
||||
->scalarNode('id')->end()
|
||||
->arrayNode('entity')
|
||||
->children()
|
||||
->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
|
||||
->scalarNode('property')->defaultNull()->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->arrayNode('chain')
|
||||
->fixXmlConfig('provider')
|
||||
->children()
|
||||
->arrayNode('providers')
|
||||
@ -315,23 +315,25 @@ class MainConfiguration implements ConfigurationInterface
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
->fixXmlConfig('user')
|
||||
->children()
|
||||
->arrayNode('users')
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->scalarNode('password')->defaultValue(uniqid())->end()
|
||||
->arrayNode('roles')
|
||||
->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
foreach ($this->userProviderFactories as $factory) {
|
||||
$name = str_replace('-', '_', $factory->getKey());
|
||||
$factoryNode = $providerNodeBuilder->children()->arrayNode($name)->canBeUnset();
|
||||
|
||||
$factory->addConfiguration($factoryNode);
|
||||
}
|
||||
|
||||
$providerNodeBuilder
|
||||
->validate()
|
||||
->ifTrue(function($v){return count($v) > 1;})
|
||||
->thenInvalid('You cannot set multiple provider types for the same provider')
|
||||
->end()
|
||||
->validate()
|
||||
->ifTrue(function($v){return count($v) === 0;})
|
||||
->thenInvalid('You must set a provider definition for the provider.')
|
||||
->end()
|
||||
;
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* InMemoryFactory creates services for the memory provider.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class InMemoryFactory implements UserProviderFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, $id, $config)
|
||||
{
|
||||
$definition = $container->setDefinition($id, new DefinitionDecorator('security.user.provider.in_memory'));
|
||||
|
||||
foreach ($config['users'] as $username => $user) {
|
||||
$userId = $id.'_'.$username;
|
||||
|
||||
$container
|
||||
->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user'))
|
||||
->setArguments(array($username, (string) $user['password'], $user['roles']))
|
||||
;
|
||||
|
||||
$definition->addMethodCall('createUser', array(new Reference($userId)));
|
||||
}
|
||||
}
|
||||
|
||||
public function getKey()
|
||||
{
|
||||
return 'memory';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeDefinition $node)
|
||||
{
|
||||
$node
|
||||
->fixXmlConfig('user')
|
||||
->children()
|
||||
->arrayNode('users')
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->scalarNode('password')->defaultValue(uniqid())->end()
|
||||
->arrayNode('roles')
|
||||
->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* UserProviderFactoryInterface is the interface for all user provider factories.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
interface UserProviderFactoryInterface
|
||||
{
|
||||
function create(ContainerBuilder $container, $id, $config);
|
||||
|
||||
function getKey();
|
||||
|
||||
function addConfiguration(NodeDefinition $builder);
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
@ -36,6 +37,7 @@ class SecurityExtension extends Extension
|
||||
private $contextListeners = array();
|
||||
private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me');
|
||||
private $factories;
|
||||
private $userProviderFactories = array();
|
||||
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
@ -49,7 +51,7 @@ class SecurityExtension extends Extension
|
||||
$factories = $this->createListenerFactories($container, $config);
|
||||
|
||||
// normalize and merge the actual configuration
|
||||
$mainConfig = new MainConfiguration($factories);
|
||||
$mainConfig = new MainConfiguration($factories, $this->userProviderFactories);
|
||||
$config = $this->processConfiguration($mainConfig, $configs);
|
||||
|
||||
// load services
|
||||
@ -452,6 +454,16 @@ class SecurityExtension extends Extension
|
||||
{
|
||||
$name = $this->getUserProviderId(strtolower($name));
|
||||
|
||||
foreach ($this->userProviderFactories as $factory) {
|
||||
$key = str_replace('-', '_', $factory->getKey());
|
||||
|
||||
if (!empty($provider[$key])) {
|
||||
$factory->create($container, $name, $provider[$key]);
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
// Existing DAO service provider
|
||||
if (isset($provider['id'])) {
|
||||
$container->setAlias($name, new Alias($provider['id'], false));
|
||||
@ -460,9 +472,9 @@ class SecurityExtension extends Extension
|
||||
}
|
||||
|
||||
// Chain provider
|
||||
if ($provider['providers']) {
|
||||
if (isset($provider['chain'])) {
|
||||
$providers = array();
|
||||
foreach ($provider['providers'] as $providerName) {
|
||||
foreach ($provider['chain']['providers'] as $providerName) {
|
||||
$providers[] = new Reference($this->getUserProviderId(strtolower($providerName)));
|
||||
}
|
||||
|
||||
@ -474,30 +486,6 @@ class SecurityExtension extends Extension
|
||||
return $name;
|
||||
}
|
||||
|
||||
// Doctrine Entity DAO provider
|
||||
if (isset($provider['entity'])) {
|
||||
$container
|
||||
->setDefinition($name, new DefinitionDecorator('security.user.provider.entity'))
|
||||
->addArgument($provider['entity']['class'])
|
||||
->addArgument($provider['entity']['property'])
|
||||
;
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
// In-memory DAO provider
|
||||
$definition = $container->setDefinition($name, new DefinitionDecorator('security.user.provider.in_memory'));
|
||||
foreach ($provider['users'] as $username => $user) {
|
||||
$userId = $name.'_'.$username;
|
||||
|
||||
$container
|
||||
->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user'))
|
||||
->setArguments(array($username, (string)$user['password'], $user['roles']))
|
||||
;
|
||||
|
||||
$definition->addMethodCall('createUser', array(new Reference($userId)));
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
@ -600,6 +588,10 @@ class SecurityExtension extends Extension
|
||||
return $this->factories = $factories;
|
||||
}
|
||||
|
||||
public function addUserProviderFactory(UserProviderFactoryInterface $factory)
|
||||
{
|
||||
$this->userProviderFactories[] = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base path for the XSD files.
|
||||
|
@ -13,7 +13,6 @@
|
||||
<parameter key="security.encoder.digest.class">Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder</parameter>
|
||||
<parameter key="security.encoder.plain.class">Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder</parameter>
|
||||
|
||||
<parameter key="security.user.provider.entity.class">Symfony\Bridge\Doctrine\Security\User\EntityUserProvider</parameter>
|
||||
<parameter key="security.user.provider.in_memory.class">Symfony\Component\Security\Core\User\InMemoryUserProvider</parameter>
|
||||
<parameter key="security.user.provider.in_memory.user.class">Symfony\Component\Security\Core\User\User</parameter>
|
||||
<parameter key="security.user.provider.chain.class">Symfony\Component\Security\Core\User\ChainUserProvider</parameter>
|
||||
@ -118,11 +117,6 @@
|
||||
</service>
|
||||
|
||||
<!-- Provisioning -->
|
||||
<service id="security.user.provider.entity" class="%security.user.provider.entity.class%" abstract="true" public="false">
|
||||
<argument type="service" id="security.user.entity_manager" />
|
||||
</service>
|
||||
<service id="security.user.entity_manager" alias="doctrine.orm.entity_manager" public="false" />
|
||||
|
||||
<service id="security.user.provider.in_memory" class="%security.user.provider.in_memory.class%" abstract="true" public="false" />
|
||||
<service id="security.user.provider.in_memory.user" class="%security.user.provider.in_memory.user.class%" abstract="true" public="false" />
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Bundle\SecurityBundle;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass;
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory;
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
@ -26,6 +27,7 @@ class SecurityBundle extends Bundle
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->getExtension('security')->addUserProviderFactory(new InMemoryFactory());
|
||||
$container->addCompilerPass(new AddSecurityVotersPass());
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
protected static $minimalConfig = array(
|
||||
'providers' => array(
|
||||
'stub' => array(),
|
||||
'stub' => array(
|
||||
'id' => 'foo',
|
||||
),
|
||||
),
|
||||
'firewalls' => array(
|
||||
'stub' => array(),
|
||||
@ -43,10 +45,45 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$processor = new Processor();
|
||||
$configuration = new MainConfiguration(array());
|
||||
$configuration = new MainConfiguration(array(), array());
|
||||
$config = $processor->processConfiguration($configuration, array($config));
|
||||
|
||||
$this->assertFalse(array_key_exists('factory', $config), 'The factory key is silently removed without an exception');
|
||||
$this->assertEquals(array(), $config['factories'], 'The factories key is just an empty array');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
public function testNoConfigForProvider()
|
||||
{
|
||||
$config = array(
|
||||
'providers' => array(
|
||||
'stub' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
$processor = new Processor();
|
||||
$configuration = new MainConfiguration(array(), array());
|
||||
$config = $processor->processConfiguration($configuration, array($config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
public function testManyConfigForProvider()
|
||||
{
|
||||
$config = array(
|
||||
'providers' => array(
|
||||
'stub' => array(
|
||||
'id' => 'foo',
|
||||
'chain' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$processor = new Processor();
|
||||
$configuration = new MainConfiguration(array(), array());
|
||||
$config = $processor->processConfiguration($configuration, array($config));
|
||||
}
|
||||
}
|
||||
|
@ -18,29 +18,34 @@ $container->loadFromExtension('security', array(
|
||||
),
|
||||
'providers' => array(
|
||||
'default' => array(
|
||||
'memory' => array(
|
||||
'users' => array(
|
||||
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
|
||||
),
|
||||
),
|
||||
),
|
||||
'digest' => array(
|
||||
'memory' => array(
|
||||
'users' => array(
|
||||
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER, ROLE_ADMIN'),
|
||||
),
|
||||
),
|
||||
),
|
||||
'basic' => array(
|
||||
'memory' => array(
|
||||
'users' => array(
|
||||
'foo' => array('password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => 'ROLE_SUPER_ADMIN'),
|
||||
'bar' => array('password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => array('ROLE_USER', 'ROLE_ADMIN')),
|
||||
),
|
||||
),
|
||||
'doctrine' => array(
|
||||
'entity' => array('class' => 'SecurityBundle:User', 'property' => 'username')
|
||||
),
|
||||
'service' => array(
|
||||
'id' => 'user.manager',
|
||||
),
|
||||
'chain' => array(
|
||||
'providers' => array('service', 'doctrine', 'basic'),
|
||||
'chain' => array(
|
||||
'providers' => array('service', 'basic'),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
@ -17,25 +17,29 @@
|
||||
<encoder class="JMS\FooBundle\Entity\User4" id="security.encoder.foo" />
|
||||
|
||||
<provider name="default">
|
||||
<memory>
|
||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
||||
</memory>
|
||||
</provider>
|
||||
|
||||
<provider name="digest">
|
||||
<memory>
|
||||
<user name="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
|
||||
</memory>
|
||||
</provider>
|
||||
|
||||
<provider name="basic">
|
||||
<memory>
|
||||
<user name="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
|
||||
<user name="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
|
||||
</provider>
|
||||
|
||||
<provider name="doctrine">
|
||||
<entity class="SecurityBundle:User" property="username" />
|
||||
</memory>
|
||||
</provider>
|
||||
|
||||
<provider name="service" id="user.manager" />
|
||||
|
||||
<provider name="chain" providers="service, doctrine, basic" />
|
||||
<provider name="chain">
|
||||
<chain providers="service, basic" />
|
||||
</provider>
|
||||
|
||||
<firewall name="simple" pattern="/login" security="false" />
|
||||
|
||||
|
@ -13,21 +13,23 @@ security:
|
||||
|
||||
providers:
|
||||
default:
|
||||
memory:
|
||||
users:
|
||||
foo: { password: foo, roles: ROLE_USER }
|
||||
digest:
|
||||
memory:
|
||||
users:
|
||||
foo: { password: foo, roles: 'ROLE_USER, ROLE_ADMIN' }
|
||||
basic:
|
||||
memory:
|
||||
users:
|
||||
foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_SUPER_ADMIN }
|
||||
bar: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: [ROLE_USER, ROLE_ADMIN] }
|
||||
doctrine:
|
||||
entity: { class: SecurityBundle:User, property: username }
|
||||
service:
|
||||
id: user.manager
|
||||
chain:
|
||||
providers: [service, doctrine, basic]
|
||||
chain:
|
||||
providers: [service, basic]
|
||||
|
||||
|
||||
firewalls:
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
|
||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
@ -46,7 +47,6 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
'security.user.provider.concrete.basic',
|
||||
'security.user.provider.concrete.basic_foo',
|
||||
'security.user.provider.concrete.basic_bar',
|
||||
'security.user.provider.concrete.doctrine',
|
||||
'security.user.provider.concrete.service',
|
||||
'security.user.provider.concrete.chain',
|
||||
);
|
||||
@ -57,7 +57,6 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
// chain provider
|
||||
$this->assertEquals(array(array(
|
||||
new Reference('security.user.provider.concrete.service'),
|
||||
new Reference('security.user.provider.concrete.doctrine'),
|
||||
new Reference('security.user.provider.concrete.basic'),
|
||||
)), $container->getDefinition('security.user.provider.concrete.chain')->getArguments());
|
||||
}
|
||||
@ -170,6 +169,7 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$security = new SecurityExtension();
|
||||
$security->addUserProviderFactory(new InMemoryFactory());
|
||||
$container->registerExtension($security);
|
||||
$this->loadFromFile($container, $file);
|
||||
|
||||
|
Reference in New Issue
Block a user