Configuration.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. // add a faux-entry for factories, so that no validation error is thrown
  38. ->fixXmlConfig('factory', 'factories')
  39. ->arrayNode('factories')
  40. ->ignoreExtraKeys()
  41. ->end()
  42. ;
  43. $this->addAclSection($rootNode);
  44. $this->addEncodersSection($rootNode);
  45. $this->addProvidersSection($rootNode);
  46. $this->addFirewallsSection($rootNode, $factories);
  47. $this->addAccessControlSection($rootNode);
  48. $this->addRoleHierarchySection($rootNode);
  49. return $tb->buildTree();
  50. }
  51. private function addAclSection($rootNode)
  52. {
  53. $rootNode
  54. ->arrayNode('acl')
  55. ->scalarNode('connection')->end()
  56. ->scalarNode('cache')->end()
  57. ->end()
  58. ;
  59. }
  60. private function addRoleHierarchySection($rootNode)
  61. {
  62. $rootNode
  63. ->fixXmlConfig('role', 'role_hierarchy')
  64. ->arrayNode('role_hierarchy')
  65. ->useAttributeAsKey('id')
  66. ->prototype('array')
  67. ->performNoDeepMerging()
  68. ->beforeNormalization()->ifString()->then(function($v) { return array('value' => $v); })->end()
  69. ->beforeNormalization()
  70. ->ifTrue(function($v) { return is_array($v) && isset($v['value']); })
  71. ->then(function($v) { return preg_split('/\s*,\s*/', $v['value']); })
  72. ->end()
  73. ->prototype('scalar')->end()
  74. ->end()
  75. ->end()
  76. ;
  77. }
  78. private function addAccessControlSection($rootNode)
  79. {
  80. $rootNode
  81. ->fixXmlConfig('rule', 'access_control')
  82. ->arrayNode('access_control')
  83. ->cannotBeOverwritten()
  84. ->prototype('array')
  85. ->scalarNode('requires_channel')->defaultNull()->end()
  86. ->scalarNode('path')->defaultNull()->end()
  87. ->scalarNode('host')->defaultNull()->end()
  88. ->scalarNode('ip')->defaultNull()->end()
  89. ->arrayNode('methods')
  90. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  91. ->prototype('scalar')->end()
  92. ->end()
  93. ->fixXmlConfig('role')
  94. ->arrayNode('roles')
  95. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  96. ->prototype('scalar')->end()
  97. ->end()
  98. ->end()
  99. ->end()
  100. ;
  101. }
  102. private function addFirewallsSection($rootNode, array $factories)
  103. {
  104. $firewallNodeBuilder =
  105. $rootNode
  106. ->fixXmlConfig('firewall')
  107. ->arrayNode('firewalls')
  108. ->isRequired()
  109. ->requiresAtLeastOneElement()
  110. ->disallowNewKeysInSubsequentConfigs()
  111. ->useAttributeAsKey('name')
  112. ->prototype('array')
  113. ->scalarNode('pattern')->end()
  114. ->booleanNode('security')->defaultTrue()->end()
  115. ->scalarNode('request_matcher')->end()
  116. ->scalarNode('access_denied_url')->end()
  117. ->scalarNode('access_denied_handler')->end()
  118. ->scalarNode('entry_point')->end()
  119. ->scalarNode('provider')->end()
  120. ->booleanNode('stateless')->defaultFalse()->end()
  121. ->scalarNode('context')->cannotBeEmpty()->end()
  122. ->arrayNode('logout')
  123. ->treatTrueLike(array())
  124. ->canBeUnset()
  125. ->scalarNode('path')->defaultValue('/logout')->end()
  126. ->scalarNode('target')->defaultValue('/')->end()
  127. ->scalarNode('success_handler')->end()
  128. ->booleanNode('invalidate_session')->defaultTrue()->end()
  129. ->fixXmlConfig('delete_cookie')
  130. ->arrayNode('delete_cookies')
  131. ->beforeNormalization()
  132. ->ifTrue(function($v) { return is_array($v) && is_int(key($v)); })
  133. ->then(function($v) { return array_map(function($v) { return array('name' => $v); }, $v); })
  134. ->end()
  135. ->useAttributeAsKey('name')
  136. ->prototype('array')
  137. ->scalarNode('path')->defaultNull()->end()
  138. ->scalarNode('domain')->defaultNull()->end()
  139. ->end()
  140. ->end()
  141. ->fixXmlConfig('handler')
  142. ->arrayNode('handlers')
  143. ->prototype('scalar')->end()
  144. ->end()
  145. ->end()
  146. ->arrayNode('anonymous')
  147. ->scalarNode('key')->defaultValue(function () { return uniqid(); })->end()
  148. ->end()
  149. ->arrayNode('switch_user')
  150. ->scalarNode('provider')->end()
  151. ->scalarNode('parameter')->defaultValue('_switch_user')->end()
  152. ->scalarNode('role')->defaultValue('ROLE_ALLOWED_TO_SWITCH')->end()
  153. ->end()
  154. ;
  155. foreach ($factories as $factoriesAtPosition) {
  156. foreach ($factoriesAtPosition as $factory) {
  157. $factoryNode =
  158. $firewallNodeBuilder->arrayNode(str_replace('-', '_', $factory->getKey()))
  159. ->canBeUnset()
  160. ;
  161. $factory->addConfiguration($factoryNode);
  162. }
  163. }
  164. }
  165. private function addProvidersSection($rootNode)
  166. {
  167. $rootNode
  168. ->fixXmlConfig('provider')
  169. ->arrayNode('providers')
  170. ->disallowNewKeysInSubsequentConfigs()
  171. ->isRequired()
  172. ->requiresAtLeastOneElement()
  173. ->useAttributeAsKey('name')
  174. ->prototype('array')
  175. ->scalarNode('id')->end()
  176. ->fixXmlConfig('provider')
  177. ->arrayNode('providers')
  178. ->beforeNormalization()
  179. ->ifString()
  180. ->then(function($v) { return preg_split('/\s*,\s*/', $v); })
  181. ->end()
  182. ->prototype('scalar')->end()
  183. ->end()
  184. ->fixXmlConfig('user')
  185. ->arrayNode('users')
  186. ->useAttributeAsKey('name')
  187. ->prototype('array')
  188. ->scalarNode('password')->defaultValue(uniqid())->end()
  189. ->arrayNode('roles')
  190. ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end()
  191. ->prototype('scalar')->end()
  192. ->end()
  193. ->end()
  194. ->end()
  195. ->arrayNode('entity')
  196. ->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
  197. ->scalarNode('property')->defaultNull()->end()
  198. ->end()
  199. ->end()
  200. ->end()
  201. ;
  202. }
  203. private function addEncodersSection($rootNode)
  204. {
  205. $rootNode
  206. ->fixXmlConfig('encoder')
  207. ->arrayNode('encoders')
  208. ->requiresAtLeastOneElement()
  209. ->useAttributeAsKey('class')
  210. ->prototype('array')
  211. ->canBeUnset()
  212. ->performNoDeepMerging()
  213. ->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
  214. ->scalarNode('algorithm')->cannotBeEmpty()->end()
  215. ->booleanNode('ignore_case')->defaultFalse()->end()
  216. ->booleanNode('encode_as_base64')->defaultTrue()->end()
  217. ->scalarNode('iterations')->defaultValue(5000)->end()
  218. ->scalarNode('id')->end()
  219. ->end()
  220. ->end()
  221. ;
  222. }
  223. }