blob: c2d0e347774fe9a60a49fb51d85898396d7bfe2b [file] [log] [blame]
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -07001<template>
2 <b-container fluid="xl">
3 <page-title :description="$t('pageLdap.pageDescription')" />
4 <page-section :section-title="$t('pageLdap.settings')">
5 <b-form novalidate @submit.prevent="handleSubmit">
6 <b-row>
7 <b-col>
8 <b-form-group
9 class="mb-3"
10 :label="$t('pageLdap.form.ldapAuthentication')"
11 >
12 <b-form-text id="enable-ldap-auth-help-block">
13 {{ $t('pageLdap.form.ldapAuthenticationHelper') }}
14 </b-form-text>
15 <b-form-checkbox
16 id="enable-ldap-auth"
17 v-model="form.ldapAuthenticationEnabled"
18 aria-describedby="enable-ldap-auth-help-block"
19 @change="onChangeldapAuthenticationEnabled"
20 >
21 {{ $t('global.action.enable') }}
22 </b-form-checkbox>
23 </b-form-group>
24 </b-col>
25 </b-row>
26 <div class="form-background p-3">
27 <b-form-group
28 class="m-0"
29 :label="$t('pageLdap.ariaLabel.ldapSettings')"
30 label-class="sr-only"
31 :disabled="!form.ldapAuthenticationEnabled"
32 >
33 <b-row>
34 <b-col md="3" lg="4" xl="3">
35 <b-form-group
36 class="mb-4"
37 :label="$t('pageLdap.form.secureLdapUsingSsl')"
38 >
39 <b-form-text id="enable-secure-help-block">
40 {{ $t('pageLdap.form.secureLdapHelper') }}
41 </b-form-text>
42 <b-form-checkbox
43 id="enable-secure-ldap"
44 v-model="form.secureLdapEnabled"
45 aria-describedby="enable-secure-help-block"
46 :disabled="
47 !caCertificateExpiration || !ldapCertificateExpiration
48 "
49 @change="$v.form.secureLdapEnabled.$touch()"
50 >
51 {{ $t('global.action.enable') }}
52 </b-form-checkbox>
53 </b-form-group>
54 <dl>
55 <dt>{{ $t('pageLdap.form.caCertificateValidUntil') }}</dt>
56 <dd v-if="caCertificateExpiration">
57 {{ caCertificateExpiration | formatDate }}
58 </dd>
59 <dd v-else>--</dd>
60 <dt>{{ $t('pageLdap.form.ldapCertificateValidUntil') }}</dt>
61 <dd v-if="ldapCertificateExpiration">
62 {{ ldapCertificateExpiration | formatDate }}
63 </dd>
64 <dd v-else>--</dd>
65 </dl>
66 <b-link
67 class="d-inline-block mb-4 m-md-0"
68 to="/access-control/ssl-certificates"
69 >
70 {{ $t('pageLdap.form.manageSslCertificates') }}
71 </b-link>
72 </b-col>
73 <b-col md="9" lg="8" xl="9">
74 <b-row>
75 <b-col>
76 <b-form-group :label="$t('pageLdap.form.serviceType')">
77 <b-form-radio
78 v-model="form.activeDirectoryEnabled"
79 :value="false"
80 @change="onChangeServiceType"
81 >
82 OpenLDAP
83 </b-form-radio>
84 <b-form-radio
85 v-model="form.activeDirectoryEnabled"
86 :value="true"
87 @change="onChangeServiceType"
88 >
89 Active Directory
90 </b-form-radio>
91 </b-form-group>
92 </b-col>
93 </b-row>
94 <b-row>
95 <b-col sm="6" xl="4">
96 <b-form-group label-for="server-uri">
97 <template v-slot:label>
98 {{ $t('pageLdap.form.serverUri') }}
99 <info-tooltip
100 :title="$t('pageLdap.form.serverUriTooltip')"
101 />
102 </template>
103 <b-input-group :prepend="ldapProtocol">
104 <b-form-input
105 id="server-uri"
106 v-model="form.serverUri"
107 :state="getValidationState($v.form.serverUri)"
108 @change="$v.form.serverUri.$touch()"
109 />
110 <b-form-invalid-feedback role="alert">
111 {{ $t('global.form.fieldRequired') }}
112 </b-form-invalid-feedback>
113 </b-input-group>
114 </b-form-group>
115 </b-col>
116 <b-col sm="6" xl="4">
117 <b-form-group
118 :label="$t('pageLdap.form.bindDn')"
119 label-for="bind-dn"
120 >
121 <b-form-input
122 id="bind-dn"
123 v-model="form.bindDn"
124 :state="getValidationState($v.form.bindDn)"
125 @change="$v.form.bindDn.$touch()"
126 />
127 <b-form-invalid-feedback role="alert">
128 {{ $t('global.form.fieldRequired') }}
129 </b-form-invalid-feedback>
130 </b-form-group>
131 </b-col>
132 <b-col sm="6" xl="4">
133 <b-form-group
134 :label="$t('pageLdap.form.bindPassword')"
135 label-for="bind-password"
136 >
137 <input-password-toggle>
138 <b-form-input
139 id="bind-password"
140 v-model="form.bindPassword"
141 type="password"
142 :state="getValidationState($v.form.bindPassword)"
143 @change="$v.form.bindPassword.$touch()"
144 />
145 <b-form-invalid-feedback role="alert">
146 {{ $t('global.form.fieldRequired') }}
147 </b-form-invalid-feedback>
148 </input-password-toggle>
149 </b-form-group>
150 </b-col>
151 <b-col sm="6" xl="4">
152 <b-form-group
153 :label="$t('pageLdap.form.baseDn')"
154 label-for="base-dn"
155 >
156 <b-form-input
157 id="base-dn"
158 v-model="form.baseDn"
159 :state="getValidationState($v.form.baseDn)"
160 @change="$v.form.baseDn.$touch()"
161 />
162 <b-form-invalid-feedback role="alert">
163 {{ $t('global.form.fieldRequired') }}
164 </b-form-invalid-feedback>
165 </b-form-group>
166 </b-col>
167 <b-col sm="6" xl="4">
168 <b-form-group
169 :label="$t('pageLdap.form.userIdAttribute')"
170 label-for="user-id-attribute"
171 >
172 <b-form-input
173 id="user-id-attribute"
174 v-model="form.userIdAttribute"
175 @change="$v.form.userIdAttribute.$touch()"
176 />
177 </b-form-group>
178 </b-col>
179 <b-col sm="6" xl="4">
180 <b-form-group
181 :label="$t('pageLdap.form.groupIdAttribute')"
182 label-for="group-id-attribute"
183 >
184 <b-form-input
185 id="group-id-attribute"
186 v-model="form.groupIdAttribute"
187 @change="$v.form.groupIdAttribute.$touch()"
188 />
189 </b-form-group>
190 </b-col>
191 </b-row>
192 </b-col>
193 </b-row>
194 </b-form-group>
195 </div>
196 <b-row class="mt-4">
197 <b-col>
198 <b-btn
199 variant="primary"
200 type="submit"
201 :disabled="!$v.form.$anyDirty"
202 >
203 {{ $t('global.action.saveSettings') }}
204 </b-btn>
205 </b-col>
206 </b-row>
207 </b-form>
208 </page-section>
209 </b-container>
210</template>
211
212<script>
213import { mapGetters } from 'vuex';
214import { find } from 'lodash';
215import { requiredIf } from 'vuelidate/lib/validators';
216
217import BVToastMixin from '@/components/Mixins/BVToastMixin.js';
218import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
219import PageTitle from '@/components/Global/PageTitle';
220import PageSection from '@/components/Global/PageSection';
221import InfoTooltip from '@/components/Global/InfoTooltip';
222import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
223
224export default {
225 name: 'Ldap',
226 components: { InfoTooltip, InputPasswordToggle, PageTitle, PageSection },
227 mixins: [BVToastMixin, VuelidateMixin],
228 data() {
229 return {
230 form: {
231 ldapAuthenticationEnabled: false,
232 secureLdapEnabled: false,
233 activeDirectoryEnabled: false,
234 serverUri: '',
235 bindDn: '',
236 bindPassword: '',
237 baseDn: '',
238 userIdAttribute: '',
239 groupIdAttribute: ''
240 }
241 };
242 },
243 computed: {
244 ...mapGetters('ldap', ['isServiceEnabled', 'ldap', 'activeDirectory']),
245 sslCertificates() {
246 return this.$store.getters['sslCertificates/allCertificates'];
247 },
248 caCertificateExpiration() {
249 const caCertificate = find(this.sslCertificates, {
250 type: 'TrustStore Certificate'
251 });
252 if (caCertificate === undefined) return null;
253 return caCertificate.validUntil;
254 },
255 ldapCertificateExpiration() {
256 const ldapCertificate = find(this.sslCertificates, {
257 type: 'LDAP Certificate'
258 });
259 if (ldapCertificate === undefined) return null;
260 return ldapCertificate.validUntil;
261 },
262 ldapProtocol() {
263 return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://';
264 }
265 },
266 watch: {
267 isServiceEnabled: function(value) {
268 this.form.ldapAuthenticationEnabled = value;
269 },
270 ldap: {
271 handler: function(value) {
272 if (value.serviceEnabled || !this.form.activeDirectoryEnabled) {
273 this.setFormValues(value);
274 }
275 },
276 deep: true
277 },
278 activeDirectory: {
279 handler: function(value) {
280 if (value.serviceEnabled) {
281 this.form.activeDirectoryEnabled = true;
282 this.setFormValues(value);
283 }
284 },
285 deep: true
286 }
287 },
288 validations: {
289 form: {
290 ldapAuthenticationEnabled: {},
291 secureLdapEnabled: {},
292 activeDirectoryEnabled: {
293 required: requiredIf(function() {
294 return this.form.ldapAuthenticationEnabled;
295 })
296 },
297 serverUri: {
298 required: requiredIf(function() {
299 return this.form.ldapAuthenticationEnabled;
300 })
301 },
302 bindDn: {
303 required: requiredIf(function() {
304 return this.form.ldapAuthenticationEnabled;
305 })
306 },
307 bindPassword: {
308 required: requiredIf(function() {
309 return this.form.ldapAuthenticationEnabled;
310 })
311 },
312 baseDn: {
313 required: requiredIf(function() {
314 return this.form.ldapAuthenticationEnabled;
315 })
316 },
317 userIdAttribute: {},
318 groupIdAttribute: {}
319 }
320 },
321 created() {
322 this.$store.dispatch('ldap/getAccountSettings');
323 this.$store.dispatch('sslCertificates/getCertificates');
324 if (this.form.activeDirectoryEnabled) {
325 this.setFormValues(this.activeDirectory);
326 } else {
327 this.setFormValues(this.ldap);
328 }
329 },
330 methods: {
331 setFormValues({
332 serviceAddress = '',
333 bindDn = '',
334 baseDn = '',
335 userAttribute = '',
336 groupsAttribute = ''
337 }) {
338 const secureLdap =
339 serviceAddress && serviceAddress.includes('ldaps://') ? true : false;
340 const serverUri = serviceAddress
341 ? serviceAddress.replace(/ldaps?:\/\//, '')
342 : '';
343 this.form.secureLdapEnabled = secureLdap;
344 this.form.serverUri = serverUri;
345 this.form.bindDn = bindDn;
346 this.form.bindPassword = '';
347 this.form.baseDn = baseDn;
348 this.form.userIdAttribute = userAttribute;
349 this.form.groupIdAttribute = groupsAttribute;
350 },
351 handleSubmit() {
352 this.$v.$touch();
353 if (this.$v.$invalid) return;
354 const data = {
355 serviceEnabled: this.form.ldapAuthenticationEnabled,
356 activeDirectoryEnabled: this.form.activeDirectoryEnabled,
357 serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`,
358 bindDn: this.form.bindDn,
359 bindPassword: this.form.bindPassword,
360 baseDn: this.form.baseDn,
361 userIdAttribute: this.form.userIdAttribute,
362 groupIdAttribute: this.form.groupIdAttribute
363 };
364 this.$store
365 .dispatch('ldap/saveAccountSettings', data)
366 .then(success => {
367 this.successToast(success);
368 this.$v.form.$reset();
369 })
370 .catch(({ message }) => this.errorToast(message))
371 .finally(() => {
372 this.form.bindPassword = '';
373 });
374 },
375 onChangeServiceType(isActiveDirectoryEnabled) {
376 this.$v.form.activeDirectoryEnabled.$touch();
377 const serviceType = isActiveDirectoryEnabled
378 ? this.activeDirectory
379 : this.ldap;
380 this.setFormValues(serviceType);
381 },
382 onChangeldapAuthenticationEnabled(isServiceEnabled) {
383 this.$v.form.ldapAuthenticationEnabled.$touch();
384 if (!isServiceEnabled) {
385 // Request will fail if sent with empty values.
386 // The frontend only checks for required fields
387 // when the service is enabled. This is to prevent
388 // an error if a user clears any properties then
389 // disables the service.
390 if (this.form.activeDirectoryEnabled) {
391 this.setFormValues(this.activeDirectory);
392 } else {
393 this.setFormValues(this.ldap);
394 }
395 }
396 }
397 }
398};
399</script>