diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
index b352a9d3a..b9e3ba0b6 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
@@ -6,6 +6,9 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
+import RowSecurityPolicySchema from './row_security_policy.ui';
+import { getNodeListByName } from '../../../../../../../../static/js/node_ajax';
+
define('pgadmin.node.row_security_policy', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
@@ -74,17 +77,21 @@ define('pgadmin.node.row_security_policy', [
},
canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
+ getSchema: function(treeNodeInfo, itemNodeData) {
+ return new RowSecurityPolicySchema(
+ {
+ role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData, {}, ()=>true, (res)=>{
+ res.unshift({label: 'PUBLIC', value: 'public'});
+ return res;
+ }),
+ nodeInfo: treeNodeInfo
+ }
+ );
+ },
model: pgAdmin.Browser.Node.Model.extend({
idAttribute: 'oid',
defaults: {
name: undefined,
- policyowner: 'public',
- event: 'ALL',
- using: undefined,
- using_orig: undefined,
- withcheck: undefined,
- withcheck_orig: undefined,
- type:'PERMISSIVE',
},
schema: [{
id: 'name', label: gettext('Name'), cell: 'string',
@@ -92,86 +99,7 @@ define('pgadmin.node.row_security_policy', [
},{
id: 'oid', label: gettext('OID'), cell: 'string',
editable: false, type: 'text', mode: ['properties'],
- },
- {
- id: 'event', label: gettext('Event'), control: 'select2', deps:['event'],
- group: gettext('Commands'), type: 'text',readonly: function(m) {
- return !m.isNew();},
- select2: {
- width: '100%',
- allowClear: false,
- },
- options:[
- {label: 'ALL', value: 'ALL'},
- {label: 'SELECT', value: 'SELECT'},
- {label: 'INSERT', value: 'INSERT'},
- {label: 'UPDATE', value: 'UPDATE'},
- {label: 'DELETE', value: 'DELETE'},
- ],
- },
- {
- id: 'using', label: gettext('Using'), deps: ['using', 'event'],
- type: 'text', disabled: 'disableUsing',
- mode: ['create', 'edit', 'properties'],
- control: 'sql-field', visible: true, group: gettext('Commands'),
- },
- {
- id: 'withcheck', label: gettext('With check'), deps: ['withcheck', 'event'],
- type: 'text', mode: ['create', 'edit', 'properties'],
- control: 'sql-field', visible: true, group: gettext('Commands'),
- disabled: 'disableWithCheck',
- },
- {
- id: 'rls_expression_key_note', label: gettext('RLS policy expression'),
- type: 'note', group: gettext('Commands'), mode: ['create', 'edit'],
- text: [
- '
- ',
- '', gettext('Using: '), '',
- gettext('This expression will be added to queries that refer to the table if row level security is enabled. Rows for which the expression returns true will be visible. Any rows for which the expression returns false or null will not be visible to the user (in a SELECT), and will not be available for modification (in an UPDATE or DELETE). Such rows are silently suppressed; no error is reported.'),
- '
- ',
- '', gettext('With check: '), '',
- gettext('This expression will be used in INSERT and UPDATE queries against the table if row level security is enabled. Only rows for which the expression evaluates to true will be allowed. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update.'),
- '
',
- ].join(''),
- },
- {
- id: 'policyowner', label: gettext('Role'), cell: 'string',
- control: 'node-list-by-name',
- node: 'role', select2: { allowClear: false },
- mode: ['properties', 'edit','create'],
- transform: function() {
- var res =
- Backform.NodeListByNameControl.prototype.defaults.transform.apply(
- this, arguments
- );
- res.unshift({
- label: 'public', value: 'public',
- });
- return res;
- },
- },
- {
- id: 'type', label: gettext('Type'), control: 'select2', deps:['type'],
- type: 'text',readonly: function(m) {
- return !m.isNew();},
- select2: {
- width: '100%',
- allowClear: false,
- },
- options:[
- {label: 'PERMISSIVE', value: 'PERMISSIVE'},
- {label: 'RESTRICTIVE', value: 'RESTRICTIVE'},
- ],
- visible: function(m) {
- if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
- && !_.isUndefined(m.node_info.server.version) &&
- m.node_info.server.version >= 100000)
- return true;
-
- return false;
- },
- },
- ],
+ }],
validate: function(keys) {
var msg;
this.errorModel.clear();
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.ui.js
new file mode 100644
index 000000000..39bd8ee82
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.ui.js
@@ -0,0 +1,137 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+
+export default class RowSecurityPolicySchema extends BaseUISchema {
+ constructor(fieldOptions={}, initValues) {
+ super({
+ name: undefined,
+ policyowner: 'public',
+ event: 'ALL',
+ using: undefined,
+ using_orig: undefined,
+ withcheck: undefined,
+ withcheck_orig: undefined,
+ type:'PERMISSIVE',
+ ...initValues
+ });
+
+ this.fieldOptions = {
+ role: [],
+ function_names: [],
+ ...fieldOptions,
+ };
+
+ this.nodeInfo = this.fieldOptions.nodeInfo;
+
+ }
+
+ get idAttribute() {
+ return 'oid';
+ }
+
+ disableUsingField(state){
+ if (state.event == 'INSERT'){
+ return true;
+ }
+ return false;
+ }
+
+ disableWithCheckField(state){
+ var event = state.event;
+ if ((event == 'SELECT') || (event == 'DELETE')){
+ state.withcheck = '';
+ return true;
+ }
+ return false;
+ }
+
+ get baseFields() {
+ let obj = this;
+ return [
+ {
+ id: 'name', label: gettext('Name'), cell: 'text',
+ editable: true, type: 'text', readonly: false,
+ noEmpty: true
+ },{
+ id: 'oid', label: gettext('OID'), cell: 'string',
+ editable: false, type: 'text', mode: ['properties'],
+ },
+ {
+ id: 'event', label: gettext('Event'), type: 'select',
+ group: gettext('Commands'),disabled: () => {
+ if(obj.isNew()) {
+ return false;
+ }
+ return true;
+ },
+ controlProps: { allowClear: false },
+ options:[
+ {label: 'ALL', value: 'ALL'},
+ {label: 'SELECT', value: 'SELECT'},
+ {label: 'INSERT', value: 'INSERT'},
+ {label: 'UPDATE', value: 'UPDATE'},
+ {label: 'DELETE', value: 'DELETE'},
+ ],
+ },
+ {
+ id: 'using', label: gettext('Using'), deps: ['using', 'event'],
+ type: 'text', disabled: obj.disableUsingField,
+ mode: ['create', 'edit', 'properties'],
+ control: 'sql', visible: true, group: gettext('Commands'),
+ },
+ {
+ id: 'withcheck', label: gettext('With check'), deps: ['withcheck', 'event'],
+ type: 'text', mode: ['create', 'edit', 'properties'],
+ control: 'sql', visible: true, group: gettext('Commands'),
+ disabled: obj.disableWithCheckField,
+ },
+ {
+ id: 'rls_expression_key_note', label: gettext('RLS policy expression'),
+ type: 'note', group: gettext('Commands'), mode: ['create', 'edit'],
+ text: [
+ '- ',
+ '', gettext('Using: '), '',
+ gettext('This expression will be added to queries that refer to the table if row level security is enabled. Rows for which the expression returns true will be visible. Any rows for which the expression returns false or null will not be visible to the user (in a SELECT), and will not be available for modification (in an UPDATE or DELETE). Such rows are silently suppressed; no error is reported.'),
+ '
- ',
+ '', gettext('With check: '), '',
+ gettext('This expression will be used in INSERT and UPDATE queries against the table if row level security is enabled. Only rows for which the expression evaluates to true will be allowed. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update.'),
+ '
',
+ ].join(''),
+ },
+ {
+ id: 'policyowner', label: gettext('Role'), cell: 'text',
+ type: 'select',
+ options: obj.fieldOptions.role,
+ controlProps: { allowClear: false }
+ },
+ {
+ id: 'type', label: gettext('Type'), type: 'select', deps:['type'],
+ disabled: () => {return !obj.isNew();},
+ controlProps: {
+ width: '100%',
+ allowClear: false,
+ },
+ options:[
+ {label: 'PERMISSIVE', value: 'PERMISSIVE'},
+ {label: 'RESTRICTIVE', value: 'RESTRICTIVE'},
+ ],
+ visible: () => {
+ if(obj.nodeInfo.server.version >= 100000)
+ return true;
+
+ return false;
+ },
+ },
+ ];
+ }
+}
diff --git a/web/regression/javascript/schema_ui_files/row_security_policy.ui.spec.js b/web/regression/javascript/schema_ui_files/row_security_policy.ui.spec.js
new file mode 100644
index 000000000..285c9b5f2
--- /dev/null
+++ b/web/regression/javascript/schema_ui_files/row_security_policy.ui.spec.js
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2021, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import jasmineEnzyme from 'jasmine-enzyme';
+import React from 'react';
+import '../helper/enzyme.helper';
+import { createMount } from '@material-ui/core/test-utils';
+import pgAdmin from 'sources/pgadmin';
+import {messages} from '../fake_messages';
+import SchemaView from '../../../pgadmin/static/js/SchemaView';
+//import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+import RowSecurityPolicySchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.ui';
+
+
+describe('RowSecurityPolicySchema', ()=>{
+ let mount;
+ let schemaObj = new RowSecurityPolicySchema(
+ {
+ role: ()=>[],
+ nodeInfo: {server: {version: 90400}},
+ }
+ );
+ let getInitData = ()=>Promise.resolve({});
+
+ /* Use createMount so that material ui components gets the required context */
+ /* https://material-ui.com/guides/testing/#api */
+ beforeAll(()=>{
+ mount = createMount();
+ });
+
+ afterAll(() => {
+ mount.cleanUp();
+ });
+
+ beforeEach(()=>{
+ jasmineEnzyme();
+ /* messages used by validators */
+ pgAdmin.Browser = pgAdmin.Browser || {};
+ pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
+ pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
+ });
+
+ it('create', ()=>{
+ mount({}}
+ onClose={()=>{}}
+ onHelp={()=>{}}
+ onEdit={()=>{}}
+ onDataChange={()=>{}}
+ confirmOnCloseReset={false}
+ hasSQL={false}
+ disableSqlHelp={false}
+ />);
+ });
+
+ it('edit', ()=>{
+ mount({}}
+ onClose={()=>{}}
+ onHelp={()=>{}}
+ onEdit={()=>{}}
+ onDataChange={()=>{}}
+ confirmOnCloseReset={false}
+ hasSQL={false}
+ disableSqlHelp={false}
+ />);
+ });
+
+ it('properties', ()=>{
+ mount({}}
+ onEdit={()=>{}}
+ />);
+ });
+});
+