-
Notifications
You must be signed in to change notification settings - Fork 33
AclManager RetrievalStrategy is wrong (I think) #35
Description
Hey,
About this function :
/**
* @param mixed $domainObject
* @param string $field
* @param int $mask
* @param UserInterface | TokenInterface | RoleInterface $securityIdentity
* @param string $type
* @param string $field
* @param boolean $replace_existing
* @return \Problematic\AclManagerBundle\Domain\AbstractAclManager
*/
protected function addPermission($domainObject, $field, $mask, $securityIdentity = null, $type = 'object', $replace_existing = false)
{
if(is_null($securityIdentity)){
$securityIdentity = $this->getUser();
}
$context = $this->doCreatePermissionContext($type, $field, $securityIdentity, $mask);
$oid = $this->getObjectIdentityRetrievalStrategy()->getObjectIdentity($domainObject);
$acl = $this->doLoadAcl($oid);
$this->doApplyPermission($acl, $context, $replace_existing);
$this->getAclProvider()->updateAcl($acl);
return $this;
}When you enter in her via this function :
/**
* {@inheritDoc}
*/
public function addClassPermission($domainObject, $mask, $securityIdentity = null)
{
$this->addPermission($domainObject, null, $mask, $securityIdentity, 'class', false);
}The following line is wrong : $oid = $this->getObjectIdentityRetrievalStrategy()->getObjectIdentity($domainObject); in the way that use the wrong service (in addPermissionfunction)
By default SecurityComponent provide this service security.acl.object_identity_retrieval_strategy but he can be apply only for DomainObject not for Object. And in case of call AddClassPermission or serClassPermission you didn't work with DomainObject but with Object.
Here the code of ObjectIdentityRetrievalStrategy provided by default :
/**
* {@inheritdoc}
*/
public function getObjectIdentity($domainObject)
{
try {
return ObjectIdentity::fromDomainObject($domainObject);
} catch (InvalidDomainObjectException $failed) {
return;
}
}So when add class permission like : $aclManager->addClassPermission(Media::CLASS, MaskBuilder::MASK_OPERATOR, $sid); That trigger InvalidDomainObjectException and do nothing.
So, may i'm wrong ? or you must create your own ObjectIdentityRetrievalStrategy service to fix it ? (or dont call ObjectIdentityRetrievalStrategyin case of Object
So in my project I made a quick fix, to create my own service ObjectIdentityRetrievalStrategy, it's only for my need so to make it proper we must implement some setter, to configure identifier, but I only use class for this moment.
class ObjectIdentityRetrievalStrategy extends \Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy
{
/**
* @param object $domainObject
*
* @return ObjectIdentityInterface|void
*/
public function getObjectIdentity($domainObject)
{
if(is_string($domainObject)){
return new ObjectIdentity('class', $domainObject);
}
return parent::getObjectIdentity($domainObject);
}
} NOTE: On your example you show this : $aclManager->addClassPermission($comment, MaskBuilder::MASK_OWNER, $userEntity); But when we work with Object the right call is $aclManager->addClassPermission(Comment::CLASS, MaskBuilder::MASK_OWNER, $userEntity); because it's not a DomainObject We want add the permission of all instance of $comment, not specially $comment.