Configuration.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
  3. use Symfony\Component\Config\Definition\Builder\TreeBuilder;
  4. /**
  5. * This class contains the configuration information for the following tags:
  6. *
  7. * * security.config
  8. * * security.acl
  9. *
  10. * This information is solely responsible for how the different configuration
  11. * sections are normalized, and merged.
  12. *
  13. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  14. */
  15. class Configuration
  16. {
  17. public function getFactoryConfigTree()
  18. {
  19. $tb = new TreeBuilder();
  20. return $tb
  21. ->root('security', 'array')
  22. ->ignoreExtraKeys()
  23. ->fixXmlConfig('factory', 'factories')
  24. ->arrayNode('factories')
  25. ->prototype('scalar')->end()
  26. ->end()
  27. ->end()
  28. ->buildTree();
  29. }
  30. public function getMainConfigTree(array $factories)
  31. {
  32. $tb = new TreeBuilder();
  33. $rootNode = $tb->root('security', 'array');
  34. $rootNode
  35. ->scalarNode('access_denied_url')->defaultNull()->end()
  36. ->scalarNode('session_fixation_strategy')->cannotBeEmpty()->defaultValue('migrate')->end()
  37. ;
  38. $this->addAclSection($rootNode);
  39. $this->addEncodersSection($rootNode);
  40. $this->addProvidersSection($rootNode);
  41. $this->addFirewallsSection($rootNode, $factories);
  42. $this->addAccessControlSection($rootNode);
  43. $this->addRoleHierarchySection($rootNode);
  44. return $tb->buildTree();
  45. }
  46. protected function addAclSection($rootNode)
  47. {
  48. $rootNode
  49. ->arrayNode('acl')
  50. ->scalarNode('connection')->end()
  51. ->scalarNode('cache')->end()
  52. ->end()
  53. ;
  54. }
  55. protected function addRoleHierarchySection($rootNode)
  56. {
  57. $rootNode
  58. ->fixXmlConfig('role', 'role_hierarchy')
  59. ->arrayNode('role_hierarchy')
  60. ->useAttributeAsKey('id')
  61. ->prototype('array')
  62. ->performNoDeepMerging()
  63. ->beforeNormalization()->ifString()->then(function($v) { return array('value' => $v); })->end()
  64. ->beforeNormalization()
  65. ->ifTrue(function($v) { return is_array($v) && isset($v['value']); })
  66. ->then(function($v) { return preg_split('/\s*,\s*/', $v['value']); })
  67. ->end()
  68. ->prototype('scalar')->end()
  69. ->end()
  70. ->end()
  71. ;
  72. }
  73. protected function addAccessControlSection($rootNode)
  74. {
  75. $rootNode
  76. ->fixXmlConfig('rule', 'access_control')
  77. ->arrayNode('access_control')
  78. ->cannotBeOverwritten()
  79. ->prototype('array')
  80. ->scalarNode('requires_channel')->defaultNull()->end()
  81. ->scalarNode('path')->defaultNull()->end()
  82. ->scalarNode('host')->defaultNull()->end()
  83. ->scalarNode('ip')->defaultNull()->end()
  84. ->arrayNode('methods')
  85. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  86. ->prototype('scalar')->end()
  87. ->end()
  88. ->fixXmlConfig('role')
  89. ->arrayNode('roles')
  90. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  91. ->prototype('scalar')->end()
  92. ->end()
  93. ->fixXmlConfig('attribute')
  94. ->arrayNode('attributes')
  95. ->useAttributeAsKey('key')
  96. ->prototype('scalar')
  97. ->beforeNormalization()
  98. ->ifTrue(function($v) { return is_array($v) && isset($v['pattern']); })
  99. ->then(function($v) { return $v['pattern']; })
  100. ->end()
  101. ->end()
  102. ->end()
  103. ->end()
  104. ->end()
  105. ;
  106. }
  107. protected function addFirewallsSection($rootNode, array $factories)
  108. {
  109. $firewallNodeBuilder =
  110. $rootNode
  111. ->fixXmlConfig('firewall')
  112. ->arrayNode('firewalls')
  113. ->isRequired()
  114. ->requiresAtLeastOneElement()
  115. ->disallowNewKeysInSubsequentConfigs()
  116. ->useAttributeAsKey('name')
  117. ->prototype('array')
  118. ->scalarNode('pattern')->end()
  119. ->booleanNode('security')->defaultTrue()->end()
  120. ->scalarNode('request_matcher')->end()
  121. ->scalarNode('access_denied_url')->end()
  122. ->scalarNode('access_denied_handler')->end()
  123. ->scalarNode('entry_point')->end()
  124. ->scalarNode('provider')->end()
  125. ->booleanNode('stateless')->defaultFalse()->end()
  126. ->scalarNode('context')->cannotBeEmpty()->end()
  127. ->arrayNode('logout')
  128. ->treatTrueLike(array())
  129. ->canBeUnset()
  130. ->scalarNode('path')->defaultValue('/logout')->end()
  131. ->scalarNode('target')->defaultValue('/')->end()
  132. ->scalarNode('success_handler')->end()
  133. ->booleanNode('invalidate_session')->defaultTrue()->end()
  134. ->fixXmlConfig('delete_cookie')
  135. ->arrayNode('delete_cookies')
  136. ->beforeNormalization()
  137. ->ifTrue(function($v) { return is_array($v) && is_int(key($v)); })
  138. ->then(function($v) { return array_map(function($v) { return array('name' => $v); }, $v); })
  139. ->end()
  140. ->useAttributeAsKey('name')
  141. ->prototype('array')
  142. ->scalarNode('path')->defaultNull()->end()
  143. ->scalarNode('domain')->defaultNull()->end()
  144. ->end()
  145. ->end()
  146. ->fixXmlConfig('handler')
  147. ->arrayNode('handlers')
  148. ->prototype('scalar')->end()
  149. ->end()
  150. ->end()
  151. ->booleanNode('anonymous')->defaultFalse()->end()
  152. ->arrayNode('switch_user')
  153. ->scalarNode('provider')->end()
  154. ->scalarNode('parameter')->defaultValue('_switch_user')->end()
  155. ->scalarNode('role')->defaultValue('ROLE_ALLOWED_TO_SWITCH')->end()
  156. ->end()
  157. ;
  158. foreach ($factories as $factoriesAtPosition) {
  159. foreach ($factoriesAtPosition as $factory) {
  160. $factoryNode =
  161. $firewallNodeBuilder->arrayNode(str_replace('-', '_', $factory->getKey()))
  162. ->canBeUnset()
  163. ;
  164. $factory->addConfiguration($factoryNode);
  165. }
  166. }
  167. }
  168. protected function addProvidersSection($rootNode)
  169. {
  170. $rootNode
  171. ->fixXmlConfig('provider')
  172. ->arrayNode('providers')
  173. ->disallowNewKeysInSubsequentConfigs()
  174. ->isRequired()
  175. ->requiresAtLeastOneElement()
  176. ->useAttributeAsKey('name')
  177. ->prototype('array')
  178. ->scalarNode('id')->end()
  179. ->fixXmlConfig('provider')
  180. ->arrayNode('providers')
  181. ->beforeNormalization()
  182. ->ifString()
  183. ->then(function($v) { return preg_split('/\s*,\s*/', $v); })
  184. ->end()
  185. ->prototype('scalar')->end()
  186. ->end()
  187. ->fixXmlConfig('user')
  188. ->arrayNode('users')
  189. ->useAttributeAsKey('name')
  190. ->prototype('array')
  191. ->scalarNode('password')->defaultValue(uniqid())->end()
  192. ->arrayNode('roles')
  193. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  194. ->prototype('scalar')->end()
  195. ->end()
  196. ->end()
  197. ->end()
  198. ->arrayNode('entity')
  199. ->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
  200. ->scalarNode('property')->defaultNull()->end()
  201. ->end()
  202. ->end()
  203. ->end()
  204. ;
  205. }
  206. protected function addEncodersSection($rootNode)
  207. {
  208. $rootNode
  209. ->fixXmlConfig('encoder')
  210. ->arrayNode('encoders')
  211. ->requiresAtLeastOneElement()
  212. ->useAttributeAsKey('class')
  213. ->prototype('array')
  214. ->canBeUnset()
  215. ->performNoDeepMerging()
  216. ->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
  217. ->scalarNode('algorithm')->cannotBeEmpty()->end()
  218. ->booleanNode('ignore_case')->end()
  219. ->booleanNode('encode_as_base64')->end()
  220. ->scalarNode('iterations')->end()
  221. ->scalarNode('id')->end()
  222. ->end()
  223. ->end()
  224. ;
  225. }
  226. }