Postgresql забывает гранты после воссоздания таблиц

Мы используем Liquibase для управления и выполнения изменений в нашей базе данных. В нашей среде DEV (и особенно на локальных машинах) мы часто воссоздаем таблицы, чтобы получить чистый лист. Мы только что перешли с MySQL на Postgres и столкнулись с проблемой, связанной с воссозданием этих таблиц.

Изначально мы предоставили нашему пользователю БД следующее:

GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO mydbuser;
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO mydbuser;

Это выполняется через psql после подключения к нашей собственной БД (где public - это схема по умолчанию / только).

Все в порядке, пока мы не попросим Liquibase воссоздать таблицы, и в этом случае он отбросит все таблицы и создаст их снова.

После этого выясняется, что mydbuser потерял все свои права доступа к таблицам.

Согласно нескольким ресурсам (например, this) нам необходимо изменить привилегии по умолчанию, поэтому мы подчиняемся:

GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO mydbuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO mydbuser;

GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO mydbuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, USAGE ON SEQUENCES TO mydbuser;

Однако, хотя это кажется очень логичным, ничего не изменилось. Все гранты (даже избранные) по-прежнему теряются после воссоздания таблиц.

Что мы делаем не так или что нам еще нужно делать?

ОБНОВЛЕНИЕ

\ ddp показывает: Права доступа по умолчанию

Владелец | Схема | Тип | Права доступа
---------- + -------- + ---------- + -------------- ------
postgres | общественный | последовательность | mydb = rU / postgres
postgres | общественный | стол | mydb = arwd / postgres


person Stijn Geukens    schedule 14.09.2013    source источник
comment
+1. У меня тоже никогда не получалось, чтобы это работало. Я всегда предполагал, что это ошибка, которую со временем исправят. Судя по всему, нет, или тогда об этом еще не сообщалось.   -  person Denis de Bernardy    schedule 14.09.2013
comment
В том, что показано, нет ничего плохого, но слишком многого не хватает. Кто владелец объектов? Этот же пользователь выдает ALTER DEFAULT PRIVILEGES...? Что происходит между этой командой и воссозданием объектов? Что сообщает \dddp в psql перед воссозданием таблиц?   -  person Daniel Vérité    schedule 15.09.2013
comment
@Daniel: пользователь postgres по умолчанию является владельцем, \ dddp (описания объектов) не возвращает результатов (0 строк).   -  person Stijn Geukens    schedule 15.09.2013
comment
... и пользователь postgres выполняет все вышеперечисленные команды.   -  person Stijn Geukens    schedule 15.09.2013
comment
извините, я имел в виду \ddp (настройки прав доступа по умолчанию)   -  person Daniel Vérité    schedule 15.09.2013
comment
\ ddp вернул результаты, см. обновление   -  person Stijn Geukens    schedule 15.09.2013


Ответы (1)


Если вы пытаетесь имитировать то, что делает Liquibase в упрощенном тестовом примере, это просто работает.

Быстрая демонстрация с 9.3:

1) Создайте объекты с нуля с пользователем postgres:

postgres=# create database dbtest;
CREATE DATABASE

postgres=# create user mydbuser;
CREATE ROLE

postgres=# \c dbtest
You are now connected to database "dbtest" as user "postgres".

dbtest=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO mydbuser;
ALTER DEFAULT PRIVILEGES

dbtest=# create table foobar(id int);
CREATE TABLE

2) В другом сеансе давайте подключимся к mydbuser и посмотрим, разрешен ли SELECT.

dbtest=> select * from foobar;
 id 
----
(0 rows)

Результат: Да, можно. Также обратите внимание на результат \ddp:

dbtest=> \ddp
             Default access privileges
  Owner   | Schema | Type  |   Access privileges    
----------+--------+-------+------------------------
 postgres | public | table | mydbuser=arwd/postgres
(1 row)

3) Давайте postgres отбросим таблицу и создадим ее заново:

dbtest=# drop table foobar;
DROP TABLE
dbtest=# create table foobar(id int);
CREATE TABLE

4) Посмотрите, может ли mydbuser по-прежнему ВЫБРАТЬ из него.

$ psql -d dbtest -U mydbuser
dbtest=> select * from foobar;
 id 
----
(0 rows)

Результат: Да, как и ожидалось.

5) Посмотрите, может ли другой пользователь ВЫБРАТЬ из него.

$ psql -d dbtest -U daniel
dbtest=> select * from foobar;
ERROR:  permission denied for relation foobar

Результат: Нет, как и ожидалось.

Это не объясняет, что у вас не работает, но вы можете сравнить вышеприведенное с набором команд, выдаваемых Liquibase.

person Daniel Vérité    schedule 15.09.2013
comment
Большое спасибо, попробую проделать то же упражнение. - person Stijn Geukens; 15.09.2013
comment
Вышеупомянутое тоже отлично работает для меня, и я думаю, что нашел причину проблемы. Таблицы на самом деле создаются не пользователем postgres, а другим суперпользователем (jenkins). Если я выберу любую таблицу, созданную этим пользователем, мне будет отказано в разрешении; он отлично работает для таблиц, созданных пользователем postgres. Однако еще не знаю, какое решение. Пользователь jenkins предоставляет права? - person Stijn Geukens; 16.09.2013
comment
@stijn: если Дженкинс выдаст ALTER DEFAULT PRIVILEGES..., должно работать. Я думаю, что суть в этом предложении в документе: Вы можете изменить привилегии по умолчанию только для объектов, которые будут созданы вами или ролями, членом которых вы являетесь - person Daniel Vérité; 16.09.2013
comment
Похоже, это сработало; Не уверен, однако, что это правильный путь, он не кажется очень чистым, но мы можем с этим жить. - person Stijn Geukens; 18.09.2013