add more tests for (Mutable)AclProvider
* fix usage of existing database entries
This commit is contained in:
parent
babf3bf203
commit
2231df621c
|
@ -32,7 +32,10 @@ use Propel\PropelBundle\Security\Acl\Domain\Entry;
|
|||
use Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException;
|
||||
use Symfony\Component\Security\Acl\Exception\Exception as AclException;
|
||||
|
||||
use Symfony\Component\Security\Acl\Domain\FieldEntry;
|
||||
|
||||
use Symfony\Component\Security\Acl\Model\AclInterface;
|
||||
use Symfony\Component\Security\Acl\Model\EntryInterface;
|
||||
use Symfony\Component\Security\Acl\Model\FieldEntryInterface;
|
||||
use Symfony\Component\Security\Acl\Model\AclCacheInterface;
|
||||
use Symfony\Component\Security\Acl\Model\MutableAclInterface;
|
||||
|
@ -58,9 +61,11 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
*/
|
||||
public function __construct(PermissionGrantingStrategyInterface $permissionGrantingStrategy, PropelPDO $connection = null, AclCacheInterface $cache = null)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
if (null === $connection) {
|
||||
$connection = Propel::getConnection(EntryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
parent::__construct($permissionGrantingStrategy, $connection, $cache);
|
||||
}
|
||||
|
@ -135,9 +140,11 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
$this->connection->commit();
|
||||
|
||||
return true;
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
throw new AclException('An error occurred while deleting the ACL.', 1, $e);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,6 +166,7 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
|
||||
try {
|
||||
$modelEntries = EntryQuery::create()->findByAclIdentity($acl->getObjectIdentity(), array(), $this->connection);
|
||||
|
||||
$objectIdentity = ObjectIdentityQuery::create()->findOneByAclObjectIdentity($acl->getObjectIdentity(), $this->connection);
|
||||
|
||||
$this->connection->beginTransaction();
|
||||
|
@ -196,11 +204,13 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
$this->connection->commit();
|
||||
|
||||
return true;
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
$this->connection->rollBack();
|
||||
|
||||
throw new AclException('An error occurred while updating the ACL.', 0, $e);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,7 +229,11 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
/* @var $eachAce \Symfony\Component\Security\Acl\Model\EntryInterface */
|
||||
foreach ($accessControlEntries as $order => $eachAce) {
|
||||
// If the given ACE has never been persisted, create a new one.
|
||||
if (null === $entry = $this->getPersistedAce($eachAce)) {
|
||||
if (null === $entry = $this->getPersistedAce($eachAce, $objectIdentity, $object)) {
|
||||
$entry = new ModelEntry();
|
||||
}
|
||||
|
||||
if (in_array($entry->getId(), $entries)) {
|
||||
$entry = new ModelEntry();
|
||||
}
|
||||
|
||||
|
@ -253,24 +267,42 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
|
|||
*
|
||||
* If none is given, null is returned.
|
||||
*
|
||||
* @param Entry $ace
|
||||
* @param EntryInterface $ace
|
||||
*
|
||||
* @return ModelEntry|null
|
||||
*/
|
||||
protected function getPersistedAce(Entry $ace)
|
||||
protected function getPersistedAce(EntryInterface $ace, ObjectIdentity $objectIdentity, $object = false)
|
||||
{
|
||||
if (null === $ace->getId()) {
|
||||
return null;
|
||||
if (null !== $ace->getId() and null !== $entry = EntryQuery::create()->findPk($ace->getId(), $this->connection)) {
|
||||
$entry->reload(true, $this->connection);
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
if (null === $entry = EntryQuery::create()->findPk($ace->getId(), $this->connection)) {
|
||||
return null;
|
||||
/*
|
||||
* The id is not set, but there may be an ACE in the database.
|
||||
*
|
||||
* This happens if the ACL has created new ACEs, but was not reloaded.
|
||||
* We try to retrieve one by the unique key.
|
||||
*/
|
||||
$ukQuery = EntryQuery::create()
|
||||
->filterByAclClass($objectIdentity->getAclClass($this->connection))
|
||||
->filterBySecurityIdentity(SecurityIdentity::fromAclIdentity($ace->getSecurityIdentity(), $this->connection))
|
||||
;
|
||||
|
||||
if (true === $object) {
|
||||
$ukQuery->filterByObjectIdentity($objectIdentity);
|
||||
} else {
|
||||
$ukQuery->filterByObjectIdentityId(null, Criteria::ISNULL);
|
||||
}
|
||||
|
||||
// Retrieve fresh data from the database not from any caching.
|
||||
$entry->reload(false, $this->connection);
|
||||
if ($ace instanceof FieldEntryInterface) {
|
||||
$ukQuery->filterByFieldName($ace->getField());
|
||||
} else {
|
||||
$ukQuery->filterByFieldName(null, Criteria::ISNULL);
|
||||
}
|
||||
|
||||
return $entry;
|
||||
return $ukQuery->findOne($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -73,6 +73,43 @@ class AclProviderTest extends AclTestCase
|
|||
$acl->isGranted(array(128), array($this->getRoleSecurityIdentity('ROLE_USER')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFindAclWithEntries
|
||||
*/
|
||||
public function testFindAclWithParent()
|
||||
{
|
||||
$parent = $this->createModelObjectIdentity(1);
|
||||
$entry = $this->createEntry();
|
||||
$entry
|
||||
->setSecurityIdentity(SecurityIdentity::fromAclIdentity($this->getRoleSecurityIdentity('ROLE_USER')))
|
||||
->setAclClass($parent->getAclClass())
|
||||
->setMask(128)
|
||||
;
|
||||
$parent->addEntry($entry)->save($this->con);
|
||||
|
||||
$obj = $this->createModelObjectIdentity(2);
|
||||
$obj->setObjectIdentityRelatedByParentObjectIdentityId($parent);
|
||||
|
||||
$entry = $this->createEntry();
|
||||
$entry
|
||||
->setSecurityIdentity(SecurityIdentity::fromAclIdentity($this->getRoleSecurityIdentity('ROLE_USER')))
|
||||
->setAclClass($obj->getAclClass())
|
||||
->setMask(64)
|
||||
;
|
||||
$obj->addEntry($entry)->save($this->con);
|
||||
|
||||
$acl = $this->getAclProvider()->findAcl($this->getAclObjectIdentity(2), array($this->getRoleSecurityIdentity('ROLE_USER')));
|
||||
$parent = $acl->getParentAcl();
|
||||
|
||||
$this->assertInstanceOf('Propel\PropelBundle\Security\Acl\Domain\Acl', $acl);
|
||||
$this->assertInstanceOf('Propel\PropelBundle\Security\Acl\Domain\Acl', $parent);
|
||||
|
||||
$aces = $acl->getObjectAces();
|
||||
$parentAces = $parent->getObjectAces();
|
||||
$this->assertEquals(64, $aces[0]->getMask());
|
||||
$this->assertEquals(128, $parentAces[0]->getMask());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFindAclWithEntries
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
namespace Propel\PropelBundle\Tests\Security\Acl;
|
||||
|
||||
use Criteria;
|
||||
|
||||
use Propel\PropelBundle\Model\Acl\EntryQuery;
|
||||
use Propel\PropelBundle\Model\Acl\ObjectIdentityQuery;
|
||||
|
||||
|
@ -71,6 +73,125 @@ class MutableAclProviderTest extends AclTestCase
|
|||
$this->assertEquals($this->getRoleSecurityIdentity('ROLE_ADMIN'), $entry->getSecurityIdentity());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateAclCreatesInsertedAces
|
||||
*/
|
||||
public function testCreateAclAlreadyExists()
|
||||
{
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
$acl->insertObjectAce($this->getRoleSecurityIdentity(), 64);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$this->setExpectedException('Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException');
|
||||
$this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateAclCreatesInsertedAces
|
||||
*/
|
||||
public function testCreateAclWithParent()
|
||||
{
|
||||
$parentAcl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
$parentAcl->insertObjectAce($this->getRoleSecurityIdentity(), 64);
|
||||
$this->getAclProvider()->updateAcl($parentAcl);
|
||||
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(2));
|
||||
$acl->insertObjectAce($this->getRoleSecurityIdentity(), 128);
|
||||
$acl->setParentAcl($parentAcl);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$entries = ObjectIdentityQuery::create()->orderById(Criteria::ASC)->find($this->con);
|
||||
$this->assertCount(2, $entries);
|
||||
$this->assertNull($entries[0]->getParentObjectIdentityId());
|
||||
$this->assertEquals($entries[0]->getId(), $entries[1]->getParentObjectIdentityId());
|
||||
}
|
||||
|
||||
public function testUpdateAclInvalidAcl()
|
||||
{
|
||||
$acl = $this->getMock('Symfony\Component\Security\Acl\Model\MutableAclInterface');
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateAclCreatesInsertedAces
|
||||
*/
|
||||
public function testUpdateAclRemovesDeletedEntries()
|
||||
{
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
|
||||
$acl->insertObjectFieldAce('name', $this->getRoleSecurityIdentity(), 4);
|
||||
$acl->insertObjectFieldAce('slug', $this->getRoleSecurityIdentity(), 1);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
$this->assertEquals(2, EntryQuery::create()->count($this->con));
|
||||
|
||||
$acl->deleteObjectFieldAce(0, 'slug');
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
$this->assertEquals(1, EntryQuery::create()->count($this->con));
|
||||
|
||||
$entry = EntryQuery::create()->findOne($this->con);
|
||||
$this->assertEquals('name', $entry->getFieldName());
|
||||
$this->assertEquals(4, $entry->getMask());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateAclCreatesInsertedAces
|
||||
*/
|
||||
public function testUpdateAclCreatesMultipleAces()
|
||||
{
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
|
||||
$acl->insertObjectFieldAce('name', $this->getRoleSecurityIdentity(), 16, 0, true, 'all');
|
||||
$acl->insertObjectFieldAce('name', $this->getRoleSecurityIdentity(), 4);
|
||||
$acl->insertObjectFieldAce('slug', $this->getRoleSecurityIdentity(), 1);
|
||||
$this->assertCount(2, $acl->getObjectFieldAces('name'));
|
||||
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$entries = EntryQuery::create()->orderByMask(Criteria::ASC)->find($this->con);
|
||||
$this->assertCount(3, $entries);
|
||||
|
||||
$slugAce = $entries[0];
|
||||
|
||||
$this->assertEquals('slug', $slugAce->getFieldName());
|
||||
$this->assertEquals(1, $slugAce->getMask());
|
||||
|
||||
$nameRead = $entries[1];
|
||||
$this->assertEquals('name', $nameRead->getFieldName());
|
||||
$this->assertEquals(0, $nameRead->getAceOrder());
|
||||
$this->assertEquals(4, $nameRead->getMask());
|
||||
$this->assertEquals('all', $nameRead->getGrantingStrategy());
|
||||
|
||||
$nameUndelete = $entries[2];
|
||||
$this->assertEquals('name', $nameUndelete->getFieldName());
|
||||
$this->assertEquals(1, $nameUndelete->getAceOrder());
|
||||
$this->assertEquals(16, $nameUndelete->getMask());
|
||||
$this->assertEquals('all', $nameUndelete->getGrantingStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateAclCreatesInsertedAces
|
||||
*/
|
||||
public function testUpdateAclReadsExistingAce()
|
||||
{
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
$acl->insertObjectAce($this->getRoleSecurityIdentity(), 64);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$entry = EntryQuery::create()->findOne($this->con);
|
||||
|
||||
$acl = $this->getAclProvider()->findAcl($this->getAclObjectIdentity(1));
|
||||
$acl->updateObjectAce(0, 128);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$updatedEntry = clone $entry;
|
||||
$updatedEntry->reload(false, $this->con);
|
||||
|
||||
$this->assertEquals($entry->getId(), $updatedEntry->getId());
|
||||
$this->assertEquals(128, $updatedEntry->getMask());
|
||||
}
|
||||
|
||||
public function testDeleteAclNotExisting()
|
||||
{
|
||||
$this->assertTrue($this->getAclProvider()->deleteAcl($this->getAclObjectIdentity()));
|
||||
|
@ -91,11 +212,35 @@ class MutableAclProviderTest extends AclTestCase
|
|||
$this->assertEquals(0, EntryQuery::create()->count($this->con));
|
||||
}
|
||||
|
||||
public function testUpdateAclInvalidAcl()
|
||||
/**
|
||||
* @depends testCreateAclWithParent
|
||||
*/
|
||||
public function testDeleteAclRemovesChildAcl()
|
||||
{
|
||||
$acl = $this->getMock('Symfony\Component\Security\Acl\Model\MutableAclInterface');
|
||||
$parentAcl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
$parentAcl->insertObjectAce($this->getRoleSecurityIdentity(), 64);
|
||||
$this->getAclProvider()->updateAcl($parentAcl);
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(2));
|
||||
$acl->insertObjectAce($this->getRoleSecurityIdentity(), 128);
|
||||
$acl->setParentAcl($parentAcl);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$this->getAclProvider()->deleteAcl($this->getAclObjectIdentity(1));
|
||||
|
||||
$this->assertEquals(0, ObjectIdentityQuery::create()->count($this->con));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteAcl
|
||||
*/
|
||||
public function testDeleteAclRemovesClassEntriesIfLastObject()
|
||||
{
|
||||
$acl = $this->getAclProvider()->createAcl($this->getAclObjectIdentity(1));
|
||||
$acl->insertClassAce($this->getRoleSecurityIdentity(), 128);
|
||||
$this->getAclProvider()->updateAcl($acl);
|
||||
|
||||
$this->getAclProvider()->deleteAcl($this->getAclObjectIdentity(1));
|
||||
$this->assertEquals(0, EntryQuery::create()->count($this->con));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue