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/07/07 07:09:14 UTC
[cloudstack-primate] branch master updated: image: Fixing
permission issues (#472)
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 8b20a95 image: Fixing permission issues (#472)
8b20a95 is described below
commit 8b20a9599cc4b6ed7e7d78a36b0c846131c2cba7
Author: davidjumani <dj...@gmail.com>
AuthorDate: Tue Jul 7 12:39:07 2020 +0530
image: Fixing permission issues (#472)
Fixes #463
Co-authored-by: Rohit Yadav <ro...@shapeblue.com>
Co-authored-by: Pearl Dsilva <pe...@shapeblue.com>
---
src/components/view/DetailSettings.vue | 10 ++++--
src/config/section/image.js | 65 ++++++++++++++++++++++++++++++----
src/views/compute/CreateSSHKeyPair.vue | 35 +++++++++++++-----
src/views/image/IsoZones.vue | 17 ++++++---
src/views/image/TemplateZones.vue | 16 ++++++---
src/views/network/VpcTiersTab.vue | 4 ++-
6 files changed, 120 insertions(+), 27 deletions(-)
diff --git a/src/components/view/DetailSettings.vue b/src/components/view/DetailSettings.vue
index e97ca6c..bb3945a 100644
--- a/src/components/view/DetailSettings.vue
+++ b/src/components/view/DetailSettings.vue
@@ -27,7 +27,7 @@
type="dashed"
style="width: 100%"
icon="plus"
- :disabled="!('updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis)"
+ :disabled="!('updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner())"
@click="showAddDetail = true">
{{ $t('label.add.setting') }}
</a-button>
@@ -69,7 +69,7 @@
<span v-else>{{ item.value }}</span>
</span>
</a-list-item-meta>
- <div slot="actions" v-if="!disableSettings && 'updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis">
+ <div slot="actions" v-if="!disableSettings && 'updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner()">
<a-button shape="circle" size="default" @click="updateDetail(index)" v-if="item.edit">
<a-icon type="check-circle" theme="twoTone" twoToneColor="#52c41a" />
</a-button>
@@ -82,7 +82,7 @@
v-if="!item.edit"
@click="showEditDetail(index)" />
</div>
- <div slot="actions" v-if="!disableSettings && 'updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis">
+ <div slot="actions" v-if="!disableSettings && 'updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner()">
<a-popconfirm
title="Delete setting?"
@confirm="deleteDetail(index)"
@@ -169,6 +169,10 @@ export default {
onAddInputChange (val, obj) {
this[obj] = val
},
+ isAdminOrOwner () {
+ return ['Admin'].includes(this.$store.getters.userInfo.roletype) ||
+ (this.resource.domainid === this.$store.getters.userInfo.domainid && this.resource.account === this.$store.getters.userInfo.account)
+ },
runApi () {
var apiName = ''
if (this.resourceType === 'UserVm') {
diff --git a/src/config/section/image.js b/src/config/section/image.js
index e489e95..7703d78 100644
--- a/src/config/section/image.js
+++ b/src/config/section/image.js
@@ -83,14 +83,32 @@ export default {
icon: 'edit',
label: 'label.edit',
dataView: true,
- args: ['name', 'displaytext', 'passwordenabled', 'sshkeyenabled', 'ostypeid', 'isdynamicallyscalable']
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ record.templatetype !== 'SYSTEM' &&
+ record.isready
+ },
+ args: (record, store) => {
+ var fields = ['name', 'displaytext', 'passwordenabled', 'sshkeyenabled', 'ostypeid', 'isdynamicallyscalable']
+ if (['Admin'].includes(store.userInfo.roletype)) {
+ fields.push('isrouting')
+ }
+ return fields
+ }
},
{
api: 'updateTemplatePermissions',
icon: 'share-alt',
label: 'label.action.template.share',
dataView: true,
- args: ['ispublic', 'isfeatured', 'isextractable']
+ args: ['ispublic', 'isfeatured', 'isextractable'],
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ record.templatetype !== 'SYSTEM' &&
+ record.isready
+ }
},
{
api: 'extractTemplate',
@@ -99,7 +117,13 @@ export default {
message: 'message.action.download.template',
docHelp: 'adminguide/templates.html#exporting-templates',
dataView: true,
- show: (record) => { return record && record.isextractable },
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ record.templatetype !== 'SYSTEM' &&
+ record.isready &&
+ record.isextractable
+ },
args: ['zoneid', 'mode'],
mapping: {
zoneid: {
@@ -118,7 +142,12 @@ export default {
docHelp: 'adminguide/templates.html#sharing-templates-with-other-accounts-projects',
dataView: true,
popup: true,
- show: (record, store) => { return (['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) && (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account) || record.templatetype !== 'BUILTIN') },
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ record.templatetype !== 'SYSTEM' &&
+ record.isready
+ },
component: () => import('@/views/image/UpdateTemplateIsoPermissions')
}
]
@@ -177,6 +206,12 @@ export default {
icon: 'edit',
label: 'label.action.edit.iso',
dataView: true,
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ !(record.account === 'SYSTEM' && record.domainid === 1) &&
+ record.isready
+ },
args: ['name', 'displaytext', 'bootable', 'ostypeid']
},
{
@@ -184,7 +219,13 @@ export default {
icon: 'share-alt',
label: 'label.action.iso.share',
dataView: true,
- args: ['ispublic', 'isfeatured', 'isextractable']
+ args: ['ispublic', 'isfeatured', 'isextractable'],
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ !(record.account === 'SYSTEM' && record.domainid === 1) &&
+ record.isready
+ }
},
{
api: 'extractIso',
@@ -193,7 +234,12 @@ export default {
message: 'message.action.download.iso',
docHelp: 'adminguide/templates.html#exporting-templates',
dataView: true,
- show: (record) => { return record && record.isextractable },
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ !(record.account === 'SYSTEM' && record.domainid === 1) &&
+ record.isready
+ },
args: ['zoneid', 'mode'],
mapping: {
zoneid: {
@@ -213,7 +259,12 @@ export default {
dataView: true,
args: ['op', 'accounts', 'projectids'],
popup: true,
- show: (record, store) => { return (['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) && (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account) || record.templatetype !== 'BUILTIN') },
+ show: (record, store) => {
+ return (['Admin'].includes(store.userInfo.roletype) ||
+ (record.domainid === store.userInfo.domainid && record.account === store.userInfo.account)) &&
+ !(record.account === 'SYSTEM' && record.domainid === 1) &&
+ record.isready
+ },
component: () => import('@/views/image/UpdateTemplateIsoPermissions')
}
]
diff --git a/src/views/compute/CreateSSHKeyPair.vue b/src/views/compute/CreateSSHKeyPair.vue
index 2800d9d..a3aa8e2 100644
--- a/src/views/compute/CreateSSHKeyPair.vue
+++ b/src/views/compute/CreateSSHKeyPair.vue
@@ -17,7 +17,7 @@
<template>
<div class="form-layout">
- <a-spin :spinning="loading">
+ <a-spin :spinning="loading" v-if="!isSubmitted">
<p v-html="$t('message.desc.create.ssh.key.pair')"></p>
<a-form
:form="form"
@@ -64,6 +64,14 @@
</div>
</a-form>
</a-spin>
+ <div v-if="isSubmitted">
+ <p v-html="$t('message.desc.created.ssh.key.pair')"></p>
+ <div :span="24" class="action-button">
+ <a-button @click="notifyCopied" v-clipboard:copy="hiddenElement.innerHTML" type="primary">{{ 'Copy to clipboard' }}</a-button>
+ <a-button @click="downloadKey" type="primary">{{ this.$t('Download') }}</a-button>
+ <a-button @click="closeAction">{{ this.$t('label.close') }}</a-button>
+ </div>
+ </div>
</div>
</template>
@@ -78,7 +86,9 @@ export default {
domains: [],
domainLoading: false,
selectedDomain: {},
- loading: false
+ loading: false,
+ isSubmitted: false,
+ hiddenElement: null
}
},
beforeCreate () {
@@ -176,22 +186,31 @@ export default {
api('createSSHKeyPair', params).then(json => {
this.$message.success('Successfully created SSH key pair: ' + values.name)
if (json.createsshkeypairresponse && json.createsshkeypairresponse.keypair && json.createsshkeypairresponse.keypair.privatekey) {
- this.$notification.info({
- message: this.$t('label.create.ssh.key.pair'),
- description: (<span domPropsInnerHTML={'<strong>' + values.name + '</strong><br/><pre>' + json.createsshkeypairresponse.keypair.privatekey + '</pre>'}></span>),
- duration: 0
- })
+ this.isSubmitted = true
+ const key = json.createsshkeypairresponse.keypair.privatekey
+ this.hiddenElement = document.createElement('a')
+ this.hiddenElement.href = 'data:text/plain;charset=utf-8,' + encodeURI(key)
+ this.hiddenElement.innerHTML = key
+ this.hiddenElement.target = '_blank'
+ this.hiddenElement.download = values.name + '.key'
}
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.$emit('refresh-data')
this.loading = false
- this.closeAction()
})
}
})
},
+ downloadKey () {
+ this.hiddenElement.click()
+ },
+ notifyCopied () {
+ this.$notification.info({
+ message: this.$t('Copied Successfully to cilpboard')
+ })
+ },
closeAction () {
this.$emit('close-action')
}
diff --git a/src/views/image/IsoZones.vue b/src/views/image/IsoZones.vue
index f23dacf..f76c034 100644
--- a/src/views/image/IsoZones.vue
+++ b/src/views/image/IsoZones.vue
@@ -166,15 +166,18 @@ export default {
title: this.$t('label.isready'),
dataIndex: 'isready',
scopedSlots: { customRender: 'isready' }
- },
- {
+ }
+ ]
+ if (this.isActionPermitted()) {
+ this.columns.push({
title: '',
dataIndex: 'action',
fixed: 'right',
width: 100,
scopedSlots: { customRender: 'action' }
- }
- ]
+ })
+ }
+
const userInfo = this.$store.getters.userInfo
if (!['Admin'].includes(userInfo.roletype) &&
(userInfo.account !== this.resource.account || userInfo.domain !== this.resource.domain)) {
@@ -222,6 +225,12 @@ export default {
this.pageSize = pageSize
this.fetchData()
},
+ isActionPermitted () {
+ return (['Admin'].includes(this.$store.getters.userInfo.roletype) ||
+ (this.resource.domainid === this.$store.getters.userInfo.domainid && this.resource.account === this.$store.getters.userInfo.account)) &&
+ !(this.resource.account !== 'SYSTEM' && this.resource.domainid === 1) &&
+ this.resource.isready
+ },
deleteIso (record) {
const params = {
id: record.id,
diff --git a/src/views/image/TemplateZones.vue b/src/views/image/TemplateZones.vue
index 3b020c8..d9f1e1c 100644
--- a/src/views/image/TemplateZones.vue
+++ b/src/views/image/TemplateZones.vue
@@ -176,15 +176,18 @@ export default {
title: this.$t('label.isready'),
dataIndex: 'isready',
scopedSlots: { customRender: 'isready' }
- },
- {
+ }
+ ]
+ if (this.isActionPermitted()) {
+ this.columns.push({
title: '',
dataIndex: 'action',
fixed: 'right',
width: 100,
scopedSlots: { customRender: 'action' }
- }
- ]
+ })
+ }
+
const userInfo = this.$store.getters.userInfo
if (!['Admin'].includes(userInfo.roletype) &&
(userInfo.account !== this.resource.account || userInfo.domain !== this.resource.domain)) {
@@ -232,6 +235,11 @@ export default {
this.pageSize = pageSize
this.fetchData()
},
+ isActionPermitted () {
+ return (['Admin'].includes(this.$store.getters.userInfo.roletype) ||
+ (this.resource.domainid === this.$store.getters.userInfo.domainid && this.resource.account === this.$store.getters.userInfo.account)) &&
+ this.resource.isready && this.resource.templatetype !== 'SYSTEM'
+ },
deleteTemplate () {
const params = {
id: this.currentRecord.id,
diff --git a/src/views/network/VpcTiersTab.vue b/src/views/network/VpcTiersTab.vue
index b4be7a6..7ff67b6 100644
--- a/src/views/network/VpcTiersTab.vue
+++ b/src/views/network/VpcTiersTab.vue
@@ -251,6 +251,7 @@ export default {
default: false
}
},
+ inject: ['parentFetchData'],
data () {
return {
networks: [],
@@ -487,11 +488,12 @@ export default {
this.$notification.success({
message: 'Successfully added VPC Network'
})
- this.fetchData()
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
+ this.parentFetchData()
this.fetchData()
+ this.fetchLoading = false
})
})
},