0
votes

I'm currently working on a Laravel project that is somewhat multi-tenant. An administrator will be creating companies that are essentially the tenants, but a user can be part of multiple companies, each with a role or assigned individual permissions.

To make things more complex, a user can also be assigned to a project with a role, which will give them access to that project even if they aren't part of that project.

A user will be able to see all of their data that they're tied to on the same portal, so there is no switching tenants.

So permissions are getting awfully confusing with all the relationships. The following are tables that I forsee being needed to set up the relationships like this:

user:

  • id

user_role (used for assigning admin users):

  • user_id
  • role_id

company:

  • id

user_company:

  • id
  • user_id
  • company_id
  • role_id

user_company_permission:

  • id
  • user_company_id
  • permission_id

permission:

  • id
  • name

role:

  • id
  • name

permission_role:

  • id
  • permission_id
  • role_id

project: - id - (other project related information)

project_user: - id - project_id - user_id - role_id

So basically, is there any easy way to manage all of these permissions? It would be nice if when checking permissions, it would default check all user's companies and projects, but if one is passed in it limits it to that company or project.

I've looked into some permission plugins but I can't find anything that seems to suit my issue easily.

1
Do permissions of a role have to be dynamic (i.e. in the database) or could it be hard-coded? I just created something similar (but not as complex) and the way I did it was to save a role in the pivot table and check permissions in policies.Thomas
Roles themselves could be hardcoded, but users for a company need to be able to be assigned individual permissions, or assigned a role.Matthew Weeks

1 Answers

0
votes

If the permissions of each role don't have to be dynamic you might be able to replace the role and permission tables with a Policies. Just add a role field to the user_company table (I would personally make it a string to be easier to read).

Then in the CompanyPolicy you can run checks like this:


    /**
     * Determine whether the user can view the object.
     *
     * @param  \App\User  $user
     * @param  \App\Company  $company
     * @return mixed
     */
    public function view(User $user, Company $company)
    {
        $allowedRoles = ['admin', 'someotherrole'];
        return $user->companies()->wherePivotIn('role', $allowedRoles)->count() > 0;
    }

If later you do require dynamic permissions you could still add them in addition to this method and check the individual permissions before checking the role.