SOLUTION
Well, that's what I get when I use a bit oldish Symfony2 release (2.0-RC6). It seems that there was a bug in __construct
of RoleSecurityIdentity
(reported back in December '10).
Instead of instance of Role
it should be instance of RoleInstance
.
I should probably close this question...
I'm pretty new to whole ACL
concept in Symfony2
but I understand basics behind it. Last night I was trying to make next scenario work:
I have 2 user roles (ROLE_GROUP1
, ROLE_GROUP2
) and I want to setup object-level ACL
for the one of these groups. If user with ROLE_GROUP1
is logged in it should put this role into ACE
, otherwise it should put ROLE_GROUP2
.
So far I wrote this code (really almost identical to official docs):
$role = $this->getRole(); // returns ROLE_GROUP1 role object
$acl_provider = $this->get('security.acl.provider');
$objIdentity = ObjectIdentity::fromDomainObject($object); // my object
$acl = $acl_provider->createAcl($objIdentity);
$securityIdentity = new RoleSecurityIdentity($role->getRole()); // Role based identity
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
$acl_provider->updateAcl($acl);
The way I understand it, this should grant all permissions to users with ROLE_GROUP1
role. Am I wrong?
To check for permissions I used this code (again, from official docs):
$context = $this->get('security.context');
if ( false === $context->isGranted("EDIT", $object) ){
throw new AccessDeniedException();
}
... but it always fails (that is throws an exception).
I looked into the ACL tables and everything seemed normal, as far as I could see.
Am I doing something wrong with RoleSecurityIdentity? Is there any way to achieve this scenario?
Any help would be much appreciated!
EDIT
I just drilled down through the Symfony's code and found out that permission grant fails in equals
method of RoleSecurityIdentity
.
if (!$sid instanceof RoleSecurityIdentity) {
return false;
}
/** I ADDED THIS IF CHECK TO SEE WHAT DOES IT COMPARE WITH **/
if ( $this->role->getName() == "ROLE_GROUP1" ){
die("<pre>" . print_r($sid->getRole(),1) . "</pre><pre>" . print_r($this->role,1) . "</pre><pre>" . print_r($this->role === $sid->getRole(),1) . "</pre>");
}
return $this->role === $sid->getRole();
It turns out that $sid->getRole()
is string
"ROLE_GROUP1" while $this->role
is Role
object of ROLE_GROUP1 role.