diff --git a/web/pgadmin/dashboard/__init__.py b/web/pgadmin/dashboard/__init__.py index 8f813d7..897bfc0 100644 --- a/web/pgadmin/dashboard/__init__.py +++ b/web/pgadmin/dashboard/__init__.py @@ -409,3 +409,36 @@ def config(sid=None): :return: """ return get_data(sid, None, 'config.sql') + + +@blueprint.route( + '/cancel_session//', methods=['DELETE'] +) +@blueprint.route( + '/cancel_session///', methods=['DELETE'] +) +@login_required +@check_precondition +def cancel_session(sid=None, did=None, pid=None): + """ + This function cancel the specific session + :param sid: server id + :param did: database id + :param pid: session/process id + :return: Response + """ + user = g.manager.user_info + if user and user.get('is_superuser'): + sql = "SELECT pg_cancel_backend({0});".format(pid) + status, res = g.conn.execute_scalar(sql) + if not status: + return internal_server_error(errormsg=res) + + return ajax_response( + response=gettext("Success") if res else gettext("Failed"), + status=200 + ) + else: + return internal_server_error( + errormsg=gettext("User must be a superuser to perform this task.") + ) diff --git a/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js index 34a1ab7..35f5a2b 100644 --- a/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js +++ b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js @@ -1,8 +1,9 @@ define([ - 'require', 'jquery', 'pgadmin', 'underscore', 'backbone', 'sources/gettext', 'flotr2', 'wcdocker', + 'require', 'jquery', 'pgadmin', 'underscore', 'backbone', 'sources/gettext', + 'alertify', 'sources/alerts/alertify_wrapper', 'flotr2', 'wcdocker', 'pgadmin.browser', 'bootstrap' ], -function(r, $, pgAdmin, _, Backbone, gettext) { +function(r, $, pgAdmin, _, Backbone, gettext, alertify, AlertifyWrapper) { var wcDocker = window.wcDocker, pgBrowser = pgAdmin.Browser; @@ -11,7 +12,65 @@ function(r, $, pgAdmin, _, Backbone, gettext) { if (pgAdmin.Dashboard) return; - var dashboardVisible = true; + var dashboardVisible = true, + cancel_session_url = '', + is_super_user = false; + + // Custom BackGrid cell, Responsible for cancelling active sessions + var cancelSessionCell = Backgrid.Extension.DeleteCell.extend({ + render: function () { + this.$el.empty(); + this.$el.html( + "" + ); + this.delegateEvents(); + return this; + }, + deleteRow: function(e) { + var self = this; + e.preventDefault(); + var _title = gettext('Cancel Active Session?'), + _txtConfirm = gettext('Are you sure you wish to cancel this active session?'); + + if (self.model.get('state') == 'idle') { + _title = gettext('Cancel Idle Session?'); + _txtConfirm = gettext('Are you sure you wish to cancel this idle session?'); + } + + alertify.confirm( + _title, + _txtConfirm, + function(evt) { + $.ajax({ + url: cancel_session_url + self.model.get('pid'), + type:'DELETE', + success: function(res) { + var alertifyWrapper = new AlertifyWrapper(); + if (res == gettext('Success')) { + alertifyWrapper.success(gettext('Session cancelled successfully.')); + } else { + alertifyWrapper.error(gettext('Error during canceling session.')); + } + }, + error: function(xhr, status, error) { + try { + var err = $.parseJSON(xhr.responseText); + if (err.success == 0) { + var alertifyWrapper = new AlertifyWrapper(); + alertifyWrapper.error(err.errormsg); + } + } catch (e) {} + } + }); + }, + function(evt) { + return true; + } + ); + } + }); pgAdmin.Dashboard = { init: function() { @@ -63,6 +122,16 @@ function(r, $, pgAdmin, _, Backbone, gettext) { sid = -1, did = -1, b = pgAdmin.Browser, m = b && b.Nodes[itemData._type]; + cancel_session_url = '{{ url_for('dashboard.index') }}' + 'cancel_session/'; + + // Check if user is super user + var server = treeHierarchy['server']; + if(server && server.user && server.user.is_superuser) { + is_super_user = true; + } else { + is_super_user = false; + } + if (m && m.dashboard) { if (_.isFunction(m.dashboard)) { url = m.dashboard.apply( @@ -76,9 +145,11 @@ function(r, $, pgAdmin, _, Backbone, gettext) { sid = treeHierarchy.server._id; did = treeHierarchy.database._id; url += sid + '/' + did; + cancel_session_url += sid + '/' + did + '/'; } else if ('server' in treeHierarchy) { sid = treeHierarchy.server._id; url += sid; + cancel_session_url += sid + '/'; } } @@ -463,6 +534,16 @@ function(r, $, pgAdmin, _, Backbone, gettext) { }]); } + // If user is super user + if(is_super_user) { + server_activity_columns.unshift({ + name: "pg-backform-delete", label: "", + cell: cancelSessionCell, + editable: false, cell_priority: -1, + canDeleteRow: true + }); + } + var server_locks_columns = [{ name: "pid", label: gettext('PID'), @@ -735,6 +816,16 @@ function(r, $, pgAdmin, _, Backbone, gettext) { }]); } + // If user is super user + if(is_super_user) { + database_activity_columns.unshift({ + name: "pg-backform-delete", label: "", + cell: cancelSessionCell, + editable: false, cell_priority: -1, + canDeleteRow: true + }); + } + var database_locks_columns = [{ name: "pid", label: gettext('PID'),