Ошибка #3009 Forbidden возникает, если у пользователя недостаточно прав на выполнение какой-либо операции. Иногда эта ошибка может появляться у пользователя с правами администратора. Статья содержит порядок диагностики проблемы и её решение.
Описание
При выполнении какого-либо действия в платформе в интерфейсе отображается Ошибка #3009 Forbidden и операция не выполняется. При этом у администратора достаточно прав на выполнение операции.
Указанное поведение возможно у администраторов, созданных до версии 2023.06.1. Причина ошибки — в рассинхронизации таблиц БД auth_user и auth_user_role. В таблице auth_user для администратора назначена роль @user, а в таблице auth_user_role — роль @admin. В результате при проверке глобальной роли из таблицы auth_user администратор получает отказ в выполнении операции.
Для решения проблемы измените роль администратора в таблице auth_user.
Решение
Вмешательство в базу данных предполагает потенциальный риск. Мы не рекомендуем вносить ручные правки в базу, поскольку это может нарушить корректную работу платформы.
Перед внесением изменений в БД создайте резервную копию платформы.
Чтобы решить проблему:
- Подключитесь к серверу с платформой по SSH.
-
Подключитесь к СУБД.
В связи с поэтапным переходом платформы на использование СУБД PostgreSQL, разные экземпляры VMmanager могут использовать разные СУБД:
- VMmanager Hosting — MySQL;
- VMmanager Infrastructure:
- для новых установок на ОС Astra Linux, начиная с версии VMmanager 2023.06.1 — PostgreSQL;
- в остальных случаях — MySQL.
Чтобы определить тип СУБД, выполните на сервере с платформой команду:
docker ps --filter name=pgsql
Пример ответаCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3213c5dc94d0 postgres:12 "docker-entrypoint.s…" 5 days ago Up 4 days 5432/tcp pgsql
Если вывод команды содержит информацию о контейнере, платформа использует PostgreSQL, если ответ пустой — MySQL.
MySQLdocker exec -it mysql bash -c "mysql isp -p\$MYSQL_ROOT_PASSWORD"
PostgreSQLdocker exec -it pgsql bash -c "psql -d isp"
-
Получите все записи с рассинхронизированным параметром roles:
SELECT au.id,au.email,au.roles,aur.roles FROM auth_user AS au JOIN auth_user_role AS aur ON au.id = aur.user WHERE au.roles != aur.roles;
Пример вывода+-----+--------------------------+-----------+------------+ | id | email | roles | roles | +-----+--------------------------+-----------+------------+ | 23 | bill@test.tk | ["@user"] | ["@admin"] | | 237 | t.test@domain.com | ["@user"] | ["@admin"] | +-----+--------------------------+-----------+------------+
-
Синхронизируйте записи:
UPDATE auth_user AS au JOIN auth_user_role AS aur ON au.id = aur.user SET au.roles = aur.roles WHERE au.roles != aur.roles;
Пример выводаQuery OK, 2 rows affected (0.01 sec) Rows matched: 2 Changed: 2 Warnings: 0
-
Убедитесь, что роли синхронизированы. Для этого повторно выполните запрос:
SELECT au.id,au.email,au.roles,aur.roles FROM auth_user AS au JOIN auth_user_role AS aur ON au.id = aur.user WHERE au.roles != aur.roles;
Вывод должен быть пустым.