Configuration.php 12 KB

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