bp/docs/ACCESS.md

10 KiB
Raw Blame History

Справка по методам проверки прав доступа

AccessService — доступ через сервис

AccessService подключается автоматически в BaseController как $this->access.

// В контроллере:
if (!$this->access->can('create', 'clients')) {
    return $this->forbiddenResponse('Нет прав для создания клиентов');
}

Методы проверки ролей

Проверка конкретной роли

// Одной роли
$this->access->isRole('owner');

// Нескольких ролей
$this->access->isRole(['owner', 'admin']);

Удобные методы для часто используемых проверок

// Владелец организации
$this->access->isOwner();

// Администратор или владелец
$this->access->isAdmin();

// Менеджер, администратор или владелец
$this->access->isManagerOrHigher();

Системные роли (суперадмин)

// Суперадмин (доступ к панели суперадмина)
$this->access->isSuperadmin();

// Системный админ или суперадмин
$this->access->isSystemAdmin();

// Проверка произвольной системной роли
$this->access->isSystemRole('admin');

Методы проверки прав на действия

Универсальный метод can()

// Проверка конкретного действия над ресурсом
$this->access->can('view', 'clients');     // Просмотр клиентов
$this->access->can('create', 'clients');   // Создание клиентов
$this->access->can('edit', 'clients');     // Редактирование клиентов
$this->access->can('delete', 'clients');   // Удаление своих клиентов
$this->access->can('delete_any', 'clients'); // Удаление любых клиентов

Краткие методы для действий

$this->access->canView('clients');    // Эквивалент can('view', 'clients')
$this->access->canCreate('clients');  // Эквивалент can('create', 'clients')
$this->access->canEdit('clients');    // Эквивалент can('edit', 'clients')
$this->access->canDelete('clients');  // Эквивалент can('delete', 'clients')
$this->access->canDelete('clients', true); // Эквивалент can('delete_any', 'clients')

Права на специальные операции

// Управление пользователями организации
$this->access->canManageUsers();

// Управление модулями (подписки)
$this->access->canManageModules();

// Просмотр финансовой информации
$this->access->canViewFinance();

// Удаление организации
$this->access->canDeleteOrganization();

// Передача прав владельца
$this->access->canTransferOwnership();

Доступные ресурсы и действия

Стандартные ресурсы модулей

Ресурс Описание Доступные действия
clients Клиенты CRM view, create, edit, delete, delete_any
deals Сделки CRM view, create, edit, delete, delete_any
bookings Записи на приём view, create, edit, delete, delete_any
projects Проекты Proof view, create, edit, delete, delete_any
tasks Задачи view, create, edit, delete, delete_any
users Пользователи view, create, edit, delete

Матрица прав по ролям

Ресурс Владелец Администратор Менеджер Гость
Клиенты Полный Полный Полный Просмотр
Сделки Полный Полный Полный Просмотр
Записи Полный Полный Полный Просмотр
Проекты Полный Полный Полный Просмотр
Задачи Полный Полный Полный Просмотр
Пользователи Полный Просмотр, создание, редактирование Только просмотр Просмотр
Модули Полный Управление
Финансы Полный Просмотр

Использование в Twig-шаблонах

Хелпер access автоматически доступен в шаблонах через TwigGlobalsExtension.

Проверка ролей

{# Проверка роли пользователя #}
{% if access.isRole('owner') %}
    <p>Вы владелец организации</p>
{% endif %}

{% if access.isRole(['owner', 'admin']) %}
    <p>Вы администратор или владелец</p>
{% endif %}

{# Удобные проверки #}
{% if access.isOwner() %}
    Кнопка "Удалить организацию"
{% endif %}

{% if access.isAdmin() %}
    Кнопка "Управление пользователями"
{% endif %}

Проверка действий

{# Кнопка создания (видима только если есть право create) #}
{% if access.canCreate('clients') %}
    <a href="{{ url('/clients/new') }}" class="btn btn-primary">
        Добавить клиента
    </a>
{% endif %}

{# Кнопка редактирования #}
{% if access.canEdit('clients') %}
    <a href="{{ url('/clients/edit/' ~ client.id) }}">Редактировать</a>
{% endif %}

{# Кнопка удаления #}
{% if access.canDelete('clients') %}
    <a href="{{ url('/clients/delete/' ~ client.id) }}">Удалить</a>
{% endif %}

Проверка специальных прав

{# Управление пользователями #}
{% if access.canManageUsers() %}
    <a href="{{ url('/organizations/' ~ currentOrg.id ~ '/users') }}">
        Управление пользователями
    </a>
{% endif %}

{# Управление модулями #}
{% if access.canManageModules() %}
    <a href="{{ url('/modules') }}">Управление подписками</a>
{% endif %}

{# Удаление организации (только владелец) #}
{% if access.canDeleteOrganization() %}
    <button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteOrgModal">
        Удалить организацию
    </button>
{% endif %}

Примеры использования в контроллерах

Базовый шаблон проверки

public function index()
{
    // Проверка права на просмотр
    if (!$this->access->canView('clients')) {
        return $this->forbiddenResponse('Нет прав для просмотра клиентов');
    }

    // ... логика метода
}

Проверка нескольких условий

public function delete($id)
{
    // Право на удаление
    if (!$this->access->canDelete('clients')) {
        return $this->forbiddenResponse('Нет прав для удаления');
    }

    // Дополнительная проверка: только владелец может удалять
    if (!$this->access->isOwner()) {
        return $this->forbiddenResponse('Только владелец может удалять');
    }

    // ... логика удаления
}

Условное выполнение в зависимости от роли

public function update($id, $data)
{
    // Менеджер может только редактировать свои записи
    // Админ и владелец — любые записи
    $canEdit = $this->access->isRole('manager')
        ? $this->isOwnerOfRecord($id)  // своя запись?
        : true;                         // любую запись

    if (!$canEdit) {
        return $this->forbiddenResponse('Можно редактировать только свои записи');
    }

    // ... обновление
}

Важные примечания

  1. Методы возвращают boolean — используйте в условиях if

  2. Проверка всегда идёт для текущей организации из сессии (active_org_id)

  3. Для личного пространства (type = 'personal') метод canManageUsers() возвращает false — в личном пространстве нет других пользователей

  4. Системные роли (system_role) проверяются отдельно от ролей организации:

    • isRole() и isOwner(), isAdmin() — для организации
    • isSuperadmin(), isSystemAdmin() — для всей системы
  5. КэшированиеAccessService кэширует membership в рамках одного запроса, но не между запросами. При переключении организации кэш сбрасывается автоматически.


Получение текстового названия роли

// В контроллере
$roleLabel = $this->access->getRoleLabel('admin');  // "Администратор"

// В шаблоне
{{ access.getRoleLabel(currentMembership.role) }}

Список всех ролей

// Получение всех ролей с описаниями
$roles = \App\Services\AccessService::getAllRoles();
// [
//     'owner' => ['label' => 'Владелец', 'description' => 'Полный доступ', 'level' => 100],
//     'admin' => ['label' => 'Администратор', 'description' => 'Управление пользователями', 'level' => 75],
//     ...
// ]