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 #3893pull/55/head
parent
a0b2a28ee2
commit
8edd5946e5
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 |
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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()
|
Loading…
Reference in New Issue