feat: Implement secretary permissions enforcement across multiple resources
- Added SecretaryAccessChecker to manage resource access for secretaries. - Integrated permission checks for payments, inventory, and tags in relevant controllers. - Updated PaymentController and PaymentMethodController to enforce secretary permissions. - Enhanced TenantTagController to check permissions for tag management actions. - Introduced tests for secretary resource enforcement, ensuring proper access control. - Updated DoctorSecretary entity to include inventory and tags permissions. - Created a comprehensive audit document for secretary permissions coverage and enforcement. - Fixed potential crashes in SecretaryDashboard when rendering without doctor data.
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\PaymentMethod\Controller;
|
||||
|
||||
use App\Auth\Entity\User;
|
||||
use App\PaymentMethod\Service\PaymentMethodService;
|
||||
use App\Secretary\Security\SecretaryAccessChecker;
|
||||
use App\Shared\Constant\ErrorCodes;
|
||||
use App\Shared\Controller\BaseController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
@@ -25,15 +26,23 @@ class PaymentMethodController extends BaseController
|
||||
private const ALLOWED_ROLES = ['ROLE_CLINIC', 'ROLE_DOCTOR', 'ROLE_SECRETARY', 'ROLE_ADMIN'];
|
||||
|
||||
public function __construct(
|
||||
private readonly PaymentMethodService $service,
|
||||
private readonly PaymentMethodService $service,
|
||||
private readonly SecretaryAccessChecker $secretaryAccess,
|
||||
) {}
|
||||
|
||||
/** نقش مجاز + مجوز منشی روی منبع payments (روشهای پرداخت زیرمجموعهٔ مالی است). */
|
||||
private function guard(User $user, string $action): void
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->secretaryAccess->denyUnlessGranted($user, 'payments', $action);
|
||||
}
|
||||
|
||||
// ---- Bank accounts -----------------------------------------------------
|
||||
|
||||
#[Route('/bank-accounts', methods: ['GET'])]
|
||||
public function listBankAccounts(#[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'view');
|
||||
|
||||
return $this->success($this->service->listBankAccounts($user));
|
||||
}
|
||||
@@ -41,7 +50,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/bank-accounts', methods: ['POST'])]
|
||||
public function createBankAccount(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'create');
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
|
||||
return $this->success($this->service->createBankAccount($user, $data), 201);
|
||||
@@ -50,7 +59,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/bank-accounts/{uuid}', methods: ['PUT'])]
|
||||
public function updateBankAccount(string $uuid, Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'update');
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
|
||||
return $this->success($this->service->updateBankAccount($user, $uuid, $data));
|
||||
@@ -59,7 +68,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/bank-accounts/{uuid}/status', methods: ['PATCH'])]
|
||||
public function toggleBankAccountStatus(string $uuid, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'update');
|
||||
|
||||
return $this->success($this->service->toggleBankAccountStatus($user, $uuid));
|
||||
}
|
||||
@@ -69,7 +78,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/pos', methods: ['GET'])]
|
||||
public function listPos(#[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'view');
|
||||
|
||||
return $this->success($this->service->listPos($user));
|
||||
}
|
||||
@@ -77,7 +86,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/pos', methods: ['POST'])]
|
||||
public function createPos(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'create');
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
|
||||
return $this->success($this->service->createPos($user, $data), 201);
|
||||
@@ -86,7 +95,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/pos/{uuid}', methods: ['PUT'])]
|
||||
public function updatePos(string $uuid, Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'update');
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
|
||||
return $this->success($this->service->updatePos($user, $uuid, $data));
|
||||
@@ -95,7 +104,7 @@ class PaymentMethodController extends BaseController
|
||||
#[Route('/pos/{uuid}/status', methods: ['PATCH'])]
|
||||
public function togglePosStatus(string $uuid, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$this->assertRole($user);
|
||||
$this->guard($user, 'update');
|
||||
|
||||
return $this->success($this->service->togglePosStatus($user, $uuid));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user