fix(permissions): make the addresses resource real instead of decorative
A full role-by-role sweep (9 roles x 18 endpoints against the running app) showed
the addresses toggles in the owner's permission form controlled nothing. Grep
confirms it: no gate anywhere referenced 'addresses'. The panel's address list was
gated on appointment_settings.view instead — the same borrowed-permission pattern
already fixed for resources and treatment.
GET /api/v1/addresses now gates on addresses.view.
The resource drops to view-only. Creating, updating and deleting an address in
ClinicController is explicitly owner-or-admin
($clinic->getUser()->getId() !== $user->getId()), so those three actions could
never be delegated to a secretary or an invited doctor no matter what the form
said. Both role defaults narrow to ['view' => true] to match, and stored JSON
keeps its old keys harmlessly since merge only reads registry keys.
This widens secretary access: addresses.view defaults to true while
appointment_settings.view defaults to false, so secretaries who could not list
addresses now can. That is deliberate and costs no confidentiality — the same
addresses are already served anonymously from
GET /api/v1/clinic/{uuid}/addresses, which is whitelisted in security.yaml.
Verified live in three states: default 200, addresses.view off 403, and
addresses off with appointment_settings on still 403, proving the borrow is gone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,7 +39,7 @@ class ClinicDoctorPermission
|
||||
'services' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'clinic_info' => ['view' => true, 'update' => false],
|
||||
'insurances' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'addresses' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'addresses' => ['view' => true],
|
||||
'resources' => ['view' => true, 'create' => true, 'update' => true, 'delete' => true],
|
||||
'inventory' => ['view' => false, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'tags' => ['view' => false, 'create' => false, 'update' => false, 'delete' => false],
|
||||
|
||||
@@ -35,8 +35,10 @@ class AddressController extends BaseController
|
||||
#[Route('/api/v1/addresses', name: 'address_list', methods: ['GET'])]
|
||||
public function list(#[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->secretaryAccess->denyUnlessGranted($user, 'appointment_settings', 'view');
|
||||
$this->clinicDoctorAccess->denyUnlessGranted($user, 'appointment_settings', 'view');
|
||||
// منبعِ خودش، نه `appointment_settings` قرضی: توگلِ «آدرسها» در فرمِ مالک
|
||||
// تا پیش از این هیچ چیزی را کنترل نمیکرد.
|
||||
$this->secretaryAccess->denyUnlessGranted($user, 'addresses', 'view');
|
||||
$this->clinicDoctorAccess->denyUnlessGranted($user, 'addresses', 'view');
|
||||
|
||||
return $this->success(array_map(
|
||||
static fn (DoctorAddress $a): array => $a->toArray(),
|
||||
|
||||
@@ -40,7 +40,7 @@ class DoctorSecretary
|
||||
'treatment' => ['view' => true, 'update' => false],
|
||||
'payments' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'insurances' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'addresses' => ['view' => true, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'addresses' => ['view' => true],
|
||||
'clinic_info' => ['view' => true, 'update' => false],
|
||||
'inventory' => ['view' => false, 'create' => false, 'update' => false, 'delete' => false],
|
||||
'tags' => ['view' => false, 'create' => false, 'update' => false, 'delete' => false],
|
||||
|
||||
@@ -65,13 +65,15 @@ final class PermissionCatalog
|
||||
'delete' => 'حذف بیمه',
|
||||
],
|
||||
],
|
||||
/**
|
||||
* فقط `view`. ساخت/ویرایش/حذفِ آدرس در ClinicController بهصورت صریح
|
||||
* owner-or-admin است (`$clinic->getUser()->getId() !== $user->getId()`)
|
||||
* و اصلاً قابل واگذاری نیست؛ سه توگلِ قبلی هیچوقت چیزی را کنترل نمیکردند.
|
||||
*/
|
||||
'addresses' => [
|
||||
'label' => 'آدرسها',
|
||||
'actions' => [
|
||||
'view' => 'مشاهده آدرسها',
|
||||
'create' => 'ایجاد آدرس',
|
||||
'update' => 'ویرایش آدرس',
|
||||
'delete' => 'حذف آدرس',
|
||||
'view' => 'مشاهده آدرسها',
|
||||
],
|
||||
],
|
||||
'clinic_info' => [
|
||||
|
||||
Reference in New Issue
Block a user