AclProviderTest.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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\Component\Security\Acl\Tests\Dbal;
  11. use Symfony\Component\Security\Acl\Dbal\AclProvider;
  12. use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
  13. use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
  14. use Symfony\Component\Security\Acl\Dbal\Schema;
  15. use Doctrine\DBAL\DriverManager;
  16. /**
  17. * @requires extension pdo_sqlite
  18. */
  19. class AclProviderTest extends \PHPUnit_Framework_TestCase
  20. {
  21. protected $con;
  22. protected $insertClassStmt;
  23. protected $insertEntryStmt;
  24. protected $insertOidStmt;
  25. protected $insertOidAncestorStmt;
  26. protected $insertSidStmt;
  27. /**
  28. * @expectedException \Symfony\Component\Security\Acl\Exception\AclNotFoundException
  29. * @expectedMessage There is no ACL for the given object identity.
  30. */
  31. public function testFindAclThrowsExceptionWhenNoAclExists()
  32. {
  33. $this->getProvider()->findAcl(new ObjectIdentity('foo', 'foo'));
  34. }
  35. public function testFindAclsThrowsExceptionUnlessAnACLIsFoundForEveryOID()
  36. {
  37. $oids = array();
  38. $oids[] = new ObjectIdentity('1', 'foo');
  39. $oids[] = new ObjectIdentity('foo', 'foo');
  40. try {
  41. $this->getProvider()->findAcls($oids);
  42. $this->fail('Provider did not throw an expected exception.');
  43. } catch (\Exception $e) {
  44. $this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\AclNotFoundException', $e);
  45. $this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\NotAllAclsFoundException', $e);
  46. $partialResult = $e->getPartialResult();
  47. $this->assertTrue($partialResult->contains($oids[0]));
  48. $this->assertFalse($partialResult->contains($oids[1]));
  49. }
  50. }
  51. public function testFindAcls()
  52. {
  53. $oids = array();
  54. $oids[] = new ObjectIdentity('1', 'foo');
  55. $oids[] = new ObjectIdentity('2', 'foo');
  56. $provider = $this->getProvider();
  57. $acls = $provider->findAcls($oids);
  58. $this->assertInstanceOf('SplObjectStorage', $acls);
  59. $this->assertCount(2, $acls);
  60. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
  61. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
  62. $this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
  63. $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
  64. }
  65. public function testFindAclsWithDifferentTypes()
  66. {
  67. $oids = array();
  68. $oids[] = new ObjectIdentity('123', 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity');
  69. $oids[] = new ObjectIdentity('123', 'Bundle\MyBundle\Entity\AnotherEntity');
  70. $provider = $this->getProvider();
  71. $acls = $provider->findAcls($oids);
  72. $this->assertInstanceOf('SplObjectStorage', $acls);
  73. $this->assertCount(2, $acls);
  74. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
  75. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
  76. $this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
  77. $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
  78. }
  79. public function testFindAclCachesAclInMemory()
  80. {
  81. $oid = new ObjectIdentity('1', 'foo');
  82. $provider = $this->getProvider();
  83. $acl = $provider->findAcl($oid);
  84. $this->assertSame($acl, $cAcl = $provider->findAcl($oid));
  85. $cAces = $cAcl->getObjectAces();
  86. foreach ($acl->getObjectAces() as $index => $ace) {
  87. $this->assertSame($ace, $cAces[$index]);
  88. }
  89. }
  90. public function testFindAcl()
  91. {
  92. $oid = new ObjectIdentity('1', 'foo');
  93. $provider = $this->getProvider();
  94. $acl = $provider->findAcl($oid);
  95. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl);
  96. $this->assertTrue($oid->equals($acl->getObjectIdentity()));
  97. $this->assertEquals(4, $acl->getId());
  98. $this->assertCount(0, $acl->getClassAces());
  99. $this->assertCount(0, $this->getField($acl, 'classFieldAces'));
  100. $this->assertCount(3, $acl->getObjectAces());
  101. $this->assertCount(0, $this->getField($acl, 'objectFieldAces'));
  102. $aces = $acl->getObjectAces();
  103. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Entry', $aces[0]);
  104. $this->assertTrue($aces[0]->isGranting());
  105. $this->assertTrue($aces[0]->isAuditSuccess());
  106. $this->assertTrue($aces[0]->isAuditFailure());
  107. $this->assertEquals('all', $aces[0]->getStrategy());
  108. $this->assertSame(2, $aces[0]->getMask());
  109. // check ACE are in correct order
  110. $i = 0;
  111. foreach ($aces as $index => $ace) {
  112. $this->assertEquals($i, $index);
  113. ++$i;
  114. }
  115. $sid = $aces[0]->getSecurityIdentity();
  116. $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\UserSecurityIdentity', $sid);
  117. $this->assertEquals('john.doe', $sid->getUsername());
  118. $this->assertEquals('SomeClass', $sid->getClass());
  119. }
  120. protected function setUp()
  121. {
  122. $this->con = DriverManager::getConnection(array(
  123. 'driver' => 'pdo_sqlite',
  124. 'memory' => true,
  125. ));
  126. // import the schema
  127. $schema = new Schema($options = $this->getOptions());
  128. foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
  129. $this->con->exec($sql);
  130. }
  131. // populate the schema with some test data
  132. $this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
  133. foreach ($this->getClassData() as $data) {
  134. $this->insertClassStmt->execute($data);
  135. }
  136. $this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
  137. foreach ($this->getSidData() as $data) {
  138. $this->insertSidStmt->execute($data);
  139. }
  140. $this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
  141. foreach ($this->getOidData() as $data) {
  142. $this->insertOidStmt->execute($data);
  143. }
  144. $this->insertEntryStmt = $this->con->prepare('INSERT INTO acl_entries (id, class_id, object_identity_id, field_name, ace_order, security_identity_id, mask, granting, granting_strategy, audit_success, audit_failure) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
  145. foreach ($this->getEntryData() as $data) {
  146. $this->insertEntryStmt->execute($data);
  147. }
  148. $this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
  149. foreach ($this->getOidAncestorData() as $data) {
  150. $this->insertOidAncestorStmt->execute($data);
  151. }
  152. }
  153. protected function tearDown()
  154. {
  155. $this->con = null;
  156. }
  157. protected function getField($object, $field)
  158. {
  159. $reflection = new \ReflectionProperty($object, $field);
  160. $reflection->setAccessible(true);
  161. return $reflection->getValue($object);
  162. }
  163. protected function getEntryData()
  164. {
  165. // id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
  166. return array(
  167. array(1, 1, 1, null, 0, 1, 1, 1, 'all', 1, 1),
  168. array(2, 1, 1, null, 1, 2, 1 << 2 | 1 << 1, 0, 'any', 0, 0),
  169. array(3, 3, 4, null, 0, 1, 2, 1, 'all', 1, 1),
  170. array(4, 3, 4, null, 2, 2, 1, 1, 'all', 1, 1),
  171. array(5, 3, 4, null, 1, 3, 1, 1, 'all', 1, 1),
  172. );
  173. }
  174. protected function getOidData()
  175. {
  176. // id, cid, oid, parent_oid, entries_inheriting
  177. return array(
  178. array(1, 1, '123', null, 1),
  179. array(2, 2, '123', 1, 1),
  180. array(3, 2, 'i:3:123', 1, 1),
  181. array(4, 3, '1', 2, 1),
  182. array(5, 3, '2', 2, 1),
  183. );
  184. }
  185. protected function getOidAncestorData()
  186. {
  187. return array(
  188. array(1, 1),
  189. array(2, 1),
  190. array(2, 2),
  191. array(3, 1),
  192. array(3, 3),
  193. array(4, 2),
  194. array(4, 1),
  195. array(4, 4),
  196. array(5, 2),
  197. array(5, 1),
  198. array(5, 5),
  199. );
  200. }
  201. protected function getSidData()
  202. {
  203. return array(
  204. array(1, 'SomeClass-john.doe', 1),
  205. array(2, 'MyClass-john.doe@foo.com', 1),
  206. array(3, 'FooClass-123', 1),
  207. array(4, 'MooClass-ROLE_USER', 1),
  208. array(5, 'ROLE_USER', 0),
  209. array(6, 'IS_AUTHENTICATED_FULLY', 0),
  210. );
  211. }
  212. protected function getClassData()
  213. {
  214. return array(
  215. array(1, 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity'),
  216. array(2, 'Bundle\MyBundle\Entity\AnotherEntity'),
  217. array(3, 'foo'),
  218. );
  219. }
  220. protected function getOptions()
  221. {
  222. return array(
  223. 'oid_table_name' => 'acl_object_identities',
  224. 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
  225. 'class_table_name' => 'acl_classes',
  226. 'sid_table_name' => 'acl_security_identities',
  227. 'entry_table_name' => 'acl_entries',
  228. );
  229. }
  230. protected function getStrategy()
  231. {
  232. return new PermissionGrantingStrategy();
  233. }
  234. protected function getProvider()
  235. {
  236. return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
  237. }
  238. }