Sonata Admin Bundle Control Panel Filter Element from Role Permissions and DDBB

I am using SonataAdminBundle with FosUserBundle. I have some problems on the toolbar.

In my application, I have resources, companies and users. The user belongs to the company and can create resources that will belong to his company. All this will be done on the control panel, accessible to all roles.

What I'm trying to do is access of all users to the control panel, but when the user selects an object (resource) to be displayed in the control panel, only the entities of his companies will be displayed. For example, two companies can create a vehicle (resource), but each company will only see its own vehicles (resources).

In conclusion, I want the toolbar to filter the entities of the company of the user who is connected. Is there a way to create a request in Sonata to show only some objects depending on the Company_Id of the user and the Company_Id of the resource displayed in BBDD?

+5
source share
3 answers

The easiest way is to edit the request and check access in the edit / show actions.

Something like that:

Admin class

/**
 * {@inheritdoc}
 */
public function createQuery($context = 'list')
{
    $user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();

    /** @var \Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery @query */
    $query = $this->getModelManager()->createQuery($this->getClass(), 'o');
    if (!$this->isGranted('MASTER')) {
        $query
            ->where('entity.user = :user')
            ->setParameter('user', $user)
        ;
    }

    return $query;
}

If the user is not a MASTER, he will only see his entities.

You can also implement the hasSubjectAccessadmin class method , for example:

/**
 * Check whether the user has access to the subject
 *
 * @return bool
 */
protected function hasSubjectAccess()
{
    $user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
    if (!$this->isGranted('MASTER') && $this->getSubject()->getUser() !== $user) {
        return false;
    }

    return true;
}

and perform this type of validation in editable and displayed forms:

/**
 * {@inheritdoc}
 */
protected function configureFormFields(FormMapper $formMapper)
{
    if (!$this->hasSubjectAccess()) {
        throw new AccessDeniedException();
    }

    // ...
}

Another way is to implement an ACL. You can learn more about this in the official documentation.

+4

, :

public function createQuery($context = 'list')
    $query = $this->getModelManager()->createQuery($this->getClass(), 'entity'); 

    if ( ($this->getClass() instanceof \Sademer\CoreBundle\Entity\Resource)
     || ( is_subclass_of($this->getClass(), \Sademer\CoreBundle\Entity\Resource') ) )
    {
          $query->select ('e');
          $query->from($this->getClass(), 'e');
          $query->from('CoreBundle\Entity\Resource', 'r');
          $query->where('e.id = r.id AND r.company = :company');
          $query->setParameter('company', 5);
    }
}
+1

For me, the createQuery () function does not work. Maybe because of the Sonata Admin version. In any case, the configureDatagridFilters () function worked for me.

It does the same job as createQuery, and looks something like this:

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
    $qb = $datagridMapper
        ->getDatagrid()
        ->getQuery()
        ->getQueryBuilder();

    $qb->andWhere(
        // Your where clause here
    );
    $qb->setParameter(); // Set Parameter
}
+1
source

All Articles