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