mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fixed an issue where shared server entries not getting deleted from SQLite database if the user gets deleted. Fixes #6143
This commit is contained in:
committed by
Akshay Joshi
parent
6683522491
commit
02c3863e8c
@@ -26,6 +26,7 @@ Bug fixes
|
|||||||
| `Issue #5871 <https://redmine.postgresql.org/issues/5871>`_ - Ensure that username should be visible in the 'Connect to Server' popup when service and user name both specified.
|
| `Issue #5871 <https://redmine.postgresql.org/issues/5871>`_ - Ensure that username should be visible in the 'Connect to Server' popup when service and user name both specified.
|
||||||
| `Issue #6045 <https://redmine.postgresql.org/issues/6045>`_ - Fixed autocomplete issue where it is not showing any suggestions if the schema name contains escape characters.
|
| `Issue #6045 <https://redmine.postgresql.org/issues/6045>`_ - Fixed autocomplete issue where it is not showing any suggestions if the schema name contains escape characters.
|
||||||
| `Issue #6087 <https://redmine.postgresql.org/issues/6087>`_ - Fixed an issue where the dependencies tab showing multiple owners for the objects having shared dependencies.
|
| `Issue #6087 <https://redmine.postgresql.org/issues/6087>`_ - Fixed an issue where the dependencies tab showing multiple owners for the objects having shared dependencies.
|
||||||
|
| `Issue #6143 <https://redmine.postgresql.org/issues/6143>`_ - Fixed an issue where shared server entries not getting deleted from SQLite database if the user gets deleted.
|
||||||
| `Issue #6163 <https://redmine.postgresql.org/issues/6163>`_ - Fixed an issue where Zoom to fit button only works if the diagram is larger than the canvas.
|
| `Issue #6163 <https://redmine.postgresql.org/issues/6163>`_ - Fixed an issue where Zoom to fit button only works if the diagram is larger than the canvas.
|
||||||
| `Issue #6164 <https://redmine.postgresql.org/issues/6164>`_ - Ensure that the diagram should not vanish entirely if zooming out too far in ERD.
|
| `Issue #6164 <https://redmine.postgresql.org/issues/6164>`_ - Ensure that the diagram should not vanish entirely if zooming out too far in ERD.
|
||||||
| `Issue #6177 <https://redmine.postgresql.org/issues/6177>`_ - Fixed an issue while downloading ERD images in Safari and Firefox.
|
| `Issue #6177 <https://redmine.postgresql.org/issues/6177>`_ - Fixed an issue while downloading ERD images in Safari and Firefox.
|
||||||
|
|||||||
@@ -177,6 +177,17 @@ class ServerGroupView(NodeView):
|
|||||||
# if server group id is 1 we won't delete it.
|
# if server group id is 1 we won't delete it.
|
||||||
sg = groups.first()
|
sg = groups.first()
|
||||||
|
|
||||||
|
shared_servers = Server.query.filter_by(servergroup_id=sg.id,
|
||||||
|
shared=True).all()
|
||||||
|
if shared_servers:
|
||||||
|
return make_json_response(
|
||||||
|
status=417,
|
||||||
|
success=0,
|
||||||
|
errormsg=gettext(
|
||||||
|
'The specified server group cannot be deleted.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if sg.id == gid:
|
if sg.id == gid:
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
status=417,
|
status=417,
|
||||||
|
|||||||
@@ -100,352 +100,353 @@ export default function newConnectionDialogModel(response, sgid, sid, handler, c
|
|||||||
server_name: server_name,
|
server_name: server_name,
|
||||||
database_name: database_name,
|
database_name: database_name,
|
||||||
},
|
},
|
||||||
schema: [{
|
schema: [
|
||||||
id: 'server',
|
{
|
||||||
name: 'server',
|
id: 'server',
|
||||||
label: gettext('Server'),
|
name: 'server',
|
||||||
type: 'text',
|
label: gettext('Server'),
|
||||||
editable: true,
|
type: 'text',
|
||||||
disabled: false,
|
editable: true,
|
||||||
select2: {
|
disabled: false,
|
||||||
allowClear: false,
|
select2: {
|
||||||
width: 'style',
|
allowClear: false,
|
||||||
templateResult: formatNode,
|
width: 'style',
|
||||||
templateSelection: formatNode,
|
templateResult: formatNode,
|
||||||
},
|
templateSelection: formatNode,
|
||||||
events: {
|
|
||||||
'focus select': 'clearInvalid',
|
|
||||||
'keydown :input': 'processTab',
|
|
||||||
'select2:select': 'onSelect',
|
|
||||||
'select2:selecting': 'beforeSelect',
|
|
||||||
'select2:clear': 'onChange',
|
|
||||||
},
|
|
||||||
transform: function(data) {
|
|
||||||
let group_template_options = [];
|
|
||||||
for (let key in data) {
|
|
||||||
if (data.hasOwnProperty(key)) {
|
|
||||||
group_template_options.push({'group': key, 'optval': data[key]});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return group_template_options;
|
|
||||||
},
|
|
||||||
control: Backform.Select2Control.extend({
|
|
||||||
template: _.template([
|
|
||||||
'<% if(label == false) {} else {%>',
|
|
||||||
' <label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
||||||
'<% }%>',
|
|
||||||
'<div class="<%=controlsClassName%>">',
|
|
||||||
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
|
|
||||||
' name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%>',
|
|
||||||
' <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
|
|
||||||
' <%=select2.first_empty ? " <option></option>" : ""%>',
|
|
||||||
' <% for (var i=0; i < options.length; i++) {%>',
|
|
||||||
' <% if (options[i].group) { %>',
|
|
||||||
' <% var group = options[i].group; %>',
|
|
||||||
' <% if (options[i].optval) { %> <% var option_length = options[i].optval.length; %>',
|
|
||||||
' <optgroup label="<%=group%>">',
|
|
||||||
' <% for (var subindex=0; subindex < option_length; subindex++) {%>',
|
|
||||||
' <% var option = options[i].optval[subindex]; %>',
|
|
||||||
' <option ',
|
|
||||||
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
|
|
||||||
' <% if (option.connected) { %> data-connected=connected <%}%>',
|
|
||||||
' value=<%- formatter.fromRaw(option.value) %>',
|
|
||||||
' <% if (option.selected) {%>selected="selected"<%} else {%>',
|
|
||||||
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
|
|
||||||
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
|
|
||||||
' <%}%>',
|
|
||||||
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
|
|
||||||
' <%}%>',
|
|
||||||
' </optgroup>',
|
|
||||||
' <%}%>',
|
|
||||||
' <%} else {%>',
|
|
||||||
' <% var option = options[i]; %>',
|
|
||||||
' <option ',
|
|
||||||
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
|
|
||||||
' <% if (option.connected) { %> data-connected=connected <%}%>',
|
|
||||||
' value=<%- formatter.fromRaw(option.value) %>',
|
|
||||||
' <% if (option.selected) {%>selected="selected"<%} else {%>',
|
|
||||||
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
|
|
||||||
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
|
|
||||||
' <%}%>',
|
|
||||||
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
|
|
||||||
' <%}%>',
|
|
||||||
' <%}%>',
|
|
||||||
' </select>',
|
|
||||||
' <% if (helpMessage && helpMessage.length) { %>',
|
|
||||||
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
|
||||||
' <% } %>',
|
|
||||||
'</div>',
|
|
||||||
].join('\n')),
|
|
||||||
beforeSelect: function() {
|
|
||||||
var selVal = arguments[0].params.args.data.id;
|
|
||||||
|
|
||||||
if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
|
|
||||||
this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
|
|
||||||
} else {
|
|
||||||
$(this.$sel).trigger('change');
|
|
||||||
setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
changeIcon: function(data) {
|
events: {
|
||||||
let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
|
'focus select': 'clearInvalid',
|
||||||
selSpan = this.$el.find('option:selected');
|
'keydown :input': 'processTab',
|
||||||
|
'select2:select': 'onSelect',
|
||||||
if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
|
'select2:selecting': 'beforeSelect',
|
||||||
let icon = (data.icon) ? data.icon : 'icon-pg';
|
'select2:clear': 'onChange',
|
||||||
span.removeClass('icon-server-not-connected');
|
|
||||||
span.addClass(icon);
|
|
||||||
span.attr('data-connected', 'connected');
|
|
||||||
|
|
||||||
selSpan.data().image = icon;
|
|
||||||
selSpan.attr('data-connected', 'connected');
|
|
||||||
alertify.connectServer().destroy();
|
|
||||||
this.onChange.apply(this);
|
|
||||||
}
|
|
||||||
else if (span.hasClass('icon-database-not-connected')) {
|
|
||||||
let icon = (data.icon) ? data.icon : 'pg-icon-database';
|
|
||||||
|
|
||||||
span.removeClass('icon-database-not-connected');
|
|
||||||
span.addClass(icon);
|
|
||||||
span.attr('data-connected', 'connected');
|
|
||||||
|
|
||||||
selSpan.removeClass('icon-database-not-connected');
|
|
||||||
selSpan.data().image = icon;
|
|
||||||
selSpan.attr('data-connected', 'connected');
|
|
||||||
alertify.connectServer().destroy();
|
|
||||||
this.onChange.apply(this);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
connect: function(self) {
|
transform: function(data) {
|
||||||
let local_self = self;
|
let group_template_options = [];
|
||||||
|
for (let key in data) {
|
||||||
if(alertify.connectServer) {
|
if (data.hasOwnProperty(key)) {
|
||||||
delete alertify.connectServer;
|
group_template_options.push({'group': key, 'optval': data[key]});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return group_template_options;
|
||||||
|
},
|
||||||
|
control: Backform.Select2Control.extend({
|
||||||
|
template: _.template([
|
||||||
|
'<% if(label == false) {} else {%>',
|
||||||
|
' <label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
||||||
|
'<% }%>',
|
||||||
|
'<div class="<%=controlsClassName%>">',
|
||||||
|
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
|
||||||
|
' name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%>',
|
||||||
|
' <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
|
||||||
|
' <%=select2.first_empty ? " <option></option>" : ""%>',
|
||||||
|
' <% for (var i=0; i < options.length; i++) {%>',
|
||||||
|
' <% if (options[i].group) { %>',
|
||||||
|
' <% var group = options[i].group; %>',
|
||||||
|
' <% if (options[i].optval) { %> <% var option_length = options[i].optval.length; %>',
|
||||||
|
' <optgroup label="<%=group%>">',
|
||||||
|
' <% for (var subindex=0; subindex < option_length; subindex++) {%>',
|
||||||
|
' <% var option = options[i].optval[subindex]; %>',
|
||||||
|
' <option ',
|
||||||
|
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
|
||||||
|
' <% if (option.connected) { %> data-connected=connected <%}%>',
|
||||||
|
' value=<%- formatter.fromRaw(option.value) %>',
|
||||||
|
' <% if (option.selected) {%>selected="selected"<%} else {%>',
|
||||||
|
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
|
||||||
|
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
|
||||||
|
' <%}%>',
|
||||||
|
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
|
||||||
|
' <%}%>',
|
||||||
|
' </optgroup>',
|
||||||
|
' <%}%>',
|
||||||
|
' <%} else {%>',
|
||||||
|
' <% var option = options[i]; %>',
|
||||||
|
' <option ',
|
||||||
|
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
|
||||||
|
' <% if (option.connected) { %> data-connected=connected <%}%>',
|
||||||
|
' value=<%- formatter.fromRaw(option.value) %>',
|
||||||
|
' <% if (option.selected) {%>selected="selected"<%} else {%>',
|
||||||
|
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
|
||||||
|
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
|
||||||
|
' <%}%>',
|
||||||
|
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
|
||||||
|
' <%}%>',
|
||||||
|
' <%}%>',
|
||||||
|
' </select>',
|
||||||
|
' <% if (helpMessage && helpMessage.length) { %>',
|
||||||
|
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
||||||
|
' <% } %>',
|
||||||
|
'</div>',
|
||||||
|
].join('\n')),
|
||||||
|
beforeSelect: function() {
|
||||||
|
var selVal = arguments[0].params.args.data.id;
|
||||||
|
|
||||||
alertify.dialog('connectServer', function factory() {
|
if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
|
||||||
return {
|
this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
|
||||||
main: function(
|
} else {
|
||||||
title, message, server_id, submit_password=true, connect_server=null,
|
$(this.$sel).trigger('change');
|
||||||
) {
|
setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
|
||||||
this.set('title', title);
|
}
|
||||||
this.message = message;
|
},
|
||||||
this.server_id = server_id;
|
changeIcon: function(data) {
|
||||||
this.submit_password = submit_password;
|
let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
|
||||||
this.connect_server = connect_server;
|
selSpan = this.$el.find('option:selected');
|
||||||
},
|
|
||||||
setup:function() {
|
|
||||||
return {
|
|
||||||
buttons:[{
|
|
||||||
text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
|
|
||||||
key: 27,
|
|
||||||
},{
|
|
||||||
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
|
|
||||||
}],
|
|
||||||
focus: {element: '#password', select: true},
|
|
||||||
options: {
|
|
||||||
modal: 0, resizable: false, maximizable: false, pinnable: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
build:function() {
|
|
||||||
},
|
|
||||||
prepare:function() {
|
|
||||||
this.setContent(this.message);
|
|
||||||
},
|
|
||||||
callback: function(closeEvent) {
|
|
||||||
var loadingDiv = $('#show_filter_progress');
|
|
||||||
if (closeEvent.button.text == gettext('OK')) {
|
|
||||||
if(this.submit_password) {
|
|
||||||
var _url = url_for('sqleditor.connect_server', {'sid': this.server_id});
|
|
||||||
|
|
||||||
loadingDiv.removeClass('d-none');
|
if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
|
||||||
$.ajax({
|
let icon = (data.icon) ? data.icon : 'icon-pg';
|
||||||
type: 'POST',
|
span.removeClass('icon-server-not-connected');
|
||||||
timeout: 30000,
|
span.addClass(icon);
|
||||||
url: _url,
|
span.attr('data-connected', 'connected');
|
||||||
data: $('#frmPassword').serialize(),
|
|
||||||
})
|
|
||||||
.done(function(res) {
|
|
||||||
|
|
||||||
local_self.model.attributes.database = null;
|
selSpan.data().image = icon;
|
||||||
local_self.changeIcon(res.data);
|
selSpan.attr('data-connected', 'connected');
|
||||||
local_self.model.attributes.user = null;
|
alertify.connectServer().destroy();
|
||||||
local_self.model.attributes.role = null;
|
this.onChange.apply(this);
|
||||||
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
|
}
|
||||||
Object.keys(response.server_list).forEach(key => {
|
else if (span.hasClass('icon-database-not-connected')) {
|
||||||
response.server_list[key].forEach(option => {
|
let icon = (data.icon) ? data.icon : 'pg-icon-database';
|
||||||
if (option.value == local_self.getValueFromDOM()) {
|
|
||||||
response.server_name = option.label;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
loadingDiv.addClass('d-none');
|
span.removeClass('icon-database-not-connected');
|
||||||
alertify.connectServer().destroy();
|
span.addClass(icon);
|
||||||
|
span.attr('data-connected', 'connected');
|
||||||
|
|
||||||
|
selSpan.removeClass('icon-database-not-connected');
|
||||||
|
selSpan.data().image = icon;
|
||||||
|
selSpan.attr('data-connected', 'connected');
|
||||||
|
alertify.connectServer().destroy();
|
||||||
|
this.onChange.apply(this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
connect: function(self) {
|
||||||
|
let local_self = self;
|
||||||
|
|
||||||
|
if(alertify.connectServer) {
|
||||||
|
delete alertify.connectServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
alertify.dialog('connectServer', function factory() {
|
||||||
|
return {
|
||||||
|
main: function(
|
||||||
|
title, message, server_id, submit_password=true, connect_server=null,
|
||||||
|
) {
|
||||||
|
this.set('title', title);
|
||||||
|
this.message = message;
|
||||||
|
this.server_id = server_id;
|
||||||
|
this.submit_password = submit_password;
|
||||||
|
this.connect_server = connect_server;
|
||||||
|
},
|
||||||
|
setup:function() {
|
||||||
|
return {
|
||||||
|
buttons:[{
|
||||||
|
text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
|
||||||
|
key: 27,
|
||||||
|
},{
|
||||||
|
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
|
||||||
|
}],
|
||||||
|
focus: {element: '#password', select: true},
|
||||||
|
options: {
|
||||||
|
modal: 0, resizable: false, maximizable: false, pinnable: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
build:function() {
|
||||||
|
},
|
||||||
|
prepare:function() {
|
||||||
|
this.setContent(this.message);
|
||||||
|
},
|
||||||
|
callback: function(closeEvent) {
|
||||||
|
var loadingDiv = $('#show_filter_progress');
|
||||||
|
if (closeEvent.button.text == gettext('OK')) {
|
||||||
|
if(this.submit_password) {
|
||||||
|
var _url = url_for('sqleditor.connect_server', {'sid': this.server_id});
|
||||||
|
|
||||||
|
loadingDiv.removeClass('d-none');
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
timeout: 30000,
|
||||||
|
url: _url,
|
||||||
|
data: $('#frmPassword').serialize(),
|
||||||
})
|
})
|
||||||
.fail(function(xhr) {
|
.done(function(res) {
|
||||||
loadingDiv.addClass('d-none');
|
|
||||||
alertify.connectServer().destroy();
|
local_self.model.attributes.database = null;
|
||||||
alertify.connectServer('Connect to server', xhr.responseJSON.result, local_self.getValueFromDOM());
|
local_self.changeIcon(res.data);
|
||||||
});
|
local_self.model.attributes.user = null;
|
||||||
} else {
|
local_self.model.attributes.role = null;
|
||||||
if(Object.keys(this.connect_server).length > 0) {
|
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
|
||||||
this.connect_server['password'] = $('#password').val();
|
Object.keys(response.server_list).forEach(key => {
|
||||||
this.connect_server['is_selected'] = false;
|
response.server_list[key].forEach(option => {
|
||||||
handler.gridView.on_change_connection(this.connect_server, conn_self, false);
|
if (option.value == local_self.getValueFromDOM()) {
|
||||||
loadingDiv = $('#fetching_data');
|
response.server_name = option.label;
|
||||||
loadingDiv.addClass('d-none');
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
alertify.connectServer().destroy();
|
||||||
|
})
|
||||||
|
.fail(function(xhr) {
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
alertify.connectServer().destroy();
|
||||||
|
alertify.connectServer('Connect to server', xhr.responseJSON.result, local_self.getValueFromDOM());
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
response.password = $('#password').val();
|
if(Object.keys(this.connect_server).length > 0) {
|
||||||
loadingDiv.addClass('d-none');
|
this.connect_server['password'] = $('#password').val();
|
||||||
|
this.connect_server['is_selected'] = false;
|
||||||
|
handler.gridView.on_change_connection(this.connect_server, conn_self, false);
|
||||||
|
loadingDiv = $('#fetching_data');
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
} else {
|
||||||
|
response.password = $('#password').val();
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
local_self.model.attributes.database = null;
|
||||||
|
local_self.model.attributes.user = null;
|
||||||
|
local_self.model.attributes.role = null;
|
||||||
|
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
alertify.connectServer().destroy();
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
closeEvent.close = true;
|
||||||
local_self.model.attributes.database = null;
|
},
|
||||||
local_self.model.attributes.user = null;
|
};
|
||||||
local_self.model.attributes.role = null;
|
|
||||||
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
|
|
||||||
loadingDiv.addClass('d-none');
|
|
||||||
alertify.connectServer().destroy();
|
|
||||||
|
|
||||||
}
|
|
||||||
closeEvent.close = true;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
let self = this;
|
|
||||||
self.connect(self);
|
|
||||||
Object.keys(response.server_list).forEach(key => {
|
|
||||||
response.server_list[key].forEach(option => {
|
|
||||||
if (option.value == parseInt(sid)) {
|
|
||||||
response.server_name = option.label;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
var transform = self.field.get('transform') || self.defaults.transform;
|
render: function() {
|
||||||
if (transform && _.isFunction(transform)) {
|
let self = this;
|
||||||
self.field.set('options', transform.bind(self, response.server_list));
|
self.connect(self);
|
||||||
} else {
|
|
||||||
self.field.set('options', response.server_list);
|
|
||||||
}
|
|
||||||
return Backform.Select2Control.prototype.render.apply(self, arguments);
|
|
||||||
},
|
|
||||||
onChange: function() {
|
|
||||||
this.model.attributes.database = null;
|
|
||||||
this.model.attributes.user = null;
|
|
||||||
let self = this;
|
|
||||||
self.connect(self);
|
|
||||||
|
|
||||||
let url = url_for('sqleditor.connect_server', {
|
|
||||||
'sid': self.getValueFromDOM(),
|
|
||||||
'usr': self.model.attributes.user,
|
|
||||||
});
|
|
||||||
var loadingDiv = $('#show_filter_progress');
|
|
||||||
loadingDiv.removeClass('d-none');
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Cache-Control' : 'no-cache',
|
|
||||||
},
|
|
||||||
}).done(function () {
|
|
||||||
Backform.Select2Control.prototype.onChange.apply(self, arguments);
|
|
||||||
Object.keys(response.server_list).forEach(key => {
|
Object.keys(response.server_list).forEach(key => {
|
||||||
response.server_list[key].forEach(option => {
|
response.server_list[key].forEach(option => {
|
||||||
if (option.value == self.getValueFromDOM()) {
|
if (option.value == parseInt(sid)) {
|
||||||
response.server_name = option.label;
|
response.server_name = option.label;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
loadingDiv.addClass('d-none');
|
var transform = self.field.get('transform') || self.defaults.transform;
|
||||||
}).fail(function(xhr){
|
if (transform && _.isFunction(transform)) {
|
||||||
loadingDiv.addClass('d-none');
|
self.field.set('options', transform.bind(self, response.server_list));
|
||||||
alertify.connectServer('Connect to server', xhr.responseJSON.result, self.getValueFromDOM());
|
} else {
|
||||||
});
|
self.field.set('options', response.server_list);
|
||||||
|
}
|
||||||
|
return Backform.Select2Control.prototype.render.apply(self, arguments);
|
||||||
|
},
|
||||||
|
onChange: function() {
|
||||||
|
this.model.attributes.database = null;
|
||||||
|
this.model.attributes.user = null;
|
||||||
|
let self = this;
|
||||||
|
self.connect(self);
|
||||||
|
|
||||||
|
let url = url_for('sqleditor.connect_server', {
|
||||||
|
'sid': self.getValueFromDOM(),
|
||||||
|
'usr': self.model.attributes.user,
|
||||||
|
});
|
||||||
|
var loadingDiv = $('#show_filter_progress');
|
||||||
|
loadingDiv.removeClass('d-none');
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Cache-Control' : 'no-cache',
|
||||||
|
},
|
||||||
|
}).done(function () {
|
||||||
|
Backform.Select2Control.prototype.onChange.apply(self, arguments);
|
||||||
|
Object.keys(response.server_list).forEach(key => {
|
||||||
|
response.server_list[key].forEach(option => {
|
||||||
|
if (option.value == self.getValueFromDOM()) {
|
||||||
|
response.server_name = option.label;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
}).fail(function(xhr){
|
||||||
|
loadingDiv.addClass('d-none');
|
||||||
|
alertify.connectServer('Connect to server', xhr.responseJSON.result, self.getValueFromDOM());
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'database',
|
||||||
|
name: 'database',
|
||||||
|
label: gettext('Database'),
|
||||||
|
type: 'text',
|
||||||
|
editable: true,
|
||||||
|
disabled: function(m) {
|
||||||
|
let self_local = this;
|
||||||
|
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
|
||||||
|
&& m.get('server') !== '') {
|
||||||
|
setTimeout(function() {
|
||||||
|
if(self_local.options.length) {
|
||||||
|
m.set('database', self_local.options[0].value);
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
}),
|
deps: ['server'],
|
||||||
},
|
url: 'sqleditor.get_new_connection_database',
|
||||||
{
|
select2: {
|
||||||
id: 'database',
|
allowClear: false,
|
||||||
name: 'database',
|
width: '100%',
|
||||||
label: gettext('Database'),
|
first_empty: true,
|
||||||
type: 'text',
|
select_first: false,
|
||||||
editable: true,
|
},
|
||||||
disabled: function(m) {
|
extraClasses:['new-connection-dialog-style'],
|
||||||
let self_local = this;
|
control: NewConnectionSelect2Control,
|
||||||
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
|
transform: function(data) {
|
||||||
|
response.database_list = data;
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
name: 'user',
|
||||||
|
label: gettext('User'),
|
||||||
|
type: 'text',
|
||||||
|
editable: true,
|
||||||
|
deps: ['server'],
|
||||||
|
select2: {
|
||||||
|
allowClear: false,
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
control: NewConnectionSelect2Control,
|
||||||
|
url: 'sqleditor.get_new_connection_user',
|
||||||
|
disabled: function(m) {
|
||||||
|
let self_local = this;
|
||||||
|
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
|
||||||
&& m.get('server') !== '') {
|
&& m.get('server') !== '') {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if(self_local.options.length) {
|
if(self_local.options.length) {
|
||||||
m.set('database', self_local.options[0].value);
|
m.set('user', self_local.options[0].value);
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return true;
|
},
|
||||||
|
},{
|
||||||
|
id: 'role',
|
||||||
|
name: 'role',
|
||||||
|
label: gettext('Role'),
|
||||||
|
type: 'text',
|
||||||
|
editable: true,
|
||||||
|
deps: ['server'],
|
||||||
|
select2: {
|
||||||
|
allowClear: false,
|
||||||
|
width: '100%',
|
||||||
|
first_empty: true,
|
||||||
|
},
|
||||||
|
control: NewConnectionSelect2Control,
|
||||||
|
url: 'sqleditor.get_new_connection_role',
|
||||||
|
disabled: false,
|
||||||
},
|
},
|
||||||
deps: ['server'],
|
|
||||||
url: 'sqleditor.get_new_connection_database',
|
|
||||||
select2: {
|
|
||||||
allowClear: false,
|
|
||||||
width: '100%',
|
|
||||||
first_empty: true,
|
|
||||||
select_first: false,
|
|
||||||
},
|
|
||||||
extraClasses:['new-connection-dialog-style'],
|
|
||||||
control: NewConnectionSelect2Control,
|
|
||||||
transform: function(data) {
|
|
||||||
response.database_list = data;
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'user',
|
|
||||||
name: 'user',
|
|
||||||
label: gettext('User'),
|
|
||||||
type: 'text',
|
|
||||||
editable: true,
|
|
||||||
deps: ['server'],
|
|
||||||
select2: {
|
|
||||||
allowClear: false,
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
control: NewConnectionSelect2Control,
|
|
||||||
url: 'sqleditor.get_new_connection_user',
|
|
||||||
disabled: function(m) {
|
|
||||||
let self_local = this;
|
|
||||||
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
|
|
||||||
&& m.get('server') !== '') {
|
|
||||||
setTimeout(function() {
|
|
||||||
if(self_local.options.length) {
|
|
||||||
m.set('user', self_local.options[0].value);
|
|
||||||
}
|
|
||||||
}, 10);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},{
|
|
||||||
id: 'role',
|
|
||||||
name: 'role',
|
|
||||||
label: gettext('Role'),
|
|
||||||
type: 'text',
|
|
||||||
editable: true,
|
|
||||||
deps: ['server'],
|
|
||||||
select2: {
|
|
||||||
allowClear: false,
|
|
||||||
width: '100%',
|
|
||||||
first_empty: true,
|
|
||||||
},
|
|
||||||
control: NewConnectionSelect2Control,
|
|
||||||
url: 'sqleditor.get_new_connection_role',
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
validate: function() {
|
validate: function() {
|
||||||
let msg = null;
|
let msg = null;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from pgadmin.utils.constants import MIMETYPE_APP_JS, INTERNAL,\
|
|||||||
SUPPORTED_AUTH_SOURCES, KERBEROS
|
SUPPORTED_AUTH_SOURCES, KERBEROS
|
||||||
from pgadmin.utils.validation_utils import validate_email
|
from pgadmin.utils.validation_utils import validate_email
|
||||||
from pgadmin.model import db, Role, User, UserPreference, Server, \
|
from pgadmin.model import db, Role, User, UserPreference, Server, \
|
||||||
ServerGroup, Process, Setting
|
ServerGroup, Process, Setting, roles_users, SharedServer
|
||||||
|
|
||||||
# set template path for sql scripts
|
# set template path for sql scripts
|
||||||
MODULE_NAME = 'user_management'
|
MODULE_NAME = 'user_management'
|
||||||
@@ -78,7 +78,9 @@ class UserManagementModule(PgAdminModule):
|
|||||||
'user_management.update_user', 'user_management.delete_user',
|
'user_management.update_user', 'user_management.delete_user',
|
||||||
'user_management.create_user', 'user_management.users',
|
'user_management.create_user', 'user_management.users',
|
||||||
'user_management.user', current_app.login_manager.login_view,
|
'user_management.user', current_app.login_manager.login_view,
|
||||||
'user_management.auth_sources', 'user_management.auth_sources'
|
'user_management.auth_sources', 'user_management.auth_sources',
|
||||||
|
'user_management.shared_servers', 'user_management.admin_users',
|
||||||
|
'user_management.change_owner',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -336,6 +338,8 @@ def delete(uid):
|
|||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
server_groups = ServerGroup.query.filter_by(user_id=uid).all()
|
||||||
|
sg = [server_group.id for server_group in server_groups]
|
||||||
|
|
||||||
Setting.query.filter_by(user_id=uid).delete()
|
Setting.query.filter_by(user_id=uid).delete()
|
||||||
|
|
||||||
@@ -346,6 +350,11 @@ def delete(uid):
|
|||||||
ServerGroup.query.filter_by(user_id=uid).delete()
|
ServerGroup.query.filter_by(user_id=uid).delete()
|
||||||
|
|
||||||
Process.query.filter_by(user_id=uid).delete()
|
Process.query.filter_by(user_id=uid).delete()
|
||||||
|
# Delete Shared servers for current user.
|
||||||
|
SharedServer.query.filter_by(user_id=uid).delete()
|
||||||
|
|
||||||
|
SharedServer.query.filter(SharedServer.servergroup_id.in_(sg)).delete(
|
||||||
|
synchronize_session=False)
|
||||||
|
|
||||||
# Finally delete user
|
# Finally delete user
|
||||||
db.session.delete(usr)
|
db.session.delete(usr)
|
||||||
@@ -361,6 +370,174 @@ def delete(uid):
|
|||||||
return internal_server_error(errormsg=str(e))
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@blueprint.route('/change_owner', methods=['POST'], endpoint='change_owner')
|
||||||
|
@roles_required('Administrator')
|
||||||
|
def change_owner():
|
||||||
|
"""
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = request.form if request.form else json.loads(
|
||||||
|
request.data, encoding='utf-8'
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
old_user_servers = Server.query.filter_by(shared=True, user_id=data[
|
||||||
|
'old_owner']).all()
|
||||||
|
server_group_ids = [server.servergroup_id for server in
|
||||||
|
old_user_servers]
|
||||||
|
server_groups = ServerGroup.query.filter(
|
||||||
|
ServerGroup.id.in_(server_group_ids)).all()
|
||||||
|
|
||||||
|
new_owner_sg = ServerGroup.query.filter_by(
|
||||||
|
user_id=data['new_owner']).all()
|
||||||
|
old_owner_sg = ServerGroup.query.filter_by(
|
||||||
|
user_id=data['old_owner']).all()
|
||||||
|
sg_data = {sg.name: sg.id for sg in new_owner_sg}
|
||||||
|
old_sg_data = {sg.id: sg.name for sg in old_owner_sg}
|
||||||
|
|
||||||
|
deleted_sg = []
|
||||||
|
# Change server user.
|
||||||
|
for server in old_user_servers:
|
||||||
|
if old_sg_data[server.servergroup_id] in sg_data:
|
||||||
|
sh_servers = SharedServer.query.filter_by(
|
||||||
|
servergroup_id=server.servergroup_id).all()
|
||||||
|
for sh in sh_servers:
|
||||||
|
sh.servergroup_id = sg_data[
|
||||||
|
old_sg_data[server.servergroup_id]]
|
||||||
|
# Update Server user and server group to prevent deleting
|
||||||
|
# shared server associated with deleting user.
|
||||||
|
Server.query.filter_by(
|
||||||
|
servergroup_id=server.servergroup_id, shared=True,
|
||||||
|
user_id=data['old_owner']
|
||||||
|
).update(
|
||||||
|
{
|
||||||
|
'servergroup_id': sg_data[old_sg_data[
|
||||||
|
server.servergroup_id]],
|
||||||
|
'user_id': data['new_owner']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ServerGroup.query.filter_by(id=server.servergroup_id).delete()
|
||||||
|
deleted_sg.append(server.servergroup_id)
|
||||||
|
else:
|
||||||
|
server.user_id = data['new_owner']
|
||||||
|
|
||||||
|
# Change server group user.
|
||||||
|
for server_group in server_groups:
|
||||||
|
if server_group.id not in deleted_sg:
|
||||||
|
server_group.user_id = data['new_owner']
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
# Delete old owner records.
|
||||||
|
delete(data['old_owner'])
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info=_("Owner changed successfully."),
|
||||||
|
data={}
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(
|
||||||
|
errormsg='Unable to update shared server owner')
|
||||||
|
|
||||||
|
|
||||||
|
@blueprint.route(
|
||||||
|
'/shared_servers/<int:uid>', methods=['GET'], endpoint='shared_servers'
|
||||||
|
)
|
||||||
|
@roles_required('Administrator')
|
||||||
|
def get_shared_servers(uid):
|
||||||
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
usr = User.query.get(uid)
|
||||||
|
|
||||||
|
if not usr:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
try:
|
||||||
|
shared_servers_count = 0
|
||||||
|
admin_role = Role.query.filter_by(name='Administrator')[0]
|
||||||
|
# Check user has admin role.
|
||||||
|
for role in usr.roles:
|
||||||
|
if role.id == admin_role.id:
|
||||||
|
# get all server created by user.
|
||||||
|
servers = Server.query.filter_by(user_id=usr.id).all()
|
||||||
|
for server in servers:
|
||||||
|
if server.shared:
|
||||||
|
shared_servers_count += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
if shared_servers_count:
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info=_(
|
||||||
|
"{0} Shared servers are associated with this user."
|
||||||
|
"".format(shared_servers_count)
|
||||||
|
),
|
||||||
|
data={
|
||||||
|
'shared_servers': shared_servers_count
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info=_("No shared servers found"),
|
||||||
|
data={'shared_servers': 0}
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
|
||||||
|
# @blueprint.route(
|
||||||
|
# '/admin_users', methods=['GET'], endpoint='admin_users'
|
||||||
|
# )
|
||||||
|
@blueprint.route(
|
||||||
|
'/admin_users/<int:uid>', methods=['GET'], endpoint='admin_users'
|
||||||
|
)
|
||||||
|
@roles_required('Administrator')
|
||||||
|
def admin_users(uid=None):
|
||||||
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
admin_role = Role.query.filter_by(name='Administrator')[0]
|
||||||
|
|
||||||
|
admin_users = db.session.query(roles_users).filter_by(
|
||||||
|
role_id=admin_role.id).all()
|
||||||
|
|
||||||
|
if uid:
|
||||||
|
admin_users = [user[0] for user in admin_users if user[0] != uid]
|
||||||
|
else:
|
||||||
|
admin_users = [user[0] for user in admin_users]
|
||||||
|
|
||||||
|
admin_list = User.query.filter(User.id.in_(admin_users)).all()
|
||||||
|
|
||||||
|
user_list = [{'value': admin.id, 'label': admin.username} for admin in
|
||||||
|
admin_list]
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info=_("No shared servers found"),
|
||||||
|
data={
|
||||||
|
'status': 'success',
|
||||||
|
'msg': 'Admin user list',
|
||||||
|
'result': {
|
||||||
|
'data': user_list,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route('/user/<int:uid>', methods=['PUT'], endpoint='update_user')
|
@blueprint.route('/user/<int:uid>', methods=['PUT'], endpoint='update_user')
|
||||||
@roles_required('Administrator')
|
@roles_required('Administrator')
|
||||||
def update(uid):
|
def update(uid):
|
||||||
|
|||||||
@@ -604,7 +604,223 @@ define([
|
|||||||
}),
|
}),
|
||||||
gridSchema = Backform.generateGridColumnsFromModel(
|
gridSchema = Backform.generateGridColumnsFromModel(
|
||||||
null, UserModel, 'edit'),
|
null, UserModel, 'edit'),
|
||||||
|
|
||||||
|
|
||||||
deleteUserCell = Backgrid.Extension.DeleteCell.extend({
|
deleteUserCell = Backgrid.Extension.DeleteCell.extend({
|
||||||
|
changeOwnership: function(res, uid) {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
let ownershipSelect2Control = Backform.Select2Control.extend({
|
||||||
|
fetchData: function(){
|
||||||
|
let self = this;
|
||||||
|
let url = self.field.get('url');
|
||||||
|
|
||||||
|
url = url_for(url, {'uid': uid});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
headers: {
|
||||||
|
'Cache-Control' : 'no-cache',
|
||||||
|
},
|
||||||
|
}).done(function (res) {
|
||||||
|
var transform = self.field.get('transform');
|
||||||
|
if(res.data.status){
|
||||||
|
let data = res.data.result.data;
|
||||||
|
|
||||||
|
if (transform && _.isFunction(transform)) {
|
||||||
|
self.field.set('options', transform.bind(self, data));
|
||||||
|
} else {
|
||||||
|
self.field.set('options', data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (transform && _.isFunction(transform)) {
|
||||||
|
self.field.set('options', transform.bind(self, []));
|
||||||
|
} else {
|
||||||
|
self.field.set('options', []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Backform.Select2Control.prototype.render.apply(self, arguments);
|
||||||
|
}).fail(function(e){
|
||||||
|
let msg = '';
|
||||||
|
if(e.status == 404) {
|
||||||
|
msg = 'Unable to find url.';
|
||||||
|
} else {
|
||||||
|
msg = e.responseJSON.errormsg;
|
||||||
|
}
|
||||||
|
alertify.error(msg);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
this.fetchData();
|
||||||
|
return Backform.Select2Control.prototype.render.apply(this, arguments);
|
||||||
|
},
|
||||||
|
onChange: function() {
|
||||||
|
Backform.Select2Control.prototype.onChange.apply(this, arguments);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let ownershipModel = pgBrowser.DataModel.extend({
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
id: 'note_text_ch_owner',
|
||||||
|
control: Backform.NoteControl,
|
||||||
|
text: 'Select the user that will take ownership of the shared servers created by <b>' + self.model.get('username') + '</b>. <b>' + res['data'].shared_servers + '</b> shared servers are currently owned by this user.',
|
||||||
|
group: gettext('General'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
name: 'user',
|
||||||
|
label: gettext('User'),
|
||||||
|
type: 'text',
|
||||||
|
editable: true,
|
||||||
|
select2: {
|
||||||
|
allowClear: true,
|
||||||
|
width: '100%',
|
||||||
|
first_empty: true,
|
||||||
|
},
|
||||||
|
control: ownershipSelect2Control,
|
||||||
|
url: 'user_management.admin_users',
|
||||||
|
helpMessage: gettext('Note: If no user is selected, the shared servers will be deleted.'),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
// Change shared server ownership before deleting the admin user
|
||||||
|
if (!alertify.changeOwnershipDialog) {
|
||||||
|
alertify.dialog('changeOwnershipDialog', function factory() {
|
||||||
|
let $container = $('<div class=\'change-ownership\'></div>');
|
||||||
|
return {
|
||||||
|
main: function(message) {
|
||||||
|
this.msg = message;
|
||||||
|
},
|
||||||
|
build: function() {
|
||||||
|
this.elements.content.appendChild($container.get(0));
|
||||||
|
alertify.pgDialogBuild.apply(this);
|
||||||
|
},
|
||||||
|
setup: function(){
|
||||||
|
return {
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: gettext('Cancel'),
|
||||||
|
key: 27,
|
||||||
|
className: 'btn btn-secondary fa fa-times pg-alertify-button',
|
||||||
|
'data-btn-name': 'cancel',
|
||||||
|
}, {
|
||||||
|
text: gettext('OK'),
|
||||||
|
key: 13,
|
||||||
|
className: 'btn btn-primary fa fa-check pg-alertify-button',
|
||||||
|
'data-btn-name': 'ok',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// Set options for dialog
|
||||||
|
options: {
|
||||||
|
title: 'Change ownership',
|
||||||
|
//disable both padding and overflow control.
|
||||||
|
padding: !1,
|
||||||
|
overflow: !1,
|
||||||
|
model: 0,
|
||||||
|
resizable: true,
|
||||||
|
maximizable: false,
|
||||||
|
pinnable: false,
|
||||||
|
closableByDimmer: false,
|
||||||
|
modal: false,
|
||||||
|
autoReset: false,
|
||||||
|
closable: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
prepare: function() {
|
||||||
|
let self = this;
|
||||||
|
$container.html('');
|
||||||
|
|
||||||
|
self.ownershipModel = new ownershipModel();
|
||||||
|
let fields = pgBackform.generateViewSchema(null, self.ownershipModel, 'create', null, null, true, null);
|
||||||
|
|
||||||
|
let view = this.view = new pgBackform.Dialog({
|
||||||
|
el: '<div></div>',
|
||||||
|
model: self.ownershipModel,
|
||||||
|
schema: fields,
|
||||||
|
});
|
||||||
|
//Render change ownership dialog.
|
||||||
|
$container.append(view.render().$el[0]);
|
||||||
|
},
|
||||||
|
callback: function(e) {
|
||||||
|
if(e.button['data-btn-name'] === 'ok') {
|
||||||
|
e.cancel = true; // Do not close dialog
|
||||||
|
let ownershipModel = this.ownershipModel.toJSON();
|
||||||
|
if (ownershipModel.user == '' || ownershipModel.user == undefined) {
|
||||||
|
alertify.confirm(
|
||||||
|
gettext('Delete user?'),
|
||||||
|
gettext('The shared servers owned by <b>'+ self.model.get('username') +'</b> will be deleted. Do you wish to continue?'),
|
||||||
|
function() {
|
||||||
|
|
||||||
|
self.model.destroy({
|
||||||
|
wait: true,
|
||||||
|
success: function() {
|
||||||
|
alertify.success(gettext('User deleted.'));
|
||||||
|
alertify.changeOwnershipDialog().destroy();
|
||||||
|
alertify.UserManagement().destroy();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
alertify.error(
|
||||||
|
gettext('Error during deleting user.')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
alertify.changeOwnershipDialog().destroy();
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.changeOwner(ownershipModel.user, uid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alertify.changeOwnershipDialog().destroy();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
alertify.changeOwnershipDialog('Change ownership').resizeTo(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
|
},
|
||||||
|
changeOwner: function(user_id, old_user) {
|
||||||
|
$.ajax({
|
||||||
|
url: url_for('user_management.change_owner'),
|
||||||
|
method: 'POST',
|
||||||
|
data:{'new_owner': user_id, 'old_owner': old_user},
|
||||||
|
})
|
||||||
|
.done(function(res) {
|
||||||
|
alertify.changeOwnershipDialog().destroy();
|
||||||
|
alertify.UserManagement().destroy();
|
||||||
|
alertify.success(gettext(res.info));
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
alertify.error(gettext('Unable to change owner.'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteUser: function() {
|
||||||
|
let self = this;
|
||||||
|
alertify.confirm(
|
||||||
|
gettext('Delete user?'),
|
||||||
|
gettext('Are you sure you wish to delete this user?'),
|
||||||
|
function() {
|
||||||
|
self.model.destroy({
|
||||||
|
wait: true,
|
||||||
|
success: function() {
|
||||||
|
alertify.success(gettext('User deleted.'));
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
alertify.error(
|
||||||
|
gettext('Error during deleting user.')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
deleteRow: function(e) {
|
deleteRow: function(e) {
|
||||||
var self = this;
|
var self = this;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -629,26 +845,27 @@ define([
|
|||||||
if (self.model.isNew()) {
|
if (self.model.isNew()) {
|
||||||
self.model.destroy();
|
self.model.destroy();
|
||||||
} else {
|
} else {
|
||||||
alertify.confirm(
|
if(self.model.get('role') == 1){
|
||||||
gettext('Delete user?'),
|
$.ajax({
|
||||||
gettext('Are you sure you wish to delete this user?'),
|
url: url_for('user_management.shared_servers', {'uid': self.model.get('id'),
|
||||||
function() {
|
}),
|
||||||
self.model.destroy({
|
method: 'GET',
|
||||||
wait: true,
|
async: false,
|
||||||
success: function() {
|
})
|
||||||
alertify.success(gettext('User deleted.'));
|
.done(function(res) {
|
||||||
},
|
if(res['data'].shared_servers > 0) {
|
||||||
error: function() {
|
self.changeOwnership(res, self.model.get('id'));
|
||||||
alertify.error(
|
} else {
|
||||||
gettext('Error during deleting user.')
|
self.deleteUser();
|
||||||
);
|
}
|
||||||
},
|
})
|
||||||
|
.fail(function() {
|
||||||
|
self.deleteUser();
|
||||||
});
|
});
|
||||||
},
|
} else {
|
||||||
function() {
|
self.deleteUser();
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alertify.alert(
|
alertify.alert(
|
||||||
|
|||||||
Reference in New Issue
Block a user