2
votes

In my Symfony2 project I managed to setup FOSUserBundle + SonataUserBundle + SonataAdminBundle following official docs. Now comes the time to setup the ACL (Access control list).

What I did :

  • Created an AdminClass called AdminReport

  • app/console sonata:admin:setup-acl

    install ACL for sonata.admin.report
    update role: ROLE_SONATA_ADMIN_REPORT_GUEST, permissions: ["LIST"]
    update role: ROLE_SONATA_ADMIN_REPORT_STAFF, permissions: ["LIST","CREATE"]
    update role: ROLE_SONATA_ADMIN_REPORT_EDITOR, permissions: ["OPERATOR","EXPORT"]
    • created a new user, granted him with ROLE_SONATA_ADMIN_REPORT_STAFF
    • app/console sonata:admin:generate-object-acl
    • Logged in with this user and accessed the default /admin/dashboard

    The block containing the AdminReport should appear but it's not... I am missing something ?

Here's my config.yml

sonata_admin:
    security:
        handler: sonata.admin.security.handler.acl
            information:
                GUEST:    [VIEW, LIST]
                STAFF:    [EDIT, LIST, CREATE]
                EDITOR:   [OPERATOR, EXPORT]
                ADMIN:    [MASTER]
            admin_permissions: [CREATE, LIST, DELETE, UNDELETE, EXPORT, OPERATOR, MASTER]
            object_permissions: [VIEW, EDIT, DELETE, UNDELETE, OPERATOR, MASTER, OWNER]

EDIT I tried to access directly app_dev.php/admin/app/report/list with this user, and Symfony throws an Access Denied error. Log says

DEBUG - Access denied, the user is neither anonymous, nor remember-me. And if I access app_dev.php/admin/app/report/list it works !

So I tried to change the handler from

sonata.admin.security.handler.acl
to
sonata.admin.security.handler.roles

It works because I can see the block in admin dashboard. I also tried to change

access_decision_manager:
        strategy: unanimous
to
affirmative
but it doesn't work...

I am definitely missing something but where ?

2
Yeah same problem here, i'm working on it actually. When i have solved it, I'll give you a solution :)Sir McPotato
Did you get new informations from your research ? I'm totally stuck with this...Hugo Lehoux
I made some tweaking around that and got something functional, I'll write an answer when I have few minutes left :)Sir McPotato

2 Answers

0
votes

Well, after some tweaking I achieved to make it working.

First, in my 'sonata.yml' in app/config/ I have changed the perms like the following :

app/config/sonata.yml :

sonata_admin:
    security:
        handler: sonata.admin.security.handler.acl

        # acl security information
        information:
            # GUEST:    [VIEW, LIST]
            # STAFF:    [EDIT, LIST, CREATE]
            # EDITOR:   [OPERATOR, EXPORT]
            # ADMIN:    [MASTER]
            EDIT: EDIT
            LIST: LIST
            CREATE: CREATE
            VIEW: VIEW
            DELETE: DELETE
            EXPORT: EXPORT
            MASTER: MASTER

To avoid this...

DEBUG - Access denied, the user is neither anonymous, nor remember-me

... i've commented out the following, because i think the firewall voter block the access to my user. Maybe not the wiser solution, but runs good for now :)

app/config/security.yml :

# set access_strategy to unanimous, else you may have unexpected behaviors
# access_decision_manager:
#     strategy: unanimous

Notice that my app is built only around the admin dahboard, so each user needs to have the dashboard access when they're created. In that way, I've modified my User constructor like this :

src/Application/Sonata/UserBundle/Entity/User.php :

class User extends BaseUser
{
    /**
     * @var integer $id
     */
    protected $id;

    public function __construct() {
        parent::__construct();
        // your own logic
        $this->roles = array('ROLE_USER', 'ROLE_SONATA_ADMIN', 'ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT');
    }

    /**
     * Get id
     *
     * @return integer $id
     */
    public function getId()
    {
        return $this->id;
    }
}

EDIT : It seems that, without knowing it, I replied to another of your questions ^^" (How can I assign default role to user in Symfony2)

Now each user can access the dashboard but like your issue, they cannot see anything.

I needed to use ACL, but like roles my users belong to groups who have their own ACL.

Once my user belong to one or many groups, he got the groups permissions in addition of his own permissions.

By managing one group's permissions, each user belonging to this group have his permissions modified. And by editing a user's permissions, I can make it access some pages that a group won't allow.

For example :

                        ┌─────────────┐
                        │   GROUP_1   │                 ┌───────────────┐
                        ├─────────────┤                 │     USER_1    │
                        │ CAT2_VIEW   │                 │ applied perms │
                        │ CAT2_LIST   │                 ├───────────────┤
                        │ CAT2_EDIT   │                 │ CAT1_VIEW     │
                        │ CAT2_DELETE │                 │ CAT1_LIST     │
                        ├─────────────┤                 ├───────────────┤
                        │ CAT3_VIEW   │  ├────┐         │ CAT2_VIEW     │
┌─────────────┐         │ CAT3_LIST   │       │         │ CAT2_LIST     │
│   USER_A    │         │ CAT3_EDIT   │       │         │ CAT2_EDIT     │
├─────────────┤<────────┤ CAT3_DELETE │       │         │ CAT2_DELETE   │
│ CAT1_VIEW   │         └─────────────┘       │         ├───────────────┤
│ CAT1_LIST   │                               ├────>    │ CAT3_VIEW     │
│             │         ┌─────────────┐       │         │ CAT3_LIST     │
│             │<────────┤   GROUP_2   │       │         │ CAT3_EDIT     │
└─────────────┘         ├─────────────┤       │         │ CAT3_DELETE   │
                        │ CAT4_VIEW   │       │         ├───────────────┤
                        │ CAT4_LIST   │       │         │ CAT4_VIEW     │
                        │ CAT4_EDIT   │  ├────┘         │ CAT4_LIST     │
                        │ CAT4_DELETE │                 │ CAT4_EDIT     │
                        │ CAT4_EXPORT │                 │ CAT4_DELETE   │
                        └─────────────┘                 │ CAT4_EXPORT   │
                                                        └───────────────┘

I managed to make it work this way, like I wanted, but I don't know if this is the best solution for your issue. I hope this will help you :)

PS : If anyone see any mistake or any illogical thing, don't hesitate to tell me in comment, i'm still learning to use it, and it'll be helpful :)

0
votes

The PermissionMap of SonataAdminBundle extends Symfony's BasicPermissionMap. Only if you change this default configuration, the AclVoter supports the attributes 'LIST' and 'EXPORT' and can possibly vote to grant the wanted permissions.

parameters:
    security.acl.permission.map.class: Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap

See my answer to AclVoter denies access to 'LIST'