Skip to content

Permissions Inheritance

Travis Blasingame edited this page Mar 27, 2017 · 3 revisions

Working With Permissions Inheritance

You can bind multiple permissions together so they inherit ones permission.

Why inheritance is needed?

In some cases, you have same permission but different approach to it on different roles. For example a client will have different permissions on an admin role and different on manager role. If we don't use inheritance we are bundled with a lot of validations like Auth::user()->hasPermission('view.client.as.manager|view.client.as.admin|view.client.as.webdev|...') and the list can go on with each type of role. To make it simpler, we use permission inheritance. We can just validate permission using Auth::user()->hasPermission('view.client') and that makes life a lot easier. Therefore, a single permission named client will work different for admin or other roles.

Let the example code speak.

NOTE: The example below will only work as expected with 'ntfs' => false set in the config/acl.php file. By default, this value is set to true, so update accordingly if this is how you want the permission inheritance to work.

I have changed the example below with a Teacher and Student roles.

First we create Roles.

        $roleTeacher = Role::create([
            'name'        => 'Teacher',
            'slug'        => 'teacher',
            'description' => 'Teacher [...]'
        ]);

        $roleStudent = Role::create([
            'name'        => 'Student',
            'slug'        => 'student',
            'description' => 'Student [...]'
        ]);

Now lets create Permissions for Teacher and Student.

        $permissionInternship = Permission::create([
            'name'        => 'internships',
            'slug'        => [ // an array of permissions.
                'create' => true,
                'view'   => true,
                'update' => true,
                'delete' => true,
            ],
            'description' => 'manage internships'
        ]);

        $permissionStudent = Permission::create([
            'name'        => 'internships.student',
            'slug'        => [ // an array of permissions only for student
                'create' => false,
            ],
            // we use permission inheriting.
            'inherit_id' => $permissionInternship->getKey(),
            'description' => 'student internship permissions'
        ]);

Note: inherit_id in internships.student. since internships.student inherit permissions from internships we can can forget about internships.student because now we recognize it as internships. so getPermissions will return array('internships' => [...permissions merged with internships.student...])

Lets assign those permissions to newly created roles.

$roleTeacher->assignPermission('internships');  // or assignPermission($permissionInternship->id)
$roleStudent->assignPermission('internships.student');

And then we can assign those roles to our user.

$user->assignRole($roleTeacher);
$user->assignRole($roleStudent);
//$user->revokeRole('teacher');

Finally, lets do our tests.

// user has teacher and student role
dump($user->hasPermission('create.internships')); // results true

// user has teacher role
dump($user->hasPermission('create.internships')); // results true

// user has student role
dump($user->hasPermission('create.internships')); // results false

dump($user->getPermissions());