mirror of
https://github.com/gravitational/teleport.git
synced 2026-11-03 16:38:35 +08:00
* Implement granular db permissions for Postgres (RFD 151) * docs, whitespace * Make sure query is closed, even in case of errors along the way * fix imports
37 lines
1.9 KiB
PL/PgSQL
37 lines
1.9 KiB
PL/PgSQL
CREATE OR REPLACE PROCEDURE pg_temp.teleport_update_permissions(username VARCHAR, permissions_ JSONB)
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
DECLARE
|
|
grant_data JSONB;
|
|
grant_item JSONB;
|
|
diff_count_1 INTEGER;
|
|
diff_count_2 INTEGER;
|
|
BEGIN
|
|
|
|
grant_data = COALESCE(permissions_->'tables', '[]'::JSONB);
|
|
|
|
-- If the user has active connections to current database, verify that permissions haven't changed.
|
|
IF EXISTS (SELECT usename FROM pg_stat_activity WHERE usename = username AND datname = current_database()) THEN
|
|
CREATE TEMPORARY TABLE cur_perms AS SELECT table_schema, table_name, privilege_type FROM information_schema.table_privileges WHERE grantee = username;
|
|
CREATE TEMPORARY TABLE new_perms AS SELECT item->>'schema' as table_schema, item->>'table' as table_name, item->>'privilege' as privilege_type FROM jsonb_array_elements(grant_data) as item;
|
|
|
|
SELECT COUNT(*) INTO diff_count_1 FROM (SELECT * FROM cur_perms EXCEPT SELECT * FROM new_perms) q1;
|
|
SELECT COUNT(*) INTO diff_count_2 FROM (SELECT * FROM new_perms EXCEPT SELECT * FROM cur_perms) q2;
|
|
|
|
IF (diff_count_1 > 0) OR (diff_count_2 > 0) THEN
|
|
RAISE WARNING 'Permission changes: removed=%, added=%', diff_count_1, diff_count_2;
|
|
RAISE EXCEPTION SQLSTATE 'TP005' USING MESSAGE = 'TP005: User has active connections and permissions have changed';
|
|
END IF;
|
|
ELSE
|
|
CALL pg_temp.teleport_remove_permissions(username);
|
|
|
|
-- Assign all roles to the created/activated user if grants are provided.
|
|
IF grant_data <> 'null'::JSONB THEN
|
|
FOR grant_item IN SELECT * FROM jsonb_array_elements(grant_data)
|
|
LOOP
|
|
EXECUTE 'GRANT ' || text(grant_item->>'privilege') || ' ON TABLE ' || QUOTE_IDENT(grant_item->>'schema') || '.' || QUOTE_IDENT(grant_item->>'table') || ' TO ' || QUOTE_IDENT(username);
|
|
END LOOP;
|
|
END IF;
|
|
END IF;
|
|
END;
|
|
$$; |