mirror of
https://github.com/jumpserver/lina.git
synced 2025-07-06 19:48:44 +00:00
perf: 增加ACL控制页面 (#651)
* perf: 增加ACL控制页面 * fix: 修改页面 * fix: 修改页面 * fix: 修改页面 * fix: 修改页面 * fix: update * fix: 完善路由条件 * fix: 完善默认值 * fix: 完善翻译 * fix: 完善表单默认值 * fix: 完善表单默认值 Co-authored-by: Orange <orangemtony@gmail.com>
This commit is contained in:
parent
3ad157848a
commit
f6aab29ecc
18
src/components/ListTable/formatters/ArrayFormatter.vue
Normal file
18
src/components/ListTable/formatters/ArrayFormatter.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<span>{{ cellValue }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseFormatter from './base'
|
||||
export default {
|
||||
name: 'ArrayFormatter',
|
||||
extends: BaseFormatter,
|
||||
mounted() {
|
||||
console.log(this.cellValue, '111')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,4 +1,5 @@
|
||||
import DetailFormatter from './DetailFormatter'
|
||||
import ArrayFormatter from './ArrayFormatter'
|
||||
import DisplayFormatter from './DisplayFormatter'
|
||||
import BooleanFormatter from './ChoicesFormatter'
|
||||
import ActionsFormatter from './ActionsFormatter'
|
||||
@ -19,7 +20,8 @@ export default {
|
||||
SystemUserFormatter,
|
||||
ShowKeyFormatter,
|
||||
DialogDetailFormatter,
|
||||
LoadingActionsFormatter
|
||||
LoadingActionsFormatter,
|
||||
ArrayFormatter
|
||||
}
|
||||
|
||||
export {
|
||||
@ -32,5 +34,6 @@ export {
|
||||
SystemUserFormatter,
|
||||
ShowKeyFormatter,
|
||||
DialogDetailFormatter,
|
||||
LoadingActionsFormatter
|
||||
LoadingActionsFormatter,
|
||||
ArrayFormatter
|
||||
}
|
||||
|
@ -1,5 +1,27 @@
|
||||
{
|
||||
"": "",
|
||||
"acl": {
|
||||
"name": "名称",
|
||||
"username": "用户名",
|
||||
"ip_group": "IP 组",
|
||||
"action": "动作",
|
||||
"priority": "优先级",
|
||||
"date_created": "创建时间",
|
||||
"created_by": "创建者",
|
||||
"asset": "资产信息",
|
||||
"users":"用户信息",
|
||||
"system_user": "系统用户",
|
||||
"username_group":"用户名",
|
||||
"hostname_group":"资产名",
|
||||
"asset_ip_group": "资产IP",
|
||||
"system_users_name_group": "系统用户名称",
|
||||
"system_users_protocol_group": "系统用户协议",
|
||||
"system_users_username_group": "系统用户名",
|
||||
"apply_login_asset": "申请登录资产",
|
||||
"apply_login_system_user": "申请登录系统用户",
|
||||
"apply_login_user": "申请登录用户",
|
||||
"RuleDetail": "规则详情"
|
||||
},
|
||||
"applications": {
|
||||
"": "",
|
||||
"RemoteApp": "远程应用",
|
||||
@ -529,7 +551,15 @@
|
||||
"KubernetesAppPermissionDetail": "Kubernetes授权详情",
|
||||
"KubernetesAppPermissionUpdate": "更新Kubernetes授权规则",
|
||||
"KubernetesAppUpdate": "更新Kubernetes",
|
||||
|
||||
"Acl": "访问控制",
|
||||
"UserAclList": "用户登录",
|
||||
"UserAclCreate": "创建用户登录规则",
|
||||
"UserAclUpdate": "更新用户登录规则",
|
||||
"UserAclDetail": "用户登录规则详情",
|
||||
"AssetAclList": "登录资产",
|
||||
"AssetAclCreate": "创建资产登录规则",
|
||||
"AssetAclUpdate": "更新资产登录规则",
|
||||
"AssetAclDetail": "资产登录规则详情",
|
||||
"DomainCreate": "创建网域",
|
||||
"DomainDetail": "网域详情",
|
||||
"DomainList": "网域列表",
|
||||
|
@ -1,5 +1,26 @@
|
||||
{
|
||||
"": "",
|
||||
"acl": {
|
||||
"name": "Name",
|
||||
"username": "Username",
|
||||
"ip_group": "IP group",
|
||||
"action": "Action",
|
||||
"priority": "Priority",
|
||||
"date_created": "Date created",
|
||||
"created_by": "Created by",
|
||||
"asset": "Asset",
|
||||
"system_user": "System user",
|
||||
"username_group":"Username group",
|
||||
"hostname_group":"Hostname group",
|
||||
"asset_ip_group": "Asset ip group",
|
||||
"system_users_name_group": "Systemusers name group",
|
||||
"system_users_protocol_group": "Systemusers protocol group",
|
||||
"system_users_username_group": "systemusers username group",
|
||||
"apply_login_asset": "Apply login asset",
|
||||
"apply_login_system_user": "Apply login system user",
|
||||
"apply_login_user": "Apply login user",
|
||||
"RuleDetail": "Rule detail"
|
||||
},
|
||||
"applications": {
|
||||
"": "",
|
||||
"RemoteApp": "Remote app",
|
||||
@ -527,6 +548,15 @@
|
||||
"KubernetesAppPermissionDetail": "Kubernetes permissions detail",
|
||||
"KubernetesAppPermissionUpdate": "Kubernetes permissions update",
|
||||
"KubernetesAppUpdate": "Kubernetes app update",
|
||||
"Acl": "Access control",
|
||||
"UserAclList": "User acl list",
|
||||
"UserAclCreate": "User acl create",
|
||||
"UserAclUpdate": "User acl update",
|
||||
"UserAclDetail": "User acl detail",
|
||||
"AssetAclList": "Asset acl list",
|
||||
"AssetAclCreate": "Asset acl create",
|
||||
"AssetAclUpdate": "Asset acl update",
|
||||
"AssetAclDetail": "Asset acl detail",
|
||||
"DomainCreate": "Domain create",
|
||||
"DomainDetail": "Domain detail",
|
||||
"DomainList": "Domains",
|
||||
|
42
src/router/acl.js
Normal file
42
src/router/acl.js
Normal file
@ -0,0 +1,42 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import empty from '@/layout/empty'
|
||||
export default [
|
||||
{
|
||||
path: 'asset-acl',
|
||||
component: empty,
|
||||
redirect: '',
|
||||
meta: {
|
||||
title: i18n.t('route.AssetAclList'),
|
||||
licenseRequired: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'AssetAclList',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclList'),
|
||||
meta: { title: i18n.t('route.AssetAclList'), activeMenu: '/acl/asset-acl' }
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'AssetAclCreate',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.AssetAclCreate'), activeMenu: '/acl/assetAcl' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
name: 'AssetAclDetail',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclDetail'),
|
||||
meta: { title: i18n.t('route.AssetAclDetail'), activeMenu: '/acl/asset-acl' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
name: 'AssetAclUpdate',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.AssetAclUpdate'), activeMenu: '/acl/asset-acl' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -36,6 +36,7 @@ import OpsRoutes from './ops'
|
||||
import TicketsRoutes from './tickets'
|
||||
import AuditsRoutes from './audits'
|
||||
import commonRoutes from './common'
|
||||
import aclRoutes from './acl'
|
||||
|
||||
/**
|
||||
* constantRoutes
|
||||
@ -117,6 +118,17 @@ export const allRoleRoutes = [
|
||||
meta: { title: i18n.t('route.Perms'), icon: 'edit' },
|
||||
children: PermsRoute
|
||||
},
|
||||
{
|
||||
path: '/acl/',
|
||||
component: Layout,
|
||||
redirect: '/perms/access-control-list/',
|
||||
name: 'Acl',
|
||||
meta: {
|
||||
licenseRequired: true,
|
||||
title: i18n.t('route.Acl'),
|
||||
icon: 'fort-awesome' },
|
||||
children: aclRoutes
|
||||
},
|
||||
{
|
||||
path: '/terminal/',
|
||||
component: Layout,
|
||||
|
@ -28,6 +28,13 @@ export default [
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/login-asset-confirm/:id',
|
||||
name: 'loginAssetTicketDetail',
|
||||
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
|
@ -103,6 +103,13 @@ export default [
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/login-asset-confirm/:id',
|
||||
name: 'loginAssetTicketDetail',
|
||||
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import empty from '@/layout/empty'
|
||||
export default [
|
||||
{
|
||||
path: 'users',
|
||||
@ -53,5 +54,42 @@ export default [
|
||||
name: 'UserGroupDetail',
|
||||
hidden: true,
|
||||
meta: { title: i18n.t('route.UserGroupDetail'), activeMenu: '/users/groups' }
|
||||
},
|
||||
{
|
||||
path: 'user-acl',
|
||||
component: empty,
|
||||
redirect: '',
|
||||
meta: { title: i18n.t('route.UserAclList') },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'UserAclList',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclList'),
|
||||
meta: { title: i18n.t('route.UserAclList'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'UserAclCreate',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.UserAclCreate'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
name: 'UserAclDetail',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclDetail'),
|
||||
meta: { title: i18n.t('route.UserAclDetail'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
name: 'UserAclUpdate',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.UserAclUpdate') },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
114
src/views/acl/AssetAcl/AssetAclCreateUpdate.vue
Normal file
114
src/views/acl/AssetAcl/AssetAclCreateUpdate.vue
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" :perform-submit="performSubmit" :after-get-form-value="afterGetFormValue" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
export default {
|
||||
name: 'AclCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
action: 'login_confirm',
|
||||
system_users: {
|
||||
name_group: '*',
|
||||
protocol_group: '*',
|
||||
username_group: '*'
|
||||
},
|
||||
users: {
|
||||
username_group: '*'
|
||||
},
|
||||
assets: {
|
||||
hostname_group: '*',
|
||||
ip_group: '*'
|
||||
}
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'priority']],
|
||||
[this.$t('acl.users'), ['users']],
|
||||
[this.$t('acl.asset'), ['assets']],
|
||||
[this.$t('acl.system_user'), ['system_users']],
|
||||
[this.$t('acl.action'), ['action', 'reviewers']],
|
||||
[this.$t('common.Other'), ['is_active', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
assets: {
|
||||
fields: ['hostname_group', 'ip_group']
|
||||
},
|
||||
users: {
|
||||
fields: ['username_group'],
|
||||
fieldsMeta: {
|
||||
|
||||
}
|
||||
},
|
||||
system_users: {
|
||||
fields: ['name_group', 'username_group', 'protocol_group']
|
||||
},
|
||||
reviewers: {
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/users/users/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/acls/login-asset-acls/'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMethod() {
|
||||
const params = this.$route.params
|
||||
if (params.id) {
|
||||
return 'put'
|
||||
} else {
|
||||
return 'post'
|
||||
}
|
||||
},
|
||||
afterGetFormValue(validValues) {
|
||||
validValues.assets.ip_group = validValues.assets.ip_group.toString()
|
||||
validValues.assets.hostname_group = validValues.assets.hostname_group.toString()
|
||||
validValues.system_users.name_group = validValues.system_users.name_group.toString()
|
||||
validValues.system_users.protocol_group = validValues.system_users.protocol_group.toString()
|
||||
validValues.system_users.username_group = validValues.system_users.username_group.toString()
|
||||
validValues.users.username_group = validValues.users.username_group.toString()
|
||||
return validValues
|
||||
},
|
||||
performSubmit(validValues) {
|
||||
if (validValues.assets.ip_group) {
|
||||
console.log(validValues.assets.ip_group)
|
||||
validValues.assets.ip_group = validValues.assets.ip_group.split(',')
|
||||
}
|
||||
if (validValues.assets.hostname_group) {
|
||||
validValues.assets.hostname_group = validValues.assets.hostname_group.split(',')
|
||||
}
|
||||
if (validValues.system_users.protocol_group) {
|
||||
validValues.system_users.protocol_group = validValues.system_users.protocol_group.split(',')
|
||||
}
|
||||
if (validValues.system_users.name_group) {
|
||||
validValues.system_users.name_group = validValues.system_users.name_group.split(',')
|
||||
}
|
||||
if (validValues.system_users.username_group) {
|
||||
validValues.system_users.username_group = validValues.system_users.username_group.split(',')
|
||||
}
|
||||
if (validValues.users.username_group) {
|
||||
validValues.users.username_group = validValues.users.username_group.split(',')
|
||||
}
|
||||
const baseUrl = `/api/v1/acls/login-asset-acls/`
|
||||
const method = this.getMethod()
|
||||
return this.$axios[method](`${baseUrl}`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
113
src/views/acl/AssetAcl/AssetAclDetail/detail.vue
Normal file
113
src/views/acl/AssetAcl/AssetAclDetail/detail.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
// import RelationCard from '@/components/RelationCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
DetailCard
|
||||
// RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUserWithThis'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('acl.name'),
|
||||
value: this.object.name
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.username_group'),
|
||||
value: this.object.users.username_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.hostname_group'),
|
||||
value: this.object.assets.hostname_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.asset_ip_group'),
|
||||
value: this.object.assets.ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_name_group'),
|
||||
value: this.object.system_users.name_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_protocol_group'),
|
||||
value: this.object.system_users.protocol_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_username_group'),
|
||||
value: this.object.system_users.username_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.action'),
|
||||
value: this.object.action_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.priority'),
|
||||
value: this.object.priority
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.date_created'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.created_by'),
|
||||
value: this.object.created_by
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
41
src/views/acl/AssetAcl/AssetAclDetail/index.vue
Normal file
41
src/views/acl/AssetAcl/AssetAclDetail/index.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="TaskDetail" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import detail from './detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
detail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
TaskDetail: {},
|
||||
config: {
|
||||
activeMenu: 'detail',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('acl.RuleDetail'),
|
||||
name: 'detail'
|
||||
}
|
||||
],
|
||||
hasRightSide: true,
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/acls/login-asset-acls/${this.$route.params.id}/`,
|
||||
deleteApiUrl: `/api/v1/acls/login-asset-acls/${this.$route.params.id}/`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
67
src/views/acl/AssetAcl/AssetAclList.vue
Normal file
67
src/views/acl/AssetAcl/AssetAclList.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/acls/login-asset-acls/',
|
||||
columns: ['name', 'user_username_group', 'hostname_group', 'ip_group', 'name_group', 'protocol_group', 'systemuser_username_group', 'reviewers', 'priority', 'is_active', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'user_username_group', 'hostname_group', 'ip_group', 'reviewers', 'priority', 'is_active', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
user_username_group: {
|
||||
prop: 'users.username_group',
|
||||
showOverflowTooltip: true,
|
||||
label: this.$t('acl.username_group')
|
||||
},
|
||||
reviewers: {
|
||||
prop: 'reviewers_amount'
|
||||
},
|
||||
hostname_group: {
|
||||
prop: 'assets.hostname_group',
|
||||
label: this.$t('acl.hostname_group')
|
||||
},
|
||||
ip_group: {
|
||||
prop: 'assets.ip_group',
|
||||
label: this.$t('acl.asset_ip_group')
|
||||
},
|
||||
name_group: {
|
||||
prop: 'system_users.name_group',
|
||||
label: this.$t('acl.system_users_name_group')
|
||||
},
|
||||
protocol_group: {
|
||||
prop: 'system_users.protocol_group',
|
||||
label: this.$t('acl.system_users_protocol_group')
|
||||
},
|
||||
systemuser_username_group: {
|
||||
prop: 'system_users.username_group',
|
||||
label: this.$t('acl.system_users_username_group')
|
||||
}
|
||||
}
|
||||
},
|
||||
updateRoute: 'AssetAclUpdate',
|
||||
headerActions: {
|
||||
createRoute: 'AssetAclCreate',
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
91
src/views/acl/UserAcl/UserAclCreateUpdate.vue
Normal file
91
src/views/acl/UserAcl/UserAclCreateUpdate.vue
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
v-bind="$data"
|
||||
:perform-submit="performSubmit"
|
||||
:after-get-form-value="afterGetFormValue"
|
||||
:get-url="getUrl"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
export default {
|
||||
name: 'AclCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
action: 'reject',
|
||||
ip_group: '*',
|
||||
user: this.$route.query.user
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'user', 'ip_group', 'action', 'priority']],
|
||||
[this.$t('common.Other'), ['is_active', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
is_active: {
|
||||
type: 'checkbox'
|
||||
},
|
||||
user: {
|
||||
el: {
|
||||
disabled: true,
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/users/users/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: `/api/v1/acls/login-acls/`,
|
||||
updateSuccessNextRoute: { name: 'UserDetail', params: {
|
||||
id: this.$route.query.user
|
||||
}},
|
||||
createSuccessNextRoute: { name: 'UserDetail', params: {
|
||||
id: this.$route.query.user
|
||||
}}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMethod() {
|
||||
const params = this.$route.params
|
||||
if (params.id) {
|
||||
return 'put'
|
||||
} else {
|
||||
return 'post'
|
||||
}
|
||||
},
|
||||
getUrl() {
|
||||
const params = this.$route.params
|
||||
let url = this.url
|
||||
if (params.id) {
|
||||
url = `${url}${params.id}/?user=${this.$route.query.user}`
|
||||
} else {
|
||||
url = `${url}?user=${this.$route.query.user}`
|
||||
}
|
||||
return url
|
||||
},
|
||||
afterGetFormValue(validValues) {
|
||||
validValues.ip_group = validValues.ip_group.toString()
|
||||
return validValues
|
||||
},
|
||||
performSubmit(validValues) {
|
||||
if (validValues.ip_group) {
|
||||
validValues.ip_group = validValues.ip_group.split(',')
|
||||
}
|
||||
const method = this.getMethod()
|
||||
return this.$axios[method](`${this.getUrl()}}`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
97
src/views/acl/UserAcl/UserAclDetail/Detail.vue
Normal file
97
src/views/acl/UserAcl/UserAclDetail/Detail.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
// import RelationCard from '@/components/RelationCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
DetailCard
|
||||
// RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUserWithThis'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('acl.name'),
|
||||
value: this.object.name
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.username'),
|
||||
value: this.object.user_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.ip_group'),
|
||||
value: this.object.ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.action'),
|
||||
value: this.object.action_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.priority'),
|
||||
value: this.object.priority
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.date_created'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.created_by'),
|
||||
value: this.object.created_by
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
41
src/views/acl/UserAcl/UserAclDetail/index.vue
Normal file
41
src/views/acl/UserAcl/UserAclDetail/index.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="TaskDetail" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import Detail from './Detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
Detail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
TaskDetail: {},
|
||||
config: {
|
||||
activeMenu: 'Detail',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('acl.RuleDetail'),
|
||||
name: 'Detail'
|
||||
}
|
||||
],
|
||||
hasRightSide: false,
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/?user=${this.$route.query.user}`,
|
||||
deleteApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/?user=${this.$route.query.user}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
65
src/views/acl/UserAcl/UserAclList.vue
Normal file
65
src/views/acl/UserAcl/UserAclList.vue
Normal file
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import { ArrayFormatter } from '@/components/ListTable/formatters'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/acls/login-acls/?user=${this.$route.params.id}`,
|
||||
columns: ['name', 'ip_group', 'priority', 'action', 'is_active', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'ip_group', 'priority', 'action', 'is_active', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatterArgs: {
|
||||
route: 'UserAclDetail',
|
||||
routeQuery: {
|
||||
user: this.$route.params.id
|
||||
}
|
||||
}
|
||||
},
|
||||
ip_group: {
|
||||
formatter: ArrayFormatter,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
action: {
|
||||
prop: 'action_display'
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasClone: false,
|
||||
updateRoute: { name: 'UserAclUpdate', query: { user: this.$route.params.id }},
|
||||
performDelete: ({ row, col }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/acls/login-acls/${id}/?user=${this.$route.params.id}`
|
||||
return this.$axios.delete(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
createRoute: { name: 'UserAclCreate', query: { user: this.$route.params.id }},
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
95
src/views/tickets/LoginAssetConfirm/Detail/TicketDetail.vue
Normal file
95
src/views/tickets/LoginAssetConfirm/Detail/TicketDetail.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<GenericTicketDetail :object="object" :detail-card-items="detailCardItems" :special-card-items="specialCardItems" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { STATUS_MAP } from '../../const'
|
||||
import { formatTime, getDateTimeStamp } from '@/utils/index'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import GenericTicketDetail from '@/views/tickets/components/GenericTicketDetail'
|
||||
export default {
|
||||
name: 'AssetTicketDetail',
|
||||
components: {
|
||||
GenericTicketDetail
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
imageUrl: require('@/assets/img/admin.png'),
|
||||
form: {
|
||||
comments: ''
|
||||
},
|
||||
comments: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.Applicant'),
|
||||
value: this.object.applicant_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.type'),
|
||||
value: this.object.type_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.status'),
|
||||
value: this.object.status,
|
||||
formatter: (item, val) => {
|
||||
return <el-tag type={this.statusMap.type} size='mini'> { this.statusMap.title }</el-tag>
|
||||
}
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
value: this.object.assignees_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: this.object.processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
}
|
||||
]
|
||||
},
|
||||
specialCardItems() {
|
||||
return [
|
||||
// apply_login_asset: "114.118.2.76(114.118.2.76)"
|
||||
// apply_login_system_user: "root()"
|
||||
// apply_login_user: "Administrator(admin)"
|
||||
{
|
||||
key: this.$t('acl.apply_login_asset'),
|
||||
value: this.object.meta.apply_login_asset
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.apply_login_system_user'),
|
||||
value: this.object.meta.apply_login_system_user
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.apply_login_user'),
|
||||
value: this.object.meta.apply_login_user
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTime(dateStr) {
|
||||
return formatTime(getDateTimeStamp(dateStr))
|
||||
},
|
||||
toSafeLocalDateStr(dataStr) {
|
||||
return toSafeLocalDateStr(dataStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
50
src/views/tickets/LoginAssetConfirm/Detail/index.vue
Normal file
50
src/views/tickets/LoginAssetConfirm/Detail/index.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="ticket" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<component :is="config.activeMenu" :object="ticket" />
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage, TabPage } from '@/layout/components'
|
||||
import TicketDetail from './TicketDetail'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
TicketDetail,
|
||||
TabPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' },
|
||||
config: {
|
||||
activeMenu: 'TicketDetail',
|
||||
url: '',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('route.TicketDetail'),
|
||||
name: 'TicketDetail'
|
||||
}
|
||||
],
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/tickets/tickets/${this.$route.params.id}/`
|
||||
},
|
||||
getObjectName: this.getObjectName,
|
||||
hasRightSide: false
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
getObjectName() {
|
||||
return this.ticket.title
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -36,6 +36,8 @@ export default {
|
||||
return 'AssetsTicketDetail'
|
||||
} else if (row.type === 'apply_application') {
|
||||
return 'AppsTicketDetail'
|
||||
} else if (row.type === 'login_asset_confirm') {
|
||||
return 'loginAssetTicketDetail'
|
||||
} else {
|
||||
return 'TicketDetail'
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import UserApplicationPermissionRules from './UserApplicationsPermissionRules'
|
||||
import UserGrantedDatabases from './UserGrantedDatabases'
|
||||
import UserGrantedK8Ss from './UserGrantedK8Ss'
|
||||
import UserK8SPermissionRules from './UserK8SPermissionRules'
|
||||
import UserAclList from '@/views/acl/UserAcl/UserAclList'
|
||||
import UserDatabasePermissionRules from './UserDatabasePermissionRules'
|
||||
import UserInfo from './UserInfo'
|
||||
|
||||
@ -29,7 +30,8 @@ export default {
|
||||
UserGrantedDatabases,
|
||||
UserDatabasePermissionRules,
|
||||
UserK8SPermissionRules,
|
||||
UserGrantedK8Ss
|
||||
UserGrantedK8Ss,
|
||||
UserAclList
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
@ -61,23 +63,11 @@ export default {
|
||||
{
|
||||
title: this.$t('users.tabs.ApplicationPermissionRules'),
|
||||
name: 'UserApplicationPermissionRules'
|
||||
},
|
||||
{
|
||||
title: '用户登录规则',
|
||||
name: 'UserAclList'
|
||||
}
|
||||
// {
|
||||
// title: this.$t('users.tabs.grantedDatabases'),
|
||||
// name: 'UserGrantedDatabases'
|
||||
// },
|
||||
// {
|
||||
// title: this.$t('users.tabs.databasePermissionRules'),
|
||||
// name: 'UserDatabasePermissionRules'
|
||||
// },
|
||||
// {
|
||||
// title: this.$t('users.tabs.grantedK8Ss'),
|
||||
// name: 'UserGrantedK8Ss'
|
||||
// },
|
||||
// {
|
||||
// title: this.$t('users.tabs.k8sPermissionRules'),
|
||||
// name: 'UserK8SPermissionRules'
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user