如何在Rails中使用PostgreSQL设置表所有权?

5
我很新于rails,所以希望这不是一个愚蠢的问题。
我正在尝试让rails使用一个postgresql数据库和两个不同的用户账户。然而,我想要能够在这些账户之间切换,以便他们对数据库拥有相同的权限(最好不是postgresql超级用户)。
我在postgres中创建了一个NOLOGIN角色,它是数据库的所有者。然后将两个用户账户分配给此角色。但是,每当我执行rake db:migrate时,它都会使用户账户(而不是角色)成为表的所有者。如果我切换用户,则第二个用户将无法对第一个用户创建的表具有正确的权限。
拥有两个账户的原因是为了能够快速切换,例如当我需要更改密码时没有停机时间。
是否有一种方法告诉rails在创建表时使用特定的角色作为所有者?(或者也许有更好的方法可以实现这一点,而不需要在同一个postgresql角色中使用两个账户?)
更新:到目前为止,我发现这个解决方案可以手动运行作为外部脚本并将所有表的所有权更改为NOLOGIN角色,但希望有更优雅或与rails更匹配的解决方案。
1个回答

6
你可以在PostgreSQL端做很多事情:
如果你想让role2拥有role1所持有的所有特权,你只需要:
GRANT role1 TO role2;

使用PostgreSQL 9.0或更高版本,可以指示PostgreSQL在新对象上设置默认权限

ALTER DEFAULT PRIVILEGES允许您设置将应用于未来创建的对象的权限。(它不影响已存在对象分配的权限。)当前只能修改表(包括视图和外部表)、序列和函数的权限。

您可以为角色或模式进行此操作。对于您的情况,您可以执行以下操作:

ALTER DEFAULT PRIVILEGES FOR ROLE role1 GRANT SELECT ON TABLES TO role2;

如果您想让多个不同的角色共享一组权限,我建议将所有对象的权限授予一个非登录角色(以前称为GROUP)- 在我的示例中为role0。使用DEFAULT PRIVILEGES来实现这一点,并且不要忘记预先存在的对象,包括序列(我经常会忘记这些)。然后将role0授予给其他角色。
按照这些线路操作:
ALTER DEFAULT PRIVILEGES FOR ROLE role1 GRANT SELECT ON TABLES TO role0;
ALTER DEFAULT PRIVILEGES FOR ROLE role2 GRANT SELECT ON TABLES TO role0;
...

GRANT role0 TO role1;
GRANT role0 TO role2;

这样,如果需要的话,您可以轻松地向一个角色授予额外的权限。您可以将任意数量的角色添加到此设置中。
许多DML语句需要对象的所有权。我引用关于ALTER TABLE的手册中的内容:
“您必须拥有该表才能使用ALTER TABLE。”
成为拥有该表的角色成员也可以。因此,在上面的示例中,如果您使`role0`拥有表格,则`role1`和`role2`可以使用`ALTER TABLE`。执行:
ALTER TABLE tbl OWNER TO user0;

对于您创建的每个表格。

或者在运行CREATE命令之前,您可以扮演这个角色:

SET ROLE user0;
CREATE ...;
CREATE ...;
RESET ROLE;

如果您迷失了自我:
SELECT current_user, session_user;

感谢您的快速回复。那么看看第一个选项:不是拥有一个具有两个用户的“主”角色,而是每个用户都被授予另一个用户?例如 GRANT user1 TO user2; GRANT user2 TO user1?这将需要在“切换”之前每次手动执行吗?但是,如果我使用“DEFAULT PRIVILEGES”,我只需执行一次就可以了。对吗? - gingerlime
GRANT 意味着永久授予权限,仅需一次即可。 - Erwin Brandstetter
抱歉我有些傻,但我不理解这会如何运作。似乎授权是分层的,例如 GRANT user1 TO user2,这样 user2 将拥有与 user1 相同的权限,但反过来则不然。我需要两个用户无论哪个创建了表都具有完全相同的权限。也许我漏看了什么。 - gingerlime
实际上不是Rails,而可能是Postgres在抱怨。手动从Postgres中检查,当尝试运行ALTER TABLE {table_name}...命令时,我得到了相同的错误,即使按照上面介绍的方式授予了ALTER DEFAULT PRIVILEGES... GRANT ALL ON TABLES... - gingerlime
感谢第二次更新答案,但这就是我提问时的起点 - 如何让Rails创建具有与postgresql用户不同所有者的表... - gingerlime
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接