blob: 2717201947b6c5ee31350b39b639610f25a92f2b [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">
Derick Montague602e98a2020-10-21 16:20:00 -050099 <template #label>
Mateusz Gapski471f2e02020-07-27 14:43:26 +0200100 {{ $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)"
Dixsie Wolmers5ea16782020-07-27 17:50:43 -0500149 class="form-control-with-button"
Mateusz Gapski471f2e02020-07-27 14:43:26 +0200150 @change="$v.form.bindPassword.$touch()"
151 />
152 <b-form-invalid-feedback role="alert">
153 {{ $t('global.form.fieldRequired') }}
154 </b-form-invalid-feedback>
155 </input-password-toggle>
156 </b-form-group>
157 </b-col>
158 <b-col sm="6" xl="4">
159 <b-form-group
160 :label="$t('pageLdap.form.baseDn')"
161 label-for="base-dn"
162 >
163 <b-form-input
164 id="base-dn"
165 v-model="form.baseDn"
166 data-test-id="ldap-input-baseDn"
167 :state="getValidationState($v.form.baseDn)"
168 @change="$v.form.baseDn.$touch()"
169 />
170 <b-form-invalid-feedback role="alert">
171 {{ $t('global.form.fieldRequired') }}
172 </b-form-invalid-feedback>
173 </b-form-group>
174 </b-col>
175 <b-col sm="6" xl="4">
Dixsie Wolmers46f17ef2020-09-08 14:53:25 -0500176 <b-form-group label-for="user-id-attribute">
Derick Montague602e98a2020-10-21 16:20:00 -0500177 <template #label>
Dixsie Wolmers46f17ef2020-09-08 14:53:25 -0500178 {{ $t('pageLdap.form.userIdAttribute') }} -
179 <span class="form-text d-inline">
180 {{ $t('global.form.optional') }}
181 </span>
182 </template>
Mateusz Gapski471f2e02020-07-27 14:43:26 +0200183 <b-form-input
184 id="user-id-attribute"
185 v-model="form.userIdAttribute"
186 data-test-id="ldap-input-userIdAttribute"
187 @change="$v.form.userIdAttribute.$touch()"
188 />
189 </b-form-group>
190 </b-col>
191 <b-col sm="6" xl="4">
Dixsie Wolmers46f17ef2020-09-08 14:53:25 -0500192 <b-form-group label-for="group-id-attribute">
Derick Montague602e98a2020-10-21 16:20:00 -0500193 <template #label>
Dixsie Wolmers46f17ef2020-09-08 14:53:25 -0500194 {{ $t('pageLdap.form.groupIdAttribute') }} -
195 <span class="form-text d-inline">
196 {{ $t('global.form.optional') }}
197 </span>
198 </template>
Mateusz Gapski471f2e02020-07-27 14:43:26 +0200199 <b-form-input
200 id="group-id-attribute"
201 v-model="form.groupIdAttribute"
202 data-test-id="ldap-input-groupIdAttribute"
203 @change="$v.form.groupIdAttribute.$touch()"
204 />
205 </b-form-group>
206 </b-col>
207 </b-row>
208 </b-col>
209 </b-row>
210 </b-form-group>
211 </div>
212 <b-row class="mt-4 mb-5">
213 <b-col>
214 <b-btn
215 variant="primary"
216 type="submit"
217 data-test-id="ldap-button-saveSettings"
Mateusz Gapski471f2e02020-07-27 14:43:26 +0200218 >
219 {{ $t('global.action.saveSettings') }}
220 </b-btn>
221 </b-col>
222 </b-row>
223 </b-form-group>
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700224 </b-form>
225 </page-section>
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700226
227 <!-- Role groups -->
228 <page-section :section-title="$t('pageLdap.roleGroups')">
229 <table-role-groups />
230 </page-section>
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700231 </b-container>
232</template>
233
234<script>
235import { mapGetters } from 'vuex';
236import { find } from 'lodash';
237import { requiredIf } from 'vuelidate/lib/validators';
238
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700239import BVToastMixin from '@/components/Mixins/BVToastMixin';
240import VuelidateMixin from '@/components/Mixins/VuelidateMixin';
241import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
Derick Montagued853fba2020-07-16 11:24:10 -0500242import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700243import PageTitle from '@/components/Global/PageTitle';
244import PageSection from '@/components/Global/PageSection';
245import InfoTooltip from '@/components/Global/InfoTooltip';
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700246import TableRoleGroups from './TableRoleGroups';
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700247
248export default {
249 name: 'Ldap',
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700250 components: {
251 InfoTooltip,
252 InputPasswordToggle,
253 PageTitle,
254 PageSection,
Derick Montague602e98a2020-10-21 16:20:00 -0500255 TableRoleGroups,
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700256 },
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700257 mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin],
Derick Montague602e98a2020-10-21 16:20:00 -0500258 beforeRouteLeave(to, from, next) {
259 this.hideLoader();
260 next();
261 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700262 data() {
263 return {
264 form: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700265 ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700266 secureLdapEnabled: false,
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700267 activeDirectoryEnabled: this.$store.getters[
268 'ldap/isActiveDirectoryEnabled'
269 ],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700270 serverUri: '',
271 bindDn: '',
272 bindPassword: '',
273 baseDn: '',
274 userIdAttribute: '',
Derick Montague602e98a2020-10-21 16:20:00 -0500275 groupIdAttribute: '',
276 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700277 };
278 },
279 computed: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700280 ...mapGetters('ldap', [
281 'isServiceEnabled',
282 'isActiveDirectoryEnabled',
283 'ldap',
Derick Montague602e98a2020-10-21 16:20:00 -0500284 'activeDirectory',
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700285 ]),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700286 sslCertificates() {
287 return this.$store.getters['sslCertificates/allCertificates'];
288 },
289 caCertificateExpiration() {
290 const caCertificate = find(this.sslCertificates, {
Derick Montague602e98a2020-10-21 16:20:00 -0500291 type: 'TrustStore Certificate',
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700292 });
293 if (caCertificate === undefined) return null;
294 return caCertificate.validUntil;
295 },
296 ldapCertificateExpiration() {
297 const ldapCertificate = find(this.sslCertificates, {
Derick Montague602e98a2020-10-21 16:20:00 -0500298 type: 'LDAP Certificate',
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700299 });
300 if (ldapCertificate === undefined) return null;
301 return ldapCertificate.validUntil;
302 },
303 ldapProtocol() {
304 return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://';
Derick Montague602e98a2020-10-21 16:20:00 -0500305 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700306 },
307 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -0500308 isServiceEnabled: function (value) {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700309 this.form.ldapAuthenticationEnabled = value;
310 },
Derick Montague602e98a2020-10-21 16:20:00 -0500311 isActiveDirectoryEnabled: function (value) {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700312 this.form.activeDirectoryEnabled = value;
313 this.setFormValues();
Derick Montague602e98a2020-10-21 16:20:00 -0500314 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700315 },
316 validations: {
317 form: {
318 ldapAuthenticationEnabled: {},
319 secureLdapEnabled: {},
320 activeDirectoryEnabled: {
Derick Montague602e98a2020-10-21 16:20:00 -0500321 required: requiredIf(function () {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700322 return this.form.ldapAuthenticationEnabled;
Derick Montague602e98a2020-10-21 16:20:00 -0500323 }),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700324 },
325 serverUri: {
Derick Montague602e98a2020-10-21 16:20:00 -0500326 required: requiredIf(function () {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700327 return this.form.ldapAuthenticationEnabled;
Derick Montague602e98a2020-10-21 16:20:00 -0500328 }),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700329 },
330 bindDn: {
Derick Montague602e98a2020-10-21 16:20:00 -0500331 required: requiredIf(function () {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700332 return this.form.ldapAuthenticationEnabled;
Derick Montague602e98a2020-10-21 16:20:00 -0500333 }),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700334 },
335 bindPassword: {
Derick Montague602e98a2020-10-21 16:20:00 -0500336 required: requiredIf(function () {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700337 return this.form.ldapAuthenticationEnabled;
Derick Montague602e98a2020-10-21 16:20:00 -0500338 }),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700339 },
340 baseDn: {
Derick Montague602e98a2020-10-21 16:20:00 -0500341 required: requiredIf(function () {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700342 return this.form.ldapAuthenticationEnabled;
Derick Montague602e98a2020-10-21 16:20:00 -0500343 }),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700344 },
345 userIdAttribute: {},
Derick Montague602e98a2020-10-21 16:20:00 -0500346 groupIdAttribute: {},
347 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700348 },
349 created() {
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700350 this.startLoader();
351 this.$store
352 .dispatch('ldap/getAccountSettings')
353 .finally(() => this.endLoader());
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700354 this.$store.dispatch('sslCertificates/getCertificates');
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700355 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700356 },
357 methods: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700358 setFormValues(serviceType) {
359 if (!serviceType) {
360 serviceType = this.isActiveDirectoryEnabled
361 ? this.activeDirectory
362 : this.ldap;
363 }
364 const {
365 serviceAddress = '',
366 bindDn = '',
367 baseDn = '',
368 userAttribute = '',
Derick Montague602e98a2020-10-21 16:20:00 -0500369 groupsAttribute = '',
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700370 } = serviceType;
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700371 const secureLdap =
372 serviceAddress && serviceAddress.includes('ldaps://') ? true : false;
373 const serverUri = serviceAddress
374 ? serviceAddress.replace(/ldaps?:\/\//, '')
375 : '';
376 this.form.secureLdapEnabled = secureLdap;
377 this.form.serverUri = serverUri;
378 this.form.bindDn = bindDn;
379 this.form.bindPassword = '';
380 this.form.baseDn = baseDn;
381 this.form.userIdAttribute = userAttribute;
382 this.form.groupIdAttribute = groupsAttribute;
383 },
384 handleSubmit() {
385 this.$v.$touch();
386 if (this.$v.$invalid) return;
387 const data = {
388 serviceEnabled: this.form.ldapAuthenticationEnabled,
389 activeDirectoryEnabled: this.form.activeDirectoryEnabled,
390 serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`,
391 bindDn: this.form.bindDn,
392 bindPassword: this.form.bindPassword,
393 baseDn: this.form.baseDn,
394 userIdAttribute: this.form.userIdAttribute,
Derick Montague602e98a2020-10-21 16:20:00 -0500395 groupIdAttribute: this.form.groupIdAttribute,
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700396 };
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700397 this.startLoader();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700398 this.$store
399 .dispatch('ldap/saveAccountSettings', data)
Derick Montague602e98a2020-10-21 16:20:00 -0500400 .then((success) => {
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700401 this.successToast(success);
402 this.$v.form.$reset();
403 })
404 .catch(({ message }) => this.errorToast(message))
405 .finally(() => {
406 this.form.bindPassword = '';
Yoshie Muranakae9a59c72020-04-30 12:16:30 -0700407 this.endLoader();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700408 });
409 },
410 onChangeServiceType(isActiveDirectoryEnabled) {
411 this.$v.form.activeDirectoryEnabled.$touch();
412 const serviceType = isActiveDirectoryEnabled
413 ? this.activeDirectory
414 : this.ldap;
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700415 // Set form values according to user selected
416 // service type
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700417 this.setFormValues(serviceType);
418 },
419 onChangeldapAuthenticationEnabled(isServiceEnabled) {
420 this.$v.form.ldapAuthenticationEnabled.$touch();
421 if (!isServiceEnabled) {
422 // Request will fail if sent with empty values.
423 // The frontend only checks for required fields
424 // when the service is enabled. This is to prevent
425 // an error if a user clears any properties then
426 // disables the service.
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700427 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700428 }
Derick Montague602e98a2020-10-21 16:20:00 -0500429 },
430 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700431};
432</script>