feat: 修改路由过滤方式

This commit is contained in:
ibuler
2020-06-03 20:36:46 +08:00
parent b6ea773c14
commit 333cdfcb4c
6 changed files with 177 additions and 191 deletions

View File

@@ -5,27 +5,27 @@ export default [
path: 'remote-apps',
name: 'RemoteAppList',
component: () => import('@/views/applications/RemoteApp/RemoteAppList'),
meta: { title: i18n.t('route.RemoteApp') }
meta: { title: i18n.t('route.RemoteApp'), licenseRequired: true }
},
{
path: 'remote-apps/create',
name: 'RemoteAppCreate',
component: () => import('@/views/applications/RemoteApp/RemoteAppCreateUpdate'),
meta: { title: i18n.t('route.RemoteApp'), activeMenu: '/applications/remote-apps', action: 'create' },
meta: { title: i18n.t('route.RemoteApp'), activeMenu: '/applications/remote-apps', action: 'create', licenseRequired: true },
hidden: true
},
{
path: 'remote-apps/:id/update',
name: 'RemoteAppUpdate',
component: () => import('@/views/applications/RemoteApp/RemoteAppCreateUpdate'),
meta: { title: i18n.t('route.RemoteAppUpdate'), activeMenu: '/applications/remote-apps', action: 'update' },
meta: { title: i18n.t('route.RemoteAppUpdate'), activeMenu: '/applications/remote-apps', action: 'update', licenseRequired: true },
hidden: true
},
{
path: 'remote-apps/:id',
name: 'RemoteAppDetail',
component: () => import('@/views/applications/RemoteApp/RemoteAppDetail/index'),
meta: { title: i18n.t('route.RemoteAppDetail'), activeMenu: '/applications/remote-apps' },
meta: { title: i18n.t('route.RemoteAppDetail'), activeMenu: '/applications/remote-apps', licenseRequired: true },
hidden: true
},
{

View File

@@ -7,7 +7,7 @@ Vue.use(Router)
/* Layout */
import Layout from '@/layout'
const requireContext = require.context('@/views/', true, /router\.js$/)
const requireContext = require.context('@/views/xpack/', true, /router\.js$/)
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
@@ -47,17 +47,11 @@ export const constantRoutes = [
name: '404',
component: () => import('@/views/404'),
hidden: true
}
]
/**
* admin and user routes
* the routes that need to be dynamically loaded based on admin or user roles
*/
export const commonRoutes = {
userProfile: {
path: '/users/profile',
},
{
path: '/profile',
component: Layout,
hidden: true,
children: [
{
path: '',
@@ -67,14 +61,20 @@ export const commonRoutes = {
}
]
}
}
]
/**
* user routes
* the routes that need to be dynamically loaded based on user roles
*/
// 权限路由
import userPageRoutes from './userPage'
/**
* admin
* the routes that need to be dynamically loaded based on admin roles
*/
export const adminRoutes = [
Object.assign({}, commonRoutes.userProfile, { hidden: true }),
export const allRoleRoutes = [
{
path: '/',
component: Layout,
@@ -144,7 +144,10 @@ export const adminRoutes = [
path: '/tickets/',
component: Layout,
redirect: '/tickets/tickets/',
children: TicketsRoutes
children: TicketsRoutes,
meta: {
licenseRequired: true
}
},
{
path: '/audits/',
@@ -164,17 +167,12 @@ export const adminRoutes = [
path: 'settings',
name: 'Settings',
component: () => import('@/views/settings/index'),
meta: { title: i18n.t('route.Settings'), icon: 'gears' }
meta: { title: i18n.t('route.Settings'), icon: 'gears', roles: ['SuperAdmin'] }
}]
},
{ path: '*', redirect: '/404', hidden: true }
...userPageRoutes,
{ path: '*', redirect: '/404', hidden: true, meta: { roles: ['SuperAdmin', 'Admin', 'Auditor', 'User'] }}
]
/**
* user routes
* the routes that need to be dynamically loaded based on user roles
*/
// 权限路由
export { default as userRoutes } from './userPage'
const createRouter = () => new Router({
// mode: 'history', // require service support

View File

@@ -10,13 +10,21 @@ export default [
{
path: '/',
component: Layout,
redirect: '/assets',
meta: {
roles: ['User'],
title: i18n.t('route.MyAssets'),
icon: 'files-o'
},
children: [
{
path: 'assets',
path: '',
name: 'assets',
component: () => import('@/userviews/assets/index'),
meta: { title: i18n.t('route.MyAssets'), icon: 'files-o' }
meta: {
title: i18n.t('route.MyAssets'),
icon: 'files-o',
roles: ['User']
}
}
]
},
@@ -25,53 +33,61 @@ export default [
name: 'Apps',
component: Layout,
redirect: '/apps/remoteapp',
meta: { title: i18n.t('route.MyApps'), icon: 'th' },
meta: { title: i18n.t('route.MyApps'), icon: 'th', roles: ['User'] },
children: [
{
path: '/apps/remoteapp',
name: 'remoteapp',
component: () => import('@/userviews/apps/RemoteApp'),
meta: { title: i18n.t('route.RemoteApp') }
meta: { title: i18n.t('route.RemoteApp'), roles: ['User'] }
},
{
path: '/apps/database',
name: 'assets',
component: () => import('@/userviews/apps/DatabaseApp'),
meta: { title: i18n.t('route.DatabaseApp') }
meta: { title: i18n.t('route.DatabaseApp'), roles: ['User'] }
}
]
},
{
path: '/command-executions',
component: Layout,
meta: {
roles: ['User']
},
children: [
{
path: '',
name: 'CommandExecutions',
component: () => import('@/views/ops/CommandExecution'),
meta: { title: i18n.t('route.CommandExecutions'), icon: 'terminal' }
meta: { title: i18n.t('route.CommandExecutions'), icon: 'terminal', roles: ['User'] }
}
]
},
{
path: `external-luna`,
component: Layout,
meta: {
roles: ['User']
},
children: [
{
path: `${URL}/luna/`,
meta: { title: i18n.t('route.WebTerminal'), icon: 'window-maximize', activeMenu: '/assets' }
meta: { title: i18n.t('route.WebTerminal'), icon: 'window-maximize', activeMenu: '/assets', roles: ['User'] }
}
]
},
{
path: 'external-elfinder',
component: Layout,
meta: {
roles: ['User']
},
children: [
{
path: `${URL}/koko/elfinder/sftp/`,
meta: { title: i18n.t('route.WebFTP'), icon: 'file', activeMenu: '/assets' }
meta: { title: i18n.t('route.WebFTP'), icon: 'file', activeMenu: '/assets', roles: ['User'] }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
}
]

View File

@@ -1,20 +1,19 @@
import {
adminRoutes,
userRoutes,
allRoleRoutes,
constantRoutes
} from '@/router'
import _ from 'lodash'
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
let requireRoles = route.meta ? route.meta.roles : null
if (!requireRoles) {
requireRoles = ['Admin']
}
const has = roles.some(role => requireRoles.includes(role))
return has
}
/**
@@ -40,41 +39,6 @@ export function filterAsyncRoutes(routes, roles) {
return res
}
export function filterNoneXpackRoutes(routes) {
const accessedRoutes = []
routes.forEach(route => {
const tmp = {
...route
}
if (tmp.name !== 'Xpack' && tmp.name !== 'Tickets') {
if (tmp.name === 'applications' || tmp.name === 'Perms') {
tmp.children = _.remove(tmp.children, (n) => {
return !n.name.includes('RemoteApp')
})
console.log(tmp.children)
}
accessedRoutes.push(tmp)
}
})
return accessedRoutes
}
export function filterUserNoneXpackRoutes(routes) {
const accessedRoutes = []
routes.forEach(route => {
const tmp = {
...route
}
if (tmp.name === 'Apps') {
tmp.children = _.remove(tmp.children, (n) => {
return !n.name.includes('remoteapp')
})
}
accessedRoutes.push(tmp)
})
return accessedRoutes
}
const state = {
routes: [],
addRoutes: []
@@ -83,27 +47,15 @@ const state = {
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
state.routes = routes.concat(constantRoutes)
}
}
const actions = {
generateRoutes(store, roles) {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('Admin')) {
accessedRoutes = adminRoutes || []
if (!store.rootState.settings.publicSettings.XPACK_LICENSE_IS_VALID) {
accessedRoutes = filterNoneXpackRoutes(adminRoutes)
}
} else if (roles.includes('User')) {
accessedRoutes = userRoutes || []
// accessedRoutes = filterAsyncRoutes(userRoutes, roles)
if (!store.rootState.settings.publicSettings.XPACK_LICENSE_IS_VALID) {
accessedRoutes = filterUserNoneXpackRoutes(userRoutes)
}
}
store.commit('SET_ROUTES', accessedRoutes)
const accessedRoutes = filterAsyncRoutes(allRoleRoutes, roles)
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}

View File

@@ -53,15 +53,15 @@ export async function getUserRoleAndSetRoutes({ to, from, next }) {
// try get user profile
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
// 不能改名 current_org_roles, 里面返回的就是这个
let { current_org_roles } = await store.dispatch('users/getProfile')
const { current_org_roles } = await store.dispatch('users/getProfile')
// console.log('Current org role: ', current_org_roles)
current_org_roles = checkRoles(current_org_roles)
// console.log('Current org role: ', current_org_roles)
const cleanedRoles = cleanCurrentRole(current_org_roles)
console.log('Current org role: ', cleanedRoles)
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', current_org_roles)
// console.log('Access routes: ', accessRoutes)
const accessRoutes = await store.dispatch('permission/generateRoutes', cleanedRoles)
console.log('Access routes: ', accessRoutes)
// dynamically add accessible routes
router.addRoutes(accessRoutes)
@@ -80,7 +80,6 @@ export async function getUserRoleAndSetRoutes({ to, from, next }) {
export async function startup({ to, from, next }) {
if (initial) {
console.debug('Has initial')
return true
}
initial = true
@@ -93,19 +92,16 @@ export async function startup({ to, from, next }) {
return true
}
function checkRoles(val) {
function cleanCurrentRole(val) {
let currentRole = store.getters.currentRole
if (currentRole) {
if (val && !val.includes(currentRole)) {
// TODO 异常注入处理
currentRole = val[0]
store.dispatch('users/setCurrentRole', currentRole)
}
} else {
// 设置默认路由
if (!currentRole) {
currentRole = val[0]
store.dispatch('users/setCurrentRole', currentRole)
}
if (val && !val.includes(currentRole)) {
// TODO 异常注入处理
currentRole = val[0]
}
store.dispatch('users/setCurrentRole', currentRole)
return [currentRole]
}

View File

@@ -7,7 +7,7 @@ export default {
component: Layout,
redirect: '/applications/remote-apps/',
name: 'Xpack',
meta: { title: 'Xpack', icon: 'sitemap' },
meta: { title: 'Xpack', icon: 'sitemap', licenseRequired: true },
children: [
{
path: 'interface-setting',
@@ -23,91 +23,115 @@ export default {
// },
{
path: 'gathered-users',
component: () => import('@/views/xpack/GatheredUser/GatheredUserList'),
name: 'GatherUserList',
meta: { title: i18n.t('xpack.GatherUserList') }
},
{
path: 'gathered-users/tasks',
component: () => import('@/views/xpack/GatheredUser/TaskList'),
name: 'GatherUserTaskList',
meta: { title: i18n.t('xpack.GatherUserTaskList') },
hidden: true
},
{
path: 'gathered-users/tasks/create',
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
name: 'GatherUserTaskCreate',
meta: { title: i18n.t('xpack.GatherUserTaskCreate') },
hidden: true
},
{
path: 'gathered-users/tasks/update',
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
name: 'GatherUserTaskUpdate',
meta: { title: i18n.t('xpack.GatherUserTaskUpdate'), action: 'update' },
hidden: true
component: empty,
redirect: '',
meta: { title: i18n.t('xpack.GatherUserList') },
children: [
{
path: '',
component: () => import('@/views/xpack/GatheredUser/GatheredUserList'),
name: 'GatherUserList',
meta: { title: i18n.t('xpack.GatherUserList') }
},
{
path: 'gathered-users/tasks',
component: () => import('@/views/xpack/GatheredUser/TaskList'),
name: 'GatherUserTaskList',
meta: { title: i18n.t('xpack.GatherUserTaskList') },
hidden: true
},
{
path: 'gathered-users/tasks/create',
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
name: 'GatherUserTaskCreate',
meta: { title: i18n.t('xpack.GatherUserTaskCreate') },
hidden: true
},
{
path: 'gathered-users/tasks/update',
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
name: 'GatherUserTaskUpdate',
meta: { title: i18n.t('xpack.GatherUserTaskUpdate'), action: 'update' },
hidden: true
}
]
},
{
path: 'orgs',
component: () => import('@/views/xpack/Org/OrganizationList'),
component: empty,
name: 'OrganizationList',
meta: { title: i18n.t('xpack.OrganizationList') }
redirect: '',
meta: { title: i18n.t('xpack.OrganizationList'), roles: ['SuperAdmin'] },
children: [
{
path: '',
component: () => import('@/views/xpack/Org/OrganizationList'),
name: 'OrganizationList',
meta: { title: i18n.t('xpack.OrganizationList') }
},
{
path: 'orgs/create',
component: () => import('@/views/xpack/Org/OrganizationCreateUpdate'),
name: 'OrganizationCreate',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationCreate'), activeMenu: '/xpack/orgs', action: 'create' }
},
{
path: 'orgs/:id/update',
component: () => import('@/views/xpack/Org/OrganizationCreateUpdate'),
name: 'OrganizationUpdate',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationUpdate'), activeMenu: '/xpack/orgs', action: 'update' }
},
{
path: 'orgs/:id',
component: () => import('@/views/xpack/Org/OrganizationDetail/index'),
name: 'OrganizationDetail',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationDetail'), activeMenu: '/xpack/orgs' }
}
]
},
{
path: 'orgs/create',
component: () => import('@/views/xpack/Org/OrganizationCreateUpdate'),
name: 'OrganizationCreate',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationCreate'), activeMenu: '/xpack/orgs', action: 'create' }
},
{
path: 'orgs/:id/update',
component: () => import('@/views/xpack/Org/OrganizationCreateUpdate'),
name: 'OrganizationUpdate',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationUpdate'), activeMenu: '/xpack/orgs', action: 'update' }
},
{
path: 'orgs/:id',
component: () => import('@/views/xpack/Org/OrganizationDetail/index'),
name: 'OrganizationDetail',
hidden: true,
meta: { title: i18n.t('xpack.OrganizationDetail'), activeMenu: '/xpack/orgs' }
},
{
path: 'change-auth-plan/plan',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanList.vue'),
name: 'ChangeAuthPlanList',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/xpack/change-auth-plan/plan' }
},
{
path: 'change-auth-plan/plan/create',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
name: 'ChangeAuthPlanCreate',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanCreate'), activeMenu: '/xpack/change-auth-plan/plan', action: 'create' },
hidden: true
},
{
path: 'change-auth-plan/plan/:id/update',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
name: 'ChangeAuthPlanUpdate',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanUpdate'), activeMenu: '/xpack/change-auth-plan/plan', action: 'update' },
hidden: true
},
{
path: 'change-auth-plan/plan/:id',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanDetail/index.vue'),
name: 'ChangeAuthPlanDetail',
path: 'change-auth-plan',
component: empty,
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/xpack/change-auth-plan/plan' },
hidden: true
},
{
path: 'change-auth-plan/plan-execution/:id',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanDetail/ChangeAuthPlanExecution/ChangeAuthPlanExecutionDetail/index.vue'),
name: 'ChangeAuthPlanExecutionDetail',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ExecutionDetail'), activeMenu: '/xpack/change-auth-plan/plan' },
hidden: true
children: [
{
path: 'plan',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanList.vue'),
name: 'ChangeAuthPlanList',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/xpack/change-auth-plan/plan' }
},
{
path: 'plan/create',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
name: 'ChangeAuthPlanCreate',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanCreate'), activeMenu: '/xpack/change-auth-plan/plan', action: 'create' },
hidden: true
},
{
path: 'plan/:id/update',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
name: 'ChangeAuthPlanUpdate',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanUpdate'), activeMenu: '/xpack/change-auth-plan/plan', action: 'update' },
hidden: true
},
{
path: 'plan/:id',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanDetail/index.vue'),
name: 'ChangeAuthPlanDetail',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/xpack/change-auth-plan/plan' },
hidden: true
},
{
path: 'plan-execution/:id',
component: () => import('@/views/xpack/ChangeAuthPlan/ChangeAuthPlanDetail/ChangeAuthPlanExecution/ChangeAuthPlanExecutionDetail/index.vue'),
name: 'ChangeAuthPlanExecutionDetail',
meta: { title: i18n.t('xpack.ChangeAuthPlan.ExecutionDetail'), activeMenu: '/xpack/change-auth-plan/plan' },
hidden: true
}
]
},
{
path: '/cloud',