如何仅允许访问Postgres中的特定和公共模式

时间:2014-06-16 16:30:09

标签: sql postgresql plpgsql

现有的postrgrsql 8.4+数据库包含公共和多个公司数据。

常见数据在公共架构中。 模式company1,company2和company3中的公司特定数据 这些模式包含每个公司具有相同名称和相同结构的表。 数据库中的所有对象都归db_owner所有

使用ODBC按用户数访问数据库。每个用户都有自己的名字和 目前是db_owner的成员。因此,每个用户都可以访问所有公司模式。 这应该改变。

用户权利在表public.kasutaja中描述:

create table kasutaja (
kasutaja char(10) primary key,  -- postgres user name
allowedcompanies  char(30)  -- comma separated list of allowed companies
)

例如,

User1可以访问Company1和公共架构 User2可以访问Company1,Company2和公共架构 User3可以访问Company3和公共架构 User4可以访问所有模式。

这在kasutaja表中描述为

insert into kasutaja values ('user1', '1');
insert into kasutaja values ('user2', '1,2');
insert into kasutaja values ('user3', '3');
insert into kasutaja values ('user4', null);

如何仅为某些用户限制某些公司架构的访问权限? 应该使用哪种方法? 我应该停止其他模式db_public_owner, db_company1_owner,db_company2_owner和db_company3_owner并为用户授予对这些模式的访问权限。

如何使用kasutaja表中定义的应用权限创建脚本给用户user1 .. user4用户?

1 个答案:

答案 0 :(得分:0)

此查询:

select 
    kasutaja,
    rtrim(
        'public,' ||
            coalesce(
                regexp_replace(
                    allowedcompanies, '(\d+)', 'company\1', 'g'),
            ''),
        ',') companies
from kasutaja

给出:

kasutaja  companies
user1     public,company1
user2     public,company1,company2
user3     public,company3
user4     public 

在匿名代码块中,您可以循环使用此结果并执行apprioriate revoke并授予:

do $$
declare
    rec record;
begin
    for rec in
        select 
            kasutaja,
            rtrim(
                'public,' ||
                    coalesce(
                        regexp_replace(
                            allowedcompanies, '(\d+)', 'company\1', 'g'),
                    ''),
                ',') companies
        from kasutaja
    loop
        execute format(
            'revoke all on all tables in schema company1,company2,company3 from %s',
            rec.kasutaja);
        execute format(
            'grant all on all tables in schema %s to %s',
            rec.companies, rec.kasutaja);
    end loop;
end $$;

使用例如grant insert, delete, update(或您需要的任何内容)而不是grant all


Postgres 9.0中引入了匿名代码块。在8.4中,您必须使用函数:

create function set_privileges()
returns void language plpgsql as $$
...
end $$;

select set_privileges();