summaryrefslogtreecommitdiffstats
path: root/webapp/components/admin_console/ldap_settings.jsx
blob: 9ffbe3b0ee5a1e8eed6e9f24ce021004303b30cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import AdminSettings from './admin_settings.jsx';
import BooleanSetting from './boolean_setting.jsx';
import {ConnectionSecurityDropdownSettingLdap} from './connection_security_dropdown_setting.jsx';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';

import {ldapSyncNow, ldapTest} from 'actions/admin_actions.jsx';

import * as Utils from 'utils/utils.jsx';

import React from 'react';
import {FormattedMessage} from 'react-intl';
import RequestButton from './request_button/request_button.jsx';

export default class LdapSettings extends AdminSettings {
    constructor(props) {
        super(props);

        this.getConfigFromState = this.getConfigFromState.bind(this);

        this.renderSettings = this.renderSettings.bind(this);
    }

    getConfigFromState(config) {
        config.LdapSettings.Enable = this.state.enable;
        config.LdapSettings.LdapServer = this.state.ldapServer;
        config.LdapSettings.LdapPort = this.parseIntNonZero(this.state.ldapPort);
        config.LdapSettings.ConnectionSecurity = this.state.connectionSecurity;
        config.LdapSettings.BaseDN = this.state.baseDN;
        config.LdapSettings.BindUsername = this.state.bindUsername;
        config.LdapSettings.BindPassword = this.state.bindPassword;
        config.LdapSettings.UserFilter = this.state.userFilter;
        config.LdapSettings.FirstNameAttribute = this.state.firstNameAttribute;
        config.LdapSettings.LastNameAttribute = this.state.lastNameAttribute;
        config.LdapSettings.NicknameAttribute = this.state.nicknameAttribute;
        config.LdapSettings.EmailAttribute = this.state.emailAttribute;
        config.LdapSettings.UsernameAttribute = this.state.usernameAttribute;
        config.LdapSettings.PositionAttribute = this.state.positionAttribute;
        config.LdapSettings.IdAttribute = this.state.idAttribute;
        config.LdapSettings.SyncIntervalMinutes = this.parseIntNonZero(this.state.syncIntervalMinutes);
        config.LdapSettings.SkipCertificateVerification = this.state.skipCertificateVerification;
        config.LdapSettings.QueryTimeout = this.parseIntNonZero(this.state.queryTimeout);
        config.LdapSettings.MaxPageSize = this.parseInt(this.state.maxPageSize);
        config.LdapSettings.LoginFieldName = this.state.loginFieldName;

        return config;
    }

    getStateFromConfig(config) {
        return {
            enable: config.LdapSettings.Enable,
            ldapServer: config.LdapSettings.LdapServer,
            ldapPort: config.LdapSettings.LdapPort,
            connectionSecurity: config.LdapSettings.ConnectionSecurity,
            baseDN: config.LdapSettings.BaseDN,
            bindUsername: config.LdapSettings.BindUsername,
            bindPassword: config.LdapSettings.BindPassword,
            userFilter: config.LdapSettings.UserFilter,
            firstNameAttribute: config.LdapSettings.FirstNameAttribute,
            lastNameAttribute: config.LdapSettings.LastNameAttribute,
            nicknameAttribute: config.LdapSettings.NicknameAttribute,
            emailAttribute: config.LdapSettings.EmailAttribute,
            usernameAttribute: config.LdapSettings.UsernameAttribute,
            positionAttribute: config.LdapSettings.PositionAttribute,
            idAttribute: config.LdapSettings.IdAttribute,
            syncIntervalMinutes: config.LdapSettings.SyncIntervalMinutes,
            skipCertificateVerification: config.LdapSettings.SkipCertificateVerification,
            queryTimeout: config.LdapSettings.QueryTimeout,
            maxPageSize: config.LdapSettings.MaxPageSize,
            loginFieldName: config.LdapSettings.LoginFieldName
        };
    }

    renderTitle() {
        return (
            <FormattedMessage
                id='admin.authentication.ldap'
                defaultMessage='AD/LDAP'
            />
        );
    }

    renderSettings() {
        const licenseEnabled = global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.LDAP === 'true';
        if (!licenseEnabled) {
            return null;
        }

        return (
            <SettingsGroup>
                <BooleanSetting
                    id='enable'
                    label={
                        <FormattedMessage
                            id='admin.ldap.enableTitle'
                            defaultMessage='Enable sign-in with AD/LDAP:'
                        />
                    }
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.enableDesc'
                            defaultMessage='When true, Mattermost allows login using AD/LDAP'
                        />
                    }
                    value={this.state.enable}
                    onChange={this.handleChange}
                />
                <TextSetting
                    id='ldapServer'
                    label={
                        <FormattedMessage
                            id='admin.ldap.serverTitle'
                            defaultMessage='AD/LDAP Server:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.serverEx', 'Ex "10.0.0.23"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.serverDesc'
                            defaultMessage='The domain or IP address of AD/LDAP server.'
                        />
                    }
                    value={this.state.ldapServer}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='ldapPort'
                    label={
                        <FormattedMessage
                            id='admin.ldap.portTitle'
                            defaultMessage='AD/LDAP Port:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.portEx', 'Ex "389"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.portDesc'
                            defaultMessage='The port Mattermost will use to connect to the AD/LDAP server. Default is 389.'
                        />
                    }
                    value={this.state.ldapPort}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <ConnectionSecurityDropdownSettingLdap
                    value={this.state.connectionSecurity}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <BooleanSetting
                    id='skipCertificateVerification'
                    label={
                        <FormattedMessage
                            id='admin.ldap.skipCertificateVerification'
                            defaultMessage='Skip Certificate Verification:'
                        />
                    }
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.skipCertificateVerificationDesc'
                            defaultMessage='Skips the certificate verification step for TLS or STARTTLS connections. Not recommended for production environments where TLS is required. For testing only.'
                        />
                    }
                    value={this.state.skipCertificateVerification}
                    onChange={this.handleChange}
                />
                <TextSetting
                    id='baseDN'
                    label={
                        <FormattedMessage
                            id='admin.ldap.baseTitle'
                            defaultMessage='BaseDN:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.baseEx', 'Ex "ou=Unit Name,dc=corp,dc=example,dc=com"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.baseDesc'
                            defaultMessage='The Base DN is the Distinguished Name of the location where Mattermost should start its search for users in the AD/LDAP tree.'
                        />
                    }
                    value={this.state.baseDN}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='bindUsername'
                    label={
                        <FormattedMessage
                            id='admin.ldap.bindUserTitle'
                            defaultMessage='Bind Username:'
                        />
                    }
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.bindUserDesc'
                            defaultMessage='The username used to perform the AD/LDAP search. This should typically be an account created specifically for use with Mattermost. It should have access limited to read the portion of the AD/LDAP tree specified in the BaseDN field.'
                        />
                    }
                    value={this.state.bindUsername}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='bindPassword'
                    label={
                        <FormattedMessage
                            id='admin.ldap.bindPwdTitle'
                            defaultMessage='Bind Password:'
                        />
                    }
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.bindPwdDesc'
                            defaultMessage='Password of the user given in "Bind Username".'
                        />
                    }
                    value={this.state.bindPassword}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='userFilter'
                    label={
                        <FormattedMessage
                            id='admin.ldap.userFilterTitle'
                            defaultMessage='User Filter:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.userFilterEx', 'Ex. "(objectClass=user)"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.userFilterDisc'
                            defaultMessage='(Optional) Enter an AD/LDAP Filter to use when searching for user objects. Only the users selected by the query will be able to access Mattermost. For Active Directory, the query to filter out disabled users is (&(objectCategory=Person)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))).'
                        />
                    }
                    value={this.state.userFilter}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='firstNameAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.firstnameAttrTitle'
                            defaultMessage='First Name Attribute'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.firstnameAttrEx', 'Ex "givenName"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.firstnameAttrDesc'
                            defaultMessage='(Optional) The attribute in the AD/LDAP server that will be used to populate the first name of users in Mattermost.  When set, users will not be able to edit their first name, since it is synchronized with the LDAP server. When left blank, users can set their own first name in Account Settings.'
                        />
                    }
                    value={this.state.firstNameAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='lastNameAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.lastnameAttrTitle'
                            defaultMessage='Last Name Attribute:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.lastnameAttrEx', 'Ex "sn"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.lastnameAttrDesc'
                            defaultMessage='(Optional) The attribute in the AD/LDAP server that will be used to populate the last name of users in Mattermost. When set, users will not be able to edit their last name, since it is synchronized with the LDAP server. When left blank, users can set their own last name in Account Settings.'
                        />
                    }
                    value={this.state.lastNameAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='nicknameAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.nicknameAttrTitle'
                            defaultMessage='Nickname Attribute:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.nicknameAttrEx', 'Ex "nickname"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.nicknameAttrDesc'
                            defaultMessage='(Optional) The attribute in the AD/LDAP server that will be used to populate the nickname of users in Mattermost. When set, users will not be able to edit their nickname, since it is synchronized with the LDAP server. When left blank, users can set their own nickname in Account Settings.'
                        />
                    }
                    value={this.state.nicknameAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='positionAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.positionAttrTitle'
                            defaultMessage='Position Attribute:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.positionAttrEx', 'E.g.: "title"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.positionAttrDesc'
                            defaultMessage='(Optional) The attribute in the AD/LDAP server that will be used to populate the position field in Mattermost.'
                        />
                    }
                    value={this.state.positionAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='emailAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.emailAttrTitle'
                            defaultMessage='Email Attribute:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.emailAttrEx', 'Ex "mail" or "userPrincipalName"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.emailAttrDesc'
                            defaultMessage='The attribute in the AD/LDAP server that will be used to populate the email addresses of users in Mattermost.'
                        />
                    }
                    value={this.state.emailAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='usernameAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.usernameAttrTitle'
                            defaultMessage='Username Attribute:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.usernameAttrEx', 'Ex "sAMAccountName"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.uernameAttrDesc'
                            defaultMessage='The attribute in the AD/LDAP server that will be used to populate the username field in Mattermost. This may be the same as the ID Attribute.'
                        />
                    }
                    value={this.state.usernameAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='idAttribute'
                    label={
                        <FormattedMessage
                            id='admin.ldap.idAttrTitle'
                            defaultMessage='ID Attribute: '
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.idAttrEx', 'Ex "sAMAccountName"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.idAttrDesc'
                            defaultMessage='The attribute in the AD/LDAP server that will be used as a unique identifier in Mattermost. It should be an AD/LDAP attribute with a value that does not change, such as username or uid. If a user’s ID Attribute changes, it will create a new Mattermost account unassociated with their old one. This is the value used to log in to Mattermost in the "AD/LDAP Username" field on the sign in page. Normally this attribute is the same as the "Username Attribute" field above. If your team typically uses domain\\username to sign in to other services with AD/LDAP, you may choose to put domain\\username in this field to maintain consistency between sites.'
                        />
                    }
                    value={this.state.idAttribute}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='loginFieldName'
                    label={
                        <FormattedMessage
                            id='admin.ldap.loginNameTitle'
                            defaultMessage='Sign-in Field Default Text:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.loginNameEx', 'Ex "AD/LDAP Username"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.loginNameDesc'
                            defaultMessage='The placeholder text that appears in the login field on the login page. Defaults to "AD/LDAP Username".'
                        />
                    }
                    value={this.state.loginFieldName}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='syncIntervalMinutes'
                    label={
                        <FormattedMessage
                            id='admin.ldap.syncIntervalTitle'
                            defaultMessage='Synchronization Interval (minutes):'
                        />
                    }
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.syncIntervalHelpText'
                            defaultMessage='AD/LDAP Synchronization updates Mattermost user information to reflect updates on the AD/LDAP server. For example, when a user’s name changes on the AD/LDAP server, the change updates in Mattermost when synchronization is performed. Accounts removed from or disabled in the AD/LDAP server have their Mattermost accounts set to "Inactive" and have their account sessions revoked. Mattermost performs synchronization on the interval entered. For example, if 60 is entered, Mattermost synchronizes every 60 minutes.'
                        />
                    }
                    value={this.state.syncIntervalMinutes}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='maxPageSize'
                    label={
                        <FormattedMessage
                            id='admin.ldap.maxPageSizeTitle'
                            defaultMessage='Maximum Page Size:'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.maxPageSizeEx', 'Ex "2000"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.maxPageSizeHelpText'
                            defaultMessage='The maximum number of users the Mattermost server will request from the AD/LDAP server at one time. 0 is unlimited.'
                        />
                    }
                    value={this.state.maxPageSize}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <TextSetting
                    id='queryTimeout'
                    label={
                        <FormattedMessage
                            id='admin.ldap.queryTitle'
                            defaultMessage='Query Timeout (seconds):'
                        />
                    }
                    placeholder={Utils.localizeMessage('admin.ldap.queryEx', 'Ex "60"')}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.queryDesc'
                            defaultMessage='The timeout value for queries to the AD/LDAP server. Increase if you are getting timeout errors caused by a slow AD/LDAP server.'
                        />
                    }
                    value={this.state.queryTimeout}
                    onChange={this.handleChange}
                    disabled={!this.state.enable}
                />
                <RequestButton
                    requestAction={ldapSyncNow}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.syncNowHelpText'
                            defaultMessage='Initiates an AD/LDAP synchronization immediately.'
                        />
                    }
                    buttonText={
                        <FormattedMessage
                            id='admin.ldap.sync_button'
                            defaultMessage='AD/LDAP Synchronize Now'
                        />
                    }
                    disabled={!this.state.enable}
                    showSuccessMessage={false}
                    errorMessage={{
                        id: 'admin.ldap.syncFailure',
                        defaultMessage: 'Sync Failure: {error}'
                    }}
                    includeDetailedError={true}
                />
                <RequestButton
                    requestAction={ldapTest}
                    helpText={
                        <FormattedMessage
                            id='admin.ldap.testHelpText'
                            defaultMessage='Tests if the Mattermost server can connect to the AD/LDAP server specified. See log file for more detailed error messages.'
                        />
                    }
                    buttonText={
                        <FormattedMessage
                            id='admin.ldap.ldap_test_button'
                            defaultMessage='AD/LDAP Test'
                        />
                    }
                    disabled={!this.state.enable}
                    saveNeeded={this.state.saveNeeded}
                    saveConfigAction={this.doSubmit}
                    errorMessage={{
                        id: 'admin.ldap.testFailure',
                        defaultMessage: 'AD/LDAP Test Failure: {error}'
                    }}
                    successMessage={{
                        id: 'admin.ldap.testSuccess',
                        defaultMessage: 'AD/LDAP Test Successful'
                    }}
                />
            </SettingsGroup>
        );
    }
}