1
votes

I have users, app_roles, app_permissions, app_permission_app_role, app_role_user.

The tables are self explanatory, I am creating permissions, Then assigning that permissions to new role on role creation, And then i assigns roles to users.

i check permission of the authenticated user like :

@if(auth()->user()->can('some route name'))
    Html...
@endif

The above condition checks if the user have access to that content or not based of the assigned role as we know that the role have permissions, And the can('some route name') parameter is a route name. Its working fine.

Where i am stuck !!!

The table app_role_user had user_id, app_role_id, Now i added another column organization_id... (Consider Organizations as groups, Where a user can be a member of that groups, And the owner of the group assigns single role(Can't assign multiple role) to that user). Because now the user can switch between organization and the user can have different roles in different organizations.

I have to clear path for the :

@if(auth()->user()->can('some route name'))
    Html...
@endif

Note : : Auth::user()->current_org->id show the id of the organization in which the user is in right now

As well as currently i am saving role_id, user_id, organization_id in app_role_user table.

Here is my AuthServiceProvider class,

I am Dynamically registering permissions with Laravel's Gate :

public function boot(GateContract $gate)
{
    $this->registerPolicies();
    $this->registerAllPermissions($gate);
}

protected function getPermissions() {
    return $this->app->make('App\Repositories\PermissionRepository')->withRoles();

}

private function registerAllPermissions($gate) {

    if (Schema::hasTable('app_permissions') and Schema::hasTable('users') and Schema::hasTable('app_roles')) {
        cache()->forget('app_permissions_with_roles');
        foreach ($this->getPermissions() as $permission) {
            $gate->define($permission->name, function ($user) use ($permission) {
                return $user->hasPermission($permission);
            });

        }
    }
}

Here is PermissionRepository class :

class PermissionRepository { protected $model;

public function __construct(AppPermission $model)
{
    $this->model = $model;
}

public function all(){
    return $this->model->all();
}

public function withRoles(){

    $model = $this->model;
    $permissions = cache()->remember('app_permissions_with_roles', 1*60*24, function() use($model) {
        return $model->with('roles')->get();
    });

    return $permissions;
}

}

And here is HasRoles trait having hasPermission(AppPermission $permission) because AuthServiceProvider class needs it in registerAllPermissions.

trait HasRoles {
    public function assignRole($role)
    {
        return $this->roles()->save(
            AppRole::whereName($role)->firstOrFail()
        );
    }

    public function hasRole($role)
    {
        if (is_string($role)) {
            return $this->roles->contains('name', $role);
        }
        return !! $role->intersect($this->roles)->count();
    }

    public function hasPermission(AppPermission $permission)
    {
        return $this->hasRole($permission->roles);
    }
}

What should i do, I have tried many conditions but nothing worked at all. Looking forward to hear from you guys.

Thanks for the read, Need serious attention please.

1

1 Answers

1
votes

You can try like this

User Model

//add organization_id as pivot field

public function roles(){
    return $this->belongsToMany(AppRole::class)->withPivot('organization_id');
}

//define a function

public function orgRoles($orgId){
    return $this->roles()->wherePivot('organization_id', $orgId)->get();
}

Now in trait modify hasRole function

public function hasRole($role)
{
    $orgId = Auth::user()->current_org->id;

    if (is_string($role)) {
        return $this->orgRoles($orgId)->contains('name', $role);
    }
    return !! $role->intersect($this->orgRoles($orgId))->count();
}