]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/AuthEditLDAP.js
window: ldap: add tooltips for firstname, lastname and email attributes
[proxmox-widget-toolkit.git] / src / window / AuthEditLDAP.js
1
2 Ext.define('Proxmox.panel.LDAPInputPanelViewModel', {
3 extend: 'Ext.app.ViewModel',
4
5 alias: 'viewmodel.pmxAuthLDAPPanel',
6
7 data: {
8 mode: 'ldap',
9 anonymous_search: 1,
10 },
11
12 formulas: {
13 tls_enabled: function(get) {
14 return get('mode') !== 'ldap';
15 },
16 },
17
18 });
19
20
21 Ext.define('Proxmox.panel.LDAPInputPanel', {
22 extend: 'Proxmox.panel.InputPanel',
23 xtype: 'pmxAuthLDAPPanel',
24 mixins: ['Proxmox.Mixin.CBind'],
25
26 viewModel: {
27 type: 'pmxAuthLDAPPanel',
28 },
29
30 type: 'ldap',
31
32 onlineHelp: 'user-realms-ldap',
33
34 onGetValues: function(values) {
35 if (this.isCreate) {
36 values.type = this.type;
37 }
38
39 if (values.anonymous_search) {
40 if (!values.delete) {
41 values.delete = [];
42 }
43
44 if (!Array.isArray(values.delete)) {
45 let tmp = values.delete;
46 values.delete = [];
47 values.delete.push(tmp);
48 }
49
50 values.delete.push("bind-dn");
51 values.delete.push("password");
52 }
53
54 delete values.anonymous_search;
55
56 return values;
57 },
58
59 onSetValues: function(values) {
60 let me = this;
61 values.anonymous_search = values["bind-dn"] ? 0 : 1;
62 me.getViewModel().set('anonymous_search', values.anonymous_search);
63
64 return values;
65 },
66
67 cbindData: function(config) {
68 return {
69 isLdap: this.type === 'ldap',
70 isAd: this.type === 'ad',
71 };
72 },
73
74 column1: [
75 {
76 xtype: 'pmxDisplayEditField',
77 name: 'realm',
78 cbind: {
79 value: '{realm}',
80 editable: '{isCreate}',
81 },
82 fieldLabel: gettext('Realm'),
83 allowBlank: false,
84 },
85 {
86 xtype: 'proxmoxtextfield',
87 fieldLabel: gettext('Base Domain Name'),
88 name: 'base-dn',
89 emptyText: 'cn=Users,dc=company,dc=net',
90 cbind: {
91 hidden: '{!isLdap}',
92 allowBlank: '{!isLdap}',
93 },
94 },
95 {
96 xtype: 'proxmoxtextfield',
97 fieldLabel: gettext('User Attribute Name'),
98 name: 'user-attr',
99 emptyText: 'uid / sAMAccountName',
100 cbind: {
101 hidden: '{!isLdap}',
102 allowBlank: '{!isLdap}',
103 },
104 },
105 {
106 xtype: 'proxmoxcheckbox',
107 fieldLabel: gettext('Anonymous Search'),
108 name: 'anonymous_search',
109 bind: {
110 value: '{anonymous_search}',
111 },
112 },
113 {
114 xtype: 'proxmoxtextfield',
115 fieldLabel: gettext('Bind Domain Name'),
116 name: 'bind-dn',
117 allowBlank: false,
118 cbind: {
119 emptyText: get => get('isAd') ? 'user@company.net' : 'cn=user,dc=company,dc=net',
120 autoEl: get => get('isAd') ? {
121 tag: 'div',
122 'data-qtip':
123 gettext('LDAP DN syntax can be used as well, e.g. cn=user,dc=company,dc=net'),
124 } : {},
125 },
126 bind: {
127 disabled: "{anonymous_search}",
128 },
129 },
130 {
131 xtype: 'proxmoxtextfield',
132 inputType: 'password',
133 fieldLabel: gettext('Bind Password'),
134 name: 'password',
135 cbind: {
136 emptyText: get => !get('isCreate') ? gettext('Unchanged') : '',
137 allowBlank: '{!isCreate}',
138 },
139 bind: {
140 disabled: "{anonymous_search}",
141 },
142 },
143 ],
144
145 column2: [
146 {
147 xtype: 'proxmoxtextfield',
148 name: 'server1',
149 fieldLabel: gettext('Server'),
150 allowBlank: false,
151 },
152 {
153 xtype: 'proxmoxtextfield',
154 name: 'server2',
155 fieldLabel: gettext('Fallback Server'),
156 submitEmpty: false,
157 cbind: {
158 deleteEmpty: '{!isCreate}',
159 },
160 },
161 {
162 xtype: 'proxmoxintegerfield',
163 name: 'port',
164 fieldLabel: gettext('Port'),
165 minValue: 1,
166 maxValue: 65535,
167 emptyText: gettext('Default'),
168 submitEmptyText: false,
169 deleteEmpty: true,
170 },
171 {
172 xtype: 'proxmoxKVComboBox',
173 name: 'mode',
174 fieldLabel: gettext('Mode'),
175 editable: false,
176 comboItems: [
177 ['ldap', 'LDAP'],
178 ['ldap+starttls', 'STARTTLS'],
179 ['ldaps', 'LDAPS'],
180 ],
181 bind: "{mode}",
182 cbind: {
183 deleteEmpty: '{!isCreate}',
184 value: get => get('isCreate') ? 'ldap' : 'LDAP',
185 },
186 },
187 {
188 xtype: 'proxmoxcheckbox',
189 fieldLabel: gettext('Verify Certificate'),
190 name: 'verify',
191 value: 0,
192 cbind: {
193 deleteEmpty: '{!isCreate}',
194 },
195
196 bind: {
197 disabled: '{!tls_enabled}',
198 },
199 autoEl: {
200 tag: 'div',
201 'data-qtip': gettext('Verify TLS certificate of the server'),
202 },
203
204 },
205 ],
206
207 columnB: [
208 {
209 xtype: 'proxmoxtextfield',
210 name: 'comment',
211 fieldLabel: gettext('Comment'),
212 cbind: {
213 deleteEmpty: '{!isCreate}',
214 },
215 },
216 ],
217
218 });
219
220
221 Ext.define('Proxmox.panel.LDAPSyncInputPanel', {
222 extend: 'Proxmox.panel.InputPanel',
223 xtype: 'pmxAuthLDAPSyncPanel',
224 mixins: ['Proxmox.Mixin.CBind'],
225
226 editableAttributes: ['firstname', 'lastname', 'email'],
227 editableDefaults: ['scope', 'enable-new'],
228 default_opts: {},
229 sync_attributes: {},
230
231 type: 'ldap',
232
233 // (de)construct the sync-attributes from the list above,
234 // not touching all others
235 onGetValues: function(values) {
236 let me = this;
237
238 me.editableDefaults.forEach((attr) => {
239 if (values[attr]) {
240 me.default_opts[attr] = values[attr];
241 delete values[attr];
242 } else {
243 delete me.default_opts[attr];
244 }
245 });
246 let vanished_opts = [];
247 ['acl', 'entry', 'properties'].forEach((prop) => {
248 if (values[`remove-vanished-${prop}`]) {
249 vanished_opts.push(prop);
250 }
251 delete values[`remove-vanished-${prop}`];
252 });
253 me.default_opts['remove-vanished'] = vanished_opts.join(';');
254
255 values['sync-defaults-options'] = Proxmox.Utils.printPropertyString(me.default_opts);
256 me.editableAttributes.forEach((attr) => {
257 if (values[attr]) {
258 me.sync_attributes[attr] = values[attr];
259 delete values[attr];
260 } else {
261 delete me.sync_attributes[attr];
262 }
263 });
264 values['sync-attributes'] = Proxmox.Utils.printPropertyString(me.sync_attributes);
265
266 Proxmox.Utils.delete_if_default(values, 'sync-defaults-options');
267 Proxmox.Utils.delete_if_default(values, 'sync-attributes');
268
269 // Force values.delete to be an array
270 if (typeof values.delete === 'string') {
271 values.delete = values.delete.split(',');
272 }
273
274 if (me.isCreate) {
275 delete values.delete; // on create we cannot delete values
276 }
277
278 return values;
279 },
280
281 setValues: function(values) {
282 let me = this;
283
284 if (values['sync-attributes']) {
285 me.sync_attributes = Proxmox.Utils.parsePropertyString(values['sync-attributes']);
286 delete values['sync-attributes'];
287 me.editableAttributes.forEach((attr) => {
288 if (me.sync_attributes[attr]) {
289 values[attr] = me.sync_attributes[attr];
290 }
291 });
292 }
293 if (values['sync-defaults-options']) {
294 me.default_opts = Proxmox.Utils.parsePropertyString(values['sync-defaults-options']);
295 delete values.default_opts;
296 me.editableDefaults.forEach((attr) => {
297 if (me.default_opts[attr]) {
298 values[attr] = me.default_opts[attr];
299 }
300 });
301
302 if (me.default_opts['remove-vanished']) {
303 let opts = me.default_opts['remove-vanished'].split(';');
304 for (const opt of opts) {
305 values[`remove-vanished-${opt}`] = 1;
306 }
307 }
308 }
309 return me.callParent([values]);
310 },
311
312 column1: [
313 {
314 xtype: 'proxmoxtextfield',
315 name: 'firstname',
316 fieldLabel: gettext('First Name attribute'),
317 autoEl: {
318 tag: 'div',
319 'data-qtip': Ext.String.format(gettext('Often called {0}'), '`givenName`'),
320 },
321 },
322 {
323 xtype: 'proxmoxtextfield',
324 name: 'lastname',
325 fieldLabel: gettext('Last Name attribute'),
326 autoEl: {
327 tag: 'div',
328 'data-qtip': Ext.String.format(gettext('Often called {0}'), '`sn`'),
329 },
330 },
331 {
332 xtype: 'proxmoxtextfield',
333 name: 'email',
334 fieldLabel: gettext('E-Mail attribute'),
335 autoEl: {
336 tag: 'div',
337 'data-qtip': get => get('isAd')
338 ? Ext.String.format(gettext('Often called {0} or {1}'), '`userPrincipalName`', '`mail`')
339 : Ext.String.format(gettext('Often called {0}'), '`mail`'),
340 },
341 },
342 {
343 xtype: 'displayfield',
344 value: gettext('Default Sync Options'),
345 },
346 {
347 xtype: 'proxmoxKVComboBox',
348 value: '__default__',
349 deleteEmpty: false,
350 comboItems: [
351 [
352 '__default__',
353 Ext.String.format(
354 gettext("{0} ({1})"),
355 Proxmox.Utils.yesText,
356 Proxmox.Utils.defaultText,
357 ),
358 ],
359 ['true', Proxmox.Utils.yesText],
360 ['false', Proxmox.Utils.noText],
361 ],
362 name: 'enable-new',
363 fieldLabel: gettext('Enable new users'),
364 },
365 ],
366
367 column2: [
368 {
369 xtype: 'proxmoxtextfield',
370 name: 'user-classes',
371 fieldLabel: gettext('User classes'),
372 deleteEmpty: true,
373 emptyText: 'inetorgperson, posixaccount, person, user',
374 autoEl: {
375 tag: 'div',
376 'data-qtip': gettext('Default user classes: inetorgperson, posixaccount, person, user'),
377 },
378 },
379 {
380 xtype: 'proxmoxtextfield',
381 name: 'filter',
382 fieldLabel: gettext('User Filter'),
383 deleteEmpty: true,
384 },
385 ],
386
387 columnB: [
388 {
389 xtype: 'fieldset',
390 title: gettext('Remove Vanished Options'),
391 items: [
392 {
393 xtype: 'proxmoxcheckbox',
394 fieldLabel: gettext('ACL'),
395 name: 'remove-vanished-acl',
396 boxLabel: gettext('Remove ACLs of vanished users'),
397 },
398 {
399 xtype: 'proxmoxcheckbox',
400 fieldLabel: gettext('Entry'),
401 name: 'remove-vanished-entry',
402 boxLabel: gettext('Remove vanished user'),
403 },
404 {
405 xtype: 'proxmoxcheckbox',
406 fieldLabel: gettext('Properties'),
407 name: 'remove-vanished-properties',
408 boxLabel: gettext('Remove vanished properties from synced users.'),
409 },
410 ],
411 },
412 ],
413 });