get('/admin/users', 'Users::index', ['filter' => 'role:admin']); * $routes->get('/admin/settings', 'Settings::index', ['filter' => 'role:owner']); */ class RoleFilter implements FilterInterface { /** * Проверка доступа перед выполнением запроса * * @param RequestInterface $request * @param array|null $arguments Аргументы из маршрута (роли, разрешения) * @return ResponseInterface|null */ public function before(RequestInterface $request, $arguments = null) { // Если фильтр вызван без аргументов - пропускаем if ($arguments === null) { return null; } $access = AccessService::getInstance(); // Разбор аргументов // Формат: 'role:admin,manager' или 'role:system:superadmin' или 'permission:manage_users:users' // Проверка системных ролей (system: prefix) if (is_string($arguments) && str_starts_with($arguments, 'role:system:')) { $roles = explode(',', substr($arguments, 13)); // 13 = длина 'role:system:' $roles = array_map('trim', $roles); // Для системных ролей НЕ требуется авторизация в организации if (!$access->isSystemRole($roles)) { return $this->forbiddenResponse(); } return null; } // Проверка организационных ролей if (is_string($arguments) && str_starts_with($arguments, 'role:')) { $roles = explode(',', substr($arguments, 5)); $roles = array_map('trim', $roles); // Проверка авторизации в организации if (!$access->isAuthenticated()) { // Если пользователь не авторизован в организации - редирект на выбор организации return redirect()->to('/organizations'); } if (!$access->isRole($roles)) { return $this->forbiddenResponse(); } } if (is_string($arguments) && str_starts_with($arguments, 'permission:')) { // Проверка авторизации в организации для разрешений if (!$access->isAuthenticated()) { return redirect()->to('/organizations'); } $parts = explode(':', substr($arguments, 11)); if (count($parts) >= 2) { $permission = $parts[0]; $resource = $parts[1] ?? '*'; if (!$access->can($permission, $resource)) { return $this->forbiddenResponse(); } } } return null; } /** * Обработка после выполнения запроса * * @param RequestInterface $request * @param ResponseInterface $response * @param array|null $arguments * @return void */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { // Ничего не делаем после } /** * Возврат ответа "Доступ запрещён" * * @return ResponseInterface */ private function forbiddenResponse(): ResponseInterface { // Проверяем, AJAX ли это запрос if (service('request')->isAJAX()) { return service('response') ->setStatusCode(403) ->setJSON(['error' => 'Доступ запрещён']); } // Для обычных запросов - редирект с сообщением session()->setFlashdata('error', 'У вас нет прав для выполнения этого действия'); return redirect()->to('/'); } }