blob: 3ae4784fc90fdbdc6e538a1f131f5888aacda703 [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
219import BVToastMixin from '@/components/Mixins/BVToastMixin.js';
220import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
221import PageTitle from '@/components/Global/PageTitle';
222import PageSection from '@/components/Global/PageSection';
223import InfoTooltip from '@/components/Global/InfoTooltip';
224import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700225import TableRoleGroups from './TableRoleGroups';
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700226
227export default {
228 name: 'Ldap',
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700229 components: {
230 InfoTooltip,
231 InputPasswordToggle,
232 PageTitle,
233 PageSection,
234 TableRoleGroups
235 },
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700236 mixins: [BVToastMixin, VuelidateMixin],
237 data() {
238 return {
239 form: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700240 ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700241 secureLdapEnabled: false,
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700242 activeDirectoryEnabled: this.$store.getters[
243 'ldap/isActiveDirectoryEnabled'
244 ],
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700245 serverUri: '',
246 bindDn: '',
247 bindPassword: '',
248 baseDn: '',
249 userIdAttribute: '',
250 groupIdAttribute: ''
251 }
252 };
253 },
254 computed: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700255 ...mapGetters('ldap', [
256 'isServiceEnabled',
257 'isActiveDirectoryEnabled',
258 'ldap',
259 'activeDirectory'
260 ]),
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700261 sslCertificates() {
262 return this.$store.getters['sslCertificates/allCertificates'];
263 },
264 caCertificateExpiration() {
265 const caCertificate = find(this.sslCertificates, {
266 type: 'TrustStore Certificate'
267 });
268 if (caCertificate === undefined) return null;
269 return caCertificate.validUntil;
270 },
271 ldapCertificateExpiration() {
272 const ldapCertificate = find(this.sslCertificates, {
273 type: 'LDAP Certificate'
274 });
275 if (ldapCertificate === undefined) return null;
276 return ldapCertificate.validUntil;
277 },
278 ldapProtocol() {
279 return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://';
280 }
281 },
282 watch: {
283 isServiceEnabled: function(value) {
284 this.form.ldapAuthenticationEnabled = value;
285 },
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700286 isActiveDirectoryEnabled: function(value) {
287 this.form.activeDirectoryEnabled = value;
288 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700289 }
290 },
291 validations: {
292 form: {
293 ldapAuthenticationEnabled: {},
294 secureLdapEnabled: {},
295 activeDirectoryEnabled: {
296 required: requiredIf(function() {
297 return this.form.ldapAuthenticationEnabled;
298 })
299 },
300 serverUri: {
301 required: requiredIf(function() {
302 return this.form.ldapAuthenticationEnabled;
303 })
304 },
305 bindDn: {
306 required: requiredIf(function() {
307 return this.form.ldapAuthenticationEnabled;
308 })
309 },
310 bindPassword: {
311 required: requiredIf(function() {
312 return this.form.ldapAuthenticationEnabled;
313 })
314 },
315 baseDn: {
316 required: requiredIf(function() {
317 return this.form.ldapAuthenticationEnabled;
318 })
319 },
320 userIdAttribute: {},
321 groupIdAttribute: {}
322 }
323 },
324 created() {
325 this.$store.dispatch('ldap/getAccountSettings');
326 this.$store.dispatch('sslCertificates/getCertificates');
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700327 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700328 },
329 methods: {
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700330 setFormValues(serviceType) {
331 if (!serviceType) {
332 serviceType = this.isActiveDirectoryEnabled
333 ? this.activeDirectory
334 : this.ldap;
335 }
336 const {
337 serviceAddress = '',
338 bindDn = '',
339 baseDn = '',
340 userAttribute = '',
341 groupsAttribute = ''
342 } = serviceType;
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700343 const secureLdap =
344 serviceAddress && serviceAddress.includes('ldaps://') ? true : false;
345 const serverUri = serviceAddress
346 ? serviceAddress.replace(/ldaps?:\/\//, '')
347 : '';
348 this.form.secureLdapEnabled = secureLdap;
349 this.form.serverUri = serverUri;
350 this.form.bindDn = bindDn;
351 this.form.bindPassword = '';
352 this.form.baseDn = baseDn;
353 this.form.userIdAttribute = userAttribute;
354 this.form.groupIdAttribute = groupsAttribute;
355 },
356 handleSubmit() {
357 this.$v.$touch();
358 if (this.$v.$invalid) return;
359 const data = {
360 serviceEnabled: this.form.ldapAuthenticationEnabled,
361 activeDirectoryEnabled: this.form.activeDirectoryEnabled,
362 serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`,
363 bindDn: this.form.bindDn,
364 bindPassword: this.form.bindPassword,
365 baseDn: this.form.baseDn,
366 userIdAttribute: this.form.userIdAttribute,
367 groupIdAttribute: this.form.groupIdAttribute
368 };
369 this.$store
370 .dispatch('ldap/saveAccountSettings', data)
371 .then(success => {
372 this.successToast(success);
373 this.$v.form.$reset();
374 })
375 .catch(({ message }) => this.errorToast(message))
376 .finally(() => {
377 this.form.bindPassword = '';
378 });
379 },
380 onChangeServiceType(isActiveDirectoryEnabled) {
381 this.$v.form.activeDirectoryEnabled.$touch();
382 const serviceType = isActiveDirectoryEnabled
383 ? this.activeDirectory
384 : this.ldap;
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700385 // Set form values according to user selected
386 // service type
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700387 this.setFormValues(serviceType);
388 },
389 onChangeldapAuthenticationEnabled(isServiceEnabled) {
390 this.$v.form.ldapAuthenticationEnabled.$touch();
391 if (!isServiceEnabled) {
392 // Request will fail if sent with empty values.
393 // The frontend only checks for required fields
394 // when the service is enabled. This is to prevent
395 // an error if a user clears any properties then
396 // disables the service.
Yoshie Muranakadc3d5412020-04-17 09:39:41 -0700397 this.setFormValues();
Yoshie Muranakac4e38ab2020-04-09 12:41:27 -0700398 }
399 }
400 }
401};
402</script>