Merge branch 'dev' of github.com:jumpserver/lina into dev

This commit is contained in:
ibuler
2020-06-05 10:37:29 +08:00
13 changed files with 314 additions and 27 deletions

View File

@@ -53,7 +53,7 @@
"vuex": "3.1.0",
"xterm": "^4.5.0",
"xterm-addon-fit": "^0.3.0",
"ztree": "^3.5.24"
"@ztree/ztree_v3": "3.5.44"
},
"devDependencies": {
"@babel/core": "7.0.0",

View File

@@ -38,7 +38,10 @@ export default {
enable: true,
url: (process.env.VUE_APP_ENV === 'production') ? (`${this.setting.treeUrl}`) : (`${process.env.VUE_APP_BASE_API}${this.setting.treeUrl}`),
autoParam: ['id=key', 'name=n', 'level=lv'],
type: 'get'
type: 'get',
headers: {
'X-JMS-ORG': JSON.parse(this.$cookie.get('jms_current_org')).id || ''
}
},
callback: {
onRightClick: this.onRightClick.bind(this),
@@ -68,6 +71,9 @@ export default {
rMenu() {
return this.$refs.dataztree.rMenu
}
},
mounted() {
},
methods: {
editTreeNode: function() {

View File

@@ -18,7 +18,7 @@
// 导入JQuery
// eslint-disable-next-line no-unused-vars
import $ from '@/utils/jquery-vendor.js'
import 'ztree'
import '@ztree/ztree_v3/js/jquery.ztree.core.min.js'
import '@/styles/ztree.css'
const defaultObject = {

View File

@@ -734,6 +734,10 @@
"dateLastLogin": ""
},
"xpack": {
"Vault": {
"Vault": "密码匣子",
"Create": "创建"
},
"Basic": "基本",
"Other": "其他",
"Admin": "管理员",

View File

@@ -727,6 +727,10 @@
"ResetAndDownloadSSHKey": "Reset and download SSH Key"
},
"xpack": {
"Vault": {
"Vault": "Vault",
"Create": "Create"
},
"Admin": "Admin",
"AssetCount": "Asset count",
"Auditor": "Auditor",

View File

@@ -1,7 +1,7 @@
<template>
<Page>
<el-alert v-if="helpMessage" type="success"> {{ helpMessage }} </el-alert>
<TreeTable :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
<TreeTable ref="TreeTable" :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
</Page>
</template>

View File

@@ -8,7 +8,7 @@
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-user" command="profile">{{ $t('common.nav.Profile') }}</el-dropdown-item>
<div v-if="currentOrgRoles.length > 1">
<div v-if="currentOrgRoles.length > 1|| hasAdminOrg ">
<el-dropdown-item v-if="isInAdminRole " icon="el-icon-guide" command="userPage">
{{ $t('common.nav.UserPage') }}
</el-dropdown-item>
@@ -46,13 +46,17 @@ export default {
this.$log.debug('Current in admin role: ', inAdmin)
return inAdmin
},
hasAdminOrg() {
return this.userAdminOrgList.length > 0
},
hasAdminRole() {
return this.currentOrgRoles.includes('Admin')
},
...mapGetters([
'currentUser',
'currentRole',
'currentOrgRoles'
'currentOrgRoles',
'userAdminOrgList'
])
},
methods: {

View File

@@ -93,6 +93,8 @@ export default {
}
testEmailSetting(value).then(res => {
vm.$message.success(res['msg'])
}).catch(res => {
vm.$message.error(res['response']['data']['error'])
})
}
}

View File

@@ -0,0 +1,60 @@
<template>
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import Uploadkey from '@/components/UploadKey'
export default {
name: 'AdminUserCreateUpdate',
components: {
GenericCreateUpdatePage
},
data() {
return {
url: '/api/v1/assets/asset-users/',
initial: {
},
fields: [
['', ['asset', 'username', 'password', 'private_key', 'comment']]
],
fieldsMeta: {
asset: {
label: this.$t('perms.Asset'),
el: {
multiple: false,
ajax: {
url: '/api/v1/assets/assets/',
transformOption: (item) => {
return { label: `${item.hostname}(${item.ip})`, value: item.id }
}
}
}
},
name: {
el: {
placeholder: this.$t('common.Name')
}
},
username: {
el: {
placeholder: this.$t('common.Username')
}
},
password: {
helpText: this.$t('common.passwordOrPassphrase')
},
private_key: {
component: Uploadkey
}
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,201 @@
<template>
<div>
<GenericTreeListPage ref="TreeTablePage" :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
<Dialog width="50" :title="this.$t('assets.UpdateAssetUserToken')" :visible.sync="showDialog" @confirm="handleConfirm()" @cancel="handleCancel()">
<el-form label-position="right" label-width="80px" :model="dialogInfo">
<el-form-item :label="this.$t('assets.Hostname')">
<el-input v-model="dialogInfo.hostname" disabled />
</el-form-item>
<el-form-item :label="this.$t('assets.Username')">
<el-input v-model="dialogInfo.username" disabled />
</el-form-item>
<el-form-item :label="this.$t('assets.Password')">
<el-input v-model="dialogInfo.password" type="password" />
</el-form-item>
<el-form-item :label="this.$t('assets.sshkey')">
<input type="file" @change="Onchange">
</el-form-item>
</el-form>
</Dialog>
</div>
</template>
<script>
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
import { ActionsFormatter, DateFormatter } from '@/components/ListTable/formatters'
import Dialog from '@/components/Dialog'
export default {
name: 'Vault',
components: {
GenericTreeListPage,
Dialog
},
data() {
return {
showDialog: false,
dialogInfo: {
asset: '',
username: '',
hostname: '',
password: '',
key: ''
},
treeSetting: {
showMenu: false,
showRefresh: false,
showAssets: true,
url: '/api/v1/assets/asset-users/',
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1'
},
headerActions: {
hasLeftActions: true,
hasRightActions: true,
hasExport: true,
hasImport: true,
hasRefresh: true,
hasSearch: true,
hasBulkDelete: false,
hasCreate: true
},
tableConfig: {
url: `/api/v1/assets/asset-users/?latest=1`,
columns: [
{
prop: 'hostname',
label: this.$t('assets.Hostname')
},
{
prop: 'ip',
label: this.$t('assets.ip')
},
{
prop: 'username',
label: this.$t('assets.Username')
},
{
prop: 'version',
label: this.$t('assets.Version')
},
{
prop: 'date_created',
label: this.$t('assets.date_joined'),
formatter: DateFormatter
},
{
prop: 'id',
align: 'center',
label: this.$t('assets.Action'),
formatter: ActionsFormatter,
formatterArgs: {
hasUpdate: false, // can set function(row, value)
canUpdate: false, // can set function(row, value)
hasDelete: false, // can set function(row, value)
canDelete: false,
extraActions: [
{
name: 'delete',
title: this.$t('common.Delete'),
type: 'primary',
callback: (val) => {
this.$axios.delete(`/api/v1/assets/asset-users/${val.cellValue}/`).then(
this.$refs.TreeTablePage.$refs.TreeTable.$refs.ListTable.reloadTable()
)
}
},
{
name: this.$t('common.Test'),
title: this.$t('common.Test'),
callback: (val) => {
console.log(val.cellValue)
this.$axios.post(
`api/v1/assets/asset-users/tasks/?id=${val.cellValue}`,
{ action: 'test' }
).then(res => {
window.open(`/core/ops/celery/task/${res.task}/log/`, '', 'width=900,height=600')
})
}
},
{
name: this.$t('common.Update'),
title: this.$t('common.Update'),
callback: function(val) {
console.log(val)
this.showDialog = true
this.dialogInfo.asset = val.row.asset
this.dialogInfo.hostname = val.row.hostname
this.dialogInfo.username = val.row.username
}.bind(this)
},
{
name: 'Push',
title: this.$t('common.Push'),
callback: function(val) {
console.log('Push')
}
}
]
}
}
]
}
}
},
methods: {
handleCancel() {
this.dialogInfo = {
asset: '',
username: '',
hostname: '',
password: '',
key: ''
}
this.showDialog = false
},
Onchange(e) {
const vm = this
// TODO 校验文件类型
const reader = new FileReader()
reader.onload = function() {
vm.dialogInfo.key = this.result
}
reader.readAsText(
e.target.files[0]
)
},
handleConfirm() {
const data = {
asset: this.dialogInfo.asset,
username: this.dialogInfo.username
}
if (this.dialogInfo.password !== '') {
data.password = this.dialogInfo.password
}
if (this.dialogInfo.key !== '') {
data.key = this.dialogInfo.key
}
this.$axios.post(
`/api/v1/assets/asset-users/`,
data
).then(res => {
this.$refs.TreeTablePage.$refs.TreeTable.$refs.ListTable.reloadTable()
this.$message.success(this.$t('common.updateSuccessMsg'))
}).catch(err => {
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
})
this.dialogInfo = {
asset: '',
username: '',
hostname: '',
password: '',
key: ''
}
this.showDialog = false
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,13 +0,0 @@
<template>
<h2>hello</h2>
</template>
<script>
export default {
name: 'Vault'
}
</script>
<style scoped>
</style>

View File

@@ -134,6 +134,26 @@ export default {
}
]
},
{
path: 'vault',
component: empty,
meta: { title: i18n.t('xpack.Vault.Vault'), activeMenu: '/xpack/vault/vault' },
children: [
{
path: 'vault',
component: () => import('@/views/xpack/Vault/VaultList.vue'),
name: 'VaultList',
meta: { title: i18n.t('xpack.Vault.Vault'), activeMenu: '/xpack/vault/vault' }
},
{
path: 'vault/create',
component: () => import('@/views/xpack/Vault/VaultCreate'),
name: 'VaultCreate',
meta: { title: i18n.t('xpack.Vault.Create'), activeMenu: '/xpack/vault/vault' },
hidden: true
}
]
},
{
path: '/cloud',
component: empty,
@@ -183,6 +203,5 @@ export default {
}
]
}
]
}

View File

@@ -1315,6 +1315,13 @@
version "4.2.2"
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
"@ztree/ztree_v3@3.5.44":
version "3.5.44"
resolved "https://registry.yarnpkg.com/@ztree/ztree_v3/-/ztree_v3-3.5.44.tgz#940890a91483bc8a7347f4fe4c9e6e3ffc7d61ec"
integrity sha512-+W6z8rCnls3/Zw9Q9JgpK9C6krQANoGk6wFupNY/aPumjb7JWQiX2V5Uzl12ClCPponaROle7cZxz4bsBWQPWw==
dependencies:
jquery ">=1.4.4"
abab@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a"
@@ -10183,10 +10190,3 @@ zrender@4.3.0:
version "4.3.0"
resolved "https://registry.npm.taobao.org/zrender/download/zrender-4.3.0.tgz#9f056121b20bbae44414d287bf6a119ff7042661"
integrity sha1-nwVhIbILuuREFNKHv2oRn/cEJmE=
ztree@^3.5.24:
version "3.5.24"
resolved "https://registry.yarnpkg.com/ztree/-/ztree-3.5.24.tgz#b63fe52981fdf2c329675cfd2772f0d147521ff1"
integrity sha1-tj/lKYH98sMpZ1z9J3Lw0UdSH/E=
dependencies:
jquery ">=1.4.4"