AclVoterTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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\Tests\Component\Security\Acl\Voter;
  11. use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
  12. use Symfony\Component\Security\Acl\Voter\FieldVote;
  13. use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
  14. use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
  15. use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
  16. use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
  17. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  18. use Symfony\Component\Security\Acl\Voter\AclVoter;
  19. class AclVoterTest extends \PHPUnit_Framework_TestCase
  20. {
  21. /**
  22. * @dataProvider getSupportsAttributeTests
  23. */
  24. public function testSupportsAttribute($attribute, $supported)
  25. {
  26. list($voter,, $permissionMap,,) = $this->getVoter();
  27. $permissionMap
  28. ->expects($this->once())
  29. ->method('contains')
  30. ->with($this->identicalTo($attribute))
  31. ->will($this->returnValue($supported))
  32. ;
  33. $this->assertSame($supported, $voter->supportsAttribute($attribute));
  34. }
  35. public function getSupportsAttributeTests()
  36. {
  37. return array(
  38. array('foo', true),
  39. array('foo', false),
  40. );
  41. }
  42. /**
  43. * @dataProvider getSupportsClassTests
  44. */
  45. public function testSupportsClass($class)
  46. {
  47. list($voter,,,,) = $this->getVoter();
  48. $this->assertTrue($voter->supportsClass($class));
  49. }
  50. public function getSupportsClassTests()
  51. {
  52. return array(
  53. array('foo'),
  54. array('bar'),
  55. array('moo'),
  56. );
  57. }
  58. public function testVote()
  59. {
  60. list($voter,, $permissionMap,,) = $this->getVoter();
  61. $permissionMap
  62. ->expects($this->atLeastOnce())
  63. ->method('getMasks')
  64. ->will($this->returnValue(null))
  65. ;
  66. $this->assertSame(VoterInterface::ACCESS_ABSTAIN, $voter->vote($this->getToken(), null, array('VIEW', 'EDIT', 'DELETE')));
  67. }
  68. /**
  69. * @dataProvider getTrueFalseTests
  70. */
  71. public function testVoteWhenNoObjectIsPassed($allowIfObjectIdentityUnavailable)
  72. {
  73. list($voter,, $permissionMap,,) = $this->getVoter($allowIfObjectIdentityUnavailable);
  74. $permissionMap
  75. ->expects($this->once())
  76. ->method('getMasks')
  77. ->will($this->returnValue(array()))
  78. ;
  79. if ($allowIfObjectIdentityUnavailable) {
  80. $vote = VoterInterface::ACCESS_GRANTED;
  81. } else {
  82. $vote = VoterInterface::ACCESS_ABSTAIN;
  83. }
  84. $this->assertSame($vote, $voter->vote($this->getToken(), null, array('VIEW')));
  85. }
  86. /**
  87. * @dataProvider getTrueFalseTests
  88. */
  89. public function testVoteWhenOidStrategyReturnsNull($allowIfUnavailable)
  90. {
  91. list($voter,, $permissionMap, $oidStrategy,) = $this->getVoter($allowIfUnavailable);
  92. $permissionMap
  93. ->expects($this->once())
  94. ->method('getMasks')
  95. ->will($this->returnValue(array()))
  96. ;
  97. $oidStrategy
  98. ->expects($this->once())
  99. ->method('getObjectIdentity')
  100. ->will($this->returnValue(null))
  101. ;
  102. if ($allowIfUnavailable) {
  103. $vote = VoterInterface::ACCESS_GRANTED;
  104. } else {
  105. $vote = VoterInterface::ACCESS_ABSTAIN;
  106. }
  107. $this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
  108. }
  109. public function getTrueFalseTests()
  110. {
  111. return array(array(true), array(false));
  112. }
  113. public function testVoteNoAclFound()
  114. {
  115. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  116. $permissionMap
  117. ->expects($this->once())
  118. ->method('getMasks')
  119. ->will($this->returnValue(array()))
  120. ;
  121. $oidStrategy
  122. ->expects($this->once())
  123. ->method('getObjectIdentity')
  124. ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
  125. ;
  126. $sidStrategy
  127. ->expects($this->once())
  128. ->method('getSecurityIdentities')
  129. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  130. ;
  131. $provider
  132. ->expects($this->once())
  133. ->method('findAcl')
  134. ->with($this->equalTo($oid), $this->equalTo($sids))
  135. ->will($this->throwException(new AclNotFoundException('Not found.')))
  136. ;
  137. $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
  138. }
  139. /**
  140. * @dataProvider getTrueFalseTests
  141. */
  142. public function testVoteGrantsAccess($grant)
  143. {
  144. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  145. $permissionMap
  146. ->expects($this->once())
  147. ->method('getMasks')
  148. ->with($this->equalTo('VIEW'))
  149. ->will($this->returnValue($masks = array(1, 2, 3)))
  150. ;
  151. $oidStrategy
  152. ->expects($this->once())
  153. ->method('getObjectIdentity')
  154. ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
  155. ;
  156. $sidStrategy
  157. ->expects($this->once())
  158. ->method('getSecurityIdentities')
  159. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  160. ;
  161. $provider
  162. ->expects($this->once())
  163. ->method('findAcl')
  164. ->with($this->equalTo($oid), $this->equalTo($sids))
  165. ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
  166. ;
  167. $acl
  168. ->expects($this->once())
  169. ->method('isGranted')
  170. ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
  171. ->will($this->returnValue($grant))
  172. ;
  173. if ($grant) {
  174. $vote = VoterInterface::ACCESS_GRANTED;
  175. } else {
  176. $vote = VoterInterface::ACCESS_DENIED;
  177. }
  178. $this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
  179. }
  180. public function testVoteNoAceFound()
  181. {
  182. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  183. $permissionMap
  184. ->expects($this->once())
  185. ->method('getMasks')
  186. ->with($this->equalTo('VIEW'))
  187. ->will($this->returnValue($masks = array(1, 2, 3)))
  188. ;
  189. $oidStrategy
  190. ->expects($this->once())
  191. ->method('getObjectIdentity')
  192. ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
  193. ;
  194. $sidStrategy
  195. ->expects($this->once())
  196. ->method('getSecurityIdentities')
  197. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  198. ;
  199. $provider
  200. ->expects($this->once())
  201. ->method('findAcl')
  202. ->with($this->equalTo($oid), $this->equalTo($sids))
  203. ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
  204. ;
  205. $acl
  206. ->expects($this->once())
  207. ->method('isGranted')
  208. ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
  209. ->will($this->throwException(new NoAceFoundException('No ACE')))
  210. ;
  211. $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
  212. }
  213. /**
  214. * @dataProvider getTrueFalseTests
  215. */
  216. public function testVoteGrantsFieldAccess($grant)
  217. {
  218. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  219. $permissionMap
  220. ->expects($this->once())
  221. ->method('getMasks')
  222. ->with($this->equalTo('VIEW'))
  223. ->will($this->returnValue($masks = array(1, 2, 3)))
  224. ;
  225. $oidStrategy
  226. ->expects($this->once())
  227. ->method('getObjectIdentity')
  228. ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
  229. ;
  230. $sidStrategy
  231. ->expects($this->once())
  232. ->method('getSecurityIdentities')
  233. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  234. ;
  235. $provider
  236. ->expects($this->once())
  237. ->method('findAcl')
  238. ->with($this->equalTo($oid), $this->equalTo($sids))
  239. ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
  240. ;
  241. $acl
  242. ->expects($this->once())
  243. ->method('isFieldGranted')
  244. ->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
  245. ->will($this->returnValue($grant))
  246. ;
  247. if ($grant) {
  248. $vote = VoterInterface::ACCESS_GRANTED;
  249. } else {
  250. $vote = VoterInterface::ACCESS_DENIED;
  251. }
  252. $this->assertSame($vote, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
  253. }
  254. public function testVoteNoFieldAceFound()
  255. {
  256. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  257. $permissionMap
  258. ->expects($this->once())
  259. ->method('getMasks')
  260. ->with($this->equalTo('VIEW'))
  261. ->will($this->returnValue($masks = array(1, 2, 3)))
  262. ;
  263. $oidStrategy
  264. ->expects($this->once())
  265. ->method('getObjectIdentity')
  266. ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
  267. ;
  268. $sidStrategy
  269. ->expects($this->once())
  270. ->method('getSecurityIdentities')
  271. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  272. ;
  273. $provider
  274. ->expects($this->once())
  275. ->method('findAcl')
  276. ->with($this->equalTo($oid), $this->equalTo($sids))
  277. ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
  278. ;
  279. $acl
  280. ->expects($this->once())
  281. ->method('isFieldGranted')
  282. ->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
  283. ->will($this->throwException(new NoAceFoundException('No ACE')))
  284. ;
  285. $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
  286. }
  287. public function testWhenReceivingAnObjectIdentityInterfaceWeDontRetrieveANewObjectIdentity()
  288. {
  289. list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
  290. $oid = new ObjectIdentity('someID','someType');
  291. $permissionMap
  292. ->expects($this->once())
  293. ->method('getMasks')
  294. ->with($this->equalTo('VIEW'))
  295. ->will($this->returnValue($masks = array(1, 2, 3)))
  296. ;
  297. $oidStrategy
  298. ->expects($this->never())
  299. ->method('getObjectIdentity')
  300. ;
  301. $sidStrategy
  302. ->expects($this->once())
  303. ->method('getSecurityIdentities')
  304. ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
  305. ;
  306. $provider
  307. ->expects($this->once())
  308. ->method('findAcl')
  309. ->with($this->equalTo($oid), $this->equalTo($sids))
  310. ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
  311. ;
  312. $acl
  313. ->expects($this->once())
  314. ->method('isGranted')
  315. ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
  316. ->will($this->throwException(new NoAceFoundException('No ACE')))
  317. ;
  318. $voter->vote($this->getToken(), $oid, array('VIEW'));
  319. }
  320. protected function getToken()
  321. {
  322. return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
  323. }
  324. protected function getVoter($allowIfObjectIdentityUnavailable = true)
  325. {
  326. $provider = $this->getMock('Symfony\Component\Security\Acl\Model\AclProviderInterface');
  327. $permissionMap = $this->getMock('Symfony\Component\Security\Acl\Permission\PermissionMapInterface');
  328. $oidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface');
  329. $sidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface');
  330. return array(
  331. new AclVoter($provider, $oidStrategy, $sidStrategy, $permissionMap, null, $allowIfObjectIdentityUnavailable),
  332. $provider,
  333. $permissionMap,
  334. $oidStrategy,
  335. $sidStrategy,
  336. );
  337. }
  338. }