-
-
Notifications
You must be signed in to change notification settings - Fork 2
Closed
Description
Environment
- Laravel: 11.9
- PHP: 8.2
- lomkit/laravel-access-control: 0.1.5
- DB: Mysql 8
Describe the bug
When adding a SharedPerimeter to the Control, users with valid shared relationships and correct permissions (view shared products) receive no results, whereas they should be able to access shared models.
If the SharedPerimeter is removed from the control, the same user correctly accesses their own records via OwnPerimeter.
Expected behavior
Users with the view shared products permission and valid shared relationships (via sharedUsers() many-to-many) should receive matching shared records when SharedPerimeter is active.
Reproduction
Permission::firstOrCreate(['name' => 'view global products']);
Permission::firstOrCreate(['name' => 'view own products']);
Permission::firstOrCreate(['name' => 'view shared products']);$userA = User::create([...]);
$userA->givePermissionTo(['view own products']);
Product::factory()->count(2)->create(['user_id' => $userA->id]);
$userB = User::create([...]);
$userB->givePermissionTo(['view own products', 'view shared products']);
Product::factory()->count(2)->create(['user_id' => $userB->id]);
$sharedProduct = Product::where('user_id', $userA->id)->first();
$sharedProduct->sharedUsers()->attach($userB->id);Then with this Control:
class ProductControl extends Control
{
/**
* Define the perimeters used for access control on products.
*
* @return array<\Lomkit\Access\Perimeters\Perimeter>
*/
protected function perimeters(): array
{
return [
GlobalPerimeter::new()
->allowed(fn($user, $method) => $user->can("$method global products"))
->should(fn($user, $model) => true)
->query(fn($query, $user) => $query),
SharedPerimeter::new()
->allowed(fn($user, $method) => $user->can("$method shared products"))
->should(fn($user, $model) => $model->sharedUsers->contains($user))
->query(fn($query, $user) =>
$query->whereHas('sharedUsers', fn(Builder $q) =>
$q->where('product_user_shared.user_id', $user->id)
)
),
OwnPerimeter::new()
->allowed(fn($user, $method) => $user->can("$method own products"))
->should(fn($user, $model) => $model->user_id === $user->id)
->query(fn($query, $user) => $query->where('user_id', $user->id)),
];
}
}With this configuration:
- ✅
OwnPerimeterworks as expected - ❌
SharedPerimetercauses the final request to return[]
Metadata
Metadata
Assignees
Labels
No labels