Skip to content

Commit c5bdada

Browse files
authored
feat: user resource permission (#3422)
1 parent 873a9a9 commit c5bdada

File tree

13 files changed

+288
-115
lines changed

13 files changed

+288
-115
lines changed

apps/common/auth/handle/impl/user_token.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from common.constants.permission_constants import Auth, PermissionConstants, ResourcePermissionGroup, \
2121
get_permission_list_by_resource_group, ResourceAuthType, \
2222
ResourcePermissionRole, get_default_role_permission_mapping_list, get_default_workspace_user_role_mapping_list, \
23-
RoleConstants
23+
RoleConstants, ResourcePermission, Resource
2424
from common.database_model_manage.database_model_manage import DatabaseModelManage
2525
from common.exception.app_exception import AppAuthenticationFailed
2626
from common.utils.common import group_by
@@ -132,9 +132,11 @@ def get_workspace_resource_permission_list_by_workspace_user_permission(
132132
resource_permission_list = [
133133
[
134134
f"{permission}:/WORKSPACE/{workspace_user_resource_permission.workspace_id}/{workspace_user_resource_permission.auth_target_type}/{workspace_user_resource_permission.target}"
135-
for permission in get_permission_list_by_resource_group(ResourcePermissionGroup[resource_permission])]
135+
for permission in get_permission_list_by_resource_group(
136+
ResourcePermissionGroup(Resource(workspace_user_resource_permission.auth_target_type),
137+
ResourcePermission(resource_permission)))]
136138
for resource_permission in workspace_user_resource_permission.permission_list if
137-
ResourcePermissionGroup.values.__contains__(resource_permission)]
139+
ResourcePermission.values.__contains__(resource_permission)]
138140
# 将二维数组扁平为一维
139141
return reduce(lambda x, y: [*x, *y], resource_permission_list, [])
140142
return []

apps/common/constants/permission_constants.py

Lines changed: 140 additions & 63 deletions
Large diffs are not rendered by default.

apps/system_manage/models/workspace_user_permission.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from django.db import models
1313

1414
from common.constants.permission_constants import Group, ResourcePermissionGroup, ResourceAuthType, \
15-
ResourcePermissionRole
15+
ResourcePermissionRole, ResourcePermission
1616
from users.models import User
1717

1818

@@ -48,8 +48,8 @@ class WorkspaceUserResourcePermission(models.Model):
4848
default=list,
4949
base_field=models.CharField(max_length=256,
5050
blank=True,
51-
choices=ResourcePermissionGroup.choices + ResourcePermissionRole.choices,
52-
default=ResourcePermissionGroup.VIEW))
51+
choices=ResourcePermission.choices + ResourcePermissionRole.choices,
52+
default=ResourcePermission.VIEW))
5353

5454
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
5555

apps/system_manage/serializers/user_resource_permission.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from application.models import Application
1818
from common.constants.cache_version import Cache_Version
1919
from common.constants.permission_constants import get_default_workspace_user_role_mapping_list, RoleConstants, \
20-
ResourcePermissionGroup, ResourcePermissionRole, ResourceAuthType
20+
ResourcePermission, ResourcePermissionRole, ResourceAuthType
2121
from common.database_model_manage.database_model_manage import DatabaseModelManage
2222
from common.db.search import native_search
2323
from common.db.sql_execute import select_list
@@ -51,7 +51,6 @@ class UserResourcePermissionResponse(serializers.Serializer):
5151

5252

5353
class UpdateTeamMemberItemPermissionSerializer(serializers.Serializer):
54-
auth_target_type = serializers.ChoiceField(required=True, choices=AuthTargetType.choices, label="授权资源")
5554
target_id = serializers.CharField(required=True, label=_('target id'))
5655
auth_type = serializers.ChoiceField(required=True, choices=ResourceAuthType.choices, label="授权类型")
5756
permission = PermissionSerializer(required=True, many=False)
@@ -60,34 +59,46 @@ class UpdateTeamMemberItemPermissionSerializer(serializers.Serializer):
6059
class UpdateUserResourcePermissionRequest(serializers.Serializer):
6160
user_resource_permission_list = UpdateTeamMemberItemPermissionSerializer(required=True, many=True)
6261

63-
def is_valid(self, *, workspace_id=None, raise_exception=False):
62+
def is_valid(self, *, auth_target_type=None, workspace_id=None, raise_exception=False):
6463
super().is_valid(raise_exception=True)
65-
user_resource_permission_list = self.data.get("user_resource_permission_list")
64+
user_resource_permission_list = [{'target_id': urp.get('target_id'), 'auth_target_type': auth_target_type} for
65+
urp in
66+
self.data.get("user_resource_permission_list")]
6667
illegal_target_id_list = select_list(
6768
get_file_content(
6869
os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', 'check_member_permission_target_exists.sql')),
6970
[json.dumps(user_resource_permission_list), workspace_id, workspace_id, workspace_id, workspace_id])
7071
if illegal_target_id_list is not None and len(illegal_target_id_list) > 0:
7172
raise AppApiException(500,
72-
_('Non-existent application|knowledge base id[') + str(illegal_target_id_list) + ']')
73+
_('Non-existent id[') + str(illegal_target_id_list) + ']')
74+
75+
76+
m_map = {
77+
"KNOWLEDGE": Knowledge,
78+
'TOOL': Tool,
79+
'MODEL': Model,
80+
'APPLICATION': Application,
81+
}
82+
sql_map = {
83+
"KNOWLEDGE": 'get_knowledge_user_resource_permission.sql',
84+
'TOOL': 'get_tool_user_resource_permission.sql',
85+
'MODEL': 'get_model_user_resource_permission.sql',
86+
'APPLICATION': 'get_application_user_resource_permission.sql'
87+
}
7388

7489

7590
class UserResourcePermissionSerializer(serializers.Serializer):
7691
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
7792
user_id = serializers.CharField(required=True, label=_('user id'))
93+
auth_target_type = serializers.CharField(required=True, label=_('resource'))
7894

7995
def get_queryset(self):
8096
return {
81-
"knowledge_query_set": QuerySet(Knowledge)
82-
.filter(workspace_id=self.data.get('workspace_id')),
83-
'tool_query_set': QuerySet(Tool)
84-
.filter(workspace_id=self.data.get('workspace_id')),
85-
'model_query_set': QuerySet(Model)
86-
.filter(workspace_id=self.data.get('workspace_id')),
87-
'application_query_set': QuerySet(Application)
88-
.filter(workspace_id=self.data.get('workspace_id')),
97+
'query_set': QuerySet(m_map.get(self.data.get('auth_target_type'))).filter(
98+
workspace_id=self.data.get('workspace_id')),
8999
'workspace_user_resource_permission_query_set': QuerySet(WorkspaceUserResourcePermission).filter(
90-
workspace_id=self.data.get('workspace_id'), user=self.data.get('user_id'))
100+
workspace_id=self.data.get('workspace_id'), user=self.data.get('user_id'),
101+
auth_target_type=self.data.get('auth_target_type'))
91102
}
92103

93104
def list(self, user, with_valid=True):
@@ -97,7 +108,7 @@ def list(self, user, with_valid=True):
97108
user_id = self.data.get("user_id")
98109
# 用户权限列表
99110
user_resource_permission_list = native_search(self.get_queryset(), get_file_content(
100-
os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', 'get_user_resource_permission.sql')))
111+
os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', sql_map.get(self.data.get('auth_target_type')))))
101112
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
102113
workspace_model = DatabaseModelManage.get_model("workspace_model")
103114
if workspace_user_role_mapping_model and workspace_model:
@@ -112,14 +123,14 @@ def list(self, user, with_valid=True):
112123
if is_workspace_manage:
113124
user_resource_permission_list = list(
114125
map(lambda row: {**row,
115-
'permission': {ResourcePermissionGroup.VIEW.value: True,
116-
ResourcePermissionGroup.MANAGE.value: True,
126+
'permission': {ResourcePermission.VIEW.value: True,
127+
ResourcePermission.MANAGE.value: True,
117128
ResourcePermissionRole.ROLE.value: True}},
118129
user_resource_permission_list))
119130
return group_by([{**user_resource_permission, 'permission': {
120131
permission: True if user_resource_permission.get('permission_list').__contains__(permission) else False for
121132
permission in
122-
[ResourcePermissionGroup.VIEW.value, ResourcePermissionGroup.MANAGE.value,
133+
[ResourcePermission.VIEW.value, ResourcePermission.MANAGE.value,
123134
ResourcePermissionRole.ROLE.value]}}
124135
for user_resource_permission in user_resource_permission_list],
125136
key=lambda item: item.get('auth_target_type'))
@@ -128,14 +139,16 @@ def edit(self, instance, user, with_valid=True):
128139
if with_valid:
129140
self.is_valid(raise_exception=True)
130141
UpdateUserResourcePermissionRequest(data=instance).is_valid(raise_exception=True,
142+
auth_target_type=self.data.get(
143+
'auth_target_type'),
131144
workspace_id=self.data.get('workspace_id'))
132145
workspace_id = self.data.get("workspace_id")
133146
user_id = self.data.get("user_id")
134147
update_list = []
135148
save_list = []
136149
user_resource_permission_list = instance.get('user_resource_permission_list')
137150
workspace_user_resource_permission_exist_list = QuerySet(WorkspaceUserResourcePermission).filter(
138-
workspace_id=workspace_id, user_id=user_id)
151+
workspace_id=workspace_id, user_id=user_id, auth_target_type=self.data.get('auth_target_type'))
139152
for user_resource_permission in user_resource_permission_list:
140153
exist_list = [user_resource_permission_exist for user_resource_permission_exist in
141154
workspace_user_resource_permission_exist_list if
@@ -147,8 +160,7 @@ def edit(self, instance, user, with_valid=True):
147160
update_list.append(exist_list[0])
148161
else:
149162
save_list.append(WorkspaceUserResourcePermission(target=user_resource_permission.get('target_id'),
150-
auth_target_type=user_resource_permission.get(
151-
'auth_target_type'),
163+
auth_target_type=self.data.get('auth_target_type'),
152164
permission_list=[key for key in
153165
user_resource_permission.get(
154166
'permission').keys() if
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SELECT app_or_knowledge.*,
2+
COALESCE(workspace_user_resource_permission.permission_list,'{}')::varchar[] as permission_list,
3+
COALESCE(workspace_user_resource_permission.auth_type,'ROLE') as auth_type
4+
FROM (SELECT "id",
5+
"name",
6+
'APPLICATION' AS "auth_target_type",
7+
user_id,
8+
workspace_id,
9+
icon,
10+
folder_id
11+
FROM application
12+
${query_set}
13+
) app_or_knowledge
14+
LEFT JOIN (SELECT *
15+
FROM workspace_user_resource_permission
16+
${workspace_user_resource_permission_query_set}) workspace_user_resource_permission
17+
ON workspace_user_resource_permission.target = app_or_knowledge."id";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SELECT app_or_knowledge.*,
2+
COALESCE(workspace_user_resource_permission.permission_list,'{}')::varchar[] as permission_list,
3+
COALESCE(workspace_user_resource_permission.auth_type,'ROLE') as auth_type
4+
FROM (SELECT "id",
5+
"name",
6+
'KNOWLEDGE' AS "auth_target_type",
7+
user_id,
8+
workspace_id,
9+
"type"::varchar AS "icon",
10+
folder_id
11+
FROM knowledge
12+
${query_set}
13+
) app_or_knowledge
14+
LEFT JOIN (SELECT *
15+
FROM workspace_user_resource_permission
16+
${workspace_user_resource_permission_query_set}) workspace_user_resource_permission
17+
ON workspace_user_resource_permission.target = app_or_knowledge."id";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SELECT app_or_knowledge.*,
2+
COALESCE(workspace_user_resource_permission.permission_list,'{}')::varchar[] as permission_list,
3+
COALESCE(workspace_user_resource_permission.auth_type,'ROLE') as auth_type
4+
FROM (SELECT "id",
5+
"name",
6+
'MODEL' AS "auth_target_type",
7+
user_id,
8+
workspace_id,
9+
provider as icon,
10+
'default' as folder_id
11+
FROM model
12+
${query_set}
13+
) app_or_knowledge
14+
LEFT JOIN (SELECT *
15+
FROM workspace_user_resource_permission
16+
${workspace_user_resource_permission_query_set}) workspace_user_resource_permission
17+
ON workspace_user_resource_permission.target = app_or_knowledge."id";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SELECT app_or_knowledge.*,
2+
COALESCE(workspace_user_resource_permission.permission_list,'{}')::varchar[] as permission_list,
3+
COALESCE(workspace_user_resource_permission.auth_type,'ROLE') as auth_type
4+
FROM (SELECT "id",
5+
"name",
6+
'TOOL' AS "auth_target_type",
7+
user_id,
8+
workspace_id,
9+
icon,
10+
folder_id
11+
FROM tool
12+
${query_set}
13+
) app_or_knowledge
14+
LEFT JOIN (SELECT *
15+
FROM workspace_user_resource_permission
16+
${workspace_user_resource_permission_query_set}) workspace_user_resource_permission
17+
ON workspace_user_resource_permission.target = app_or_knowledge."id";

apps/system_manage/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
app_name = "system_manage"
66
# @formatter:off
77
urlpatterns = [
8-
path('workspace/<str:workspace_id>/user_resource_permission/user/<str:user_id>', views.WorkSpaceUserResourcePermissionView.as_view()),
8+
path('workspace/<str:workspace_id>/user_resource_permission/user/<str:user_id>/resource/<str:resource>', views.WorkSpaceUserResourcePermissionView.as_view()),
99
path('email_setting', views.SystemSetting.Email.as_view()),
1010
path('profile', views.SystemProfile.as_view()),
1111
path('valid/<str:valid_type>/<int:valid_count>', views.Valid.as_view())

apps/system_manage/views/user_resource_permission.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from common import result
1616
from common.auth import TokenAuth
1717
from common.auth.authentication import has_permissions
18-
from common.constants.permission_constants import PermissionConstants, RoleConstants
18+
from common.constants.permission_constants import PermissionConstants, RoleConstants, Permission, Group, Operate
1919
from common.log.log import log
2020
from common.result import DefaultResultSerializer
2121
from system_manage.api.user_resource_permission import UserResourcePermissionAPI, EditUserResourcePermissionAPI
@@ -43,11 +43,13 @@ class WorkSpaceUserResourcePermissionView(APIView):
4343
responses=UserResourcePermissionAPI.get_response(),
4444
tags=[_('Resources authorization')] # type: ignore
4545
)
46-
@has_permissions(PermissionConstants.WORKSPACE_USER_RESOURCE_PERMISSION_READ.get_workspace_permission(),
47-
RoleConstants.ADMIN, RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
48-
def get(self, request: Request, workspace_id: str, user_id: str):
46+
@has_permissions(
47+
lambda r, kwargs: Permission(group=Group(kwargs.get('resource') + '_WORKSPACE_USER_RESOURCE_PERMISSION'),
48+
operate=Operate.READ),
49+
RoleConstants.ADMIN, RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
50+
def get(self, request: Request, workspace_id: str, user_id: str, resource: str):
4951
return result.success(UserResourcePermissionSerializer(
50-
data={'workspace_id': workspace_id, 'user_id': user_id}
52+
data={'workspace_id': workspace_id, 'user_id': user_id, 'auth_target_type': resource}
5153
).list(request.user))
5254

5355
@extend_schema(
@@ -62,9 +64,11 @@ def get(self, request: Request, workspace_id: str, user_id: str):
6264
@log(menu='System', operate='Modify the resource authorization list',
6365
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id'))
6466
)
65-
@has_permissions(PermissionConstants.WORKSPACE_USER_RESOURCE_PERMISSION_EDIT.get_workspace_permission(),
66-
RoleConstants.ADMIN, RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
67-
def put(self, request: Request, workspace_id: str, user_id: str):
67+
@has_permissions(
68+
lambda r, kwargs: Permission(group=Group(kwargs.get('resource') + '_WORKSPACE_USER_RESOURCE_PERMISSION'),
69+
operate=Operate.EDIT),
70+
RoleConstants.ADMIN, RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
71+
def put(self, request: Request, workspace_id: str, user_id: str, resource: str):
6872
return result.success(UserResourcePermissionSerializer(
69-
data={'workspace_id': workspace_id, 'user_id': user_id}
73+
data={'workspace_id': workspace_id, 'user_id': user_id, 'auth_target_type': resource}
7074
).edit(request.data, request.user))

0 commit comments

Comments
 (0)