mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added LDAP authentication support. Fixes #2186
This commit is contained in:
committed by
Akshay Joshi
parent
8ceeb39268
commit
f77aa3284f
@@ -74,7 +74,8 @@ class UserManagementModule(PgAdminModule):
|
||||
'user_management.roles', 'user_management.role',
|
||||
'user_management.update_user', 'user_management.delete_user',
|
||||
'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'
|
||||
]
|
||||
|
||||
|
||||
@@ -100,7 +101,7 @@ def validate_user(data):
|
||||
else:
|
||||
raise Exception(_("Passwords do not match."))
|
||||
|
||||
if 'email' in data and data['email'] != "":
|
||||
if 'email' in data and data['email'] and data['email'] != "":
|
||||
if email_filter.match(data['email']):
|
||||
new_data['email'] = data['email']
|
||||
else:
|
||||
@@ -112,6 +113,12 @@ def validate_user(data):
|
||||
if 'active' in data and data['active'] != "":
|
||||
new_data['active'] = data['active']
|
||||
|
||||
if 'username' in data and data['username'] != "":
|
||||
new_data['username'] = data['username']
|
||||
|
||||
if 'auth_source' in data and data['auth_source'] != "":
|
||||
new_data['auth_source'] = data['auth_source']
|
||||
|
||||
return new_data
|
||||
|
||||
|
||||
@@ -140,6 +147,7 @@ def script():
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
def current_user_info():
|
||||
|
||||
return Response(
|
||||
response=render_template(
|
||||
"user_management/js/current_user.js",
|
||||
@@ -148,13 +156,15 @@ def current_user_info():
|
||||
user_id=current_user.id,
|
||||
email=current_user.email,
|
||||
name=(
|
||||
current_user.email.split('@')[0] if config.SERVER_MODE is True
|
||||
current_user.username.split('@')[0] if
|
||||
config.SERVER_MODE is True
|
||||
else 'postgres'
|
||||
),
|
||||
allow_save_password='true' if config.ALLOW_SAVE_PASSWORD
|
||||
else 'false',
|
||||
allow_save_tunnel_password='true'
|
||||
if config.ALLOW_SAVE_TUNNEL_PASSWORD else 'false',
|
||||
auth_sources=config.AUTHENTICATION_SOURCES,
|
||||
),
|
||||
status=200,
|
||||
mimetype="application/javascript"
|
||||
@@ -180,9 +190,11 @@ def user(uid):
|
||||
u = User.query.get(uid)
|
||||
|
||||
res = {'id': u.id,
|
||||
'username': u.username,
|
||||
'email': u.email,
|
||||
'active': u.active,
|
||||
'role': u.roles[0].id
|
||||
'role': u.roles[0].id,
|
||||
'auth_source': u.auth_source
|
||||
}
|
||||
else:
|
||||
users = User.query.all()
|
||||
@@ -190,9 +202,11 @@ def user(uid):
|
||||
users_data = []
|
||||
for u in users:
|
||||
users_data.append({'id': u.id,
|
||||
'username': u.username,
|
||||
'email': u.email,
|
||||
'active': u.active,
|
||||
'role': u.roles[0].id
|
||||
'role': u.roles[0].id,
|
||||
'auth_source': u.auth_source
|
||||
})
|
||||
|
||||
res = users_data
|
||||
@@ -215,11 +229,29 @@ def create():
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
|
||||
for f in ('email', 'role', 'active', 'newPassword', 'confirmPassword'):
|
||||
status, res = create_user(data)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return ajax_response(
|
||||
response=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
|
||||
def create_user(data):
|
||||
if 'auth_source' in data and data['auth_source'] != 'internal':
|
||||
req_params = ('username', 'role', 'active', 'auth_source')
|
||||
else:
|
||||
req_params = ('email', 'role', 'active', 'newPassword',
|
||||
'confirmPassword')
|
||||
|
||||
for f in req_params:
|
||||
if f in data and data[f] != '':
|
||||
continue
|
||||
else:
|
||||
return bad_request(errormsg=_("Missing field: '{0}'".format(f)))
|
||||
return False, _("Missing field: '{0}'".format(f))
|
||||
|
||||
try:
|
||||
new_data = validate_user(data)
|
||||
@@ -228,13 +260,23 @@ def create():
|
||||
new_data['roles'] = [Role.query.get(new_data['roles'])]
|
||||
|
||||
except Exception as e:
|
||||
return bad_request(errormsg=_(str(e)))
|
||||
return False, str(e)
|
||||
|
||||
try:
|
||||
usr = User(email=new_data['email'],
|
||||
|
||||
username = new_data['username'] if 'username' in new_data \
|
||||
else new_data['email']
|
||||
email = new_data['email'] if 'email' in new_data else None
|
||||
password = new_data['password'] if 'password' in new_data else None
|
||||
auth_source = new_data['auth_source'] if 'auth_source' in new_data \
|
||||
else current_app.PGADMIN_DEFAULT_AUTH_SOURCE
|
||||
|
||||
usr = User(username=username,
|
||||
email=email,
|
||||
roles=new_data['roles'],
|
||||
active=new_data['active'],
|
||||
password=new_data['password'])
|
||||
password=password,
|
||||
auth_source=auth_source)
|
||||
db.session.add(usr)
|
||||
db.session.commit()
|
||||
# Add default server group for new user.
|
||||
@@ -242,18 +284,15 @@ def create():
|
||||
db.session.add(server_group)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
return False, str(e)
|
||||
|
||||
res = {'id': usr.id,
|
||||
'email': usr.email,
|
||||
'active': usr.active,
|
||||
'role': usr.roles[0].id
|
||||
}
|
||||
|
||||
return ajax_response(
|
||||
response=res,
|
||||
status=200
|
||||
)
|
||||
return True, {
|
||||
'id': usr.id,
|
||||
'username': usr.username,
|
||||
'email': usr.email,
|
||||
'active': usr.active,
|
||||
'role': usr.roles[0].id
|
||||
}
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
@@ -337,9 +376,11 @@ def update(uid):
|
||||
db.session.commit()
|
||||
|
||||
res = {'id': usr.id,
|
||||
'username': usr.username,
|
||||
'email': usr.email,
|
||||
'active': usr.active,
|
||||
'role': usr.roles[0].id
|
||||
'role': usr.roles[0].id,
|
||||
'auth_source': usr.auth_source
|
||||
}
|
||||
|
||||
return ajax_response(
|
||||
@@ -384,3 +425,17 @@ def role(rid):
|
||||
response=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/auth_sources/', methods=['GET'], endpoint='auth_sources'
|
||||
)
|
||||
def auth_sources():
|
||||
sources = []
|
||||
for source in current_app.PGADMIN_SUPPORTED_AUTH_SOURCE:
|
||||
sources.append({'label': source, 'value': source})
|
||||
|
||||
return ajax_response(
|
||||
response=sources,
|
||||
status=200
|
||||
)
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'pgadmin.alertifyjs',
|
||||
'pgadmin.browser', 'backbone', 'backgrid', 'backform', 'pgadmin.browser.node',
|
||||
'pgadmin.browser', 'backbone', 'backgrid', 'backform', 'pgadmin.browser.node', 'pgadmin.backform',
|
||||
'pgadmin.user_management.current_user',
|
||||
'backgrid.select.all', 'backgrid.filter',
|
||||
], function(
|
||||
gettext, url_for, $, _, alertify, pgBrowser, Backbone, Backgrid, Backform,
|
||||
pgNode, userInfo
|
||||
pgNode, pgBackform, userInfo
|
||||
) {
|
||||
|
||||
// if module is already initialized, refer to that.
|
||||
@@ -24,6 +24,8 @@ define([
|
||||
|
||||
var USERURL = url_for('user_management.users'),
|
||||
ROLEURL = url_for('user_management.roles'),
|
||||
SOURCEURL = url_for('user_management.auth_sources'),
|
||||
AUTH_ONLY_INTERNAL = (userInfo['auth_sources'].length == 1 && userInfo['auth_sources'].includes('internal')) ? true : false,
|
||||
userFilter = function(collection) {
|
||||
return (new Backgrid.Extension.ClientSideFilter({
|
||||
collection: collection,
|
||||
@@ -33,6 +35,41 @@ define([
|
||||
}));
|
||||
};
|
||||
|
||||
// Integer Cell for Columns Length and Precision
|
||||
var PasswordDepCell = Backgrid.Extension.PasswordDepCell =
|
||||
Backgrid.Extension.PasswordCell.extend({
|
||||
initialize: function() {
|
||||
Backgrid.Extension.PasswordCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
dependentChanged: function () {
|
||||
this.$el.empty();
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get('editable'),
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
|
||||
if (is_editable){ this.$el.addClass('editable'); }
|
||||
else { this.$el.removeClass('editable'); }
|
||||
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
render: function() {
|
||||
Backgrid.NumberCell.prototype.render.apply(this, arguments);
|
||||
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
editable = this.column.get('editable'),
|
||||
is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
|
||||
|
||||
if (is_editable){ this.$el.addClass('editable'); }
|
||||
else { this.$el.removeClass('editable'); }
|
||||
return this;
|
||||
},
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove,
|
||||
});
|
||||
|
||||
pgBrowser.UserManagement = {
|
||||
init: function() {
|
||||
if (this.initialized)
|
||||
@@ -235,20 +272,67 @@ define([
|
||||
// Callback to draw User Management Dialog.
|
||||
show_users: function() {
|
||||
if (!userInfo['is_admin']) return;
|
||||
var Roles = [];
|
||||
var Roles = [],
|
||||
Sources = [];
|
||||
|
||||
var UserModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'id',
|
||||
urlRoot: USERURL,
|
||||
defaults: {
|
||||
id: undefined,
|
||||
username: undefined,
|
||||
email: undefined,
|
||||
active: true,
|
||||
role: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined,
|
||||
auth_source: 'internal',
|
||||
authOnlyInternal: AUTH_ONLY_INTERNAL,
|
||||
},
|
||||
schema: [{
|
||||
id: 'auth_source',
|
||||
label: gettext('Authentication Source'),
|
||||
type: 'text',
|
||||
control: 'Select2',
|
||||
url: url_for('user_management.auth_sources'),
|
||||
cellHeaderClasses: 'width_percent_30',
|
||||
visible: function(m) {
|
||||
if (m.get('authOnlyInternal')) return false;
|
||||
return true;
|
||||
},
|
||||
disabled: false,
|
||||
cell: 'Select2',
|
||||
select2: {
|
||||
allowClear: false,
|
||||
openOnEnter: false,
|
||||
first_empty: false,
|
||||
},
|
||||
options: function() {
|
||||
return Sources;
|
||||
},
|
||||
editable: function(m) {
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return true;
|
||||
}
|
||||
if (m.isNew() && !m.get('authOnlyInternal')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}, {
|
||||
id: 'username',
|
||||
label: gettext('Username'),
|
||||
type: 'text',
|
||||
cell: Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_30',
|
||||
deps: ['auth_source'],
|
||||
editable: function(m) {
|
||||
if (m.get('authOnlyInternal') || m.get('auth_source') == 'internal') return false;
|
||||
return true;
|
||||
},
|
||||
disabled: false,
|
||||
}, {
|
||||
id: 'email',
|
||||
label: gettext('Email'),
|
||||
type: 'text',
|
||||
@@ -256,6 +340,8 @@ define([
|
||||
cellHeaderClasses: 'width_percent_30',
|
||||
deps: ['id'],
|
||||
editable: function(m) {
|
||||
if (!m.get('authOnlyInternal')) return true;
|
||||
|
||||
if (m instanceof Backbone.Collection) {
|
||||
return false;
|
||||
}
|
||||
@@ -328,23 +414,39 @@ define([
|
||||
type: 'password',
|
||||
disabled: false,
|
||||
control: 'input',
|
||||
cell: 'password',
|
||||
cell: PasswordDepCell,
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
deps: ['auth_source'],
|
||||
editable: function(m) {
|
||||
if (m.get('auth_source') == 'internal') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}, {
|
||||
id: 'confirmPassword',
|
||||
label: gettext('Confirm password'),
|
||||
type: 'password',
|
||||
disabled: false,
|
||||
control: 'input',
|
||||
cell: 'password',
|
||||
cell: PasswordDepCell,
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
deps: ['auth_source'],
|
||||
editable: function(m) {
|
||||
if (m.get('auth_source') == 'internal') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}],
|
||||
validate: function() {
|
||||
var errmsg = null,
|
||||
changedAttrs = this.changed || {},
|
||||
email_filter = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
||||
|
||||
if (('email' in changedAttrs || !this.isNew()) && (_.isUndefined(this.get('email')) ||
|
||||
if (this.get('auth_source') == 'internal' && ('email' in changedAttrs || !this.isNew()) && (_.isUndefined(this.get('email')) ||
|
||||
_.isNull(this.get('email')) ||
|
||||
String(this.get('email')).replace(/^\s+|\s+$/g, '') == '')) {
|
||||
errmsg = gettext('Email address cannot be empty.');
|
||||
@@ -358,9 +460,8 @@ define([
|
||||
this.errorModel.set('email', errmsg);
|
||||
return errmsg;
|
||||
} else if (!!this.get('email') && this.collection.where({
|
||||
'email': this.get('email'),
|
||||
'email': this.get('email'), 'auth_source': 'internal',
|
||||
}).length > 1) {
|
||||
|
||||
errmsg = gettext('The email address %s already exists.',
|
||||
this.get('email')
|
||||
);
|
||||
@@ -385,111 +486,113 @@ define([
|
||||
this.errorModel.unset('role');
|
||||
}
|
||||
|
||||
if (this.isNew()) {
|
||||
// Password is compulsory for new user.
|
||||
if ('newPassword' in changedAttrs && (_.isUndefined(this.get('newPassword')) ||
|
||||
_.isNull(this.get('newPassword')) ||
|
||||
this.get('newPassword') == '')) {
|
||||
if (this.get('auth_source') == 'internal') {
|
||||
if (this.isNew()) {
|
||||
// Password is compulsory for new user.
|
||||
if ('newPassword' in changedAttrs && (_.isUndefined(this.get('newPassword')) ||
|
||||
_.isNull(this.get('newPassword')) ||
|
||||
this.get('newPassword') == '')) {
|
||||
|
||||
errmsg = gettext('Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
errmsg = gettext('Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (!_.isUndefined(this.get('newPassword')) &&
|
||||
!_.isNull(this.get('newPassword')) &&
|
||||
this.get('newPassword').length < 6) {
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (!_.isUndefined(this.get('newPassword')) &&
|
||||
!_.isNull(this.get('newPassword')) &&
|
||||
this.get('newPassword').length < 6) {
|
||||
|
||||
errmsg = gettext('Password must be at least 6 characters for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
errmsg = gettext('Password must be at least 6 characters for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('newPassword');
|
||||
}
|
||||
|
||||
if ('confirmPassword' in changedAttrs && (_.isUndefined(this.get('confirmPassword')) ||
|
||||
_.isNull(this.get('confirmPassword')) ||
|
||||
this.get('confirmPassword') == '')) {
|
||||
|
||||
errmsg = gettext('Confirm Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
|
||||
if (!!this.get('newPassword') && !!this.get('confirmPassword') &&
|
||||
this.get('newPassword') != this.get('confirmPassword')) {
|
||||
|
||||
errmsg = gettext('Passwords do not match for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('newPassword');
|
||||
}
|
||||
if ((_.isUndefined(this.get('newPassword')) || _.isNull(this.get('newPassword')) ||
|
||||
this.get('newPassword') == '') &&
|
||||
((_.isUndefined(this.get('confirmPassword')) || _.isNull(this.get('confirmPassword')) ||
|
||||
this.get('confirmPassword') == ''))) {
|
||||
|
||||
if ('confirmPassword' in changedAttrs && (_.isUndefined(this.get('confirmPassword')) ||
|
||||
this.errorModel.unset('newPassword');
|
||||
if (this.get('newPassword') == '') {
|
||||
this.set({
|
||||
'newPassword': undefined,
|
||||
});
|
||||
}
|
||||
|
||||
this.errorModel.unset('confirmPassword');
|
||||
if (this.get('confirmPassword') == '') {
|
||||
this.set({
|
||||
'confirmPassword': undefined,
|
||||
});
|
||||
}
|
||||
} else if (!_.isUndefined(this.get('newPassword')) &&
|
||||
!_.isNull(this.get('newPassword')) &&
|
||||
!this.get('newPassword') == '' &&
|
||||
this.get('newPassword').length < 6) {
|
||||
|
||||
errmsg = gettext('Password must be at least 6 characters for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (_.isUndefined(this.get('confirmPassword')) ||
|
||||
_.isNull(this.get('confirmPassword')) ||
|
||||
this.get('confirmPassword') == '')) {
|
||||
this.get('confirmPassword') == '') {
|
||||
|
||||
errmsg = gettext('Confirm Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
errmsg = gettext('Confirm Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (!!this.get('newPassword') && !!this.get('confirmPassword') &&
|
||||
this.get('newPassword') != this.get('confirmPassword')) {
|
||||
|
||||
if (!!this.get('newPassword') && !!this.get('confirmPassword') &&
|
||||
this.get('newPassword') != this.get('confirmPassword')) {
|
||||
errmsg = gettext('Passwords do not match for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
errmsg = gettext('Passwords do not match for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((_.isUndefined(this.get('newPassword')) || _.isNull(this.get('newPassword')) ||
|
||||
this.get('newPassword') == '') &&
|
||||
((_.isUndefined(this.get('confirmPassword')) || _.isNull(this.get('confirmPassword')) ||
|
||||
this.get('confirmPassword') == ''))) {
|
||||
|
||||
this.errorModel.unset('newPassword');
|
||||
if (this.get('newPassword') == '') {
|
||||
this.set({
|
||||
'newPassword': undefined,
|
||||
});
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('newPassword');
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
|
||||
this.errorModel.unset('confirmPassword');
|
||||
if (this.get('confirmPassword') == '') {
|
||||
this.set({
|
||||
'confirmPassword': undefined,
|
||||
});
|
||||
}
|
||||
} else if (!_.isUndefined(this.get('newPassword')) &&
|
||||
!_.isNull(this.get('newPassword')) &&
|
||||
!this.get('newPassword') == '' &&
|
||||
this.get('newPassword').length < 6) {
|
||||
|
||||
errmsg = gettext('Password must be at least 6 characters for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('newPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (_.isUndefined(this.get('confirmPassword')) ||
|
||||
_.isNull(this.get('confirmPassword')) ||
|
||||
this.get('confirmPassword') == '') {
|
||||
|
||||
errmsg = gettext('Confirm Password cannot be empty for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else if (!!this.get('newPassword') && !!this.get('confirmPassword') &&
|
||||
this.get('newPassword') != this.get('confirmPassword')) {
|
||||
|
||||
errmsg = gettext('Passwords do not match for user %s.',
|
||||
(this.get('email') || '')
|
||||
);
|
||||
|
||||
this.errorModel.set('confirmPassword', errmsg);
|
||||
return errmsg;
|
||||
} else {
|
||||
this.errorModel.unset('newPassword');
|
||||
this.errorModel.unset('confirmPassword');
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -716,7 +819,10 @@ define([
|
||||
saveUser: function(m) {
|
||||
var d = m.toJSON(true);
|
||||
|
||||
if (m.isNew() && (!m.get('email') || !m.get('role') ||
|
||||
if(m.isNew() && m.get('authOnlyInternal') === false &&
|
||||
(!m.get('username') || !m.get('auth_source') || !m.get('role')) ) {
|
||||
return false;
|
||||
} else if (m.isNew() && m.get('authOnlyInternal') === true && (!m.get('email') || !m.get('role') ||
|
||||
!m.get('newPassword') || !m.get('confirmPassword') ||
|
||||
m.get('newPassword') != m.get('confirmPassword'))) {
|
||||
// New user model is valid but partially filled so return without saving.
|
||||
@@ -741,7 +847,7 @@ define([
|
||||
|
||||
m.startNewSession();
|
||||
alertify.success(gettext('User \'%s\' saved.',
|
||||
m.get('email')
|
||||
m.get('username')
|
||||
));
|
||||
},
|
||||
error: function(res, jqxhr) {
|
||||
@@ -797,6 +903,23 @@ define([
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: SOURCEURL,
|
||||
method: 'GET',
|
||||
async: false,
|
||||
})
|
||||
.done(function(res) {
|
||||
Sources = res;
|
||||
})
|
||||
.fail(function() {
|
||||
setTimeout(function() {
|
||||
alertify.alert(
|
||||
gettext('Error'),
|
||||
gettext('Cannot load user Sources.')
|
||||
);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
var view = this.view = new Backgrid.Grid({
|
||||
row: UserRow,
|
||||
columns: gridSchema.columns,
|
||||
|
||||
@@ -14,6 +14,7 @@ define('pgadmin.user_management.current_user', [], function() {
|
||||
'is_admin': {{ is_admin }},
|
||||
'name': '{{ name }}',
|
||||
'allow_save_password': {{ allow_save_password }},
|
||||
'allow_save_tunnel_password': {{ allow_save_tunnel_password }}
|
||||
'allow_save_tunnel_password': {{ allow_save_tunnel_password }},
|
||||
'auth_sources': {{ auth_sources }}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user