Privileges
Privilege and Group control for Laravel, (*1)
Installation
You can install this package via composer using this command:, (*2)
composer require panoscape/privileges
Register service provider:, (*3)
config/app.php, (*4)
'providers' => [
...
Panoscape\Privileges\PrivilegesServiceProvider::class,
];
If you need blade directives, also add this:, (*5)
config/app.php, (*6)
'providers' => [
...
Panoscape\Privileges\PrivilegesBladeServiceProvider::class,
];
A middleware can also be registered:, (*7)
app/Http/Kernel.php, (*8)
protected $routeMiddleware = [
...
'privileges' => \Panoscape\Privileges\Middleware\PrivilegesMiddleware::class,
];
Publish profile config:, (*9)
php artisan vendor:publish --provider="Panoscape\Privileges\PrivilegesServiceProvider" --tag="profile"
Modify the published profile template to suit your application., (*10)
config/privileges_profile.php, (*11)
<?php
return [
/*
|--------------------------------------------------------------
| User entity
|--------------------------------------------------------------
|
*/
'user' => [
/*
|--------------------------------------------------------------
| Model class
|--------------------------------------------------------------
|
*/
'model' => '\App\User',
/*
|--------------------------------------------------------------
| Table name
|--------------------------------------------------------------
|
*/
'table' => 'users',
/*
|--------------------------------------------------------------
| Primary key name in table
|--------------------------------------------------------------
|
*/
'id' => 'id',
],
/*
|--------------------------------------------------------------
| Group entity
|--------------------------------------------------------------
|
*/
'group' => [
/*
|--------------------------------------------------------------
| Model class
|--------------------------------------------------------------
|
*/
'model' => '\App\Group',
/*
|--------------------------------------------------------------
| Table name
|--------------------------------------------------------------
|
*/
'table' => 'groups',
/*
|--------------------------------------------------------------
| Primary key name in table
|--------------------------------------------------------------
|
*/
'id' => 'id',
],
/*
|--------------------------------------------------------------
| Privilege entity
|--------------------------------------------------------------
|
*/
'privilege' => [
/*
|--------------------------------------------------------------
| Model class
|--------------------------------------------------------------
|
*/
'model' => '\App\Privilege',
/*
|--------------------------------------------------------------
| Table name
|--------------------------------------------------------------
|
*/
'table' => 'privileges',
/*
|--------------------------------------------------------------
| Primary key name in table
|--------------------------------------------------------------
|
*/
'id' => 'id',
],
/*
|--------------------------------------------------------------
| User-Group pivot table
|--------------------------------------------------------------
|
*/
'user_group' => [
/*
|--------------------------------------------------------------
| Table name
|--------------------------------------------------------------
|
*/
'table' => 'group_user',
/*
|--------------------------------------------------------------
| User foreign key in table
|--------------------------------------------------------------
|
*/
'user_id' => 'user_id',
/*
|--------------------------------------------------------------
| Group foreign key in table
|--------------------------------------------------------------
|
*/
'group_id' => 'group_id',
],
/*
|--------------------------------------------------------------
| Group-Privilege pivot table
|--------------------------------------------------------------
|
*/
'group_privilege' => [
/*
|--------------------------------------------------------------
| Table name
|--------------------------------------------------------------
|
*/
'table' => 'privilege_group',
/*
|--------------------------------------------------------------
| Group foreign key in table
|--------------------------------------------------------------
|
*/
'group_id' => 'group_id',
/*
|--------------------------------------------------------------
| Privilege foreign key in table
|--------------------------------------------------------------
|
*/
'privilege_id' => 'privilege_id',
]
];
Add Panoscape\Privileges\Privilege\UserEntity
trait to your user model, Panoscape\Privileges\Privilege\GroupEntity
trait to your group model, and Panoscape\Privileges\Privilege\PrivilegeEntity
trait to your privilege model., (*12)
If you have multiple privileges control flow or you prefer a different profile name, you may copy and modify the default profile template and rename it to something else, admin_profile
for example. Then defile a method named profile
in your related models and set them to the config name of your choice., (*13)
Here is an example of Admin
, Role
, Permission
(instead of User
,Group
,Privilege
):, (*14)
config/admin_profile.php, (*15)
<?php
return [
'user' => [
'model' => '\App\Admin',
'table' => 'admins',
'id' => 'id',
],
'group' => [
'model' => '\App\Role',
'table' => 'roles',
'id' => 'id',
],
'privilege' => [
'model' => '\App\Permission',
'table' => 'permissions',
'id' => 'id',
],
'user_group' => [
'table' => 'admin_role',
'user_id' => 'admin_id',
'group_id' => 'role_id',
],
'group_privilege' => [
'table' => 'permission_role',
'group_id' => 'role_id',
'privilege_id' => 'permission_id',
]
];
app/Admin.php, (*16)
class Admin extends Authenticatable
{
...
use \Panoscape\Privileges\UserEntity;
public function profile()
{
return 'admin_profile';
}
}
app\Role.php, (*17)
class Role extends Model
{
...
use \Panoscape\Privileges\GroupEntity;
public function profile()
{
return 'admin_profile';
}
}
app\Permission.php, (*18)
class Permission extends Model
{
...
use \Panoscape\Privileges\PrivilegeEntity;
public function profile()
{
return 'admin_profile';
}
}
Migration
This package does not provide any migrations or commands. You should create three required models/migrations and two pivot tables by yourself. The minimal requirements of table structures are listed in the profile template., (*19)
Basic Usage
Access groups/privileges relationship of a user:, (*20)
$user->groups()->get();
$user->privileges()->get();
or via dynamic properties:, (*21)
$user->groups->get();
$user->privileges->get();
If you have different entity names other than the default User
, Group
, Privilege
, You should access the relationships by the table
values defined in your profile., (*22)
Example of Admin
, Role
, Permission
:, (*23)
$admin->roles()->get();
$admin->roles->get();
$admin->permissions()->get();
$role->admins->get();
$role->permissions->get();
$permission->roles->get();
Group and Privilege validation, (*24)
has:, (*25)
//returns true if target group is found on this user
$user->groups()->has('root');
all:, (*26)
//returns false unless all groups are found on this user
$user->groups()->all(['editor', 'author', 'subscriber']);
any:, (*27)
//returns true as long as any of these groups are found on this user
$user->groups()->any(['editor', 'author', 'subscriber']);
Instead of the default name
column checking, you may specify which column to check:, (*28)
//check name column by default
$user->groups()->has('root');
//check fullname column instead
$user->groups()->has('Root Administrator', 'fullname');
//check id column instead
$user->groups()->any([1, 3, 5], 'id');
validate:, (*29)
With this method you can do complex checking, (*30)
all:, (*31)
$user->groups()->validate('root|author|subscriber')
equivalent to, (*32)
$user->groups()->all(['editor', 'author', 'subscriber'])
any:, (*33)
$user->groups()->validate('(root|author|subscriber)')
equivalent to, (*34)
$user->groups()->any(['editor', 'author', 'subscriber'])
all + any:, (*35)
$user->privileges()->validate('query|(delete|insert)|update')
equivalent to, (*36)
$user->privileges()->all(['query', 'update']) && $user->privileges()->any(['delete', 'insert'])
group:, (*37)
$user->validate('g=root|(author|subscriber)')
equivalent to, (*38)
$user->groups()->all(['root']) && $user->groups()->any(['author', 'subscriber'])
privilege:, (*39)
$user->validate('p=query|(delete|insert)|update')
equivalent to, (*40)
$user->privileges()->all(['query', 'update']) && $user->privileges()->any(['delete', 'insert'])
group + privilege:, (*41)
$user->validate('g=root|(author|subscriber);p=query|(delete|insert)|update')
equivalent to, (*42)
$user->groups()->all(['root']) && $user->groups()->any(['author', 'subscriber'])
&& $user->privileges()->all(['query', 'update']) && $user->privileges()->any(['delete', 'insert'])
Column specification is also available:, (*43)
$user->validate('g=1|(3|5);p=1|(2|10)|3', 'id')
Middleware
If you have registered the middleware, you can add it to any routes you'd like to guard with it., (*44)
Route::get('/pages', 'PageController@index')->middleware('privileges:g=editor|(author|subscriber);p=query|(delete|insert)|update');
Balde
If you have registered the blade service provider, you may guard your blade codes with @validate
, @group
and @privilege
., (*45)
Also your user entity need to implement Panoscape\Privileges\Privileged
interface in order to use these blade directives., (*46)
class Admin extends Authenticatable implements \Panoscape\Privileges\Privileged
{
...
use \Panoscape\Privileges\UserEntity;
}
Blade directives:, (*47)
@group('root')
<button>
...
</button>
@endgroup
@privilege('edit_users')
<button>
...
</button>
@endprivilege
@validate('g=(root|editor);p=edit_users')
<button>
...
</button>
@endvalidate
$user->privileges()->validate('editor_users|edit_admins')
joined 5 tables(2 of them are pivot tables) within one query:, (*48)
select count(*) as aggregate from "permissions" inner join "permission_role" on "permissions"."id" = "permission_role"."permission_id" inner join "roles" on "roles"."id" = "permission_role"."role_id" inner join "admin_role" on "roles"."id" = "admin_role"."role_id" inner join "admins" on "admins"."id" = "admin_role"."admin_id" where "admins"."id" = '1' and "permissions"."name" in ('edit_users', 'edit_admins')
$user->privileges()->validate('edit_users|(create_admins|edit_admins)')
joined 5 tables(2 of them are pivot tables) within two query:, (*49)
select count(*) as aggregate from "permissions" inner join "permission_role" on "permissions"."id" = "permission_role"."permission_id" inner join "roles" on "roles"."id" = "permission_role"."role_id" inner join "admin_role" on "roles"."id" = "admin_role"."role_id" inner join "admins" on "admins"."id" = "admin_role"."admin_id" where "admins"."id" = '1' and "permissions"."name" in ('create_admins', 'edit_admins')
select count(*) as aggregate from "permissions" inner join "permission_role" on "permissions"."id" = "permission_role"."permission_id" inner join "roles" on "roles"."id" = "permission_role"."role_id" inner join "admin_role" on "roles"."id" = "admin_role"."role_id" inner join "admins" on "admins"."id" = "admin_role"."admin_id" where "admins"."id" = '1' and "permissions"."name" in ('edit_users')
$user->privileges()->validate('(edit_users|delete_users)|(create_admins|edit_admins)')
joined 5 tables(2 of them are pivot tables) within two query:, (*50)
select count(*) as aggregate from "permissions" inner join "permission_role" on "permissions"."id" = "permission_role"."permission_id" inner join "roles" on "roles"."id" = "permission_role"."role_id" inner join "admin_role" on "roles"."id" = "admin_role"."role_id" inner join "admins" on "admins"."id" = "admin_role"."admin_id" where "admins"."id" = '1' and "permissions"."name" in ('edit_users', 'delete_users')
select count(*) as aggregate from "permissions" inner join "permission_role" on "permissions"."id" = "permission_role"."permission_id" inner join "roles" on "roles"."id" = "permission_role"."role_id" inner join "admin_role" on "roles"."id" = "admin_role"."role_id" inner join "admins" on "admins"."id" = "admin_role"."admin_id" where "admins"."id" = '1' and "permissions"."name" in ('create_admins', 'edit_admins')
Conclusion, (*51)
Each any group costs one query;, (*52)
All all group costs one query., (*53)