- M2 GET /insurance/{id}: was unguarded; now owner-or-admin (403 otherwise) —
stops reading another doctor's negotiated price by id enumeration.
- M3 GET /clinic-pro/doctor-address/{id}: add the same owner/admin check the
sibling PATCH/DELETE already had.
- M4 POST/PATCH /service-item: staff_uuid must belong to the caller's tenant
(entity_type/entity_id) → 422; stops binding another tenant's staff.
- M5 appointment-settings list endpoints (date-override/holidays/
available-locations): add the per-doctor ownership check the sibling
single-record endpoints already enforce.
Regressions (6 negative cases fail without the fixes):
DoctorInsuranceOwnershipTest, DoctorAddressOwnershipTest,
ServiceItemStaffOwnershipTest, AppointmentSettingsListOwnershipTest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
1.4 KiB
PHP
45 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\ClinicService;
|
|
|
|
use App\ClinicService\Entity\ServiceItem;
|
|
use App\ClinicService\Entity\ServiceSection;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Staff\Entity\ClinicStaff;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* Binding staff to a service item must be scoped: a tenant must not attach
|
|
* another tenant's staff member via staff_uuid.
|
|
*/
|
|
class ServiceItemStaffOwnershipTest extends ApiTestCase
|
|
{
|
|
public function testCannotBindForeignStaff(): void
|
|
{
|
|
// owner A: their section + item
|
|
$ownerA = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctorA = new Doctor($ownerA, 'دکتر A');
|
|
$this->em->persist($doctorA);
|
|
$this->em->flush();
|
|
|
|
$section = new ServiceSection('doctor', $doctorA->getId(), 'بخش A');
|
|
$item = new ServiceItem($section, 'خدمت');
|
|
$this->em->persist($section);
|
|
$this->em->persist($item);
|
|
|
|
// unrelated tenant B's staff
|
|
$doctorB = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر B');
|
|
$this->em->persist($doctorB);
|
|
$this->em->flush();
|
|
$foreignStaff = new ClinicStaff('doctor', $doctorB->getId(), 'پرسنل B');
|
|
$this->em->persist($foreignStaff);
|
|
$this->em->flush();
|
|
|
|
$this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $ownerA, [
|
|
'staff_uuid' => $foreignStaff->getUuid(),
|
|
]);
|
|
|
|
$this->assertSame(422, $this->responseCode());
|
|
}
|
|
}
|