Создание ролей

Создадим роль:

postgres=# CREATE ROLE alice LOGIN CREATEROLE;
CREATE ROLE

В этом модуле приглашение будет показывать имя роли, от которой выполняется команда.


Алиса имеет возможность подключения (атрибут LOGIN) и создания других ролей (CREATEROLE).

Проверим это:

postgres=# \c - alice
You are now connected to database "access_roles" as user "alice".
alice=> CREATE ROLE bob LOGIN;
CREATE ROLE

Действительно, получилось и подключиться, и создать другого пользователя, Боба.


А вот Боб не сможет создать другую роль:

postgres$ psql -U bob -d access_roles
bob=> CREATE ROLE charlie LOGIN;
ERROR:  permission denied to create role

Посмотреть роли, имеющиеся в кластере, можно так:

alice=> \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 alice     | Create role                                                | {}
 bob       |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

Или в системном каталоге:

alice=> SELECT usename FROM pg_user;
 usename  
----------
 postgres
 alice
 bob
(3 rows)


Существующие роли можно изменять. Например, Алиса может отобрать у Боба право входа:

alice=> ALTER ROLE bob NOLOGIN;
ALTER ROLE

А у себя самой Алиса отберет CREATEROLE:

alice=> ALTER ROLE alice NOCREATEROLE;
ALTER ROLE

Такие пары, как LOGIN-NOLOGIN или CREATEROLE-NOCREATEROLE, есть и у других атрибутов.


Теперь Боб не сможет подключиться:

bob=> \c - bob
\connect: FATAL:  role "bob" is not permitted to log in



Групповые роли

А Алиса теперь не может ни создавать новые роли, ни изменять атрибуты существующих:

alice=> ALTER ROLE bob LOGIN;
ERROR:  permission denied

Чтобы снова наделить Алису супервозможностями, включим ее в суперпользовательскую роль postgres:

alice=> \c - postgres
You are now connected to database "access_roles" as user "postgres".
postgres=# GRANT postgres TO alice;
GRANT ROLE
postgres=# \du
                                    List of roles
 Role name |                         Attributes                         | Member of  
-----------+------------------------------------------------------------+------------
 alice     |                                                            | {postgres}
 bob       | Cannot login                                               | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}


А чтобы Алиса не злоупотребляла полномочиями, сделаем так, чтобы все ее команды попадали в журнал сообщений:

postgres=# ALTER ROLE alice SET log_min_duration_statement=0;
ALTER ROLE

Это еще один вариант установки конфигурационных параметров - он срабатывает при подключении пользователя к серверу.

Можно ограничить действие и конкретной базой данных:

postgres=# ALTER ROLE alice RESET log_min_duration_statement;
ALTER ROLE
postgres=# ALTER ROLE alice IN DATABASE postgres SET log_min_duration_statement=0;
ALTER ROLE

Алиса не получает возможности групповой роли автоматически. Она может ими воспользоваться, только если переключится на эту роль:

postgres=# \c - alice
You are now connected to database "access_roles" as user "alice".
alice=> SET ROLE postgres;
SET
alice=> ALTER ROLE bob LOGIN;
ALTER ROLE

Это напоминает команду su в ОС Unix.


Чтобы понять, кем является пользователь на самом деле, и на какую роль он переключился, есть функции:

alice=> SELECT session_user, current_user;
 session_user | current_user 
--------------+--------------
 alice        | postgres
(1 row)

Вернемся к прежней роли:

alice=> RESET ROLE;
RESET
alice=> SELECT session_user, current_user;
 session_user | current_user 
--------------+--------------
 alice        | alice
(1 row)


Владение объектами

Когда Алиса создает какой-либо объект в БД, она становится его владельцем.

alice=> CREATE TABLE test(id integer);
CREATE TABLE

Как в этом убедиться? Владелец указан в столбце owner:

alice=> \dt test
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 public | test | table | alice
(1 row)


Удаление ролей

Удалить роль можно, если нет объектов, которыми она владеет.

alice=> \c - postgres
You are now connected to database "access_roles" as user "postgres".
postgres=# DROP ROLE alice;
ERROR:  role "alice" cannot be dropped because some objects depend on it
DETAIL:  owner of table test

Чтобы удалить Алису, можно передать ее объекты другой роли:

postgres=# REASSIGN OWNED BY alice TO bob;
REASSIGN OWNED
postgres=# \dt test
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 public | test | table | bob
(1 row)

postgres=# DROP ROLE alice;
DROP ROLE

Другой вариант - удалить объекты.

postgres=# DROP OWNED BY bob;
DROP OWNED
postgres=# DROP ROLE bob;
DROP ROLE

Надо только иметь в виду, что роль может владеть объектами в разных базах данных.


Конец демонстрации.