This is an automated email from the ASF dual-hosted git repository.
nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-webui.git
The following commit(s) were added to refs/heads/main by this push:
new 24fdbfef [Bugfix] Fix permission management (#404)
24fdbfef is described below
commit 24fdbfefd8e992ccec6a8842a17a5819f7292a07
Author: yangyang zhong <[email protected]>
AuthorDate: Sun Jun 16 15:14:42 2024 +0800
[Bugfix] Fix permission management (#404)
---
paimon-web-ui/src/layouts/content/index.tsx | 14 +++++++++---
paimon-web-ui/src/layouts/content/use-data.ts | 7 ++++++
paimon-web-ui/src/router/routes.ts | 1 -
paimon-web-ui/src/store/config/index.ts | 6 ++---
paimon-web-ui/src/store/user/index.ts | 26 +++++++++++++++++++++-
paimon-web-ui/src/views/login/use-form.ts | 15 +++++++++++--
.../system/role/components/role-form/index.tsx | 1 -
.../system/user/components/user-form/index.tsx | 6 -----
8 files changed, 59 insertions(+), 17 deletions(-)
diff --git a/paimon-web-ui/src/layouts/content/index.tsx
b/paimon-web-ui/src/layouts/content/index.tsx
index 8e5650fd..b6755f45 100644
--- a/paimon-web-ui/src/layouts/content/index.tsx
+++ b/paimon-web-ui/src/layouts/content/index.tsx
@@ -22,16 +22,24 @@ import SideBar from './components/sidebar'
import { useData } from './use-data'
import { useConfigStore } from '@/store/config'
import { usePermissionStore } from '@/store/permission'
+import { useUserStore } from '@/store/user'
export default defineComponent({
name: 'ContentPage',
setup() {
const permissionStore = usePermissionStore()
const configStore = useConfigStore()
+ const userStore = useUserStore()
const { menuOptions, state } = useData()
+ const isAdmin = userStore.getAdmin
+ const userMenus = userStore.getMenus
+ const userDirectories = userStore.getDiresctoies
+ const showDirectories = ref(menuOptions.value?.filter(e => isAdmin ||
userDirectories.includes(e.menuName)))
const getSideOption = (state: any) => {
const activeNavKey = configStore.getCurrentNavActive
- state.sideMenuOptions = menuOptions.value.find((m: any) => m.key ===
activeNavKey)?.sideMenuOptions || []
+ state.sideMenuOptions = showDirectories.value.find((m: any) => m.key ===
activeNavKey)?.sideMenuOptions?.filter((e) => {
+ return isAdmin || userMenus?.includes(e.menuName)
+ }) || []
state.isShowSided = state.sideMenuOptions && state.sideMenuOptions.length
}
@@ -48,7 +56,7 @@ export default defineComponent({
return {
...toRefs(state),
- menuOptions,
+ showDirectories,
}
},
render() {
@@ -56,7 +64,7 @@ export default defineComponent({
<div class={styles.container}>
<n-layout style="height: 100%">
<n-layout-header style="height: 64px;" bordered>
- <NavBar headerMenuOptions={this.menuOptions}></NavBar>
+ <NavBar headerMenuOptions={this.showDirectories}></NavBar>
</n-layout-header>
<n-layout has-sider position="absolute" style="top: 64px">
{this.isShowSided
diff --git a/paimon-web-ui/src/layouts/content/use-data.ts
b/paimon-web-ui/src/layouts/content/use-data.ts
index 7579d1d4..b9586088 100644
--- a/paimon-web-ui/src/layouts/content/use-data.ts
+++ b/paimon-web-ui/src/layouts/content/use-data.ts
@@ -43,33 +43,40 @@ export function useData() {
{
label: () => renderLabel(t('layout.playground'), 'playground'),
key: 'playground',
+ menuName: 'playground',
icon: renderIcon(Code),
},
{
label: () => renderLabel(t('layout.metadata'), 'metadata'),
key: 'metadata',
+ menuName: 'metadata',
icon: renderIcon(Catalog),
},
{
label: () => renderLabel(t('layout.cdc_ingestion'), 'cdc_ingestion'),
key: 'cdc_ingestion',
+ menuName: 'cdc',
icon: renderIcon(FileSyncOutlined),
},
{
label: () => renderLabel(t('layout.system'), 'system'),
key: 'system',
+ menuName: 'system',
icon: renderIcon(SettingsOutline),
sideMenuOptions: [{
label: () => renderLabel(t('layout.user'), 'system'),
key: '/system/user',
+ menuName: 'user_manager',
icon: renderIcon(UserOutlined),
}, {
label: () => renderLabel(t('layout.role'), 'system'),
key: '/system/role',
+ menuName: 'role_manager',
icon: renderIcon(UserSwitchOutlined),
}, {
label: () => renderLabel(t('layout.cluster'), 'system'),
key: '/system/cluster',
+ menuName: 'menu_manager',
icon: renderIcon(ClusterOutlined),
}],
},
diff --git a/paimon-web-ui/src/router/routes.ts
b/paimon-web-ui/src/router/routes.ts
index cdfc8e3a..0ca12b93 100644
--- a/paimon-web-ui/src/router/routes.ts
+++ b/paimon-web-ui/src/router/routes.ts
@@ -29,7 +29,6 @@ const basePage: RouteRecordRaw = {
path: '/',
name: 'homepage',
meta: { title: 'Home' },
- redirect: { name: 'playground' },
component: () => import('@/layouts/content'),
children: [
playground_routes,
diff --git a/paimon-web-ui/src/store/config/index.ts
b/paimon-web-ui/src/store/config/index.ts
index 9e826c07..04f55913 100644
--- a/paimon-web-ui/src/store/config/index.ts
+++ b/paimon-web-ui/src/store/config/index.ts
@@ -20,7 +20,7 @@ import { LANGUAGES } from '@/locales'
export const useConfigStore = defineStore({
id: 'config',
- state: (): { theme: Theme, locale: LANGUAGES, navActive: NavBar, menuActive:
Menu } => ({
+ state: (): { theme: Theme, locale: LANGUAGES, navActive: NavBar | null,
menuActive: Menu } => ({
theme: 'light',
locale: LANGUAGES.ZH,
navActive: 'playground',
@@ -34,7 +34,7 @@ export const useConfigStore = defineStore({
getCurrentTheme(): Theme {
return this.theme
},
- getCurrentNavActive(): NavBar {
+ getCurrentNavActive(): NavBar | null {
return this.navActive
},
getCurrentMenuActive(): Menu {
@@ -48,7 +48,7 @@ export const useConfigStore = defineStore({
setCurrentTheme(theme: Theme): void {
this.theme = theme
},
- setCurrentNavActive(navActive: NavBar): void {
+ setCurrentNavActive(navActive: NavBar | null): void {
this.navActive = navActive
},
setCurrentMenuActive(menuActive: Menu): void {
diff --git a/paimon-web-ui/src/store/user/index.ts
b/paimon-web-ui/src/store/user/index.ts
index 59576e50..ec1f1646 100644
--- a/paimon-web-ui/src/store/user/index.ts
+++ b/paimon-web-ui/src/store/user/index.ts
@@ -18,13 +18,19 @@ under the License. */
export interface UserState {
username: string | null
nickname: string | null
+ directories: Array<string>
+ menus: Array<string>
+ admin: boolean
}
export const useUserStore = defineStore({
- id: 'config',
+ id: 'user',
state: (): UserState => ({
username: '',
nickname: '',
+ directories: [],
+ menus: [],
+ admin: false,
}),
persist: true,
getters: {
@@ -34,6 +40,15 @@ export const useUserStore = defineStore({
getNickname(): string | null {
return this.nickname
},
+ getMenus(): Array<string> | null {
+ return this.menus
+ },
+ getDiresctoies(): Array<string> {
+ return this.directories
+ },
+ getAdmin(): boolean | null {
+ return this.admin
+ },
},
actions: {
setUsername(username: string): void {
@@ -42,5 +57,14 @@ export const useUserStore = defineStore({
setNickname(nickname: string): void {
this.nickname = nickname
},
+ setAdmin(admin: boolean): void {
+ this.admin = admin
+ },
+ setMenus(menus: Array<string>): void {
+ this.menus = menus
+ },
+ setDirectories(directories: Array<string>) {
+ this.directories = directories
+ },
},
})
diff --git a/paimon-web-ui/src/views/login/use-form.ts
b/paimon-web-ui/src/views/login/use-form.ts
index 394437d3..9750a1a9 100644
--- a/paimon-web-ui/src/views/login/use-form.ts
+++ b/paimon-web-ui/src/views/login/use-form.ts
@@ -20,15 +20,18 @@ import type { Router } from 'vue-router'
import { onLogin } from '@/api'
import { useUserStore } from '@/store/user'
import type { ResponseOptions } from '@/api/types'
+import { useConfigStore } from '@/store/config'
export function useForm() {
const router: Router = useRouter()
const userStore = useUserStore()
+ const configStore = useConfigStore()
const state = reactive({
loginForm: ref(),
model: {
username: '',
password: '',
+
},
})
@@ -41,8 +44,16 @@ export function useForm() {
ldapLogin: false,
rememberMe: true,
}).then((res: ResponseOptions<any>) => {
- userStore.username = res.data.user.username
- userStore.nickname = res.data.user.nickname
+ userStore.setUsername(res.data.user.username)
+ userStore.setNickname(res.data.user.nickname)
+ configStore.setCurrentNavActive(null)
+ userStore.setAdmin(res.data.user.admin)
+ userStore.setMenus(res.data.sysMenuList?.filter((e: any) => e.type
=== 'C')?.map((e: any) => {
+ return e.menuName
+ }) || [])
+ userStore.setDirectories(res.data.sysMenuList?.filter((e: any) =>
e.type === 'M')?.map((e: any) => {
+ return e.menuName
+ }) || [])
})
router.push({ path: '/' })
}
diff --git a/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
b/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
index 2d5075c7..41eab85e 100644
--- a/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
+++ b/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
@@ -162,7 +162,6 @@ export default defineComponent({
key-field="id"
default-expand-all
block-line
- cascade
renderLabel={this.renderLabel}
onUpdate:checkedKeys={this.onUpdateMenuIds}
checkedKeys={this.formValue.menuIds}
diff --git a/paimon-web-ui/src/views/system/user/components/user-form/index.tsx
b/paimon-web-ui/src/views/system/user/components/user-form/index.tsx
index 80864d02..5336b0a0 100644
--- a/paimon-web-ui/src/views/system/user/components/user-form/index.tsx
+++ b/paimon-web-ui/src/views/system/user/components/user-form/index.tsx
@@ -15,8 +15,6 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
-import type { FormItemRule } from 'naive-ui'
-
import type { UserDTO } from '@/api/models/user/types'
import { listRoles } from '@/api/models/role'
@@ -72,11 +70,7 @@ export default defineComponent({
message: 'roleIds required',
},
mobile: {
- required: true,
trigger: ['input'],
- validator: (rule: FormItemRule, value: string) => {
- return /^1+[3,8]+\d{9}$/.test(value)
- },
},
}