Skip to content
This repository has been archived by the owner on May 25, 2020. It is now read-only.

Commit

Permalink
Merge pull request #4 from nuxia/transactionalize-acl-updating
Browse files Browse the repository at this point in the history
Transactionalize acl updating
  • Loading branch information
Johann Saunier committed Dec 18, 2014
2 parents f07dcbd + 0f22084 commit 5dd35b5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 29 deletions.
73 changes: 45 additions & 28 deletions Domain/AbstractAclManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Problematic\AclManagerBundle\Domain;

use Doctrine\DBAL\Driver\Connection;
use Problematic\AclManagerBundle\Model\AclManagerInterface;
use Problematic\AclManagerBundle\Model\PermissionContextInterface;
use Problematic\AclManagerBundle\RetrievalStrategy\AclObjectIdentityRetrievalStrategyInterface;
use Problematic\AclManagerBundle\RetrievalStrategy\AclObjectRetrievalStrategy;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
Expand Down Expand Up @@ -42,18 +42,26 @@ abstract class AbstractAclManager implements AclManagerInterface
protected $objectIdentityRetrievalStrategy;

/**
* @param MutableAclProviderInterface $aclProvider
* @param SecurityContextInterface $securityContext
* @param AclObjectRetrievalStrategy $objectIdentityRetrievalStrategy
* @var Connection
*/
protected $connection;

/**
* @param MutableAclProviderInterface $aclProvider
* @param SecurityContextInterface $securityContext
* @param AclObjectIdentityRetrievalStrategyInterface $objectIdentityRetrievalStrategy
* @param Connection $connection
*/
public function __construct(
MutableAclProviderInterface $aclProvider,
SecurityContextInterface $securityContext,
AclObjectIdentityRetrievalStrategyInterface $objectIdentityRetrievalStrategy
AclObjectIdentityRetrievalStrategyInterface $objectIdentityRetrievalStrategy,
Connection $connection
) {
$this->aclProvider = $aclProvider;
$this->securityContext = $securityContext;
$this->objectIdentityRetrievalStrategy = $objectIdentityRetrievalStrategy;
$this->connection = $connection;
}

/**
Expand Down Expand Up @@ -170,7 +178,6 @@ protected function doCreateSecurityIdentity($identity)
/**
* Loads an ACE collection from the ACL and updates the permissions (creating if no appropriate ACE exists)
*
* @todo refactor this code to transactionalize ACL updating
* @param MutableAclInterface $acl
* @param PermissionContextInterface $context
* @return void
Expand All @@ -189,39 +196,49 @@ protected function doApplyPermission(MutableAclInterface $acl, PermissionContext
$size = count($aceCollection) - 1;
reset($aceCollection);

for ($i = $size; $i >= 0; $i--) {
if (true === $replaceExisting) {
// Replace all existing permissions with the new one
if ($context->hasDifferentPermission($aceCollection[$i])) {
// The ACE was found but with a different permission. Update it.
if (is_null($field)) {
$acl->{"update{$type}Ace"}($i, $context->getMask());
$this->connection->beginTransaction();

try{
for ($i = $size; $i >= 0; $i--) {
if (true === $replaceExisting) {
// Replace all existing permissions with the new one
if ($context->hasDifferentPermission($aceCollection[$i])) {
// The ACE was found but with a different permission. Update it.
if (is_null($field)) {
$acl->{"update{$type}Ace"}($i, $context->getMask());
} else {
$acl->{"update{$type}FieldAce"}($i, $field, $context->getMask());
}

//No need to proceed further because the acl is updated
return;
} else {
$acl->{"update{$type}FieldAce"}($i, $field, $context->getMask());
if ($context->equals($aceCollection[$i])) {
// The exact same ACE was found. Nothing to do.
return;
}
}

//No need to proceed further because the acl is updated
return;
} else {
if ($context->equals($aceCollection[$i])) {
// The exact same ACE was found. Nothing to do.
return;
}
}
} else {
if ($context->equals($aceCollection[$i])) {
// The exact same ACE was found. Nothing to do.
return;
}
}
}
//If we come this far means we have to insert ace
if (is_null($field)) {
$acl->{"insert{$type}Ace"}($context->getSecurityIdentity(),

//If we come this far means we have to insert ace
if (is_null($field)) {
$acl->{"insert{$type}Ace"}($context->getSecurityIdentity(),
$context->getMask(), 0, $context->isGranting());
} else {
$acl->{"insert{$type}FieldAce"}($field, $context->getSecurityIdentity(),
} else {
$acl->{"insert{$type}FieldAce"}($field, $context->getSecurityIdentity(),
$context->getMask(), 0, $context->isGranting());
}

$this->connection->commit();
} catch(\Exception $e){
$this->connection->rollBack();
throw $e;
}
}

Expand Down
3 changes: 2 additions & 1 deletion Domain/AclManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Symfony\Component\Security\Core\User\UserInterface;

Expand Down Expand Up @@ -305,6 +306,6 @@ public function getUser()

$user = $token->getUser();

return (is_object($user)) ? $user : 'IS_AUTHENTICATED_ANONYMOUSLY';
return (is_object($user)) ? $user : AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY;
}
}
1 change: 1 addition & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
aclProvider: @security.acl.provider
securityContext: @security.context
objectIdentityRetrievalStrategy: @problematic.acl.object_identity_retrieval_strategy
connection: @security.acl.dbal.connection

problematic.acl.object_identity_retrieval_strategy:
class: %problematic.acl_object_identity_retrieval_strategy%
Expand Down

0 comments on commit 5dd35b5

Please sign in to comment.