Skip to content

Commit 6866ff0

Browse files
authored
fix: Tools cannot be called in the workflow (#3516)
1 parent dc51cc1 commit 6866ff0

File tree

6 files changed

+68
-35
lines changed

6 files changed

+68
-35
lines changed

apps/application/flow/i_step_node.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class FlowParamsSerializer(serializers.Serializer):
144144

145145
workspace_id = serializers.CharField(required=True, label="工作空间id")
146146

147+
application_id = serializers.CharField(required=True, label="应用id")
148+
147149
re_chat = serializers.BooleanField(required=True, label="换个答案")
148150

149151
debug = serializers.BooleanField(required=True, label="是否debug")

apps/application/flow/step_node/tool_lib_node/i_tool_lib_node.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ class InputField(serializers.Serializer):
2323

2424

2525
class FunctionLibNodeParamsSerializer(serializers.Serializer):
26-
tool_id = serializers.UUIDField(required=True, label=_('Library ID'))
26+
tool_lib_id = serializers.UUIDField(required=True, label=_('Library ID'))
2727
input_field_list = InputField(required=True, many=True)
2828
is_result = serializers.BooleanField(required=False,
2929
label=_('Whether to return content'))
3030

3131
def is_valid(self, *, raise_exception=False):
3232
super().is_valid(raise_exception=True)
33-
f_lib = QuerySet(Tool).filter(id=self.data.get('tool_id')).first()
33+
f_lib = QuerySet(Tool).filter(id=self.data.get('tool_lib_id')).first()
3434
if f_lib is None:
3535
raise Exception(_('The function has been deleted'))
3636

@@ -44,5 +44,5 @@ def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
4444
def _run(self):
4545
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
4646

47-
def execute(self, function_lib_id, input_field_list, **kwargs) -> NodeResult:
47+
def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult:
4848
pass

apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515

1616
from application.flow.i_step_node import NodeResult
1717
from application.flow.step_node.tool_lib_node.i_tool_lib_node import IToolLibNode
18+
from common.database_model_manage.database_model_manage import DatabaseModelManage
1819
from common.exception.app_exception import AppApiException
1920
from common.utils.function_code import FunctionExecutor
2021
from common.utils.rsa_util import rsa_long_decrypt
2122
from maxkb.const import CONFIG
23+
from system_manage.models import AuthTargetType
24+
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
2225
from tools.models import Tool
2326

2427
function_executor = FunctionExecutor(CONFIG.get('SANDBOX'))
@@ -101,13 +104,14 @@ def convert_value(name: str, value, _type, is_required, source, node):
101104
value=value))
102105

103106

104-
def valid_function(function_lib, user_id):
105-
if function_lib is None:
106-
raise Exception(_('Function does not exist'))
107-
if function_lib.permission_type == 'PRIVATE' and str(function_lib.user_id) != str(user_id):
108-
raise Exception(_('No permission to use this function {name}').format(name=function_lib.name))
109-
if not function_lib.is_active:
110-
raise Exception(_('Function {name} is unavailable').format(name=function_lib.name))
107+
def valid_function(tool_lib, workspace_id):
108+
if tool_lib is None:
109+
raise Exception(_('Tool does not exist'))
110+
get_authorized_tool = DatabaseModelManage.get_model("get_authorized_tool")
111+
if tool_lib and tool_lib.workspace_id != workspace_id and get_authorized_tool is not None:
112+
tool_lib = get_authorized_tool(QuerySet(Tool).filter(id=tool_lib.id), workspace_id).first()
113+
if tool_lib is None:
114+
raise Exception(_("Tool does not exist"))
111115

112116

113117
class BaseToolLibNodeNode(IToolLibNode):
@@ -116,25 +120,26 @@ def save_context(self, details, workflow_manage):
116120
if self.node_params.get('is_result'):
117121
self.answer_text = str(details.get('result'))
118122

119-
def execute(self, function_lib_id, input_field_list, **kwargs) -> NodeResult:
120-
function_lib = QuerySet(Tool).filter(id=function_lib_id).first()
121-
valid_function(function_lib, self.flow_params_serializer.data.get('user_id'))
123+
def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult:
124+
workspace_id = self.workflow_manage.get_body().get('workspace_id')
125+
tool_lib = QuerySet(Tool).filter(id=tool_lib_id).first()
126+
valid_function(tool_lib, workspace_id)
122127
params = {field.get('name'): convert_value(field.get('name'), field.get('value'), field.get('type'),
123128
field.get('is_required'),
124129
field.get('source'), self)
125130
for field in
126131
[{'value': get_field_value(input_field_list, field.get('name'), field.get('is_required'),
127132
), **field}
128133
for field in
129-
function_lib.input_field_list]}
134+
tool_lib.input_field_list]}
130135

131136
self.context['params'] = params
132137
# 合并初始化参数
133-
if function_lib.init_params is not None:
134-
all_params = json.loads(rsa_long_decrypt(function_lib.init_params)) | params
138+
if tool_lib.init_params is not None:
139+
all_params = json.loads(rsa_long_decrypt(tool_lib.init_params)) | params
135140
else:
136141
all_params = params
137-
result = function_executor.exec_code(function_lib.code, all_params)
142+
result = function_executor.exec_code(tool_lib.code, all_params)
138143
return NodeResult({'result': result}, {}, _write_context=write_context)
139144

140145
def get_details(self, index: int, **kwargs):

apps/chat/serializers/chat.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ def chat_work_flow(self, chat_info: ChatInfo, instance: dict, base_to_response):
237237
'chat_user_type': chat_user_type,
238238
'workspace_id': workspace_id,
239239
'debug': debug,
240-
'chat_user': chat_info.get_chat_user()},
240+
'chat_user': chat_info.get_chat_user(),
241+
'application_id': chat_info.application_id},
241242
WorkFlowPostHandler(chat_info),
242243
base_to_response, form_data, image_list, document_list, audio_list,
243244
other_list,

apps/system_manage/serializers/user_resource_permission.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,33 @@ def get_queryset(self):
103103
auth_target_type=self.data.get('auth_target_type'))
104104
}
105105

106+
def is_auth(self, resource_id: str):
107+
self.is_valid(raise_exception=True)
108+
auth_target_type = self.data.get('auth_target_type')
109+
workspace_id = self.data.get('workspace_id')
110+
user_id = self.data.get('user_id')
111+
workspace_manage = is_workspace_manage(user_id, workspace_id)
112+
if workspace_manage:
113+
return True
114+
wurp = QuerySet(WorkspaceUserResourcePermission).filter(auth_target_type=auth_target_type,
115+
workspace_id=workspace_id, user=user_id,
116+
target=resource_id).first()
117+
if wurp is None:
118+
return False
119+
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
120+
role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model")
121+
122+
if wurp.auth_type == ResourceAuthType.ROLE.value:
123+
if workspace_user_role_mapping_model and role_permission_mapping_model:
124+
inner = QuerySet(workspace_user_role_mapping_model).filter(workspace_id=workspace_id, user_id=user_id)
125+
return QuerySet(role_permission_mapping_model).filter(role_id__in=inner,
126+
permission_id=(
127+
auth_target_type + ':READ')).exists()
128+
else:
129+
return False
130+
else:
131+
return wurp.permission_list.__contains__(ResourcePermission.VIEW.value)
132+
106133
def auth_resource(self, resource_id: str):
107134
self.is_valid(raise_exception=True)
108135
auth_target_type = self.data.get('auth_target_type')

ui/src/api/tool/tool.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import { Result } from '@/request/Result'
22
import { get, post, del, put, exportFile } from '@/request/index'
33
import { type Ref } from 'vue'
44
import type { pageRequest } from '@/api/type/common'
5-
import type {AddInternalToolParam, toolData} from '@/api/type/tool'
6-
5+
import type { AddInternalToolParam, toolData } from '@/api/type/tool'
76

87
import useStore from '@/stores'
98
const prefix: any = { _value: '/workspace/' }
@@ -18,10 +17,10 @@ Object.defineProperty(prefix, 'value', {
1817
* 工具列表带分页(无分页)
1918
* @params 参数 {folder_id: string}
2019
*/
21-
const getToolList: (data?: any, loading?: Ref<boolean>) => Promise<Result<{tools: any[], folders: any[]}>> = (
22-
data,
23-
loading,
24-
) => {
20+
const getToolList: (
21+
data?: any,
22+
loading?: Ref<boolean>,
23+
) => Promise<Result<{ tools: any[]; folders: any[] }>> = (data, loading) => {
2524
return get(`${prefix.value}`, data, loading)
2625
}
2726

@@ -83,18 +82,18 @@ const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<a
8382
* 删除工具
8483
* @param 参数 tool_id
8584
*/
86-
const delTool: (
87-
tool_id: string,
88-
loading?: Ref<boolean>
89-
) => Promise<Result<boolean>> = (tool_id, loading) => {
85+
const delTool: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
86+
tool_id,
87+
loading,
88+
) => {
9089
return del(`${prefix.value}/${tool_id}`, undefined, {}, loading)
9190
}
9291

93-
const putToolIcon: (
94-
id: string,
95-
data: any,
96-
loading?: Ref<boolean>
97-
) => Promise<Result<any>> = (id, data, loading) => {
92+
const putToolIcon: (id: string, data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
93+
id,
94+
data,
95+
loading,
96+
) => {
9897
return put(`${prefix.value}/${id}/edit_icon`, data, undefined, loading)
9998
}
10099

@@ -139,7 +138,6 @@ const addInternalTool: (
139138
return post(`${prefix.value}/${tool_id}/add_internal_tool`, param, undefined, loading)
140139
}
141140

142-
143141
export default {
144142
getToolList,
145143
getToolListPage,
@@ -152,5 +150,5 @@ export default {
152150
exportTool,
153151
putToolIcon,
154152
delTool,
155-
addInternalTool
153+
addInternalTool,
156154
}

0 commit comments

Comments
 (0)