DEV Community

Andrzej Klusiewicz
Andrzej Klusiewicz

Posted on

Role grupowe w PostgreSQL - zbiorcze zarzadzanie uprawnieniami krok po kroku

Nadawanie uprawnien kazdemu userowi z osobna szybko robi sie niezarzadzalne - role grupowe w PostgreSQL rozwiazuja ten problem. Pokazujemy praktyczny model.

Z tego artykułu dowiesz się:

  • czym są role grupowe i do czego służą,- jak sprawdzać kto jest przypisany do jakiej roli grupowej,- jak dodawać użytkownika do roli grupowej,- jak usuwać użytkownika z roli grupowej,- jak zbiorowo nadawać i odbierać uprawnienia wielu użytkownikom za pomocą ról grupowych,- jak kasować role grupowe.

Tworzenie ról grupowych, przydzielanie uprawnień i nadawanie ról grupowych użytkownikom

Role grupowe służą do zbiorowego nadawania i odbierania uprawnień. Jeśli masz grupę użytkowników, którzy powinni mieć podobne uprawnienia, zamiast nadawać im uprawnienia pojedynczo możesz stworzyć rolę grupową i poprzez nią zarządzać ich uprawnieniami. Przejdźmy przez prosty przykład. - Załóżmy, że mamy tabelę i kilku użytkowników, którzy powinni mieć identyczne uprawnienia do tej tabeli. Tworzymy tabelę "role_grupowe" do testowania uprawnień. Tworzymy rolę grupową "programiści". Zwróćmy uwagę, że - rolę grupową stworzyliśmy, korzystając z "create role" a nie "create user"! Rola ta ma nie mieć możliwości logowania, służyć będzie tylko do zarządzania uprawnieniami. Dalej tworzymy dwóch użytkowników - "programista1" i "programista2". Tym razem posługujemy się jednak "create user", ponieważ mają to być role z możliwością logowania (użytkownicy). Nadajemy rolę "programiści" obu użytkownikom. Do roli przypisujemy uprawnienia pozwalające na odczyt i zmianę zawartości tabeli i nadajemy uprawnienie usage na schemacie, w którym znajduje się tabela (public):

create table role_grupowe(x integer);

create role programisci;

create user programista1;

create user programista2;

grant programisci to programista1, programista2;

grant select,update,insert, delete on role_grupowe to programisci;

grant usage on schema public to programisci;
Enter fullscreen mode Exit fullscreen mode

Logujemy się teraz jako - nowo stworzeni - użytkownicy i sprawdzamy uprawnienia:

Tworzenie ról grupowych, przydzielanie uprawnień i nadawanie ról grupowych użytkownikom: PostgreSQL

Nie potrzebujemy tworzyć haseł dla użytkowników ani ich podawać przy logowaniu, bo domyślnie logowanie lokalne w pliku pg_hba.conf jest ustawione na “trust”.

Nadawanie uprawnień poprzez role działa od razu. Nie jest wymagane ponowne nawiązanie sesji przez użytkownika. Sprawdźmy to w praktyce. Tworzymy kolejnego użytkownika:

create user programista3;
Enter fullscreen mode Exit fullscreen mode

Logujemy się na niego do bazy i sprawdzamy, - czy mamy dostęp do tabeli "role_grupowe":

Tworzenie ról grupowych, przydzielanie uprawnień i nadawanie ról grupowych użytkownikom: PostgreSQL (2)

Oczywiście nie mamy do niej uprawnień, więc nadajemy rolę “programisci” temu użytkownikowi z sesji użytkownika postgres:

grant programisci to programista3;
Enter fullscreen mode Exit fullscreen mode

Nie przelogowujemy sesji użytkownika programista3, tylko ponownie sprawdzamy dostęp:

Tworzenie ról grupowych, przydzielanie uprawnień i nadawanie ról grupowych użytkownikom: PostgreSQL (3)

Tym razem udało się, uprawnienie zadziałało natychmiast, bez potrzeby przelogowania.

Możesz też stworzyć użytkownika i za jednym zamachem nadać mu rolę:

create user programista2 with password 'szpyrki!' in role programisci;
Enter fullscreen mode Exit fullscreen mode

Odbieranie ról grupowych użytkownikom

Role grupowe odbieramy w ten sposób:

revoke programisci from programista3;
Enter fullscreen mode Exit fullscreen mode

gdzie "programiści" jest nazwą roli grupowej, a "programista3" nazwą użytkownika. Odbieranie ról, i co za tym idzie wynikających z nich uprawnień, odbywa się natychmiast, podobnie jak ich nadawanie.

Po odebraniu roli programisci, a co za tym idzie również uprawnień z niej wynikających (tutaj dostęp do tabeli “role_grupowe”), użytkownik natychmiast traci uprawnienia, mimo że cały czas trwa jego sesja:

Odbieranie ról grupowych użytkownikom: PostgreSQL

Sprawdzanie przydzielonych ról grupowych

Nie ma - gotowego słownika z listą ról grupowych nadanych użytkownikom, więc aby uzyskać listing wszystkich grup, musimy zrobić mały zabieg w SQL:

select roleid,member,g.rolname grupa,u.rolname uzytkownik

from pg_auth_members m join pg_roles g on m.roleid=g.oid

join pg_roles u on m.member=u.oid;
Enter fullscreen mode Exit fullscreen mode

W wyniku widzimy, że rola “programisci” jest przydzielona użytkownikom “programista1” i “programista2”

Sprawdzanie przydzielonych ról grupowych: PostgreSQL

Usuwanie ról grupowych

Usuwanie ról grupowych mogłoby się sprowadzać do wykonania:

drop role programisci;
Enter fullscreen mode Exit fullscreen mode

gdyby nie to, że nie ;) Taka próba skończyła się w ten sposób:

Usuwanie ról grupowych: PostgreSQL

Błąd wynika z tego, że rola ta ma nadane wcześniej uprawnienia - odczyt i modyfikację tabeli "role_grupowe", oraz uprawnienie “USAGE” na schemacie “pubic”. - Abyśmy mogli usunąć rolę grupową, trzeba będzie najpierw sprawdzić, jakie uprawnienia zostały do tej roli nadane i je odebrać. Zaczniemy od uprawnień do tabeli “role_grupowe”. Sprawdźmy więc uprawnienia:

select * from information_schema.role_table_grants where grantee='programisci';
Enter fullscreen mode Exit fullscreen mode

Usuwanie ról grupowych: PostgreSQL (2)

Jak widać, rola ta ma przypisane uprawnienia do INSERT, SELECT, UPDATE i DELETE w tabeli "role_grupowe". Możemy je teraz odebrać:

revoke select,insert,delete,update on role_grupowe from programisci;
Enter fullscreen mode Exit fullscreen mode

Nadal nie możemy jeszcze skasować roli:

drop role programisci;
Enter fullscreen mode Exit fullscreen mode

Wynika to z uprawnień do schematu “public” nadanych tej roli:

Usuwanie ról grupowych: PostgreSQL (3)

Sprawdźmy więc, jakie uprawnienia ma rola “programisci” do poszczególnych schematów (zwróćmy uwagę na wskazanie roli ‘programisci’ w wywołaniu funkcji has_schema_privilege):

WITH "names"("name") AS (

  SELECT n.nspname AS "name"

    FROM pg_catalog.pg_namespace n

    WHERE n.nspname !~ '^pg_'

        AND n.nspname <> 'information_schema'

) SELECT "name",

  pg_catalog.has_schema_privilege('programisci', "name", 'CREATE') AS "create",

  pg_catalog.has_schema_privilege('programisci', "name", 'USAGE') - AS "usage",

  "name" = pg_catalog.current_schema() AS "current"

    FROM "names";
Enter fullscreen mode Exit fullscreen mode

W wyniku widzimy, - że rola “programisci” ma uprawnienie “USAGE” na schemacie public:

Usuwanie ról grupowych: PostgreSQL (4)

Odbieramy więc to uprawnienie z roli “programisci”:

revoke usage on schema public from programisci;
Enter fullscreen mode Exit fullscreen mode

Teraz możemy spróbować ponownie skasować rolę:

drop role programisci;
Enter fullscreen mode Exit fullscreen mode

Usuwanie ról grupowych: PostgreSQL (5)

Top comments (0)