diff options
Diffstat (limited to 'src/views')
-rw-r--r-- | src/views/AccessControl/Ldap/Ldap.vue | 87 | ||||
-rw-r--r-- | src/views/AccessControl/Ldap/ModalAddRoleGroup.vue | 164 | ||||
-rw-r--r-- | src/views/AccessControl/Ldap/TableRoleGroups.vue | 240 |
3 files changed, 449 insertions, 42 deletions
diff --git a/src/views/AccessControl/Ldap/Ldap.vue b/src/views/AccessControl/Ldap/Ldap.vue index c2d0e347..3ae4784f 100644 --- a/src/views/AccessControl/Ldap/Ldap.vue +++ b/src/views/AccessControl/Ldap/Ldap.vue @@ -8,14 +8,11 @@ <b-form-group class="mb-3" :label="$t('pageLdap.form.ldapAuthentication')" + label-for="enable-ldap-auth" > - <b-form-text id="enable-ldap-auth-help-block"> - {{ $t('pageLdap.form.ldapAuthenticationHelper') }} - </b-form-text> <b-form-checkbox id="enable-ldap-auth" v-model="form.ldapAuthenticationEnabled" - aria-describedby="enable-ldap-auth-help-block" @change="onChangeldapAuthenticationEnabled" > {{ $t('global.action.enable') }} @@ -193,7 +190,7 @@ </b-row> </b-form-group> </div> - <b-row class="mt-4"> + <b-row class="mt-4 mb-5"> <b-col> <b-btn variant="primary" @@ -206,6 +203,11 @@ </b-row> </b-form> </page-section> + + <!-- Role groups --> + <page-section :section-title="$t('pageLdap.roleGroups')"> + <table-role-groups /> + </page-section> </b-container> </template> @@ -220,17 +222,26 @@ import PageTitle from '@/components/Global/PageTitle'; import PageSection from '@/components/Global/PageSection'; import InfoTooltip from '@/components/Global/InfoTooltip'; import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; +import TableRoleGroups from './TableRoleGroups'; export default { name: 'Ldap', - components: { InfoTooltip, InputPasswordToggle, PageTitle, PageSection }, + components: { + InfoTooltip, + InputPasswordToggle, + PageTitle, + PageSection, + TableRoleGroups + }, mixins: [BVToastMixin, VuelidateMixin], data() { return { form: { - ldapAuthenticationEnabled: false, + ldapAuthenticationEnabled: this.$store.getters['ldap/isServiceEnabled'], secureLdapEnabled: false, - activeDirectoryEnabled: false, + activeDirectoryEnabled: this.$store.getters[ + 'ldap/isActiveDirectoryEnabled' + ], serverUri: '', bindDn: '', bindPassword: '', @@ -241,7 +252,12 @@ export default { }; }, computed: { - ...mapGetters('ldap', ['isServiceEnabled', 'ldap', 'activeDirectory']), + ...mapGetters('ldap', [ + 'isServiceEnabled', + 'isActiveDirectoryEnabled', + 'ldap', + 'activeDirectory' + ]), sslCertificates() { return this.$store.getters['sslCertificates/allCertificates']; }, @@ -267,22 +283,9 @@ export default { isServiceEnabled: function(value) { this.form.ldapAuthenticationEnabled = value; }, - ldap: { - handler: function(value) { - if (value.serviceEnabled || !this.form.activeDirectoryEnabled) { - this.setFormValues(value); - } - }, - deep: true - }, - activeDirectory: { - handler: function(value) { - if (value.serviceEnabled) { - this.form.activeDirectoryEnabled = true; - this.setFormValues(value); - } - }, - deep: true + isActiveDirectoryEnabled: function(value) { + this.form.activeDirectoryEnabled = value; + this.setFormValues(); } }, validations: { @@ -321,20 +324,22 @@ export default { created() { this.$store.dispatch('ldap/getAccountSettings'); this.$store.dispatch('sslCertificates/getCertificates'); - if (this.form.activeDirectoryEnabled) { - this.setFormValues(this.activeDirectory); - } else { - this.setFormValues(this.ldap); - } + this.setFormValues(); }, methods: { - setFormValues({ - serviceAddress = '', - bindDn = '', - baseDn = '', - userAttribute = '', - groupsAttribute = '' - }) { + 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 @@ -377,6 +382,8 @@ export default { const serviceType = isActiveDirectoryEnabled ? this.activeDirectory : this.ldap; + // Set form values according to user selected + // service type this.setFormValues(serviceType); }, onChangeldapAuthenticationEnabled(isServiceEnabled) { @@ -387,11 +394,7 @@ export default { // when the service is enabled. This is to prevent // an error if a user clears any properties then // disables the service. - if (this.form.activeDirectoryEnabled) { - this.setFormValues(this.activeDirectory); - } else { - this.setFormValues(this.ldap); - } + this.setFormValues(); } } } diff --git a/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue b/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue new file mode 100644 index 00000000..e2da1eb1 --- /dev/null +++ b/src/views/AccessControl/Ldap/ModalAddRoleGroup.vue @@ -0,0 +1,164 @@ +<template> + <b-modal id="modal-role-group" ref="modal" @ok="onOk" @hidden="resetForm"> + <template v-slot:modal-title> + <template v-if="roleGroup"> + {{ $t('pageLdap.modal.editRoleGroup') }} + </template> + <template v-else> + {{ $t('pageLdap.modal.addNewRoleGroup') }} + </template> + </template> + <b-container> + <b-row> + <b-col sm="8"> + <b-form id="role-group"> + <!-- Edit role group --> + <template v-if="roleGroup !== null"> + <dl class="mb-4"> + <dt>{{ $t('pageLdap.modal.groupName') }}</dt> + <dd>{{ form.groupName }}</dd> + </dl> + </template> + + <!-- Add new role group --> + <template v-else> + <b-form-group + :label="$t('pageLdap.modal.groupName')" + label-for="role-group-name" + > + <b-form-input + id="role-group-name" + v-model="form.groupName" + :state="getValidationState($v.form.groupName)" + @input="$v.form.groupName.$touch()" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </template> + + <b-form-group + :label="$t('pageLdap.modal.groupPrivilege')" + label-for="privilege" + > + <b-form-select + id="privilege" + v-model="form.groupPrivilege" + :options="accountRoles" + :state="getValidationState($v.form.groupPrivilege)" + @input="$v.form.groupPrivilege.$touch()" + > + <template v-if="!roleGroup" v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-form> + </b-col> + </b-row> + </b-container> + <template v-slot:modal-footer="{ ok, cancel }"> + <b-button variant="secondary" @click="cancel()"> + {{ $t('global.action.cancel') }} + </b-button> + <b-button form="role-group" type="submit" variant="primary" @click="ok()"> + <template v-if="roleGroup"> + {{ $t('global.action.save') }} + </template> + <template v-else> + {{ $t('global.action.add') }} + </template> + </b-button> + </template> + </b-modal> +</template> + +<script> +import { required, requiredIf } from 'vuelidate/lib/validators'; +import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; + +export default { + mixins: [VuelidateMixin], + props: { + roleGroup: { + type: Object, + default: null, + validator: prop => { + if (prop === null) return true; + return ( + prop.hasOwnProperty('groupName') && + prop.hasOwnProperty('groupPrivilege') + ); + } + } + }, + data() { + return { + form: { + groupName: null, + groupPrivilege: null + } + }; + }, + computed: { + accountRoles() { + return this.$store.getters['localUsers/accountRoles']; + } + }, + watch: { + roleGroup: function(value) { + if (value === null) return; + this.form.groupName = value.groupName; + this.form.groupPrivilege = value.groupPrivilege; + } + }, + validations() { + return { + form: { + groupName: { + required: requiredIf(function() { + return !this.roleGroup; + }) + }, + groupPrivilege: { + required + } + } + }; + }, + methods: { + handleSubmit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.$emit('ok', { + addNew: !this.roleGroup, + groupName: this.form.groupName, + groupPrivilege: this.form.groupPrivilege + }); + this.closeModal(); + }, + closeModal() { + this.$nextTick(() => { + this.$refs.modal.hide(); + }); + }, + resetForm() { + this.form.groupName = null; + this.form.groupPrivilege = null; + this.$v.$reset(); + this.$emit('hidden'); + }, + onOk(bvModalEvt) { + // prevent modal close + bvModalEvt.preventDefault(); + this.handleSubmit(); + } + } +}; +</script> diff --git a/src/views/AccessControl/Ldap/TableRoleGroups.vue b/src/views/AccessControl/Ldap/TableRoleGroups.vue new file mode 100644 index 00000000..a851a033 --- /dev/null +++ b/src/views/AccessControl/Ldap/TableRoleGroups.vue @@ -0,0 +1,240 @@ +<template> + <div> + <b-row> + <b-col md="9"> + <alert :show="isServiceEnabled === false" variant="info"> + {{ $t('pageLdap.tableRoleGroups.alertContent') }} + </alert> + </b-col> + </b-row> + <b-row> + <b-col class="text-right" md="9"> + <b-btn + variant="primary" + :disabled="!isServiceEnabled" + @click="initRoleGroupModal(null)" + > + <icon-add /> + {{ $t('pageLdap.addRoleGroup') }} + </b-btn> + </b-col> + </b-row> + <b-row> + <b-col md="9"> + <table-toolbar + ref="toolbar" + :selected-items-count="selectedRows.length" + :actions="batchActions" + @clearSelected="clearSelectedRows($refs.table)" + @batchAction="onBatchAction" + /> + <b-table + ref="table" + selectable + no-select-on-click + no-sort-reset + sort-icon-left + :items="tableItems" + :fields="fields" + @row-selected="onRowSelected($event, tableItems.length)" + > + <!-- Checkbox column --> + <template v-slot:head(checkbox)> + <b-form-checkbox + v-model="tableHeaderCheckboxModel" + :indeterminate="tableHeaderCheckboxIndeterminate" + :disabled="!isServiceEnabled" + @change="onChangeHeaderCheckbox($refs.table)" + /> + </template> + <template v-slot:cell(checkbox)="row"> + <b-form-checkbox + v-model="row.rowSelected" + :disabled="!isServiceEnabled" + @change="toggleSelectRow($refs.table, row.index)" + /> + </template> + + <!-- table actions column --> + <template v-slot:cell(actions)="{ item }"> + <table-row-action + v-for="(action, index) in item.actions" + :key="index" + :value="action.value" + :enabled="action.enabled" + :title="action.title" + @click:tableAction="onTableRowAction($event, item)" + > + <template v-slot:icon> + <icon-edit v-if="action.value === 'edit'" /> + <icon-trashcan v-if="action.value === 'delete'" /> + </template> + </table-row-action> + </template> + </b-table> + </b-col> + </b-row> + <modal-add-role-group + :role-group="activeRoleGroup" + @ok="saveRoleGroup" + @hidden="activeRoleGroup = null" + /> + </div> +</template> + +<script> +import IconEdit from '@carbon/icons-vue/es/edit/20'; +import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; +import IconAdd from '@carbon/icons-vue/es/add--alt/20'; +import { mapGetters } from 'vuex'; + +import Alert from '@/components/Global/Alert'; +import TableToolbar from '@/components/Global/TableToolbar'; +import TableRowAction from '@/components/Global/TableRowAction'; +import BVTableSelectableMixin from '@/components/Mixins/BVTableSelectableMixin'; +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import ModalAddRoleGroup from './ModalAddRoleGroup'; + +export default { + components: { + Alert, + IconAdd, + IconEdit, + IconTrashcan, + ModalAddRoleGroup, + TableRowAction, + TableToolbar + }, + mixins: [BVTableSelectableMixin, BVToastMixin], + data() { + return { + activeRoleGroup: null, + fields: [ + { + key: 'checkbox', + sortable: false + }, + { + key: 'groupName', + sortable: true, + label: this.$t('pageLdap.tableRoleGroups.groupName') + }, + { + key: 'groupPrivilege', + sortable: true, + label: this.$t('pageLdap.tableRoleGroups.groupPrivilege') + }, + { + key: 'actions', + sortable: false, + label: '', + tdClass: 'text-right' + } + ], + batchActions: [ + { + value: 'delete', + label: this.$t('global.action.delete') + } + ] + }; + }, + computed: { + ...mapGetters('ldap', ['isServiceEnabled', 'enabledRoleGroups']), + tableItems() { + return this.enabledRoleGroups.map(({ LocalRole, RemoteGroup }) => { + return { + groupName: RemoteGroup, + groupPrivilege: LocalRole, + actions: [ + { + value: 'edit', + title: this.$t('global.action.edit'), + enabled: this.isServiceEnabled + }, + { + value: 'delete', + title: this.$t('global.action.delete'), + enabled: this.isServiceEnabled + } + ] + }; + }); + } + }, + created() { + this.$store.dispatch('localUsers/getAccountRoles'); + }, + methods: { + onBatchAction() { + this.$bvModal + .msgBoxConfirm( + this.$tc( + 'pageLdap.modal.deleteRoleGroupBatchConfirmMessage', + this.selectedRows.length + ), + { + title: this.$t('pageLdap.modal.deleteRoleGroup'), + okTitle: this.$t('global.action.delete') + } + ) + .then(deleteConfirmed => { + if (deleteConfirmed) { + this.$store + .dispatch('ldap/deleteRoleGroup', { + roleGroups: this.selectedRows + }) + .then(success => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)); + } + }); + }, + onTableRowAction(action, row) { + switch (action) { + case 'edit': + this.initRoleGroupModal(row); + break; + case 'delete': + this.$bvModal + .msgBoxConfirm( + this.$t('pageLdap.modal.deleteRoleGroupConfirmMessage', { + groupName: row.groupName + }), + { + title: this.$t('pageLdap.modal.deleteRoleGroup'), + okTitle: this.$t('global.action.delete') + } + ) + .then(deleteConfirmed => { + if (deleteConfirmed) { + this.$store + .dispatch('ldap/deleteRoleGroup', { roleGroups: [row] }) + .then(success => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)); + } + }); + break; + } + }, + initRoleGroupModal(roleGroup) { + this.activeRoleGroup = roleGroup; + this.$bvModal.show('modal-role-group'); + }, + saveRoleGroup({ addNew, groupName, groupPrivilege }) { + this.activeRoleGroup = null; + const data = { groupName, groupPrivilege }; + if (addNew) { + this.$store + .dispatch('ldap/addNewRoleGroup', data) + .then(success => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)); + } else { + this.$store + .dispatch('ldap/saveRoleGroup', data) + .then(success => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)); + } + } + } +}; +</script> |