Skip to content

Commit 592ae54

Browse files
authored
fix: Application import (#3566)
1 parent 109e850 commit 592ae54

File tree

7 files changed

+233
-99
lines changed

7 files changed

+233
-99
lines changed

apps/application/serializers/application.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from common.db.search import native_search, native_page_search
3535
from common.exception.app_exception import AppApiException
3636
from common.field.common import UploadedFileField
37-
from common.utils.common import get_file_content, valid_license, restricted_loads, generate_uuid
37+
from common.utils.common import get_file_content, restricted_loads, generate_uuid
3838
from knowledge.models import Knowledge, KnowledgeScope
3939
from knowledge.serializers.knowledge import KnowledgeSerializer, KnowledgeModelSerializer
4040
from maxkb.conf import PROJECT_DIR
@@ -377,6 +377,7 @@ def page(self, current_page: int, page_size: int, instance: Dict):
377377

378378
class ApplicationImportRequest(serializers.Serializer):
379379
file = UploadedFileField(required=True, label=_("file"))
380+
folder_id = serializers.CharField(required=True, label=_("Folder ID"))
380381

381382

382383
class ApplicationEditSerializer(serializers.Serializer):
@@ -478,16 +479,14 @@ def insert_simple(self, instance: Dict):
478479
QuerySet(ApplicationKnowledgeMapping).bulk_create(application_knowledge_mapping_model_list)
479480
return ApplicationCreateSerializer.ApplicationResponse(application_model).data
480481

481-
@valid_license(model=Application, count=5,
482-
message=_(
483-
'The community version supports up to 5 applications. If you need more applications, please contact us (https://fit2cloud.com/).'))
484482
@transaction.atomic
485-
def import_(self, instance: dict, with_valid=True):
483+
def import_(self, instance: dict, is_import_tool, with_valid=True):
486484
if with_valid:
487485
self.is_valid()
488486
ApplicationImportRequest(data=instance).is_valid(raise_exception=True)
489487
user_id = self.data.get('user_id')
490488
workspace_id = self.data.get("workspace_id")
489+
folder_id = instance.get('folder_id')
491490
mk_instance_bytes = instance.get('file').read()
492491
try:
493492
mk_instance = restricted_loads(mk_instance_bytes)
@@ -498,15 +497,15 @@ def import_(self, instance: dict, with_valid=True):
498497
update_tool_map = {}
499498
if len(tool_list) > 0:
500499
tool_id_list = reduce(lambda x, y: [*x, *y],
501-
[[tool.get('id'), generate_uuid((tool.get('id') + tool.get('workspace_id') or ''))]
500+
[[tool.get('id'), generate_uuid((tool.get('id') + workspace_id or ''))]
502501
for tool
503502
in
504503
tool_list], [])
505504
# 存在的工具列表
506505
exits_tool_id_list = [str(tool.id) for tool in
507506
QuerySet(Tool).filter(id__in=tool_id_list, workspace_id=workspace_id)]
508507
# 需要更新的工具集合
509-
update_tool_map = {tool.get('id'): generate_uuid((tool.get('id') + tool.get('workspace_id') or '')) for tool
508+
update_tool_map = {tool.get('id'): generate_uuid((tool.get('id') + workspace_id or '')) for tool
510509
in
511510
tool_list if
512511
not exits_tool_id_list.__contains__(
@@ -515,8 +514,8 @@ def import_(self, instance: dict, with_valid=True):
515514
tool_list = [{**tool, 'id': update_tool_map.get(tool.get('id'))} for tool in tool_list if
516515
not exits_tool_id_list.__contains__(
517516
tool.get('id')) and not exits_tool_id_list.__contains__(
518-
generate_uuid((tool.get('id') + tool.get('workspace_id') or '')))]
519-
application_model = self.to_application(application, workspace_id, user_id, update_tool_map)
517+
generate_uuid((tool.get('id') + workspace_id or '')))]
518+
application_model = self.to_application(application, workspace_id, user_id, update_tool_map, folder_id)
520519
tool_model_list = [self.to_tool(f, workspace_id, user_id) for f in tool_list]
521520
application_model.save()
522521
# 插入授权数据
@@ -528,7 +527,14 @@ def import_(self, instance: dict, with_valid=True):
528527
# 插入认证信息
529528
ApplicationAccessToken(application_id=application_model.id,
530529
access_token=hashlib.md5(str(uuid.uuid7()).encode()).hexdigest()[8:24]).save()
531-
QuerySet(Tool).bulk_create(tool_model_list) if len(tool_model_list) > 0 else None
530+
if is_import_tool:
531+
if len(tool_model_list) > 0:
532+
QuerySet(Tool).bulk_create(tool_model_list)
533+
UserResourcePermissionSerializer(data={
534+
'workspace_id': self.data.get('workspace_id'),
535+
'user_id': self.data.get('user_id'),
536+
'auth_target_type': AuthTargetType.APPLICATION.value
537+
}).auth_resource_batch([t.id for t in tool_model_list])
532538
return True
533539

534540
@staticmethod
@@ -550,7 +556,7 @@ def to_tool(tool, workspace_id, user_id):
550556
workspace_id=workspace_id)
551557

552558
@staticmethod
553-
def to_application(application, workspace_id, user_id, update_tool_map):
559+
def to_application(application, workspace_id, user_id, update_tool_map, folder_id):
554560
work_flow = application.get('work_flow')
555561
for node in work_flow.get('nodes', []):
556562
if node.get('type') == 'tool-lib-node':
@@ -563,7 +569,7 @@ def to_application(application, workspace_id, user_id, update_tool_map):
563569
user_id=user_id,
564570
name=application.get('name'),
565571
workspace_id=workspace_id,
566-
folder_id=workspace_id,
572+
folder_id=folder_id,
567573
desc=application.get('desc'),
568574
prologue=application.get('prologue'), dialogue_number=application.get('dialogue_number'),
569575
knowledge_setting=application.get('knowledge_setting'),

apps/application/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
urlpatterns = [
88

99
path('workspace/<str:workspace_id>/application', views.ApplicationAPI.as_view(), name='application'),
10-
path('workspace/<str:workspace_id>/application/import', views.ApplicationAPI.Import.as_view()),
10+
path('workspace/<str:workspace_id>/application/folder/<str:folder_id>/import', views.ApplicationAPI.Import.as_view()),
1111
path('workspace/<str:workspace_id>/application/<int:current_page>/<int:page_size>', views.ApplicationAPI.Page.as_view(), name='application_page'),
1212
path('workspace/<str:workspace_id>/application/<str:application_id>', views.ApplicationAPI.Operate.as_view()),
1313
path('workspace/<str:workspace_id>/application/<str:application_id>/publish', views.ApplicationAPI.Publish.as_view()),

apps/application/views/application.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from application.serializers.application import ApplicationSerializer, Query, ApplicationOperateSerializer
2222
from common import result
2323
from common.auth import TokenAuth
24-
from common.auth.authentication import has_permissions
24+
from common.auth.authentication import has_permissions, get_is_permissions
2525
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
2626
from common.log.log import log
2727

@@ -112,10 +112,15 @@ class Import(APIView):
112112
RoleConstants.USER.get_workspace_role(),
113113
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
114114
@log(menu='Application', operate="Import Application", )
115-
def post(self, request: Request, workspace_id: str):
115+
def post(self, request: Request, workspace_id: str, folder_id: str):
116+
is_import_tool = get_is_permissions(request, workspace_id=workspace_id, folder_id=folder_id)(
117+
PermissionConstants.TOOL_IMPORT.get_workspace_permission(),
118+
PermissionConstants.TOOL_IMPORT.get_workspace_permission_workspace_manage_role(),
119+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
120+
)
116121
return result.success(ApplicationSerializer(
117122
data={'user_id': request.user.id, 'workspace_id': workspace_id,
118-
}).import_({'file': request.FILES.get('file')}))
123+
}).import_({'file': request.FILES.get('file'), 'folder_id': folder_id}, is_import_tool))
119124

120125
class Export(APIView):
121126
authentication_classes = [TokenAuth]

apps/common/auth/authentication.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ def exist_permissions_by_view_permission(user_role: List[RoleConstants],
4949
:return: 是否存在 True False
5050
"""
5151

52-
role_list = [user_r(request, kwargs) if callable(user_r) else user_r for user_r in
53-
permission.roleList]
52+
role_list = [user_r(request, kwargs) if callable(user_r) else user_r for user_r in
53+
permission.roleList]
5454
role_ok = any(list(map(lambda up: role_list.__contains__(up),
55-
user_role)))
55+
user_role)))
5656
permission_list = [user_p(request, kwargs) if callable(user_p) else user_p for user_p in
5757
permission.permissionList
5858
]
@@ -79,10 +79,20 @@ def exist_permissions(user_role: List[RoleConstants], user_permission: List[Perm
7979
def exist(user_role: List[RoleConstants], user_permission: List[PermissionConstants], permission, request, **kwargs):
8080
if callable(permission):
8181
p = permission(request, kwargs)
82-
return exist_permissions(user_role, user_permission, p, request,**kwargs)
82+
return exist_permissions(user_role, user_permission, p, request, **kwargs)
8383
return exist_permissions(user_role, user_permission, permission, request, **kwargs)
8484

8585

86+
def get_is_permissions(request, **kwargs):
87+
def is_permissions(*permission, compare=CompareConstants.OR):
88+
exit_list = list(
89+
map(lambda p: exist(request.auth.role_list, request.auth.permission_list, p, request, **kwargs),
90+
permission))
91+
return any(exit_list) if compare == CompareConstants.OR else all(exit_list)
92+
93+
return is_permissions
94+
95+
8696
def has_permissions(*permission, compare=CompareConstants.OR):
8797
"""
8898
权限 role or permission

apps/system_manage/serializers/user_resource_permission.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,32 @@ def is_auth(self, resource_id: str):
130130
else:
131131
return wurp.permission_list.__contains__(ResourcePermission.VIEW.value)
132132

133+
def auth_resource_batch(self, resource_id_list: list):
134+
self.is_valid(raise_exception=True)
135+
auth_target_type = self.data.get('auth_target_type')
136+
workspace_id = self.data.get('workspace_id')
137+
user_id = self.data.get('user_id')
138+
wurp = QuerySet(WorkspaceUserResourcePermission).filter(auth_target_type=auth_target_type,
139+
workspace_id=workspace_id, user_id=user_id).first()
140+
auth_type = wurp.auth_type if wurp else (
141+
ResourceAuthType.RESOURCE_PERMISSION_GROUP if edition == 'CE' else ResourceAuthType.ROLE)
142+
workspace_user_resource_permission = [WorkspaceUserResourcePermission(
143+
target=resource_id,
144+
auth_target_type=auth_target_type,
145+
permission_list=[ResourcePermission.VIEW,
146+
ResourcePermission.MANAGE] if auth_type == ResourceAuthType.RESOURCE_PERMISSION_GROUP else [
147+
ResourcePermissionRole.ROLE],
148+
workspace_id=workspace_id,
149+
user_id=user_id,
150+
auth_type=auth_type
151+
) for resource_id in resource_id_list]
152+
QuerySet(WorkspaceUserResourcePermission).bulk_create(workspace_user_resource_permission)
153+
# 刷新缓存
154+
version = Cache_Version.PERMISSION_LIST.get_version()
155+
key = Cache_Version.PERMISSION_LIST.get_key(user_id=user_id)
156+
cache.delete(key, version=version)
157+
return True
158+
133159
def auth_resource(self, resource_id: str):
134160
self.is_valid(raise_exception=True)
135161
auth_target_type = self.data.get('auth_target_type')

ui/src/api/application/application.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ const putXpackAccessToken: (
140140
return put(`${prefix.value}/${application_id}/setting`, data, undefined, loading)
141141
}
142142

143-
144143
/**
145144
* 导出应用
146145
*/
@@ -161,11 +160,12 @@ const exportApplication = (
161160
/**
162161
* 导入应用
163162
*/
164-
const importApplication: (data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
165-
data,
166-
loading,
167-
) => {
168-
return post(`${prefix.value}/import`, data, undefined, loading)
163+
const importApplication: (
164+
folder_id: string,
165+
data: any,
166+
loading?: Ref<boolean>,
167+
) => Promise<Result<any>> = (folder_id, data, loading) => {
168+
return post(`${prefix.value}/folder/${folder_id}/import`, data, undefined, loading)
169169
}
170170

171171
/**

0 commit comments

Comments
 (0)