How to check user roles in canAccessPanel()
Hello, I can't seem to find the code to use to check if a role is assigned to a user from database into canAccessPanel()
I need to check:
role_user pivot table
Admin has role_id 1, user_id 1
Company user has role_id 2, user_id 2
(for this example, but many users will have role_id 2)
I have a different panel for each... AdminPanelProvider for Admin Role, CompanyPanelProvider for Company Role
I tried checking documentation and online and can't figure this out 😦
Thank you in advanced!
34 Replies
What I would do is add this helper function to the User model
Then, in the
canAccessPanel
method
This definitely works so far, is there a way to specify which role gets to view which panel?
For example, Company gets CompanyPanelProvider, and Admin gets AdminPanelProvider?
I personally haven't found one yet 🤷♂️
Same, I can't find it for the life of me :/ must not be a way to do that yet :/
But how do I prevent a Company user from switching to the Admin panel? Seems like it should be implemented somehow haha
Especially because all they need to do is just change the endpoint URL and they would get access easily
Well, if the Admin panel only allows access to users with admin role, I would guess they'd just get a 403 error page
Yup, that's exactly what happens
Well, there's an idea. You can customize Laravel error pages and maybe offer a link to take the user to the proper panel based on their role
True but then how do I allow access to Company panel? Haha
If I use: return auth()->user()->hasRole(['admin', 'company']);
This would let Admin & Company see both panels :/
If I remove Company, then only Admin can see both panels :/
Ok, walk me through the process here:
- Admin users can access both panels (as they should)
- Company users can only access the Company panel
- If a Company user logs in using the Admin panel, they get a 403
This would return true, only if the currently logged in user has at least one of those roles (ie. an admin user)
So, you would want the Company user to only have the 'company' role
Yes those steps are correct
And yes, Company user would only have 'company' role and can only access the Company panel (get 403 for Admin panel)
Oh good, I got it right. So yeah. If you do
php artisan vendor:publish --tag=laravel-errors
, you can customize the 403 page and render a link based on the user roles. You have access to the auth()
helper withing any template.
So if I'm a Company user in the admin panel, the link would say "Looks like you're lost, try logging in the <a href="...">Company panel</a>"Interesting, how does it know that when using
return auth()->user()->hasRole(['admin', 'company']);
?I would use it like this:
Because we already know that the Admin user would never get a 403
and I may have confused you before. The
canAccessPanel()
method of the Admin panel would have auth()->user()->hasRole('admin')
. Allowing only admin users to that panelInteresting, how does it know to let the company access the company panel tho 😆
Sorry this filament user access part is really new for me
is canAccessPanel only for admins?
You would add
auth()->user()->hasRole('company')
to the canAccessPanel()
of the Company panel
canAccessPanel is just a way of letting certain user see the current panelBut if it's on the User model, how do we set it for the Company panel?
If I set it to Admin then Company can't access any panels, if I set it to both Admin and Company, both can access both :/
I believe the panel instance is injected into the
canAccessPanel()
method
OMG
How am I so blind
haha
$panel->getId()
should helpFor reference, this is what worked (I called the Company Owner the Owner Role)
public function canAccessPanel(Panel $panel): bool
{
$panelGetId = $panel->getId();
if(auth()->user()->hasRole(['Admin']) && $panelGetId == 'admin'){
return true;
}elseif(auth()->user()->hasRole(['Owner']) && $panelGetId == 'company'){
return true;
}else{
return false;
}
}
Thank you for leading me in the right direction! I was so lost!More than happy to help 👍
I just realized I might have to change this around a bit, as Filament expects to use "company_user" table to determine who is a company user (instead of using the roles with company_id)
Yeah, you're right.
So maybe it's better to get rid of roles all together and just check if they are in company_user table 😮
Or I should add role_id to company_user?
but, isn't company_user for multi-tenancy purposes?
Yeah it is 😮 Man this is difficult
My end goal is to have
Admin
Company Owner (just Owner for the role)
Clients
I know. So you still need roles. Panels and Multi-Tenancy are different. As I understand it. You can have multiple panels. And each panel can have their own Tenants (as configured in the panel service provider).
Yes that's correct
I think my main confusion is how do I assign the Role to the specific User for the specific Company
As Users can have multiple Companies, and Companies can have multiple Users, and a User can have multiple Roles within the same Company...
I tried this:
$user = auth()->user()->id;
$company = Company::create($data);
$role = Role::where('name', 'Owner')->first();
//assign pivot table
$company->user()->attach(auth()->user());
//assign company owner role
$user->attachRole($role);
return $company;
But it tells me:
Call to a member function attachRole() on int
$user = auth()->user()->id;
$user->attachRole($role);
Do you see the issue there?
Dang I think I need a break hahahha
Yeah I see the issue, it's giving the User ID instead of the User Model :/
Yeah, sometimes is best to take a breath and clear your mind.
Got it to work with this 😄
//create company, assign pivot table
$company = Company::create($data);
$company->user()->attach(auth()->user());
//assign company owner role
$user = User::find(auth()->user()->id);
$role = Role::find(2); //Owner Role
$user->roles()->attach($role, ['company_id' => $company->id]);
return $company;
Now the question is if I leave assigned roles in the role_user
table, or move role_id
to the company_user
table and get rid of the role_user
table... decisions...
I'll leave it since someone can be a client or a company owner in the same company
Thank you! I'll stop buggin you now haha🤣 It's no problem at all. I'm here to help
😆 It's the
abstract thinking
that can really get to me sometimes haha
In my User
model, I have:
This is giving an error saying undefined method 'hasRole'
Disregard, it was VS Code giving this error even though it's working... intelliphense (or whatever) for ya