feat(tenant): implement tenant filter scope to manage cross-tenant data visibility
This commit is contained in:
@@ -547,6 +547,12 @@ Get all appointments for the authenticated user.
|
||||
|
||||
**Permission:** `AUTH` — عمداً بدون مجوزِ رجیستری.
|
||||
|
||||
> **فیلتر محیط اینجا اعمال نمیشود.** رکورد در محیطِ پزشکِ مقصد ثبت میشود، ولی
|
||||
> مالکش از راه `user_id` تعیین میشود. کاربری که خودش صاحب محیط دیگری است — پزشک،
|
||||
> منشی، مالک کلینیک — با فیلترِ محیطِ خودش رکورد خودش را نمیدید و ۴۰۴ میگرفت.
|
||||
> دورزدن فیلتر فقط از راه `App\Shared\Tenant\TenantFilterScope` انجام میشود و
|
||||
> مجوز دستنخورده باقی میماند.
|
||||
|
||||
> این اندپوینت `a.user = خودِ کاربر` را میدهد، یعنی نوبتهای خودِ فرد **بهعنوان
|
||||
> بیمار**، نه دادهٔ محیط. مصرفکنندهاش داشبورد بیمار در `nobat724_front` است.
|
||||
> آدیت ۲۰۲۶-۰۸-۰۷ آن را در فهرست گَپها آورده بود؛ در ۲۰۲۶-۰۸-۰۸ مثبت کاذب تشخیص
|
||||
|
||||
@@ -131,6 +131,12 @@ List the **authenticated user's own** payments (derived from the token — there
|
||||
|
||||
**Permission:** `IS_AUTHENTICATED_FULLY`
|
||||
|
||||
> **فیلتر محیط اینجا اعمال نمیشود.** رکورد در محیطِ پزشکِ مقصد ثبت میشود، ولی
|
||||
> مالکش از راه `user_id` تعیین میشود. کاربری که خودش صاحب محیط دیگری است — پزشک،
|
||||
> منشی، مالک کلینیک — با فیلترِ محیطِ خودش رکورد خودش را نمیدید و ۴۰۴ میگرفت.
|
||||
> دورزدن فیلتر فقط از راه `App\Shared\Tenant\TenantFilterScope` انجام میشود و
|
||||
> مجوز دستنخورده باقی میماند.
|
||||
|
||||
### Query Parameters
|
||||
| Param | Type | Default | Description |
|
||||
|-------|------|---------|-------------|
|
||||
@@ -405,6 +411,12 @@ Get payment status and details.
|
||||
|
||||
**Permission:** `AUTH` — must be the payment owner or `ROLE_ADMIN`
|
||||
|
||||
> **فیلتر محیط اینجا اعمال نمیشود.** رکورد در محیطِ پزشکِ مقصد ثبت میشود، ولی
|
||||
> مالکش از راه `user_id` تعیین میشود. کاربری که خودش صاحب محیط دیگری است — پزشک،
|
||||
> منشی، مالک کلینیک — با فیلترِ محیطِ خودش رکورد خودش را نمیدید و ۴۰۴ میگرفت.
|
||||
> دورزدن فیلتر فقط از راه `App\Shared\Tenant\TenantFilterScope` انجام میشود و
|
||||
> مجوز دستنخورده باقی میماند.
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
|
||||
@@ -76,6 +76,30 @@ clinic_uuid صریحِ درخواست > UserActiveContext ذخیرهشده
|
||||
| SQL خام DBAL | ❌ |
|
||||
| فرزندان aggregate | ❌ — همیشه از ریشه JOIN کن |
|
||||
|
||||
### استثنای مجاز: دادهٔ «مالِ خودِ کاربر»
|
||||
|
||||
چند رکورد در محیطِ یک مطب ثبت میشوند ولی مالکشان بیمار است، نه آن مطب: پرداختِ نوبت و
|
||||
خودِ نوبتِ بیمار. مجوزشان با `user_id` بررسی میشود، نه با محیط.
|
||||
|
||||
اینجا فیلتر چیزی به امنیت اضافه نمیکند و فقط ضرر میزند: کاربری که خودش صاحب محیط
|
||||
دیگری است — پزشکی که از مطب دیگری نوبت میگیرد، منشیای که جایی بیمار است — رکورد
|
||||
خودش را نمیدید و صفحهٔ نتیجهٔ پرداخت ۴۰۴ میشد.
|
||||
|
||||
تنها راه مجاز دورزدن، `App\Shared\Tenant\TenantFilterScope::withoutFilter()` است.
|
||||
عمداً یک کلاس جداست تا جاهای دورزدن قابل شمردن بمانند، و فیلتر را در `finally`
|
||||
برمیگرداند تا بقیهٔ همان درخواست دوباره محدود شود.
|
||||
|
||||
مصرفکنندگان فعلی — هر سه کاربرمحور، نه محیطمحور:
|
||||
|
||||
| اندپوینت | چرا |
|
||||
|---|---|
|
||||
| `GET /api/v1/payment/{uuid}` | پرداختکننده باید پرداخت خودش را ببیند |
|
||||
| `GET /api/v1/my/payments` | همان، به شکل فهرست |
|
||||
| `GET /api/v1/appointments/user` | نوبتهای خودِ فرد بهعنوان بیمار |
|
||||
|
||||
`PayerSeesOwnPaymentTest` هر سه را میبندد و همزمان تأیید میکند که پرداختِ کاربر
|
||||
دیگر همچنان ۴۰۳ میگیرد.
|
||||
|
||||
**فیلتر جایگزین authorization نیست.** `AppointmentAccessChecker`، `ClinicDoctorAccessChecker`، `SecretaryAccessChecker` و `PatientRecordScopeResolver` سر جایشان میمانند: آنها «چه کاری مجاز است» را جواب میدهند، فیلتر فقط «کدام ردیفها».
|
||||
|
||||
### تغییر رفتار: ۴۰۴ بهجای ۴۰۳
|
||||
|
||||
Reference in New Issue
Block a user