mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 08:46:39 -06:00
Port RLS node to react. Fixes #6660
This commit is contained in:
parent
977d148c40
commit
40879a5784
@ -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: [
|
||||
'<ul><li>',
|
||||
'<strong>', gettext('Using: '), '</strong>',
|
||||
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.'),
|
||||
'</li><li>',
|
||||
'<strong>', gettext('With check: '), '</strong>',
|
||||
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.'),
|
||||
'</li></ul>',
|
||||
].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();
|
||||
|
@ -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: [
|
||||
'<ul><li>',
|
||||
'<strong>', gettext('Using: '), '</strong>',
|
||||
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.'),
|
||||
'</li><li>',
|
||||
'<strong>', gettext('With check: '), '</strong>',
|
||||
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.'),
|
||||
'</li></ul>',
|
||||
].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;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
@ -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(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('properties', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='tab'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'properties',
|
||||
}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
/>);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user