| <template> |
| <b-container fluid="xl"> |
| <page-title :description="$t('pageLdap.pageDescription')" /> |
| <page-section :section-title="$t('pageLdap.settings')"> |
| <b-form novalidate @submit.prevent="handleSubmit"> |
| <b-row> |
| <b-col> |
| <b-form-group |
| class="mb-3" |
| :label="$t('pageLdap.form.ldapAuthentication')" |
| :disabled="loading" |
| > |
| <b-form-checkbox |
| v-model="form.ldapAuthenticationEnabled" |
| data-test-id="ldap-checkbox-ldapAuthenticationEnabled" |
| @change="onChangeldapAuthenticationEnabled" |
| > |
| {{ $t('global.action.enable') }} |
| </b-form-checkbox> |
| </b-form-group> |
| </b-col> |
| </b-row> |
| <div class="form-background p-3"> |
| <b-form-group |
| class="m-0" |
| :label="$t('pageLdap.ariaLabel.ldapSettings')" |
| label-class="sr-only" |
| :disabled="!form.ldapAuthenticationEnabled || loading" |
| > |
| <b-row> |
| <b-col md="3" lg="4" xl="3"> |
| <b-form-group |
| class="mb-4" |
| :label="$t('pageLdap.form.secureLdapUsingSsl')" |
| > |
| <b-form-text id="enable-secure-help-block"> |
| {{ $t('pageLdap.form.secureLdapHelper') }} |
| </b-form-text> |
| <b-form-checkbox |
| id="enable-secure-ldap" |
| v-model="form.secureLdapEnabled" |
| aria-describedby="enable-secure-help-block" |
| data-test-id="ldap-checkbox-secureLdapEnabled" |
| :disabled=" |
| !caCertificateExpiration || !ldapCertificateExpiration |
| " |
| @change="$v.form.secureLdapEnabled.$touch()" |
| > |
| {{ $t('global.action.enable') }} |
| </b-form-checkbox> |
| </b-form-group> |
| <dl> |
| <dt>{{ $t('pageLdap.form.caCertificateValidUntil') }}</dt> |
| <dd v-if="caCertificateExpiration"> |
| {{ caCertificateExpiration }} |
| </dd> |
| <dd v-else>--</dd> |
| <dt>{{ $t('pageLdap.form.ldapCertificateValidUntil') }}</dt> |
| <dd v-if="ldapCertificateExpiration"> |
| {{ ldapCertificateExpiration }} |
| </dd> |
| <dd v-else>--</dd> |
| </dl> |
| <b-link |
| class="d-inline-block mb-4 m-md-0" |
| to="/security-and-access/certificates" |
| > |
| {{ $t('pageLdap.form.manageSslCertificates') }} |
| </b-link> |
| </b-col> |
| <b-col md="9" lg="8" xl="9"> |
| <b-row> |
| <b-col> |
| <b-form-group :label="$t('pageLdap.form.serviceType')"> |
| <b-form-radio |
| v-model="form.activeDirectoryEnabled" |
| data-test-id="ldap-radio-activeDirectoryEnabled" |
| :value="false" |
| @change="onChangeServiceType" |
| > |
| {{ $t('pageLdap.form.openLDAP') }} |
| </b-form-radio> |
| <b-form-radio |
| v-model="form.activeDirectoryEnabled" |
| data-test-id="ldap-radio-activeDirectoryEnabled" |
| :value="true" |
| @change="onChangeServiceType" |
| > |
| {{ $t('pageLdap.form.activeDirectory') }} |
| </b-form-radio> |
| </b-form-group> |
| </b-col> |
| </b-row> |
| <b-row> |
| <b-col sm="6" xl="4"> |
| <b-form-group label-for="server-uri"> |
| <template #label> |
| {{ $t('pageLdap.form.serverUri') }} |
| <info-tooltip |
| :title="$t('pageLdap.form.serverUriTooltip')" |
| /> |
| </template> |
| <b-input-group :prepend="ldapProtocol"> |
| <b-form-input |
| id="server-uri" |
| v-model="form.serverUri" |
| data-test-id="ldap-input-serverUri" |
| :state="getValidationState($v.form.serverUri)" |
| @change="$v.form.serverUri.$touch()" |
| /> |
| <b-form-invalid-feedback role="alert"> |
| {{ $t('global.form.fieldRequired') }} |
| </b-form-invalid-feedback> |
| </b-input-group> |
| </b-form-group> |
| </b-col> |
| <b-col sm="6" xl="4"> |
| <b-form-group |
| :label="$t('pageLdap.form.bindDn')" |
| label-for="bind-dn" |
| > |
| <b-form-input |
| id="bind-dn" |
| v-model="form.bindDn" |
| data-test-id="ldap-input-bindDn" |
| :state="getValidationState($v.form.bindDn)" |
| @change="$v.form.bindDn.$touch()" |
| /> |
| <b-form-invalid-feedback role="alert"> |
| {{ $t('global.form.fieldRequired') }} |
| </b-form-invalid-feedback> |
| </b-form-group> |
| </b-col> |
| <b-col sm="6" xl="4"> |
| <b-form-group |
| :label="$t('pageLdap.form.bindPassword')" |
| label-for="bind-password" |
| > |
| <input-password-toggle |
| data-test-id="ldap-input-togglePassword" |
| > |
| <b-form-input |
| id="bind-password" |
| v-model="form.bindPassword" |
| type="password" |
| :state="getValidationState($v.form.bindPassword)" |
| class="form-control-with-button" |
| @change="$v.form.bindPassword.$touch()" |
| /> |
| <b-form-invalid-feedback role="alert"> |
| {{ $t('global.form.fieldRequired') }} |
| </b-form-invalid-feedback> |
| </input-password-toggle> |
| </b-form-group> |
| </b-col> |
| <b-col sm="6" xl="4"> |
| <b-form-group |
| :label="$t('pageLdap.form.baseDn')" |
| label-for="base-dn" |
| > |
| <b-form-input |
| id="base-dn" |
| v-model="form.baseDn" |
| data-test-id="ldap-input-baseDn" |
| :state="getValidationState($v.form.baseDn)" |
| @change="$v.form.baseDn.$touch()" |
| /> |
| <b-form-invalid-feedback role="alert"> |
| {{ $t('global.form.fieldRequired') }} |
| </b-form-invalid-feedback> |
| </b-form-group> |
| </b-col> |
| <b-col sm="6" xl="4"> |
| <b-form-group label-for="user-id-attribute"> |
| <template #label> |
| {{ $t('pageLdap.form.userIdAttribute') }} - |
| <span class="form-text d-inline"> |
| {{ $t('global.form.optional') }} |
| </span> |
| </template> |
| <b-form-input |
| id="user-id-attribute" |
| v-model="form.userIdAttribute" |
| data-test-id="ldap-input-userIdAttribute" |
| @change="$v.form.userIdAttribute.$touch()" |
| /> |
| </b-form-group> |
| </b-col> |
| <b-col sm="6" xl="4"> |
| <b-form-group label-for="group-id-attribute"> |
| <template #label> |
| {{ $t('pageLdap.form.groupIdAttribute') }} - |
| <span class="form-text d-inline"> |
| {{ $t('global.form.optional') }} |
| </span> |
| </template> |
| <b-form-input |
| id="group-id-attribute" |
| v-model="form.groupIdAttribute" |
| data-test-id="ldap-input-groupIdAttribute" |
| @change="$v.form.groupIdAttribute.$touch()" |
| /> |
| </b-form-group> |
| </b-col> |
| </b-row> |
| </b-col> |
| </b-row> |
| </b-form-group> |
| </div> |
| <b-row class="mt-4 mb-5"> |
| <b-col> |
| <b-btn |
| variant="primary" |
| type="submit" |
| data-test-id="ldap-button-saveSettings" |
| :disabled="loading" |
| > |
| {{ $t('global.action.saveSettings') }} |
| </b-btn> |
| </b-col> |
| </b-row> |
| </b-form> |
| </page-section> |
| |
| <!-- Role groups --> |
| <page-section :section-title="$t('pageLdap.roleGroups')"> |
| <table-role-groups /> |
| </page-section> |
| </b-container> |
| </template> |
| |
| <script> |
| import { mapGetters } from 'vuex'; |
| import { find } from 'lodash'; |
| import { requiredIf } from '@vuelidate/validators'; |
| import { useVuelidate } from '@vuelidate/core'; |
| |
| import BVToastMixin from '@/components/Mixins/BVToastMixin'; |
| import VuelidateMixin from '@/components/Mixins/VuelidateMixin'; |
| import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin'; |
| import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; |
| import PageTitle from '@/components/Global/PageTitle'; |
| import PageSection from '@/components/Global/PageSection'; |
| import InfoTooltip from '@/components/Global/InfoTooltip'; |
| import TableRoleGroups from './TableRoleGroups'; |
| |
| export default { |
| name: 'Ldap', |
| components: { |
| InfoTooltip, |
| InputPasswordToggle, |
| PageTitle, |
| PageSection, |
| TableRoleGroups, |
| }, |
| mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin], |
| beforeRouteLeave(to, from, next) { |
| this.hideLoader(); |
| next(); |
| }, |
| setup() { |
| return { |
| v$: useVuelidate(), |
| }; |
| }, |
| data() { |
| return { |
| form: { |
| ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'], |
| secureLdapEnabled: false, |
| activeDirectoryEnabled: |
| this.$store.getters['ldap/isActiveDirectoryEnabled'], |
| serverUri: '', |
| bindDn: '', |
| bindPassword: '', |
| baseDn: '', |
| userIdAttribute: '', |
| groupIdAttribute: '', |
| loading, |
| }, |
| }; |
| }, |
| computed: { |
| ...mapGetters('ldap', [ |
| 'isServiceEnabled', |
| 'isActiveDirectoryEnabled', |
| 'ldap', |
| 'activeDirectory', |
| ]), |
| sslCertificates() { |
| return this.$store.getters['certificates/allCertificates']; |
| }, |
| caCertificateExpiration() { |
| const caCertificate = find(this.sslCertificates, { |
| type: 'TrustStore Certificate', |
| }); |
| if (caCertificate === undefined) return null; |
| return caCertificate.validUntil; |
| }, |
| ldapCertificateExpiration() { |
| const ldapCertificate = find(this.sslCertificates, { |
| type: 'LDAP Certificate', |
| }); |
| if (ldapCertificate === undefined) return null; |
| return ldapCertificate.validUntil; |
| }, |
| ldapProtocol() { |
| return this.form.secureLdapEnabled ? 'ldaps://' : 'ldap://'; |
| }, |
| }, |
| watch: { |
| isServiceEnabled: function (value) { |
| this.form.ldapAuthenticationEnabled = value; |
| }, |
| isActiveDirectoryEnabled: function (value) { |
| this.form.activeDirectoryEnabled = value; |
| this.setFormValues(); |
| }, |
| }, |
| validations: { |
| form: { |
| ldapAuthenticationEnabled: {}, |
| secureLdapEnabled: {}, |
| activeDirectoryEnabled: { |
| required: requiredIf(function () { |
| return this.form.ldapAuthenticationEnabled; |
| }), |
| }, |
| serverUri: { |
| required: requiredIf(function () { |
| return this.form.ldapAuthenticationEnabled; |
| }), |
| }, |
| bindDn: { |
| required: requiredIf(function () { |
| return this.form.ldapAuthenticationEnabled; |
| }), |
| }, |
| bindPassword: { |
| required: requiredIf(function () { |
| return this.form.ldapAuthenticationEnabled; |
| }), |
| }, |
| baseDn: { |
| required: requiredIf(function () { |
| return this.form.ldapAuthenticationEnabled; |
| }), |
| }, |
| userIdAttribute: {}, |
| groupIdAttribute: {}, |
| }, |
| }, |
| created() { |
| this.startLoader(); |
| this.$store |
| .dispatch('ldap/getAccountSettings') |
| .finally(() => this.endLoader()); |
| this.$store |
| .dispatch('certificates/getCertificates') |
| .finally(() => this.endLoader()); |
| this.setFormValues(); |
| }, |
| methods: { |
| setFormValues(serviceType) { |
| if (!serviceType) { |
| serviceType = this.isActiveDirectoryEnabled |
| ? this.activeDirectory |
| : this.ldap; |
| } |
| const { |
| serviceAddress = '', |
| bindDn = '', |
| baseDn = '', |
| userAttribute = '', |
| groupsAttribute = '', |
| } = serviceType; |
| const secureLdap = |
| serviceAddress && serviceAddress.includes('ldaps://') ? true : false; |
| const serverUri = serviceAddress |
| ? serviceAddress.replace(/ldaps?:\/\//, '') |
| : ''; |
| this.form.secureLdapEnabled = secureLdap; |
| this.form.serverUri = serverUri; |
| this.form.bindDn = bindDn; |
| this.form.bindPassword = ''; |
| this.form.baseDn = baseDn; |
| this.form.userIdAttribute = userAttribute; |
| this.form.groupIdAttribute = groupsAttribute; |
| }, |
| handleSubmit() { |
| this.$v.$touch(); |
| if (this.$v.$invalid) return; |
| const data = { |
| serviceEnabled: this.form.ldapAuthenticationEnabled, |
| activeDirectoryEnabled: this.form.activeDirectoryEnabled, |
| serviceAddress: `${this.ldapProtocol}${this.form.serverUri}`, |
| bindDn: this.form.bindDn, |
| bindPassword: this.form.bindPassword, |
| baseDn: this.form.baseDn, |
| userIdAttribute: this.form.userIdAttribute, |
| groupIdAttribute: this.form.groupIdAttribute, |
| }; |
| this.startLoader(); |
| this.$store |
| .dispatch('ldap/saveAccountSettings', data) |
| .then((success) => { |
| this.successToast(success); |
| }) |
| .catch(({ message }) => { |
| this.errorToast(message); |
| }) |
| .finally(() => { |
| this.form.bindPassword = ''; |
| this.$v.form.$reset(); |
| this.endLoader(); |
| }); |
| }, |
| onChangeServiceType(isActiveDirectoryEnabled) { |
| this.$v.form.activeDirectoryEnabled.$touch(); |
| const serviceType = isActiveDirectoryEnabled |
| ? this.activeDirectory |
| : this.ldap; |
| // Set form values according to user selected |
| // service type |
| this.setFormValues(serviceType); |
| }, |
| onChangeldapAuthenticationEnabled(isServiceEnabled) { |
| this.$v.form.ldapAuthenticationEnabled.$touch(); |
| if (!isServiceEnabled) { |
| // Request will fail if sent with empty values. |
| // The frontend only checks for required fields |
| // when the service is enabled. This is to prevent |
| // an error if a user clears any properties then |
| // disables the service. |
| this.setFormValues(); |
| } |
| }, |
| }, |
| }; |
| </script> |