CanAccessPanel logic causing 403 error for livewire.update on Tenant Registration Form

Dealing with an issue that I think comes down to inexperience. In my development environment, I am working on my logic for what panels a user has access to. in my user model, i have these functions:
public function canAccessPanel(Panel $panel): bool
{
//if panel is admin, only saas employees can access
if($panel->getId() === 'admin'){
return $this->canAccessAdminPanel();
}elseif ($panel->getId() === 'company') {
return $this->canAccessCompanyPanel();
}
return false;
}

public function canAccessAdminPanel(): bool
{
return $this->isSaasEmployee();
}

public function canAccessCompanyPanel(): bool
{

// Check if user is a SAAS employee
if ($this->isSaasEmployee()) {
return true;
}

// Check if user is associated with any companies
if ($this->companies()->exists()) {
return true;
}

return false;
public function canAccessPanel(Panel $panel): bool
{
//if panel is admin, only saas employees can access
if($panel->getId() === 'admin'){
return $this->canAccessAdminPanel();
}elseif ($panel->getId() === 'company') {
return $this->canAccessCompanyPanel();
}
return false;
}

public function canAccessAdminPanel(): bool
{
return $this->isSaasEmployee();
}

public function canAccessCompanyPanel(): bool
{

// Check if user is a SAAS employee
if ($this->isSaasEmployee()) {
return true;
}

// Check if user is associated with any companies
if ($this->companies()->exists()) {
return true;
}

return false;
Simple enough. Does what it is supposed to. However, I ran into problems. Because a newly registered user is not associated with a tenant yet, the user was not able to access the company/new page to create a tenant. Additionally, I realized they couldn't access the /company/logout page. Each presented with a 403 error. This is where I worry I'm messing up. I added some exceptions based on routes:
11 Replies
karpadiem
karpadiemOP3mo ago
public function canAccessCompanyPanel(): bool
{

$route = request()->route();

if ($route && $route->getName()) {
\Log::info('Route name:', ['route' => $route->getName()]);
} else {
\Log::info('No route name available');
}

// Allow access to specific routes
if ($route && in_array($route->getName(), [
'filament.company.tenant.registration',
'filament.company.auth.logout',
'filament.company.auth.login',
])) {
\Log::info('User is accessing an allowed route');
return true;
}
public function canAccessCompanyPanel(): bool
{

$route = request()->route();

if ($route && $route->getName()) {
\Log::info('Route name:', ['route' => $route->getName()]);
} else {
\Log::info('No route name available');
}

// Allow access to specific routes
if ($route && in_array($route->getName(), [
'filament.company.tenant.registration',
'filament.company.auth.logout',
'filament.company.auth.login',
])) {
\Log::info('User is accessing an allowed route');
return true;
}
This allowed the user to access these pages. However, shortly after accessing the page, the first livewire.update request happens and a 403 error is thrown. The only thing i can think to do to fix it (and it does) is add
//if route is livewire.update
if ($route && $route->getName() && $route->getName() === 'livewire.update') {
\Log::info('User is accessing livewire message');
return true;
}
//if route is livewire.update
if ($route && $route->getName() && $route->getName() === 'livewire.update') {
\Log::info('User is accessing livewire message');
return true;
}
But i worry that will create some sort of security issue. Am i missing something obvious?
awcodes
awcodes3mo ago
Seems like you are creating circular logic.
karpadiem
karpadiemOP3mo ago
Oh? Im not sure i see where that is happening. That would cause a 403 error on a livewire request?
awcodes
awcodes3mo ago
403 just means that one of your conditions is returning false. So you have to step through each condition to figure out where the logic is falling apart.
karpadiem
karpadiemOP3mo ago
After lots of trial and error. It's failing when the route is a livewire.update request orignating from the company panel when the user is not yet associated with a company (my tenant model). This bit of code added to anAccessCompanyPanel() fixes it, but I worry that's not the approprate way to handle it. Does this present a security risk?
/if route is livewire.update
if ($route && $route->getName() && $route->getName() === 'livewire.update') {
\Log::info('User is accessing livewire message');
return true;
}
/if route is livewire.update
if ($route && $route->getName() && $route->getName() === 'livewire.update') {
\Log::info('User is accessing livewire message');
return true;
}
I think the TLDR here is: How do I use canAccessPanel() on the user model and tenantRegistration() on the panel service provider together.
awcodes
awcodes3mo ago
Ah, it’s not a security risk but a side effect of having tenants and the way that works fundamentally. In a tenant context you can’t authorize them without being associated with a tenant. There’s not a way to have an in between state. It’s just how tenancy works. It just doesn’t make sense to have routes based on a tenant but users that can access any tenant without a global gate for something like admin or super admin roles.
karpadiem
karpadiemOP3mo ago
Access to particular tenant is controlled elsewhere right? This is just if the user can access the particular panel or not? I did it this way because besides the two user types above (member of an company and employees of the Saas [admins]) there is a third user type and panel of customer. Based on your feedback, sounds like i have three options? - Leave it as is with the livewire.update route override (assuming this is not security risk) - Move my tenant (company) registration outside of the company panel - Remove the check for accessing the company panel and handle rerouting "customers" a different way. Does that sound right?
awcodes
awcodes3mo ago
Do the users registering for company create their own tenants (company), or should they be added to existing ones?
karpadiem
karpadiemOP3mo ago
They create their own tenants
awcodes
awcodes3mo ago
Hmm, ok then something is hijacking the process. In a standard tenant setup when a user registers it should redirect to a tenant creation page before it even hits the panel. If you have a repo you can share I can dig further.
karpadiem
karpadiemOP3mo ago
That would be great! I’ll clean some stuff up and send it your way!
Want results from more Discord servers?
Add your server