10

Potrzebuję określić, jakie uprawnienia są obecnie przyznawane dla niektórych zmaterializowanych widoków w mojej bazie danych.Lista przydziałów i uprawnień dla zmaterializowanego widoku w PostgreSQL

Zapytanie to zrobić dla tabeli lub widoku standardowym jest dość prosta:

SELECT grantee, string_agg(privilege_type, ', ') AS privileges 
FROM information_schema.table_privileges 
WHERE table_schema = 'some_schema' AND table_name = 'some_table' 
GROUP by grantee; 

To powiedziawszy, nie wydaje się być analogiczna tabela dla zmaterializowanych widoków. Gdzie PostgreSQL przechowuje te informacje?

+0

Twoje zapytanie działa dla zwykłych widoków, ale nie dla zmaterializowanych widoków. –

Odpowiedz

4

W Postgresie system catalogs to podstawowy zestaw kompletnych informacji o instalacji i bazach danych. Katalogi systemowe są najbardziej wiarygodnym źródłem informacji. Information schema jako funkcji pomocniczej jest na podstawie katalogów systemowych i jest udostępniona dla zgodności z innymi RDBMS:

Schemat informacje są zdefiniowane w standardzie SQL, a zatem można oczekiwać, aby być przenośne i pozostają stabilne - w odróżnieniu od systemu katalogi, które są specyficzne dla PostgreSQL i są wzorowane na problemach implementacji. Widoki schematów informacji nie zawierają jednak informacji o funkcjach specyficznych dla PostgreSQL; zapytać o te, których potrzebujesz, aby zapytać o katalogi systemowe lub inne widoki specyficzne dla PostgreSQL.

Materializowane widoki nie są obiektami standardowymi SQL, dlatego schemat informacji nie zawiera informacji na ich temat.

Katalog systemowy pg_class zawiera wszystkie informacje na temat uprawnień w kolumnie relacl.

Jeśli kolumna jest null, wówczas właściciel ma wszystkie uprawnienia.

Pusty ciąg znaków jako nazwa użytkownika w acl ciąg oznacza public.

create materialized view test_view as select 1; 
grant select on test_view to public; 
grant delete on test_view to a_user; 

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    s[2] as privileges 
from 
    pg_class c 
    join pg_namespace n on n.oid = relnamespace 
    join pg_roles r on r.oid = relowner, 
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s 
where nspname = 'public' and relname = 'test_view'; 

grantee | privileges 
----------+------------ 
postgres | arwdDxt 
public | r 
a_user | d 
(3 rows) 

Trzeba funkcję pokazać przywileje w czytelnej formacie:

create or replace function priviliges_from_acl(text) 
returns text language sql as $$ 
    select string_agg(privilege, ', ') 
    from (
     select 
      case ch 
       when 'r' then 'SELECT' 
       when 'w' then 'UPDATE' 
       when 'a' then 'INSERT' 
       when 'd' then 'DELETE' 
       when 'D' then 'TRUNCATE' 
       when 'x' then 'REFERENCES' 
       when 't' then 'TRIGGER' 
      end privilege 
     from 
      regexp_split_to_table($1, '') ch 
    ) s 
$$; 

Zastosowanie:

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    priviliges_from_acl(s[2]) as privileges 
from 
    pg_class c 
    join pg_namespace n on n.oid = relnamespace 
    join pg_roles r on r.oid = relowner, 
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s 
where nspname = 'public' and relname = 'test_view'; 

grantee |       privileges       
----------+--------------------------------------------------------------- 
postgres | INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER 
public | SELECT 
a_user | DELETE 
(3 rows) 
+0

Dziękuję bardzo, to pomogło mi niezmiernie. Uważam, że bardzo interesujące jest to, że PostgreSQL pozwala nadawać uprawnienia, takie jak UPDATE, INSERT i DELETE w zmaterializowanym widoku. Czy to tylko dlatego, że planują wspierać te operacje w przyszłości? –

+1

To jest raczej funkcja systemu uprawnień PostgreSQL. Zasadniczo można przyznać przywilej na obiekcie, nawet jeśli nie ma on zastosowania. – klin

+0

* "Katalogi systemowe są najbardziej wiarygodnym źródłem informacji." * Gdzie widoki danych w PostgreSQL-u zwracają niewiarygodne informacje? –

1

za pomocną odpowiedź Klin jest, mam wymyślić zdania, że zawiera podsumowanie wszystkich przywilejów dla wszystkich relacji, które pojawiają się w pg_class (tabele, widoki, m. widoki, indeksy, sekwencje, tabele obce, typy złożone) dla r wszystkie role:

CREATE VIEW show_privileges AS (
    SELECT 
     grantee, 
     string_agg(relname, ', ' ORDER BY relname) AS rel_names, 
     privileges 
    FROM (
     SELECT 
      relname, 
      coalesce(nullif(s[1], ''), 'public') grantee, 
      (SELECT string_agg(privilege, ', ' ORDER BY privilege ASC) 
       FROM (SELECT 
        CASE ch 
         WHEN 'r' THEN 'SELECT' 
         WHEN 'w' THEN 'UPDATE' 
         WHEN 'a' THEN 'INSERT' 
         WHEN 'd' THEN 'DELETE' 
         WHEN 'D' THEN 'TRUNCATE' 
         WHEN 'x' THEN 'REFERENCES' 
         WHEN 't' THEN 'TRIGGER' 
        END AS privilege 
        FROM regexp_split_to_table(s[2], '') ch 
       ) s 
      ) AS privileges 
     FROM 
      pg_class 
      JOIN pg_namespace ON pg_namespace.oid = relnamespace 
      JOIN pg_roles ON pg_roles.oid = relowner, 
      unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) AS acl, 
      regexp_split_to_array(acl, '=|/') AS s 
     WHERE nspname = 'public' 
    ) AS t 
    GROUP BY grantee, privileges 
    ORDER BY grantee, privileges, rel_names 
); 
Powiązane problemy