PGSQL 04: Разграничение прав доступа

Описание:

В прошлых заданиях вы научились создавать базу данных, вносить в нее данные и получать эти данные разными способами в зависимости от поставленной задачи. Еще вы узнали, что запросы можно модифицировать и хранить в базе данных как представления, и разобрались, как написать хранимую процедуру или функцию и потом использовать эти объекты в качестве параметризованного запроса в других запросах или триггерах.

Но есть еще ряд важных вопросов, которые нам предстоит разобрать!

В данном задании мы поговорим о правах на выполнение каких-либо действий в СУБД или базе данных. А также разберем, как субъекты получают права на действия над объектами базы и какие механизмы в СУБД регулируют эти права.

А теперь приступим!

PostgreSQL использует концепцию ролей (roles) для управления разрешениями на доступ к базе данных. Роль можно рассматривать как пользователя базы данных или как группу пользователей, в зависимости от того, как она настроена. Роли могут владеть объектами базы данных (например, таблицами и функциями) и выдавать другим ролям разрешения на доступ к этим объектам, управляя тем, кто и к каким объектам имеет доступ. Кроме того, можно предоставить одной роли членство в другой, таким образом, она сможет использовать права других ролей.

Концепция ролей включает в себя концепцию пользователей (users) и групп (groups). До версии 8.1 в PostgreSQL пользователи и группы были отдельными сущностями, но теперь есть только роли. Любая роль может использоваться в качестве пользователя, группы или того и другого совместно.

Поговорим о ролях подробнее.

Роли

Роли базы данных концептуально полностью отличаются от пользователей операционной системы. На практике соответствие между ними может быть удобным, но не является обязательным.

Важно понимать, что роли базы данных являются глобальными для всей СУБД!!! (не для отдельной базы данных).

Для создания роли используется команда DDL SQL CREATE ROLE:

CREATE ROLE role_name;

Для удобства поставляются программы createuser и dropuser, которые являются обертками для этих команд SQL и вызываются из командной строки оболочки ОС:

createuser role_name
dropuser role_name

Для получения списка существующих ролей рассмотрите pg_roles системного каталога, например:

SELECT rolname FROM pg_roles;

Метакоманда \du программы psql также полезна для получения списка существующих ролей.

И да! Такие команды правильно называть «метакомандами», потому что они — всего лишь обертка (alias) для конкретного запроса к СУБД, который указан чуть выше.

Сразу после инициализации создания кластера СУБД всегда содержит одну заранее определенную роль. Эта роль является суперпользователем (superuser) и по умолчанию (если не изменено при запуске initdb) имеет такое же имя, как и пользователь операционной системы, инициализирующий кластер баз данных. Обычно она называется postgres и служит для начальной настройки кластера базы данных, в частности, для создания других ролей, которые потребуются для выполнения поставленных задач.

Каждое подключение к серверу базы данных выполняется под именем конкретной роли, и она определяет начальные права доступа для команд, выполняемых в этом соединении.

Имя роли для конкретного подключения к базе данных указывается клиентской программой характерным для нее способом, таким образом инициируя запрос на подключение. Например, программа psql для указания роли использует аргумент командной строки -U.

Чтобы подключиться с правами роли postgres к СУБД PostgreSQL, необходимо выполнить команду:

psql -U postgres 

Многие приложения предполагают, что по умолчанию нужно использовать имя пользователя операционной системы (включая createuser и psql). Поэтому часто бывает удобным поддерживать соответствие между именами ролей и именами пользователей операционной системы.

Повторим на примере. Если вы заранее вошли в операционную систему под пользователем postgres, то для psql не нужно будет писать -U postgres, так как psql пытается по умолчанию подключиться с именем пользователя от системы.

Так как с ролью связан набор прав, доступных для клиента, в многопользовательской среде распределять эти права следует с осторожностью, четко понимая, каких будет достаточно для выполнения необходимых операций каждым конкретным пользователем (ролью).

Атрибуты ролей

Полномочия для каждой конкретной роли определяются соответствующими атрибутами ролей.

Разберемся в важных аспектах предоставления прав.

  1. Право подключения:
    Только роли с атрибутом LOGIN могут использоваться для начального подключения к базе данных. Роль с атрибутом LOGIN можно рассматривать как пользователя базы данных. Для создания такой роли можно использовать любой из вариантов, например:
CREATE ROLE role_name LOGIN;

или

CREATE USER role_name;

Команда CREATE USER эквивалентна CREATE ROLE за исключением того, что CREATE USER по умолчанию включает атрибут LOGIN, в то время как CREATE ROLE — нет.

  1. Статус суперпользователя:
    Суперпользователь базы данных обходит все проверки прав доступа, за исключением права на вход в систему. Это опасная привилегия, и она не должна использоваться небрежно. Лучше всего выполнять большую часть работы под другим статусом. Для создания нового суперпользователя используется следующий запрос:
CREATE ROLE role_name SUPERUSER

Важно, что этот запрос выполним только с правами роли, которая также является суперпользователем.

  1. Создание базы данных:
    Роль должна явно иметь разрешение на создание базы данных (за исключением суперпользователей, которые пропускают все проверки). Для создания такой роли используется запрос:
CREATE ROLE role_name CREATEDB
  1. Создание роли:
    Роль должна явно иметь разрешение на создание других ролей (за исключением суперпользователей, которые пропускают все проверки). Для создания такой роли используется запрос:
CREATE ROLE role_name CREATEROLE

Роль с привилегией CREATEROLE может также изменять и удалять другие роли, а также выдавать и отзывать членство в ролях. Однако, для создания, изменения, удаления суперпользовательских ролей, а также изменения в них членства, требуется иметь статус суперпользователя, привилегии CREATEROLE в таких случаях недостаточно.

  1. Запуск репликации:
    Роль должна иметь явное разрешение на запуск потоковой репликации (за исключением суперпользователей, которые пропускают все проверки). Роль, используемая для потоковой репликации, также должна иметь атрибут LOGIN. Для создания такой роли используется запрос:
CREATE ROLE role_name REPLICATION LOGIN
  1. Пароль:
    Пароль имеет значение, если метод аутентификации клиентов требует, чтобы пользователи предоставляли пароль при подключении к базе данных. Методы аутентификации password и md5 используют пароли. База данных и операционная система используют раздельные пароли. Пароль указывается при создании роли:
CREATE ROLE role_name PASSWORD 'string'

Атрибуты ролей могут быть изменены после создания командой ALTER ROLE:

ALTER ROLE role_name [ WITH ] SUPERUSER   

Также нужно знать, что на уровне ролей можно устанавливать многие конфигурационные параметры окружения. Например, если по некоторым причинам всякий раз при подключении к базе данных требуется отключить использование индексов (подсказка: плохая идея), можно выполнить запрос:

ALTER ROLE role_name SET enable_indexscan TO off;

Установленное значение параметра будет сохранено (но не будет применено сразу). Для применения необходимо переподключение. Тогда для последующих подключений с этой ролью будет происходить виртуальное выполнение команды SET enable_indexscan TO off перед началом сеанса. Но это только значение по умолчанию; в течение сеанса этот параметр можно изменить. Для удаления установок на уровне ролей для параметров конфигурации используется запрос:

ALTER ROLE role_name RESET var_name

Обратите внимание, что установка параметров конфигурации на уровне роли без права LOGIN лишено смысла, так как они никогда не будут применены.

Также следует упомянуть о полезном кейсе при создании ролей: рекомендуется создать роль с правами CREATEDB и CREATEROLE, но не суперпользователя, и в дальнейшем использовать ее для управления базами данных и ролями. Такой подход позволит избежать опасностей, связанных с использованием полномочий суперпользователя для задач, которые их не требуют.

Членство в роли (групповые роли)

Часто бывает удобно сгруппировать пользователей для упрощения управления правами: права можно выдавать для всей группы и у всей группы забирать. В PostgreSQL для этого создается роль, представляющая группу, а затем членство в этой группе выдается ролям индивидуальных пользователей.

Для настройки групповой роли сначала нужно создать саму роль:

CREATE ROLE role_name;

Обычно групповая роль не имеет атрибута LOGIN, хотя при желании его можно установить.

После того как групповая роль создана, в нее можно добавлять или удалять членов, используя команды GRANT и REVOKE:

GRANT group_role_name TO role_name1, role_name2 ... ;
REVOKE group_role_name FROM role_name1, role_name2 ... ;

Членом роли может быть и другая групповая роль (потому что, в действительности, нет никаких различий между групповыми и негрупповыми ролями). При этом база данных не допускает замыкания членства по кругу. Также не допускается управление членством роли PUBLIC в других ролях.

Члены групповой роли могут использовать ее права двумя способами:

  1. Каждый член группы может явно выполнить SET ROLE, чтобы временно «стать» групповой ролью. В этом состоянии сеанс базы данных использует полномочия групповой роли вместо оригинальной, под которой был выполнен вход в систему. При этом для всех создаваемых объектов базы данных владельцем считается групповая роль.

  2. Роли, имеющие атрибут INHERIT, автоматически используют права всех ролей, членами которых они являются, в том числе и унаследованные права. Например:

CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;

После подключения с ролью joe сеанс базы данных будет использовать права, выданные напрямую joe, и права, выданные роли admin, так как joe «наследует» права admin. Однако права, выданные wheel, не будут доступны, потому что, хотя joe неявно и является членом wheel, это членство получено через роль admin, которая имеет атрибут NOINHERIT. После выполнения команды:

SET ROLE admin;

сеанс будет использовать только права, назначенные admin, а права, назначенные роли joe, не будут доступны. После выполнения команды:

SET ROLE wheel;

сеанс будет использовать только права, выданные wheel, а права joe и admin не будут доступны. Начальный набор прав можно получить любой из команд:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

Нужно понимать, что команда SET ROLE в любой момент разрешает выбрать любую роль, прямым или косвенным членом которой является оригинальная роль, под которой был выполнен вход в систему. Поэтому в примере выше не обязательно сначала становиться admin, а только потом — wheel.

Важно! В стандарте SQL есть четкое различие между пользователями и ролями. При этом пользователи, в отличие от ролей, не наследуют права автоматически. В PostgreSQL по умолчанию такого нет, это отхождение от стандарта сделано в пользу удобства и совместимости! Но поведение в стиле стандарта SQL для PostgreSQL может быть получено, если для ролей, используемых в стандарте SQL, устанавливать атрибут INHERIT, а для ролей-пользователей — атрибут NOINHERIT, как для пользователей в стандарте SQL. Но снова повторюсь, в PostgreSQL все роли по умолчанию имеют атрибут INHERIT. Изначально это сделано для обратной совместимости с версиями до 8.1, в которых пользователи всегда могли использовать права групп, членами которых они являются.

Атрибуты роли LOGIN, SUPERUSER, CREATEDB и CREATEROLE можно рассматривать как особые права, но они никогда не наследуются как обычные права на объекты базы данных. Чтобы ими воспользоваться, необходимо переключиться на роль, имеющую этот атрибут, с помощью команды SET ROLE. Продолжая предыдущий пример, можно установить атрибуты CREATEDB и CREATEROLE для роли admin. Затем при входе с ролью joe получить доступ к этим правам будет возможно только после выполнения запроса:

SET ROLE admin;

Это все, конечно, хорошо, но что, если нам потребуется удалить роль? И как это сделать правильно?

Смотрите ниже!

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

Так как роли могут владеть объектами баз данных и иметь права доступа к объектам других, удаление роли не сводится к немедленному действию DROP ROLE. Сначала должны быть удалены и переданы другим владельцам все объекты, принадлежащие роли. Также должны быть отозваны все права, данные роли.

Владение объектами можно передавать в индивидуальном порядке, применяя команду ALTER, например:

ALTER TABLE newrepublic_table OWNER TO LeyaOrgana;

Кроме того, для переназначения владения сразу всеми объектами какой-либо другой роли можно применить команду REASSIGN OWNED. Так как REASSIGN OWNED не может обращаться к объектам в других базах данных, ее необходимо выполнить в каждой базе, которая содержит объекты, принадлежащие этой роли. Заметьте, что первая такая команда изменит владельца для всех разделяемых между базами объектов, то есть для баз данных или табличных пространств, принадлежащих удаляемой роли.

После того как все ценные объекты будут переданы новым владельцам, все оставшиеся, принадлежащие удаляемой роли, могут быть удалены с помощью команды DROP OWNED. И эта команда не может обращаться к объектам в других базах данных, так что ее нужно запускать в каждой базе, которая содержит объекты, принадлежащие роли. Также заметьте, что DROP OWNED не удаляет табличные пространства или базы данных целиком, так что это необходимо сделать вручную, если роли принадлежат базы или табличные пространства, не переданные новым владельцам.

DROP OWNED также удаляет все права, которые даны целевой роли для объектов, не принадлежащих ей. Так как REASSIGN OWNED такие объекты не затрагивает, обычно необходимо запустить и REASSIGN OWNED, и DROP OWNED (только в таком порядке!), чтобы полностью ликвидировать зависимости удаляемой роли.

С учетом вышеизложенного, общий рецепт удаления роли, которая владела объектами, следующий:

  1. Передаем объекты роли del_role в пользование роли getter_role:
REASSIGN OWNED BY del_role TO getter_role;
  1. Затем удаляем оставшиеся уже ненужные объекты роли del_role:
DROP OWNED BY del_role;
  1. Повторяем предыдущие команды для каждой базы в кластере, если необходимо.
  2. Удаляем роль:
DROP ROLE del_role;

Когда не все объекты нужно передать одному новому владельцу, лучше сначала вручную отработать исключения, а в завершение выполнить показанные выше действия.

При попытке выполнить DROP ROLE для роли, у которой сохраняются зависимые объекты, будут выданы сообщения, говорящие, какие объекты нужно передать другому владельцу или удалить. Если запрос завершится успешно, роль будет удалена. Также любое членство в групповой роли будет автоматически отозвано (в остальном на других членов групповой роли удаление роли из текущего списка никак не повлияет).

Теперь немного поговорим о схемах.

Схемы

Кластер баз данных PostgreSQL содержит один или несколько именованных экземпляров баз. На уровне кластера создаются роли и некоторые другие объекты. При этом в рамках одного подключения к серверу можно обращаться к данным только одной базы — той, что была выбрана при установлении соединения.

Пользователи кластера не обязательно будут иметь доступ ко всем базам данных этого кластера. Тот факт, что роли создаются на уровне кластера, означает только то, что в кластере не может быть двух ролей joe в разных базах данных, хотя система позволяет ограничить доступ joe только некоторыми базами данных. Для работы с объектами БД в кластере создаются схемы.

Схема базы данных — это коллекция объектов базы данных, имеющая одного владельца и формирующая одно пространство имен. Две таблицы в одной и той же схеме не могут иметь одно и то же имя.

База данных содержит одну или несколько именованных схем, которые, в свою очередь, содержат таблицы. Схемы также содержат именованные объекты других видов, включая типы данных, функции и операторы. Одно и то же имя объекта можно свободно использовать в разных схемах, например, и schema1, и myschema могут содержать таблицы с именем mytable. В отличие от баз данных схемы не ограничивают доступ к данным: пользователи могут обращаться к объектам в любой схеме текущей базы данных, если им назначены соответствующие права.

Есть несколько возможных объяснений, для чего стоит применять схемы:

  1. Чтобы одну базу данных могли использовать несколько пользователей, независимо друг от друга.
  2. Чтобы объединить объекты базы данных в логические группы для облегчения управления ими.
  3. Чтобы в одной базе сосуществовали разные приложения, и при этом не возникало конфликтов имен.

Схемы в некоторым смысле подобны каталогам в операционной системе, но они не могут быть вложенными.

Для создания схемы используется команда CREATE SCHEMA. При этом вы определяете имя схемы по своему выбору, например, так:

CREATE SCHEMA schema_name;

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

schema_name.table_name

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

Есть еще более общий синтаксис:

db_name.schema_name.table_name

но в настоящее время он поддерживается только для формального соответствия стандарту SQL. Если вы указываете базу данных, это может быть только база данных, к которой вы подключены.

Таким образом, создать таблицу в новой схеме можно так:

CREATE TABLE myschema.mytable (
 ...
);

Чтобы удалить пустую схему (не содержащую объектов), выполните:

DROP SCHEMA schema_name;

Удалить схему со всеми содержащимися в ней объектами можно так:

DROP SCHEMA schema_name CASCADE;

Часто бывает нужно создать схему, владельцем которой будет другой пользователь (это один из способов ограничения пользователей пространствами имен). Сделать это можно так:

CREATE SCHEMA schema_name AUTHORIZATION user_name;

Вы даже можете опустить имя схемы, в этом случае именем схемы станет имя пользователя.

Схемы с именами, начинающимися с pg_, являются системными; пользователям не разрешено использовать такие имена.

До этого вы создавали таблицы, не указывая никакие имена схем. По умолчанию такие таблицы (и другие объекты) автоматически помещаются в схему public. Она содержится во всех создаваемых базах данных. Таким образом, команда:

CREATE TABLE cources ( ... );

эквивалентна:

CREATE TABLE public.cources ( ... );

Путь поиска схемы

Везде писать полные имена утомительно и часто все равно лучше не привязывать приложения к конкретной схеме. Поэтому к таблицам обычно обращаются по неполному имени, состоящему просто из имени таблицы. Система определяет, какая именно таблица подразумевается, используя путь поиска, который представляет собой список просматриваемых схем. Подразумеваемой таблицей считается первая подходящая таблица, найденная в схемах пути. Если подходящая таблица не найдена, возникает ошибка, даже если таблица с таким именем есть в других схемах базы данных.

Возможность создавать одноименные объекты в разных схемах усложняет написание запросов, которые должны всегда обращаться к конкретным объектам. Это также потенциально позволяет пользователям влиять на поведение запросов других пользователей, злонамеренно или случайно. Ввиду преобладания неполных имен в запросах и их использования внутри PostgreSQL, добавить схему в search_path — по сути, значит доверять всем пользователям, имеющим право CREATE в этой схеме. Когда вы выполняете обычный запрос, злонамеренный пользователь может создать объекты в схеме, включенной в ваш путь поиска, и таким образом перехватывать управление и выполнять произвольные функции SQL, как если бы их выполняли вы.

Первая схема в пути поиска называется текущей. Эта схема будет использоваться не только при поиске, но и при создании объектов — она будет включать таблицы, созданные командой CREATE TABLE без указания схемы.

Чтобы узнать текущий тип поиска, выполните следующую команду:

SHOW search_path;

В конфигурации по умолчанию она возвращает:

search_path
"$user", public

Первый элемент ссылается на схему с именем текущего пользователя. Если такой схемы не существует, ссылка на нее игнорируется. Второй элемент ссылается на схему public, которую мы уже видели.

Первая существующая схема в пути поиска также считается схемой по умолчанию для новых объектов. Именно поэтому по умолчанию объекты создаются в схеме public. При указании неполной ссылки на объект в любом контексте (при модификации таблиц, изменении данных или в запросах) система просматривает путь поиска, пока не найдет соответствующий объект. Таким образом, в конфигурации по умолчанию неполные имена могут относиться только к объектам в схеме public.

Чтобы добавить в путь нашу новую схему, мы выполняем:

SET search_path TO myschema,public;

Мы опускаем компонент $user, так как здесь в нем нет необходимости. Теперь мы можем обращаться к таблице без указания схемы:

DROP TABLE mytable;

И так как myschema — первый элемент в пути, новые объекты будут по умолчанию создаваться в этой схеме.

Мы можем также написать:

SET search_path TO myschema;

Тогда мы больше не сможем обращаться к схеме public, не написав полное имя объекта. Единственное, что отличает схему public от других, — это то, что она существует по умолчанию, хотя ее также можно удалить.

Путь поиска аналогично работает для имен типов данных, имен функций и имен операторов. Имена типов данных и функций можно записать в полном виде также, как и имена таблиц. Если же вам нужно использовать в выражении полное имя оператора, для этого есть специальный способ — вы должны написать:

OPERATOR(схема.оператор)

Такая запись необходима для избежания синтаксической неоднозначности. Пример такого выражения:

SELECT 3 OPERATOR(pg_catalog.+) 4;

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

Схемы и права

По умолчанию пользователь не может обращаться к объектам в чужих схемах. Чтобы изменить это, владелец схемы должен дать пользователю право USAGE для данной схемы. Чтобы пользователи могли использовать объекты схемы, может понадобиться назначить дополнительные права на уровне объектов.

Пользователю также можно разрешить создавать объекты в схеме, не принадлежащей ему. Для этого ему нужно дать право CREATE в требуемой схеме. Заметьте, что по умолчанию все имеют права CREATE и USAGE в схеме public. Благодаря этому все пользователи могут подключаться к заданной базе данных и создавать объекты в её схеме public. Некоторые шаблоны использования требуют запретить это:

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

(Первое слово «public» обозначает схему, а второе означает «каждый пользователь». В первом случае это идентификатор, а во втором — ключевое слово, поэтому они написаны в разном регистре.

Схема системного каталога

В дополнение к схеме public и схемам, создаваемым пользователями, любая база данных содержит схему pg_catalog, в которой находятся системные таблицы и все встроенные типы данных, функции и операторы. pg_catalog фактически всегда является частью пути поиска. Если даже эта схема не добавлена в путь явно, она неявно просматривается до всех схем, указанных в пути. Так обеспечивается доступность встроенных имён при любых условиях. Однако вы можете явным образом поместить pg_catalog в конец пути поиска, если вам нужно, чтобы пользовательские имена переопределяли встроенные.

Так как имена системных таблиц начинаются с pg_, такие имена лучше не использовать во избежание конфликта имён, возможного при появлении в будущем системной таблицы с тем же именем, что и ваша. (С путём поиска по умолчанию неполная ссылка будет воспринята как обращение к системной таблице.) Системные таблицы будут и дальше содержать в имени приставку pg_, так что они не будут конфликтовать с неполными именами пользовательских таблиц, если пользователи со своей стороны не будут использовать приставку pg_.

Шаблоны использования схем

Схемам можно найти множество применений. Для защиты от влияния недоверенных пользователей на поведение запросов других пользователей предлагается шаблон безопасного использования схем, но если этот шаблон не применяется в базе данных, пользователи, желающие безопасно выполнять в ней запросы, должны будут принимать защитные меры в начале каждого сеанса. В частности, они должны начинать каждый сеанс с присвоения пустого значения переменной search_path или каким-либо другим образом удалять из search_path схемы, доступные для записи обычным пользователям. С конфигурацией по умолчанию легко реализуются следующие шаблоны использования:

  1. Ограничить обычных пользователей личными схемами. Для реализации этого подхода выполните REVOKE CREATE ON SCHEMA public FROM PUBLIC и создайте для каждого пользователя схему с его именем. Как вы знаете, путь поиска по умолчанию начинается с имени $user, вместо которого подставляется имя пользователя. Таким образом, если у всех пользователей будет отдельная схема, они по умолчанию будут обращаться к собственным схемам. Применяя этот шаблон в базе, к которой уже могли подключаться недоверенные пользователи, проверьте, нет ли в схеме public объектов с такими же именами, как у объектов в схеме pg_catalog. Этот случай является шаблоном безопасного использования схем, только если никакой недоверенный пользователь не является владельцем базы данных и не имеет права CREATEROLE. В противном случае безопасное использование схем невозможно.

  2. Удалить схему public из пути поиска по умолчанию, изменив postgresql.conf или выполнив команду ALTER ROLE ALL SET search_path = "$user". При этом все по-прежнему смогут создавать объекты в общей схеме, но выбираться эти объекты будут только по полному имени, со схемой. Тогда как обращаться к таблицам по полному имени вполне допустимо, обращения к функциям в общей схеме всё же будут небезопасными или ненадёжными. Поэтому если вы создаёте функции или расширения в схеме public, применяйте первый шаблон. Если же нет, этот шаблон, как и первый, безопасен при условии, что никакой недоверенный пользователь не является владельцем базы данных и не имеет права CREATEROLE.

  3. Сохранить поведение по умолчанию. Все пользователи неявно обращаются к схеме public. Тем самым имитируется ситуация с полным отсутствием схем, что позволяет осуществить плавный переход из среды без схем. Однако данный шаблон ни в коем случае нельзя считать безопасным. Он подходит, только если в базе данных имеется всего один либо несколько доверяющих друг другу пользователей.

При любом подходе, устанавливая совместно используемые приложения (таблицы, которые нужны всем, дополнительные функции сторонних разработчиков и т. д.), помещайте их в отдельные схемы. Не забудьте дать другим пользователям права для доступа к этим схемам. Тогда пользователи смогут обращаться к этим дополнительным объектам по полному имени или при желании добавят эти схемы в свои пути поиска.

Полезные ссылки:

Правила выполнения задания:

  1. Время создания окружения занимает до 5 минут.
  2. После нажатия кнопки «Начать выполнение» для вас будет создано окружение для выполнения задания, состоящее из одной или более виртуальнах машин с Ubuntu Linux. К ним будут выданы IP, логин и пароль для доступа по SSH, а также при необходимости — дополнительных ресурсов.
  3. Также, если необходимо, вам могут быть выданы переменные, которые в задании указаны в фигурных скобках, — их надо будет подставить при выполнении задания (например, ${base_domain}).
  4. После выполнения всех пунктов задания нажмите кнопку «Проверить выполнение», и в течение 3-5 минут скрипт проверит выполнение всех условий и выставит вам оценку.
  5. В случае, если вы что-то забыли, можно исправить ошибку и отправить на проверку повторно (нажав кнопку «Проверить выполнение»).
  6. После получения удовлетворительной оценки нажмите кнопку «Завершить задание», чтобы созданное окружение уничтожилось и вы могли приступить к следующему заданию.
  7. Если у вас закончилось время (истек таймер) — окружение будет автоматически уничтожено и вам придется начать выполнение заново.
  8. Также, если вы успешно сдали задание, но у вас остались вопросы — вы всегда сможете задать их куратору после проверки (используя кнопку «Задать вопрос куратору») или в чате практикума в любое удобное для вас время. Обращаем внимание — кураторы проверяют вопросы в течение 24 часов.

Задание:

  1. Установите postgresql v13 на предоставленной VM c OS Ubuntu 20.04.

  2. Добавьте в PostgreSQL пользователя root c правами SUPERUSER.

  3. Подключитесь к PostgreSQL пользователем root с помощью команды: psql -U root -d postgres

  4. Cоздайте базу данных rebrain_courses_db так, чтобы владелцем базы данных был root.

  5. Для работы с базой данных создайте пользователя rebrain_admin.

  6. Переместите файл бэкапа базы данных rebrain_courses_db из предыдущего задания на сервер и положите в директорию /tmp/ с именем rebrain_courses_db.sql.bqp.

  7. Восстановите данные из бэкапа базы данных из предыдущего задания командой: psql -U root -d rebrain_courses_db -f /tmp/rebrain_courses_db.sql.bqp

  8. Выдайте все права пользователю rebrain_admin на базу данных rebrain_courses_db.

  9. Создайте роль backup.

  10. Подключитесь пользователем root к базе данных rebrain_courses_db.

  11. С помощью команды GRANT USAGE выдайте права на использование схемы public пользователю rebrain_admin. Затем, с помощью команды ALTER DEFAULT PRIVILEGES выдайте для роли backup права SELECT на вновь создаваемые таблицы пользователем rebrain_admin в схеме public.

  12. Зайдите под пользователем rebrain_admin в базу данных rebrain_courses_db: psql -U rebrain_admin -h 127.0.0.1 -p 5432 rebrain_courses_db;

  13. Cоздайте таблицу blog в базе данных rebrain_courses_db:

CREATE TABLE blog(
    id SERIAL PRIMARY KEY NOT NULL,     -- Primary Key
    user_id INT NOT NULL,               -- Foreign Key to table users 
    blog_text TEXT NOT NULL,
    CONSTRAINT fk_user_id
        FOREIGN KEY (user_id) 
            REFERENCES users(user_id)
    );
  1. Занесите следующие данные в таблицу blog:
INSERT INTO blog(user_id,blog_text)
VALUES (1,'We are studying at the REBRAIN PostgreSQL Workshop');
  1. Снова подключитесь пользователем root к базе данных rebrain_courses_db.
  2. Создайте роль rebrain_group_select_access.
  3. С помощью команды GRANT USAGE выдайте права на использование схемы public пользователю rebrain_group_select_access.
  4. Выдайте права для rebrain_group_select_access только на SELECT из всех таблиц в схеме public.
  5. Создайте роль rebrain_user.
  6. Выдайте для роли rebrain_user права роли rebrain_group_select_access.
  7. Убедитесь, что роль rebrain_user может получать все данные из любых таблиц базы данных rebrain_courses_db в схеме public.
  8. Создайте роль rebrain_portal.
  9. Убедитесь, что вы подключены к базе данных rebrain_courses_db. Для базы данных rebrain_courses_db создайте новую схему rebrain_portal.
  10. С помощью команды GRANT USAGE выдайте права на использование схемы rebrain_portal пользователю rebrain_portal.
  11. Выдайте все права на схему rebrain_portal для роли rebrain_portal.
  12. Сделайте бекап базы данных rebrain_courses_db с помощью команды: pg_dump -U root rebrain_courses_db > /tmp/rebrain_courses_db_task04.sql.bqp
  13. Если уверены, что все выполнили правильно, оправляйте задание на проверку.

Связаться с нами