summaryrefslogtreecommitdiff
path: root/src/views
diff options
context:
space:
mode:
authorYoshie Muranaka <yoshiemuranaka@gmail.com>2020-02-20 21:18:36 +0300
committerYoshie Muranaka <yoshiemuranaka@gmail.com>2020-02-25 01:53:37 +0300
commit1b1c1005905c0d5a0145377718ad773fe08d0863 (patch)
tree977960b251df84403364eee9337e33810c606a87 /src/views
parent52b0223005c91dc95f82ef0752ea2f3ae50788e6 (diff)
downloadwebui-vue-1b1c1005905c0d5a0145377718ad773fe08d0863.tar.xz
Add account settings to local user page
Adds ability to change account LockoutThreshold and LockoutDuration properties from the GUI. Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com> Change-Id: Ieeb75aa83c07b3de840bccdfc28e2d6e87512e2e
Diffstat (limited to 'src/views')
-rw-r--r--src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue14
-rw-r--r--src/views/AccessControl/LocalUserManagement/ModalSettings.vue183
2 files changed, 190 insertions, 7 deletions
diff --git a/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue b/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue
index 97b00e49..ee2ec433 100644
--- a/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue
+++ b/src/views/AccessControl/LocalUserManagement/LocalUserManagement.vue
@@ -75,7 +75,7 @@
</b-col>
</b-row>
<!-- Modals -->
- <modal-settings :settings="settings" />
+ <modal-settings :settings="settings" @ok="saveAccountSettings" />
<modal-user
:user="activeUser"
:password-requirements="passwordRequirements"
@@ -216,11 +216,7 @@ export default {
});
},
initModalSettings() {
- if (this.settings) {
- this.$bvModal.show('modal-settings');
- } else {
- // fetch settings then show modal
- }
+ this.$bvModal.show('modal-settings');
},
saveUser({ isNewUser, userData }) {
if (isNewUser) {
@@ -288,6 +284,12 @@ export default {
default:
break;
}
+ },
+ saveAccountSettings(settings) {
+ this.$store
+ .dispatch('localUsers/saveAccountSettings', settings)
+ .then(message => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
}
}
};
diff --git a/src/views/AccessControl/LocalUserManagement/ModalSettings.vue b/src/views/AccessControl/LocalUserManagement/ModalSettings.vue
index afe2d95e..2e41b292 100644
--- a/src/views/AccessControl/LocalUserManagement/ModalSettings.vue
+++ b/src/views/AccessControl/LocalUserManagement/ModalSettings.vue
@@ -1,14 +1,195 @@
<template>
- <b-modal id="modal-settings" title="Account policy settings"> </b-modal>
+ <b-modal
+ id="modal-settings"
+ ref="modal"
+ :title="$t('localUserManagement.accountPolicySettings')"
+ :ok-title="$t('global.actions.save')"
+ @ok="onOk"
+ @hidden="resetForm"
+ >
+ <b-form novalidate @submit="handleSubmit">
+ <b-container>
+ <b-row>
+ <b-col>
+ <b-form-group
+ :label="$t('localUserManagement.modals.maxFailedLoginAttempts')"
+ label-for="lockout-threshold"
+ >
+ <b-form-text id="lockout-threshold-help-block">
+ {{
+ $t('global.formField.valueMustBeBetween', {
+ min: 0,
+ max: 65535
+ })
+ }}
+ </b-form-text>
+ <b-form-input
+ id="lockout-threshold"
+ v-model.number="form.lockoutThreshold"
+ type="number"
+ aria-describedby="lockout-threshold-help-block"
+ :state="getValidationState($v.form.lockoutThreshold)"
+ @input="$v.form.lockoutThreshold.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.lockoutThreshold.required">
+ {{ $t('global.formField.fieldRequired') }}
+ </template>
+ <template
+ v-if="
+ !$v.form.lockoutThreshold.minLength ||
+ !$v.form.lockoutThreshold.maxLength
+ "
+ >
+ {{
+ $t('global.formField.valueMustBeBetween', {
+ min: 0,
+ max: 65535
+ })
+ }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col>
+ <b-form-group
+ :label="$t('localUserManagement.modals.userUnlockMethod')"
+ >
+ <b-form-radio
+ v-model="form.unlockMethod"
+ name="unlock-method"
+ class="mb-2"
+ :value="0"
+ @input="$v.form.unlockMethod.$touch()"
+ >
+ {{ $t('localUserManagement.modals.manual') }}
+ </b-form-radio>
+ <b-form-radio
+ v-model="form.unlockMethod"
+ name="unlock-method"
+ :value="1"
+ @input="$v.form.unlockMethod.$touch()"
+ >
+ {{ $t('localUserManagement.modals.automaticAfterTimeout') }}
+ </b-form-radio>
+ <div class="mt-3 ml-4">
+ <b-form-text id="lockout-duration-help-block">
+ {{ $t('localUserManagement.modals.timeoutDurationSeconds') }}
+ </b-form-text>
+ <b-form-input
+ v-model.number="form.lockoutDuration"
+ aria-describedby="lockout-duration-help-block"
+ type="number"
+ :state="getValidationState($v.form.lockoutDuration)"
+ :readonly="$v.form.unlockMethod.$model === 0"
+ @input="$v.form.lockoutDuration.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.lockoutDuration.required">
+ {{ $t('global.formField.fieldRequired') }}
+ </template>
+ <template v-else-if="!$v.form.lockoutDuration.minvalue">
+ {{ $t('global.formField.mustBeAtLeast', { value: 1 }) }}
+ </template>
+ </b-form-invalid-feedback>
+ </div>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ </b-container>
+ </b-form>
+ </b-modal>
</template>
<script>
+import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js';
+import {
+ required,
+ requiredIf,
+ minValue,
+ maxValue
+} from 'vuelidate/lib/validators';
+
export default {
+ mixins: [VuelidateMixin],
props: {
settings: {
type: Object,
required: true
}
+ },
+ data() {
+ return {
+ form: {
+ lockoutThreshold: 0,
+ unlockMethod: 0,
+ lockoutDuration: null
+ }
+ };
+ },
+ watch: {
+ settings: function({ lockoutThreshold, lockoutDuration }) {
+ this.form.lockoutThreshold = lockoutThreshold;
+ this.form.unlockMethod = lockoutDuration ? 1 : 0;
+ this.form.lockoutDuration = lockoutDuration ? lockoutDuration : null;
+ }
+ },
+ validations: {
+ form: {
+ lockoutThreshold: {
+ minValue: minValue(0),
+ maxValue: maxValue(65535),
+ required
+ },
+ unlockMethod: { required },
+ lockoutDuration: {
+ minValue: function(value) {
+ return this.form.unlockMethod === 0 || value > 0;
+ },
+ required: requiredIf(function() {
+ return this.form.unlockMethod === 1;
+ })
+ }
+ }
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+
+ let lockoutThreshold;
+ let lockoutDuration;
+ if (this.$v.form.lockoutThreshold.$dirty) {
+ lockoutThreshold = this.form.lockoutThreshold;
+ }
+ if (this.$v.form.unlockMethod.$dirty) {
+ lockoutDuration = this.form.unlockMethod
+ ? this.form.lockoutDuration
+ : 0;
+ }
+
+ this.$emit('ok', { lockoutThreshold, lockoutDuration });
+ this.closeModal();
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ // Reset form models
+ this.form.lockoutThreshold = this.settings.lockoutThreshold;
+ this.form.unlockMethod = this.settings.lockoutDuration ? 1 : 0;
+ this.form.lockoutDuration = this.settings.lockoutDuration
+ ? this.settings.lockoutDuration
+ : null;
+ this.$v.$reset(); // clear validations
+ }
}
};
</script>