1) Modified some labels and controls.

2) Fixed issue where the same user is showing in SQL query.

3) Added SQL tab in the dialog.

refs #3893
This commit is contained in:
Rahul Shirsat 2021-07-07 10:44:02 +05:30 committed by Akshay Joshi
parent a0b2a28ee2
commit 8edd5946e5
9 changed files with 309 additions and 14 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -5,33 +5,45 @@
`Role Reassign/Drop Own Dialog`:index:
**************************************
Use the *Role Reassign/Drop Own* dialog to change the ownership of database objects owned
Use the *Reassign/Drop Own* dialog to change the ownership of database objects owned
by a database role. This dialog instructs the system to change the ownership of database
objects owned by any of the *old_roles* to *new_role*.
The *Role Reassign/Drop Own* dialog organizes the Reassign & Drop role through General tab.
The *Reassign/Drop Own* dialog organizes the Reassign & Drop role through General tab.
.. image:: images/role_reassign_dialog.png
:alt: Role Reassign/Drop Own dialog
:alt: Reassign/Drop Own dialog
:align: center
* Use the *Role operation* field to provide Reassign option.
* Use the *Operation* field to provide Reassign option.
* Provide a new role in the *Reassign Objects to* field; The ownership of all the objects within the selected database,
and of all shared objects (databases, tablespaces), owned by the *old_role* will be reassigned to *new_role*.
* Provide a database on which the reassignment is to be carried out.
The above example demonstrates reassigning *old_role* to *new_role*.
Click the *SQL* tab to continue.
.. image:: images/role_reassign_dialog_sql.png
:alt: Reassign/Drop Own dialog sql
:align: center
Removing database objects owned by a database role.
.. image:: images/role_drop_dialog.png
:alt: Role Reassign/Drop Own dialog
:alt: Reassign/Drop Own dialog
:align: center
* Use the *Role operation* field to provide Drop option.
* Use the *Drop with* field to provide CASCADE option, RESTRICT is default.
* Use the *Operation* field to provide Drop option.
* Use the *Cascade?* field to provide Yes, No is default.
* Provide a database on which the drop of objects is to be carried out.
Click the *SQL* tab to continue.
.. image:: images/role_drop_dialog_sql.png
:alt: Reassign/Drop Own dialog sql
:align: center
The above examples demonstrates drop owned by *role*.
* Click the *Help* button (?) to access online help.

View File

@ -1301,6 +1301,61 @@ WHERE
return status, res
@check_precondition()
def get_reassign_own_sql(self, gid, sid, rid):
"""
This function is used to generate sql for reassign/drop role.
Args:
sid: Server ID
rid: Role Id.
Returns: Json object with sql generate
"""
try:
data = dict()
if request.data:
data = json.loads(request.data, encoding='utf-8')
else:
rargs = request.args or request.form
for k, v in rargs.items():
try:
data[k] = json.loads(v, encoding='utf-8')
except ValueError as ve:
data[k] = v
required_args = ['role_op', 'did', 'old_role_name',
'new_role_name'] \
if 'role_op' in data and data['role_op'] == 'reassign' \
else ['role_op', 'did', 'drop_with_cascade']
for arg in required_args:
if arg not in data:
return make_json_response(
data=gettext("-- definition incomplete"),
status=200
)
is_reassign = True if data['role_op'] == 'reassign' else False
data['is_reassign'] = is_reassign
sql = render_template(
"/".join([self.sql_path, _REASSIGN_OWN_SQL]),
data=data
)
return make_json_response(
data=sql.strip('\n'),
status=200
)
except Exception as e:
return False, internal_server_error(errormsg=str(e))
@check_precondition()
def role_reassign_own(self, gid, sid, rid):
@ -1387,8 +1442,9 @@ WHERE
return make_json_response(
success=1,
info=gettext("Reassign owned successfully!") if is_reassign
else gettext("Drop owned successfully!")
info=gettext("Reassign owned executed successfully!")
if is_reassign
else gettext("Drop owned executed successfully!")
)
except Exception as e:

View File

@ -392,7 +392,7 @@ define('pgadmin.node.role', [
var tree = pgBrowser.tree,
_i = tree.selected(),
_d = _i && _i.length == 1 ? tree.itemData(_i) : undefined,
obj = this, finalUrl;
obj = this, finalUrl, old_role_name;
//RoleReassign Model (Objects like role, database)
var RoleReassignObjectModel = Backbone.Model.extend({
@ -402,6 +402,7 @@ define('pgadmin.node.role', [
did: undefined,
new_role_id: undefined,
new_role_name: undefined,
old_role_name: undefined,
drop_with_cascade: false
},
@ -413,7 +414,7 @@ define('pgadmin.node.role', [
schema: [
{
id: 'role_op',
label: gettext('Role operation'),
label: gettext('Operation'),
cell: 'string',
type: 'radioModern',
controlsClassName: 'pgadmin-controls col-12 col-sm-8',
@ -538,7 +539,7 @@ define('pgadmin.node.role', [
},
{
id: 'drop_with_cascade',
label: gettext('Drop with'),
label: gettext('Cascade?'),
cell: 'string',
type: 'switch',
controlsClassName: 'pgadmin-controls col-12 col-sm-8',
@ -546,8 +547,8 @@ define('pgadmin.node.role', [
disabled: 'isDisabled',
group: gettext('General'),
options: {
'onText': gettext('CASCADE'),
'offText': gettext('RESTRICT'), 'size': 'mini', width: '90'
'onText': gettext('Yes'),
'offText': gettext('No'), 'size': 'mini'
},
deps: ['role_op'],
helpMessage: gettext('Note: CASCADE will automatically drop objects that depend on the affected objects, and in turn all objects that depend on those objects'),
@ -577,6 +578,38 @@ define('pgadmin.node.role', [
},
first_empty: false,
helpMessage: gettext('Target database on which the operation will be carried out'),
},
{
id: 'sqltab', label: gettext('SQL'), group: gettext('SQL'),
type: 'text', disabled: false, control: Backform.SqlTabControl.extend({
initialize: function() {
// Initialize parent class
Backform.SqlTabControl.prototype.initialize.apply(this, arguments);
},
onTabChange: function(sql_tab_obj) {
// Fetch the information only if the SQL tab is visible at the moment.
if (this.dialog && sql_tab_obj.shown == this.tabIndex) {
var self = this,
roleReassignData = self.model.toJSON(),
getUrl;
// Add existing role
roleReassignData.old_role_name = old_role_name;
getUrl = obj.generate_url(_i, 'reassign' , _d, true);
$.ajax({
url: getUrl,
type: 'GET',
cache: false,
data: roleReassignData,
dataType: 'json',
contentType: 'application/json',
}).done(function(res) {
self.sqlCtrl.setValue(res.data);
});
}
},
}),
}
],
validate: function() {
@ -668,6 +701,7 @@ define('pgadmin.node.role', [
node = _d && pgBrowser.Nodes[_d._type];
finalUrl = obj.generate_url(_i, 'reassign' , _d, true);
old_role_name = _d.label;
if (!_d)
return;

View File

@ -123,5 +123,127 @@
"test_result_data": {}
}
}
],
"role_reassign_sql": [
{
"name": "Reassign own role - sql",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"old_role_name": "role_user_1",
"new_role_name": "role_user_2",
"role_op": "reassign"
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {
"result": "REASSIGN OWNED BY role_user_1 TO role_user_2"
}
}
},
{
"name": "Reassign own role - sql (SESSION_USER)",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"role_op": "reassign",
"old_role_name": "role_user_1",
"new_role_name": "SESSION_USER"
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {
"result": "REASSIGN OWNED BY role_user_1 TO SESSION_USER"
}
}
},
{
"name": "Reassign own role - sql (CURRENT_USER)",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"role_op": "reassign",
"old_role_name": "role_user_1",
"new_role_name": "CURRENT_USER"
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {
"result": "REASSIGN OWNED BY role_user_1 TO CURRENT_USER"
}
}
},
{
"name": "Reassign own role - sql (CURRENT_ROLE)",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"role_op": "reassign",
"old_role_name": "role_user_1",
"new_role_name": "CURRENT_ROLE"
},
"server_min_version": 140000,
"skip_msg": "CURRENT_ROLE are not supported by PPAS/PG 13.0 and below.",
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {}
}
},
{
"name": "Drop own role - sql (default)",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"old_role_name": "role_user_1",
"role_op": "drop",
"drop_with_cascade": false
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {
"result": "DROP OWNED BY role_user_1"
}
}
},
{
"name": "Drop own role - sql (cascade)",
"is_positive_test": true,
"test_data": {
"did": null,
"new_role_id": null,
"old_role_name": "role_user_1",
"role_op": "drop",
"drop_with_cascade": true
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {
"result": "DROP OWNED BY role_user_1 CASCADE"
}
}
}
]
}

View File

@ -0,0 +1,71 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as roles_utils
import json
from unittest.mock import patch
class ReassignRoleSQLTestCase(BaseTestGenerator):
"""This class tests the role reassign/drop scenario"""
url = '/browser/role/reassign/'
# Generates scenarios
scenarios = utils.generate_scenarios("role_reassign_sql",
roles_utils.test_cases)
def setUp(self):
self.server_id = parent_node_dict["server"][-1]["server_id"]
self.data = self.test_data
self.role_id = 1
self.data['did'] = parent_node_dict['database'][-1]['db_id']
if hasattr(self, 'server_min_version') and \
self.server_information['server_version'] \
< self.server_min_version:
self.skipTest(self.skip_msg)
def reassign_get_api(self):
get_response = self.tester.get(
self.url + str(utils.SERVER_GROUP) + '/' +
str(self.server_id) + '/' + str(self.role_id),
data=json.dumps(self.data),
follow_redirects=True)
return get_response
def runTest(self):
"""This function tests role reassign/drop scenario"""
if self.is_positive_test:
get_response = self.reassign_get_api()
elif self.mocking_required:
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
get_response = self.reassign_get_api()
self.assertEqual(get_response.status_code,
self.expected_data['status_code'])
self.assertEqual(get_response.json['data'],
self.expected_data['test_result_data']['result'])
def tearDown(self):
"""This function delete the role from added server"""
connection = utils.get_db_connection(self.server['db'],
self.server['username'],
self.server['db_password'],
self.server['host'],
self.server['port'],
self.server['sslmode'])
connection.close()