[Security/DependencyInjection] updated SecurityBundle's configuration, some bug fixes in DIC config classes

This commit is contained in:
Johannes Schmitt 2011-02-10 22:42:10 +01:00 committed by Fabien Potencier
parent fc3f56d17c
commit a5cfc2207c
26 changed files with 168 additions and 245 deletions

View File

@ -205,7 +205,7 @@ class Configuration
->treatTrueLike(array())
->fixXmlConfig('namespace')
->arrayNode('namespaces')
->containsNameValuePairsWithKeyAttribute('prefix')
->useAttributeAsKey('prefix')
->prototype('scalar')
->beforeNormalization()
->ifTrue(function($v) { return is_array($v) && isset($v['namespace']); })

View File

@ -67,7 +67,7 @@ class Configuration
$rootNode
->fixXmlConfig('role', 'role_hierarchy')
->arrayNode('role_hierarchy')
->containsNameValuePairsWithKeyAttribute('id')
->useAttributeAsKey('id')
->prototype('array')
->performNoDeepMerging()
->beforeNormalization()->ifString()->then(function($v) { return array('value' => $v); })->end()
@ -103,7 +103,7 @@ class Configuration
->end()
->fixXmlConfig('attribute')
->arrayNode('attributes')
->containsNameValuePairsWithKeyAttribute('key')
->useAttributeAsKey('key')
->prototype('scalar')
->beforeNormalization()
->ifTrue(function($v) { return is_array($v) && isset($v['pattern']); })
@ -122,6 +122,8 @@ class Configuration
$rootNode
->fixXmlConfig('firewall')
->arrayNode('firewalls')
->isRequired()
->requiresAtLeastOneElement()
->disallowNewKeysInSubsequentConfigs()
->useAttributeAsKey('name')
->prototype('array')
@ -183,6 +185,7 @@ class Configuration
->fixXmlConfig('provider')
->arrayNode('providers')
->disallowNewKeysInSubsequentConfigs()
->isRequired()
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('array')
@ -220,10 +223,13 @@ class Configuration
$rootNode
->fixXmlConfig('encoder')
->arrayNode('encoders')
->requiresAtLeastOneElement()
->useAttributeAsKey('class')
->prototype('array')
->canBeUnset()
->performNoDeepMerging()
->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
->scalarNode('algorithm')->isRequired()->cannotBeEmpty()->end()
->scalarNode('algorithm')->cannotBeEmpty()->end()
->booleanNode('ignore_case')->end()
->booleanNode('encode_as_base64')->end()
->scalarNode('iterations')->end()

View File

@ -470,7 +470,7 @@ class SecurityExtension extends Extension
$definition = $container->register($name, '%security.user.provider.in_memory.class%');
$definition->setPublic(false);
foreach ($provider['users'] as $username => $user) {
$userId = $name.'_'.md5(json_encode(array($username, $user['password'], $user['roles'])));
$userId = $name.'_'.$username;
$container
->register($userId, 'Symfony\Component\Security\Core\User\User')
@ -486,7 +486,7 @@ class SecurityExtension extends Extension
protected function getUserProviderId($name)
{
return 'security.authentication.provider.'.$name;
return 'security.user.provider.'.$name;
}
protected function createExceptionListener($container, $config, $id, $defaultEntryPoint)

View File

@ -1,8 +0,0 @@
<?php
$container->loadFromExtension('security', 'config', array(
'access_control' => array(
array('path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https'),
array('path' => '/blog/.*', 'attributes' => array('_controller' => '.*\\BlogBundle\\.*'), 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
),
));

View File

@ -0,0 +1,52 @@
<?php
$container->loadFromExtension('security', 'config', array(
'providers' => array(
'default' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
'digest' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER, ROLE_ADMIN'),
),
),
'basic' => 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',
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
'secure' => array('stateless' => true,
'http_basic' => true,
'http_digest' => true,
'form_login' => true,
'anonymous' => true,
'switch_user' => true,
'x509' => true,
'logout' => true,
),
),
'access_control' => array(
array('path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https'),
array('path' => '/blog/.*', 'attributes' => array('_controller' => '.*\\BlogBundle\\.*'), 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
),
'role_hierarchy' => array(
'ROLE_ADMIN' => 'ROLE_USER',
'ROLE_SUPER_ADMIN' => array('ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'),
'ROLE_REMOTE' => 'ROLE_USER,ROLE_ADMIN',
),
));

View File

@ -1,24 +0,0 @@
<?php
$container->loadFromExtension('security', 'config', array(
'providers' => array(
'basic' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
'secure' => array('stateless' => true,
'http_basic' => true,
'http_digest' => true,
'form_login' => true,
'anonymous' => true,
'switch_user' => true,
'x509' => true,
'logout' => true,
),
)
));

View File

@ -1,9 +0,0 @@
<?php
$container->loadFromExtension('security', 'config', array(
'role_hierarchy' => array(
'ROLE_ADMIN' => 'ROLE_USER',
'ROLE_SUPER_ADMIN' => array('ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'),
'ROLE_REMOTE' => 'ROLE_USER,ROLE_ADMIN',
)
));

View File

@ -3,12 +3,17 @@
$this->load('merge_import.php', $container);
$container->loadFromExtension('security', 'config', array(
'providers' => array(
'default' => array('id' => 'foo'),
),
'firewalls' => array(
'main' => array(
'form_login' => false,
'http_basic' => null,
),
),
'role_hierarchy' => array(
'FOO' => array('MOO'),
)

View File

@ -1,24 +0,0 @@
<?php
$container->loadFromExtension('security', 'config', array(
'providers' => array(
'digest' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER, ROLE_ADMIN'),
),
),
'basic' => array(
'password_encoder' => 'sha1',
'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',
),
)
));

View File

@ -1,14 +0,0 @@
<?xml version="1.0" ?>
<srv:container xmlns="http://www.symfony-project.org/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://www.symfony-project.org/schema/dic/services"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<config>
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" />
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*">
<attribute key="_controller" pattern=".*\\BlogBundle\\.*" />
</rule>
</config>
</srv:container>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?>
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://www.symfony-project.org/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@ -6,12 +6,15 @@
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<config>
<provider name="default">
<user name="foo" password="foo" roles="ROLE_USER" />
</provider>
<provider name="digest">
<user name="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
</provider>
<provider name="basic">
<password-encoder hash="sha1" />
<user name="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
<user name="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
</provider>
@ -21,5 +24,26 @@
</provider>
<provider name="service" id="user.manager" />
<firewall name="simple" pattern="/login" security="false" />
<firewall name="secure" stateless="true">
<http-basic />
<http-digest />
<form-login />
<anonymous />
<switch-user />
<x509 />
<logout />
</firewall>
<role id="ROLE_ADMIN">ROLE_USER</role>
<role id="ROLE_SUPER_ADMIN">ROLE_USER,ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH</role>
<role id="ROLE_REMOTE">ROLE_USER,ROLE_ADMIN</role>
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" />
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*">
<attribute key="_controller" pattern=".*\\BlogBundle\\.*" />
</rule>
</config>
</srv:container>

View File

@ -1,25 +0,0 @@
<?xml version="1.0" ?>
<srv:container xmlns="http://www.symfony-project.org/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://www.symfony-project.org/schema/dic/services"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<config>
<provider name="foo">
<user name="foo" password="foo" roles="ROLE_USER" />
</provider>
<firewall name="simple" pattern="/login" security="false" />
<firewall name="secure" stateless="true">
<http-basic />
<http-digest />
<form-login />
<anonymous />
<switch-user />
<x509 />
<logout />
</firewall>
</config>
</srv:container>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" ?>
<srv:container xmlns="http://www.symfony-project.org/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://www.symfony-project.org/schema/dic/services"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<config>
<role id="ROLE_ADMIN">ROLE_USER</role>
<role id="ROLE_SUPER_ADMIN">ROLE_USER,ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH</role>
<role id="ROLE_REMOTE">ROLE_USER,ROLE_ADMIN</role>
</config>
</srv:container>

View File

@ -10,6 +10,8 @@
</imports>
<sec:config>
<sec:provider name="default" id="foo" />
<sec:firewall name="main" form-login="false">
<sec:http-basic />
</sec:firewall>

View File

@ -1,7 +0,0 @@
security.config:
access_control:
- { path: /blog/524, role: ROLE_USER, requires_channel: https }
-
path: /blog/.*
attributes: { _controller: .*\\BlogBundle\\.* }
role: IS_AUTHENTICATED_ANONYMOUSLY

View File

@ -0,0 +1,41 @@
security.config:
providers:
default:
users:
foo: { password: foo, roles: ROLE_USER }
digest:
users:
foo: { password: foo, roles: 'ROLE_USER, ROLE_ADMIN' }
basic:
password_encoder: sha1
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
firewalls:
simple: { pattern: /login, security: false }
secure:
stateless: true
http_basic: true
http_digest: true
form_login: true
anonymous: true
switch_user: true
x509: true
logout: true
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_REMOTE: ROLE_USER,ROLE_ADMIN
access_control:
- { path: /blog/524, role: ROLE_USER, requires_channel: https }
-
path: /blog/.*
attributes: { _controller: .*\\BlogBundle\\.* }
role: IS_AUTHENTICATED_ANONYMOUSLY

View File

@ -1,17 +0,0 @@
security.config:
providers:
basic:
users:
foo: { password: foo, roles: ROLE_USER }
firewalls:
simple: { pattern: /login, security: false }
secure:
stateless: true
http_basic: true
http_digest: true
form_login: true
anonymous: true
switch_user: true
x509: true
logout: true

View File

@ -1,5 +0,0 @@
security.config:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_REMOTE: ROLE_USER,ROLE_ADMIN

View File

@ -2,10 +2,13 @@ imports:
- { resource: merge_import.yml }
security.config:
providers:
default: { id: foo }
firewalls:
main:
form_login: false
http_basic: ~
role_hierarchy:
FOO: [MOO]

View File

@ -1,17 +0,0 @@
security.config:
providers:
digest:
users:
foo: { password: foo, roles: 'ROLE_USER, ROLE_ADMIN' }
basic:
password_encoder: sha1
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

View File

@ -20,7 +20,7 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
public function testRolesHierarchy()
{
$container = $this->getContainer('hierarchy');
$container = $this->getContainer('container1');
$this->assertEquals(array(
'ROLE_ADMIN' => array('ROLE_USER'),
'ROLE_SUPER_ADMIN' => array('ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'),
@ -30,22 +30,20 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
public function testUserProviders()
{
$container = $this->getContainer('provider');
$container = $this->getContainer('container1');
$providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.authentication.provider.'); }));
$providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.user.provider.'); }));
$expectedProviders = array(
'security.authentication.provider.digest',
'security.authentication.provider.digest_23374fce51fe846516ff85bfa9add8fe',
'security.authentication.provider.basic',
'security.authentication.provider.basic_745e8583f784c83c4b4208fd281001f3',
'security.authentication.provider.basic_af4bcce7246fb064b8e219034043d88a',
'security.authentication.provider.doctrine',
'security.authentication.provider.service',
'security.authentication.provider.anonymous',
'security.authentication.provider.dao',
'security.authentication.provider.pre_authenticated',
'security.authentication.provider.rememberme',
'security.user.provider.default',
'security.user.provider.default_foo',
'security.user.provider.digest',
'security.user.provider.digest_foo',
'security.user.provider.basic',
'security.user.provider.basic_foo',
'security.user.provider.basic_bar',
'security.user.provider.doctrine',
'security.user.provider.service',
);
$this->assertEquals(array(), array_diff($expectedProviders, $providers));
@ -54,7 +52,7 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
public function testFirewalls()
{
$container = $this->getContainer('firewall');
$container = $this->getContainer('container1');
$arguments = $container->getDefinition('security.firewall.map')->getArguments();
$listeners = array();
@ -82,7 +80,7 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
public function testAccess()
{
$container = $this->getContainer('access');
$container = $this->getContainer('container1');
$rules = array();
foreach ($container->getDefinition('security.access_map')->getMethodCalls() as $call) {

View File

@ -225,7 +225,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
if ($child->isRequired()) {
throw new InvalidConfigurationException(sprintf(
'The node at path "%s" must be configured.',
$this->getPath()
$this->getPath().'.'.$name
));
}
@ -352,19 +352,15 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
continue;
}
try {
if (null !== $this->prototype) {
$this->prototype->setName($k);
$leftSide[$k] = $this->prototype->merge($leftSide[$k], $v);
} else {
if (!isset($this->children[$k])) {
throw new \RuntimeException('merge() expects a normalized config array.');
}
$leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
if (null !== $this->prototype) {
$this->prototype->setName($k);
$leftSide[$k] = $this->prototype->merge($leftSide[$k], $v);
} else {
if (!isset($this->children[$k])) {
throw new \RuntimeException('merge() expects a normalized config array.');
}
} catch (UnsetKeyException $unset) {
unset($leftSide[$k]);
$leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
}
}

View File

@ -92,31 +92,6 @@ class ExprBuilder
return $this;
}
/**
* Sets a closure replacing the key with an attribute of the value when it is an array.
*
* @param string $attribute
*
* @return Symfony\Component\DependencyInjection\Configuration\Builder\ExprBuilder
*/
public function thenReplaceKeyWithAttribute($attribute)
{
$this->thenPart = function($v) use ($attribute) {
$newValue = array();
foreach ($v as $k => $oldValue) {
if (is_array($oldValue) && isset($oldValue[$attribute])) {
$k = $oldValue[$attribute];
}
$newValue[$k] = $oldValue;
}
return $newValue;
};
return $this;
}
/**
* Sets a closure returning an empty array.
*

View File

@ -152,25 +152,6 @@ class NodeBuilder
return $this;
}
/**
* Sets the attribute to use as key of the array.
*
* @param string $attribute The name of the attribute
*
* @return Symfony\Component\DependencyInjection\Configuration\Builder\NodeBuilder
*/
public function containsNameValuePairsWithKeyAttribute($attribute)
{
$this->beforeNormalization()
->ifArray()
->thenReplaceKeyWithAttribute($attribute)
;
$this->useAttributeAsKey($attribute);
return $this;
}
/**
* Requires the node to have at least one element.
*

View File

@ -128,6 +128,7 @@ class TreeBuilder
$configNode->addEquivalentValue(null, $node->nullEquivalent);
$configNode->addEquivalentValue(true, $node->trueEquivalent);
$configNode->addEquivalentValue(false, $node->falseEquivalent);
$configNode->setRequired($node->required);
}
/**
@ -146,6 +147,7 @@ class TreeBuilder
$configNode->addEquivalentValue(true, $node->trueEquivalent);
$configNode->addEquivalentValue(false, $node->falseEquivalent);
$configNode->setPerformDeepMerging($node->performDeepMerging);
$configNode->setRequired($node->required);
if (null !== $node->key) {
$configNode->setKeyAttribute($node->key);

View File

@ -19,4 +19,5 @@ interface NodeInterface
function getDefaultValue();
function normalize($value);
function merge($leftSide, $rightSide);
function finalize($value);
}