Add support for comments on RLS policy object. #7414

This commit is contained in:
Rohit Bhati 2024-06-12 17:18:55 +05:30 committed by GitHub
parent c98cea2ea9
commit 288fd7ed12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 58 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -21,6 +21,7 @@ Use the fields in the *General* tab to define the RLS Policy:
* Use the *Name* field to add a descriptive name for the RLS Policy. The name will be displayed in the *pgAdmin* tree control.
* Use the drop-down listbox next to *Role* to select the Role to which the RLS Policy is to be applied.
* Use the drop-down listbox next to *Type* to select the type of the policy.
* Store notes about the policy in the Comment field.
Click the *Commands* tab to continue.

View File

@ -357,6 +357,17 @@ class RowSecurityView(PGChildNodeView):
data = request.form if request.form else json.loads(
request.data
)
for k, v in data.items():
try:
# comments should be taken as is because if user enters a
# json comment it is parsed by loads which should not happen
if k in ('description',):
data[k] = v
else:
data[k] = json.loads(v)
except (ValueError, TypeError, KeyError):
data[k] = v
data['schema'] = self.schema
data['table'] = self.table
for arg in required_args:
@ -421,16 +432,22 @@ class RowSecurityView(PGChildNodeView):
# Most probably this is due to error
if not isinstance(sql, str):
return sql
status, res = self.conn.execute_scalar(sql)
if not status:
return internal_server_error(errormsg=res)
other_node_info = {}
if 'description' in data:
other_node_info['description'] = data['description']
return jsonify(
node=self.blueprint.generate_browser_node(
plid,
tid,
name,
icon="icon-row_security_policy"
icon="icon-row_security_policy",
**other_node_info
)
)

View File

@ -123,6 +123,10 @@ export default class RowSecurityPolicySchema extends BaseUISchema {
return obj.nodeInfo.server.version >= 100000;
},
},
{
id: 'description', label: gettext('Comment'), type: 'multiline',
mode: ['properties', 'create', 'edit'],
}
];
}
}

View File

@ -8,3 +8,7 @@ CREATE POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
FOR SELECT
TO public
USING ((name = CURRENT_USER));
COMMENT ON POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
ON public.test_rls_policy
IS 'This is test description';

View File

@ -39,7 +39,8 @@
"event": "SELECT",
"policyowner": "public",
"schema": "public",
"type": "PERMISSIVE"
"type": "PERMISSIVE",
"description": "This is test description"
},
"expected_sql_file": "create_select_policy.sql",
"expected_msql_file": "create_select_policy_msql.sql"

View File

@ -7,3 +7,7 @@ CREATE POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
AS PERMISSIVE
FOR SELECT
TO public;
COMMENT ON POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
ON public.test_rls_policy
IS 'This is test description';

View File

@ -3,3 +3,7 @@ CREATE POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
AS PERMISSIVE
FOR SELECT
TO public;
COMMENT ON POLICY "test_select_policy_rls_$%{}[]()&*^!@""'`\/#"
ON public.test_rls_policy
IS 'This is test description';

View File

@ -39,7 +39,8 @@
"event": "SELECT",
"policyowner": "public",
"schema": "public",
"type": "PERMISSIVE"
"type": "PERMISSIVE",
"description": "This is test description"
},
"expected_sql_file": "create_select_policy.sql",
"expected_msql_file": "create_select_policy_msql.sql"

View File

@ -61,6 +61,8 @@ class RulesAddTestCase(BaseTestGenerator):
"""This function will Policy under table node."""
self.test_data['name'] = \
"test_policy_add_%s" % (str(uuid.uuid4())[1:8])
self.test_data['description'] = \
"test_comment_add_%s" % (str(uuid.uuid4())[1:8])
if hasattr(self, "owner_policy"):
self.test_data['policyowner'] = self.role_name

View File

@ -25,3 +25,10 @@ CREATE POLICY {{ conn|qtIdent(data.name) }}
WITH CHECK ({{ data.withcheck }});
{% endif %}
{% if data.description %}
COMMENT ON POLICY {{ conn|qtIdent(data.name) }}
ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.description|qtLiteral(conn) }};
{% endif %}

View File

@ -7,13 +7,14 @@ SELECT
rw.qual AS using_orig,
rw.with_check AS withcheck,
rw.with_check AS withcheck_orig,
pg_catalog.array_to_string(rw.roles::name[], ', ') AS policyowner
pg_catalog.array_to_string(rw.roles::name[], ', ') AS policyowner,
des.description
FROM
pg_catalog.pg_policy pl
JOIN pg_catalog.pg_policies rw ON pl.polname=rw.policyname
JOIN pg_catalog.pg_namespace n ON n.nspname=rw.schemaname
JOIN pg_catalog.pg_class rel on rel.relname=rw.tablename
LEFT JOIN pg_catalog.pg_description des ON des.objoid = pl.oid AND des.classoid = 'pg_policy'::regclass
WHERE
{% if plid %}
pl.oid = {{ plid }} and n.oid = {{ scid }} and rel.oid = {{ policy_table_id }};

View File

@ -30,4 +30,10 @@ ALTER POLICY {{ conn|qtIdent(o_data.name) }} ON {{conn|qtIdent(o_data.schema, o_
RENAME TO {{ conn|qtIdent(data.name) }};
{% endif %}
{#####################################################}
{## Change policy comment ##}
{#####################################################}
{% if data.description and o_data.description != data.description %}
COMMENT ON POLICY {{ conn|qtIdent(o_data.name) }} ON {{conn|qtIdent(o_data.schema, o_data.table)}}
IS {{ data.description|qtLiteral(conn) }};
{% endif %}