perf: 用户登录 ACL 挪到控制中

This commit is contained in:
ibuler
2023-06-07 17:41:40 +08:00
parent aa80a07bfc
commit fb85e168e7
19 changed files with 337 additions and 161 deletions

View File

@@ -65,6 +65,10 @@ export default {
return fields
}
},
mounted() {
console.log('Value is: ', this.value)
console.log('Fields: ', this.iFields)
},
methods: {
objectToString(obj) {
let data = ''

View File

@@ -1151,6 +1151,7 @@
},
"route": {
"": "",
"AppletDetail": "Remote apps",
"CreateEndpoint": "Create endpoint",
"UpdateEndpoint": "Update endpoint",

View File

@@ -1150,6 +1150,11 @@
},
"route": {
"": "",
"UserLoginAclList": "登录控制",
"UserLoginAclUpdate": "更新登录控制",
"ConnectMethodAclList": "连接方式",
"ConnectMethodAclCreate": "创建连接方式控制",
"ConnectMethodAclUpdate": "更新连接方式控制",
"AppletDetail": "远程应用",
"AppletHostDetail": "远程应用发布机详情",
"AppletHostCreate": "添加远程应用发布机",
@@ -1369,7 +1374,8 @@
"uploadZipTips": "请上传 zip 格式的文件",
"HostDeployment": "发布机部署",
"TerminalStat": "CPU/内存/磁盘",
"Endpoint": "端点"
"Endpoint": "端点",
"ConnectMethod": "连接方式"
},
"sessions": {
"SetToDefaultStorage": "设置为默认存储",

View File

@@ -39,6 +39,7 @@ export default [
}
]
},
{
path: 'login-asset-acls',
component: empty,
@@ -53,27 +54,27 @@ export default [
{
path: '',
name: 'AssetAclList',
component: () => import('@/views/acl/AssetAcl/AssetAclList'),
component: () => import('@/views/acl/AssetLoginAcl/AssetLoginAclList.vue'),
meta: { title: i18n.t('route.AssetAclList') }
},
{
path: 'create',
name: 'AssetAclCreate',
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
component: () => import('@/views/acl/AssetLoginAcl/AssetLoginAclCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.AssetAclCreate') }
},
{
path: ':id',
name: 'AssetAclDetail',
component: () => import('@/views/acl/AssetAcl/AssetAclDetail/index'),
component: () => import('@/views/acl/AssetLoginAcl/AssetLoginAclDetail/index'),
hidden: true,
meta: { title: i18n.t('route.AssetAclDetail') }
},
{
path: ':id/update',
name: 'AssetAclUpdate',
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
component: () => import('@/views/acl/AssetLoginAcl/AssetLoginAclCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.AssetAclUpdate') }
}
@@ -175,5 +176,90 @@ export default [
}
}
]
},
{
path: 'login-acls',
component: empty,
redirect: '',
meta: {
title: i18n.t('route.UserLoginAclList'),
app: 'acls',
resource: 'loginacl'
},
children: [
{
path: '',
name: 'UserLoginAclList',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLList.vue'),
meta: { title: i18n.t('route.UserLoginAclList') }
},
{
path: 'create',
name: 'UserLoginAclCreate',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLCreateUpdate.vue'),
hidden: true,
meta: {
title: i18n.t('route.UserLoginAclCreate')
}
},
{
path: ':id',
name: 'UserLoginAclDetail',
component: () => import('@/views/acl/UserLoginACL/UserDetail/index'),
hidden: true,
meta: {
title: i18n.t('route.AssetAclDetail'),
app: 'acls',
resource: 'loginacl'
}
},
{
path: ':id/update',
name: 'UserLoginAclUpdate',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.UserLoginAclUpdate') }
}
]
},
{
path: 'connect-method-acls',
component: empty,
redirect: '',
meta: {
title: i18n.t('route.ConnectMethodList'),
licenseRequired: true,
app: 'acls',
resource: 'connectmethodacl'
},
children: [
{
path: '',
name: 'ConnectMethodAclList',
component: () => import('@/views/acl/ConnectMethodAcl/ConnectMethodAclList.vue'),
meta: { title: i18n.t('route.ConnectMethodAclList') }
},
{
path: 'create',
name: 'ConnectMethodAclCreate',
component: () => import('@/views/acl/ConnectMethodAcl/ConnectMethodAclCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.ConnectMethodAclCreate') }
},
{
path: ':id',
name: 'ConnectMethodAclDetail',
component: () => import('@/views/acl/AssetLoginAcl/AssetLoginAclDetail/index'),
hidden: true,
meta: { title: i18n.t('route.AssetAclDetail') }
},
{
path: ':id/update',
name: 'ConnectMethodAclUpdate',
component: () => import('@/views/acl/ConnectMethodAcl/ConnectMethodAclCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.ConnectMethodAclUpdate') }
}
]
}
]

View File

@@ -2,7 +2,6 @@ import i18n from '@/i18n/i18n'
import empty from '@/layout/empty'
import { BASE_URL } from '@/utils/common'
// Todo: 放到系统设置中
export default [
{
path: 'sessions',

View File

@@ -44,47 +44,6 @@ export default [
name: 'UserDetail',
hidden: true,
meta: { title: i18n.t('route.UserDetail') }
},
{
path: 'user-acl',
component: empty,
redirect: '',
hidden: true,
meta: {
title: i18n.t('route.UserLoginACLList'),
app: 'acls',
resource: 'loginacl'
},
children: [
{
path: '',
name: 'UserLoginACLList',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLList'),
hidden: true,
meta: { title: i18n.t('route.UserLoginACLList') }
},
{
path: 'create',
name: 'UserLoginACLCreate',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLCreateUpdate'),
hidden: true,
meta: { title: i18n.t('route.UserLoginACLCreate') }
},
{
path: ':id',
name: 'UserLoginACLDetail',
component: () => import('@/views/acl/UserLoginACL/UserDetail/index'),
hidden: true,
meta: { title: i18n.t('route.UserLoginACLDetail') }
},
{
path: ':id/update',
name: 'UserLoginACLUpdate',
component: () => import('@/views/acl/UserLoginACL/UserLoginACLCreateUpdate'),
hidden: true,
meta: { title: i18n.t('route.UserLoginACLUpdate') }
}
]
}
]
},

View File

@@ -107,7 +107,10 @@ export async function generatePageRoutes({ to, from, next }) {
hidden: true
}]
// dynamically add accessible routes
Vue.$log.debug('All routes:', accessRoutes)
Vue.$log.debug('All routes:', accessRoutes.reduce((acc, cur) => {
acc[cur.name] = cur
return acc
}, {}))
router.addRoutes(accessRoutes)
await store.dispatch('permission/generateViewRoutes', { to, from })

View File

@@ -19,11 +19,9 @@ export default {
return {
initial: {
accounts: ['@ALL'],
rules: [
{
ip_group: ['*']
}
]
rules: {
ip_group: ['*']
}
},
fields: [
[this.$t('common.Basic'), ['name', 'priority']],

View File

@@ -0,0 +1,71 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import rules from '@/components/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
import { assetJSONSelectMeta } from '@/views/assets/const'
import { Select2 } from '@/components/FormFields'
export default {
name: 'AclCreateUpdate',
components: {
GenericCreateUpdatePage
},
data() {
return {
initial: {
},
fields: [
[this.$t('common.Basic'), ['name', 'priority']],
[this.$t('users.Users'), ['users']],
[this.$t('terminal.ConnectMethod'), ['connect_methods']],
[this.$t('common.Action'), ['action', 'reviewers']],
[this.$t('common.Other'), ['is_active', 'comment']]
],
fieldsMeta: {
priority: {
rules: [rules.Required]
},
assets: assetJSONSelectMeta(this),
users: userJSONSelectMeta(this),
connect_methods: {
component: Select2,
label: this.$t('terminal.ConnectMethod'),
el: {
url: '/api/v1/terminal/components/connect-methods/?flat=1&limit=10&os=all',
ajax: {
processResults: (data) => {
return {
results: data,
more: false
}
}
}
}
},
reviewers: {
hidden: (item) => item.action !== 'review',
rules: [rules.RequiredChange],
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/connect-method-acls/'
}
},
methods: {}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,35 @@
<template>
<GenericListPage :header-actions="headerActions" :table-config="tableConfig" />
</template>
<script>
import GenericListPage from '@/layout/components/GenericListPage/index.vue'
export default {
name: 'ConnectMethodListAcl',
components: { GenericListPage },
data() {
return {
tableConfig: {
url: '/api/v1/acls/connect-method-acls/',
columnsExclude: ['users', 'assets', 'accounts'],
columnsShow: {
min: ['name', 'actions'],
default: [
'name', 'priority', 'is_active', 'comment', 'actions'
]
}
},
headerActions: {
hasRefresh: true,
hasExport: false,
hasImport: false
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,5 +1,5 @@
<template>
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
<GenericDetailPage :active-menu.sync="config.activeMenu" :object.sync="TaskDetail" v-bind="config" v-on="$listeners">
<keep-alive>
<component :is="config.activeMenu" :object="TaskDetail" />
</keep-alive>
@@ -9,6 +9,7 @@
<script>
import { GenericDetailPage } from '@/layout/components'
import Detail from './Detail.vue'
export default {
components: {
GenericDetailPage,
@@ -27,8 +28,8 @@ export default {
],
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}`
detailApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/`,
deleteApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/`
}
}
}

View File

@@ -1,14 +1,12 @@
<template>
<GenericCreateUpdatePage
:after-get-form-value="afterGetFormValue"
v-bind="$data"
/>
<GenericCreateUpdatePage v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import { WeekCronSelect } from '@/components/FormFields'
import { Required } from '@/components/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
export default {
name: 'AclCreateUpdate',
@@ -23,17 +21,15 @@ export default {
users: {
username_group: ''
},
rules: [
{
ip_group: ['*']
}
]
rules: {
ip_group: ['*']
}
},
url: '/api/v1/acls/login-acls/',
hasDetailInMsg: false,
fields: [
[this.$t('common.Basic'), ['name', 'priority']],
[this.$t('acl.users'), ['user']],
[this.$t('acl.users'), ['users']],
[this.$t('acl.Rules'), ['rules']],
[this.$t('acl.Action'), ['action', 'reviewers']],
[this.$t('common.Other'), ['is_active', 'comment']]
@@ -42,18 +38,7 @@ export default {
is_active: {
type: 'checkbox'
},
user: {
el: {
disabled: !!this.$route.query.user,
multiple: false,
ajax: {
url: '/api/v1/users/users/?fields_size=mini&all=true',
transformOption: (item) => {
return { label: item.name + '(' + item.username + ')', value: item.id }
}
}
}
},
users: userJSONSelectMeta(this),
reviewers: {
el: {
value: [],
@@ -97,46 +82,10 @@ export default {
}
return url
},
updateSuccessNextRoute: this.$route.query.user ? { name: 'UserDetail', params: {
id: this.$route.query.user
}} : { name: 'UserLoginACLList' },
createSuccessNextRoute: this.$route.query.user ? { name: 'UserDetail', params: {
id: this.$route.query.user
}} : { name: 'UserLoginACLList' },
onPerformError(error, method, vm) {
this.$emit('submitError', error)
const response = error.response
const data = response.data
if (response.status === 400) {
for (const key of Object.keys(data)) {
let value = data[key]
if (key === 'ip_group') {
value = Object.values(data[key])
}
if (value instanceof Array) {
value = value.join(';')
}
this.$refs.form.setFieldError(key, value)
}
}
},
afterGetFormValue(validValues) {
if (!this.$route.query.user) {
validValues.users.username_group = validValues.users.username_group.toString()
}
return validValues
},
cleanFormValue(value) {
if (!Array.isArray(value.rules.ip_group)) {
value.rules.ip_group = value.rules.ip_group ? value.rules.ip_group.split(',') : []
}
if (!this.$route.query.user) {
if (!Array.isArray(value.users.username_group)) {
value.users.username_group = value.users.username_group ? value.users.username_group.split(',') : []
}
} else {
delete value.users
}
if (value.action !== 'review') {
value.reviewers = []
}

View File

@@ -1,56 +1,21 @@
<template>
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
<Page>
<UserLoginACLTable />
</Page>
</template>
<script>
import GenericListTable from '@/layout/components/GenericListTable'
import UserLoginACLTable from '@/views/acl/UserLoginACL/UserLoginACLTable.vue'
import Page from '@/layout/components/Page'
export default {
components: {
GenericListTable
UserLoginACLTable,
Page
},
data() {
return {
tableConfig: {
url: `/api/v1/acls/login-acls/?user=${this.$route.params.id}`,
columnsExclude: ['rules'],
columnsShow: {
min: ['name', 'actions'],
default: ['name', 'priority', 'is_active', 'user_display', 'action', 'comment', 'actions']
},
columnsMeta: {
name: {
formatterArgs: {
route: 'UserLoginACLDetail',
routeQuery: {
user: this.$route.params.id
}
}
},
reviewers_amount: {
label: this.$t('common.ApproverNumbers')
},
actions: {
formatterArgs: {
hasClone: false,
updateRoute: { name: 'UserLoginACLUpdate', 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: 'UserLoginACLCreate', query: { user: this.$route.params.id }},
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false
}
}
return {}
}
}
</script>

View File

@@ -0,0 +1,69 @@
<template>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
</template>
<script>
import ListTable from '@/components/ListTable/index.vue'
export default {
components: {
ListTable
},
props: {
url: {
type: String,
default: '/api/v1/acls/login-acls/'
}
},
data() {
return {
tableConfig: {
url: this.url,
columnsExclude: ['rules'],
columnsShow: {
min: ['name', 'actions'],
default: [
'name', 'priority', 'is_active',
'action', 'comment', 'actions'
]
},
columnsMeta: {
name: {
formatterArgs: {
route: 'UserLoginAclDetail'
}
},
reviewers_amount: {
label: this.$t('common.ApproverNumbers')
},
actions: {
formatterArgs: {
hasClone: false,
updateRoute: ({ row }) => {
console.log('row', row)
return {
name: 'UserLoginAclUpdate',
params: {
id: row.id
}
}
}
}
}
}
},
headerActions: {
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,30 @@
<template>
<UserLoginACLTable :url="url" />
</template>
<script>
import UserLoginACLTable from '@/views/acl/UserLoginACL/UserLoginACLTable.vue'
export default {
name: 'UserLoginAcl',
components: {
UserLoginACLTable
},
props: {
object: {
type: Object,
required: true
}
},
data() {
return {
url: '/api/v1/acls/login-acls/?users=' + this.object.id
}
}
}
</script>
<style scoped>
</style>

View File

@@ -10,14 +10,14 @@
import { GenericDetailPage } from '@/layout/components'
import UserAssetPermissionRules from './UserAssetPermissionRules'
import UserGrantedAssets from './UserGrantedAssets'
import UserLoginACLList from '@/views/acl/UserLoginACL/UserLoginACLList'
import UserInfo from './UserInfo'
import UserLoginAcl from './UserLoginAcl.vue'
import { mapGetters } from 'vuex'
export default {
components: {
UserInfo,
UserLoginACLList,
UserLoginAcl,
GenericDetailPage,
UserGrantedAssets,
UserAssetPermissionRules
@@ -51,7 +51,7 @@ export default {
},
{
title: this.$t('route.UserAclLists'),
name: 'UserLoginACLList',
name: 'UserLoginAcl',
hidden: () => !vm.$hasPerm('acls.view_loginacl')
}
]