sw1*_*1nn 28 sql amazon-redshift
我想查看红移补助金.
我找到了postgres的这个视图:
CREATE OR REPLACE VIEW view_all_grants AS
SELECT
use.usename as subject,
nsp.nspname as namespace,
c.relname as item,
c.relkind as type,
use2.usename as owner,
c.relacl,
(use2.usename != use.usename and c.relacl::text !~ ('({|,)' || use.usename || '=')) as public
FROM
pg_user use
cross join pg_class c
left join pg_namespace nsp on (c.relnamespace = nsp.oid)
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
c.relowner = use.usesysid or
c.relacl::text ~ ('({|,)(|' || use.usename || ')=')
ORDER BY
subject,
namespace,
item
Run Code Online (Sandbox Code Playgroud)
哪个不起作用,因为::text演员表relacl失败了以下内容:
ERROR: cannot cast type aclitem[] to character varying [SQL State=42846]
Run Code Online (Sandbox Code Playgroud)
将查询修改为
CREATE OR REPLACE VIEW view_all_grants AS
SELECT
use.usename as subject,
nsp.nspname as namespace,
c.relname as item,
c.relkind as type,
use2.usename as owner,
c.relacl
-- , (use2.usename != use.usename and c.relacl::text !~ ('({|,)' || use.usename || '=')) as public
FROM
pg_user use
cross join pg_class c
left join pg_namespace nsp on (c.relnamespace = nsp.oid)
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
c.relowner = use.usesysid
-- or c.relacl::text ~ ('({|,)(|' || use.usename || ')=')
ORDER BY
subject,
namespace,
item
Run Code Online (Sandbox Code Playgroud)
允许创建视图,但我担心这不会显示所有相关数据.
如何修改视图以使用红移?还是有更好的/替代方式来查看红移上的授权?
更新: Redshift具有HAS_TABLE_PRIVILEGE函数来检查授权.(见这里)
drt*_*rtf 65
另一种变化如下:
SELECT *
FROM
(
SELECT
schemaname
,objectname
,usename
,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS sel
,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS ins
,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS upd
,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS del
,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS ref
FROM
(
SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj FROM pg_tables
WHERE schemaname not in ('pg_internal')
UNION
SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj FROM pg_views
WHERE schemaname not in ('pg_internal')
) AS objs
,(SELECT * FROM pg_user) AS usrs
ORDER BY fullobj
)
WHERE (sel = true or ins = true or upd = true or del = true or ref = true)
and schemaname='<opt schema>'
and usename = '<opt username>';
Run Code Online (Sandbox Code Playgroud)
sw1*_*1nn 17
沿线的东西:
select tablename,
HAS_TABLE_PRIVILEGE(tablename, 'select') as select,
HAS_TABLE_PRIVILEGE(tablename, 'insert') as insert,
HAS_TABLE_PRIVILEGE(tablename, 'update') as update,
HAS_TABLE_PRIVILEGE(tablename, 'delete') as delete,
HAS_TABLE_PRIVILEGE(tablename, 'references') as references
from pg_tables where schemaname='public' order by tablename;
Run Code Online (Sandbox Code Playgroud)
给了我所需要的一切.
has_table_privilege函数很方便,但在管理组时并不总是有助于管理.我将您的原始查询变形为特定用户或组创建授权脚本.此示例查询可以轻松变换以满足您的需求
select namespace||'.'||item as tablename ,
'grant ' || substring(
case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',select ' else '' end
||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',update ' else '' end
||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',insert ' else '' end
||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',delete ' else '' end
||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',rule ' else '' end
||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',references ' else '' end
||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',trigger ' else '' end
||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',execute ' else '' end
||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',create ' else '' end
||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',temporary ' else '' end
, 2,10000)
|| ' on '||namespace||'.'||item ||' to group dw_developers;' as grantsql
from
(SELECT
use.usename as subject,
nsp.nspname as namespace,
c.relname as item,
c.relkind as type,
use2.usename as owner,
c.relacl
FROM
pg_user use
cross join pg_class c
left join pg_namespace nsp on (c.relnamespace = nsp.oid)
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
c.relowner = use.usesysid
and nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY
subject, namespace, item
) where relacl is not null
and array_to_string(relacl, '|') like '%group dw_developers%' order by 1
Run Code Online (Sandbox Code Playgroud)
mike_pdb 的答案的发展我想出了以下内容
WITH object_list(schema_name,object_name,permission_info)
AS (
SELECT N.nspname, C.relname, array_to_string(relacl,',')
FROM pg_class AS C
INNER JOIN pg_namespace AS N
ON C.relnamespace = N.oid
WHERE C.relkind in ('v','r')
AND N.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
AND C.relacl[1] IS NOT NULL
),
object_permissions(schema_name,object_name,permission_string)
AS (
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',1) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',2) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',3) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',4) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',5) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',6) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',7) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',8) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',9) FROM object_list
UNION ALL
SELECT schema_name,object_name, SPLIT_PART(permission_info,',',10) FROM object_list
),
permission_parts(schema_name, object_name,security_principal, permission_pattern)
AS (
SELECT
schema_name,
object_name,
LEFT(permission_string ,CHARINDEX('=',permission_string)-1),
SPLIT_PART(SPLIT_PART(permission_string,'=',2),'/',1)
FROM object_permissions
WHERE permission_string >''
)
SELECT
schema_name,
object_name,
'GRANT ' ||
SUBSTRING(
case when charindex('r',permission_pattern) > 0 then ',SELECT ' else '' end
||case when charindex('w',permission_pattern) > 0 then ',UPDATE ' else '' end
||case when charindex('a',permission_pattern) > 0 then ',INSERT ' else '' end
||case when charindex('d',permission_pattern) > 0 then ',DELETE ' else '' end
||case when charindex('R',permission_pattern) > 0 then ',RULE ' else '' end
||case when charindex('x',permission_pattern) > 0 then ',REFERENCES ' else '' end
||case when charindex('t',permission_pattern) > 0 then ',TRIGGER ' else '' end
||case when charindex('X',permission_pattern) > 0 then ',EXECUTE ' else '' end
||case when charindex('U',permission_pattern) > 0 then ',USAGE ' else '' end
||case when charindex('C',permission_pattern) > 0 then ',CREATE ' else '' end
||case when charindex('T',permission_pattern) > 0 then ',TEMPORARY ' else '' end
,2,10000
)
|| ' ON ' || schema_name||'.'||object_name
|| ' TO ' || security_principal
|| ';' as grantsql
FROM permission_parts
;
Run Code Online (Sandbox Code Playgroud)
这里使用了 3 个常用的表表达式。
根据 mike_pdb 的解决方案,单个权限字符被转换为一个串联的授权列表。由于我们不知道将使用哪些授权,因此我们使用位置 2 的 SUBSTRING 来丢弃列表中的第一个逗号。
您可以使用完全相同的方法来编写架构权限的脚本
WITH schema_list(schema_name, permission_info)
AS (
SELECT nspname, array_to_string(nspacl,',')
FROM pg_namespace
WHERE nspacl[1] IS NOT NULL
AND nspname NOT LIKE 'pg%' AND nspname NOT IN ('public','information_schema')
),
schema_permissions(schema_name,permission_string)
AS (
SELECT schema_name,SPLIT_PART(permission_info,',',1) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',2) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',3) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',4) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',5) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',6) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',7) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',8) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',9) FROM schema_list
UNION ALL
SELECT schema_name,SPLIT_PART(permission_info,',',10) FROM schema_list
),
permission_parts(schema_name, security_principal, permission_pattern)
AS (
SELECT
schema_name,
LEFT(permission_string ,CHARINDEX('=',permission_string)-1),
SPLIT_PART(SPLIT_PART(permission_string,'=',2),'/',1)
FROM schema_permissions
WHERE permission_string >''
)
SELECT
schema_name,
'GRANT ' ||
SUBSTRING(
case when charindex('r',permission_pattern) > 0 then ',SELECT ' else '' end
||case when charindex('w',permission_pattern) > 0 then ',UPDATE ' else '' end
||case when charindex('a',permission_pattern) > 0 then ',INSERT ' else '' end
||case when charindex('d',permission_pattern) > 0 then ',DELETE ' else '' end
||case when charindex('R',permission_pattern) > 0 then ',RULE ' else '' end
||case when charindex('x',permission_pattern) > 0 then ',REFERENCES ' else '' end
||case when charindex('t',permission_pattern) > 0 then ',TRIGGER ' else '' end
||case when charindex('X',permission_pattern) > 0 then ',EXECUTE ' else '' end
||case when charindex('U',permission_pattern) > 0 then ',USAGE ' else '' end
||case when charindex('C',permission_pattern) > 0 then ',CREATE ' else '' end
||case when charindex('T',permission_pattern) > 0 then ',TEMPORARY ' else '' end
,2,10000
)
|| ' ON SCHEMA ' || schema_name
|| ' TO ' || security_principal
|| ';' as grantsql
FROM permission_parts;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44895 次 |
| 最近记录: |