10

Tôi cần phải xác định những đặc quyền nào hiện đang được cấp cho một số chế độ xem vật chất trong cơ sở dữ liệu của tôi.Danh sách tài trợ và đặc quyền cho một cái nhìn vật hoá trong PostgreSQL

Các truy vấn để làm việc này cho một bảng hoặc chế độ xem chuẩn là khá thẳng về phía trước:

SELECT grantee, string_agg(privilege_type, ', ') AS privileges 
FROM information_schema.table_privileges 
WHERE table_schema = 'some_schema' AND table_name = 'some_table' 
GROUP by grantee; 

Điều đó nói rằng, có vẻ không phải là một bảng tương tự như đối với quan điểm hiện thực. PostgreSQL lưu trữ thông tin này ở đâu?

+0

Truy vấn của bạn không hoạt động cho chế độ xem thông thường, nhưng không cho lượt xem vật chất. –

Trả lời

4

Trong Postgres system catalogs là tập hợp cơ bản của thông tin đầy đủ về cài đặt và cơ sở dữ liệu. Danh mục hệ thống là nguồn thông tin đáng tin cậy nhất. Information schema như một tính năng phụ trợ dựa trên catalog hệ thống và được cung cấp để tương thích với RDBMS khác:

Giản đồ thông tin được định nghĩa trong tiêu chuẩn SQL và do đó có thể được dự kiến ​​sẽ được cầm tay và duy trì ổn định - không giống như hệ thống các danh mục, cụ thể cho PostgreSQL và được mô hình hóa sau các mối quan tâm thực hiện. Tuy nhiên, các khung nhìn lược đồ thông tin không chứa thông tin về các tính năng cụ thể của PostgreSQL; để hỏi về những người bạn cần truy vấn danh mục hệ thống hoặc các chế độ xem cụ thể khác của PostgreSQL.

Chế độ xem vật chất không phải là các đối tượng chuẩn SQL do đó lược đồ thông tin không chứa thông tin về chúng.

Danh mục hệ thống pg_class chứa tất cả thông tin về các đặc quyền trong cột relacl.

Nếu cột là null thì chủ sở hữu có tất cả các đặc quyền.

Chuỗi trống dưới dạng tên người dùng trong acl chuỗi có nghĩa là public.

create materialized view test_view as select 1; 
grant select on test_view to public; 
grant delete on test_view to a_user; 

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    s[2] as privileges 
from 
    pg_class c 
    join pg_namespace n on n.oid = relnamespace 
    join pg_roles r on r.oid = relowner, 
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s 
where nspname = 'public' and relname = 'test_view'; 

grantee | privileges 
----------+------------ 
postgres | arwdDxt 
public | r 
a_user | d 
(3 rows) 

Bạn cần một chức năng để hiển thị đặc quyền trong có thể đọc được định dạng:

create or replace function priviliges_from_acl(text) 
returns text language sql as $$ 
    select string_agg(privilege, ', ') 
    from (
     select 
      case ch 
       when 'r' then 'SELECT' 
       when 'w' then 'UPDATE' 
       when 'a' then 'INSERT' 
       when 'd' then 'DELETE' 
       when 'D' then 'TRUNCATE' 
       when 'x' then 'REFERENCES' 
       when 't' then 'TRIGGER' 
      end privilege 
     from 
      regexp_split_to_table($1, '') ch 
    ) s 
$$; 

Sử dụng:

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    priviliges_from_acl(s[2]) as privileges 
from 
    pg_class c 
    join pg_namespace n on n.oid = relnamespace 
    join pg_roles r on r.oid = relowner, 
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s 
where nspname = 'public' and relname = 'test_view'; 

grantee |       privileges       
----------+--------------------------------------------------------------- 
postgres | INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER 
public | SELECT 
a_user | DELETE 
(3 rows) 
+0

Cảm ơn bạn rất nhiều, điều này đã giúp rất nhiều. Tôi thấy nó rất thú vị khi PostgreSQL cho phép bạn cấp các đặc quyền như UPDATE, INSERT và DELETE trên một khung nhìn vật chất hóa. Có phải chỉ vì họ dự định hỗ trợ các hoạt động này trong tương lai? –

+1

Đây thực sự là một tính năng của hệ thống đặc quyền Postgres. Nói chung, một đặc quyền có thể được cấp trên một đối tượng ngay cả khi nó không được áp dụng. – klin

+0

* "Danh mục hệ thống là nguồn thông tin đáng tin cậy nhất." * Các khung nhìn lược đồ thông tin của PostgreSQL trả về thông tin không đáng tin cậy ở đâu? –

1

Sau câu trả lời hữu ích klin, tôi đã đưa ra một quan điểm cho rằng liệt kê tóm tắt tất cả các đặc quyền cho tất cả các mối quan hệ xuất hiện trong pg_class (bảng, lượt xem, số lần xem, chỉ mục, trình tự, bảng ngoại, loại hỗn hợp) cho r tất cả các vai trò:

CREATE VIEW show_privileges AS (
    SELECT 
     grantee, 
     string_agg(relname, ', ' ORDER BY relname) AS rel_names, 
     privileges 
    FROM (
     SELECT 
      relname, 
      coalesce(nullif(s[1], ''), 'public') grantee, 
      (SELECT string_agg(privilege, ', ' ORDER BY privilege ASC) 
       FROM (SELECT 
        CASE ch 
         WHEN 'r' THEN 'SELECT' 
         WHEN 'w' THEN 'UPDATE' 
         WHEN 'a' THEN 'INSERT' 
         WHEN 'd' THEN 'DELETE' 
         WHEN 'D' THEN 'TRUNCATE' 
         WHEN 'x' THEN 'REFERENCES' 
         WHEN 't' THEN 'TRIGGER' 
        END AS privilege 
        FROM regexp_split_to_table(s[2], '') ch 
       ) s 
      ) AS privileges 
     FROM 
      pg_class 
      JOIN pg_namespace ON pg_namespace.oid = relnamespace 
      JOIN pg_roles ON pg_roles.oid = relowner, 
      unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) AS acl, 
      regexp_split_to_array(acl, '=|/') AS s 
     WHERE nspname = 'public' 
    ) AS t 
    GROUP BY grantee, privileges 
    ORDER BY grantee, privileges, rel_names 
); 
Các vấn đề liên quan