auth ui: add LDAP realm edit panel

The panel was mostly taken from from PVE, but altered slightly:
  - bind-dn and bind-password are displayed under "General"
    and not under "Sync". For some servers, we need to be bound
    to lookup a user's domain from a given user id attribute.
    In PVE, the bind-dn and bind-password fields are under
    "Sync", which is a bit confusing if a user is not interested
    in automatic user syncing.

  - There is a 'anonymous search' checkbox. The value is not persisted
    in the configuration, it merely enables/disables the
    bind-dn and bind-password fiels to make their intent a bit more
    clear.

  - Instead of a 'secure' checkbox, a combobox for TLS mode is shown.
    This way users can select between LDAP, STARTLS and LDAPS.
    In PVE, the 'secure' config parameter is deprecated anyway, so
    I took the opportunity to replace it with the 'mode' parameter
    as described.

  - Parameters now consistently use kebab-case for naming. If
    PVE is modified to use the same panel, some sort of adapter
    will be needed.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
This commit is contained in:
Lukas Wagner 2023-03-17 09:47:18 +01:00 committed by Thomas Lamprecht
parent 64f65c027d
commit aa5cbdbb32
3 changed files with 203 additions and 0 deletions

View File

@ -84,6 +84,7 @@ JSSRC= \
window/FileBrowser.js \ window/FileBrowser.js \
window/AuthEditBase.js \ window/AuthEditBase.js \
window/AuthEditOpenId.js \ window/AuthEditOpenId.js \
window/AuthEditLDAP.js \
window/TfaWindow.js \ window/TfaWindow.js \
window/AddTfaRecovery.js \ window/AddTfaRecovery.js \
window/AddTotp.js \ window/AddTotp.js \

View File

@ -17,6 +17,14 @@ Ext.define('Proxmox.Schema', { // a singleton
pwchange: false, pwchange: false,
iconCls: 'pmx-itype-icon-openid-logo', iconCls: 'pmx-itype-icon-openid-logo',
}, },
ldap: {
name: gettext('LDAP Server'),
ipanel: 'pmxAuthLDAPPanel',
add: true,
edit: true,
tfa: true,
pwchange: false,
},
}, },
// to add or change existing for product specific ones // to add or change existing for product specific ones
overrideAuthDomains: function(extra) { overrideAuthDomains: function(extra) {

194
src/window/AuthEditLDAP.js Normal file
View File

@ -0,0 +1,194 @@
Ext.define('Proxmox.panel.LDAPInputPanelViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.pmxAuthLDAPPanel',
data: {
mode: 'ldap',
anonymous_search: 1,
},
formulas: {
tls_enabled: function(get) {
return get('mode') !== 'ldap';
},
},
});
Ext.define('Proxmox.panel.LDAPInputPanel', {
extend: 'Proxmox.panel.InputPanel',
xtype: 'pmxAuthLDAPPanel',
mixins: ['Proxmox.Mixin.CBind'],
viewModel: {
type: 'pmxAuthLDAPPanel',
},
type: 'ldap',
onGetValues: function(values) {
if (this.isCreate) {
values.type = this.type;
}
if (values.anonymous_search) {
if (!values.delete) {
values.delete = [];
}
if (!Array.isArray(values.delete)) {
let tmp = values.delete;
values.delete = [];
values.delete.push(tmp);
}
values.delete.push("bind-dn");
values.delete.push("password");
}
delete values.anonymous_search;
return values;
},
onSetValues: function(values) {
values.anonymous_search = values["bind-dn"] ? 0 : 1;
return values;
},
column1: [
{
xtype: 'pmxDisplayEditField',
name: 'realm',
cbind: {
value: '{realm}',
editable: '{isCreate}',
},
fieldLabel: gettext('Realm'),
allowBlank: false,
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Base Domain Name'),
name: 'base-dn',
allowBlank: false,
emptyText: 'cn=Users,dc=company,dc=net',
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('User Attribute Name'),
name: 'user-attr',
allowBlank: false,
emptyText: 'uid / sAMAccountName',
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: gettext('Anonymous Search'),
name: 'anonymous_search',
bind: '{anonymous_search}',
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Bind Domain Name'),
name: 'bind-dn',
allowBlank: false,
emptyText: 'cn=user,dc=company,dc=net',
bind: {
disabled: "{anonymous_search}",
},
},
{
xtype: 'proxmoxtextfield',
inputType: 'password',
fieldLabel: gettext('Bind Password'),
name: 'password',
allowBlank: true,
cbind: {
emptyText: get => !get('isCreate') ? gettext('Unchanged') : '',
},
bind: {
disabled: "{anonymous_search}",
},
},
],
column2: [
{
xtype: 'proxmoxtextfield',
name: 'server1',
fieldLabel: gettext('Server'),
allowBlank: false,
},
{
xtype: 'proxmoxtextfield',
name: 'server2',
fieldLabel: gettext('Fallback Server'),
submitEmpty: false,
cbind: {
deleteEmpty: '{!isCreate}',
},
},
{
xtype: 'proxmoxintegerfield',
name: 'port',
fieldLabel: gettext('Port'),
minValue: 1,
maxValue: 65535,
emptyText: gettext('Default'),
submitEmptyText: false,
deleteEmpty: true,
},
{
xtype: 'proxmoxKVComboBox',
name: 'mode',
fieldLabel: gettext('Mode'),
editable: false,
comboItems: [
['ldap', 'LDAP'],
['ldap+starttls', 'STARTTLS'],
['ldaps', 'LDAPS'],
],
bind: "{mode}",
cbind: {
deleteEmpty: '{!isCreate}',
value: get => get('isCreate') ? 'ldap' : 'LDAP',
},
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: gettext('Verify Certificate'),
name: 'verify',
value: 0,
cbind: {
deleteEmpty: '{!isCreate}',
},
bind: {
disabled: '{!tls_enabled}',
},
autoEl: {
tag: 'div',
'data-qtip': gettext('Verify TLS certificate of the server'),
},
},
],
columnB: [
{
xtype: 'textfield',
name: 'comment',
fieldLabel: gettext('Comment'),
cbind: {
deleteEmpty: '{!isCreate}',
},
},
],
});