diff --git a/frontend/src/boot/permissions.ts b/frontend/src/boot/permissions.ts index 4d5050a..05aad49 100644 --- a/frontend/src/boot/permissions.ts +++ b/frontend/src/boot/permissions.ts @@ -13,22 +13,63 @@ export const MenuMapping = { userDomain: null, }; +export const Actions = { + user: { + show: 'user_list', + add: 'user_add', + edit: 'user_edit', + delete: 'user_delete', + }, + role: { + show: 'role_list', + }, + domain: { + show: 'domain_list', + add: 'domain_add', + edit: 'domain_edit', + delete: 'domain_delete', + grantUse: { + list: 'domain_grant_use_list', + edit: 'domain_grant_use_edit', + }, + grantManage: { + list: 'domain_grant_manage_list', + edit: 'domain_grant_manage_edit', + }, + }, +}; + const store = useAuthStore(); export default boot(({ app }) => { app.directive('permissions', { mounted(el: HTMLElement, binding: DirectiveBinding) { - const { value } = binding; - if (!value || store.isSuperAdmin) { - return; + if (!hasPermission(binding.value)) { + hideElement(el); } - if (!store.permissions[value]) { - if (el.parentNode) { - el.parentNode.removeChild(el); - } else { - el.style.display = 'none'; - } - } - }, + }, }); + + app.config.globalProperties.$hasPermission = hasPermission; }); + +function hasPermission(value: any) { + if (!value || store.isSuperAdmin) { + return true; + } + if (typeof value === 'string') { + return store.permissions[value]; + } else if (typeof value === 'object') { + return Object.values(value).some((permission: any) => store.permissions[permission]); + } else if (Array.isArray(value)) { + return value.some((permission) => store.permissions[permission]); + } +} + +function hideElement(el: HTMLElement) { + if (el.parentNode) { + el.parentNode.removeChild(el); + } else { + el.style.display = 'none'; + } +} \ No newline at end of file diff --git a/frontend/src/components/EssentialLink.vue b/frontend/src/components/EssentialLink.vue index 4d4be1b..1e473df 100644 --- a/frontend/src/components/EssentialLink.vue +++ b/frontend/src/components/EssentialLink.vue @@ -36,7 +36,7 @@ export interface EssentialLinkProps { isSeparator?: boolean; target?:string; disable?:boolean; - permission?: string + permission?: string|null; } withDefaults(defineProps(), { caption: '', diff --git a/frontend/src/components/ShareDomain/ShareDomainDialog.vue b/frontend/src/components/ShareDomain/ShareDomainDialog.vue index f47d2ca..32182d4 100644 --- a/frontend/src/components/ShareDomain/ShareDomainDialog.vue +++ b/frontend/src/components/ShareDomain/ShareDomainDialog.vue @@ -8,6 +8,7 @@ @@ -76,7 +77,6 @@ import { useAuthStore } from 'stores/useAuthStore'; import SharingUserList from 'components/ShareDomain/SharingUserList.vue'; import RoleLabel from 'components/ShareDomain/RoleLabel.vue'; import { Dialog } from 'quasar' -import { IResponse } from 'src/types/BaseTypes'; const authStore = useAuthStore(); @@ -89,6 +89,7 @@ interface Props { shareApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise; removeSharedApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise; getSharedApi: (domain: IDomainOwnerDisplay) => Promise; + actionPermissions: { 'list': string, 'edit': string }; } interface IUserDisplayWithShareRole extends IUserDisplay { diff --git a/frontend/src/components/ShareDomain/ShareManageDialog.vue b/frontend/src/components/ShareDomain/ShareManageDialog.vue index 594667b..e225095 100644 --- a/frontend/src/components/ShareDomain/ShareManageDialog.vue +++ b/frontend/src/components/ShareDomain/ShareManageDialog.vue @@ -8,6 +8,7 @@ :get-shared-api="getSharedApi" :is-action-disable="(row) => row.id === authStore.userId" :model-value="modelValue" + :action-permissions="Actions.domain.grantManage" @update:modelValue="updateModelValue" @close="close" /> @@ -19,6 +20,7 @@ import ShareDomainDialog from 'components/ShareDomain/ShareDomainDialog.vue'; import { IUserDisplay } from '../../types/UserTypes'; import { IDomainOwnerDisplay } from '../../types/DomainTypes'; import { api } from 'boot/axios'; +import { Actions } from 'boot/permissions'; import { useAuthStore } from 'src/stores/useAuthStore'; import { IResponse } from 'src/types/BaseTypes'; diff --git a/frontend/src/components/ShareDomain/ShareUsageDialog.vue b/frontend/src/components/ShareDomain/ShareUsageDialog.vue index 04132a5..2aa9a19 100644 --- a/frontend/src/components/ShareDomain/ShareUsageDialog.vue +++ b/frontend/src/components/ShareDomain/ShareUsageDialog.vue @@ -7,6 +7,7 @@ :remove-shared-api="removeSharedApi" :get-shared-api="getSharedApi" :model-value="modelValue" + :action-permissions="Actions.domain.grantUse" @update:modelValue="updateModelValue" @close="close" /> @@ -18,6 +19,7 @@ import ShareDomainDialog from 'components/ShareDomain/ShareDomainDialog.vue'; import { IUserDisplay } from '../../types/UserTypes'; import { IDomainOwnerDisplay } from '../../types/DomainTypes'; import { api } from 'boot/axios'; +import { Actions } from 'boot/permissions'; interface Props { modelValue: boolean; diff --git a/frontend/src/components/TableActionMenu.vue b/frontend/src/components/TableActionMenu.vue index 5d7a6ce..cc65ea9 100644 --- a/frontend/src/components/TableActionMenu.vue +++ b/frontend/src/components/TableActionMenu.vue @@ -1,9 +1,9 @@