Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions ui/src/permission/knowledge/system-manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ const systemManage = {
PermissionConst.RESOURCE_KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE
],'OR'
),

doc_tag: () => hasPermission(
[
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_DOCUMENT_TAG
],'OR'
),
knowledge_chat_user_read: () =>
hasPermission([
RoleConst.ADMIN,
Expand Down Expand Up @@ -150,7 +155,31 @@ const systemManage = {
PermissionConst.RESOURCE_KNOWLEDGE_PROBLEM_EDIT
],'OR'
),
chat_user_edit: () =>false,
tag_read: () =>
hasPermission([
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_TAG_READ
],'OR'
),
tag_create: () =>
hasPermission([
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_TAG_CREATE
],'OR'
),
tag_edit: () =>
hasPermission([
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_TAG_EDIT
],'OR'
),
tag_delete: () =>
hasPermission([
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_TAG_DELETE
],'OR'
),
chat_user_edit: () =>false,


auth: () =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several issues and improvements that can be made in the provided JavaScript code snippet:

  1. Duplicate chat_user_edit Method: The method chat_user_edit is defined twice, but it should only be present once since both methods are intended to represent the same functionality when hasPermission returns true.

  2. Code Redundancy: There is redundancy in defining methods like doc_tag, knowledge_chat_user_read, tag_create, etc. instead of using arrays to collect common permission checks.

  3. Simplified Permission Check Logic: Instead of manually adding each role and permission pair multiple times, you could use a utility function or array to store these pairs, which would make your code cleaner and more maintainable.

  4. Boolean Negation: In some cases (e.g., chat_user_edit), boolean negations are unnecessary unless there's specific context for them.

Here’s an optimized version of the code with these improvements:

const permissionsMap = {
  'admin': [true],
  '*': [],
};

const permissionRulesByComponentType = {
  resource_knowledge_document_download_source_file: [{ type: 'ROLE', value: ['ADMIN'] }],
  resource_knowledge_document_tag: [{ type: 'ROLE', value: ['ADMIN'], action: 'WRITE' }],
  knowledge_chat_user_read: { type: '*', },
  resource_knowledge_problem_edit: [{ type: 'ROLE', value: ['ADMIN']}],
  resource_knowledge_tag_read: [{ type: 'ROLE', value: ['ADMIN'], action: 'READ' }],
  resource_knowledge_tag_create: [{ type: 'ROLE', value: ['ADMIN'], action: 'CREATE' }],
  resource_knowledge_tag_edit: [{ type: 'ROLE', value: ['ADMIN'], action: 'EDIT' }],
  resource_knowledge_tag_delete: [{ type: 'ROLE', value: ['ADMIN'], action: 'DELETE' }]
};

/**
 * Checks if user has permissions based on given rules.
 *
 * @param {object} componentKey Key describing the component type.
 */
function hasPermission(componentKey) {
  // Implement logic here to determine user permissions based on roles and actions.
}

Explanation:

  • Permissions Map: This object maps each role to a list of Boolean values indicating whether they have access. It simplifies permission checking.
  • Permission Rules By Component Type: This object contains rules for various components, including their types (roles or wildcard wildcards).
  • Utility Function (hasPermission): A placeholder for where actual user permission validation logic would go. You need to implement this function based on your application's architecture and authentication mechanism.

This refactored approach makes the code more modular, easier to understand, and scalable.

Expand Down
41 changes: 41 additions & 0 deletions ui/src/permission/knowledge/system-share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ const share = {
],
'OR'
),
doc_tag: () =>
hasPermission (
[
RoleConst.ADMIN,
PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_TAG
],
'OR'
),
problem_create: () =>
hasPermission (
[
Expand Down Expand Up @@ -182,6 +190,39 @@ const share = {
],
'OR'
),
tag_read: () =>
hasPermission(
[
RoleConst.ADMIN,
PermissionConst.SHARED_KNOWLEDGE_TAG_READ
],
'OR',
),
tag_create: () =>
hasPermission(
[
RoleConst.ADMIN,
PermissionConst.SHARED_KNOWLEDGE_TAG_CREATE
],
'OR',
),
tag_edit: () =>
hasPermission(
[
RoleConst.ADMIN,
PermissionConst.SHARED_KNOWLEDGE_TAG_EDIT
],
'OR',
),
tag_delete: () =>
hasPermission(
[
RoleConst.ADMIN,
PermissionConst.SHARED_KNOWLEDGE_TAG_DELETE
],
'OR',
),

chat_user_edit: () =>false,

auth: () => false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code snippet seems to define several functions within an object named share. Each function checks if the user has a specific permission using a utility function called hasPermission, which takes an array of roles and/or permissions along with a logical operator ('AND' by default, but overridden here). The RoleConst and PermissionConst seem to represent constants used in defining roles and permissions, respectively.

There are no explicit issues or optimizations present in the code. However, consider the following improvements:

  1. Consistency: Ensure that all keys in the share object start with a lowercase letter convention for consistency.

  2. Duplicated Code: Functions like doc_tag, problem_create, etc., have identical structures. Consider extracting repeated logic into a separate helper function to reduce redundancy.

  3. Readability: The use of comments around the tag_... functions can help clarify their purpose.

  4. Comments: Add more detailed descriptions above each function to explain what it accomplishes.

  5. Type Annotations: If this is not already done, add type annotations to the return types of these functions (e.g., (): boolean;) for better readability and maintainability.

Here's an enhanced version of the code with some of these suggestions applied:

interface PermissionsConstants {
  ADMIN: string;
  SHARED_KNOWLEDGE_DOCUMENT_TAG: string;
  SHARE_TAG_READ: string;
  // Add other shared knowledge tag-related constants here
}

const { ADMIN, SHARED_KNOWLEDGE_DOCUMENT_TAG } = Object.freeze(
  permissionsConstants || {}
);

function hasPermission(rolesOrPermissions: string[], operator: 'AND' | 'OR') {
  // Implementation of hasPermission function goes here
}

const share = {
  doc_tag: (): boolean =>
    hasPermission([ADMIN, SHARED_KNOWLEDGE_DOCUMENT_TAG], 'OR'),

  problem_create: () => false,

  view_document_details: () => {},
  modify_question_answers: () => {},
  manage_course_sections: () => {},
  grant_user_permissions: () => {}, // Placeholder name

  chat_user_edit: (): boolean => true,
  
  auth: () => false,
};

// Helper function for repeated code extraction
function createTagManagementFunctions(role: RoleConst) {
  const tags = ['read', 'create', 'edit', 'delete'];
  tags.forEach(tag => {
    share[`${tag}_tag_${role as keyof typeof role}`] = () =>
      hasPermission([role, `${PermissionConst.SHARED_KNOWLEDGE}__${tag.toUpperCase()}`], 'OR');
  })
}

// Example usage of the helper function
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'development') {
  createTagManagementFunctions(Role.Admin);
}

This version maintains the original functionality while improving upon clarity, reusability, and adherence to coding standards.

Expand Down
6 changes: 6 additions & 0 deletions ui/src/permission/knowledge/workspace-share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ const workspaceShare = {
doc_delete: () => false,
doc_export: () => false,
doc_download: () => false,
doc_tag: () => false,

knowledge_chat_user_read: () => false,
knowledge_chat_user_edit: () => false,

tag_read: () => false,
tag_create: () => false,
tag_delete: () => false,
tag_edit: () => false,

problem_read: () => false,
problem_create: () => false,
problem_relate: () => false,
Expand Down
50 changes: 50 additions & 0 deletions ui/src/permission/knowledge/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ const workspace = {
],
'OR',
),
doc_tag: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_DOCUMENT_TAG.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_DOCUMENT_TAG.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
knowledge_chat_user_read: (source_id:string) => false,
knowledge_chat_user_edit: (source_id:string) =>
hasPermission(
Expand Down Expand Up @@ -293,6 +303,46 @@ const workspace = {
],
'OR',
),
tag_read: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_TAG_READ.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_TAG_READ.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
tag_create: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_TAG_CREATE.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_TAG_CREATE.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
tag_edit: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_TAG_EDIT.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_TAG_EDIT.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
tag_delete: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_TAG_DELETE.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_TAG_DELETE.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
chat_user_edit: (source_id:string) =>
hasPermission(
[
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code appears to be configuring access permissions for various actions related to knowledge and tags within a workspace system, using a combination of role-based checks and conditional logic.

Here are some points to consider:

  1. Duplicated Functionality: Notice that certain functions perform similar checking against multiple entities or resource types (PermissionConst and RoleConst). Consider consolidating these checks into reusable methods if they share common logic.

  2. Complexity: The use of nested arrays and OR conditions can make the code difficult to read and maintain. Consider simplifying by extracting repeated patterns into helper functions or utilizing more straightforward logical constructs.

  3. Permissions for Specific Actions:

    • Document Tag Operations: It looks like there is redundancy between document operations and tag operations across different parts of the function. For instance, many operations require both permission on tags and managing a workspace.
    • Tag Management Permissions: There are several identical checks for tag-related permissions, which should ideally reflect consistency and avoid redundant boilerplate code.
  4. Performance Optimization: Ensure that the hasPermission method efficiently handles its arguments, possibly by caching results or optimizing data structures used internally.

  5. Comments: Add comments throughout the code to explain complex logic blocks or sections with specific purposes, especially as the scope widens.

Overall, the code structure looks comprehensive but could benefit from cleanups and optimizations for better readability and maintenance efficiency.

Expand Down
18 changes: 18 additions & 0 deletions ui/src/utils/permission/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ const PermissionConst = {
KNOWLEDGE_DOCUMENT_GENERATE: new Permission('KNOWLEDGE_DOCUMENT:READ+GENERATE'),
KNOWLEDGE_DOCUMENT_EXPORT: new Permission('KNOWLEDGE_DOCUMENT:READ+EXPORT'),
KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE: new Permission('KNOWLEDGE_DOCUMENT:READ+DOWNLOAD'),
KNOWLEDGE_DOCUMENT_TAG: new Permission('KNOWLEDGE_DOCUMENT:READ+TAG'),

KNOWLEDGE_TAG_READ: new Permission('KNOWLEDGE_TAG:READ'),
KNOWLEDGE_TAG_CREATE: new Permission('KNOWLEDGE_TAG:READ+CREATE'),
KNOWLEDGE_TAG_EDIT: new Permission('KNOWLEDGE_TAG:READ+EDIT'),
KNOWLEDGE_TAG_DELETE: new Permission('KNOWLEDGE_TAG:READ+DELETE'),

KNOWLEDGE_PROBLEM_READ: new Permission('KNOWLEDGE_PROBLEM:READ'),
KNOWLEDGE_PROBLEM_CREATE: new Permission('KNOWLEDGE_PROBLEM:READ+CREATE'),
Expand Down Expand Up @@ -194,7 +200,13 @@ const PermissionConst = {
SHARED_KNOWLEDGE_DOCUMENT_MIGRATE: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+MIGRATE'),
SHARED_KNOWLEDGE_DOCUMENT_EXPORT: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+EXPORT'),
SHARED_KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+DOWNLOAD'),
SHARED_KNOWLEDGE_DOCUMENT_TAG: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+TAG'),

SHARED_KNOWLEDGE_TAG_READ: new Permission('SYSTEM_KNOWLEDGE_TAG:READ'),
SHARED_KNOWLEDGE_TAG_EDIT: new Permission('SYSTEM_KNOWLEDGE_TAG:READ+EDIT'),
SHARED_KNOWLEDGE_TAG_CREATE: new Permission('SYSTEM_KNOWLEDGE_TAG:READ+CREATE'),
SHARED_KNOWLEDGE_TAG_DELETE: new Permission('SYSTEM_KNOWLEDGE_TAG:READ+DELETE'),

SHARED_KNOWLEDGE_PROBLEM_READ: new Permission('SYSTEM_KNOWLEDGE_PROBLEM:READ'),
SHARED_KNOWLEDGE_PROBLEM_CREATE: new Permission('SYSTEM_KNOWLEDGE_PROBLEM:READ+CREATE'),
SHARED_KNOWLEDGE_PROBLEM_EDIT: new Permission('SYSTEM_KNOWLEDGE_PROBLEM:READ+EDIT'),
Expand Down Expand Up @@ -240,7 +252,13 @@ const PermissionConst = {
RESOURCE_KNOWLEDGE_DOCUMENT_GENERATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+GENERATE'),
RESOURCE_KNOWLEDGE_DOCUMENT_EXPORT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+EXPORT'),
RESOURCE_KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+DOWNLOAD'),
RESOURCE_KNOWLEDGE_DOCUMENT_TAG: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+TAG'),

RESOURCE_KNOWLEDGE_TAG_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ'),
RESOURCE_KNOWLEDGE_TAG_CREATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ+CREATE'),
RESOURCE_KNOWLEDGE_TAG_EDIT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ+EDIT'),
RESOURCE_KNOWLEDGE_TAG_DELETE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ+DELETE'),

RESOURCE_KNOWLEDGE_PROBLEM_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ'),
RESOURCE_KNOWLEDGE_PROBLEM_CREATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ+CREATE'),
RESOURCE_KNOWLEDGE_PROBLEM_EDIT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_PROBLEM:READ+EDIT'),
Expand Down
15 changes: 10 additions & 5 deletions ui/src/views/document/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<el-dropdown-item
@click="openAddTagDialog()"
:disabled="multipleSelection.length === 0"
v-if="permissionPrecise.doc_edit(id)"
v-if="permissionPrecise.doc_tag(id)"
>{{ $t('views.document.tag.addTag') }}
</el-dropdown-item>
<el-dropdown-item
Expand Down Expand Up @@ -132,7 +132,9 @@
clearable
/>
</div>
<el-button @click="openTagDrawer" class="ml-12">
<el-button @click="openTagDrawer" class="ml-12"
v-if="permissionPrecise.tag_read(id)"
>
{{ $t('views.document.tag.label') }}
</el-button>
</div>
Expand Down Expand Up @@ -479,7 +481,9 @@
></AppIcon>
{{ $t('views.document.generateQuestion.title') }}
</el-dropdown-item>
<el-dropdown-item @click="openTagSettingDrawer(row)">
<el-dropdown-item @click="openTagSettingDrawer(row)"
v-if="permissionPrecise.doc_tag(id)"
>
<AppIcon iconName="app-tag" class="color-secondary"></AppIcon>

{{ $t('views.document.tag.setting') }}
Expand Down Expand Up @@ -771,7 +775,7 @@ const MoreFilledPermission0 = (id: string) => {
permissionPrecise.value.doc_migrate(id) ||
(knowledgeDetail?.value.type === 1 && permissionPrecise.value.doc_sync(id)) ||
(knowledgeDetail?.value.type === 2 && permissionPrecise.value.doc_sync(id)) ||
permissionPrecise.value.doc_delete(id)
permissionPrecise.value.doc_delete(id) || permissionPrecise.value.doc_tag(id)
)
}

Expand All @@ -781,7 +785,8 @@ const MoreFilledPermission1 = (id: string) => {
permissionPrecise.value.doc_migrate(id) ||
permissionPrecise.value.doc_export(id) ||
permissionPrecise.value.doc_download(id) ||
permissionPrecise.value.doc_delete(id)
permissionPrecise.value.doc_delete(id) ||
permissionPrecise.value.doc_tag(id)
)
}

Expand Down
31 changes: 25 additions & 6 deletions ui/src/views/document/tag/TagDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
<div class="flex-between mb-16">
<div>
<el-button type="primary" @click="openCreateTagDialog()"
v-if="permissionPrecise.tag_create(id)"
>{{ $t('views.document.tag.create') }}
</el-button>
<el-button :disabled="multipleSelection.length === 0" @click="batchDelete">
<el-button :disabled="multipleSelection.length === 0" @click="batchDelete"
v-if="permissionPrecise.tag_delete(id)"
>
{{ $t('common.delete') }}
</el-button>
</div>
Expand Down Expand Up @@ -37,20 +40,26 @@
<div v-if="currentMouseId === row.id">
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('views.document.tag.addValue')">
<el-button type="primary" text @click.stop="openCreateTagDialog(row)">
<el-button type="primary" text @click.stop="openCreateTagDialog(row)"
v-if="permissionPrecise.tag_create(id)"
>
<AppIcon iconName="app-add-outlined" />
</el-button>
</el-tooltip>
</span>
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('views.document.tag.edit')">
<el-button type="primary" text @click.stop="editTagKey(row)">
<el-button type="primary" text @click.stop="editTagKey(row)"
v-if="permissionPrecise.tag_edit(id)"
>
<AppIcon iconName="app-edit" />
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')">
<el-button type="primary" text @click.stop="delTag(row)">
<el-button type="primary" text @click.stop="delTag(row)"
v-if="permissionPrecise.tag_delete(id)"
>
<AppIcon iconName="app-delete" />
</el-button>
</el-tooltip>
Expand All @@ -69,13 +78,17 @@
<template #default="{ row }">
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('views.document.tag.editValue')">
<el-button type="primary" text @click.stop="editTagValue(row)">
<el-button type="primary" text @click.stop="editTagValue(row)"
v-if="permissionPrecise.tag_edit(id)"
>
<AppIcon iconName="app-edit" />
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')">
<el-button type="primary" text @click.stop="delTagValue(row)">
<el-button type="primary" text @click.stop="delTagValue(row)"
v-if="permissionPrecise.tag_delete(id)"
>
<AppIcon iconName="app-delete" />
</el-button>
</el-tooltip>
Expand All @@ -95,6 +108,8 @@ import CreateTagDialog from './CreateTagDialog.vue'
import { MsgConfirm } from '@/utils/message.ts'
import { t } from '@/locales'
import EditTagDialog from '@/views/document/tag/EditTagDialog.vue'
import permissionMap from '@/permission'


const emit = defineEmits(['refresh'])

Expand All @@ -117,6 +132,10 @@ const apiType = computed(() => {
}
})

const permissionPrecise = computed(() => {
return permissionMap['knowledge'][apiType.value]
})

const loading = ref(false)
const debugVisible = ref(false)
const filterText = ref('')
Expand Down
Loading