summaryrefslogtreecommitdiffstats
path: root/Acl/Tests/Domain
diff options
context:
space:
mode:
Diffstat (limited to 'Acl/Tests/Domain')
-rw-r--r--Acl/Tests/Domain/AclTest.php513
-rw-r--r--Acl/Tests/Domain/AuditLoggerTest.php83
-rw-r--r--Acl/Tests/Domain/DoctrineAclCacheTest.php101
-rw-r--r--Acl/Tests/Domain/EntryTest.php119
-rw-r--r--Acl/Tests/Domain/FieldEntryTest.php74
-rw-r--r--Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php41
-rw-r--r--Acl/Tests/Domain/ObjectIdentityTest.php135
-rw-r--r--Acl/Tests/Domain/PermissionGrantingStrategyTest.php186
-rw-r--r--Acl/Tests/Domain/RoleSecurityIdentityTest.php55
-rw-r--r--Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php196
-rw-r--r--Acl/Tests/Domain/UserSecurityIdentityTest.php73
11 files changed, 1576 insertions, 0 deletions
diff --git a/Acl/Tests/Domain/AclTest.php b/Acl/Tests/Domain/AclTest.php
new file mode 100644
index 0000000..84b9ba9
--- /dev/null
+++ b/Acl/Tests/Domain/AclTest.php
@@ -0,0 +1,513 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\Acl;
+
+class AclTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $acl = new Acl(1, $oid = new ObjectIdentity('foo', 'foo'), $permissionStrategy = new PermissionGrantingStrategy(), array(), true);
+
+ $this->assertSame(1, $acl->getId());
+ $this->assertSame($oid, $acl->getObjectIdentity());
+ $this->assertNull($acl->getParentAcl());
+ $this->assertTrue($acl->isEntriesInheriting());
+ }
+
+ /**
+ * @expectedException \OutOfBoundsException
+ * @dataProvider getDeleteAceTests
+ */
+ public function testDeleteAceThrowsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'delete'.$type.'Ace'}(0);
+ }
+
+ /**
+ * @dataProvider getDeleteAceTests
+ */
+ public function testDeleteAce($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 1);
+ $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 2, 1);
+ $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 3, 2);
+
+ $listener = $this->getListener(array(
+ $type.'Aces', 'aceOrder', 'aceOrder', $type.'Aces',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $this->assertCount(3, $acl->{'get'.$type.'Aces'}());
+
+ $acl->{'delete'.$type.'Ace'}(0);
+ $this->assertCount(2, $aces = $acl->{'get'.$type.'Aces'}());
+ $this->assertEquals(2, $aces[0]->getMask());
+ $this->assertEquals(3, $aces[1]->getMask());
+
+ $acl->{'delete'.$type.'Ace'}(1);
+ $this->assertCount(1, $aces = $acl->{'get'.$type.'Aces'}());
+ $this->assertEquals(2, $aces[0]->getMask());
+ }
+
+ public function getDeleteAceTests()
+ {
+ return array(
+ array('class'),
+ array('object'),
+ );
+ }
+
+ /**
+ * @expectedException \OutOfBoundsException
+ * @dataProvider getDeleteFieldAceTests
+ */
+ public function testDeleteFieldAceThrowsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'delete'.$type.'Ace'}('foo', 0);
+ }
+
+ /**
+ * @dataProvider getDeleteFieldAceTests
+ */
+ public function testDeleteFieldAce($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1, 0);
+ $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 2, 1);
+ $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 3, 2);
+
+ $listener = $this->getListener(array(
+ $type.'Aces', 'aceOrder', 'aceOrder', $type.'Aces',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $this->assertCount(3, $acl->{'get'.$type.'Aces'}('foo'));
+
+ $acl->{'delete'.$type.'Ace'}(0, 'foo');
+ $this->assertCount(2, $aces = $acl->{'get'.$type.'Aces'}('foo'));
+ $this->assertEquals(2, $aces[0]->getMask());
+ $this->assertEquals(3, $aces[1]->getMask());
+
+ $acl->{'delete'.$type.'Ace'}(1, 'foo');
+ $this->assertCount(1, $aces = $acl->{'get'.$type.'Aces'}('foo'));
+ $this->assertEquals(2, $aces[0]->getMask());
+ }
+
+ public function getDeleteFieldAceTests()
+ {
+ return array(
+ array('classField'),
+ array('objectField'),
+ );
+ }
+
+ /**
+ * @dataProvider getInsertAceTests
+ */
+ public function testInsertAce($property, $method)
+ {
+ $acl = $this->getAcl();
+
+ $listener = $this->getListener(array(
+ $property, 'aceOrder', $property, 'aceOrder', $property,
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $sid = new RoleSecurityIdentity('foo');
+ $acl->$method($sid, 1);
+ $acl->$method($sid, 2);
+ $acl->$method($sid, 3, 1, false);
+
+ $this->assertCount(3, $aces = $acl->{'get'.$property}());
+ $this->assertEquals(2, $aces[0]->getMask());
+ $this->assertEquals(3, $aces[1]->getMask());
+ $this->assertEquals(1, $aces[2]->getMask());
+ }
+
+ /**
+ * @expectedException \OutOfBoundsException
+ * @dataProvider getInsertAceTests
+ */
+ public function testInsertClassAceThrowsExceptionOnInvalidIndex($property, $method)
+ {
+ $acl = $this->getAcl();
+ $acl->$method(new RoleSecurityIdentity('foo'), 1, 1);
+ }
+
+ public function getInsertAceTests()
+ {
+ return array(
+ array('classAces', 'insertClassAce'),
+ array('objectAces', 'insertObjectAce'),
+ );
+ }
+
+ /**
+ * @dataProvider getInsertFieldAceTests
+ */
+ public function testInsertClassFieldAce($property, $method)
+ {
+ $acl = $this->getAcl();
+
+ $listener = $this->getListener(array(
+ $property, $property, 'aceOrder', $property,
+ 'aceOrder', 'aceOrder', $property,
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $sid = new RoleSecurityIdentity('foo');
+ $acl->$method('foo', $sid, 1);
+ $acl->$method('foo2', $sid, 1);
+ $acl->$method('foo', $sid, 3);
+ $acl->$method('foo', $sid, 2);
+
+ $this->assertCount(3, $aces = $acl->{'get'.$property}('foo'));
+ $this->assertCount(1, $acl->{'get'.$property}('foo2'));
+ $this->assertEquals(2, $aces[0]->getMask());
+ $this->assertEquals(3, $aces[1]->getMask());
+ $this->assertEquals(1, $aces[2]->getMask());
+ }
+
+ /**
+ * @expectedException \OutOfBoundsException
+ * @dataProvider getInsertFieldAceTests
+ */
+ public function testInsertClassFieldAceThrowsExceptionOnInvalidIndex($property, $method)
+ {
+ $acl = $this->getAcl();
+ $acl->$method('foo', new RoleSecurityIdentity('foo'), 1, 1);
+ }
+
+ public function getInsertFieldAceTests()
+ {
+ return array(
+ array('classFieldAces', 'insertClassFieldAce'),
+ array('objectFieldAces', 'insertObjectFieldAce'),
+ );
+ }
+
+ public function testIsFieldGranted()
+ {
+ $sids = array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_IDDQD'));
+ $masks = array(1, 2, 4);
+ $strategy = $this->getMock('Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface');
+ $acl = new Acl(1, new ObjectIdentity(1, 'foo'), $strategy, array(), true);
+
+ $strategy
+ ->expects($this->once())
+ ->method('isFieldGranted')
+ ->with($this->equalTo($acl), $this->equalTo('foo'), $this->equalTo($masks), $this->equalTo($sids), $this->isTrue())
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($acl->isFieldGranted('foo', $masks, $sids, true));
+ }
+
+ public function testIsGranted()
+ {
+ $sids = array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_IDDQD'));
+ $masks = array(1, 2, 4);
+ $strategy = $this->getMock('Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface');
+ $acl = new Acl(1, new ObjectIdentity(1, 'foo'), $strategy, array(), true);
+
+ $strategy
+ ->expects($this->once())
+ ->method('isGranted')
+ ->with($this->equalTo($acl), $this->equalTo($masks), $this->equalTo($sids), $this->isTrue())
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($acl->isGranted($masks, $sids, true));
+ }
+
+ public function testSetGetParentAcl()
+ {
+ $acl = $this->getAcl();
+ $parentAcl = $this->getAcl();
+
+ $listener = $this->getListener(array('parentAcl'));
+ $acl->addPropertyChangedListener($listener);
+
+ $this->assertNull($acl->getParentAcl());
+ $acl->setParentAcl($parentAcl);
+ $this->assertSame($parentAcl, $acl->getParentAcl());
+
+ $acl->setParentAcl(null);
+ $this->assertNull($acl->getParentAcl());
+ }
+
+ public function testSetIsEntriesInheriting()
+ {
+ $acl = $this->getAcl();
+
+ $listener = $this->getListener(array('entriesInheriting'));
+ $acl->addPropertyChangedListener($listener);
+
+ $this->assertTrue($acl->isEntriesInheriting());
+ $acl->setEntriesInheriting(false);
+ $this->assertFalse($acl->isEntriesInheriting());
+ }
+
+ public function testIsSidLoadedWhenAllSidsAreLoaded()
+ {
+ $acl = $this->getAcl();
+
+ $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('foo', 'Foo')));
+ $this->assertTrue($acl->isSidLoaded(new RoleSecurityIdentity('ROLE_FOO', 'Foo')));
+ }
+
+ public function testIsSidLoaded()
+ {
+ $acl = new Acl(1, new ObjectIdentity('1', 'foo'), new PermissionGrantingStrategy(), array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('johannes', 'Bar')), true);
+
+ $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('foo', 'Foo')));
+ $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('johannes', 'Bar')));
+ $this->assertTrue($acl->isSidLoaded(array(
+ new UserSecurityIdentity('foo', 'Foo'),
+ new UserSecurityIdentity('johannes', 'Bar'),
+ )));
+ $this->assertFalse($acl->isSidLoaded(new RoleSecurityIdentity('ROLE_FOO')));
+ $this->assertFalse($acl->isSidLoaded(new UserSecurityIdentity('schmittjoh@gmail.com', 'Moo')));
+ $this->assertFalse($acl->isSidLoaded(array(
+ new UserSecurityIdentity('foo', 'Foo'),
+ new UserSecurityIdentity('johannes', 'Bar'),
+ new RoleSecurityIdentity('ROLE_FOO'),
+ )));
+ }
+
+ /**
+ * @dataProvider getUpdateAceTests
+ * @expectedException \OutOfBoundsException
+ */
+ public function testUpdateAceThrowsOutOfBoundsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'update'.$type}(0, 1);
+ }
+
+ /**
+ * @dataProvider getUpdateAceTests
+ */
+ public function testUpdateAce($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type}(new RoleSecurityIdentity('foo'), 1);
+
+ $listener = $this->getListener(array(
+ 'mask', 'mask', 'strategy',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $aces = $acl->{'get'.$type.'s'}();
+ $ace = reset($aces);
+ $this->assertEquals(1, $ace->getMask());
+ $this->assertEquals('all', $ace->getStrategy());
+
+ $acl->{'update'.$type}(0, 3);
+ $this->assertEquals(3, $ace->getMask());
+ $this->assertEquals('all', $ace->getStrategy());
+
+ $acl->{'update'.$type}(0, 1, 'foo');
+ $this->assertEquals(1, $ace->getMask());
+ $this->assertEquals('foo', $ace->getStrategy());
+ }
+
+ public function getUpdateAceTests()
+ {
+ return array(
+ array('classAce'),
+ array('objectAce'),
+ );
+ }
+
+ /**
+ * @dataProvider getUpdateFieldAceTests
+ * @expectedException \OutOfBoundsException
+ */
+ public function testUpdateFieldAceThrowsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'update'.$type}(0, 'foo', 1);
+ }
+
+ /**
+ * @dataProvider getUpdateFieldAceTests
+ */
+ public function testUpdateFieldAce($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type}('foo', new UserSecurityIdentity('foo', 'Foo'), 1);
+
+ $listener = $this->getListener(array(
+ 'mask', 'mask', 'strategy',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $aces = $acl->{'get'.$type.'s'}('foo');
+ $ace = reset($aces);
+ $this->assertEquals(1, $ace->getMask());
+ $this->assertEquals('all', $ace->getStrategy());
+
+ $acl->{'update'.$type}(0, 'foo', 3);
+ $this->assertEquals(3, $ace->getMask());
+ $this->assertEquals('all', $ace->getStrategy());
+
+ $acl->{'update'.$type}(0, 'foo', 1, 'foo');
+ $this->assertEquals(1, $ace->getMask());
+ $this->assertEquals('foo', $ace->getStrategy());
+ }
+
+ public function getUpdateFieldAceTests()
+ {
+ return array(
+ array('classFieldAce'),
+ array('objectFieldAce'),
+ );
+ }
+
+ /**
+ * @dataProvider getUpdateAuditingTests
+ * @expectedException \OutOfBoundsException
+ */
+ public function testUpdateAuditingThrowsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'update'.$type.'Auditing'}(0, true, false);
+ }
+
+ /**
+ * @dataProvider getUpdateAuditingTests
+ */
+ public function testUpdateAuditing($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 1);
+
+ $listener = $this->getListener(array(
+ 'auditFailure', 'auditSuccess', 'auditFailure',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $aces = $acl->{'get'.$type.'Aces'}();
+ $ace = reset($aces);
+ $this->assertFalse($ace->isAuditSuccess());
+ $this->assertFalse($ace->isAuditFailure());
+
+ $acl->{'update'.$type.'Auditing'}(0, false, true);
+ $this->assertFalse($ace->isAuditSuccess());
+ $this->assertTrue($ace->isAuditFailure());
+
+ $acl->{'update'.$type.'Auditing'}(0, true, false);
+ $this->assertTrue($ace->isAuditSuccess());
+ $this->assertFalse($ace->isAuditFailure());
+ }
+
+ public function getUpdateAuditingTests()
+ {
+ return array(
+ array('class'),
+ array('object'),
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getUpdateFieldAuditingTests
+ */
+ public function testUpdateFieldAuditingThrowsExceptionOnInvalidField($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'update'.$type.'Auditing'}(0, 'foo', true, true);
+ }
+
+ /**
+ * @expectedException \OutOfBoundsException
+ * @dataProvider getUpdateFieldAuditingTests
+ */
+ public function testUpdateFieldAuditingThrowsExceptionOnInvalidIndex($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1);
+ $acl->{'update'.$type.'Auditing'}(1, 'foo', true, false);
+ }
+
+ /**
+ * @dataProvider getUpdateFieldAuditingTests
+ */
+ public function testUpdateFieldAuditing($type)
+ {
+ $acl = $this->getAcl();
+ $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1);
+
+ $listener = $this->getListener(array(
+ 'auditSuccess', 'auditSuccess', 'auditFailure',
+ ));
+ $acl->addPropertyChangedListener($listener);
+
+ $aces = $acl->{'get'.$type.'Aces'}('foo');
+ $ace = reset($aces);
+ $this->assertFalse($ace->isAuditSuccess());
+ $this->assertFalse($ace->isAuditFailure());
+
+ $acl->{'update'.$type.'Auditing'}(0, 'foo', true, false);
+ $this->assertTrue($ace->isAuditSuccess());
+ $this->assertFalse($ace->isAuditFailure());
+
+ $acl->{'update'.$type.'Auditing'}(0, 'foo', false, true);
+ $this->assertFalse($ace->isAuditSuccess());
+ $this->assertTrue($ace->isAuditFailure());
+ }
+
+ public function getUpdateFieldAuditingTests()
+ {
+ return array(
+ array('classField'),
+ array('objectField'),
+ );
+ }
+
+ protected function getListener($expectedChanges)
+ {
+ $aceProperties = array('aceOrder', 'mask', 'strategy', 'auditSuccess', 'auditFailure');
+
+ $listener = $this->getMock('Doctrine\Common\PropertyChangedListener');
+ foreach ($expectedChanges as $index => $property) {
+ if (in_array($property, $aceProperties)) {
+ $class = 'Symfony\Component\Security\Acl\Domain\Entry';
+ } else {
+ $class = 'Symfony\Component\Security\Acl\Domain\Acl';
+ }
+
+ $listener
+ ->expects($this->at($index))
+ ->method('propertyChanged')
+ ->with($this->isInstanceOf($class), $this->equalTo($property))
+ ;
+ }
+
+ return $listener;
+ }
+
+ protected function getAcl()
+ {
+ return new Acl(1, new ObjectIdentity(1, 'foo'), new PermissionGrantingStrategy(), array(), true);
+ }
+}
diff --git a/Acl/Tests/Domain/AuditLoggerTest.php b/Acl/Tests/Domain/AuditLoggerTest.php
new file mode 100644
index 0000000..15538d3
--- /dev/null
+++ b/Acl/Tests/Domain/AuditLoggerTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+class AuditLoggerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTestLogData
+ */
+ public function testLogIfNeeded($granting, $audit)
+ {
+ $logger = $this->getLogger();
+ $ace = $this->getEntry();
+
+ if (true === $granting) {
+ $ace
+ ->expects($this->once())
+ ->method('isAuditSuccess')
+ ->will($this->returnValue($audit))
+ ;
+
+ $ace
+ ->expects($this->never())
+ ->method('isAuditFailure')
+ ;
+ } else {
+ $ace
+ ->expects($this->never())
+ ->method('isAuditSuccess')
+ ;
+
+ $ace
+ ->expects($this->once())
+ ->method('isAuditFailure')
+ ->will($this->returnValue($audit))
+ ;
+ }
+
+ if (true === $audit) {
+ $logger
+ ->expects($this->once())
+ ->method('doLog')
+ ->with($this->equalTo($granting), $this->equalTo($ace))
+ ;
+ } else {
+ $logger
+ ->expects($this->never())
+ ->method('doLog')
+ ;
+ }
+
+ $logger->logIfNeeded($granting, $ace);
+ }
+
+ public function getTestLogData()
+ {
+ return array(
+ array(true, false),
+ array(true, true),
+ array(false, false),
+ array(false, true),
+ );
+ }
+
+ protected function getEntry()
+ {
+ return $this->getMock('Symfony\Component\Security\Acl\Model\AuditableEntryInterface');
+ }
+
+ protected function getLogger()
+ {
+ return $this->getMockForAbstractClass('Symfony\Component\Security\Acl\Domain\AuditLogger');
+ }
+}
diff --git a/Acl/Tests/Domain/DoctrineAclCacheTest.php b/Acl/Tests/Domain/DoctrineAclCacheTest.php
new file mode 100644
index 0000000..255f7f4
--- /dev/null
+++ b/Acl/Tests/Domain/DoctrineAclCacheTest.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
+use Symfony\Component\Security\Acl\Domain\Acl;
+use Symfony\Component\Security\Acl\Domain\DoctrineAclCache;
+use Doctrine\Common\Cache\ArrayCache;
+
+class DoctrineAclCacheTest extends \PHPUnit_Framework_TestCase
+{
+ protected $permissionGrantingStrategy;
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getEmptyValue
+ */
+ public function testConstructorDoesNotAcceptEmptyPrefix($empty)
+ {
+ new DoctrineAclCache(new ArrayCache(), $this->getPermissionGrantingStrategy(), $empty);
+ }
+
+ public function getEmptyValue()
+ {
+ return array(
+ array(null),
+ array(false),
+ array(''),
+ );
+ }
+
+ public function test()
+ {
+ $cache = $this->getCache();
+
+ $aclWithParent = $this->getAcl(1);
+ $acl = $this->getAcl();
+
+ $cache->putInCache($aclWithParent);
+ $cache->putInCache($acl);
+
+ $cachedAcl = $cache->getFromCacheByIdentity($acl->getObjectIdentity());
+ $this->assertEquals($acl->getId(), $cachedAcl->getId());
+ $this->assertNull($acl->getParentAcl());
+
+ $cachedAclWithParent = $cache->getFromCacheByIdentity($aclWithParent->getObjectIdentity());
+ $this->assertEquals($aclWithParent->getId(), $cachedAclWithParent->getId());
+ $this->assertNotNull($cachedParentAcl = $cachedAclWithParent->getParentAcl());
+ $this->assertEquals($aclWithParent->getParentAcl()->getId(), $cachedParentAcl->getId());
+ }
+
+ protected function getAcl($depth = 0)
+ {
+ static $id = 1;
+
+ $acl = new Acl($id, new ObjectIdentity($id, 'foo'), $this->getPermissionGrantingStrategy(), array(), $depth > 0);
+
+ // insert some ACEs
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+ $acl->insertClassAce($sid, 1);
+ $acl->insertClassFieldAce('foo', $sid, 1);
+ $acl->insertObjectAce($sid, 1);
+ $acl->insertObjectFieldAce('foo', $sid, 1);
+ ++$id;
+
+ if ($depth > 0) {
+ $acl->setParentAcl($this->getAcl($depth - 1));
+ }
+
+ return $acl;
+ }
+
+ protected function getPermissionGrantingStrategy()
+ {
+ if (null === $this->permissionGrantingStrategy) {
+ $this->permissionGrantingStrategy = new PermissionGrantingStrategy();
+ }
+
+ return $this->permissionGrantingStrategy;
+ }
+
+ protected function getCache($cacheDriver = null, $prefix = DoctrineAclCache::PREFIX)
+ {
+ if (null === $cacheDriver) {
+ $cacheDriver = new ArrayCache();
+ }
+
+ return new DoctrineAclCache($cacheDriver, $this->getPermissionGrantingStrategy(), $prefix);
+ }
+}
diff --git a/Acl/Tests/Domain/EntryTest.php b/Acl/Tests/Domain/EntryTest.php
new file mode 100644
index 0000000..ab8e481
--- /dev/null
+++ b/Acl/Tests/Domain/EntryTest.php
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\Entry;
+
+class EntryTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $ace = $this->getAce($acl = $this->getAcl(), $sid = $this->getSid());
+
+ $this->assertEquals(123, $ace->getId());
+ $this->assertSame($acl, $ace->getAcl());
+ $this->assertSame($sid, $ace->getSecurityIdentity());
+ $this->assertEquals('foostrat', $ace->getStrategy());
+ $this->assertEquals(123456, $ace->getMask());
+ $this->assertTrue($ace->isGranting());
+ $this->assertTrue($ace->isAuditSuccess());
+ $this->assertFalse($ace->isAuditFailure());
+ }
+
+ public function testSetAuditSuccess()
+ {
+ $ace = $this->getAce();
+
+ $this->assertTrue($ace->isAuditSuccess());
+ $ace->setAuditSuccess(false);
+ $this->assertFalse($ace->isAuditSuccess());
+ $ace->setAuditSuccess(true);
+ $this->assertTrue($ace->isAuditSuccess());
+ }
+
+ public function testSetAuditFailure()
+ {
+ $ace = $this->getAce();
+
+ $this->assertFalse($ace->isAuditFailure());
+ $ace->setAuditFailure(true);
+ $this->assertTrue($ace->isAuditFailure());
+ $ace->setAuditFailure(false);
+ $this->assertFalse($ace->isAuditFailure());
+ }
+
+ public function testSetMask()
+ {
+ $ace = $this->getAce();
+
+ $this->assertEquals(123456, $ace->getMask());
+ $ace->setMask(4321);
+ $this->assertEquals(4321, $ace->getMask());
+ }
+
+ public function testSetStrategy()
+ {
+ $ace = $this->getAce();
+
+ $this->assertEquals('foostrat', $ace->getStrategy());
+ $ace->setStrategy('foo');
+ $this->assertEquals('foo', $ace->getStrategy());
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $ace = $this->getAce();
+
+ $serialized = serialize($ace);
+ $uAce = unserialize($serialized);
+
+ $this->assertNull($uAce->getAcl());
+ $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity());
+ $this->assertEquals($ace->getId(), $uAce->getId());
+ $this->assertEquals($ace->getMask(), $uAce->getMask());
+ $this->assertEquals($ace->getStrategy(), $uAce->getStrategy());
+ $this->assertEquals($ace->isGranting(), $uAce->isGranting());
+ $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess());
+ $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure());
+ }
+
+ protected function getAce($acl = null, $sid = null)
+ {
+ if (null === $acl) {
+ $acl = $this->getAcl();
+ }
+ if (null === $sid) {
+ $sid = $this->getSid();
+ }
+
+ return new Entry(
+ 123,
+ $acl,
+ $sid,
+ 'foostrat',
+ 123456,
+ true,
+ false,
+ true
+ );
+ }
+
+ protected function getAcl()
+ {
+ return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface');
+ }
+
+ protected function getSid()
+ {
+ return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface');
+ }
+}
diff --git a/Acl/Tests/Domain/FieldEntryTest.php b/Acl/Tests/Domain/FieldEntryTest.php
new file mode 100644
index 0000000..735e2e8
--- /dev/null
+++ b/Acl/Tests/Domain/FieldEntryTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\FieldEntry;
+
+class FieldEntryTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $ace = $this->getAce();
+
+ $this->assertEquals('foo', $ace->getField());
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $ace = $this->getAce();
+
+ $serialized = serialize($ace);
+ $uAce = unserialize($serialized);
+
+ $this->assertNull($uAce->getAcl());
+ $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity());
+ $this->assertEquals($ace->getId(), $uAce->getId());
+ $this->assertEquals($ace->getField(), $uAce->getField());
+ $this->assertEquals($ace->getMask(), $uAce->getMask());
+ $this->assertEquals($ace->getStrategy(), $uAce->getStrategy());
+ $this->assertEquals($ace->isGranting(), $uAce->isGranting());
+ $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess());
+ $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure());
+ }
+
+ protected function getAce($acl = null, $sid = null)
+ {
+ if (null === $acl) {
+ $acl = $this->getAcl();
+ }
+ if (null === $sid) {
+ $sid = $this->getSid();
+ }
+
+ return new FieldEntry(
+ 123,
+ $acl,
+ 'foo',
+ $sid,
+ 'foostrat',
+ 123456,
+ true,
+ false,
+ true
+ );
+ }
+
+ protected function getAcl()
+ {
+ return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface');
+ }
+
+ protected function getSid()
+ {
+ return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface');
+ }
+}
diff --git a/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
new file mode 100644
index 0000000..59fc3bd
--- /dev/null
+++ b/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy;
+
+class ObjectIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetObjectIdentityReturnsNullForInvalidDomainObject()
+ {
+ $strategy = new ObjectIdentityRetrievalStrategy();
+ $this->assertNull($strategy->getObjectIdentity('foo'));
+ }
+
+ public function testGetObjectIdentity()
+ {
+ $strategy = new ObjectIdentityRetrievalStrategy();
+ $domainObject = new DomainObject();
+ $objectIdentity = $strategy->getObjectIdentity($domainObject);
+
+ $this->assertEquals($domainObject->getId(), $objectIdentity->getIdentifier());
+ $this->assertEquals(get_class($domainObject), $objectIdentity->getType());
+ }
+}
+
+class DomainObject
+{
+ public function getId()
+ {
+ return 'foo';
+ }
+}
diff --git a/Acl/Tests/Domain/ObjectIdentityTest.php b/Acl/Tests/Domain/ObjectIdentityTest.php
new file mode 100644
index 0000000..770ada7
--- /dev/null
+++ b/Acl/Tests/Domain/ObjectIdentityTest.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain
+{
+ use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+ use Symfony\Component\Security\Acl\Model\DomainObjectInterface;
+
+ class ObjectIdentityTest extends \PHPUnit_Framework_TestCase
+ {
+ public function testConstructor()
+ {
+ $id = new ObjectIdentity('fooid', 'footype');
+
+ $this->assertEquals('fooid', $id->getIdentifier());
+ $this->assertEquals('footype', $id->getType());
+ }
+
+ // Test that constructor never changes passed type, even with proxies
+ public function testConstructorWithProxy()
+ {
+ $id = new ObjectIdentity('fooid', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject');
+
+ $this->assertEquals('fooid', $id->getIdentifier());
+ $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
+ }
+
+ public function testFromDomainObjectPrefersInterfaceOverGetId()
+ {
+ $domainObject = new DomainObjectImplementation();
+
+ $id = ObjectIdentity::fromDomainObject($domainObject);
+ $this->assertEquals('getObjectIdentifier()', $id->getIdentifier());
+ }
+
+ public function testFromDomainObjectWithoutInterface()
+ {
+ $id = ObjectIdentity::fromDomainObject(new TestDomainObject());
+ $this->assertEquals('getId()', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
+ }
+
+ public function testFromDomainObjectWithProxy()
+ {
+ $id = ObjectIdentity::fromDomainObject(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject());
+ $this->assertEquals('getId()', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
+ }
+
+ public function testFromDomainObjectWithoutInterfaceEnforcesStringIdentifier()
+ {
+ $domainObject = new TestDomainObject();
+ $domainObject->id = 1;
+ $id = ObjectIdentity::fromDomainObject($domainObject);
+
+ $this->assertSame('1', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
+ }
+
+ public function testFromDomainObjectWithoutInterfaceAllowsZeroAsIdentifier()
+ {
+ $domainObject = new TestDomainObject();
+ $domainObject->id = '0';
+ $id = ObjectIdentity::fromDomainObject($domainObject);
+
+ $this->assertSame('0', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
+ }
+
+ /**
+ * @dataProvider getCompareData
+ */
+ public function testEquals($oid1, $oid2, $equal)
+ {
+ if ($equal) {
+ $this->assertTrue($oid1->equals($oid2));
+ } else {
+ $this->assertFalse($oid1->equals($oid2));
+ }
+ }
+
+ public function getCompareData()
+ {
+ return array(
+ array(new ObjectIdentity('123', 'foo'), new ObjectIdentity('123', 'foo'), true),
+ array(new ObjectIdentity('123', 'foo'), new ObjectIdentity(123, 'foo'), true),
+ array(new ObjectIdentity('1', 'foo'), new ObjectIdentity('2', 'foo'), false),
+ array(new ObjectIdentity('1', 'bla'), new ObjectIdentity('1', 'blub'), false),
+ );
+ }
+ }
+
+ class TestDomainObject
+ {
+ public $id = 'getId()';
+
+ public function getObjectIdentifier()
+ {
+ return 'getObjectIdentifier()';
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+ }
+
+ class DomainObjectImplementation implements DomainObjectInterface
+ {
+ public function getObjectIdentifier()
+ {
+ return 'getObjectIdentifier()';
+ }
+
+ public function getId()
+ {
+ return 'getId()';
+ }
+ }
+}
+
+namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain
+{
+ class TestDomainObject extends \Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject
+ {
+ }
+}
diff --git a/Acl/Tests/Domain/PermissionGrantingStrategyTest.php b/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
new file mode 100644
index 0000000..34ef690
--- /dev/null
+++ b/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
@@ -0,0 +1,186 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\Acl;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
+use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
+
+class PermissionGrantingStrategyTest extends \PHPUnit_Framework_TestCase
+{
+ public function testIsGrantedObjectAcesHavePriority()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $acl->insertClassAce($sid, 1);
+ $acl->insertObjectAce($sid, 1, 0, false);
+ $this->assertFalse($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ public function testIsGrantedFallsBackToClassAcesIfNoApplicableObjectAceWasFound()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $acl->insertClassAce($sid, 1);
+ $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ public function testIsGrantedFavorsLocalAcesOverParentAclAces()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $acl = $this->getAcl($strategy);
+ $acl->insertClassAce($sid, 1);
+
+ $parentAcl = $this->getAcl($strategy);
+ $acl->setParentAcl($parentAcl);
+ $parentAcl->insertClassAce($sid, 1, 0, false);
+
+ $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ public function testIsGrantedFallsBackToParentAcesIfNoLocalAcesAreApplicable()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+ $anotherSid = new UserSecurityIdentity('ROLE_USER', 'Foo');
+
+ $acl = $this->getAcl($strategy);
+ $acl->insertClassAce($anotherSid, 1, 0, false);
+
+ $parentAcl = $this->getAcl($strategy);
+ $acl->setParentAcl($parentAcl);
+ $parentAcl->insertClassAce($sid, 1);
+
+ $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Acl\Exception\NoAceFoundException
+ */
+ public function testIsGrantedReturnsExceptionIfNoAceIsFound()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $strategy->isGranted($acl, array(1), array($sid));
+ }
+
+ public function testIsGrantedFirstApplicableEntryMakesUltimateDecisionForPermissionIdentityCombination()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+ $aSid = new RoleSecurityIdentity('ROLE_USER');
+
+ $acl->insertClassAce($aSid, 1);
+ $acl->insertClassAce($sid, 1, 1, false);
+ $acl->insertClassAce($sid, 1, 2);
+ $this->assertFalse($strategy->isGranted($acl, array(1), array($sid, $aSid)));
+
+ $acl->insertObjectAce($sid, 1, 0, false);
+ $acl->insertObjectAce($aSid, 1, 1);
+ $this->assertFalse($strategy->isGranted($acl, array(1), array($sid, $aSid)));
+ }
+
+ public function testIsGrantedCallsAuditLoggerOnGrant()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $logger = $this->getMock('Symfony\Component\Security\Acl\Model\AuditLoggerInterface');
+ $logger
+ ->expects($this->once())
+ ->method('logIfNeeded')
+ ;
+ $strategy->setAuditLogger($logger);
+
+ $acl->insertObjectAce($sid, 1);
+ $acl->updateObjectAuditing(0, true, false);
+
+ $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ public function testIsGrantedCallsAuditLoggerOnDeny()
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $logger = $this->getMock('Symfony\Component\Security\Acl\Model\AuditLoggerInterface');
+ $logger
+ ->expects($this->once())
+ ->method('logIfNeeded')
+ ;
+ $strategy->setAuditLogger($logger);
+
+ $acl->insertObjectAce($sid, 1, 0, false);
+ $acl->updateObjectAuditing(0, false, true);
+
+ $this->assertFalse($strategy->isGranted($acl, array(1), array($sid)));
+ }
+
+ /**
+ * @dataProvider getAllStrategyTests
+ */
+ public function testIsGrantedStrategies($maskStrategy, $aceMask, $requiredMask, $result)
+ {
+ $strategy = new PermissionGrantingStrategy();
+ $acl = $this->getAcl($strategy);
+ $sid = new UserSecurityIdentity('johannes', 'Foo');
+
+ $acl->insertObjectAce($sid, $aceMask, 0, true, $maskStrategy);
+
+ if (false === $result) {
+ try {
+ $strategy->isGranted($acl, array($requiredMask), array($sid));
+ $this->fail('The ACE is not supposed to match.');
+ } catch (NoAceFoundException $e) {
+ }
+ } else {
+ $this->assertTrue($strategy->isGranted($acl, array($requiredMask), array($sid)));
+ }
+ }
+
+ public function getAllStrategyTests()
+ {
+ return array(
+ array('all', 1 << 0 | 1 << 1, 1 << 0, true),
+ array('all', 1 << 0 | 1 << 1, 1 << 2, false),
+ array('all', 1 << 0 | 1 << 10, 1 << 0 | 1 << 10, true),
+ array('all', 1 << 0 | 1 << 1, 1 << 0 | 1 << 1 || 1 << 2, false),
+ array('any', 1 << 0 | 1 << 1, 1 << 0, true),
+ array('any', 1 << 0 | 1 << 1, 1 << 0 | 1 << 2, true),
+ array('any', 1 << 0 | 1 << 1, 1 << 2, false),
+ array('equal', 1 << 0 | 1 << 1, 1 << 0, false),
+ array('equal', 1 << 0 | 1 << 1, 1 << 1, false),
+ array('equal', 1 << 0 | 1 << 1, 1 << 0 | 1 << 1, true),
+ );
+ }
+
+ protected function getAcl($strategy)
+ {
+ static $id = 1;
+
+ return new Acl($id++, new ObjectIdentity(1, 'Foo'), $strategy, array(), true);
+ }
+}
diff --git a/Acl/Tests/Domain/RoleSecurityIdentityTest.php b/Acl/Tests/Domain/RoleSecurityIdentityTest.php
new file mode 100644
index 0000000..ad5f236
--- /dev/null
+++ b/Acl/Tests/Domain/RoleSecurityIdentityTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Core\Role\Role;
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+
+class RoleSecurityIdentityTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $id = new RoleSecurityIdentity('ROLE_FOO');
+
+ $this->assertEquals('ROLE_FOO', $id->getRole());
+ }
+
+ public function testConstructorWithRoleInstance()
+ {
+ $id = new RoleSecurityIdentity(new Role('ROLE_FOO'));
+
+ $this->assertEquals('ROLE_FOO', $id->getRole());
+ }
+
+ /**
+ * @dataProvider getCompareData
+ */
+ public function testEquals($id1, $id2, $equal)
+ {
+ if ($equal) {
+ $this->assertTrue($id1->equals($id2));
+ } else {
+ $this->assertFalse($id1->equals($id2));
+ }
+ }
+
+ public function getCompareData()
+ {
+ return array(
+ array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_FOO'), true),
+ array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity(new Role('ROLE_FOO')), true),
+ array(new RoleSecurityIdentity('ROLE_USER'), new RoleSecurityIdentity('ROLE_FOO'), false),
+ array(new RoleSecurityIdentity('ROLE_FOO'), new UserSecurityIdentity('ROLE_FOO', 'Foo'), false),
+ );
+ }
+}
diff --git a/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
new file mode 100644
index 0000000..160c27c
--- /dev/null
+++ b/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy;
+
+class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getSecurityIdentityRetrievalTests
+ */
+ public function testGetSecurityIdentities($user, array $roles, $authenticationStatus, array $sids)
+ {
+ $strategy = $this->getStrategy($roles, $authenticationStatus);
+
+ if ('anonymous' === $authenticationStatus) {
+ $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken')
+ ->disableOriginalConstructor()
+ ->getMock();
+ } else {
+ $class = '';
+ if (is_string($user)) {
+ $class = 'MyCustomTokenImpl';
+ }
+
+ $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')
+ ->setMockClassName($class)
+ ->getMock();
+ }
+ $token
+ ->expects($this->once())
+ ->method('getRoles')
+ ->will($this->returnValue(array('foo')))
+ ;
+ if ('anonymous' === $authenticationStatus) {
+ $token
+ ->expects($this->never())
+ ->method('getUser')
+ ;
+ } else {
+ $token
+ ->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($user))
+ ;
+ }
+
+ $extractedSids = $strategy->getSecurityIdentities($token);
+
+ foreach ($extractedSids as $index => $extractedSid) {
+ if (!isset($sids[$index])) {
+ $this->fail(sprintf('Expected SID at index %d, but there was none.', true));
+ }
+
+ if (false === $sids[$index]->equals($extractedSid)) {
+ $this->fail(sprintf('Index: %d, expected SID "%s", but got "%s".', $index, $sids[$index], $extractedSid));
+ }
+ }
+ }
+
+ public function getSecurityIdentityRetrievalTests()
+ {
+ return array(
+ array($this->getAccount('johannes', 'FooUser'), array('ROLE_USER', 'ROLE_SUPERADMIN'), 'fullFledged', array(
+ new UserSecurityIdentity('johannes', 'FooUser'),
+ new RoleSecurityIdentity('ROLE_USER'),
+ new RoleSecurityIdentity('ROLE_SUPERADMIN'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
+ )),
+ array('johannes', array('ROLE_FOO'), 'fullFledged', array(
+ new UserSecurityIdentity('johannes', 'MyCustomTokenImpl'),
+ new RoleSecurityIdentity('ROLE_FOO'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
+ )),
+ array(new CustomUserImpl('johannes'), array('ROLE_FOO'), 'fullFledged', array(
+ new UserSecurityIdentity('johannes', 'Symfony\Component\Security\Acl\Tests\Domain\CustomUserImpl'),
+ new RoleSecurityIdentity('ROLE_FOO'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
+ )),
+ array($this->getAccount('foo', 'FooBarUser'), array('ROLE_FOO'), 'rememberMe', array(
+ new UserSecurityIdentity('foo', 'FooBarUser'),
+ new RoleSecurityIdentity('ROLE_FOO'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
+ )),
+ array('guest', array('ROLE_FOO'), 'anonymous', array(
+ new RoleSecurityIdentity('ROLE_FOO'),
+ new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
+ )),
+ );
+ }
+
+ protected function getAccount($username, $class)
+ {
+ $account = $this->getMock('Symfony\Component\Security\Core\User\UserInterface', array(), array(), $class);
+ $account
+ ->expects($this->any())
+ ->method('getUsername')
+ ->will($this->returnValue($username))
+ ;
+
+ return $account;
+ }
+
+ protected function getStrategy(array $roles = array(), $authenticationStatus = 'fullFledged')
+ {
+ $roleHierarchy = $this->getMock('Symfony\Component\Security\Core\Role\RoleHierarchyInterface');
+ $roleHierarchy
+ ->expects($this->once())
+ ->method('getReachableRoles')
+ ->with($this->equalTo(array('foo')))
+ ->will($this->returnValue($roles))
+ ;
+
+ $trustResolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver', array(), array('', ''));
+
+ $trustResolver
+ ->expects($this->at(0))
+ ->method('isAnonymous')
+ ->will($this->returnValue('anonymous' === $authenticationStatus))
+ ;
+
+ if ('fullFledged' === $authenticationStatus) {
+ $trustResolver
+ ->expects($this->once())
+ ->method('isFullFledged')
+ ->will($this->returnValue(true))
+ ;
+ $trustResolver
+ ->expects($this->never())
+ ->method('isRememberMe')
+ ;
+ } elseif ('rememberMe' === $authenticationStatus) {
+ $trustResolver
+ ->expects($this->once())
+ ->method('isFullFledged')
+ ->will($this->returnValue(false))
+ ;
+ $trustResolver
+ ->expects($this->once())
+ ->method('isRememberMe')
+ ->will($this->returnValue(true))
+ ;
+ } else {
+ $trustResolver
+ ->expects($this->at(1))
+ ->method('isAnonymous')
+ ->will($this->returnValue(true))
+ ;
+ $trustResolver
+ ->expects($this->once())
+ ->method('isFullFledged')
+ ->will($this->returnValue(false))
+ ;
+ $trustResolver
+ ->expects($this->once())
+ ->method('isRememberMe')
+ ->will($this->returnValue(false))
+ ;
+ }
+
+ return new SecurityIdentityRetrievalStrategy($roleHierarchy, $trustResolver);
+ }
+}
+
+class CustomUserImpl
+{
+ protected $name;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function __toString()
+ {
+ return $this->name;
+ }
+}
diff --git a/Acl/Tests/Domain/UserSecurityIdentityTest.php b/Acl/Tests/Domain/UserSecurityIdentityTest.php
new file mode 100644
index 0000000..09d3f0d
--- /dev/null
+++ b/Acl/Tests/Domain/UserSecurityIdentityTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Tests\Domain;
+
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+
+class UserSecurityIdentityTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $id = new UserSecurityIdentity('foo', 'Foo');
+
+ $this->assertEquals('foo', $id->getUsername());
+ $this->assertEquals('Foo', $id->getClass());
+ }
+
+ // Test that constructor never changes the type, even for proxies
+ public function testConstructorWithProxy()
+ {
+ $id = new UserSecurityIdentity('foo', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo');
+
+ $this->assertEquals('foo', $id->getUsername());
+ $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo', $id->getClass());
+ }
+
+ /**
+ * @dataProvider getCompareData
+ */
+ public function testEquals($id1, $id2, $equal)
+ {
+ $this->assertSame($equal, $id1->equals($id2));
+ }
+
+ public function getCompareData()
+ {
+ $account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')
+ ->setMockClassName('USI_AccountImpl')
+ ->getMock();
+ $account
+ ->expects($this->any())
+ ->method('getUsername')
+ ->will($this->returnValue('foo'))
+ ;
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $token
+ ->expects($this->any())
+ ->method('getUser')
+ ->will($this->returnValue($account))
+ ;
+
+ return array(
+ array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('foo', 'Foo'), true),
+ array(new UserSecurityIdentity('foo', 'Bar'), new UserSecurityIdentity('foo', 'Foo'), false),
+ array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('bar', 'Foo'), false),
+ array(new UserSecurityIdentity('foo', 'Foo'), UserSecurityIdentity::fromAccount($account), false),
+ array(new UserSecurityIdentity('bla', 'Foo'), new UserSecurityIdentity('blub', 'Foo'), false),
+ array(new UserSecurityIdentity('foo', 'Foo'), new RoleSecurityIdentity('foo'), false),
+ array(new UserSecurityIdentity('foo', 'Foo'), UserSecurityIdentity::fromToken($token), false),
+ array(new UserSecurityIdentity('foo', 'USI_AccountImpl'), UserSecurityIdentity::fromToken($token), true),
+ );
+ }
+}