Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zircuitz's avatar

Dynamic permissions based on eloquent model data

Hi all :)

I was hoping someone with a bigger brain than me could help me out with this one 😅

I have a model named Department. In that model; is a database table with names of every department in my organization.

I also have a User model, and the permissions and role based system from Spatie called Laravel-Permission installed in my environment.

Now here is what i'm trying to achieve using the Laravel-Permission package:

  • Say I have a user: $user1;
  • That user should have all permissions within one department called accounting and read only permissions from another department called hr.
  • So i'd assign a role to that user like this: $user1->assignRole(["operator.accounting.*", "operator.hr.read"];

Now here is where my problem is: How do I make the operator.accounting.* part of the role dynamic based on the data from the Department -model.

Or in other words:

How do I make the accounting and hr -part of the role assignment dynamic with values from whatever the Department -model contains?

What I could do is make an event listener for the department model, and just update the roles table whenever the data within the department model changes, but that seems cumbersome, and not a very elegant way to do it. As I would have to keep double sets of records.

Is there a better way to do this where I could keep it to just one dataset?

Any help is greatly appreciated.

Thanks :)

0 likes
1 reply
jlrdw's avatar

Why don't you just check that the user with that particular role can access a method at method level?

However in your case you are verifying role and Department belongs to user, if I understood correctly.

Edit

If that is the case you could prefix your roles.

Also from a previous post:

  • Bob is an admin

  • Suzy is admin and does bookkeeping

  • Mary is a bookkeeper only

  • If Bob is logged in, Bob can only do admin stuff and all access to user stuff. But Bob cannot mess with bookkeeping.

  • If Suzy is logged in she can access admin stuff and bookkeeping and accounting stuff.

  • If Mary is logged in she cannot mess with admin stuff, but has access to bookkeeping and accounting stuff.

So I just check at method level if the logged in users role can or cannot access that method / function.

And use query scopes to let a user edit / view their own data or an admin can access all users data.

Each app will be different as to who can do what.

So in pseudocode:

public function makeInvoice()
    {
        if (a required role of bkeep is not true here) {   // bkeep = bookkeeper
            return redirect('somewhere'); // whereever you redirect to if not authorized
        }
        // Rest of method here is accomplished if 
        // the logged in user has the required role of 'bkeep'.
    }

Again just examples.

Another example I saw:

public function update(Request $request, Post $post) {
    if ($post->author !== auth()->user()->id || auth()->user()->cannot('edit posts'))
        abort(404);// or redirect, or whatever action 
    }
    //rest of method if all okay
}

In summary RBAC is at least 3 main steps:

  • A login required
  • An authorization implementation to determine what the logged in person with role can or cannot do
  • Protection of URL and parameters, checking that the logged in users id matches the id used in a query

Each application will require unique tweaks in RBAC, no two apps are exactly the same.

Please or to participate in this conversation.