mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-11 07:24:47 +00:00
* Fix CustomerPolicy missing hasCompany() check (cross-company IDOR) Add $user->hasCompany($customer->company_id) check to view, update, delete, restore, and forceDelete methods in CustomerPolicy, matching the pattern used by all other policies (InvoicePolicy, PaymentPolicy, EstimatePolicy, etc.). Without this check, a user in Company A with view-customer ability could access customers belonging to Company B by providing the target customer's ID. Add cross-company authorization tests to verify the fix. Closes #565 * Scope bulk delete to current company to prevent cross-company deletion Filter customer IDs through whereCompany() before passing to deleteCustomers(), ensuring users cannot delete customers belonging to other companies via the bulk delete endpoint.
126 lines
2.7 KiB
PHP
126 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Policies;
|
|
|
|
use App\Models\Customer;
|
|
use App\Models\User;
|
|
use Illuminate\Auth\Access\HandlesAuthorization;
|
|
use Silber\Bouncer\BouncerFacade;
|
|
|
|
class CustomerPolicy
|
|
{
|
|
use HandlesAuthorization;
|
|
|
|
/**
|
|
* Determine whether the user can view any models.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function viewAny(User $user): bool
|
|
{
|
|
if (BouncerFacade::can('view-customer', Customer::class)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can view the model.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function view(User $user, Customer $customer): bool
|
|
{
|
|
if (BouncerFacade::can('view-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can create models.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function create(User $user): bool
|
|
{
|
|
if (BouncerFacade::can('create-customer', Customer::class)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can update the model.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function update(User $user, Customer $customer): bool
|
|
{
|
|
if (BouncerFacade::can('edit-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can delete the model.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function delete(User $user, Customer $customer): bool
|
|
{
|
|
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can restore the model.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function restore(User $user, Customer $customer): bool
|
|
{
|
|
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can permanently delete the model.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function forceDelete(User $user, Customer $customer): bool
|
|
{
|
|
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the user can delete models.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function deleteMultiple(User $user)
|
|
{
|
|
if (BouncerFacade::can('delete-customer', Customer::class)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|