[Security] added AbstractFactory
This commit is contained in:
parent
3ac4994507
commit
2539da5e6a
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.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\Factory;
|
||||
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* AbstractFactory is the base class for all classes inheriting from
|
||||
* AbstractAuthenticationListener
|
||||
*
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class AbstractFactory implements SecurityFactoryInterface
|
||||
{
|
||||
protected $options = array(
|
||||
'check_path' => '/login_check',
|
||||
'login_path' => '/login',
|
||||
'use_forward' => false,
|
||||
'always_use_default_target_path' => false,
|
||||
'default_target_path' => '/',
|
||||
'target_path_parameter' => '_target_path',
|
||||
'use_referer' => false,
|
||||
'failure_path' => null,
|
||||
'failure_forward' => false,
|
||||
);
|
||||
|
||||
public function create(ContainerBuilder $container, $id, $config, $userProviderId, $defaultEntryPointId)
|
||||
{
|
||||
if (!is_array($config)) {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
// merge set options with default options
|
||||
$options = $this->getOptionsFromConfig($config);
|
||||
|
||||
// authentication provider
|
||||
$authProviderId = $this->createAuthProvider($container, $id, $options, $userProviderId);
|
||||
$container
|
||||
->getDefinition($authProviderId)
|
||||
->addTag('security.authentication_provider')
|
||||
;
|
||||
|
||||
// authentication listener
|
||||
$listenerId = $this->createListener($container, $id, $options, $userProviderId);
|
||||
|
||||
// add remember-me aware tag if requested
|
||||
if ($this->isRememberMeAware($config)) {
|
||||
$container
|
||||
->getDefinition($listenerId)
|
||||
->addTag('security.remember_me_aware', array('id' => $id, 'provider' => $userProviderId))
|
||||
;
|
||||
}
|
||||
|
||||
// create entry point if applicable (optional)
|
||||
$entryPointId = $this->createEntryPoint($container, $id, $options, $defaultEntryPointId);
|
||||
|
||||
return array($authProviderId, $listenerId, $entryPointId);
|
||||
}
|
||||
|
||||
public final function addOption($name, $default = null)
|
||||
{
|
||||
$this->options[$name] = $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must return the id of a service which implements the
|
||||
* AuthenticationProviderInterface.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
* @param string $id The unique id of the firewall
|
||||
* @param array $options The options array for this listener
|
||||
* @param string $userProviderId The id of the user provider
|
||||
*
|
||||
* @return string never null, the id of the authentication provider
|
||||
*/
|
||||
abstract protected function createAuthProvider(ContainerBuilder $container, $id, $options, $userProviderId);
|
||||
|
||||
/**
|
||||
* Subclasses must return the id of the abstract listener template.
|
||||
*
|
||||
* Listener definitions should inherit from the AbstractAuthenticationListener
|
||||
* like this:
|
||||
*
|
||||
* <service id="my.listener.id"
|
||||
* class="My\Concrete\Classname"
|
||||
* parent="security.authentication.listener.abstract"
|
||||
* abstract="true" />
|
||||
*
|
||||
* In the above case, this method would return "my.listener.id".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getListenerId();
|
||||
|
||||
/**
|
||||
* Subclasses may create an entry point of their as they see fit. The
|
||||
* default implementation does not change the default entry point.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
* @param string $id
|
||||
* @param array $options
|
||||
* @param string $defaultEntryPointId
|
||||
*
|
||||
* @return string the entry point id
|
||||
*/
|
||||
protected function createEntryPoint($container, $id, $options, $defaultEntryPointId)
|
||||
{
|
||||
return $defaultEntryPointId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may disable remember-me features for the listener, by
|
||||
* always returning false from this method.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return Boolean Whether a possibly configured RememberMeServices should be set for this listener
|
||||
*/
|
||||
protected function isRememberMeAware($config)
|
||||
{
|
||||
return !isset($config['remember_me']) || (Boolean) $config['remember_me'];
|
||||
}
|
||||
|
||||
protected function createListener($container, $id, $options, $userProvider)
|
||||
{
|
||||
$listenerId = $this->getListenerId();
|
||||
$listener = new DefinitionDecorator($listenerId);
|
||||
$listener->setArgument(3, $id);
|
||||
$listener->setArgument(4, $options);
|
||||
|
||||
// success handler
|
||||
if (isset($config['success_handler'])) {
|
||||
$listener->setArgument(5, new Reference($config['success_handler']));
|
||||
}
|
||||
|
||||
// failure handler
|
||||
if (isset($config['failure_handler'])) {
|
||||
$listener->setArgument(6, new Reference($config['failure_handler']));
|
||||
}
|
||||
|
||||
$listenerId .= '.'.$id;
|
||||
$container->setDefinition($listenerId, $listener);
|
||||
|
||||
return $listenerId;
|
||||
}
|
||||
|
||||
protected final function getOptionsFromConfig($config)
|
||||
{
|
||||
$options = $this->options;
|
||||
|
||||
foreach (array_keys($options) as $key) {
|
||||
if (array_key_exists($key, $config)) {
|
||||
$options[$key] = $config[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
@ -19,71 +19,15 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
* FormLoginFactory creates services for form login authentication.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class FormLoginFactory implements SecurityFactoryInterface
|
||||
class FormLoginFactory extends AbstractFactory
|
||||
{
|
||||
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
|
||||
public function __construct()
|
||||
{
|
||||
$provider = 'security.authentication.provider.dao.'.$id;
|
||||
$container
|
||||
->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao'))
|
||||
->setArgument(0, new Reference($userProvider))
|
||||
->setArgument(2, $id)
|
||||
->addTag('security.authentication_provider')
|
||||
;
|
||||
|
||||
// listener
|
||||
$listenerId = 'security.authentication.listener.form.'.$id;
|
||||
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.form'));
|
||||
$listener->setArgument(3, $id);
|
||||
|
||||
// add remember-me tag
|
||||
$rememberMe = true;
|
||||
if (isset($config['remember_me']) && false === $config['remember_me']) {
|
||||
$rememberMe = false;
|
||||
}
|
||||
if ($rememberMe) {
|
||||
$listener->addTag('security.remember_me_aware', array('id' => $id, 'provider' => $userProvider));
|
||||
}
|
||||
|
||||
// generate options
|
||||
$options = array(
|
||||
'check_path' => '/login_check',
|
||||
'login_path' => '/login',
|
||||
'use_forward' => false,
|
||||
'always_use_default_target_path' => false,
|
||||
'default_target_path' => '/',
|
||||
'target_path_parameter' => '_target_path',
|
||||
'use_referer' => false,
|
||||
'failure_path' => null,
|
||||
'failure_forward' => false,
|
||||
);
|
||||
foreach (array_keys($options) as $key) {
|
||||
if (array_key_exists($key, $config)) {
|
||||
$options[$key] = $config[$key];
|
||||
}
|
||||
}
|
||||
$listener->setArgument(4, $options);
|
||||
|
||||
// success handler
|
||||
if (isset($config['success_handler'])) {
|
||||
$listener->setArgument(5, new Reference($config['success_handler']));
|
||||
}
|
||||
|
||||
// failure handler
|
||||
if (isset($config['failure_handler'])) {
|
||||
$listener->setArgument(6, new Reference($config['failure_handler']));
|
||||
}
|
||||
|
||||
// form entry point
|
||||
$entryPointId = 'security.authentication.form_entry_point.'.$id;
|
||||
$container
|
||||
->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.form_entry_point'))
|
||||
->addArgument($options['login_path'])
|
||||
->addArgument($options['use_forward'])
|
||||
;
|
||||
|
||||
return array($provider, $listenerId, $entryPointId);
|
||||
$this->addOption('username_parameter', '_username');
|
||||
$this->addOption('password_parameter', '_password');
|
||||
$this->addOption('post_only', true);
|
||||
}
|
||||
|
||||
public function getPosition()
|
||||
@ -95,4 +39,33 @@ class FormLoginFactory implements SecurityFactoryInterface
|
||||
{
|
||||
return 'form-login';
|
||||
}
|
||||
|
||||
protected function getListenerId()
|
||||
{
|
||||
return 'security.authentication.listener.form';
|
||||
}
|
||||
|
||||
protected function createAuthProvider(ContainerBuilder $container, $id, $options, $userProviderId)
|
||||
{
|
||||
$provider = 'security.authentication.provider.dao.'.$id;
|
||||
$container
|
||||
->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao'))
|
||||
->setArgument(0, new Reference($userProviderId))
|
||||
->setArgument(2, $id)
|
||||
;
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
protected function createEntryPoint($container, $id, $options, $defaultEntryPoint)
|
||||
{
|
||||
$entryPointId = 'security.authentication.form_entry_point.'.$id;
|
||||
$container
|
||||
->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.form_entry_point'))
|
||||
->addArgument($options['login_path'])
|
||||
->addArgument($options['use_forward'])
|
||||
;
|
||||
|
||||
return $entryPointId;
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
'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',
|
||||
);
|
||||
|
||||
$this->assertEquals(array(), array_diff($expectedProviders, $providers));
|
||||
@ -58,7 +61,7 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
foreach (array_keys($arguments[1]) as $contextId) {
|
||||
$contextDef = $container->getDefinition($contextId);
|
||||
$arguments = $contextDef->getArguments();
|
||||
$listeners[] = array_map(function ($ref) { return preg_replace('/\.[a-f0-9]+$/', '', (string) $ref); }, $arguments[0]);
|
||||
$listeners[] = array_map(function ($ref) { return preg_replace('/\.[a-f0-9]+$/', '', (string) $ref); }, $arguments['index_0']);
|
||||
}
|
||||
|
||||
$this->assertEquals(array(
|
||||
|
Reference in New Issue
Block a user