/** * Constructor. * * @param \PropelObjectCollection $entries * @param \Symfony\Component\Security\Acl\Model\ObjectIdentityInterface $objectIdentity * @param \Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface $permissionGrantingStrategy * @param array $loadedSecurityIdentities * @param \Symfony\Component\Security\Acl\Model\AclInterface $parentAcl * @param bool $inherited * @param \PropelPDO $con */ public function __construct(\PropelObjectCollection $entries, ObjectIdentityInterface $objectIdentity, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $loadedSecurityIdentities = array(), AclInterface $parentAcl = null, $inherited = true, \PropelPDO $con = null) { parent::__construct($entries, $objectIdentity, $permissionGrantingStrategy, $loadedSecurityIdentities, $parentAcl, $inherited); $this->modelObjectIdentity = ObjectIdentityQuery::create()->filterByAclObjectIdentity($objectIdentity, $con)->findOneOrCreate($con); if ($this->modelObjectIdentity->isNew()) { $this->modelObjectIdentity->save($con); } $this->id = $this->modelObjectIdentity->getId(); $this->con = $con; }
/** * Update all ancestor entries to reflect changes on this instance. * * @param \PropelPDO $con * * @return \Propel\PropelBundle\Model\Acl\ObjectIdentity $this */ protected function updateAncestorsTree(\PropelPDO $con = null) { $con->beginTransaction(); $oldAncestors = ObjectIdentityQuery::create()->findAncestors($this, $con); $children = ObjectIdentityQuery::create()->findGrandChildren($this, $con); $children->append($this); if (count($oldAncestors)) { foreach ($children as $eachChild) { /* * Delete only those entries, that are ancestors based on the parent relation. * Ancestors of grand children up to the current node will be kept. */ $query = ObjectIdentityAncestorQuery::create()->filterByObjectIdentityId($eachChild->getId())->filterByObjectIdentityRelatedByAncestorId($oldAncestors, \Criteria::IN); if ($eachChild->getId() !== $this->getId()) { $query->filterByAncestorId(array($eachChild->getId(), $this->getId()), \Criteria::NOT_IN); } else { $query->filterByAncestorId($this->getId(), \Criteria::NOT_EQUAL); } $query->delete($con); } } // This is the new parent object identity! $parent = $this->getObjectIdentityRelatedByParentObjectIdentityId($con); if (null !== $parent) { $newAncestors = ObjectIdentityQuery::create()->findAncestors($parent, $con); $newAncestors->append($parent); foreach ($newAncestors as $eachAncestor) { // This collection contains the current object identity! foreach ($children as $eachChild) { $ancestor = ObjectIdentityAncestorQuery::create()->filterByObjectIdentityId($eachChild->getId())->filterByAncestorId($eachAncestor->getId())->findOneOrCreate($con); // If the entry already exists, next please. if (!$ancestor->isNew()) { continue; } if ($eachChild->getId() === $this->getId()) { // Do not save() here, as it would result in an infinite recursion loop! $this->addObjectIdentityAncestorRelatedByObjectIdentityId($ancestor); } else { // Save the new ancestor to avoid integrity constraint violation. $ancestor->save($con); $eachChild->addObjectIdentityAncestorRelatedByObjectIdentityId($ancestor)->save($con); } } } } $con->commit(); return $this; }
/** * Returns the ACL that belongs to the given object identity * * @throws \Symfony\Component\Security\Acl\Exception\AclNotFoundException * * @param \Symfony\Component\Security\Acl\Model\ObjectIdentityInterface $objectIdentity * @param array $securityIdentities * * @return \Symfony\Component\Security\Acl\Model\AclInterface */ public function findAcl(ObjectIdentityInterface $objectIdentity, array $securityIdentities = array()) { $modelObj = ObjectIdentityQuery::create()->findOneByAclObjectIdentity($objectIdentity, $this->connection); if (null !== $this->cache and null !== $modelObj) { $cachedAcl = $this->cache->getFromCacheById($modelObj->getId()); if ($cachedAcl instanceof AclInterface) { return $cachedAcl; } } $collection = EntryQuery::create()->findByAclIdentity($objectIdentity, $securityIdentities, $this->connection); if (0 === count($collection)) { if (empty($securityIdentities)) { $errorMessage = 'There is no ACL available for this object identity. Please create one using the MutableAclProvider.'; } else { $errorMessage = 'There is at least no ACL for this object identity and the given security identities. Try retrieving the ACL without security identity filter and add ACEs for the security identities.'; } throw new AclNotFoundException($errorMessage); } $loadedSecurityIdentities = array(); foreach ($collection as $eachEntry) { if (!isset($loadedSecurityIdentities[$eachEntry->getSecurityIdentity()->getId()])) { $loadedSecurityIdentities[$eachEntry->getSecurityIdentity()->getId()] = SecurityIdentity::toAclIdentity($eachEntry->getSecurityIdentity()); } } $parentAcl = null; $entriesInherited = true; if (null !== $modelObj) { $entriesInherited = $modelObj->getEntriesInheriting(); if (null !== $modelObj->getParentObjectIdentityId()) { $parentObj = $modelObj->getObjectIdentityRelatedByParentObjectIdentityId($this->connection); try { $parentAcl = $this->findAcl(new ObjectIdentity($parentObj->getIdentifier(), $parentObj->getAclClass($this->connection)->getType())); } catch (AclNotFoundException $e) { /* * This happens e.g. if the parent ACL is created, but does not contain any ACE by now. * The ACEs may be applied later on. */ } } } return $this->getAcl($collection, $objectIdentity, $loadedSecurityIdentities, $parentAcl, $entriesInherited); }
public function testInsertWithAssignedParent() { $parent = $this->createModelObjectIdentity(1); $obj = new ObjectIdentity(); $obj->setAclClass($this->getAclClass())->setIdentifier(2)->setObjectIdentityRelatedByParentObjectIdentityId($parent)->save($this->con); $entries = ObjectIdentityQuery::create()->orderByParentObjectIdentityId(Criteria::ASC)->find($this->con); $this->assertCount(2, $entries); $this->assertNull($entries[0]->getParentObjectIdentityId()); $this->assertEquals($entries[0]->getId(), $entries[1]->getParentObjectIdentityId()); }
/** * @depends testCreateAclWithParent */ public function testDeleteAclRemovesChildAcl() { $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); $this->getAclProvider()->deleteAcl($this->getAclObjectIdentity(1)); $this->assertEquals(0, ObjectIdentityQuery::create()->count($this->con)); }
/** * @depends testFindOneByAclObjectIdentity */ public function testFindAncestors() { list($objIdentity, $childObjIdentity) = $this->createObjectIdentities(); // Parents not set, yet. $result = ObjectIdentityQuery::create()->findAncestors($childObjIdentity, $this->con); $this->assertCount(0, $result); $childObjIdentity->setObjectIdentityRelatedByParentObjectIdentityId($objIdentity)->save($this->con); $result = ObjectIdentityQuery::create()->findAncestors($childObjIdentity, $this->con); $this->assertCount(1, $result); }
/** * Persists any changes which were made to the ACL, or any associated access control entries. * * Changes to parent ACLs are not persisted. * * @throws \Symfony\Component\Security\Acl\Exception\Exception * * @param \Symfony\Component\Security\Acl\Model\MutableAclInterface $acl * * @return bool */ public function updateAcl(MutableAclInterface $acl) { if (!$acl instanceof MutableAcl) { throw new \InvalidArgumentException('The given ACL is not tracked by this provider. Please provide \\Propel\\PropelBundle\\Security\\Acl\\Domain\\MutableAcl only.'); } try { $modelEntries = EntryQuery::create()->findByAclIdentity($acl->getObjectIdentity(), array(), $this->connection); $objectIdentity = ObjectIdentityQuery::create()->findOneByAclObjectIdentity($acl->getObjectIdentity(), $this->connection); $this->connection->beginTransaction(); $keepEntries = array_merge($this->persistAcl($acl->getClassAces(), $objectIdentity), $this->persistAcl($acl->getObjectAces(), $objectIdentity, true)); foreach ($acl->getFields() as $eachField) { $keepEntries = array_merge($keepEntries, $this->persistAcl($acl->getClassFieldAces($eachField), $objectIdentity), $this->persistAcl($acl->getObjectFieldAces($eachField), $objectIdentity, true)); } foreach ($modelEntries as &$eachEntry) { if (!in_array($eachEntry->getId(), $keepEntries)) { $eachEntry->delete($this->connection); } } if (null === $acl->getParentAcl()) { $objectIdentity->setParentObjectIdentityId(null)->save($this->connection); } else { $objectIdentity->setParentObjectIdentityId($acl->getParentAcl()->getId())->save($this->connection); } $this->connection->commit(); // After successfully committing the transaction, we are good to update the cache. if (null !== $this->cache) { $this->cache->evictFromCacheById($objectIdentity->getId()); $this->cache->putInCache($acl); } return true; // @codeCoverageIgnoreStart } catch (Exception $e) { $this->connection->rollBack(); throw new AclException('An error occurred while updating the ACL.', 0, $e); } // @codeCoverageIgnoreEnd }