bp/app/Filters/RoleFilter.php

101 lines
3.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Filters;
use App\Services\AccessService;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
/**
* RoleFilter - Фильтр проверки ролей и прав доступа
*
* Применяется к маршрутам для проверки прав доступа на уровне роутинга.
*
* Использование в роутах:
* $routes->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();
// Проверка авторизации в организации
if (!$access->isAuthenticated()) {
// Если пользователь не авторизован в организации - редирект на выбор организации
return redirect()->to('/organizations');
}
// Разбор аргументов
// Формат: 'role:admin,manager' или 'permission:manage_users:users'
if (is_string($arguments) && str_starts_with($arguments, 'role:')) {
$roles = explode(',', substr($arguments, 5));
$roles = array_map('trim', $roles);
if (!$access->isRole($roles)) {
return $this->forbiddenResponse();
}
}
if (is_string($arguments) && str_starts_with($arguments, 'permission:')) {
$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('/');
}
}