/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php

https://bitbucket.org/hill2steve/mobileroom · PHP · 197 lines · 102 code · 31 blank · 64 comment · 5 complexity · 816e094d5681e6b5b0cf0371ff7a71ea MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
  11. use Symfony\Component\Config\Definition\Builder\NodeDefinition;
  12. use Symfony\Component\DependencyInjection\DefinitionDecorator;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\DependencyInjection\Reference;
  15. /**
  16. * AbstractFactory is the base class for all classes inheriting from
  17. * AbstractAuthenticationListener
  18. *
  19. * @author Lukas Kahwe Smith <smith@pooteeweet.org>
  20. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  21. */
  22. abstract class AbstractFactory implements SecurityFactoryInterface
  23. {
  24. protected $options = array(
  25. 'check_path' => '/login_check',
  26. 'use_forward' => false,
  27. );
  28. protected $defaultSuccessHandlerOptions = array(
  29. 'always_use_default_target_path' => false,
  30. 'default_target_path' => '/',
  31. 'login_path' => '/login',
  32. 'target_path_parameter' => '_target_path',
  33. 'use_referer' => false,
  34. );
  35. protected $defaultFailureHandlerOptions = array(
  36. 'failure_path' => null,
  37. 'failure_forward' => false,
  38. 'login_path' => '/login',
  39. );
  40. public function create(ContainerBuilder $container, $id, $config, $userProviderId, $defaultEntryPointId)
  41. {
  42. // authentication provider
  43. $authProviderId = $this->createAuthProvider($container, $id, $config, $userProviderId);
  44. // authentication listener
  45. $listenerId = $this->createListener($container, $id, $config, $userProviderId);
  46. // add remember-me aware tag if requested
  47. if ($this->isRememberMeAware($config)) {
  48. $container
  49. ->getDefinition($listenerId)
  50. ->addTag('security.remember_me_aware', array('id' => $id, 'provider' => $userProviderId))
  51. ;
  52. }
  53. // create entry point if applicable (optional)
  54. $entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPointId);
  55. return array($authProviderId, $listenerId, $entryPointId);
  56. }
  57. public function addConfiguration(NodeDefinition $node)
  58. {
  59. $builder = $node->children();
  60. $builder
  61. ->scalarNode('provider')->end()
  62. ->booleanNode('remember_me')->defaultTrue()->end()
  63. ->scalarNode('success_handler')->end()
  64. ->scalarNode('failure_handler')->end()
  65. ;
  66. foreach (array_merge($this->options, $this->defaultSuccessHandlerOptions, $this->defaultFailureHandlerOptions) as $name => $default) {
  67. if (is_bool($default)) {
  68. $builder->booleanNode($name)->defaultValue($default);
  69. } else {
  70. $builder->scalarNode($name)->defaultValue($default);
  71. }
  72. }
  73. }
  74. final public function addOption($name, $default = null)
  75. {
  76. $this->options[$name] = $default;
  77. }
  78. /**
  79. * Subclasses must return the id of a service which implements the
  80. * AuthenticationProviderInterface.
  81. *
  82. * @param ContainerBuilder $container
  83. * @param string $id The unique id of the firewall
  84. * @param array $config The options array for this listener
  85. * @param string $userProviderId The id of the user provider
  86. *
  87. * @return string never null, the id of the authentication provider
  88. */
  89. abstract protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId);
  90. /**
  91. * Subclasses must return the id of the abstract listener template.
  92. *
  93. * Listener definitions should inherit from the AbstractAuthenticationListener
  94. * like this:
  95. *
  96. * <service id="my.listener.id"
  97. * class="My\Concrete\Classname"
  98. * parent="security.authentication.listener.abstract"
  99. * abstract="true" />
  100. *
  101. * In the above case, this method would return "my.listener.id".
  102. *
  103. * @return string
  104. */
  105. abstract protected function getListenerId();
  106. /**
  107. * Subclasses may create an entry point of their as they see fit. The
  108. * default implementation does not change the default entry point.
  109. *
  110. * @param ContainerBuilder $container
  111. * @param string $id
  112. * @param array $config
  113. * @param string $defaultEntryPointId
  114. *
  115. * @return string the entry point id
  116. */
  117. protected function createEntryPoint($container, $id, $config, $defaultEntryPointId)
  118. {
  119. return $defaultEntryPointId;
  120. }
  121. /**
  122. * Subclasses may disable remember-me features for the listener, by
  123. * always returning false from this method.
  124. *
  125. * @param array $config
  126. *
  127. * @return Boolean Whether a possibly configured RememberMeServices should be set for this listener
  128. */
  129. protected function isRememberMeAware($config)
  130. {
  131. return $config['remember_me'];
  132. }
  133. protected function createListener($container, $id, $config, $userProvider)
  134. {
  135. $listenerId = $this->getListenerId();
  136. $listener = new DefinitionDecorator($listenerId);
  137. $listener->replaceArgument(4, $id);
  138. $listener->replaceArgument(5, new Reference($this->createAuthenticationSuccessHandler($container, $id, $config)));
  139. $listener->replaceArgument(6, new Reference($this->createAuthenticationFailureHandler($container, $id, $config)));
  140. $listener->replaceArgument(7, array_intersect_key($config, $this->options));
  141. $listenerId .= '.'.$id;
  142. $container->setDefinition($listenerId, $listener);
  143. return $listenerId;
  144. }
  145. protected function createAuthenticationSuccessHandler($container, $id, $config)
  146. {
  147. if (isset($config['success_handler'])) {
  148. return $config['success_handler'];
  149. }
  150. $successHandlerId = 'security.authentication.success_handler.'.$id.'.'.str_replace('-', '_', $this->getKey());
  151. $successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.success_handler'));
  152. $successHandler->replaceArgument(1, array_intersect_key($config, $this->defaultSuccessHandlerOptions));
  153. $successHandler->addMethodCall('setProviderKey', array($id));
  154. return $successHandlerId;
  155. }
  156. protected function createAuthenticationFailureHandler($container, $id, $config)
  157. {
  158. if (isset($config['failure_handler'])) {
  159. return $config['failure_handler'];
  160. }
  161. $id = 'security.authentication.failure_handler.'.$id.'.'.str_replace('-', '_', $this->getKey());
  162. $failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.failure_handler'));
  163. $failureHandler->replaceArgument(2, array_intersect_key($config, $this->defaultFailureHandlerOptions));
  164. return $id;
  165. }
  166. }