diff --git a/Dbal/AclProvider.php b/Dbal/AclProvider.php index 64102d2..83f8943 100644 --- a/Dbal/AclProvider.php +++ b/Dbal/AclProvider.php @@ -26,6 +26,7 @@ use Symfony\Component\Security\Acl\Model\AclProviderInterface; use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface; use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface; +use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; /** * An ACL provider implementation. @@ -37,6 +38,7 @@ class AclProvider implements AclProviderInterface { const MAX_BATCH_SIZE = 30; + const TOKEN_FILTER_PREFIX = 'IS_AUTHENTICATED_'; /** * @var AclCacheInterface|null @@ -228,9 +230,12 @@ public function findAcls(array $oids, array $sids = array()) * * @return string */ - protected function getLookupSql(array $ancestorIds) + protected function getLookupSql(array $ancestorIds/*, array $identityIds = []*/) { - // FIXME: add support for filtering by sids (right now we select all sids) + $identityIds = []; + if (\func_num_args() > 1) { + $identityIds = \func_get_arg(1); + } $sql = <<getLookupSql($ancestorIds); + $sql = $this->getLookupSql($ancestorIds, $this->getIdentityIds($sids)); $stmt = $this->connection->executeQuery($sql); return $this->hydrateObjectIdentities($stmt, $oidLookup, $sids); @@ -692,4 +700,22 @@ private function hydrateObjectIdentities(Statement $stmt, array $oidLookup, arra return $result; } + + /** + * Retrieves all the security identity ids which need to be queried from the database + * + * @param SecurityIdentityInterface[] $sids + * + * @return array + */ + private function getIdentityIds(array $sids) + { + $filteredSids = \array_filter($sids, function ($sid) { + return false === \strpos($sid->getRole(), self::TOKEN_FILTER_PREFIX); + }); + + return \array_map(function ($sid) { + return $sid->getRole(); + }, $filteredSids); + } } diff --git a/Dbal/MutableAclProvider.php b/Dbal/MutableAclProvider.php index bf08f60..0241477 100644 --- a/Dbal/MutableAclProvider.php +++ b/Dbal/MutableAclProvider.php @@ -854,8 +854,8 @@ private function updateNewFieldAceProperty($name, array $changes) $sids = new \SplObjectStorage(); $classIds = new \SplObjectStorage(); foreach ($changes[1] as $field => $new) { - for ($i = 0, $c = count($new); $i < $c; ++$i) { - $ace = $new[$i]; + foreach($new as $aceOrder => $newEntry) { + $ace = $newEntry; if (null === $ace->getId()) { if ($sids->contains($ace->getSecurityIdentity())) { @@ -873,8 +873,8 @@ private function updateNewFieldAceProperty($name, array $changes) $objectIdentityId = $name === 'classFieldAces' ? null : $ace->getAcl()->getId(); - $this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure())); - $aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $i))->fetchColumn(); + $this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $aceOrder, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure())); + $aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $aceOrder))->fetchColumn(); $this->loadedAces[$aceId] = $ace; $aceIdProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'id'); @@ -895,8 +895,8 @@ private function updateOldFieldAceProperty($name, array $changes) { $currentIds = array(); foreach ($changes[1] as $field => $new) { - for ($i = 0, $c = count($new); $i < $c; ++$i) { - $ace = $new[$i]; + foreach($new as $newEntry) { + $ace = $newEntry; if (null !== $ace->getId()) { $currentIds[$ace->getId()] = true; @@ -905,8 +905,8 @@ private function updateOldFieldAceProperty($name, array $changes) } foreach ($changes[0] as $old) { - for ($i = 0, $c = count($old); $i < $c; ++$i) { - $ace = $old[$i]; + foreach($old as $oldEntry) { + $ace = $oldEntry; if (!isset($currentIds[$ace->getId()])) { $this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId())); @@ -977,8 +977,8 @@ private function updateOldAceProperty($name, array $changes) } } - for ($i = 0, $c = count($old); $i < $c; ++$i) { - $ace = $old[$i]; + foreach($old as $oldEntry) { + $ace = $oldEntry; if (!isset($currentIds[$ace->getId()])) { $this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId()));