Ответ 1
Я уже нашел это:
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name='mytable'
Как я могу запросить все GRANTS, предоставленные объекту в postgres?
Например, у меня есть таблица "mytable":
GRANT SELECT, INSERT ON mytable TO user1
GRANT UPDATE ON mytable TO user2
Мне нужно что-то, что дает мне:
user1: SELECT, INSERT
user2: UPDATE
Я уже нашел это:
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name='mytable'
\z mytable
из psql дает вам все гранты из таблицы, но вам придется разделить его на отдельного пользователя.
Если вам действительно нужна одна строка для каждого пользователя, вы можете группировать ее по грантополучателю (требуется PG9 + для string_agg)
SELECT grantee, string_agg(privilege_type, ', ') AS privileges
FROM information_schema.role_table_grants
WHERE table_name='mytable'
GROUP BY grantee;
Это должно вывести что-то вроде:
grantee | privileges
---------+----------------
user1 | INSERT, SELECT
user2 | UPDATE
(2 rows)
Попробуйте выполнить запрос ниже. Он предоставит вам список всех пользователей и их разрешения в таблице.
select a.tablename,b.usename,HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert,
HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update,
HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete,
HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references from pg_tables a , pg_user b
where a.tablename='your_table_name';
В этом запросе будут перечислены все таблицы во всех базах данных и схемах (раскомментируйте строки в WHERE
для фильтрации по конкретным базам данных, схемам или таблицам) с привилегиями, показанными по порядку, чтобы его было легко увидеть если конкретная привилегия предоставлена или нет:
SELECT grantee
,table_catalog
,table_schema
,table_name
,string_agg(privilege_type, ', ' ORDER BY privilege_type) AS privileges
FROM information_schema.role_table_grants
WHERE grantee != 'postgres'
-- and table_catalog = 'somedatabase' /* uncomment line to filter database */
-- and table_schema = 'someschema' /* uncomment line to filter schema */
-- and table_name = 'sometable' /* uncomment line to filter table */
GROUP BY 1, 2, 3, 4;
Образец вывода:
grantee |table_catalog |table_schema |table_name |privileges |
--------|----------------|--------------|---------------|---------------|
PUBLIC |adventure_works |pg_catalog |pg_sequence |SELECT |
PUBLIC |adventure_works |pg_catalog |pg_sequences |SELECT |
PUBLIC |adventure_works |pg_catalog |pg_settings |SELECT, UPDATE |
...
Вот script, который генерирует запросы на грант для конкретной таблицы. Он пропускает права владельца.
SELECT
format (
'GRANT %s ON TABLE %I.%I TO %I%s;',
string_agg(tg.privilege_type, ', '),
tg.table_schema,
tg.table_name,
tg.grantee,
CASE
WHEN tg.is_grantable = 'YES'
THEN ' WITH GRANT OPTION'
ELSE ''
END
)
FROM information_schema.role_table_grants tg
JOIN pg_tables t ON t.schemaname = tg.table_schema AND t.tablename = tg.table_name
WHERE
tg.table_schema = 'myschema' AND
tg.table_name='mytable' AND
t.tableowner <> tg.grantee
GROUP BY tg.table_schema, tg.table_name, tg.grantee, tg.is_grantable;
Добавление к ответу @shruti
Для запроса грантов для всех таблиц в схеме для данного пользователя
select a.tablename,
b.usename,
HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert,
HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update,
HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete,
HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references
from pg_tables a,
pg_user b
where schemaname='your_schema_name'
and b.usename='your_user_name'
order by tablename;