Merge branch '2013.10' into 2014.11
[tine20] / tine20 / Setup / js / AuthenticationPanel.js
1 /*
2  * Tine 2.0
3  * 
4  * @package     Setup
5  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
6  * @author      Cornelius Weiss <c.weiss@metaways.de>
7  * @copyright   Copyright (c) 2009-2015 Metaways Infosystems GmbH (http://www.metaways.de)
8  *
9  */
10
11 /*global Ext, Tine*/
12
13 Ext.ns('Tine', 'Tine.Setup');
14  
15 /**
16  * Setup Authentication Manager
17  * 
18  * @namespace   Tine.Setup
19  * @class       Tine.Setup.AuthenticationPanel
20  * @extends     Tine.Tinebase.widgets.form.ConfigPanel
21  * 
22  * <p>Authentication Panel</p>
23  * <p><pre>
24  * TODO         move to next step after install?
25  * TODO         make default is valid mechanism with 'allowEmpty' work
26  * TODO         add port for ldap hosts
27  * </pre></p>
28  * 
29  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
30  * @author      Cornelius Weiss <c.weiss@metaways.de>
31  * @copyright   Copyright (c) 2009 Metaways Infosystems GmbH (http://www.metaways.de)
32  * 
33  * @param       {Object} config
34  * @constructor
35  * Create a new Tine.Setup.AuthenticationPanel
36  */
37 Tine.Setup.AuthenticationPanel = Ext.extend(Tine.Tinebase.widgets.form.ConfigPanel, {
38     
39     /**
40      * @property idPrefix DOM Id prefix
41      * @type String
42      */
43     idPrefix: null,
44     
45     /**
46      * authProviderPrefix DOM Id prefix
47      * 
48      * @property authProviderIdPrefix
49      * @type String
50      */
51     authProviderIdPrefix: null,
52     
53     /**
54      * accountsStorageIdPrefix DOM Id prefix
55      * 
56      * @property accountsStorageIdPrefix
57      * @type String
58      */
59     accountsStorageIdPrefix: null,
60     
61     /**
62      * combo box containing the authentication backend selection
63      * 
64      * @property authenticationBackendCombo
65      * @type Ext.form.ComboBox 
66      */
67     authenticationBackendCombo: null,
68
69     /**
70      * combo box containing the accounts storage selection
71      * 
72      * @property accountsStorageCombo
73      * @type Ext.form.ComboBox
74      */
75     accountsStorageCombo: null,
76     
77     /**
78      * The currently active accounts storage backend
79      * 
80      * @property originalAccountsStorage
81      * @type String
82      */
83     originalAccountsStorage: null,
84
85     /**
86      * @private
87      * panel cfg
88      */
89     saveMethod: 'Setup.saveAuthentication',
90     registryKey: 'authenticationData',
91     
92     /**
93      * @private
94      * field index counter
95      */
96     tabIndexCounter: 1,
97     
98     /**
99      * @private
100      */
101     initComponent: function () {
102         this.idPrefix                   = Ext.id();
103         this.authProviderIdPrefix       = this.idPrefix + '-authProvider-';
104         this.accountsStorageIdPrefix    = this.idPrefix + '-accountsStorage-';
105         this.originalAccountsStorage    = (Tine.Setup.registry.get(this.registryKey).accounts) ? Tine.Setup.registry.get(this.registryKey).accounts.backend : 'Sql';
106         
107         Tine.Setup.AuthenticationPanel.superclass.initComponent.call(this);
108     },
109     
110     /**
111      * Change card layout depending on selected combo box entry
112      */
113     onChangeAuthProvider: function () {
114         var authProvider = this.authenticationBackendCombo.getValue();
115         
116         var cardLayout = Ext.getCmp(this.authProviderIdPrefix + 'CardLayout').getLayout();
117         cardLayout.setActiveItem(this.authProviderIdPrefix + authProvider);
118     },
119     
120     /**
121      * Change card layout depending on selected combo box entry
122      */
123     onChangeAccountsStorage: function () {
124         var AccountsStorage = this.accountsStorageCombo.getValue();
125
126         if ((AccountsStorage === 'Ldap' || AccountsStorage === 'ActiveDirectory') && AccountsStorage !== this.originalAccountsStorage) {
127             Ext.Msg.confirm(this.app.i18n._('Delete all existing users and groups'), this.app.i18n._('Switching from SQL to LDAP will delete all existing User Accounts, Groups and Roles. Do you really want to switch the accounts storage backend to LDAP ?'), function (confirmbtn, value) {
128                 if (confirmbtn === 'yes') {
129                     this.doOnChangeAccountsStorage(AccountsStorage);
130                 } else {
131                     this.accountsStorageCombo.setValue(this.originalAccountsStorage);
132                 }
133             }, this);
134         } else {
135             this.doOnChangeAccountsStorage(AccountsStorage);
136         }
137     },
138     
139     /**
140      * Change card layout depending on selected combo box entry
141      */
142     doOnChangeAccountsStorage: function (AccountsStorage) {
143         var cardLayout = Ext.getCmp(this.accountsStorageIdPrefix + 'CardLayout').getLayout();
144         
145         cardLayout.setActiveItem(this.accountsStorageIdPrefix + AccountsStorage);
146         this.originalAccountsStorage = AccountsStorage;
147     },
148     
149     /**
150      * @private
151      */
152     onRender: function (ct, position) {
153         Tine.Setup.AuthenticationPanel.superclass.onRender.call(this, ct, position);
154         
155         this.onChangeAuthProvider.defer(250, this);
156         this.onChangeAccountsStorage.defer(250, this);
157     },
158         
159     /**
160      * transforms form data into a config object
161      * 
162      * @hack   smuggle termsAccept in 
163      * @return {Object} configData
164      */
165     form2config: function () {
166         var configData = this.supr().form2config.call(this);
167         configData.acceptedTermsVersion = Tine.Setup.registry.get('acceptedTermsVersion');
168         
169         return configData;
170     },
171     
172     /**
173      * get tab index for field
174      * 
175      * @return {Integer}
176      */
177     getTabIndex: function () {
178         return this.tabIndexCounter++;
179     },
180     
181    /**
182      * returns config manager form
183      * 
184      * @private
185      * @return {Array} items
186      */
187     getFormItems: function () {
188         var setupRequired = Tine.Setup.registry.get('setupRequired');
189         
190         // common config for all combos in this setup
191         var commonComboConfig = {
192             xtype: 'combo',
193             listWidth: 300,
194             mode: 'local',
195             forceSelection: true,
196             allowEmpty: false,
197             triggerAction: 'all',
198             editable: false,
199             tabIndex: this.getTabIndex
200         };
201         
202         this.authenticationBackendCombo = new Ext.form.ComboBox(Ext.applyIf({
203             name: 'authentication_backend',
204             fieldLabel: this.app.i18n._('Backend'),
205             store: [['Sql', 'SQL'], ['Ldap', 'LDAP'], ['Imap', 'IMAP'], ['ModSsl', this.app.i18n._('TLS client certificate')]],
206             value: 'Sql',
207             width: 300,
208             listeners: {
209                 scope: this,
210                 change: this.onChangeAuthProvider,
211                 select: this.onChangeAuthProvider
212             }
213         }, commonComboConfig));
214             
215         this.accountsStorageCombo = new Ext.form.ComboBox(Ext.applyIf({
216             name: 'accounts_backend',
217             fieldLabel: this.app.i18n._('Backend'),
218             store: [['Sql', 'Sql'], ['Ldap', 'Ldap'], ['ActiveDirectory', 'ActiveDirectory']],
219             value: 'Sql',
220             width: 300,
221             listeners: {
222                 scope: this,
223                 change: this.onChangeAccountsStorage,
224                 select: this.onChangeAccountsStorage
225             }
226         }, commonComboConfig));
227         
228         return [{
229             xtype: 'fieldset',
230             collapsible: true,
231             collapsed: !setupRequired,
232             autoHeight: true,
233             title: this.app.i18n._('Initial Admin User'),
234             items: [{
235                 layout: 'form',
236                 autoHeight: 'auto',
237                 border: false,
238                 defaults: {
239                     width: 300,
240                     xtype: 'textfield',
241                     inputType: 'password',
242                     tabIndex: this.getTabIndex
243                 },
244                 items: [{
245                     name: 'authentication_Sql_adminLoginName',
246                     fieldLabel: this.app.i18n._('Initial admin login name'),
247                     inputType: 'text',
248                     disabled: !setupRequired
249                 }, {
250                     name: 'authentication_Sql_adminPassword',
251                     fieldLabel: this.app.i18n._('Initial admin Password'),
252                     disabled: !setupRequired
253                 }, {
254                     name: 'authentication_Sql_adminPasswordConfirmation',
255                     fieldLabel: this.app.i18n._('Password confirmation'),
256                     disabled: !setupRequired
257                 }]
258             }]
259         }, {
260             xtype: 'fieldset',
261             collapsible: false,
262             autoHeight: true,
263             title: this.app.i18n._('Authentication provider'),
264             items: [
265                 this.authenticationBackendCombo,
266                 {
267                     id: this.authProviderIdPrefix + 'CardLayout',
268                     layout: 'card',
269                     activeItem: this.authProviderIdPrefix + 'Sql',
270                     border: false,
271                     defaults: {border: false},
272                     items: [{
273                         id: this.authProviderIdPrefix + 'Sql',
274                         layout: 'form',
275                         autoHeight: 'auto',
276                         defaults: {
277                             width: 300,
278                             xtype: 'textfield',
279                             tabIndex: this.getTabIndex
280                         },
281                         items: [
282                             Ext.applyIf({
283                                 name: 'authentication_Sql_tryUsernameSplit',
284                                 fieldLabel: this.app.i18n._('Try to split username'),
285                                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
286                                 value: '1'
287                             }, commonComboConfig), 
288                             Ext.applyIf({
289                                 name: 'authentication_Sql_accountCanonicalForm',
290                                 fieldLabel: this.app.i18n._('Account canonical form'),
291                                 store: [['2', 'ACCTNAME_FORM_USERNAME'], ['3', 'ACCTNAME_FORM_BACKSLASH'], ['4', 'ACCTNAME_FORM_PRINCIPAL']],
292                                 value: '2'
293                             }, commonComboConfig), 
294                             {
295                                 name: 'authentication_Sql_accountDomainName',
296                                 fieldLabel: this.app.i18n._('Account domain name')
297                             }, {
298                                 name: 'authentication_Sql_accountDomainNameShort',
299                                 fieldLabel: this.app.i18n._('Account domain short name')
300                             }
301                         ]
302                     }, {
303                         id: this.authProviderIdPrefix + 'Ldap',
304                         layout: 'form',
305                         autoHeight: 'auto',
306                         defaults: {
307                             width: 300,
308                             xtype: 'textfield',
309                             tabIndex: this.getTabIndex
310                         },
311                         items: [{
312                             name: 'authentication_Ldap_host',
313                             fieldLabel: this.app.i18n._('Host')
314                         }/*, {
315                             inputType: 'text',
316                             name: 'authentication_Ldap_port',
317                             fieldLabel: this.app.i18n._('Port')
318                         }*/, {
319                             name: 'authentication_Ldap_username',
320                             fieldLabel: this.app.i18n._('Login name')
321                         }, {
322                             name: 'authentication_Ldap_password',
323                             fieldLabel: this.app.i18n._('Password'),
324                             inputType: 'password'
325                         },
326                         Ext.applyIf({
327                             name: 'authentication_Ldap_bindRequiresDn',
328                             fieldLabel: this.app.i18n._('Bind requires DN'),
329                             store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
330                             value: '1'
331                         }, commonComboConfig),
332                         Ext.applyIf({
333                             name: 'authentication_Ldap_useStartTls',
334                             fieldLabel: this.app.i18n._('Start TLS'),
335                             store: [['0', this.app.i18n._('No')], ['1', this.app.i18n._('Yes')]],
336                             value: '0'
337                         }, commonComboConfig), 
338                         {
339                             name: 'authentication_Ldap_baseDn',
340                             fieldLabel: this.app.i18n._('Base DN')
341                         }, {
342                             name: 'authentication_Ldap_accountFilterFormat',
343                             fieldLabel: this.app.i18n._('Search filter')
344                         }, 
345                         Ext.applyIf({
346                             name: 'authentication_Ldap_tryUsernameSplit',
347                             fieldLabel: this.app.i18n._('Try to split username'),
348                             store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
349                             value: '1'
350                         }, commonComboConfig),
351                         Ext.applyIf({
352                             name: 'authentication_Ldap_accountCanonicalForm',
353                             fieldLabel: this.app.i18n._('Account canonical form'),
354                             store: [['2', 'ACCTNAME_FORM_USERNAME'], ['3', 'ACCTNAME_FORM_BACKSLASH'], ['4', 'ACCTNAME_FORM_PRINCIPAL']],
355                             value: '2'
356                         }, commonComboConfig), 
357                         {
358                             name: 'authentication_Ldap_accountDomainName',
359                             fieldLabel: this.app.i18n._('Account domain name')
360                         }, {
361                             name: 'authentication_Ldap_accountDomainNameShort',
362                             fieldLabel: this.app.i18n._('Account domain short name')
363                         }]
364                     }, {
365                         id: this.authProviderIdPrefix + 'Imap',
366                         layout: 'form',
367                         autoHeight: 'auto',
368                         defaults: {
369                             width: 300,
370                             xtype: 'textfield',
371                             tabIndex: this.getTabIndex
372                         },
373                         items: [{
374                             name: 'authentication_Imap_host',
375                             fieldLabel: this.app.i18n._('Hostname')
376                         }, {
377                             name: 'authentication_Imap_port',
378                             fieldLabel: this.app.i18n._('Port'),
379                             xtype: 'numberfield'
380                         }, 
381                         Ext.applyIf({
382                             fieldLabel: this.app.i18n._('Secure Connection'),
383                             name: 'authentication_Imap_ssl',
384                             store: [['none', this.app.i18n._('None')], ['tls', this.app.i18n._('TLS')], ['ssl', this.app.i18n._('SSL')]],
385                             value: 'none'
386                         }, commonComboConfig), 
387                         {
388                             name: 'authentication_Imap_domain',
389                             fieldLabel: this.app.i18n._('Append domain to login name')
390                         }
391                         ]
392                     }, {
393                         id: this.authProviderIdPrefix + 'ModSsl',
394                         layout: 'form',
395                         autoHeight: 'auto',
396                         defaults: {
397                             width: 300,
398                             xtype: 'textfield',
399                             tabIndex: this.getTabIndex
400                         },
401                         items: [Ext.applyIf({
402                             fieldLabel: this.app.i18n._('Certificate validation'),
403                             name: 'authentication_ModSsl_validation',
404                             store: [['Apache', 'Apache'], ['X509', 'X509'], ['ICPBrasil', 'ICP Brasil']],
405                             value: 'Apache'
406                         }, commonComboConfig),
407                         Ext.applyIf({
408                             name: 'authentication_ModSsl_tryUsernameSplit',
409                             fieldLabel: this.app.i18n._('Try to split username'),
410                             store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
411                             value: '1'
412                         }, commonComboConfig), 
413                         {
414                             name: 'authentication_ModSsl_casfile',
415                             fieldLabel: this.app.i18n._('CA file')
416                         }, {
417                             name: 'authentication_ModSsl_crlspath',
418                             fieldLabel: this.app.i18n._('CRL directory')
419                         }
420                         ]
421                     }]
422                 }
423             ]
424         }, {
425             xtype: 'fieldset',
426             collapsible: false,
427             autoHeight: true,
428             title: this.app.i18n._('Accounts storage'),
429             items: [
430                 this.accountsStorageCombo,
431                 {
432                     id: this.accountsStorageIdPrefix + 'CardLayout',
433                     layout: 'card',
434                     activeItem: this.accountsStorageIdPrefix + 'Sql',
435                     border: false,
436                     defaults: {
437                         border: false
438                     },
439                     items: [{
440                         id: this.accountsStorageIdPrefix + 'Sql',
441                         layout: 'form',
442                         autoHeight: 'auto',
443                         defaults: {
444                             width: 300,
445                             xtype: 'textfield',
446                             tabIndex: this.getTabIndex
447                         },
448                         items: [{
449                             name: 'accounts_Sql_defaultUserGroupName',
450                             fieldLabel: this.app.i18n._('Default user group name')
451                         }, {
452                             name: 'accounts_Sql_defaultAdminGroupName',
453                             fieldLabel: this.app.i18n._('Default admin group name')
454                         }]
455                     },
456                         this.getDirectoryOptions('Ldap', commonComboConfig),
457                         this.getDirectoryOptions('ActiveDirectory', commonComboConfig)
458                     ]
459                 }
460             ]
461           }, {
462             xtype: 'fieldset',
463             collapsible: false,
464             autoHeight: true,
465             title: this.app.i18n._('Login panel'),
466             defaults: {
467                 width: 300,
468                 xtype: 'uxspinner',
469                 tabIndex: this.getTabIndex,
470                 strategy: {
471                     xtype: 'number',
472                     minValue: 0,
473                     maxValue: 64
474                 },
475                 value: 0
476             },
477             items: [
478             Ext.applyIf({
479                 name: 'saveusername_saveusername',
480                 fieldLabel: this.app.i18n._('Reuse last username logged'),
481                 store: [[1, this.app.i18n._('Yes')], [0, this.app.i18n._('No')]],
482                 value: 0
483             }, commonComboConfig)
484             ]
485         }, {
486             xtype: 'fieldset',
487             collapsible: false,
488             autoHeight: true,
489             title: this.app.i18n._('Password Settings'),
490             defaults: {
491                 width: 300,
492                 xtype: 'uxspinner',
493                 tabIndex: this.getTabIndex,
494                 strategy: {
495                     xtype: 'number',
496                     minValue: 0,
497                     maxValue: 64
498                 },
499                 value: 0
500             },
501             items: [
502             Ext.applyIf({
503                 name: 'password_changepw',
504                 fieldLabel: this.app.i18n._('User can change password'),
505                 store: [[1, this.app.i18n._('Yes')], [0, this.app.i18n._('No')]],
506                 value: 1
507             }, commonComboConfig),
508             Ext.applyIf({
509                 name: 'password_pwPolicyActive',
510                 fieldLabel: this.app.i18n._('Enable password policy'),
511                 store: [[1, this.app.i18n._('Yes')], [0, this.app.i18n._('No')]],
512                 value: 0
513             }, commonComboConfig),
514             Ext.applyIf({
515                 name: 'password_pwPolicyOnlyASCII',
516                 fieldLabel: this.app.i18n._('Only ASCII'),
517                 store: [[1, this.app.i18n._('Yes')], [0, this.app.i18n._('No')]],
518                 value: 0
519             }, commonComboConfig), {
520                 name: 'password_pwPolicyMinLength',
521                 fieldLabel: this.app.i18n._('Minimum length')
522             }, {
523                 name: 'password_pwPolicyMinWordChars',
524                 fieldLabel: this.app.i18n._('Minimum word chars')
525             }, {
526                 name: 'password_pwPolicyMinUppercaseChars',
527                 fieldLabel: this.app.i18n._('Minimum uppercase chars')
528             }, {
529                 name: 'password_pwPolicyMinSpecialChars',
530                 fieldLabel: this.app.i18n._('Minimum special chars')
531             }, {
532                 name: 'password_pwPolicyMinNumbers',
533                 fieldLabel: this.app.i18n._('Minimum numbers')
534             },
535             Ext.applyIf({
536                 name: 'password_pwPolicyForbidUsername',
537                 fieldLabel: this.app.i18n._('Forbid part of username in password'),
538                 store: [[1, this.app.i18n._('Yes')], [0, this.app.i18n._('No')]],
539                 value: 0
540             }, commonComboConfig)
541             ]
542         }, {
543             xtype: 'fieldset',
544             collapsible: false,
545             autoHeight: true,
546             title: this.app.i18n._('Redirect Settings'),
547             defaults: {
548                 width: 300,
549                 xtype: 'textfield',
550                 tabIndex: this.getTabIndex
551             },
552             items: [{
553                 name: 'redirectSettings_redirectUrl',
554                 fieldLabel: this.app.i18n._('Redirect Url (redirect to login screen if empty)')
555             }, 
556             Ext.applyIf({
557                 name: 'redirectSettings_redirectAlways',
558                 fieldLabel: this.app.i18n._('Redirect Always (if No, only redirect after logout)'),
559                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
560                 value: '0'
561             }, commonComboConfig), 
562             Ext.applyIf({
563                 name: 'redirectSettings_redirectToReferrer',
564                 fieldLabel: this.app.i18n._('Redirect to referring site, if exists'),
565                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
566                 value: '0'
567             }, commonComboConfig)]
568         }];
569     },
570     
571     /**
572      * getDirectoryOptions
573      * 
574      * @param {String} type LDAP or ActiveDirectory
575      * @param {Object} commonComboConfig
576      */
577     getDirectoryOptions: function(type, commonComboConfig)
578     {
579         return {
580             id: this.accountsStorageIdPrefix + type,
581             layout: 'form',
582             autoHeight: 'auto',
583             defaults: {
584                 width: 300,
585                 xtype: 'textfield',
586                 tabIndex: this.getTabIndex
587             },
588             items: [{
589                 name: 'accounts_' + type + '_host',
590                 fieldLabel: this.app.i18n._('Host')
591             }, {
592                 name: 'accounts_' + type + '_username',
593                 fieldLabel: this.app.i18n._('Login name')
594             }, {
595                 name: 'accounts_' + type + '_password',
596                 fieldLabel: this.app.i18n._('Password'),
597                 inputType: 'password'
598             }, 
599             Ext.applyIf({
600                 name: 'accounts_' + type + '_bindRequiresDn',
601                 fieldLabel: this.app.i18n._('Bind requires DN'),
602                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
603                 value: '1'
604             }, commonComboConfig),
605             Ext.applyIf({
606                 name: 'accounts_' + type + '_useStartTls',
607                 fieldLabel: this.app.i18n._('Start TLS'),
608                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
609                 value: '1'
610             }, commonComboConfig),
611             Ext.applyIf({
612                 hidden: type === 'ActiveDirectory' ,
613                 name: 'accounts_' + type + '_pwEncType',
614                 fieldLabel: this.app.i18n._('Password encoding'),
615                 store: [
616                     ['des', this.app.i18n._('des')],
617                     ['crypt', this.app.i18n._('crypt')],
618                     ['blowfish_crypt', this.app.i18n._('blowfish_crypt')],
619                     ['md5_crypt', this.app.i18n._('md5_crypt')],
620                     ['ext_crypt', this.app.i18n._('ext_crypt')],
621                     ['md5', this.app.i18n._('md5')],
622                     ['smd5', this.app.i18n._('smd5')],
623                     ['sha', this.app.i18n._('sha')],
624                     ['ssha', this.app.i18n._('ssha')],
625                     ['ntpassword', this.app.i18n._('ntpassword')],
626                     ['plain', this.app.i18n._('plain')]
627                 ],
628                 value: 'ssha'
629             }, commonComboConfig),
630             {
631                 name: 'accounts_' + type + '_userDn',
632                 fieldLabel: this.app.i18n._('User DN')
633             }, {
634                 name: 'accounts_' + type + '_userFilter',
635                 fieldLabel: this.app.i18n._('User Filter')
636             }, 
637             Ext.applyIf({
638                 name: 'accounts_' + type + '_userSearchScope',
639                 fieldLabel: this.app.i18n._('User Search Scope'),
640                 store: [['1', 'SEARCH_SCOPE_SUB'], ['2', 'SEARCH_SCOPE_ONE']],
641                 value: '1'
642             }, commonComboConfig), 
643             {
644                 name: 'accounts_' + type + '_groupsDn',
645                 fieldLabel: this.app.i18n._('Groups DN')
646             }, {
647                 name: 'accounts_' + type + '_groupFilter',
648                 fieldLabel: this.app.i18n._('Group Filter')
649             }, 
650             Ext.applyIf({
651                 name: 'accounts_' + type + '_groupSearchScope',
652                 fieldLabel: this.app.i18n._('Group Search Scope'),
653                 store: [['1', 'SEARCH_SCOPE_SUB'], ['2', 'SEARCH_SCOPE_ONE']],
654                 value: '1'
655             }, commonComboConfig), 
656             Ext.applyIf({
657                 name: 'accounts_' + type + ((type === 'Ldap') ? '_useRfc2307bis' : '_useRfc2307'),
658                 fieldLabel: (type === 'Ldap') ? this.app.i18n._('Use Rfc 2307 bis') : this.app.i18n._('Maintain RFC 2307 attributes'),
659                 store: [['1', this.app.i18n._('Yes')], ['0', this.app.i18n._('No')]],
660                 value: '0'
661             }, commonComboConfig), 
662             {
663                 name: 'accounts_' + type + '_minUserId',
664                 fieldLabel: this.app.i18n._('Min User Id')
665             }, {
666                 name: 'accounts_' + type + '_maxUserId',
667                 fieldLabel: this.app.i18n._('Max User Id')
668             }, {
669                 name: 'accounts_' + type + '_minGroupId',
670                 fieldLabel: this.app.i18n._('Min Group Id')
671             }, {
672                 name: 'accounts_' + type + '_maxGroupId',
673                 fieldLabel: this.app.i18n._('Max Group Id')
674             },
675             Ext.applyIf({
676                 name: 'accounts_' + type + '_groupUUIDAttribute',
677                 fieldLabel: this.app.i18n._('Group UUID Attribute name'),
678                 store: (type === 'ActiveDirectory' ? [['objectGUID', 'objectGUID']] : [['entryUUID', 'entryUUID'], ['gidNumber', 'gidNumber']])
679             }, commonComboConfig),
680             Ext.applyIf({
681                 name: 'accounts_' + type + '_userUUIDAttribute',
682                 fieldLabel: this.app.i18n._('User UUID Attribute name'),
683                 store: (type === 'ActiveDirectory' ? [['objectGUID', 'objectGUID']] : [['entryUUID', 'entryUUID'], ['uidNumber', 'uidNumber']])
684             }, commonComboConfig),
685             {
686                 name: 'accounts_' + type + '_defaultUserGroupName',
687                 fieldLabel: this.app.i18n._('Default user group name')
688             }, {
689                 name: 'accounts_' + type + '_defaultAdminGroupName',
690                 fieldLabel: this.app.i18n._('Default admin group name')
691             },
692             Ext.applyIf({
693                 name: 'accounts_' + type + '_readonly',
694                 fieldLabel: this.app.i18n._('Readonly access'),
695                 store: [['0', this.app.i18n._('No')], ['1', this.app.i18n._('Yes')]],
696                 value: '0'
697             }, commonComboConfig)]
698         };
699     },
700     
701     /**
702      * applies registry state to this cmp
703      */
704     applyRegistryState: function () {
705         this.action_saveConfig.setDisabled(false);
706         
707         if (Tine.Setup.registry.get('setupRequired')) {
708             this.action_saveConfig.setText(this.app.i18n._('Save config and install'));
709         } else {
710             this.action_saveConfig.setText(this.app.i18n._('Save config'));
711             this.getForm().findField('authentication_Sql_adminPassword').setDisabled(true);
712             this.getForm().findField('authentication_Sql_adminPasswordConfirmation').setDisabled(true);
713             this.getForm().findField('authentication_Sql_adminLoginName').setDisabled(true);
714         }
715     },
716     
717     /**
718      * checks if form is valid
719      * - password fields are equal
720      * 
721      * @return {Boolean}
722      */
723     isValid: function () {
724         var form = this.getForm();
725
726         var result = form.isValid();
727         
728         // check if passwords match
729         if (this.authenticationBackendCombo.getValue() === 'Sql' && 
730             form.findField('authentication_Sql_adminPassword') && 
731             form.findField('authentication_Sql_adminPassword').getValue() !== form.findField('authentication_Sql_adminPasswordConfirmation').getValue()) 
732         {
733             form.markInvalid([{
734                 id: 'authentication_Sql_adminPasswordConfirmation',
735                 msg: this.app.i18n._("Passwords don't match")
736             }]);
737             result = false;
738         }
739         
740         // check if initial username/passwords are set
741         if (Tine.Setup.registry.get('setupRequired')
742             && form.findField('authentication_Sql_adminLoginName')
743             && ! form.findField('authentication_Sql_adminLoginName').disabled) 
744         {
745             if (Ext.isEmpty(form.findField('authentication_Sql_adminLoginName').getValue())) {
746                 form.markInvalid([{
747                     id: 'authentication_Sql_adminLoginName',
748                     msg: this.app.i18n._("Should not be empty")
749                 }]);
750                 result = false;
751             }
752             if (Ext.isEmpty(form.findField('authentication_Sql_adminPassword').getValue())) {
753                 form.markInvalid([{
754                     id: 'authentication_Sql_adminPassword',
755                     msg: this.app.i18n._("Should not be empty")
756                 }]);
757                 form.markInvalid([{
758                     id: 'authentication_Sql_adminPasswordConfirmation',
759                     msg: this.app.i18n._("Should not be empty")
760                 }]);
761                 result = false;
762             }
763         }
764         
765         if (this.accountsStorageCombo.getValue() === 'Sql' && 
766                form.findField('accounts_Sql_defaultUserGroupName') && 
767                Ext.isEmpty(form.findField('accounts_Sql_defaultUserGroupName').getValue())) 
768           {
769             form.markInvalid([{
770                 id: 'accounts_Sql_defaultUserGroupName',
771                 msg: this.app.i18n._("Should not be empty")
772             }]);
773             result = false;
774         }
775         
776         if (this.accountsStorageCombo.getValue() === 'Sql' && 
777             form.findField('accounts_Sql_defaultAdminGroupName') && 
778             Ext.isEmpty(form.findField('accounts_Sql_defaultAdminGroupName').getValue())) 
779         {
780             form.markInvalid([{
781                 id: 'accounts_Sql_defaultAdminGroupName',
782                 msg: this.app.i18n._("Should not be empty")
783             }]);
784             result = false;
785         }
786         
787         return result;
788     }
789 });