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
70 changes: 70 additions & 0 deletions apps/application/tests/test_application_advanced_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from types import SimpleNamespace
from unittest.mock import patch

from django.test import TestCase

from application.views.application import ApplicationAPI
from application.views.application_api_key import ApplicationApiKeyEnable
from common.auth.constants.operate_constants import Operate
from common.auth.constants.permission_constants import PermissionConstants
from common.auth.struct.permission import Role
from common.exception.app_exception import AppUnauthorizedFailed


class ApplicationAdvancedPermissionTests(TestCase):
workspace_id = "workspace-a"
application_id = "00000000-0000-0000-0000-000000000001"

def kwargs(self):
return {"workspace_id": self.workspace_id, "application_id": self.application_id}

def request_with_permission(self, permission_constant):
permission = permission_constant.get_workspace_application_permission()(None, self.kwargs())
permissions = {permission.get_resource_permission_key(permission.resource_id): permission.bit()}
return SimpleNamespace(
auth=SimpleNamespace(roles=[Role("USER", self.workspace_id)], permissions=permissions),
user=SimpleNamespace(id=self.application_id, type="test"),
META={"REMOTE_ADDR": "127.0.0.1"},
path="/test",
data={"enable_api_key": True},
query_params={},
build_absolute_uri=lambda _: "http://localhost/",
)

def test_backend_api_access_uses_dedicated_permission(self):
request = self.request_with_permission(PermissionConstants.APPLICATION_OVERVIEW_BACKEND_API_ACCESS)
with (
patch("application.views.application_api_key.ApiKeyEnableSerializer") as serializer,
patch("application.views.application_api_key.get_application_operation_object", return_value={}),
):
serializer.return_value.edit.return_value = {}
ApplicationApiKeyEnable.put(ApplicationApiKeyEnable(), request, **self.kwargs())
serializer.assert_called_once()

def test_backend_api_access_rejects_legacy_api_key_permission(self):
request = self.request_with_permission(PermissionConstants.APPLICATION_OVERVIEW_API_KEY)
with self.assertRaises(AppUnauthorizedFailed):
ApplicationApiKeyEnable.put(ApplicationApiKeyEnable(), request, **self.kwargs())

def test_export_skills_uses_dedicated_permission(self):
request = self.request_with_permission(PermissionConstants.APPLICATION_EXPORT_SKILLS)
with (
patch("application.views.application.ApplicationOperateSerializer") as serializer,
patch("application.views.application.get_application_operation_object", return_value={}),
):
serializer.return_value.export_skills.return_value = {}
ApplicationAPI.ExportSkills.get(ApplicationAPI.ExportSkills(), request, **self.kwargs())
serializer.assert_called_once()

def test_export_skills_rejects_application_export_permission(self):
request = self.request_with_permission(PermissionConstants.APPLICATION_EXPORT)
with self.assertRaises(AppUnauthorizedFailed):
ApplicationAPI.ExportSkills.get(ApplicationAPI.ExportSkills(), request, **self.kwargs())

def test_mcp_permission_bits_exist_for_role_tree(self):
self.assertEqual(PermissionConstants.APPLICATION_MCP_CONFIG.value.operate, Operate.MCP_CONFIG)
self.assertEqual(PermissionConstants.RESOURCE_APPLICATION_MCP_CONFIG.value.operate, Operate.MCP_CONFIG)
self.assertEqual(
PermissionConstants.APPLICATION_OVERVIEW_BACKEND_API_ACCESS.value.operate,
Operate.BACKEND_API_ACCESS,
)
4 changes: 2 additions & 2 deletions apps/application/views/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ class ExportSkills(APIView):
tags=[_("Application")], # type: ignore
)
@has_permissions(
PermissionConstants.APPLICATION_EXPORT.get_workspace_application_permission(),
PermissionConstants.APPLICATION_EXPORT.get_workspace_permission_workspace_manage_role(),
PermissionConstants.APPLICATION_EXPORT_SKILLS.get_workspace_application_permission(),
PermissionConstants.APPLICATION_EXPORT_SKILLS.get_workspace_permission_workspace_manage_role(),
ViewPermission(
[RoleConstants.USER.get_workspace_role()],
[PermissionConstants.APPLICATION.get_workspace_application_permission()],
Expand Down
4 changes: 2 additions & 2 deletions apps/application/views/application_api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ class ApplicationApiKeyEnable(APIView):
get_operation_object=lambda r, k: get_application_operation_object(k.get("application_id")),
)
@has_permissions(
PermissionConstants.APPLICATION_OVERVIEW_API_KEY.get_workspace_application_permission(),
PermissionConstants.APPLICATION_OVERVIEW_API_KEY.get_workspace_permission_workspace_manage_role(),
PermissionConstants.APPLICATION_OVERVIEW_BACKEND_API_ACCESS.get_workspace_application_permission(),
PermissionConstants.APPLICATION_OVERVIEW_BACKEND_API_ACCESS.get_workspace_permission_workspace_manage_role(),
ViewPermission(
[RoleConstants.USER.get_workspace_role()],
[PermissionConstants.APPLICATION.get_workspace_application_permission()],
Expand Down
1 change: 1 addition & 0 deletions apps/common/auth/constants/operate_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Operate(Enum):
DISPLAY = ("READ+DISPLAY", _("Display Settings"))
API_KEY = ("READ+API_KEY", _("API KEY"))
PUBLIC_ACCESS = ("READ+PUBLIC_ACCESS", _("Public access link"))
BACKEND_API_ACCESS = ("READ+BACKEND_API_ACCESS", _("Backend API access"))
Q_WEIXIN = ("READ+Q_WEIXIN", _("Enterprise WeiXin"))
FEISHU = ("READ+FEISHU", _("Feishu"))
DD = ("READ+DD", _("Dingding"))
Expand Down
110 changes: 110 additions & 0 deletions apps/common/auth/constants/permission_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -1608,6 +1608,26 @@ class PermissionConstants(Enum):
),
)

APPLICATION_MCP_CONFIG = (
Permission(group=Group.APPLICATION, sub_group=Group.APPLICATION, operate=Operate.MCP_CONFIG, bit_index=39),
PermissionMeta(
role_list=[RoleConstants.WORKSPACE_MANAGE, RoleConstants.USER],
category=Category.WORKSPACE,
scope=[PermissionScopeConstants.WORKSPACE_RESOURCE, PermissionScopeConstants.WORKSPACE],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANAGE],
),
)

APPLICATION_EXPORT_SKILLS = (
Permission(group=Group.APPLICATION, sub_group=Group.APPLICATION, operate=Operate.EXPORT_SKILLS, bit_index=40),
PermissionMeta(
role_list=[RoleConstants.WORKSPACE_MANAGE, RoleConstants.USER],
category=Category.WORKSPACE,
scope=[PermissionScopeConstants.WORKSPACE_RESOURCE, PermissionScopeConstants.WORKSPACE],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANAGE],
),
)

APPLICATION_PUBLISH = (
Permission(group=Group.APPLICATION, sub_group=Group.APPLICATION, operate=Operate.PUBLISH, bit_index=7),
PermissionMeta(
Expand Down Expand Up @@ -1827,6 +1847,21 @@ class PermissionConstants(Enum):
),
)

APPLICATION_OVERVIEW_BACKEND_API_ACCESS = (
Permission(
group=Group.APPLICATION,
sub_group=Group.OVERVIEW,
operate=Operate.BACKEND_API_ACCESS,
bit_index=38,
),
PermissionMeta(
role_list=[RoleConstants.WORKSPACE_MANAGE, RoleConstants.USER],
category=Category.WORKSPACE,
scope=[PermissionScopeConstants.WORKSPACE_RESOURCE, PermissionScopeConstants.WORKSPACE],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANAGE],
),
)

# ==================== 应用接入 ====================
APPLICATION_ACCESS_READ = (
Permission(group=Group.APPLICATION, sub_group=Group.ACCESS, operate=Operate.READ, bit_index=29),
Expand Down Expand Up @@ -2446,6 +2481,36 @@ class PermissionConstants(Enum):
),
)

SHARED_KNOWLEDGE_MCP_CONFIG = (
Permission(
group=Group.SYSTEM_SHARED_KNOWLEDGE,
sub_group=Group.SYSTEM_SHARED_KNOWLEDGE,
operate=Operate.MCP_CONFIG,
bit_index=63,
),
PermissionMeta(
role_list=[RoleConstants.ADMIN],
category=Category.SHARED,
is_ee=is_ee,
scope=[PermissionScopeConstants.SYSTEM],
),
)

SHARED_KNOWLEDGE_EXPORT_SKILLS = (
Permission(
group=Group.SYSTEM_SHARED_KNOWLEDGE,
sub_group=Group.SYSTEM_SHARED_KNOWLEDGE,
operate=Operate.EXPORT_SKILLS,
bit_index=64,
),
PermissionMeta(
role_list=[RoleConstants.ADMIN],
category=Category.SHARED,
is_ee=is_ee,
scope=[PermissionScopeConstants.SYSTEM],
),
)

# 共享知识库工作流
SHARED_KNOWLEDGE_WORKFLOW_READ = (
Permission(
Expand Down Expand Up @@ -3370,6 +3435,36 @@ class PermissionConstants(Enum):
),
)

RESOURCE_APPLICATION_MCP_CONFIG = (
Permission(
group=Group.SYSTEM_RES_APPLICATION,
sub_group=Group.SYSTEM_RES_APPLICATION,
operate=Operate.MCP_CONFIG,
bit_index=30,
),
PermissionMeta(
role_list=[RoleConstants.ADMIN],
category=Category.RESOURCE,
is_ee=is_ee,
scope=[PermissionScopeConstants.SYSTEM],
),
)

RESOURCE_APPLICATION_EXPORT_SKILLS = (
Permission(
group=Group.SYSTEM_RES_APPLICATION,
sub_group=Group.SYSTEM_RES_APPLICATION,
operate=Operate.EXPORT_SKILLS,
bit_index=31,
),
PermissionMeta(
role_list=[RoleConstants.ADMIN],
category=Category.RESOURCE,
is_ee=is_ee,
scope=[PermissionScopeConstants.SYSTEM],
),
)

RESOURCE_APPLICATION_COPY = (
Permission(
group=Group.SYSTEM_RES_APPLICATION,
Expand Down Expand Up @@ -3596,6 +3691,21 @@ class PermissionConstants(Enum):
),
)

RESOURCE_APPLICATION_OVERVIEW_BACKEND_API_ACCESS = (
Permission(
group=Group.SYSTEM_RES_APPLICATION,
sub_group=Group.SYSTEM_OVERVIEW,
operate=Operate.BACKEND_API_ACCESS,
bit_index=29,
),
PermissionMeta(
role_list=[RoleConstants.ADMIN],
category=Category.RESOURCE,
is_ee=is_ee,
scope=[PermissionScopeConstants.SYSTEM],
),
)

# 资源管理 - 应用接入
RESOURCE_APPLICATION_ACCESS_READ = (
Permission(
Expand Down
2 changes: 1 addition & 1 deletion apps/locales/en_US/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -3978,7 +3978,7 @@ msgstr "Overview"
#: apps/common/auth/constants/group_constants.py:51
#: apps/common/auth/constants/group_constants.py:140
msgid "Application Access"
msgstr "Application Access"
msgstr "Distribution Channels"

#: apps/common/auth/constants/group_constants.py:52
#: apps/common/auth/constants/group_constants.py:141
Expand Down
34 changes: 27 additions & 7 deletions apps/locales/zh_CN/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -3950,7 +3950,7 @@ msgstr "问题"
#: apps/common/auth/constants/group_constants.py:116
#: apps/common/auth/constants/group_constants.py:136
msgid "Termbase"
msgstr "词库"
msgstr "自定义分词"

#: apps/common/auth/constants/group_constants.py:47
#: apps/common/auth/constants/group_constants.py:117
Expand All @@ -3966,7 +3966,7 @@ msgstr "概览"
#: apps/common/auth/constants/group_constants.py:51
#: apps/common/auth/constants/group_constants.py:140
msgid "Application Access"
msgstr "智能体接入"
msgstr "发布渠道"

#: apps/common/auth/constants/group_constants.py:52
#: apps/common/auth/constants/group_constants.py:141
Expand Down Expand Up @@ -3997,7 +3997,7 @@ msgstr "邮箱设置"

#: apps/common/auth/constants/group_constants.py:63
msgid "Login Auth"
msgstr "登录认证"
msgstr "系统用户认证"

#: apps/common/auth/constants/group_constants.py:64
#: apps/xpack/views/system_params.py:24 apps/xpack/views/system_params.py:40
Expand All @@ -4020,7 +4020,7 @@ msgstr "对话用户认证"

#: apps/common/auth/constants/group_constants.py:70
msgid "Portal Setting"
msgstr "门户设置"
msgstr "门户访问设置"

#: apps/common/auth/constants/group_constants.py:78
#: apps/common/auth/constants/group_constants.py:91
Expand Down Expand Up @@ -4101,12 +4101,32 @@ msgstr "访问限制"

#: apps/common/auth/constants/operate_constants.py:44
msgid "API KEY"
msgstr "API KEY"
msgstr "API Key"

#: apps/common/auth/constants/operate_constants.py:45
msgid "Public access link"
msgstr "公共访问链接"

#: apps/common/auth/constants/operate_constants.py:46
msgid "Backend API access"
msgstr "后端API访问"

#: apps/role_setting/constants/permission_display.py
msgid "Web access"
msgstr "Web 访问"

#: apps/role_setting/constants/permission_display.py
msgid "MCP configuration details"
msgstr "MCP配置详情"

#: apps/role_setting/constants/permission_display.py
msgid "View settings"
msgstr "查看设置"

#: apps/role_setting/constants/permission_display.py
msgid "Edit settings"
msgstr "编辑设置"

#: apps/common/auth/constants/operate_constants.py:46
msgid "Enterprise WeiXin"
msgstr "企业微信"
Expand Down Expand Up @@ -4202,11 +4222,11 @@ msgstr "设置角色"

#: apps/common/auth/constants/operate_constants.py:71
msgid "MCP service configuration"
msgstr "MCP 服务配置"
msgstr "MCP服务配置"

#: apps/common/auth/constants/operate_constants.py:72
msgid "Export skills"
msgstr "导出 skills"
msgstr "导出skills"

#: apps/common/auth/constants/operate_constants.py:73
msgid "Quota Setting"
Expand Down
Loading
Loading