@@ -41,15 +41,24 @@ async def get_ws_resource(oid, type) -> list:
4141async def check_ws_permission (oid , type , resource ) -> bool :
4242 if not resource or (isinstance (resource , list ) and len (resource ) == 0 ):
4343 return True
44-
44+
4545 resource_id_list = await get_ws_resource (oid , type )
4646 if not resource_id_list :
4747 return False
4848 if isinstance (resource , list ):
4949 return set (resource ).issubset (set (resource_id_list ))
5050 return resource in resource_id_list
51-
52-
51+
52+
53+ async def _dynamic_assistant_ds_allowed (assistant , ds_id ) -> bool :
54+ """高级小助手(type 1/3 动态数据源)的 ds 来自宿主 API,本地 core_datasource 无记录:
55+ 仅当 ds_id 在本地不存在时才跳过归属校验;本地数据源仍按工作区 oid 校验。"""
56+ if assistant is None or assistant .type not in (1 , 3 ) or isinstance (ds_id , list ):
57+ return False
58+ with Session (engine ) as session :
59+ return session .get (CoreDatasource , ds_id ) is None
60+
61+
5362def require_permissions (permission : SqlbotPermission ):
5463 def decorator (func ):
5564 @wraps (func )
@@ -62,6 +71,7 @@ async def wrapper(*args, **kwargs):
6271 status_code = 401 ,
6372 detail = "用户未认证"
6473 )
74+ assistant = getattr (request .state , 'assistant' , None )
6575 current_oid = current_user .oid
6676
6777 trans = i18n (request )
@@ -90,7 +100,9 @@ async def wrapper(*args, **kwargs):
90100 if match := re .match (r"args\[(\d+)\]" , keyExpression ):
91101 index = int (match .group (1 ))
92102 value = bound_args .args [index ]
93- if await check_ws_permission (current_oid , resource_type , value ):
103+ if await check_ws_permission (current_oid , resource_type , value ) or (
104+ resource_type in ('ds' , 'datasource' )
105+ and await _dynamic_assistant_ds_allowed (assistant , value )):
94106 return await func (* args , ** kwargs )
95107 #raise Exception('no permission to execute or resource do not exist!')
96108 raise Exception (trans ('i18n_permission.permission_resource_limit' ))
@@ -101,7 +113,9 @@ async def wrapper(*args, **kwargs):
101113 value = bound_args .arguments [parts [0 ]]
102114 for part in parts [1 :]:
103115 value = getattr (value , part )
104- if await check_ws_permission (current_oid , resource_type , value ):
116+ if await check_ws_permission (current_oid , resource_type , value ) or (
117+ resource_type in ('ds' , 'datasource' )
118+ and await _dynamic_assistant_ds_allowed (assistant , value )):
105119 return await func (* args , ** kwargs )
106120 raise Exception (trans ('i18n_permission.permission_resource_limit' ))
107121
0 commit comments