fix: rbac 合并 (#1329)

* perf: 修改 route name

* fix: perm app router

* fix: 修复资产应用授权路由权限问题

* feat: home页放到user里,调整文件位置

* perf: 修复 view change routers (#1326)

Co-authored-by: ibuler <ibuler@qq.com>

* fix: 修复搜集用户 改密计划 账号备份路由

* feat: 终端管理、存储配置文件路径修改,放到系统设置中显示

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: feng626 <1304903146@qq.com>
Co-authored-by: “怀磊” <2280131253@qq.com>
Co-authored-by: fit2bot <68588906+fit2bot@users.noreply.github.com>
This commit is contained in:
Jiangjie.Bai
2022-02-21 16:24:43 +08:00
committed by GitHub
parent 172f970a0b
commit 96157bb18d
39 changed files with 221 additions and 211 deletions

View File

@@ -3,6 +3,7 @@ import router from './router'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { startup } from '@/utils/startup'
import store from '@/store'
NProgress.configure({
showSpinner: false
@@ -20,8 +21,24 @@ router.beforeEach(async(to, from, next) => {
}
})
router.afterEach(() => {
function generateViewRoutesIfChange({ to, from }) {
const fromView = from?.path.split('/')[1]
const toView = to?.path.split('/')[1]
if (fromView !== toView) {
return store.dispatch('permission/generateViewRoutes', { to: to, from: from })
}
}
function setPageTitle() {
const currentRoute = router.currentRoute
const loginTitle = store.getters.publicSettings['LOGIN_TITLE']
document.title = currentRoute.meta.title + ' - ' + loginTitle
}
router.afterEach(async(to, from) => {
// finish progress bar
await setPageTitle()
NProgress.done()
await generateViewRoutesIfChange({ to, from })
})

View File

@@ -425,8 +425,9 @@
"isValid": "有效",
"nav": {
"APIKey": "API Key",
"AdminPage": "管理视图",
"AuditPage": "审计视图",
"Workspace": "工作台",
"Console": "控制台",
"Audits": "审计台",
"HomePage": "首页",
"QuickAccess": "快速访问",
"SwitchPage": "切换视图",
@@ -654,6 +655,7 @@
},
"route": {
"": "",
"WorkBench": "工作台",
"Role": "角色",
"RoleDetail": "角色详情",
"RoleList": "角色列表",

View File

@@ -70,17 +70,12 @@ export default {
},
methods: {
handleClick(val) {
const fromRoute = this.$route
switch (val) {
case 'profile':
this.$router.push('/users/profile', () => {
store.dispatch('permission/generateViewRoutes', { to: this.$route, from: fromRoute })
})
this.$router.push('/users/profile')
break
case 'settings':
this.$router.push('/settings', () => {
store.dispatch('permission/generateViewRoutes', { to: this.$route, from: fromRoute })
})
this.$router.push('/settings')
break
case 'adminPage':
if (this.hasCurrentOrgAdminPagePerm) {

View File

@@ -10,7 +10,6 @@
<script>
import { getTicketOpenCount } from '@/api/ticket'
import { mapGetters } from 'vuex'
import store from '@/store'
export default {
name: 'WebTerminal',
@@ -35,10 +34,7 @@ export default {
},
goToTickets() {
// this.$router.push({ name: 'TicketList' })
const route = this.$route
this.$router.push('/tickets', () => {
store.dispatch('permission/generateViewRoutes', { to: this.$route, from: route })
})
this.$router.push('/tickets')
}
}
}

View File

@@ -27,7 +27,6 @@
</template>
<script>
import store from '@/store'
import { mapGetters } from 'vuex'
export default {
@@ -66,10 +65,7 @@ export default {
methods: {
handleSelectView(key, keyPath) {
const routeName = this.viewsMapper[key] || '/'
const fromRoute = this.$route
this.$router.push(routeName, () => {
store.dispatch('permission/generateViewRoutes', { to: this.$route, from: fromRoute })
})
this.$router.push(routeName)
}
}
}

View File

@@ -11,7 +11,7 @@
<WebTerminal />
</el-tooltip>
</li>
<li class="header-item">
<li class="header-item header-hover">
<Tickets />
</li>
<li class="header-item">
@@ -116,6 +116,12 @@ export default {
vertical-align: middle;
}
.header-hover {
&:hover {
background-color: #e6e6e6;
}
}
.header-icon {
&:hover {
background-color: #e6e6e6;

View File

@@ -1,116 +0,0 @@
import i18n from '@/i18n/i18n'
import empty from '@/layout/empty'
import { BASE_URL } from '@/utils/common'
// Todo: 放到系统设置中
export default [
{
path: 'sessions',
component: empty,
redirect: '',
meta: { title: i18n.t('route.Sessions'), permissions: [] },
children: [
{
path: '',
name: 'SessionList',
component: () => import('@/views/sessions/SessionList/index'),
meta: { title: i18n.t('route.Sessions'), permissions: [] }
},
{
path: ':id',
name: 'SessionDetail',
component: () => import('@/views/sessions/SessionDetail/index'),
meta: { title: i18n.t('route.SessionDetail') }
}
]
},
{
path: 'commands',
name: 'CommandList',
component: () => import('@/views/sessions/CommandList'),
meta: { title: i18n.t('route.Commands'), permissions: [] }
},
{
path: `${BASE_URL}/luna/?_=${Date.now()}`,
name: 'WebTerminal',
// component: () => window.open(`/luna/?_=${Date.now()}`),
meta: { title: i18n.t('route.WebTerminal') }
// hidden: true
},
{
path: `${BASE_URL}/koko/elfinder/sftp/?`,
name: 'FileManager',
// component: () => window.open(`/koko/elfinder/sftp/?`),
meta: { title: i18n.t('route.FileManager') }
},
{
path: 'terminal',
component: empty,
redirect: '',
meta: { title: i18n.t('route.Terminal'), permissions: [] },
children: [
{
path: '',
name: 'TerminalList',
component: () => import('@/views/sessions/TerminalList'),
meta: { title: i18n.t('route.Terminal') }
},
{
path: ':id',
name: 'TerminalDetail',
component: () => import('@/views/sessions/TerminalDetail'),
meta: {
title: i18n.t('route.Terminal'), hidden: true
}
},
{
path: ':id/update',
name: 'TerminalUpdate',
component: () => import('@/views/sessions/TerminalUpdate'),
meta: {
title: i18n.t('route.Terminal'), hidden: true
}
}
]
},
{
path: 'storages',
component: empty,
meta: {
redirect: '',
hidden: true,
children: [
{
path: '',
name: 'Storage',
component: () => import('@/views/sessions/Storage/index'),
meta: { activeMenu: '/terminal/terminal' }
},
{
path: 'replay-storage/create',
name: 'CreateReplayStorage',
component: () => import('@/views/sessions/ReplayStorageCreateUpdate'),
meta: { title: i18n.t('route.CreateReplayStorage') }
},
{
path: 'replay-storage/:id/update',
name: 'ReplayStorageUpdate',
component: () => import('@/views/sessions/ReplayStorageCreateUpdate'),
meta: { title: i18n.t('route.ReplayStorageUpdate') }
},
{
path: 'command-storage/create',
name: 'CreateCommandStorage',
component: () => import('@/views/sessions/CommandStorageCreateUpdate'),
meta: { title: i18n.t('route.CreateCommandStorage') }
},
{
path: 'command-storage/:id/update',
name: 'CommandStorageUpdate',
component: () => import('@/views/sessions/CommandStorageCreateUpdate'),
meta: { title: i18n.t('route.CommandStorageUpdate') }
}
]
}
}
]

View File

@@ -7,11 +7,11 @@ import empty from '@/layout/empty'
export default {
path: '/audit/',
name: 'AuditView',
name: 'Audit',
component: Layout,
redirect: '/audit/dashboard',
meta: {
title: i18n.t('common.nav.AuditPage'),
title: i18n.t('common.nav.Audits'),
icon: 'el-icon-s-claim',
showNavSwitcher: true,
permissions: ['rbac.view_auditview'],

View File

@@ -51,7 +51,8 @@ export default [
component: empty,
redirect: '',
meta: {
title: i18n.t('xpack.GatherUser.GatherUserList')
title: i18n.t('xpack.GatherUser.GatherUserList'),
app: 'assets'
},
children: [
{
@@ -116,7 +117,10 @@ export default [
path: 'change-auth-plan',
component: empty,
redirect: '',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan') },
meta: {
title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'),
app: 'xpack'
},
children: [
{
path: '',
@@ -232,7 +236,11 @@ export default [
path: 'backup',
component: empty,
redirect: '',
meta: { title: i18n.t('xpack.AccountBackupPlan.AccountBackupPlan') },
meta: {
title: i18n.t('xpack.AccountBackupPlan.AccountBackupPlan'),
app: 'assets',
resource: 'accountbackupplan'
},
children: [
{
path: '',

View File

@@ -198,7 +198,7 @@ export default [
name: 'CommandFilterRulesCreate',
meta: {
title: i18n.t('route.CommandFilterRulesCreate'),
activeMenu: '/admin/assets/cmd-filters'
activeMenu: '/console/assets/cmd-filters'
}
},
{
@@ -207,7 +207,7 @@ export default [
name: 'CommandFilterRulesUpdate',
meta: {
title: i18n.t('route.CommandFilterRulesUpdate'),
activeMenu: '/admin/assets/cmd-filters'
activeMenu: '/console/assets/cmd-filters'
}
}
]

View File

@@ -12,21 +12,21 @@ import AccountRoutes from './accounts'
import XPackRoutes from './xpack'
export default {
path: '/admin',
path: '/console',
component: Layout,
name: 'AdminView',
redirect: '/admin/dashboard',
name: 'Console',
redirect: '/console/dashboard',
meta: {
title: i18n.t('common.nav.AdminPage'),
title: i18n.t('common.nav.Console'),
icon: 'el-icon-s-tools',
view: 'admin',
view: 'console',
type: 'view',
showNavSwitcher: true,
permissions: ['rbac.view_adminview']
},
children: [
{
path: '/admin/dashboard',
path: '/console/dashboard',
component: () => import('@/views/dashboard/index'),
name: 'AdminDashboard',
meta: {
@@ -36,7 +36,7 @@ export default {
}
},
{
path: '/admin/users',
path: '/console/users',
component: empty,
name: 'Users',
meta: {
@@ -46,7 +46,7 @@ export default {
children: UsersRoute
},
{
path: '/admin/assets',
path: '/console/assets',
component: empty,
name: 'Assets',
meta: {
@@ -56,7 +56,7 @@ export default {
children: AssetsRoute
},
{
path: '/admin/applications',
path: '/console/applications',
component: empty,
name: 'applications',
meta: {
@@ -66,7 +66,7 @@ export default {
children: ApplicationsRoute
},
{
path: '/admin/accounts',
path: '/console/accounts',
component: empty,
name: 'Accounts',
meta: {
@@ -77,7 +77,7 @@ export default {
children: AccountRoutes
},
{
path: '/admin/perms',
path: '/console/perms',
component: empty,
name: 'Perms',
meta: {
@@ -87,7 +87,7 @@ export default {
children: PermsRoute
},
{
path: '/admin/acls',
path: '/console/acls',
component: empty,
name: 'Acl',
meta: {
@@ -98,7 +98,7 @@ export default {
children: AclRoutes
},
{
path: '/admin/ops',
path: '/console/ops',
component: empty,
name: 'JobCenter',
meta: {
@@ -108,7 +108,7 @@ export default {
children: OpsRoutes
},
{
path: '/admin/xpack',
path: '/console/xpack',
component: empty,
redirect: '/applications/remote-apps/',
name: 'Xpack',

View File

@@ -28,14 +28,14 @@ export default [
component: () => import('@/views/ops/TaskDetail/AdhocDetail'),
name: 'AdhocDetail',
hidden: true,
meta: { title: i18n.t('route.TaskDetail'), activeMenu: '/admin/ops/tasks' }
meta: { title: i18n.t('route.TaskDetail'), activeMenu: '/console/ops/tasks' }
},
{
path: 'executions/:id',
component: () => import('@/views/ops/TaskDetail/HistoryExecutionDetail'),
name: 'HistoryExecutionDetail',
hidden: true,
meta: { title: i18n.t('route.TaskDetail'), activeMenu: '/admin/ops/tasks' }
meta: { title: i18n.t('route.TaskDetail'), activeMenu: '/console/ops/tasks' }
},
{
path: 'command-executions/create',

View File

@@ -7,7 +7,7 @@ export default [
component: empty,
meta: {
title: i18n.t('route.AssetPermission'),
permissions: ['perms.view_assetpermission']
resource: 'assetpermission'
},
children: [
{
@@ -44,7 +44,8 @@ export default [
component: empty,
meta: {
title: i18n.t('route.ApplicationPermission'),
permissions: ['perms.view_applicationpermission']
permissions: ['perms.view_applicationpermission'],
resource: 'applicationpermission'
},
redirect: '',
children: [

View File

@@ -0,0 +1,46 @@
import i18n from '@/i18n/i18n'
import empty from '@/layout/empty'
import { BASE_URL } from '@/utils/common'
// Todo: 放到系统设置中
export default [
{
path: 'sessions',
component: empty,
redirect: '',
meta: { title: i18n.t('route.Sessions'), permissions: [] },
children: [
{
path: '',
name: 'SessionList',
component: () => import('@/views/sessions/SessionList/index'),
meta: { title: i18n.t('route.Sessions'), permissions: [] }
},
{
path: ':id',
name: 'SessionDetail',
component: () => import('@/views/sessions/SessionDetail/index'),
meta: { title: i18n.t('route.SessionDetail') }
}
]
},
{
path: 'commands',
name: 'CommandList',
component: () => import('@/views/sessions/CommandList'),
meta: { title: i18n.t('route.Commands'), permissions: [] }
},
{
path: `${BASE_URL}/luna/?_=${Date.now()}`,
name: 'WebTerminal',
// component: () => window.open(`/luna/?_=${Date.now()}`),
meta: { title: i18n.t('route.WebTerminal') }
// hidden: true
},
{
path: `${BASE_URL}/koko/elfinder/sftp/?`,
name: 'FileManager',
// component: () => window.open(`/koko/elfinder/sftp/?`),
meta: { title: i18n.t('route.FileManager') }
}
]

View File

@@ -1,6 +1,5 @@
import Vue from 'vue'
import Router from 'vue-router'
import i18n from '@/i18n/i18n'
Vue.use(Router)
@@ -45,8 +44,8 @@ export const constantRoutes = [
* the routes that need to be dynamically loaded based on user roles
*/
// 权限路由
import userViewRoutes from './user'
import adminViewRoutes from './admin'
import workspaceViewRoutes from './workspace'
import consoleViewRoutes from './console'
import auditViewRoutes from './audit'
import ticketsRoutes from './tickets'
import settingsRoutes from './settings'
@@ -57,30 +56,16 @@ import profileRoutes from './profile'
* the routes that need to be dynamically loaded based on admin roles
*/
export const allRoutes = [
// {
// path: '',
// redirect: '/admin/',
// meta: {
// permissions: []
// }
// },
{
path: '',
name: 'Home',
redirect: '',
component: () => import('@/views/home'),
redirect: '/workspace/home',
meta: {
title: i18n.t('common.nav.HomePage'),
icon: 'el-icon-s-home',
view: 'home',
type: 'view',
showNavSwitcher: true,
permissions: []
}
},
adminViewRoutes,
consoleViewRoutes,
auditViewRoutes,
userViewRoutes,
workspaceViewRoutes,
ticketsRoutes,
settingsRoutes,
profileRoutes

View File

@@ -2,21 +2,21 @@ import Layout from '@/layout'
import i18n from '@/i18n/i18n'
export default {
path: '/users/profile',
redirect: '/users/profile-info',
path: '/profile',
redirect: '/profile/info',
component: Layout,
meta: {
title: i18n.t('route.UserProfile'),
icon: 'gear',
view: 'users',
view: 'profile',
type: 'view',
showNavSwitcher: false,
permissions: []
},
children: [
{
path: '/users/profile-info',
name: 'profileInfo',
path: '/profile/info',
name: 'ProfileInfo',
component: () => import('@/views/profile/UserProfile/ProfileInfo'),
meta: {
title: i18n.t('users.AccountInformation'),
@@ -25,7 +25,7 @@ export default {
}
},
{
path: '/users/profile-setting',
path: '/profile/setting',
name: 'profileSetting',
component: () => import('@/views/profile/UserProfile/index'),
meta: {

View File

@@ -82,11 +82,10 @@ export default {
{
path: '',
name: 'TerminalList',
component: () => import('@/views/settings/Terminal/index'),
component: () => import('@/views/settings/Terminal'),
meta: {
title: i18n.t('setting.Terminal'),
icon: 'terminal',
permissions: ['terminal.view_command'],
resource: 'terminal',
app: 'terminal'
}
@@ -96,6 +95,7 @@ export default {
name: 'TerminalDetail',
component: () => import('@/views/settings/Terminal/TerminalDetail'),
meta: {
title: i18n.t('route.Terminal'),
permissions: ['terminal.view_command']
},
hidden: true
@@ -105,6 +105,76 @@ export default {
name: 'TerminalUpdate',
component: () => import('@/views/settings/Terminal/TerminalUpdate'),
meta: {
title: i18n.t('route.Terminal'),
permissions: ['terminal.view_command']
},
hidden: true
}
]
},
{
path: '/settings/storages',
component: empty,
redirect: '',
meta: {
title: i18n.t('setting.storage'),
permissions: ['terminal.view_command'],
resource: 'terminal',
app: 'terminal'
},
hidden: true,
children: [
{
path: '',
name: 'Storage',
component: () => import('@/views/settings/Terminal/Storage/index'),
meta: {
title: i18n.t('setting.storage'),
activeMenu: '/settings/terminal',
permissions: ['terminal.view_command']
},
hidden: true
},
{
path: 'replay-storage/create',
name: 'CreateReplayStorage',
component: () => import('@/views/settings/Terminal/Storage/ReplayStorageCreateUpdate'),
meta: {
title: i18n.t('route.CreateReplayStorage'),
activeMenu: '/settings/terminal',
permissions: ['terminal.view_command']
},
hidden: true
},
{
path: 'replay-storage/:id/update',
name: 'ReplayStorageUpdate',
component: () => import('@/views/settings/Terminal/Storage/ReplayStorageCreateUpdate'),
meta: {
title: i18n.t('route.ReplayStorageUpdate'),
activeMenu: '/settings/terminal',
permissions: ['terminal.view_command']
},
hidden: true
},
{
path: 'command-storage/create',
name: 'CreateCommandStorage',
component: () => import('@/views/settings/Terminal/Storage/CommandStorageCreateUpdate'),
meta: {
title: i18n.t('route.CreateCommandStorage'),
activeMenu: '/settings/terminal',
permissions: ['terminal.view_command']
},
hidden: true
},
{
path: 'command-storage/:id/update',
name: 'CommandStorageUpdate',
component: () => import('@/views/settings/Terminal/Storage/CommandStorageCreateUpdate'),
meta: {
title: i18n.t('route.CommandStorageUpdate'),
activeMenu: '/settings/terminal',
permissions: ['terminal.view_command']
},
hidden: true

View File

@@ -4,22 +4,33 @@ import { BASE_URL } from '@/utils/common'
import empty from '@/layout/empty'
export default {
path: '/user/',
path: '/workspace/',
component: Layout,
name: 'UserView',
redirect: '/user/assets',
name: 'Workspace',
redirect: '/workspace/assets',
meta: {
title: i18n.t('common.nav.UserPage'),
title: i18n.t('common.nav.Workspace'),
type: 'view',
view: 'user',
view: 'workspace',
icon: 'el-icon-user-solid',
showNavSwitcher: true,
showOrganization: false,
permissions: ['rbac.view_userview']
},
children: [
// 404 page must be placed at the end !!!
{
path: '/user/assets',
path: '/workspace/home',
name: 'MyHome',
component: () => import('@/views/myhome'),
meta: {
icon: 'home',
title: i18n.t('route.WorkBench'),
permissions: []
}
},
{
path: '/workspace/assets',
name: 'MyAssets',
component: () => import('@/views/myassets'),
meta: {
@@ -29,7 +40,7 @@ export default {
}
},
{
path: '/user/apps',
path: '/workspace/apps',
name: 'Apps',
component: empty,
redirect: 'remoteapp',
@@ -71,7 +82,7 @@ export default {
]
},
{
path: '/user/ops',
path: '/workspace/ops',
component: empty,
meta: {
permissions: [],

View File

@@ -116,7 +116,6 @@ export async function generatePageRoutes({ to, from, next }) {
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', { to, from })
console.log('Add routes: ', accessRoutes)
// dynamically add accessible routes
router.addRoutes(accessRoutes)

View File

@@ -1,6 +1,5 @@
<template>
<div class="home">
<NavHeader />
<el-container class="container">
<el-main class="main">
<div class="content">
@@ -26,7 +25,6 @@
<script>
import store from '@/store'
import { NavHeader } from '@/layout/components'
import User from './components/User'
import Announcement from './components/Announcement'
import Ticket from './components/Ticket'
@@ -37,7 +35,6 @@ import Session from './components/Session'
export default {
name: 'Name',
components: {
NavHeader,
User,
Announcement,
Ticket,
@@ -70,11 +67,7 @@ export default {
</script>
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.home {
@include clearfix;
position: relative;
height: 100%;
width: 100%;

View File

@@ -9,7 +9,7 @@
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import { STORAGE_TYPE_META_MAP } from './const'
import { STORAGE_TYPE_META_MAP } from '../../../sessions/const'
import { UpdateToken } from '@/components/FormFields'
export default {

View File

@@ -1,6 +1,6 @@
<template>
<div>
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<Dialog
:visible.sync="dialogSettings.visible"
:destroy-on-close="true"
@@ -14,7 +14,8 @@
</template>
<script>
import { GenericListPage, GenericCreateUpdateForm } from '@/layout/components'
import ListTable from '@/components/ListTable'
import { GenericCreateUpdateForm } from '@/layout/components'
import Dialog from '@/components/Dialog'
import Select2 from '@/components/FormFields/Select2'
@@ -27,7 +28,7 @@ const numTotFixed = (row, type) => {
}
export default {
components: {
GenericListPage,
ListTable,
Dialog,
GenericCreateUpdateForm
},

View File

@@ -8,7 +8,7 @@
<script>
import TabPage from '@/layout/components/TabPage'
import Basic from './Terminal'
import Basic from './Base'
import TerminalList from './TerminalList'
export default {