Управление командой¶
Раздел описывает работу с пользователями трекера TrafMate: учётные записи, роли, разграничение доступа (ACL), API-ключи и восстановление пароля.
Пользователи¶
Управление пользователями доступно в разделе «Пользователи». Раздел виден только
администраторам - и в интерфейсе, и в API: обращение не-админа к
/api/v1/users отклоняется с кодом 403.
Каждая учётная запись содержит поля:
| Поле | Описание |
|---|---|
| Логин | Уникальное имя для входа |
| Роль | admin или user |
| Статус | active (активна) или любое другое значение (вход закрыт) |
| Пароль | Задаётся при создании; хранится в виде bcrypt-хеша |
Войти может только учётная запись со статусом active. Пароль никогда не
хранится и не отображается в открытом виде - в базе данных сохраняется только его
bcrypt-хеш. Принимаются оба формата хеша ($2a$ и $2y$), поэтому пользователи,
перенесённые из Keitaro, входят со своими прежними паролями.
Защищённые учётные записи¶
Отдельные учётные записи помечаются флагом protected. Такую запись нельзя:
- удалить;
- деактивировать (увести статус из
active); - лишить роли
admin.
Ограничение действует не только в интерфейсе, но и на уровне базы данных - через
триггеры на DELETE, UPDATE и TRUNCATE. Это означает, что защищённую запись
невозможно испортить даже прямым SQL-запросом в обход панели. Механизм защищает
основной аккаунт владельца от случайной или ошибочной блокировки.
Аварийный выход предусмотрен и он один: сначала снять сам флаг
(UPDATE users SET protected=false), и только потом удалять или менять запись.
Роли¶
В трекере две роли:
- admin - полный доступ ко всем разделам, сущностям и настройкам без ограничений. Проверки прав администратор проходит всегда.
- user (баер) - ограниченный доступ, определяемый настройками ACL.
Разграничение доступа (ACL)¶
Доступ баера ограничивают два независимых слоя. Чтобы баер увидел сущность, должны сработать оба: ему нужен и раздел, и группа, к которой сущность относится.
Слой 1. Доступ к разделам¶
Набор разделов пользователя определяет, какие пункты меню и какие адреса API ему доступны. Полный список разделов:
dashboard, campaigns, streams, offers, landings, domains,
traffic_sources, affiliate_networks, geo_profiles, groups, reports,
trends, clicks, conversions.
Если раздел не выдан, обращение к его адресам возвращает 403 с текстом «нет доступа к разделу».
Пустой набор разделов означает «не настроено» и даёт доступ ко всем разделам. Это сделано намеренно: у пользователя, созданного без настройки прав, иначе было бы пустое меню. Чтобы ограничить баера, нужно выдать ему непустое подмножество разделов - снятые галочки при пустом наборе ничего не ограничивают.
Слой 2. Изоляция по группам¶
Группы пользователя (раздел «Пользователи» -> карточка -> «Группы») определяют, какие конкретные сущности он видит. Правило зависит от типа сущности, и это не оплошность, а два разных сценария:
| Сущность | Что видит баер |
|---|---|
| Кампании, потоки | Строго свои группы. Кампания без группы баеру не видна вовсе |
| Офферы, лендинги, домены, источники трафика | Свои группы и общие (записи без группы) |
| Партнёрские сети, гео-профили | Группы у сущности нет - доступ решает только раздел |
Общие записи (без группы) видны всем не случайно: источники трафика на реальных установках часто заведены без группы, и без них у баера был бы пустой выпадающий список «Источник трафика». Менять общую запись по-прежнему может только администратор.
У потока собственной группы нет: поток принадлежит кампании и наследует её группу.
Что именно режется по группам¶
Изоляция применяется не только к спискам сущностей:
- Кампании и потоки. Проверка стоит на маршруте, а не внутри обработчика: чтение, изменение, удаление, клонирование, смена состояния, порядок потоков, метки, домены кампании. Чужой id даёт 403 - тот же ответ, что и несуществующий id, чтобы перебором нельзя было выяснить, какие кампании существуют.
- Отчёты. Каждый запрос статистики несёт ограничение по кампаниям групп
пользователя: дашборд, отчёт по кликам, лог конверсий, лог кликов, тренды, лог
постбеков, ручное обновление расхода. Чужие
campaign_idв выдачу не попадают. - Файлы лендингов и офферов. Список файлов, чтение, сохранение, удаление, переименование, загрузка, выгрузка архивом, замена и предпросмотр проходят через одну общую проверку прав. Прочитать или переписать чужую связку по её id нельзя.
- Правила постбеков. Баер работает только с правилами области
campaignи только для своих кампаний. Глобальное правило (scope=global) - админское: такое правило шлёт копию каждой конверсии установки на указанный адрес. - Глобальный поиск. Ищет сразу по семи таблицам и применяет оба слоя: раздел и группу, по правилам того раздела, к которому относится сущность.
Пользователь без групп не видит ничего¶
Это ожидаемое поведение, а не поломка. Отказ по умолчанию означает:
- списки кампаний и потоков пусты;
- отчёты пусты (не «вся установка», а именно ноль строк);
- глобальный поиск не находит ни кампаний, ни потоков.
Если баер жалуется, что «трекер пустой», первое, что нужно проверить, - выданы ли ему группы. Порядок настройки: сначала завести группу, разложить по ней кампании, затем выдать группу пользователю.
Что может и чего не может баер¶
Может (при выданных разделах и группах): вести свои кампании и потоки, заводить офферы и лендинги, править файлы своих лендингов, смотреть отчёты по своим кампаниям, настраивать S2S-постбеки своих кампаний, обновлять расход своих кампаний, создавать себе избранное, пользоваться поиском.
Не может ни при каких настройках ACL:
- управлять пользователями, командами, метками, пользовательскими метриками, белым списком IP, триггерами и интеграциями - это админские сущности;
- открывать глобальные настройки трекера и курсы валют;
- смотреть журнал действий, диагностику системы и обновления;
- работать с обслуживанием (объём статистики, срок хранения, очистка);
- создавать и удалять API-ключи;
- заводить глобальные правила постбеков;
- менять общие (без группы) офферы, лендинги, домены и источники.
Отдельно стоит знать про два ограничения, которых у нас нет: уровня доступа «только чтение» и скрытия отдельных столбцов отчёта. Баер, которому выдан раздел «Отчёты», видит по своим кампаниям все метрики, включая расход, доход и ROI.
Поведение при нарушении¶
Обращение к недоступному разделу, к чужой группе или к административному адресу отклоняется с кодом 403 (Forbidden). Неавторизованный запрос - 401.
Управление доступом пользователя¶
Настройка выполняется в карточке пользователя. Администратор задаёт:
- Разделы - к каким пунктам меню и адресам API есть доступ
(
GET/PUT /api/v1/users/{id}/resources); - Группы - какие группы сущностей видит пользователь
(
GET/PUT /api/v1/users/{id}/groups).
Обе настройки заменяют набор целиком, а не дополняют его. Изменения вступают в силу немедленно и распространяются на все обращения пользователя, включая доступ по его API-ключам.
API-ключи (Admin API)¶
API-ключи создаются в разделе «Настройки» -> карточка «API-ключи». Раздел доступен только администраторам - завести себе ключ баер не может.
Назначение¶
Ключ даёт доступ к REST API трекера. Формат ключа: префикс tm_ и hex-строка
(например, tm_a1b2c3...).
Ключ передаётся в запросе одним из способов:
- заголовок
Api-Key: <ключ>; - заголовок
Authorization: Bearer <ключ>.
Наследование прав (ACL)¶
API-ключ наследует права своего пользователя. Ключ не даёт больше доступа, чем есть у владельца:
- ключ администратора имеет полный доступ;
- ключ баера ограничен теми же разделами и группами, что и его учётная запись в панели.
Показ и хранение¶
Ключ показывается полностью только один раз - в момент создания. Скопируйте и сохраните его сразу. При последующих просмотрах ключ отображается в маскированном виде и восстановить его целиком нельзя. У ключа есть имя и отметка последнего использования - по ней видно, какой ключ давно не работает.
В базе ключ лежит открытым текстом. Практическое следствие: дамп конфигурации
(trafmate backup-config) содержит рабочие ключи, поэтому бэкапы нужно хранить
там же, где хранят пароли.
Отзыв¶
Чтобы отозвать доступ, удалите ключ. После удаления запросы с этим ключом перестают работать немедленно.
Защита от подбора пароля¶
Неудачные попытки входа считаются в двух счётчиках - по адресу обратившегося и по логину. При превышении лимита вход отвечает 429 и текстом «слишком много попыток входа, попробуйте через 15 минут». Успешный вход счётчики сбрасывает.
Требований к сложности пароля трекер не предъявляет: принимается любая непустая строка. Единственное исключение - сброс пароля из CLI, там пароль короче 8 символов не примут. Ответ на неверный вход одинаков для несуществующего логина и неверного пароля («неверный логин или пароль»), поэтому перебрать список логинов по ответу нельзя.
Восстановление пароля¶
Самостоятельного сброса пароля пользователем нет: письма с восстановлением трекер не шлёт. Есть два пути.
Обычный: администратор задаёт новый пароль¶
- Откройте раздел «Пользователи».
- Откройте карточку нужного пользователя.
- Задайте новый пароль и сохраните.
Новый пароль сохраняется в виде bcrypt-хеша и вступает в силу сразу.
Важно знать: ранее выданная сессия пользователя после смены пароля из панели
продолжает жить (до 7 суток). Чтобы гарантированно выбить человека из панели,
уведите его учётную запись из статуса active.
Аварийный: сброс пароля владельца через CLI¶
Если пароль потерял сам владелец и в панель войти некому, пароль сбрасывается на сервере командой:
Как это работает:
- логин можно не указывать - тогда берётся
ADMIN_LOGINиз.env, а если его нет -admin; --passwordможно не указывать - CLI сгенерирует случайный пароль из 20 символов и покажет его один раз;- пароль короче 8 символов команда не примет;
- если такой пользователь есть, ему меняется только пароль и возвращается статус
active. Роль не меняется: повысить баера до администратора сбросом пароля нельзя; - если такого логина нет, создаётся новая учётная запись с ролью
admin; - все прежние сессии этого пользователя гасятся - в отличие от смены пароля из панели.
Команда требует запущенного Postgres. Хеш считается bcrypt-ом: сначала через
контейнер lander, если он не поднят - через расширение pgcrypto в Postgres.