20.3. Членство в роли #
Часто бывает удобно сгруппировать пользователей для упрощения управления правами: права можно выдавать для всей группы и у всей группы забирать. В Postgres Pro для этого создаётся роль, представляющая группу, а затем членство в этой группе выдаётся ролям индивидуальных пользователей.
Для настройки групповой роли сначала нужно создать саму роль:
CREATE ROLE имя;
Обычно групповая роль не имеет атрибута LOGIN, хотя при желании его можно установить.
После того как групповая роль создана, в неё можно добавлять или удалять членов, используя команды GRANT и REVOKE:
GRANTгрупповая_рольTOроль1, ... ; REVOKEгрупповая_рольFROMроль1, ... ;
Членом роли может быть и другая групповая роль (потому что в действительности нет никаких различий между групповыми и не групповыми ролями). При этом база данных не допускает замыкания членства по кругу. Также не допускается управление членством роли PUBLIC в других ролях.
Члены групповой роли могут использовать её права двумя способами. Во-первых, члены группы, которым было предоставлено членство с атрибутом SET, могут выполнить команду SET ROLE, чтобы временно «стать» групповой ролью. В этом состоянии сеанс базы данных имеет доступ к правам групповой роли вместо исходной роли, от имени которой был выполнен вход в систему. При этом для всех создаваемых объектов базы данных владельцем считается групповая, а не исходная роль. Во-вторых, члены группы, которым было предоставлено членство с атрибутом INHERIT, автоматически используют права ролей, членами которых они являются прямо или косвенно, вплоть до роли без атрибута INHERIT. Например:
CREATE ROLE joe LOGIN; CREATE ROLE admin; CREATE ROLE wheel; CREATE ROLE island; GRANT admin TO joe WITH INHERIT TRUE; GRANT wheel TO admin WITH INHERIT FALSE; GRANT island TO joe WITH INHERIT TRUE, SET FALSE;
После подключения с ролью joe сеанс базы данных будет использовать права, выданные напрямую joe, и права, выданные ролям admin и island, так как joe «наследует» эти права. Однако права, выданные wheel, будут недоступны, потому что, хотя joe косвенно является членом wheel, это членство получено через роль admin, которая была выдана с атрибутом WITH INHERIT FALSE. После выполнения команды:
SET ROLE admin;
сеанс будет использовать только права, выданные admin, а не права, выданные роли joe или island. После выполнения команды:
SET ROLE wheel;
сеанс будет использовать только права, выданные wheel, а не права, выданные joe или admin. Начальный набор прав можно восстановить любой из команд:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
Примечание
Команда SET ROLE в любой момент разрешает выбрать любую роль, прямым или косвенным членом которой является оригинальная роль, под которой был выполнен вход в систему, при условии, что существует цепочка членства в ролях, каждая из которых имеет атрибут SET TRUE (установленный по умолчанию). Поэтому в примере выше не обязательно сначала становиться admin перед тем как стать wheel. С другой стороны, стать island не получится вовсе, а joe может получить доступ к правам только через механизм наследования.
Примечание
В стандарте SQL есть чёткое различие между пользователями и ролями. При этом пользователи, в отличие от ролей, не наследуют права автоматически. Такое поведение может быть получено в Postgres Pro, если для ролей, используемых как роли в стандарте SQL, устанавливать атрибут INHERIT, а для ролей-пользователей в стандарте SQL — атрибут NOINHERIT. Однако в Postgres Pro все роли по умолчанию имеют атрибут INHERIT. Это сделано для обратной совместимости с версиями до 8.1, в которых пользователи всегда могли использовать права групп, членами которых они являются.
Атрибуты роли LOGIN, SUPERUSER, CREATEDB и CREATEROLE можно рассматривать как особые права, но они никогда не наследуются как обычные права на объекты базы данных. Чтобы ими воспользоваться, необходимо переключиться на роль, имеющую этот атрибут, с помощью команды SET ROLE. Продолжая предыдущий пример, можно установить атрибуты CREATEDB и CREATEROLE для роли admin. Затем при входе с ролью joe, получить доступ к этим правам будет возможно только после выполнения SET ROLE admin.
Для удаления групповой роли используется DROP ROLE:
DROP ROLE имя;
Любое членство в групповой роли будет автоматически отозвано (в остальном на членов этой роли это никак не повлияет).