You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2020/05/05 09:57:38 UTC
[cloudstack-primate] branch master updated: iam: user change
password action form (#264)
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-primate.git
The following commit(s) were added to refs/heads/master by this push:
new f52c7e2 iam: user change password action form (#264)
f52c7e2 is described below
commit f52c7e203363afeba1300443dc6494ee69b1f808
Author: Abhishek Kumar <ab...@gmail.com>
AuthorDate: Tue May 5 15:27:27 2020 +0530
iam: user change password action form (#264)
Fixes #177
Signed-off-by: Abhishek Kumar <ab...@gmail.com>
Co-authored-by: Rohit Yadav <ro...@shapeblue.com>
---
src/config/section/iam.js | 13 +--
src/locales/en.json | 4 +-
src/views/iam/ChangeUserPassword.vue | 183 +++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+), 7 deletions(-)
diff --git a/src/config/section/iam.js b/src/config/section/iam.js
index f91789a..b473d0c 100644
--- a/src/config/section/iam.js
+++ b/src/config/section/iam.js
@@ -46,34 +46,35 @@ export default {
{
api: 'updateUser',
icon: 'key',
- label: 'Change Password',
+ label: 'label.action.change.password',
dataView: true,
- args: ['currentpassword', 'password']
+ popup: true,
+ component: () => import('@/views/iam/ChangeUserPassword.vue')
},
{
api: 'registerUserKeys',
icon: 'file-protect',
- label: 'Generate Keys',
+ label: 'label.action.generate.keys',
dataView: true
},
{
api: 'enableUser',
icon: 'play-circle',
- label: 'Enable User',
+ label: 'label.action.enable.user',
dataView: true,
show: (record) => { return record.state === 'disabled' }
},
{
api: 'disableUser',
icon: 'pause-circle',
- label: 'Disable User',
+ label: 'label.action.disable.user',
dataView: true,
show: (record) => { return record.state === 'enabled' }
},
{
api: 'deleteUser',
icon: 'delete',
- label: 'Delete user',
+ label: 'label.action.delete.user',
dataView: true
}
]
diff --git a/src/locales/en.json b/src/locales/en.json
index 7174a08..86d80d7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -127,6 +127,7 @@
"clusternamelabel": "Cluster Name",
"clusters": "Clusters",
"clustertype": "Cluster Type",
+"confirmpassword": "Confirm Password",
"connectiontimeout": "Connection Timeout",
"conservemode": "Conserve mode",
"counterid": "Counter",
@@ -149,6 +150,7 @@
"credit": "Credit",
"crossZones": "Cross Zones",
"current": "isCurrent",
+"currentpassword": "Current Password",
"date": "Date",
"dedicated": "Dedicated",
"default": "Default",
@@ -744,6 +746,7 @@
"message.network.removeNIC": "Please confirm that want to remove this NIC, which will also remove the associated network from the VM.",
"message.network.secondaryIP" : "Please confirm that you would like to acquire a new secondary IP for this NIC. \n NOTE: You need to manually configure the newly-acquired secondary IP inside the virtual machine.",
"message.network.updateIp": "Please confirm that you would like to change the IP address for this NIC on VM.",
+"message.validate.equalto": "Please enter the same value again.",
"message.desc.create.ssh.key.pair": "Please fill in the following data to create or register a ssh key pair.<br><br>(1) If public key is set, CloudStack will register the public key. You can use it through your private key.<br><br>(2) If public key is not set, CloudStack will create a new SSH Key pair. In this case, please copy and save the private key. CloudStack will not keep it.<br>",
"mincpunumber": "Min CPU Cores",
"minInstance": "Min Instances",
@@ -1111,7 +1114,6 @@
"sshKeyPairs": "SSH keypairs",
"wednesday": "Wednesday",
"noselect": "No thanks",
-"group": "Group",
"keyboard": "Keyboard language",
"userdata": "Userdata",
"label.back": "Back",
diff --git a/src/views/iam/ChangeUserPassword.vue b/src/views/iam/ChangeUserPassword.vue
new file mode 100644
index 0000000..927312c
--- /dev/null
+++ b/src/views/iam/ChangeUserPassword.vue
@@ -0,0 +1,183 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+<template>
+ <div class="form-layout">
+ <a-spin :spinning="loading">
+ <a-form
+ :form="form"
+ @submit="handleSubmit"
+ layout="vertical">
+ <a-form-item v-if="!this.isAdminOrDomainAdmin()">
+ <span slot="label">
+ {{ $t('currentpassword') }}
+ <a-tooltip :title="apiParams.currentpassword.description">
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
+ </a-tooltip>
+ </span>
+ <a-input-password
+ v-decorator="['currentpassword', {
+ rules: [{ required: true, message: 'Please enter current password' }]
+ }]"
+ :placeholder="apiParams.currentpassword.description"/>
+ </a-form-item>
+ <a-form-item>
+ <span slot="label">
+ {{ $t('password') }}
+ <a-tooltip :title="apiParams.password.description">
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
+ </a-tooltip>
+ </span>
+ <a-input-password
+ v-decorator="['password', {
+ rules: [{ required: true, message: 'Please enter new password' }]
+ }]"
+ :placeholder="apiParams.password.description"/>
+ </a-form-item>
+ <a-form-item>
+ <span slot="label">
+ {{ $t('confirmpassword') }}
+ <a-tooltip :title="apiParams.password.description">
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
+ </a-tooltip>
+ </span>
+ <a-input-password
+ v-decorator="['confirmpassword', {
+ rules: [
+ {
+ required: true,
+ message: 'Please confirm new password'
+ },
+ {
+ validator: validateTwoPassword
+ }
+ ]
+ }]"
+ :placeholder="apiParams.password.description"/>
+ </a-form-item>
+
+ <div :span="24" class="action-button">
+ <a-button @click="closeAction">{{ this.$t('Cancel') }}</a-button>
+ <a-button :loading="loading" type="primary" @click="handleSubmit">{{ this.$t('OK') }}</a-button>
+ </div>
+ </a-form>
+ </a-spin>
+ </div>
+</template>
+
+<script>
+import { api } from '@/api'
+
+export default {
+ name: 'ChangeUserPassword',
+ props: {
+ resource: {
+ type: Object,
+ required: true
+ }
+ },
+ data () {
+ return {
+ loading: false
+ }
+ },
+ beforeCreate () {
+ this.form = this.$form.createForm(this)
+ this.apiParams = {}
+ this.apiConfig = this.$store.getters.apis.updateUser || {}
+ this.apiConfig.params.forEach(param => {
+ this.apiParams[param.name] = param
+ })
+ },
+ methods: {
+ isAdminOrDomainAdmin () {
+ return ['Admin', 'DomainAdmin'].includes(this.$store.getters.userInfo.roletype)
+ },
+ isValidValueForKey (obj, key) {
+ return key in obj && obj[key] != null
+ },
+ validateTwoPassword (rule, value, callback) {
+ if (!value || value.length === 0) {
+ callback()
+ } else if (rule.field === 'confirmpassword') {
+ const form = this.form
+ const messageConfirm = this.$t('message.validate.equalto')
+ const passwordVal = form.getFieldValue('password')
+ if (passwordVal && passwordVal !== value) {
+ callback(messageConfirm)
+ } else {
+ callback()
+ }
+ } else {
+ callback()
+ }
+ },
+ handleSubmit (e) {
+ e.preventDefault()
+ this.form.validateFields((err, values) => {
+ if (err) {
+ return
+ }
+ this.loading = true
+ const params = {
+ id: this.resource.id,
+ password: values.password
+ }
+ if (this.isValidValueForKey(values, 'currentpassword') && values.currentpassword.length > 0) {
+ params.currentpassword = values.currentpassword
+ }
+ api('updateUser', params).then(json => {
+ this.$notification.success({
+ message: this.$t('label.action.change.password'),
+ description: 'Successfully changed password for user "' + this.resource.username + '"'
+ })
+ }).catch(error => {
+ this.$notification.error({
+ message: 'Error',
+ description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
+ })
+ }).finally(() => {
+ this.$emit('refresh-data')
+ this.loading = false
+ this.closeAction()
+ })
+ })
+ },
+ closeAction () {
+ this.$emit('close-action')
+ }
+ }
+}
+</script>
+
+<style scoped lang="less">
+ .form-layout {
+ width: 80vw;
+
+ @media (min-width: 600px) {
+ width: 450px;
+ }
+ }
+
+ .action-button {
+ text-align: right;
+
+ button {
+ margin-right: 5px;
+ }
+ }
+</style>