]> git.proxmox.com Git - pmg-gui.git/blobdiff - js/LDAPConfig.js
fix #2533: quarantine: add overflowHandler to the preview panel
[pmg-gui.git] / js / LDAPConfig.js
index cb20eada18539b6b0961a751da188f5ca9f0fd13..0a114ff4f50080422f84369925904713230268f0 100644 (file)
@@ -1,23 +1,26 @@
 Ext.define('pmg-ldap-config', {
     extend: 'Ext.data.Model',
-    fields: [ 'section', 'server1', 'server2', 'comment',
+    fields: ['profile', 'server1', 'server2', 'comment',
              'mode', 'binddn', 'bindpw', 'basedn', 'groupbasedn',
              'filter', 'accountattr', 'mailattr',
-             { name: 'port',  type: 'integer' },
-             { name: 'disable',  type: 'boolean' }
+             { name: 'port', type: 'integer' },
+             { name: 'gcount', type: 'integer' },
+             { name: 'mcount', type: 'integer' },
+             { name: 'ucount', type: 'integer' },
+             { name: 'disable', type: 'boolean' },
            ],
     proxy: {
         type: 'proxmox',
-       url: "/api2/json/config/ldap"
+       url: "/api2/json/config/ldap",
     },
-    idProperty: 'section'
+    idProperty: 'profile',
 });
 
 Ext.define('PMG.LDAPInputPanel', {
     extend: 'Proxmox.panel.InputPanel',
     alias: 'widget.pmgLDAPInputPanel',
 
-    sectionId: undefined,
+    profileId: undefined,
 
     onGetValues: function(values) {
        var me = this;
@@ -25,51 +28,72 @@ Ext.define('PMG.LDAPInputPanel', {
        values.disable = values.enable ? 0 : 1;
        delete values.enable;
 
+       // do not send empty password
+       if (values.bindpw === '') {
+           delete values.bindpw;
+       }
+
        return values;
     },
 
-    initComponent : function() {
+    initComponent: function() {
        var me = this;
 
        me.column1 = [
            {
-               xtype: me.sectionId ? 'displayfield' : 'textfield',
+               xtype: me.profileId ? 'displayfield' : 'textfield',
                fieldLabel: gettext('Profile Name'),
-               value: me.sectionId || '',
-               name: 'section',
+               value: me.profileId || '',
+               name: 'profile',
                vtype: 'StorageId',
-               allowBlank: false
+               allowBlank: false,
            },
            {
                xtype: 'proxmoxKVComboBox',
                name: 'mode',
                comboItems: [
                    ['ldap', PMG.Utils.format_ldap_protocol('ldap')],
-                   ['ldaps', PMG.Utils.format_ldap_protocol('ldaps')]
+                   ['ldaps', PMG.Utils.format_ldap_protocol('ldaps')],
+                   ['ldap+starttls', PMG.Utils.format_ldap_protocol('ldap+starttls')],
                ],
                value: 'ldap',
-               fieldLabel: gettext('Protocol')
+               fieldLabel: gettext('Protocol'),
+               listeners: {
+                   change: function(cb, value) {
+                       var isldap = value === 'ldap';
+                       me.down('field[name=verify]').setVisible(!isldap);
+                   },
+               },
+           },
+           {
+               xtype: 'proxmoxcheckbox',
+               name: 'verify',
+               fieldLabel: gettext('Verify Certificate'),
+               hidden: true,
+               uncheckedValue: 0,
+               value: 1,
+               checked: 1,
            },
            {
                xtype: 'textfield',
                fieldLabel: gettext('Server'),
                allowBlank: false,
-               vtype: 'IP64Address',
-               name: 'server1'
+               vtype: 'DnsOrIp',
+               name: 'server1',
            },
            {
                xtype: 'proxmoxtextfield',
                fieldLabel: gettext('Server'),
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
-               vtype: 'IP64Address',
-               name: 'server2'
+               deleteEmpty: !me.isCreate,
+               vtype: 'DnsOrIp',
+               name: 'server2',
            },
            {
                xtype: 'proxmoxintegerfield',
                name: 'port',
                emptyText: gettext('Default'),
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                minValue: 1,
                maxValue: 65535,
                fieldLabel: gettext('Port'),
@@ -78,15 +102,16 @@ Ext.define('PMG.LDAPInputPanel', {
                xtype: 'textfield',
                name: 'binddn',
                allowBlank: true,
-               fieldLabel: gettext('User name')
+               fieldLabel: gettext('User name'),
            },
            {
                xtype: 'textfield',
                inputType: 'password',
                allowBlank: true,
+               emptyText: gettext('Unchanged'),
                name: 'bindpw',
-               fieldLabel: gettext('Password')
-           }
+               fieldLabel: gettext('Password'),
+           },
        ];
 
        me.column2 = [
@@ -95,43 +120,50 @@ Ext.define('PMG.LDAPInputPanel', {
                name: 'enable',
                checked: true,
                uncheckedValue: 0,
-               fieldLabel: gettext('Enable')
+               fieldLabel: gettext('Enable'),
            },
            {
                xtype: 'proxmoxtextfield',
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                name: 'basedn',
-               fieldLabel: gettext('Base DN')
+               fieldLabel: gettext('Base DN'),
            },
            {
                xtype: 'proxmoxtextfield',
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                name: 'groupbasedn',
-               fieldLabel: gettext('Base DN for Groups')
+               fieldLabel: gettext('Base DN for Groups'),
            },
            {
                xtype: 'proxmoxtextfield',
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                name: 'mailattr',
-               fieldLabel: gettext('EMail attribute name(s)')
+               fieldLabel: gettext('EMail attribute name(s)'),
            },
            {
                xtype: 'proxmoxtextfield',
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                name: 'accountattr',
-               fieldLabel: gettext('Account attribute name')
+               fieldLabel: gettext('Account attribute name'),
            },
            {
                xtype: 'proxmoxtextfield',
                allowBlank: true,
-               deleteEmpty: me.create ? false : true,
+               deleteEmpty: !me.isCreate,
                name: 'filter',
-               fieldLabel: gettext('LDAP filter')
-           }
+               fieldLabel: gettext('LDAP filter'),
+           },
+           {
+               xtype: 'proxmoxtextfield',
+               allowBlank: true,
+               deleteEmpty: !me.isCreate,
+               name: 'groupclass',
+               fieldLabel: gettext('Group objectclass'),
+           },
        ];
 
        me.columnB = [
@@ -139,160 +171,445 @@ Ext.define('PMG.LDAPInputPanel', {
                xtype: 'textfield',
                fieldLabel: gettext('Comment'),
                allowBlank: true,
-               name: 'comment'
-           }
+               name: 'comment',
+           },
        ];
 
        me.callParent();
-    }
+    },
 });
 
 Ext.define('PMG.LDAPEdit', {
     extend: 'Proxmox.window.Edit',
     alias: 'widget.pmgLDAPEdit',
+    onlineHelp: 'pmgconfig_ldap',
 
     subject: 'LDAP Profile',
     isAdd: true,
 
-    initComponent : function() {
+    initComponent: function() {
        var me = this;
 
-       me.create = me.sectionId ? false : true;
+       me.isCreate = !me.profileId;
 
-       if (me.create) {
+       if (me.isCreate) {
             me.url = '/api2/extjs/config/ldap';
             me.method = 'POST';
        } else {
-            me.url = '/api2/extjs/config/ldap/' + me.sectionId;
+            me.url = '/api2/extjs/config/ldap/' + me.profileId + '/config';
             me.method = 'PUT';
        }
 
        var ipanel = Ext.create('PMG.LDAPInputPanel', {
-           create: me.create,
-           sectionId: me.sectionId
+           isCreate: me.isCreate,
+           profileId: me.profileId,
        });
 
-       me.items = [ ipanel ];
+       me.items = [ipanel];
 
        me.fieldDefaults = {
-           labelWidth: 150
+           labelWidth: 150,
        };
 
        me.callParent();
 
-       if (!me.create) {
+       if (!me.isCreate) {
            me.load({
-               success:  function(response, options) {
+               success: function(response, options) {
                    var values = response.result.data;
 
                    values.enable = values.disable ? 0 : 1;
+                   values.verify = !!values.verify;
                    ipanel.setValues(values);
-               }
+               },
            });
        }
-    }
+    },
 });
 
-Ext.define('PMG.LDAPConfig', {
-    extend: 'Ext.grid.GridPanel',
-    alias: ['widget.pmgLDAPConfig'],
+Ext.define('PMG.LDAPUserGrid', {
+    extend: 'Ext.grid.Panel',
+    xtype: 'pmgLDAPUserGrid',
 
-    initComponent : function() {
+    emptyText: gettext('No data in database'),
+    store: {
+       autoDestroy: true,
+       fields: ['dn', 'account', 'pmail'],
+       proxy: { type: 'proxmox' },
+       sorters: ['dn'],
+    },
+    columns: [
+       {
+           text: 'DN',
+           dataIndex: 'dn',
+           flex: 1,
+       },
+       {
+           text: gettext('Account'),
+           dataIndex: 'account',
+           flex: 1,
+       },
+       {
+           text: gettext('Primary E-Mail'),
+           dataIndex: 'pmail',
+           flex: 1,
+       },
+    ],
+
+    initComponent: function() {
        var me = this;
+       me.callParent();
+       if (me.url) {
+           me.getStore().getProxy().setUrl(me.url);
+           me.getStore().load();
+       }
+    },
+});
 
-       me.store = new Ext.data.Store({
-           model: 'pmg-ldap-config',
-           sorters: {
-               property: 'section',
-               order: 'DESC'
+Ext.define('PMG.LDAPConfig', {
+    extend: 'Ext.panel.Panel',
+    xtype: 'pmgLDAPConfig',
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       openUserList: function(grid, record) {
+           var name = this.getViewModel().get('name');
+           Ext.create('Ext.window.Window', {
+               title: Ext.String.format(gettext("Users of '{0}'"), record.data.dn),
+               modal: true,
+               width: 600,
+               height: 400,
+               layout: 'fit',
+               items: [{
+                   xtype: 'pmgLDAPUserGrid',
+                   border: false,
+                   url: '/api2/json/config/ldap/' + name + '/groups/' + encodeURIComponent(record.data.gid),
+               }],
+           }).show();
+       },
+
+       showUsers: function(button) {
+           var me = this;
+           var view = me.lookup('groupgrid');
+           var record = view.getSelection()[0];
+           me.openUserList(view, record);
+       },
+
+       openUserMails: function(grid, record) {
+           var name = this.getViewModel().get('name');
+           Ext.create('Ext.window.Window', {
+               title: Ext.String.format(gettext("E-Mail addresses of '{0}'"), record.data.dn),
+               modal: true,
+               width: 600,
+               height: 400,
+               layout: 'fit',
+               items: [{
+                   xtype: 'grid',
+                   border: false,
+                   store: {
+                       autoLoad: true,
+                       field: ['email', 'primary'],
+                       proxy: {
+                           type: 'proxmox',
+                           url: '/api2/json/config/ldap/' + name + '/users/' + encodeURIComponent(record.data.pmail),
+                       },
+                   },
+                   columns: [
+                       { dataIndex: 'email', text: gettext('E-Mail address'), flex: 1 },
+                   ],
+               }],
+           }).show();
+       },
+
+       showEmails: function(button) {
+           var me = this;
+           var view = me.lookup('usergrid');
+           var record = view.getSelection()[0];
+           me.openUserMails(view, record);
+       },
+
+       reload: function(grid) {
+           var me = this;
+           var selection = grid.getSelection();
+           me.showInfo(grid, selection);
+       },
+
+       showInfo: function(grid, selected) {
+           var me = this;
+           var viewModel = me.getViewModel();
+           if (selected[0]) {
+               var name = selected[0].data.profile;
+               viewModel.set('selected', true);
+               viewModel.set('name', name);
+
+               // set grid stores and load them
+               var gstore = me.lookup('groupgrid').getStore();
+               var ustore = me.lookup('usergrid').getStore();
+               gstore.getProxy().setUrl('/api2/json/config/ldap/' + name + '/groups');
+               ustore.getProxy().setUrl('/api2/json/config/ldap/' + name + '/users');
+               gstore.load();
+               ustore.load();
+           } else {
+               viewModel.set('selected', false);
            }
-       });
+       },
+
+       init: function(view) {
+           var me = this;
+           me.lookup('grid').relayEvents(view, ['activate']);
+           var groupgrid = me.lookup('groupgrid');
+           var usergrid = me.lookup('usergrid');
+
+           Proxmox.Utils.monStoreErrors(groupgrid, groupgrid.getStore(), true);
+           Proxmox.Utils.monStoreErrors(usergrid, usergrid.getStore(), true);
+       },
+
+       control: {
+           'grid[reference=grid]': {
+               selectionchange: 'showInfo',
+               load: 'reload',
+           },
+           'grid[reference=groupgrid]': {
+               itemdblclick: 'openUserList',
+           },
+           'grid[reference=usergrid]': {
+               itemdblclick: 'openUserMails',
+           },
+       },
+    },
 
-        var reload = function() {
-            me.store.load();
-        };
+    viewModel: {
+       data: {
+           name: '',
+           selected: false,
+       },
+    },
 
-       me.selModel = Ext.create('Ext.selection.RowModel', {});
+    layout: 'border',
+
+    items: [
+       {
+           region: 'center',
+           reference: 'grid',
+           xtype: 'pmgLDAPConfigGrid',
+           border: false,
+       },
+       {
+           xtype: 'tabpanel',
+           reference: 'data',
+           hidden: true,
+           height: '50%',
+           border: false,
+           split: true,
+           region: 'south',
+           bind: {
+               hidden: '{!selected}',
+           },
+           items: [
+               {
+                   xtype: 'grid',
+                   reference: 'groupgrid',
+                   border: false,
+                   emptyText: gettext('No data in database'),
+                   tbar: [{
+                       xtype: 'proxmoxButton',
+                       text: gettext('Show Users'),
+                       handler: 'showUsers',
+                       disabled: true,
+                   }],
+                   store: {
+                       fields: ['dn', 'gid'],
+                       proxy: { type: 'proxmox' },
+                       sorters: ['dn'],
+                   },
+                   bind: {
+                       title: Ext.String.format(gettext("Groups of '{0}'"), '{name}'),
+                   },
+                   columns: [
+                       {
+                           text: 'DN',
+                           dataIndex: 'dn',
+                           flex: 1,
+                       },
+                   ],
+               },
+               {
+                   xtype: 'pmgLDAPUserGrid',
+                   reference: 'usergrid',
+                   border: false,
+                   tbar: [{
+                       xtype: 'proxmoxButton',
+                       text: gettext('Show E-Mail addresses'),
+                       handler: 'showEmails',
+                       disabled: true,
+                   }],
+                   bind: {
+                       title: Ext.String.format(gettext("Users of '{0}'"), '{name}'),
+                   },
+               },
+           ],
+       },
+    ],
+
+});
+
+Ext.define('PMG.LDAPConfigGrid', {
+    extend: 'Ext.grid.GridPanel',
+    alias: 'widget.pmgLDAPConfigGrid',
 
-       var run_editor = function() {
-           var rec = me.selModel.getSelection()[0];
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       run_editor: function() {
+           var me = this;
+           var view = me.getView();
+           var rec = view.getSelection()[0];
            if (!rec) {
                return;
            }
 
            var win = Ext.createWidget('pmgLDAPEdit', {
-               sectionId: rec.data.section
+               profileId: rec.data.profile,
            });
+           win.on('destroy', me.reload, me);
            win.load();
-           win.on('destroy', reload);
            win.show();
-       };
+       },
 
-       me.tbar = [
-            {
-               xtype: 'proxmoxButton',
-               text: gettext('Edit'),
-               disabled: true,
-               selModel: me.selModel,
-               handler: run_editor
-            },
-            {
-               text: gettext('Create'),
-               handler: function() {
-                   var win = Ext.createWidget('pmgLDAPEdit', {});
-                   win.on('destroy', reload);
-                   win.show();
-               }
-           }
-       ];
-
-       Ext.apply(me, {
-
-           columns: [
-               {
-                   header: gettext('ID'),
-                   width: 200,
-                   sortable: true,
-                   dataIndex: 'section'
-               },
-               {
-                   header: gettext('Protocol'),
-                   sortable: true,
-                   dataIndex: 'mode',
-                   renderer: PMG.Utils.format_ldap_protocol
-               },
-               {
-                   header: gettext('Server'),
-                   sortable: true,
-                   dataIndex: 'server1',
-                   renderer: function(value, metaData, rec) {
-                       if (rec.data.server2) {
-                           return value + '<br>' + rec.data.server2;
-                       }
-                       return value;
-                   }
+       newProfile: function() {
+           var me = this;
+           var win = Ext.createWidget('pmgLDAPEdit', {});
+           win.on('destroy', me.reload, me);
+           win.show();
+       },
+
+
+       reload: function() {
+           let view = this.getView();
+           view.getStore().load();
+           view.fireEvent('load', view);
+       },
+
+       sync: function() {
+           var me = this;
+           var view = me.getView();
+           var rec = view.getSelection()[0];
+           Proxmox.Utils.API2Request({
+               url: '/config/ldap/' + rec.data.profile + '/sync',
+               method: 'POST',
+               waitMsgTarget: view,
+               callback: function() {
+                   me.reload();
                },
-               {
-                   header: gettext('Enabled'),
-                   width: 80,
-                   sortable: true,
-                   dataIndex: 'disable',
-                   renderer: Proxmox.Utils.format_neg_boolean
+               failure: function(response, opts) {
+                   Ext.Msg.alert(gettext('Error'), response.htmlStatus);
                },
-               {
-                   header: gettext('Comment'),
-                   sortable: false,
-                   renderer: Ext.String.htmlEncode,
-                   dataIndex: 'comment',
-                   flex: 1
+           });
+       },
+
+       init: function(view) {
+           var me = this;
+           Proxmox.Utils.monStoreErrors(view, view.getStore(), true);
+       },
+    },
+
+    store: {
+       model: 'pmg-ldap-config',
+       sorters: [{
+           property: 'profile',
+           direction: 'ASC',
+       }],
+    },
+
+    tbar: [
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Edit'),
+           disabled: true,
+           handler: 'run_editor',
+       },
+       {
+           text: gettext('Create'),
+           handler: 'newProfile',
+       },
+       {
+           xtype: 'proxmoxStdRemoveButton',
+           baseurl: '/config/ldap',
+           callback: 'reload',
+       },
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Synchronize'),
+           enableFn: function(rec) {
+               return !rec.data.disable;
+           },
+           disabled: true,
+           handler: 'sync',
+       },
+    ],
+
+    listeners: {
+       itemdblclick: 'run_editor',
+       activate: 'reload',
+    },
+
+    columns: [
+       {
+           header: gettext('Profile Name'),
+           sortable: true,
+           width: 120,
+           dataIndex: 'profile',
+       },
+       {
+           header: gettext('Protocol'),
+           sortable: true,
+           dataIndex: 'mode',
+           renderer: PMG.Utils.format_ldap_protocol,
+       },
+       {
+           header: gettext('Server'),
+           sortable: true,
+           dataIndex: 'server1',
+           renderer: function(value, metaData, rec) {
+               if (rec.data.server2) {
+                   return value + '<br>' + rec.data.server2;
                }
-           ],
-           listeners: {
-               itemdblclick: run_editor,
-               activate: reload
-           }
-       });
+               return value;
+           },
+       },
+       {
+           header: gettext('Enabled'),
+           width: 80,
+           sortable: true,
+           dataIndex: 'disable',
+           renderer: Proxmox.Utils.format_neg_boolean,
+       },
+       {
+           header: gettext('Comment'),
+           sortable: false,
+           renderer: Ext.String.htmlEncode,
+           dataIndex: 'comment',
+           flex: 1,
+       },
+       {
+           header: gettext('Accounts'),
+           width: 80,
+           sortable: true,
+           dataIndex: 'ucount',
+       },
+       {
+           header: gettext('Addresses'),
+           width: 80,
+           sortable: true,
+           dataIndex: 'mcount',
+       },
+       {
+           header: gettext('Groups'),
+           width: 80,
+           sortable: true,
+           dataIndex: 'gcount',
+       },
+    ],
 
-       me.callParent();
-    }
 });