Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,267 @@
<?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\Dbal;
use Symfony\Component\Security\Acl\Dbal\AclProvider;
use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Dbal\Schema;
use Doctrine\DBAL\DriverManager;
/**
* @group benchmark
*/
class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
{
/** @var \Doctrine\DBAL\Connection */
protected $con;
protected $insertClassStmt;
protected $insertSidStmt;
protected $insertOidAncestorStmt;
protected $insertOidStmt;
protected $insertEntryStmt;
protected function setUp()
{
try {
$this->con = DriverManager::getConnection(array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'user' => 'root',
'dbname' => 'testdb',
));
$this->con->connect();
} catch (\Exception $e) {
$this->markTestSkipped('Unable to connect to the database: '.$e->getMessage());
}
}
protected function tearDown()
{
$this->con = null;
}
public function testFindAcls()
{
// $this->generateTestData();
// get some random test object identities from the database
$oids = array();
$stmt = $this->con->executeQuery('SELECT object_identifier, class_type FROM acl_object_identities o INNER JOIN acl_classes c ON c.id = o.class_id ORDER BY RAND() LIMIT 25');
foreach ($stmt->fetchAll() as $oid) {
$oids[] = new ObjectIdentity($oid['object_identifier'], $oid['class_type']);
}
$provider = $this->getProvider();
$start = microtime(true);
$provider->findAcls($oids);
$time = microtime(true) - $start;
echo 'Total Time: '.$time."s\n";
}
/**
* This generates a huge amount of test data to be used mainly for benchmarking
* purposes, not so much for testing. That's why it's not called by default.
*/
protected function generateTestData()
{
$sm = $this->con->getSchemaManager();
$sm->dropAndCreateDatabase('testdb');
$this->con->exec('USE testdb');
// import the schema
$schema = new Schema($options = $this->getOptions());
foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
$this->con->exec($sql);
}
// setup prepared statements
$this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
$this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
$this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
$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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
$this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
for ($i = 0; $i < 40000; ++$i) {
$this->generateAclHierarchy();
}
}
protected function generateAclHierarchy()
{
$rootId = $this->generateAcl($this->chooseClassId(), null, array());
$this->generateAclLevel(rand(1, 15), $rootId, array($rootId));
}
protected function generateAclLevel($depth, $parentId, $ancestors)
{
$level = count($ancestors);
for ($i = 0, $t = rand(1, 10); $i < $t; ++$i) {
$id = $this->generateAcl($this->chooseClassId(), $parentId, $ancestors);
if ($level < $depth) {
$this->generateAclLevel($depth, $id, array_merge($ancestors, array($id)));
}
}
}
protected function chooseClassId()
{
static $id = 1000;
if ($id === 1000 || ($id < 1500 && rand(0, 1))) {
$this->insertClassStmt->execute(array($id, $this->getRandomString(rand(20, 100), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\_')));
++$id;
return $id - 1;
} else {
return rand(1000, $id - 1);
}
}
protected function generateAcl($classId, $parentId, $ancestors)
{
static $id = 1000;
$this->insertOidStmt->execute(array(
$id,
$classId,
$this->getRandomString(rand(20, 50)),
$parentId,
rand(0, 1),
));
$this->insertOidAncestorStmt->execute(array($id, $id));
foreach ($ancestors as $ancestor) {
$this->insertOidAncestorStmt->execute(array($id, $ancestor));
}
$this->generateAces($classId, $id);
++$id;
return $id - 1;
}
protected function chooseSid()
{
static $id = 1000;
if ($id === 1000 || ($id < 11000 && rand(0, 1))) {
$this->insertSidStmt->execute(array(
$id,
$this->getRandomString(rand(5, 30)),
rand(0, 1),
));
++$id;
return $id - 1;
} else {
return rand(1000, $id - 1);
}
}
protected function generateAces($classId, $objectId)
{
static $id = 1000;
$sids = array();
$fieldOrder = array();
for ($i = 0; $i <= 30; ++$i) {
$fieldName = rand(0, 1) ? null : $this->getRandomString(rand(10, 20));
do {
$sid = $this->chooseSid();
} while (array_key_exists($sid, $sids) && in_array($fieldName, $sids[$sid], true));
$fieldOrder[$fieldName] = array_key_exists($fieldName, $fieldOrder) ? $fieldOrder[$fieldName] + 1 : 0;
if (!isset($sids[$sid])) {
$sids[$sid] = array();
}
$sids[$sid][] = $fieldName;
$strategy = rand(0, 2);
if ($strategy === 0) {
$strategy = PermissionGrantingStrategy::ALL;
} elseif ($strategy === 1) {
$strategy = PermissionGrantingStrategy::ANY;
} else {
$strategy = PermissionGrantingStrategy::EQUAL;
}
// id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
$this->insertEntryStmt->execute(array(
$id,
$classId,
rand(0, 5) ? $objectId : null,
$fieldName,
$fieldOrder[$fieldName],
$sid,
$this->generateMask(),
rand(0, 1),
$strategy,
rand(0, 1),
rand(0, 1),
));
++$id;
}
}
protected function generateMask()
{
$i = rand(1, 30);
$mask = 0;
while ($i <= 30) {
$mask |= 1 << rand(0, 30);
++$i;
}
return $mask;
}
protected function getRandomString($length, $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$s = '';
$cLength = strlen($chars);
while (strlen($s) < $length) {
$s .= $chars[mt_rand(0, $cLength - 1)];
}
return $s;
}
protected function getOptions()
{
return array(
'oid_table_name' => 'acl_object_identities',
'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
'class_table_name' => 'acl_classes',
'sid_table_name' => 'acl_security_identities',
'entry_table_name' => 'acl_entries',
);
}
protected function getStrategy()
{
return new PermissionGrantingStrategy();
}
protected function getProvider()
{
return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
}
}

View File

@@ -0,0 +1,280 @@
<?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\Dbal;
use Symfony\Component\Security\Acl\Dbal\AclProvider;
use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Dbal\Schema;
use Doctrine\DBAL\DriverManager;
/**
* @requires extension pdo_sqlite
*/
class AclProviderTest extends \PHPUnit_Framework_TestCase
{
protected $con;
protected $insertClassStmt;
protected $insertEntryStmt;
protected $insertOidStmt;
protected $insertOidAncestorStmt;
protected $insertSidStmt;
/**
* @expectedException \Symfony\Component\Security\Acl\Exception\AclNotFoundException
* @expectedMessage There is no ACL for the given object identity.
*/
public function testFindAclThrowsExceptionWhenNoAclExists()
{
$this->getProvider()->findAcl(new ObjectIdentity('foo', 'foo'));
}
public function testFindAclsThrowsExceptionUnlessAnACLIsFoundForEveryOID()
{
$oids = array();
$oids[] = new ObjectIdentity('1', 'foo');
$oids[] = new ObjectIdentity('foo', 'foo');
try {
$this->getProvider()->findAcls($oids);
$this->fail('Provider did not throw an expected exception.');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\AclNotFoundException', $e);
$this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\NotAllAclsFoundException', $e);
$partialResult = $e->getPartialResult();
$this->assertTrue($partialResult->contains($oids[0]));
$this->assertFalse($partialResult->contains($oids[1]));
}
}
public function testFindAcls()
{
$oids = array();
$oids[] = new ObjectIdentity('1', 'foo');
$oids[] = new ObjectIdentity('2', 'foo');
$provider = $this->getProvider();
$acls = $provider->findAcls($oids);
$this->assertInstanceOf('SplObjectStorage', $acls);
$this->assertCount(2, $acls);
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
$this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
$this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
}
public function testFindAclsWithDifferentTypes()
{
$oids = array();
$oids[] = new ObjectIdentity('123', 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity');
$oids[] = new ObjectIdentity('123', 'Bundle\MyBundle\Entity\AnotherEntity');
$provider = $this->getProvider();
$acls = $provider->findAcls($oids);
$this->assertInstanceOf('SplObjectStorage', $acls);
$this->assertCount(2, $acls);
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
$this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
$this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
}
public function testFindAclCachesAclInMemory()
{
$oid = new ObjectIdentity('1', 'foo');
$provider = $this->getProvider();
$acl = $provider->findAcl($oid);
$this->assertSame($acl, $cAcl = $provider->findAcl($oid));
$cAces = $cAcl->getObjectAces();
foreach ($acl->getObjectAces() as $index => $ace) {
$this->assertSame($ace, $cAces[$index]);
}
}
public function testFindAcl()
{
$oid = new ObjectIdentity('1', 'foo');
$provider = $this->getProvider();
$acl = $provider->findAcl($oid);
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl);
$this->assertTrue($oid->equals($acl->getObjectIdentity()));
$this->assertEquals(4, $acl->getId());
$this->assertCount(0, $acl->getClassAces());
$this->assertCount(0, $this->getField($acl, 'classFieldAces'));
$this->assertCount(3, $acl->getObjectAces());
$this->assertCount(0, $this->getField($acl, 'objectFieldAces'));
$aces = $acl->getObjectAces();
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Entry', $aces[0]);
$this->assertTrue($aces[0]->isGranting());
$this->assertTrue($aces[0]->isAuditSuccess());
$this->assertTrue($aces[0]->isAuditFailure());
$this->assertEquals('all', $aces[0]->getStrategy());
$this->assertSame(2, $aces[0]->getMask());
// check ACE are in correct order
$i = 0;
foreach ($aces as $index => $ace) {
$this->assertEquals($i, $index);
++$i;
}
$sid = $aces[0]->getSecurityIdentity();
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\UserSecurityIdentity', $sid);
$this->assertEquals('john.doe', $sid->getUsername());
$this->assertEquals('SomeClass', $sid->getClass());
}
protected function setUp()
{
$this->con = DriverManager::getConnection(array(
'driver' => 'pdo_sqlite',
'memory' => true,
));
// import the schema
$schema = new Schema($options = $this->getOptions());
foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
$this->con->exec($sql);
}
// populate the schema with some test data
$this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
foreach ($this->getClassData() as $data) {
$this->insertClassStmt->execute($data);
}
$this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
foreach ($this->getSidData() as $data) {
$this->insertSidStmt->execute($data);
}
$this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
foreach ($this->getOidData() as $data) {
$this->insertOidStmt->execute($data);
}
$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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
foreach ($this->getEntryData() as $data) {
$this->insertEntryStmt->execute($data);
}
$this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
foreach ($this->getOidAncestorData() as $data) {
$this->insertOidAncestorStmt->execute($data);
}
}
protected function tearDown()
{
$this->con = null;
}
protected function getField($object, $field)
{
$reflection = new \ReflectionProperty($object, $field);
$reflection->setAccessible(true);
return $reflection->getValue($object);
}
protected function getEntryData()
{
// id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
return array(
array(1, 1, 1, null, 0, 1, 1, 1, 'all', 1, 1),
array(2, 1, 1, null, 1, 2, 1 << 2 | 1 << 1, 0, 'any', 0, 0),
array(3, 3, 4, null, 0, 1, 2, 1, 'all', 1, 1),
array(4, 3, 4, null, 2, 2, 1, 1, 'all', 1, 1),
array(5, 3, 4, null, 1, 3, 1, 1, 'all', 1, 1),
);
}
protected function getOidData()
{
// id, cid, oid, parent_oid, entries_inheriting
return array(
array(1, 1, '123', null, 1),
array(2, 2, '123', 1, 1),
array(3, 2, 'i:3:123', 1, 1),
array(4, 3, '1', 2, 1),
array(5, 3, '2', 2, 1),
);
}
protected function getOidAncestorData()
{
return array(
array(1, 1),
array(2, 1),
array(2, 2),
array(3, 1),
array(3, 3),
array(4, 2),
array(4, 1),
array(4, 4),
array(5, 2),
array(5, 1),
array(5, 5),
);
}
protected function getSidData()
{
return array(
array(1, 'SomeClass-john.doe', 1),
array(2, 'MyClass-john.doe@foo.com', 1),
array(3, 'FooClass-123', 1),
array(4, 'MooClass-ROLE_USER', 1),
array(5, 'ROLE_USER', 0),
array(6, 'IS_AUTHENTICATED_FULLY', 0),
);
}
protected function getClassData()
{
return array(
array(1, 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity'),
array(2, 'Bundle\MyBundle\Entity\AnotherEntity'),
array(3, 'foo'),
);
}
protected function getOptions()
{
return array(
'oid_table_name' => 'acl_object_identities',
'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
'class_table_name' => 'acl_classes',
'sid_table_name' => 'acl_security_identities',
'entry_table_name' => 'acl_entries',
);
}
protected function getStrategy()
{
return new PermissionGrantingStrategy();
}
protected function getProvider()
{
return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
}
}

View File

@@ -0,0 +1,572 @@
<?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\Dbal;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Model\FieldEntryInterface;
use Symfony\Component\Security\Acl\Model\AuditableEntryInterface;
use Symfony\Component\Security\Acl\Model\EntryInterface;
use Symfony\Component\Security\Acl\Domain\Entry;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\Acl;
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
use Symfony\Component\Security\Acl\Exception\ConcurrentModificationException;
use Symfony\Component\Security\Acl\Dbal\AclProvider;
use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
use Symfony\Component\Security\Acl\Dbal\MutableAclProvider;
use Symfony\Component\Security\Acl\Dbal\Schema;
use Doctrine\DBAL\DriverManager;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
/**
* @requires extension pdo_sqlite
*/
class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
{
protected $con;
public static function assertAceEquals(EntryInterface $a, EntryInterface $b)
{
self::assertInstanceOf(get_class($a), $b);
foreach (array('getId', 'getMask', 'getStrategy', 'isGranting') as $getter) {
self::assertSame($a->$getter(), $b->$getter());
}
self::assertTrue($a->getSecurityIdentity()->equals($b->getSecurityIdentity()));
self::assertSame($a->getAcl()->getId(), $b->getAcl()->getId());
if ($a instanceof AuditableEntryInterface) {
self::assertSame($a->isAuditSuccess(), $b->isAuditSuccess());
self::assertSame($a->isAuditFailure(), $b->isAuditFailure());
}
if ($a instanceof FieldEntryInterface) {
self::assertSame($a->getField(), $b->getField());
}
}
/**
* @expectedException \Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException
*/
public function testCreateAclThrowsExceptionWhenAclAlreadyExists()
{
$provider = $this->getProvider();
$oid = new ObjectIdentity('123456', 'FOO');
$provider->createAcl($oid);
$provider->createAcl($oid);
}
public function testCreateAcl()
{
$provider = $this->getProvider();
$oid = new ObjectIdentity('123456', 'FOO');
$acl = $provider->createAcl($oid);
$cachedAcl = $provider->findAcl($oid);
$this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl);
$this->assertSame($acl, $cachedAcl);
$this->assertTrue($acl->getObjectIdentity()->equals($oid));
}
public function testDeleteAcl()
{
$provider = $this->getProvider();
$oid = new ObjectIdentity(1, 'Foo');
$acl = $provider->createAcl($oid);
$provider->deleteAcl($oid);
$loadedAcls = $this->getField($provider, 'loadedAcls');
$this->assertCount(0, $loadedAcls['Foo']);
try {
$provider->findAcl($oid);
$this->fail('ACL has not been properly deleted.');
} catch (AclNotFoundException $e) {
}
}
public function testDeleteAclDeletesChildren()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$parentAcl = $provider->createAcl(new ObjectIdentity(2, 'Foo'));
$acl->setParentAcl($parentAcl);
$provider->updateAcl($acl);
$provider->deleteAcl($parentAcl->getObjectIdentity());
try {
$provider->findAcl(new ObjectIdentity(1, 'Foo'));
$this->fail('Child-ACLs have not been deleted.');
} catch (AclNotFoundException $e) {
}
}
public function testFindAclsAddsPropertyListener()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$propertyChanges = $this->getField($provider, 'propertyChanges');
$this->assertCount(1, $propertyChanges);
$this->assertTrue($propertyChanges->contains($acl));
$this->assertEquals(array(), $propertyChanges->offsetGet($acl));
$listeners = $this->getField($acl, 'listeners');
$this->assertSame($provider, $listeners[0]);
}
public function testFindAclsAddsPropertyListenerOnlyOnce()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$acl = $provider->findAcl(new ObjectIdentity(1, 'Foo'));
$propertyChanges = $this->getField($provider, 'propertyChanges');
$this->assertCount(1, $propertyChanges);
$this->assertTrue($propertyChanges->contains($acl));
$this->assertEquals(array(), $propertyChanges->offsetGet($acl));
$listeners = $this->getField($acl, 'listeners');
$this->assertCount(1, $listeners);
$this->assertSame($provider, $listeners[0]);
}
public function testFindAclsAddsPropertyListenerToParentAcls()
{
$provider = $this->getProvider();
$this->importAcls($provider, array(
'main' => array(
'object_identifier' => '1',
'class_type' => 'foo',
'parent_acl' => 'parent',
),
'parent' => array(
'object_identifier' => '1',
'class_type' => 'anotherFoo',
),
));
$propertyChanges = $this->getField($provider, 'propertyChanges');
$this->assertCount(0, $propertyChanges);
$acl = $provider->findAcl(new ObjectIdentity('1', 'foo'));
$this->assertCount(2, $propertyChanges);
$this->assertTrue($propertyChanges->contains($acl));
$this->assertTrue($propertyChanges->contains($acl->getParentAcl()));
}
/**
* @expectedException \InvalidArgumentException
*/
public function testPropertyChangedDoesNotTrackUnmanagedAcls()
{
$provider = $this->getProvider();
$acl = new Acl(1, new ObjectIdentity(1, 'foo'), new PermissionGrantingStrategy(), array(), false);
$provider->propertyChanged($acl, 'classAces', array(), array('foo'));
}
public function testPropertyChangedTracksChangesToAclProperties()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$propertyChanges = $this->getField($provider, 'propertyChanges');
$provider->propertyChanged($acl, 'entriesInheriting', false, true);
$changes = $propertyChanges->offsetGet($acl);
$this->assertTrue(isset($changes['entriesInheriting']));
$this->assertFalse($changes['entriesInheriting'][0]);
$this->assertTrue($changes['entriesInheriting'][1]);
$provider->propertyChanged($acl, 'entriesInheriting', true, false);
$provider->propertyChanged($acl, 'entriesInheriting', false, true);
$provider->propertyChanged($acl, 'entriesInheriting', true, false);
$changes = $propertyChanges->offsetGet($acl);
$this->assertFalse(isset($changes['entriesInheriting']));
}
public function testPropertyChangedTracksChangesToAceProperties()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$ace = new Entry(1, $acl, new UserSecurityIdentity('foo', 'FooClass'), 'all', 1, true, true, true);
$ace2 = new Entry(2, $acl, new UserSecurityIdentity('foo', 'FooClass'), 'all', 1, true, true, true);
$propertyChanges = $this->getField($provider, 'propertyChanges');
$provider->propertyChanged($ace, 'mask', 1, 3);
$changes = $propertyChanges->offsetGet($acl);
$this->assertTrue(isset($changes['aces']));
$this->assertInstanceOf('\SplObjectStorage', $changes['aces']);
$this->assertTrue($changes['aces']->contains($ace));
$aceChanges = $changes['aces']->offsetGet($ace);
$this->assertTrue(isset($aceChanges['mask']));
$this->assertEquals(1, $aceChanges['mask'][0]);
$this->assertEquals(3, $aceChanges['mask'][1]);
$provider->propertyChanged($ace, 'strategy', 'all', 'any');
$changes = $propertyChanges->offsetGet($acl);
$this->assertTrue(isset($changes['aces']));
$this->assertInstanceOf('\SplObjectStorage', $changes['aces']);
$this->assertTrue($changes['aces']->contains($ace));
$aceChanges = $changes['aces']->offsetGet($ace);
$this->assertTrue(isset($aceChanges['mask']));
$this->assertTrue(isset($aceChanges['strategy']));
$this->assertEquals('all', $aceChanges['strategy'][0]);
$this->assertEquals('any', $aceChanges['strategy'][1]);
$provider->propertyChanged($ace, 'mask', 3, 1);
$changes = $propertyChanges->offsetGet($acl);
$aceChanges = $changes['aces']->offsetGet($ace);
$this->assertFalse(isset($aceChanges['mask']));
$this->assertTrue(isset($aceChanges['strategy']));
$provider->propertyChanged($ace2, 'mask', 1, 3);
$provider->propertyChanged($ace, 'strategy', 'any', 'all');
$changes = $propertyChanges->offsetGet($acl);
$this->assertTrue(isset($changes['aces']));
$this->assertFalse($changes['aces']->contains($ace));
$this->assertTrue($changes['aces']->contains($ace2));
$provider->propertyChanged($ace2, 'mask', 3, 4);
$provider->propertyChanged($ace2, 'mask', 4, 1);
$changes = $propertyChanges->offsetGet($acl);
$this->assertFalse(isset($changes['aces']));
}
/**
* @expectedException \InvalidArgumentException
*/
public function testUpdateAclDoesNotAcceptUntrackedAcls()
{
$provider = $this->getProvider();
$acl = new Acl(1, new ObjectIdentity(1, 'Foo'), new PermissionGrantingStrategy(), array(), true);
$provider->updateAcl($acl);
}
public function testUpdateDoesNothingWhenThereAreNoChanges()
{
$con = $this->getMock('Doctrine\DBAL\Connection', array(), array(), '', false);
$con
->expects($this->never())
->method('beginTransaction')
;
$con
->expects($this->never())
->method('executeQuery')
;
$provider = new MutableAclProvider($con, new PermissionGrantingStrategy(), array());
$acl = new Acl(1, new ObjectIdentity(1, 'Foo'), new PermissionGrantingStrategy(), array(), true);
$propertyChanges = $this->getField($provider, 'propertyChanges');
$propertyChanges->offsetSet($acl, array());
$provider->updateAcl($acl);
}
public function testUpdateAclThrowsExceptionOnConcurrentModificationOfSharedProperties()
{
$provider = $this->getProvider();
$acl1 = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$acl2 = $provider->createAcl(new ObjectIdentity(2, 'Foo'));
$acl3 = $provider->createAcl(new ObjectIdentity(1, 'AnotherFoo'));
$sid = new RoleSecurityIdentity('ROLE_FOO');
$acl1->insertClassAce($sid, 1);
$acl3->insertClassAce($sid, 1);
$provider->updateAcl($acl1);
$provider->updateAcl($acl3);
$acl2->insertClassAce($sid, 16);
$provider->updateAcl($acl2);
$acl1->insertClassAce($sid, 3);
$acl2->insertClassAce($sid, 5);
try {
$provider->updateAcl($acl1);
$this->fail('Provider failed to detect a concurrent modification.');
} catch (ConcurrentModificationException $e) {
}
}
public function testUpdateAcl()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$sid = new UserSecurityIdentity('johannes', 'FooClass');
$acl->setEntriesInheriting(!$acl->isEntriesInheriting());
$acl->insertObjectAce($sid, 1);
$acl->insertClassAce($sid, 5, 0, false);
$acl->insertObjectAce($sid, 2, 1, true);
$acl->insertClassFieldAce('field', $sid, 2, 0, true);
$provider->updateAcl($acl);
$acl->updateObjectAce(0, 3);
$acl->deleteObjectAce(1);
$acl->updateObjectAuditing(0, true, false);
$acl->updateClassFieldAce(0, 'field', 15);
$provider->updateAcl($acl);
$reloadProvider = $this->getProvider();
$reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
$this->assertNotSame($acl, $reloadedAcl);
$this->assertSame($acl->isEntriesInheriting(), $reloadedAcl->isEntriesInheriting());
$aces = $acl->getObjectAces();
$reloadedAces = $reloadedAcl->getObjectAces();
$this->assertEquals(count($aces), count($reloadedAces));
foreach ($aces as $index => $ace) {
$this->assertAceEquals($ace, $reloadedAces[$index]);
}
}
public function testUpdateAclWorksForChangingTheParentAcl()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$parentAcl = $provider->createAcl(new ObjectIdentity(1, 'AnotherFoo'));
$acl->setParentAcl($parentAcl);
$provider->updateAcl($acl);
$reloadProvider = $this->getProvider();
$reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
$this->assertNotSame($acl, $reloadedAcl);
$this->assertSame($parentAcl->getId(), $reloadedAcl->getParentAcl()->getId());
}
public function testUpdateAclUpdatesChildAclsCorrectly()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$parentAcl = $provider->createAcl(new ObjectIdentity(1, 'Bar'));
$acl->setParentAcl($parentAcl);
$provider->updateAcl($acl);
$parentParentAcl = $provider->createAcl(new ObjectIdentity(1, 'Baz'));
$parentAcl->setParentAcl($parentParentAcl);
$provider->updateAcl($parentAcl);
$newParentParentAcl = $provider->createAcl(new ObjectIdentity(2, 'Baz'));
$parentAcl->setParentAcl($newParentParentAcl);
$provider->updateAcl($parentAcl);
$reloadProvider = $this->getProvider();
$reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
$this->assertEquals($newParentParentAcl->getId(), $reloadedAcl->getParentAcl()->getParentAcl()->getId());
}
public function testUpdateAclInsertingMultipleObjectFieldAcesThrowsDBConstraintViolations()
{
$provider = $this->getProvider();
$oid = new ObjectIdentity(1, 'Foo');
$sid1 = new UserSecurityIdentity('johannes', 'FooClass');
$sid2 = new UserSecurityIdentity('guilro', 'FooClass');
$sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
$fieldName = 'fieldName';
$acl = $provider->createAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid1, 4);
$provider->updateAcl($acl);
$acl = $provider->findAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid2, 4);
$provider->updateAcl($acl);
$acl = $provider->findAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid3, 4);
$provider->updateAcl($acl);
}
public function testUpdateAclDeletingObjectFieldAcesThrowsDBConstraintViolations()
{
$provider = $this->getProvider();
$oid = new ObjectIdentity(1, 'Foo');
$sid1 = new UserSecurityIdentity('johannes', 'FooClass');
$sid2 = new UserSecurityIdentity('guilro', 'FooClass');
$sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
$fieldName = 'fieldName';
$acl = $provider->createAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid1, 4);
$provider->updateAcl($acl);
$acl = $provider->findAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid2, 4);
$provider->updateAcl($acl);
$index = 0;
$acl->deleteObjectFieldAce($index, $fieldName);
$provider->updateAcl($acl);
$acl = $provider->findAcl($oid);
$acl->insertObjectFieldAce($fieldName, $sid3, 4);
$provider->updateAcl($acl);
}
public function testUpdateUserSecurityIdentity()
{
$provider = $this->getProvider();
$acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
$sid = new UserSecurityIdentity('johannes', 'FooClass');
$acl->setEntriesInheriting(!$acl->isEntriesInheriting());
$acl->insertObjectAce($sid, 1);
$acl->insertClassAce($sid, 5, 0, false);
$acl->insertObjectAce($sid, 2, 1, true);
$acl->insertClassFieldAce('field', $sid, 2, 0, true);
$provider->updateAcl($acl);
$newSid = new UserSecurityIdentity('mathieu', 'FooClass');
$provider->updateUserSecurityIdentity($newSid, 'johannes');
$reloadProvider = $this->getProvider();
$reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
$this->assertNotSame($acl, $reloadedAcl);
$this->assertSame($acl->isEntriesInheriting(), $reloadedAcl->isEntriesInheriting());
$aces = $acl->getObjectAces();
$reloadedAces = $reloadedAcl->getObjectAces();
$this->assertEquals(count($aces), count($reloadedAces));
foreach ($reloadedAces as $ace) {
$this->assertTrue($ace->getSecurityIdentity()->equals($newSid));
}
}
/**
* Imports acls.
*
* Data must have the following format:
* array(
* *name* => array(
* 'object_identifier' => *required*
* 'class_type' => *required*,
* 'parent_acl' => *name (optional)*
* ),
* )
*
* @param AclProvider $provider
* @param array $data
*
* @throws \InvalidArgumentException
* @throws \Exception
*/
protected function importAcls(AclProvider $provider, array $data)
{
$aclIds = $parentAcls = array();
$con = $this->getField($provider, 'connection');
$con->beginTransaction();
try {
foreach ($data as $name => $aclData) {
if (!isset($aclData['object_identifier'], $aclData['class_type'])) {
throw new \InvalidArgumentException('"object_identifier", and "class_type" must be present.');
}
$this->callMethod($provider, 'createObjectIdentity', array(new ObjectIdentity($aclData['object_identifier'], $aclData['class_type'])));
$aclId = $con->lastInsertId();
$aclIds[$name] = $aclId;
$sql = $this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclId));
$con->executeQuery($sql);
if (isset($aclData['parent_acl'])) {
if (isset($aclIds[$aclData['parent_acl']])) {
$con->executeQuery('UPDATE acl_object_identities SET parent_object_identity_id = '.$aclIds[$aclData['parent_acl']].' WHERE id = '.$aclId);
$con->executeQuery($this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclIds[$aclData['parent_acl']])));
} else {
$parentAcls[$aclId] = $aclData['parent_acl'];
}
}
}
foreach ($parentAcls as $aclId => $name) {
if (!isset($aclIds[$name])) {
throw new \InvalidArgumentException(sprintf('"%s" does not exist.', $name));
}
$con->executeQuery(sprintf('UPDATE acl_object_identities SET parent_object_identity_id = %d WHERE id = %d', $aclIds[$name], $aclId));
$con->executeQuery($this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclIds[$name])));
}
$con->commit();
} catch (\Exception $e) {
$con->rollBack();
throw $e;
}
}
protected function callMethod($object, $method, array $args)
{
$method = new \ReflectionMethod($object, $method);
$method->setAccessible(true);
return $method->invokeArgs($object, $args);
}
protected function setUp()
{
$this->con = DriverManager::getConnection(array(
'driver' => 'pdo_sqlite',
'memory' => true,
));
// import the schema
$schema = new Schema($this->getOptions());
foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
$this->con->exec($sql);
}
}
protected function tearDown()
{
$this->con = null;
}
protected function getField($object, $field)
{
$reflection = new \ReflectionProperty($object, $field);
$reflection->setAccessible(true);
return $reflection->getValue($object);
}
public function setField($object, $field, $value)
{
$reflection = new \ReflectionProperty($object, $field);
$reflection->setAccessible(true);
$reflection->setValue($object, $value);
$reflection->setAccessible(false);
}
protected function getOptions()
{
return array(
'oid_table_name' => 'acl_object_identities',
'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
'class_table_name' => 'acl_classes',
'sid_table_name' => 'acl_security_identities',
'entry_table_name' => 'acl_entries',
);
}
protected function getStrategy()
{
return new PermissionGrantingStrategy();
}
protected function getProvider($cache = null)
{
return new MutableAclProvider($this->con, $this->getStrategy(), $this->getOptions(), $cache);
}
}

View File

@@ -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);
}
}

View File

@@ -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');
}
}

View File

@@ -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);
}
}

View File

@@ -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');
}
}

View File

@@ -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');
}
}

View File

@@ -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';
}
}

View File

@@ -0,0 +1,131 @@
<?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;
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 = $this->getMock('Symfony\Component\Security\Acl\Model\DomainObjectInterface');
$domainObject
->expects($this->once())
->method('getObjectIdentifier')
->will($this->returnValue('getObjectIdentifier()'))
;
$domainObject
->expects($this->never())
->method('getId')
->will($this->returnValue('getId()'))
;
$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;
}
}
}
namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain
{
class TestDomainObject extends \Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject
{
}
}

View File

@@ -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);
}
}

View File

@@ -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),
);
}
}

View File

@@ -0,0 +1,226 @@
<?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;
use Symfony\Component\Security\Core\Role\Role;
class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider getSecurityIdentityRetrievalTests
*/
public function testGetSecurityIdentities($user, array $roles, $authenticationStatus, array $sids)
{
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();
}
if (method_exists($token, 'getRoleNames')) {
$strategy = $this->getStrategy($roles, $authenticationStatus, false);
$token
->expects($this->once())
->method('getRoleNames')
->will($this->returnValue(array('foo')))
;
} else {
$strategy = $this->getStrategy($roles, $authenticationStatus, true);
$token
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array(new Role('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', $isBC = false)
{
$roleHierarchyBuilder = $this->getMockBuilder('Symfony\Component\Security\Core\Role\RoleHierarchyInterface')
->disableProxyingToOriginalMethods()
->disableOriginalConstructor();
if ($isBC) {
$roleHierarchy = $roleHierarchyBuilder->setMethods(['getReachableRoles'])
->getMockForAbstractClass();
$roleHierarchy
->expects($this->any())
->method('getReachableRoles')
->with($this->equalTo([new Role('foo')]))
->will($this->returnValue($roles));
} else {
$roleHierarchy = $roleHierarchyBuilder->setMethods(['getReachableRoleNames'])
->getMockForAbstractClass();
$roleHierarchy
->expects($this->any())
->method('getReachableRoleNames')
->with($this->equalTo(['foo']))
->will($this->returnValue($roles));
}
$trustResolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface', 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;
}
}

View File

@@ -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),
);
}
}

View File

@@ -0,0 +1,23 @@
<?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\Permission;
use Symfony\Component\Security\Acl\Permission\BasicPermissionMap;
class BasicPermissionMapTest extends \PHPUnit_Framework_TestCase
{
public function testGetMasksReturnsNullWhenNotSupportedMask()
{
$map = new BasicPermissionMap();
$this->assertNull($map->getMasks('IS_AUTHENTICATED_REMEMBERED', null));
}
}

View File

@@ -0,0 +1,103 @@
<?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\Permission;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
class MaskBuilderTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \InvalidArgumentException
* @dataProvider getInvalidConstructorData
*/
public function testConstructorWithNonInteger($invalidMask)
{
new MaskBuilder($invalidMask);
}
public function getInvalidConstructorData()
{
return array(
array(234.463),
array('asdgasdf'),
array(array()),
array(new \stdClass()),
);
}
public function testConstructorWithoutArguments()
{
$builder = new MaskBuilder();
$this->assertEquals(0, $builder->get());
}
public function testConstructor()
{
$builder = new MaskBuilder(123456);
$this->assertEquals(123456, $builder->get());
}
public function testAddAndRemove()
{
$builder = new MaskBuilder();
$builder
->add('view')
->add('eDiT')
->add('ownEr')
;
$mask = $builder->get();
$this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW);
$this->assertEquals(MaskBuilder::MASK_EDIT, $mask & MaskBuilder::MASK_EDIT);
$this->assertEquals(MaskBuilder::MASK_OWNER, $mask & MaskBuilder::MASK_OWNER);
$this->assertEquals(0, $mask & MaskBuilder::MASK_MASTER);
$this->assertEquals(0, $mask & MaskBuilder::MASK_CREATE);
$this->assertEquals(0, $mask & MaskBuilder::MASK_DELETE);
$this->assertEquals(0, $mask & MaskBuilder::MASK_UNDELETE);
$builder->remove('edit')->remove('OWner');
$mask = $builder->get();
$this->assertEquals(0, $mask & MaskBuilder::MASK_EDIT);
$this->assertEquals(0, $mask & MaskBuilder::MASK_OWNER);
$this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW);
}
public function testGetPattern()
{
$builder = new MaskBuilder();
$this->assertEquals(MaskBuilder::ALL_OFF, $builder->getPattern());
$builder->add('view');
$this->assertEquals(str_repeat('.', 31).'V', $builder->getPattern());
$builder->add('owner');
$this->assertEquals(str_repeat('.', 24).'N......V', $builder->getPattern());
$builder->add(1 << 10);
$this->assertEquals(str_repeat('.', 21).MaskBuilder::ON.'..N......V', $builder->getPattern());
}
public function testReset()
{
$builder = new MaskBuilder();
$this->assertEquals(0, $builder->get());
$builder->add('view');
$this->assertTrue($builder->get() > 0);
$builder->reset();
$this->assertEquals(0, $builder->get());
}
}

View File

@@ -0,0 +1,432 @@
<?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\Voter;
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
use Symfony\Component\Security\Acl\Voter\FieldVote;
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Acl\Voter\AclVoter;
class AclVoterTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider getSupportsAttributeTests
*/
public function testSupportsAttribute($attribute, $supported)
{
list($voter, , $permissionMap) = $this->getVoter(true, false);
$permissionMap
->expects($this->once())
->method('contains')
->with($this->identicalTo($attribute))
->will($this->returnValue($supported))
;
$this->assertSame($supported, $voter->supportsAttribute($attribute));
}
/**
* @dataProvider getSupportsAttributeNonStringTests
*/
public function testSupportsAttributeNonString($attribute)
{
list($voter) = $this->getVoter(true, false);
$this->assertFalse($voter->supportsAttribute($attribute));
}
public function getSupportsAttributeTests()
{
return array(
array('foo', true),
array('foo', false),
);
}
public function getSupportsAttributeNonStringTests()
{
return array(
array(new \stdClass()),
array(1),
array(true),
array(array()),
);
}
/**
* @dataProvider getSupportsClassTests
*/
public function testSupportsClass($class)
{
list($voter) = $this->getVoter();
$this->assertTrue($voter->supportsClass($class));
}
public function getSupportsClassTests()
{
return array(
array('foo'),
array('bar'),
array('moo'),
);
}
public function testVote()
{
list($voter, , $permissionMap) = $this->getVoter();
$permissionMap
->expects($this->atLeastOnce())
->method('getMasks')
->will($this->returnValue(null))
;
$this->assertSame(VoterInterface::ACCESS_ABSTAIN, $voter->vote($this->getToken(), null, array('VIEW', 'EDIT', 'DELETE')));
}
/**
* @dataProvider getTrueFalseTests
*/
public function testVoteWhenNoObjectIsPassed($allowIfObjectIdentityUnavailable)
{
list($voter, , $permissionMap) = $this->getVoter($allowIfObjectIdentityUnavailable);
$permissionMap
->expects($this->once())
->method('getMasks')
->will($this->returnValue(array()))
;
if ($allowIfObjectIdentityUnavailable) {
$vote = VoterInterface::ACCESS_GRANTED;
} else {
$vote = VoterInterface::ACCESS_ABSTAIN;
}
$this->assertSame($vote, $voter->vote($this->getToken(), null, array('VIEW')));
}
/**
* @dataProvider getTrueFalseTests
*/
public function testVoteWhenOidStrategyReturnsNull($allowIfUnavailable)
{
list($voter, , $permissionMap, $oidStrategy) = $this->getVoter($allowIfUnavailable);
$permissionMap
->expects($this->once())
->method('getMasks')
->will($this->returnValue(array()))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue(null))
;
if ($allowIfUnavailable) {
$vote = VoterInterface::ACCESS_GRANTED;
} else {
$vote = VoterInterface::ACCESS_ABSTAIN;
}
$this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
}
public function getTrueFalseTests()
{
return array(array(true), array(false));
}
public function testVoteNoAclFound()
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$permissionMap
->expects($this->once())
->method('getMasks')
->will($this->returnValue(array()))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->throwException(new AclNotFoundException('Not found.')))
;
$this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
}
/**
* @dataProvider getTrueFalseTests
*/
public function testVoteGrantsAccess($grant)
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$permissionMap
->expects($this->once())
->method('getMasks')
->with($this->equalTo('VIEW'))
->will($this->returnValue($masks = array(1, 2, 3)))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
;
$acl
->expects($this->once())
->method('isGranted')
->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
->will($this->returnValue($grant))
;
if ($grant) {
$vote = VoterInterface::ACCESS_GRANTED;
} else {
$vote = VoterInterface::ACCESS_DENIED;
}
$this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
}
public function testVoteNoAceFound()
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$permissionMap
->expects($this->once())
->method('getMasks')
->with($this->equalTo('VIEW'))
->will($this->returnValue($masks = array(1, 2, 3)))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
;
$acl
->expects($this->once())
->method('isGranted')
->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
->will($this->throwException(new NoAceFoundException('No ACE')))
;
$this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
}
/**
* @dataProvider getTrueFalseTests
*/
public function testVoteGrantsFieldAccess($grant)
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$permissionMap
->expects($this->once())
->method('getMasks')
->with($this->equalTo('VIEW'))
->will($this->returnValue($masks = array(1, 2, 3)))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
;
$acl
->expects($this->once())
->method('isFieldGranted')
->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
->will($this->returnValue($grant))
;
if ($grant) {
$vote = VoterInterface::ACCESS_GRANTED;
} else {
$vote = VoterInterface::ACCESS_DENIED;
}
$this->assertSame($vote, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
}
public function testVoteNoFieldAceFound()
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$permissionMap
->expects($this->once())
->method('getMasks')
->with($this->equalTo('VIEW'))
->will($this->returnValue($masks = array(1, 2, 3)))
;
$oidStrategy
->expects($this->once())
->method('getObjectIdentity')
->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
;
$acl
->expects($this->once())
->method('isFieldGranted')
->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
->will($this->throwException(new NoAceFoundException('No ACE')))
;
$this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
}
public function testWhenReceivingAnObjectIdentityInterfaceWeDontRetrieveANewObjectIdentity()
{
list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
$oid = new ObjectIdentity('someID', 'someType');
$permissionMap
->expects($this->once())
->method('getMasks')
->with($this->equalTo('VIEW'))
->will($this->returnValue($masks = array(1, 2, 3)))
;
$oidStrategy
->expects($this->never())
->method('getObjectIdentity')
;
$sidStrategy
->expects($this->once())
->method('getSecurityIdentities')
->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
;
$provider
->expects($this->once())
->method('findAcl')
->with($this->equalTo($oid), $this->equalTo($sids))
->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
;
$acl
->expects($this->once())
->method('isGranted')
->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
->will($this->throwException(new NoAceFoundException('No ACE')))
;
$voter->vote($this->getToken(), $oid, array('VIEW'));
}
protected function getToken()
{
return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
}
protected function getVoter($allowIfObjectIdentityUnavailable = true, $alwaysContains = true)
{
$provider = $this->getMock('Symfony\Component\Security\Acl\Model\AclProviderInterface');
$permissionMap = $this->getMock('Symfony\Component\Security\Acl\Permission\PermissionMapInterface');
$oidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface');
$sidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface');
if ($alwaysContains) {
$permissionMap
->expects($this->any())
->method('contains')
->will($this->returnValue(true));
}
return array(
new AclVoter($provider, $oidStrategy, $sidStrategy, $permissionMap, null, $allowIfObjectIdentityUnavailable),
$provider,
$permissionMap,
$oidStrategy,
$sidStrategy,
);
}
}