feat:Multiple permission filtering function#3856
Conversation
|
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
| permission__in=query_p_list) | ||
|
|
||
| return { | ||
| 'workspace_user_resource_permission_query_set': workspace_user_resource_permission_query_set, |
There was a problem hiding this comment.
It looks like the provided code snippet contains a few issues and areas for improvement:
-
Imports: The
django.db.models.QuerySetimport should be followed by another import of its base class (QuerySet) to prevent conflicts. -
Permissions List Modification: In the
editmethod, there's an attempt to modifytargetsbased on permission values. This could lead to unexpected behavior since it depends on internal logic that isn't clearly defined in the context. -
Empty Permission Handling: When processing permissions, it seems there might be a missing case where empty permissions should return no results.
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:
- Import Clarification: Added
import django.db.models as _models. - Multiple Choice Handling: Used
serializers.BooleanFieldfor better handling True/False logic rather than strings. - Filter Logic Simplification: Ensured proper filtering logic without relying on undefined conditions.
- Model Update: Changed
permissioncolumn inWorkspaceUserResourcePermissionmodel to useBooleanFieldto represent the choices instead of string literals. Adjusted related logic accordingly.
These changes should address most identified issues while maintaining good coding practices.
| '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, | ||
| )) |
There was a problem hiding this comment.
There are a few improvements and corrections that can be made to this code:
-
Consistent Use of
getlist: In Django views, it's common practice to userequest.query_params.getlist()when you expect multiple values (e.g., tags, permissions) rather thanget(). This avoids errors and makes the intent clearer.# Line 53: 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.getlist('permission')}, current_page, page_size, request.user)) # Line 94: 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.getlist('permission')}, request.user)) # Lines 114-150 in `WorkspaceResourceUserPermissionView` should also use getlist for permissions parameter. -
Code Reformatting: It may improve readability slightly by adding more indentation or aligning parameters under their respective functions.
-
Comments and Docstrings: Adding comments and docstrings is crucial for understanding the purpose and functionality of each part of the code. Here’s an example of how you might add some documentation:
@@ -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.
| many=True, | ||
| required=False | ||
| ), | ||
| ] |
There was a problem hiding this comment.
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:
def get_parameters():
"""
Returns the parameters for accessing an endpoint requiring multiple permissions.
:return: List of dictionary objects describing endpoints with their specific query parameters.
"""
return [
{
"name": "permission",
"description": "Allowed permissions separated by commas.",
"type": [ # Assuming 'type' should specify one more option here based on the original context.
OpenApiTypes.STR,
OpenApiTypes.INT # Example, depending on actual usage requirements
],
"location": "query",
"many": True,
"required": False
}
]Key Changes:
- Consistency: Used
"permission"as the variable name consistently across all instances. - Parameter Explanation: Added a brief"description".
- Documentation Comments: Provided explanation at the top to describe what the function does.
- Data Type Flexibility: Suggested including additional types (
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.
feat:Multiple permission filtering function