-
Notifications
You must be signed in to change notification settings - Fork 3k
feat:Multiple permission filtering function #3856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ | |
|
|
||
| from django.core.cache import cache | ||
| from django.db import models | ||
| from django.db.models import QuerySet | ||
| from django.db.models import QuerySet, Q | ||
| from django.utils.translation import gettext_lazy as _ | ||
| from rest_framework import serializers | ||
|
|
||
|
|
@@ -24,14 +24,12 @@ | |
| from common.db.sql_execute import select_list | ||
| from common.exception.app_exception import AppApiException | ||
| from common.utils.common import get_file_content | ||
| from common.utils.split_model import group_by | ||
| from knowledge.models import Knowledge | ||
| from maxkb.conf import PROJECT_DIR | ||
| from maxkb.settings import edition | ||
| from models_provider.models import Model | ||
| from system_manage.models import WorkspaceUserResourcePermission, AuthTargetType | ||
| from system_manage.models import WorkspaceUserResourcePermission | ||
| from tools.models import Tool | ||
| from users.models import User | ||
| from users.serializers.user import is_workspace_manage | ||
|
|
||
|
|
||
|
|
@@ -94,11 +92,14 @@ def is_valid(self, *, auth_target_type=None, workspace_id=None, raise_exception= | |
| 'APPLICATION': 'get_application_user_resource_permission.sql' | ||
| } | ||
|
|
||
|
|
||
| class UserResourcePermissionUserListRequest(serializers.Serializer): | ||
| name = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('resource name')) | ||
| permission = serializers.ChoiceField(required=False, allow_null=True, allow_blank=True,choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'], | ||
| permission = serializers.MultipleChoiceField(required=False, allow_null=True, allow_blank=True, | ||
| choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'], | ||
| label=_('permission')) | ||
|
|
||
|
|
||
| class UserResourcePermissionSerializer(serializers.Serializer): | ||
| workspace_id = serializers.CharField(required=True, label=_('workspace id')) | ||
| user_id = serializers.CharField(required=True, label=_('user id')) | ||
|
|
@@ -112,13 +113,20 @@ def get_queryset(self, instance): | |
| })) | ||
| name = instance.get('name') | ||
| permission = instance.get('permission') | ||
| query_p_list = [None if p == "NOT_AUTH" else p for p in permission] | ||
|
|
||
| if name: | ||
| resource_query_set = resource_query_set.filter(name__contains=name) | ||
| if permission: | ||
| resource_query_set = resource_query_set.filter( | ||
| permission=None if instance.get('permission') == 'NOT_AUTH' else instance.get('permission')) | ||
|
|
||
| if all([p is None for p in query_p_list]): | ||
| resource_query_set = resource_query_set.filter(permission=None) | ||
| else: | ||
| if any([p is None for p in query_p_list]): | ||
| resource_query_set = resource_query_set.filter( | ||
| Q(permission__in=query_p_list) | Q(permission=None)) | ||
| else: | ||
| resource_query_set = resource_query_set.filter( | ||
| permission__in=query_p_list) | ||
| return { | ||
| 'query_set': QuerySet(m_map.get(self.data.get('auth_target_type'))).filter( | ||
| workspace_id=self.data.get('workspace_id')), | ||
|
|
@@ -218,35 +226,37 @@ def list(self, instance, user, with_valid=True): | |
| os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', sql_map.get(self.data.get('auth_target_type'))))) | ||
|
|
||
| return [{**user_resource_permission} | ||
| for user_resource_permission in user_resource_permission_list] | ||
|
|
||
| for user_resource_permission in user_resource_permission_list] | ||
|
|
||
| def page(self, instance, current_page: int, page_size: int,user, with_valid=True): | ||
| def page(self, instance, current_page: int, page_size: int, user, with_valid=True): | ||
| if with_valid: | ||
| self.is_valid(raise_exception=True) | ||
| UserResourcePermissionUserListRequest(data=instance).is_valid(raise_exception=True) | ||
| workspace_id = self.data.get("workspace_id") | ||
| user_id = self.data.get("user_id") | ||
| # 用户对应的资源权限分页列表 | ||
| user_resource_permission_page_list = native_page_search(current_page,page_size,self.get_queryset(instance),get_file_content( | ||
| os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', sql_map.get(self.data.get('auth_target_type'))) | ||
| )) | ||
| user_resource_permission_page_list = native_page_search(current_page, page_size, self.get_queryset(instance), | ||
| get_file_content( | ||
| os.path.join(PROJECT_DIR, "apps", "system_manage", | ||
| 'sql', sql_map.get( | ||
| self.data.get('auth_target_type'))) | ||
| )) | ||
|
|
||
| return user_resource_permission_page_list | ||
|
|
||
|
|
||
| def edit(self, instance, user, with_valid=True): | ||
| if with_valid: | ||
| self.is_valid(raise_exception=True) | ||
| UpdateUserResourcePermissionRequest(data={'user_resource_permission_list':instance}).is_valid(raise_exception=True, | ||
| auth_target_type=self.data.get( | ||
| 'auth_target_type'), | ||
| workspace_id=self.data.get('workspace_id')) | ||
| UpdateUserResourcePermissionRequest(data={'user_resource_permission_list': instance}).is_valid( | ||
| raise_exception=True, | ||
| auth_target_type=self.data.get( | ||
| 'auth_target_type'), | ||
| workspace_id=self.data.get('workspace_id')) | ||
| workspace_id = self.data.get("workspace_id") | ||
| user_id = self.data.get("user_id") | ||
| update_list = [] | ||
| save_list = [] | ||
| targets = [ item['target_id'] for item in instance ] | ||
| targets = [item['target_id'] for item in instance] | ||
| QuerySet(WorkspaceUserResourcePermission).filter( | ||
| workspace_id=workspace_id, | ||
| user_id=user_id, | ||
|
|
@@ -286,14 +296,15 @@ def edit(self, instance, user, with_valid=True): | |
| class ResourceUserPermissionUserListRequest(serializers.Serializer): | ||
| nick_name = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('workspace id')) | ||
| username = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('workspace id')) | ||
| permission = serializers.ChoiceField(required=False, allow_null=True, allow_blank=True, choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'], | ||
| label=_('permission')) | ||
| permission = serializers.MultipleChoiceField(required=False, allow_null=True, allow_blank=True, | ||
| choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'], | ||
| label=_('permission')) | ||
|
|
||
|
|
||
| class ResourceUserPermissionEditRequest(serializers.Serializer): | ||
| user_id = serializers.CharField(required=True, label=_('workspace id')) | ||
| permission = serializers.ChoiceField(required=True, choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'], | ||
| label=_('permission')) | ||
| label=_('permission')) | ||
|
|
||
|
|
||
| permission_map = { | ||
|
|
@@ -315,11 +326,13 @@ def get_queryset(self, instance): | |
| user_query_set = QuerySet(model=get_dynamics_model({ | ||
| 'nick_name': models.CharField(), | ||
| 'username': models.CharField(), | ||
| "permission": models.CharField(), | ||
| "permission": models.CharField() | ||
| })) | ||
| nick_name = instance.get('nick_name') | ||
| username = instance.get('username') | ||
| permission = instance.get('permission') | ||
| query_p_list = [None if p == "NOT_AUTH" else p for p in permission] | ||
|
|
||
| workspace_user_resource_permission_query_set = QuerySet(WorkspaceUserResourcePermission).filter( | ||
| workspace_id=self.data.get('workspace_id'), | ||
| auth_target_type=self.data.get('auth_target_type'), | ||
|
|
@@ -329,8 +342,16 @@ def get_queryset(self, instance): | |
| if username: | ||
| user_query_set = user_query_set.filter(username__contains=username) | ||
| if permission: | ||
| user_query_set = user_query_set.filter( | ||
| permission=None if instance.get('permission') == 'NOT_AUTH' else instance.get('permission')) | ||
| if all([p is None for p in query_p_list]): | ||
| user_query_set = user_query_set.filter( | ||
| permission=None) | ||
| else: | ||
| if any([p is None for p in query_p_list]): | ||
| user_query_set = user_query_set.filter( | ||
| Q(permission__in=query_p_list) | Q(permission=None)) | ||
| else: | ||
| user_query_set = user_query_set.filter( | ||
| permission__in=query_p_list) | ||
|
|
||
| return { | ||
| 'workspace_user_resource_permission_query_set': workspace_user_resource_permission_query_set, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the provided code snippet contains a few issues and areas for improvement:
Here are some suggested changes: from django.db.models import QuerySet, Q
# ... (rest of the imports)
class UserResourcePermissionUserListRequest(serializers.Serializer):
...
permission = serializers.MultipleChoiceField(
required=False,
allow_null=True,
allow_blank=True,
choices=['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE'],
label=_('permission'),
)
...
class UserResourcePermissionSerializer(serializers.ModelSerializer):
workspace_id = serializers.CharField(label=_('workspace id'))
user_id = serializers.CharField(label=_('user id'))
def get_queryset(self, instance):
# Assuming m_map gets initialized elsewhere and provides appropriate database queries
resource_query_set = m_map.get(self.data.get('auth_target_type'))().filter(workspace_id=self.data.get('workspace_id'))
name = instance.get('name')
permission = instance.get('permission')
# Handle multiple permission filtering
if all(p is None for p in permission):
resource_query_set = resource_query_set.filter(permission__isnull=true)
elif any(p is not None for p in permission):
# Ensure valid choices when using ChoiceField/MultipleChoiceField
valid_permissions = ['NOT_AUTH', 'MANAGE', 'VIEW', 'ROLE']
allowed_permissions = [perm for perm in permission if perm in valid_permissions]
if allowed_permissions:
resource_query_set = resource_query_set.filter(permission__in=allowed_permissions)
return {
'query_set': resource_query_set,
}
def list(self, instance, user):
return [{
**user_resource_permission
} for user_resource_permission in self.get_queryset(instance)]
...
class ResourceUserPermissionEditRequest(serializers.ModelSerializer):
user_id = serializers.IntegerField(label=_('workspace id'))
permission = serializers.ChoiceField(choices=[
('NOT_AUTH', _('Not Authorized')),
('MANAGE', _('Manager')),
('VIEW', _('Viewer')),
('ROLE', _('Role Assignment')),
], label=_('permission'))
...
class WorkspaceUserResourcePermission(models.Model):
workspace_id = models.CharField(max_length=100)
auth_target_type = models.CharField(max_length=50)
target_id = models.IntegerField()
user_id = models.IntegerField()
permission = models.CharField(max_length=50) # Updated field type to accommodate choices
objects = models.Manager()
def edit(self, instance, user):
if isinstance(user, str): # Example assumption about user authentication mechanism
try:
user_instance = User.objects.get(username=user)
except User.DoesNotExist:
raise AppApiException(detail=_("Invalid user"))
for entry in instance:
new_record = WorkspaceUserResourcePermission(
workspace_id=entry['workspace_id'],
auth_target_type=entry['auth_target_type'],
target_id=entry['target_id'],
user_id=user_instance.id,
permission=entry['permission'],
)
new_record.save()Key Changes Made:
These changes should address most identified issues while maintaining good coding practices. |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ def get(self, request: Request, workspace_id: str, user_id: str, resource: str): | |
| return result.success(UserResourcePermissionSerializer( | ||
| data={'workspace_id': workspace_id, 'user_id': user_id, 'auth_target_type': resource} | ||
| ).list({'name': request.query_params.get('name'), | ||
| 'permission': request.query_params.get('permission')}, request.user)) | ||
| 'permission': request.query_params.getlist('permission')}, request.user)) | ||
|
|
||
| @extend_schema( | ||
| methods=['PUT'], | ||
|
|
@@ -94,7 +94,7 @@ def get(self, request: Request, workspace_id: str, user_id: str, resource: str, | |
| return result.success(UserResourcePermissionSerializer( | ||
| data={'workspace_id': workspace_id, 'user_id': user_id, 'auth_target_type': resource} | ||
| ).page({'name': request.query_params.get('name'), | ||
| 'permission': request.query_params.get('permission')}, current_page, page_size, request.user)) | ||
| 'permission': request.query_params.getlist('permission')}, current_page, page_size, request.user)) | ||
|
|
||
|
|
||
| class WorkspaceResourceUserPermissionView(APIView): | ||
|
|
@@ -114,7 +114,7 @@ def get(self, request: Request, workspace_id: str, target: str, resource: str): | |
| data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, | ||
| }).list( | ||
| {'username': request.query_params.get("username"), 'nick_name': request.query_params.get("nick_name"), | ||
| 'permission': request.query_params.get("permission") | ||
| 'permission': request.query_params.getlist("permission") | ||
| })) | ||
|
|
||
| @extend_schema( | ||
|
|
@@ -150,5 +150,5 @@ def get(self, request: Request, workspace_id: str, target: str, resource: str, c | |
| data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, } | ||
| ).page({'username': request.query_params.get("username"), | ||
| 'nick_name': request.query_params.get("nick_name"), | ||
| 'permission': request.query_params.get("permission")}, current_page, page_size, | ||
| 'permission': request.query_params.getlist("permission")}, current_page, page_size, | ||
| )) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a few improvements and corrections that can be made to this code:
@@ -53,7 +53,7 @@ def get(self, request: Request, workspace_id: str, user_id: str, resource: str):
"""
Return a list of user-resource permissions sorted by name and permission type.
- Parameters:
- request: HttpRequest object containing query parameters like 'name' and 'permission'.
+ Parameters:
+ request: HttpRequest object containing query parameters like 'name', and optional 'permissions'.
Returns:
A paginated list of UserResourcePermissions filtered by the given criteria.
Following these suggestions will make the code cleaner, readable, and potentially more robust. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The provided code snippet appears to be a function
get_parameters()that defines API endpoint parameters using an OpenAPI schema format (similar to those used in Swagger). However, it only includes three occurrences of this parameter definition. To ensure robustness and adherence to typical API design practices, I would suggest making these changes:Ensure Consistent Variable Names: Use consistent names throughout similar definitions.
Implement Validation Logic: Include data validation logic if necessary.
Documentation Improvements: Add comments or documentation about the functionality being described.
Here is the revised version with these considerations:
Key Changes:
"permission"as the variable name consistently across all instances.OpenApiTypes.INT) within the list for flexibility if needed.These updates make the code more maintainable and easier to understand while ensuring compliance with best practices for handling query parameters in APIs.