AclProviderTest.php 9.3 KB

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