diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml
index e5df6c8b8151..7c0ef382ea8a 100644
--- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml
+++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml
@@ -37,12 +37,6 @@
Doctrine\ORM\Mapping\Driver\StaticPHPDriver
Doctrine\ORM\Mapping\ClassMetadataFactory
-
- Symfony\Bundle\DoctrineBundle\Security\EntityUserProvider
-
-
- Symfony\Bundle\DoctrineBundle\Security\AclCollectionCache
-
Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer
@@ -59,8 +53,6 @@
-
-
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php
index 9df9589e40ad..5acf264f3a5e 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php
@@ -17,18 +17,6 @@
*/
class Configuration
{
- public function getAclConfigTree()
- {
- $tb = new TreeBuilder();
-
- return $tb
- ->root('security', 'array')
- ->scalarNode('connection')->end()
- ->scalarNode('cache')->end()
- ->end()
- ->buildTree();
- }
-
public function getFactoryConfigTree()
{
$tb = new TreeBuilder();
@@ -53,6 +41,7 @@ public function getMainConfigTree(array $factories)
->scalarNode('session_fixation_strategy')->cannotBeEmpty()->defaultValue('migrate')->end()
;
+ $this->addAclSection($rootNode);
$this->addEncodersSection($rootNode);
$this->addProvidersSection($rootNode);
$this->addFirewallsSection($rootNode, $factories);
@@ -62,6 +51,16 @@ public function getMainConfigTree(array $factories)
return $tb->buildTree();
}
+ protected function addAclSection($rootNode)
+ {
+ $rootNode
+ ->arrayNode('acl')
+ ->scalarNode('connection')->end()
+ ->scalarNode('cache')->end()
+ ->end()
+ ;
+ }
+
protected function addRoleHierarchySection($rootNode)
{
$rootNode
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index 29a0bd9f9816..abfd2fd8d601 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -47,8 +47,6 @@ public function __construct()
public function load(array $configs, ContainerBuilder $container)
{
- $this->aclLoad($configs, $container);
-
$tmp = array_filter($configs);
if (empty($tmp)) {
return;
@@ -83,22 +81,10 @@ public function load(array $configs, ContainerBuilder $container)
if ($config['encoders']) {
$this->createEncoders($config['encoders'], $container);
}
- }
-
- protected function aclLoad(array $configs, ContainerBuilder $container)
- {
- $processor = new Processor();
- $config = $processor->process($this->configuration->getAclConfigTree(), $configs);
-
- $loader = new XmlFileLoader($container, new FileLocator(array(__DIR__.'/../Resources/config', __DIR__.'/Resources/config')));
- $loader->load('security_acl.xml');
-
- if (isset($config['connection'])) {
- $container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection']));
- }
- if (isset($config['cache'])) {
- $container->setAlias('security.acl.cache', sprintf('security.acl.cache.%s', $config['cache']));
+ // load ACL
+ if (isset($config['acl'])) {
+ $this->aclLoad($config['acl'], $container);
}
}
@@ -122,6 +108,20 @@ public function getAlias()
return 'security';
}
+ protected function aclLoad($config, ContainerBuilder $container)
+ {
+ $loader = new XmlFileLoader($container, new FileLocator(array(__DIR__.'/../Resources/config', __DIR__.'/Resources/config')));
+ $loader->load('security_acl.xml');
+
+ if (isset($config['connection'])) {
+ $container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection']));
+ }
+
+ if (isset($config['cache'])) {
+ $container->setAlias('security.acl.cache', sprintf('security.acl.cache.%s', $config['cache']));
+ }
+ }
+
/**
* Loads the web configuration.
*
@@ -421,8 +421,6 @@ protected function createUserProviders($config, ContainerBuilder $container)
}
// Parses a tag and returns the id for the related user provider service
- // FIXME: Replace register() calls in this method with DefinitionDecorator
- // and move the actual definition to an xml file
protected function createUserDaoProvider($name, $provider, ContainerBuilder $container, $master = true)
{
$name = $this->getUserProviderId(strtolower($name));
@@ -443,42 +441,22 @@ protected function createUserDaoProvider($name, $provider, ContainerBuilder $con
// Doctrine Entity DAO provider
if (isset($provider['entity'])) {
$container
- ->register($name, '%security.user.provider.entity.class%')
- ->setPublic(false)
- ->setArguments(array(
- new Reference('security.user.entity_manager'),
- $provider['entity']['class'],
- $provider['entity']['property'],
- ))
+ ->setDefinition($name, new DefinitionDecorator('security.user.provider.entity'))
+ ->addArgument($provider['entity']['class'])
+ ->addArgument($provider['entity']['property'])
;
return $name;
}
- // Doctrine Document DAO provider
- if (isset($provider['document'])) {
- $container
- ->register($name, '%security.user.provider.document.class%')
- ->setPublic(false)
- ->setArguments(array(
- new Reference('security.user.document_manager'),
- $provider['document']['class'],
- $provider['document']['property'],
- ));
-
- return $name;
- }
-
// In-memory DAO provider
- $definition = $container->register($name, '%security.user.provider.in_memory.class%');
- $definition->setPublic(false);
+ $definition = $container->setDefinition($name, new DefinitionDecorator('security.user.provider.in_memory'));
foreach ($provider['users'] as $username => $user) {
$userId = $name.'_'.$username;
$container
- ->register($userId, 'Symfony\Component\Security\Core\User\User')
+ ->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user'))
->setArguments(array($username, $user['password'], $user['roles']))
- ->setPublic(false)
;
$definition->addMethodCall('createUser', array(new Reference($userId)));
@@ -489,7 +467,7 @@ protected function createUserDaoProvider($name, $provider, ContainerBuilder $con
protected function getUserProviderId($name)
{
- return 'security.user.provider.'.$name;
+ return 'security.user.provider.concrete.'.$name;
}
protected function createExceptionListener($container, $config, $id, $defaultEntryPoint)
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
index bdab6f915196..8e53998834f2 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
@@ -14,7 +14,9 @@
Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder
Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder
+ Symfony\Component\Security\Core\User\EntityUserProvider
Symfony\Component\Security\Core\User\InMemoryUserProvider
+ Symfony\Component\Security\Core\User\User
Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver
Symfony\Component\Security\Core\Authentication\Token\AnonymousToken
@@ -117,5 +119,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
index 6e293cc6a258..fb51ffe1b8f1 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
@@ -11,30 +11,32 @@
acl_object_identity_ancestors
acl_security_identities
Symfony\Component\Security\Acl\Dbal\MutableAclProvider
-
+
Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy
-
+
Symfony\Component\Security\Acl\Voter\AclVoter
true
Symfony\Component\Security\Acl\Permission\BasicPermissionMap
-
+
Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy
Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy
-
+
Symfony\Component\Security\Acl\Domain\DoctrineAclCache
sf2_acl_
+
+ Symfony\Component\Security\Acl\Domain\AclCollectionCache
-
+
-
+
-
+
@@ -49,23 +51,23 @@
-
+
-
+
%security.acl.cache.doctrine.prefix%
-
+
-
+
-
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
index 8332d86c4281..0a57f06a7767 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
@@ -36,18 +36,18 @@ public function testUserProviders()
{
$container = $this->getContainer('container1');
- $providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.user.provider.'); }));
+ $providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.user.provider.concrete'); }));
$expectedProviders = array(
- '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',
+ 'security.user.provider.concrete.default',
+ 'security.user.provider.concrete.default_foo',
+ 'security.user.provider.concrete.digest',
+ 'security.user.provider.concrete.digest_foo',
+ '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',
);
$this->assertEquals(array(), array_diff($expectedProviders, $providers));
diff --git a/src/Symfony/Component/Security/Acl/Domain/AclCollectionCache.php b/src/Symfony/Component/Security/Acl/Domain/AclCollectionCache.php
new file mode 100644
index 000000000000..5ac8dfafe577
--- /dev/null
+++ b/src/Symfony/Component/Security/Acl/Domain/AclCollectionCache.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Domain;
+
+use Symfony\Component\Security\Acl\Model\AclProviderInterface;
+use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
+use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
+
+/**
+ * This service caches ACLs for an entire collection of objects.
+ *
+ * @author Johannes M. Schmitt
+ */
+class AclCollectionCache
+{
+ protected $aclProvider;
+ protected $objectIdentityRetrievalStrategy;
+ protected $securityIdentityRetrievalStrategy;
+
+ /**
+ * Constructor
+ *
+ * @param AclProviderInterface $aclProvider
+ * @param ObjectIdentityRetrievalStrategy $oidRetrievalStrategy
+ * @param SecurityIdentityRetrievalStrategy $sidRetrievalStrategy
+ * @return void
+ */
+ public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy)
+ {
+ $this->aclProvider = $aclProvider;
+ $this->objectIdentityRetrievalStrategy = $oidRetrievalStrategy;
+ $this->securityIdentityRetrievalStrategy = $sidRetrievalStrategy;
+ }
+
+ /**
+ * Batch loads ACLs for an entire collection; thus, it reduces the number
+ * of required queries considerably.
+ *
+ * @param mixed $collection anything that can be passed to foreach()
+ * @param array $tokens an array of TokenInterface implementations
+ * @return void
+ */
+ public function cache($collection, array $tokens = array())
+ {
+ $sids = array();
+ foreach ($tokens as $token) {
+ $sids = array_merge($sids, $this->securityIdentityRetrievalStrategy->getSecurityIdentities($token));
+ }
+
+ $oids = array();
+ foreach ($collection as $domainObject) {
+ $oids[] = $this->objectIdentityRetrievalStrategy->getObjectIdentity($domainObject);
+ }
+
+ $this->aclProvider->findAcls($oids, $sids);
+ }
+}
\ No newline at end of file
diff --git a/src/Symfony/Bundle/DoctrineBundle/Security/EntityUserProvider.php b/src/Symfony/Component/Security/Core/User/EntityUserProvider.php
similarity index 83%
rename from src/Symfony/Bundle/DoctrineBundle/Security/EntityUserProvider.php
rename to src/Symfony/Component/Security/Core/User/EntityUserProvider.php
index 03094c29ca29..89ff443448f5 100644
--- a/src/Symfony/Bundle/DoctrineBundle/Security/EntityUserProvider.php
+++ b/src/Symfony/Component/Security/Core/User/EntityUserProvider.php
@@ -9,20 +9,27 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Bundle\DoctrineBundle\Security;
+namespace Symfony\Component\Security\Core\User;
-use Symfony\Component\Security\Core\User\AccountInterface;
-use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Exception\UnsupportedAccountException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+/**
+ * Wrapper around a Doctrine EntityManager.
+ *
+ * Provides easy to use provisioning for Doctrine entity users.
+ *
+ * @author Fabien Potencier
+ * @author Johannes M. Schmitt
+ */
class EntityUserProvider implements UserProviderInterface
{
protected $class;
protected $repository;
protected $property;
- public function __construct($em, $class, $property = null)
+ public function __construct(EntityManager $em, $class, $property = null)
{
$this->class = $class;
diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 0e3b396b0f12..d7518e6f7d7e 100644
--- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -64,7 +64,7 @@ protected function attemptAuthentication(Request $request)
if (null !== $this->csrfProvider) {
$csrfToken = $request->get($this->options['csrf_parameter']);
- if (false === $this->csrfProvider->isTokenValid($this->options['csrf_page_id'], $csrfToken)) {
+ if (false === $this->csrfProvider->isCsrfTokenValid($this->options['csrf_page_id'], $csrfToken)) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}