Skip to content
This repository was archived by the owner on Apr 7, 2020. It is now read-only.
This repository was archived by the owner on Apr 7, 2020. It is now read-only.

AclManager RetrievalStrategy is wrong (I think) #35

@jjsaunier

Description

@jjsaunier

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions