Files
clinicpro/tests/Insurance/DoctorInsuranceOwnershipTest.php
T
hamedandClaude Opus 4.8 fe6383314e fix(security): enforce ownership on 4 IDOR read/bind endpoints (M2-M5)
- 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>
2026-06-28 20:17:52 +03:30

50 lines
1.5 KiB
PHP

<?php
namespace App\Tests\Insurance;
use App\Doctor\Entity\Doctor;
use App\Insurance\Entity\DoctorInsurance;
use App\Insurance\Entity\Insurance;
use App\Insurance\Enum\InsuranceType;
use App\Tests\ApiTestCase;
/**
* GET /api/v1/insurance/{id} must enforce ownership — a doctor must not read
* another doctor's insurance record (incl. negotiated price) by id enumeration.
*/
class DoctorInsuranceOwnershipTest extends ApiTestCase
{
private function makeDoctorInsurance(): DoctorInsurance
{
$doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر مالک');
$this->em->persist($doctor);
$insurance = new Insurance('بیمه تست', InsuranceType::Basic);
$this->em->persist($insurance);
$di = new DoctorInsurance($doctor, $insurance);
$this->em->persist($di);
$this->em->flush();
return $di;
}
public function testOtherDoctorCannotRead(): void
{
$di = $this->makeDoctorInsurance();
$stranger = $this->createUser(['ROLE_DOCTOR']);
$this->authJson('GET', '/api/v1/insurance/' . $di->getId(), $stranger);
$this->assertSame(403, $this->responseCode());
}
public function testOwnerCanRead(): void
{
$di = $this->makeDoctorInsurance();
$owner = $di->getDoctor()->getUser();
$this->authJson('GET', '/api/v1/insurance/' . $di->getId(), $owner);
$this->assertSame(200, $this->responseCode());
}
}