blob: 8bebed9c907e13f86ef73f2935b94d2a024603f7 [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">
Mateusz Gapski471f2e02020-07-27 14:43:26 +02006 <b-form-group :disabled="loading">
7 <b-row>
8 <b-col>
9 <b-form-group
10 class="mb-3"
11 :label="$t('pageLdap.form.ldapAuthentication')"
12 label-for="enable-ldap-auth"
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -070013 >
Mateusz Gapski471f2e02020-07-27 14:43:26 +020014 <b-form-checkbox
15 id="enable-ldap-auth"
16 v-model="form.ldapAuthenticationEnabled"
17 data-test-id="ldap-checkbox-ldapAuthenticationEnabled"
18 @change="onChangeldapAuthenticationEnabled"
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -070019 >
Mateusz Gapski471f2e02020-07-27 14:43:26 +020020 {{ $t('global.action.enable') }}
21 </b-form-checkbox>
22 </b-form-group>
23 </b-col>
24 </b-row>
25 <div class="form-background p-3">
26 <b-form-group
27 class="m-0"
28 :label="$t('pageLdap.ariaLabel.ldapSettings')"
29 label-class="sr-only"
30 :disabled="!form.ldapAuthenticationEnabled"
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -070031 >
Mateusz Gapski471f2e02020-07-27 14:43:26 +020032 <b-row>
33 <b-col md="3" lg="4" xl="3">
34 <b-form-group
35 class="mb-4"
36 :label="$t('pageLdap.form.secureLdapUsingSsl')"
37 >
38 <b-form-text id="enable-secure-help-block">
39 {{ $t('pageLdap.form.secureLdapHelper') }}
40 </b-form-text>
41 <b-form-checkbox
42 id="enable-secure-ldap"
43 v-model="form.secureLdapEnabled"
44 aria-describedby="enable-secure-help-block"
45 data-test-id="ldap-checkbox-secureLdapEnabled"
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 data-test-id="ldap-radio-activeDirectoryEnabled"
80 :value="false"
81 @change="onChangeServiceType"
82 >
83 OpenLDAP
84 </b-form-radio>
85 <b-form-radio
86 v-model="form.activeDirectoryEnabled"
87 data-test-id="ldap-radio-activeDirectoryEnabled"
88 :value="true"
89 @change="onChangeServiceType"
90 >
91 Active Directory
92 </b-form-radio>
93 </b-form-group>
94 </b-col>
95 </b-row>
96 <b-row>
97 <b-col sm="6" xl="4">
98 <b-form-group label-for="server-uri">
99 <template v-slot:label>
100 {{ $t('pageLdap.form.serverUri') }}
101 <info-tooltip
102 :title="$t('pageLdap.form.serverUriTooltip')"
103 />
104 </template>
105 <b-input-group :prepend="ldapProtocol">
106 <b-form-input
107 id="server-uri"
108 v-model="form.serverUri"
109 data-test-id="ldap-input-serverUri"
110 :state="getValidationState($v.form.serverUri)"
111 @change="$v.form.serverUri.$touch()"
112 />
113 <b-form-invalid-feedback role="alert">
114 {{ $t('global.form.fieldRequired') }}
115 </b-form-invalid-feedback>
116 </b-input-group>
117 </b-form-group>
118 </b-col>
119 <b-col sm="6" xl="4">
120 <b-form-group
121 :label="$t('pageLdap.form.bindDn')"
122 label-for="bind-dn"
123 >
124 <b-form-input
125 id="bind-dn"
126 v-model="form.bindDn"
127 data-test-id="ldap-input-bindDn"
128 :state="getValidationState($v.form.bindDn)"
129 @change="$v.form.bindDn.$touch()"
130 />
131 <b-form-invalid-feedback role="alert">
132 {{ $t('global.form.fieldRequired') }}
133 </b-form-invalid-feedback>
134 </b-form-group>
135 </b-col>
136 <b-col sm="6" xl="4">
137 <b-form-group
138 :label="$t('pageLdap.form.bindPassword')"
139 label-for="bind-password"
140 >
141 <input-password-toggle
142 data-test-id="ldap-input-togglePassword"
143 >
144 <b-form-input
145 id="bind-password"
146 v-model="form.bindPassword"
147 type="password"
148 :state="getValidationState($v.form.bindPassword)"
149 @change="$v.form.bindPassword.$touch()"
150 />
151 <b-form-invalid-feedback role="alert">
152 {{ $t('global.form.fieldRequired') }}
153 </b-form-invalid-feedback>
154 </input-password-toggle>
155 </b-form-group>
156 </b-col>
157 <b-col sm="6" xl="4">
158 <b-form-group
159 :label="$t('pageLdap.form.baseDn')"
160 label-for="base-dn"
161 >
162 <b-form-input
163 id="base-dn"
164 v-model="form.baseDn"
165 data-test-id="ldap-input-baseDn"
166 :state="getValidationState($v.form.baseDn)"
167 @change="$v.form.baseDn.$touch()"
168 />
169 <b-form-invalid-feedback role="alert">
170 {{ $t('global.form.fieldRequired') }}
171 </b-form-invalid-feedback>
172 </b-form-group>
173 </b-col>
174 <b-col sm="6" xl="4">
175 <b-form-group
176 :label="$t('pageLdap.form.userIdAttribute')"
177 label-for="user-id-attribute"
178 >
179 <b-form-input
180 id="user-id-attribute"
181 v-model="form.userIdAttribute"
182 data-test-id="ldap-input-userIdAttribute"
183 @change="$v.form.userIdAttribute.$touch()"
184 />
185 </b-form-group>
186 </b-col>
187 <b-col sm="6" xl="4">
188 <b-form-group
189 :label="$t('pageLdap.form.groupIdAttribute')"
190 label-for="group-id-attribute"
191 >
192 <b-form-input
193 id="group-id-attribute"
194 v-model="form.groupIdAttribute"
195 data-test-id="ldap-input-groupIdAttribute"
196 @change="$v.form.groupIdAttribute.$touch()"
197 />
198 </b-form-group>
199 </b-col>
200 </b-row>
201 </b-col>
202 </b-row>
203 </b-form-group>
204 </div>
205 <b-row class="mt-4 mb-5">
206 <b-col>
207 <b-btn
208 variant="primary"
209 type="submit"
210 data-test-id="ldap-button-saveSettings"
211 :disabled="!$v.form.$anyDirty"
212 >
213 {{ $t('global.action.saveSettings') }}
214 </b-btn>
215 </b-col>
216 </b-row>
217 </b-form-group>
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700218 </b-form>
219 </page-section>
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700220
221 <!-- Role groups -->
222 <page-section :section-title="$t('pageLdap.roleGroups')">
223 <table-role-groups />
224 </page-section>
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700225 </b-container>
226</template>
227
228<script>
229import { mapGetters } from 'vuex';
230import { find } from 'lodash';
231import { requiredIf } from 'vuelidate/lib/validators';
232
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700233import BVToastMixin from '@/components/Mixins/BVToastMixin';
234import VuelidateMixin from '@/components/Mixins/VuelidateMixin';
235import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
Derick Montagued853fba2020-07-16 11:24:10 -0500236import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700237import PageTitle from '@/components/Global/PageTitle';
238import PageSection from '@/components/Global/PageSection';
239import InfoTooltip from '@/components/Global/InfoTooltip';
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700240import TableRoleGroups from './TableRoleGroups';
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700241
242export default {
243 name: 'Ldap',
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700244 components: {
245 InfoTooltip,
246 InputPasswordToggle,
247 PageTitle,
248 PageSection,
249 TableRoleGroups
250 },
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700251 mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700252 data() {
253 return {
254 form: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700255 ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700256 secureLdapEnabled: false,
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700257 activeDirectoryEnabled: this.$store.getters[
258 'ldap/isActiveDirectoryEnabled'
259 ],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700260 serverUri: '',
261 bindDn: '',
262 bindPassword: '',
263 baseDn: '',
264 userIdAttribute: '',
265 groupIdAttribute: ''
266 }
267 };
268 },
269 computed: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700270 ...mapGetters('ldap', [
271 'isServiceEnabled',
272 'isActiveDirectoryEnabled',
273 'ldap',
274 'activeDirectory'
275 ]),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700276 sslCertificates() {
277 return this.$store.getters['sslCertificates/allCertificates'];
278 },
279 caCertificateExpiration() {
280 const caCertificate = find(this.sslCertificates, {
281 type: 'TrustStore Certificate'
282 });
283 if (caCertificate === undefined) return null;
284 return caCertificate.validUntil;
285 },
286 ldapCertificateExpiration() {
287 const ldapCertificate = find(this.sslCertificates, {
288 type: 'LDAP Certificate'
289 });
290 if (ldapCertificate === undefined) return null;
291 return ldapCertificate.validUntil;
292 },
293 ldapProtocol() {
294 return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://';
295 }
296 },
297 watch: {
298 isServiceEnabled: function(value) {
299 this.form.ldapAuthenticationEnabled = value;
300 },
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700301 isActiveDirectoryEnabled: function(value) {
302 this.form.activeDirectoryEnabled = value;
303 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700304 }
305 },
306 validations: {
307 form: {
308 ldapAuthenticationEnabled: {},
309 secureLdapEnabled: {},
310 activeDirectoryEnabled: {
311 required: requiredIf(function() {
312 return this.form.ldapAuthenticationEnabled;
313 })
314 },
315 serverUri: {
316 required: requiredIf(function() {
317 return this.form.ldapAuthenticationEnabled;
318 })
319 },
320 bindDn: {
321 required: requiredIf(function() {
322 return this.form.ldapAuthenticationEnabled;
323 })
324 },
325 bindPassword: {
326 required: requiredIf(function() {
327 return this.form.ldapAuthenticationEnabled;
328 })
329 },
330 baseDn: {
331 required: requiredIf(function() {
332 return this.form.ldapAuthenticationEnabled;
333 })
334 },
335 userIdAttribute: {},
336 groupIdAttribute: {}
337 }
338 },
339 created() {
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700340 this.startLoader();
341 this.$store
342 .dispatch('ldap/getAccountSettings')
343 .finally(() => this.endLoader());
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700344 this.$store.dispatch('sslCertificates/getCertificates');
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700345 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700346 },
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700347 beforeRouteLeave(to, from, next) {
348 this.hideLoader();
349 next();
350 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700351 methods: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700352 setFormValues(serviceType) {
353 if (!serviceType) {
354 serviceType = this.isActiveDirectoryEnabled
355 ? this.activeDirectory
356 : this.ldap;
357 }
358 const {
359 serviceAddress = '',
360 bindDn = '',
361 baseDn = '',
362 userAttribute = '',
363 groupsAttribute = ''
364 } = serviceType;
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700365 const secureLdap =
366 serviceAddress && serviceAddress.includes('ldaps://') ? true : false;
367 const serverUri = serviceAddress
368 ? serviceAddress.replace(/ldaps?:\/\//, '')
369 : '';
370 this.form.secureLdapEnabled = secureLdap;
371 this.form.serverUri = serverUri;
372 this.form.bindDn = bindDn;
373 this.form.bindPassword = '';
374 this.form.baseDn = baseDn;
375 this.form.userIdAttribute = userAttribute;
376 this.form.groupIdAttribute = groupsAttribute;
377 },
378 handleSubmit() {
379 this.$v.$touch();
380 if (this.$v.$invalid) return;
381 const data = {
382 serviceEnabled: this.form.ldapAuthenticationEnabled,
383 activeDirectoryEnabled: this.form.activeDirectoryEnabled,
384 serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`,
385 bindDn: this.form.bindDn,
386 bindPassword: this.form.bindPassword,
387 baseDn: this.form.baseDn,
388 userIdAttribute: this.form.userIdAttribute,
389 groupIdAttribute: this.form.groupIdAttribute
390 };
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700391 this.startLoader();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700392 this.$store
393 .dispatch('ldap/saveAccountSettings', data)
394 .then(success => {
395 this.successToast(success);
396 this.$v.form.$reset();
397 })
398 .catch(({ message }) => this.errorToast(message))
399 .finally(() => {
400 this.form.bindPassword = '';
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700401 this.endLoader();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700402 });
403 },
404 onChangeServiceType(isActiveDirectoryEnabled) {
405 this.$v.form.activeDirectoryEnabled.$touch();
406 const serviceType = isActiveDirectoryEnabled
407 ? this.activeDirectory
408 : this.ldap;
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700409 // Set form values according to user selected
410 // service type
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700411 this.setFormValues(serviceType);
412 },
413 onChangeldapAuthenticationEnabled(isServiceEnabled) {
414 this.$v.form.ldapAuthenticationEnabled.$touch();
415 if (!isServiceEnabled) {
416 // Request will fail if sent with empty values.
417 // The frontend only checks for required fields
418 // when the service is enabled. This is to prevent
419 // an error if a user clears any properties then
420 // disables the service.
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700421 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700422 }
423 }
424 }
425};
426</script>