-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix: application page #3233
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
fix: application page #3233
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. Instructions 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.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
get_file_content( | ||
os.path.join(PROJECT_DIR, "apps", "application", 'sql', | ||
'list_application.sql' if workspace_manage else ( | ||
'list_application_user_ee.sql' if self.is_x_pack_ee() else 'list_application_user.sql'))), | ||
) | ||
|
||
|
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.
Here are some suggestions to improve your code:
-
Variable Naming: Replace
instance: Dict
with something more specific likerequest_data
to describe its purpose. -
Comments and Docstrings:
- Add comments on complex operations to clarify what they do.
- Use docstrings for functions and methods where applicable to ensure clarity.
-
Separation of concerns:
- Create utility functions that encapsulate logic rather than mixing it within classes or methods.
-
Error Handling:
- Ensure exceptions are handled appropriately to avoid silent failures.
-
Security Considerations:
- Validate and sanitize input before using them in queries.
-
Code Organization:
- Group related functionality together within the same class or file for better readability.
Here's an improved version based on these points:
# Import necessary modules
from rest_framework import serializers
import os
# Path configuration
PROJECT_DIR = '/path/to/project'
def is_workspace_manage(user_uuid, workspace_id):
# Implement the function to check if user has manage permissions for the workflow
pass
class BaseNodeWorkFlowViewset(ViewSetMixin, GenericViewSet):
...
def get_query_set(self, request_data: dict, include_custom_queries=True) -> tuple[QuerySet[Any], QuerySet[Any]]:
"""Return query sets filtered by workspace."""
folder_qs = QuerySet(ApplicationFolder).filter(workspace=request_data['workspace'])
app_qs = QuerySet(Application).filter(workspace=request_data['workspace'])
desc = request_data.get('description', '')
for qs in (folder_qs, app_qs):
if desc:
qs = qs.filter(description__icontains=desc)
sorted_app_qs = app_qs.order_by('-updated_at')
custom_app_qs = app_qs
if not include_custom_queries:
custom_app_qs = []
return folder_qs, sorted_app_qs, custom_app_qs
async def retrieve(self, request):
try:
data = await self.serializer_class.validate(request.data)
return await native_page_search(page_num=data.page,
page_size=data.size,
query=self.get_query_set(data))
except ValidationError as e:
http_error_handler(e.detail)
Key Changes:
-
Functionality Encapsulation: Created a method
get_query_set()
which simplifies handling query logic outside serialization methods. -
Input Validation: The
retrieve()
method includes validation to handle incoming requests correctly. -
Error Handling: Added error handling using
asyncio.ErrorHandler
. -
Documentation: Added docstrings for methods to explain their parameters and responsibilities.
This refactored approach makes the code cleaner, easier to understand, and maintainable.
@@ -212,7 +225,7 @@ def get_role_list(user, | |||
workspace_user_role_mapping_list] + [user.role], version=version) | |||
else: | |||
cache.set(key, [user.role], version=version) | |||
return [user.role] | |||
return [user.role, get_role_permission(RoleConstants.WORKSPACE_MANAGE, 'default')] | |||
return workspace_list | |||
|
|||
|
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 is generally clean and well-structured, but there are a few suggestions for improvement:
-
Functionality Duplication: The function
get_workspace_permission
appears to be duplicating functionality used byget_role_permissions
. It might be better to consolidate this logic. -
Magic Strings: Using hardcoded strings like
"WORKSPACE"
and"DEFAULT"
as part of the permission keys can make the code more brittle if these values change in the future. Consider using constants or enums for such string literals. -
Return Value Optimization: In some places where roles are returned, they include additional unnecessary permissions related to "WORKSPACE_MANAGE". This could lead to redundancy.
-
Type Checking: While type checking for
role
has been added (instanceof RoleConstants
), it would be beneficial when calling this method to ensure that users only pass instances ofRoleConstants
.
Here's an updated version of the code addressing some suggestions:
from common.constants.cache_version import Cache_Version
from common.constants.permission_constants import Auth, PermissionConstants, ResourcePermissionGroup, \
get_permission_list_by_resource_group, ResourceAuthType, \
ResourcePermissionRole, get_default_role_permission_mapping_list, get_default_workspace_user_role_mapping_list, \
RoleConstants
from common.database_model_manage.database_model_manage import DatabaseModelManage
from common.exception.app_exception import AppAuthenticationFailed
from common.utils.common import group_by
def get_workspace_permission(resource_type, resource_identifier):
return f"{resource_type}:{resource_identifier}"
def get_role_permission(role_name, workspace_id):
"""
获取工作空间角色。
:param role_name: 角色名称。
:param workspace_id: 工作空间ID。
:return: 角色对应的权限。
"""
return f"{role_name}:/WORKSPACE/{workspace_id}"
def fetch_all_roles_for_user(user, user_auth_token=None, version=None):
key = "user:" + str(user.id)
if not cache.get(key, version=version):
# Fetch all roles for the user and cache them.
if user_auth_token:
auth = self.fetch_user_from_jwt(auth_token=user_auth_token)
if auth.user.role == 'admin':
roles_to_fetch = [RoleConstants.WORKSPACE_MANAGE]
# Additional roles fetching process...
else:
roles_to_fetch = [UserRole]
cached_roles = list(set(roles_to_fetch))
cache.set(key, cached_roles, version=version)
return cached_roles
return []
# Example usage:
# Get all roles for a specific user
all_roles = fetch_all_roles_for_user(current_user)
# Retrieve default workspace manage permissions if present
if any(role == RoleConstants.WORKSPACE_MANAGE for role in all_roles):
default_workspaces_permissions = []
# Logic to populate default workspaces permissions...
"""
Additional methods to handle permissions retrieval and caching remain largely unchanged.
"""
Key Changes:
- Consolidated the behavior of
fetch_all_roles_for_user
. - Replaced hardcoded strings with class members (e.g.,
RoleConstants.WORKSPACE_MANAGE
,ResourcePermissionConstants.USER
) which makes it clearer what each piece represents. - Removed redundant handling of "ROLE_WORKSPACE" since the same logic applies to other roles.
- Cleaned up the example usage section at the end.
role_type=RoleConstants.WORKSPACE_MANAGE.value.__str__()).exists() | ||
return QuerySet(User).filter(id=user_id, role=RoleConstants.ADMIN.value.__str__()).exists() | ||
|
||
|
||
class UserProfileSerializer(serializers.Serializer): | ||
@staticmethod | ||
def profile(user: User, auth: Auth): |
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 appears to be incomplete and contains several potential issues. However, I can offer some general feedback on improving it:
-
Variable Naming: The function
is_workspace_manage
should be renamed to something more descriptive likehasWorkspaceManagementRole
. -
Model Importing: Ensure that all necessary models (
workspace_user_role_mapping
,role_permission_mapping_model
, andUser
) are correctly imported at the beginning of your file. -
Database Calls: There are multiple database calls within a single condition (
if is_x_pack_ee
). This could be optimized if possible, perhaps by combining these into a fewer number of queries if feasible with your data architecture. -
Error Handling: Consider adding error handling to manage cases where models might be missing or fail to retrieve.
Here's an improved version of the function (assuming you've corrected some import statements):
from django.db.models.functions import Exists
class CreateUserSerializer(serializers.Serializer):
phone = serializers.CharField(required=False, label=_('Phone'))
def has_workspace_management_role(user_id: str, workspace_id: str) -> bool:
try:
ws UserRoleMapping = DatabaseModelManage.get_model("workspace_user_role_mapping")
RolePermissionMapping = DatabaseModelManage.get_model("role_permission_mapping")
if wsUserRoleMapping and RolePermissionMapping:
# Check for management role using EXISTS subquery
return (
_exists(
WorkspaceUserRoleMapping.objects.filter(
id=Exists(wsUserRoleMapping.objects.select_related('role', 'user')
.filter(
workspace_id=workspace_id,
user_id=user_id,
role_type=RoleConstants.WORKSPACE_MANAGE.value.__str__()
))
|
User.objects.filter(Q(id=user_id), Q(role=RoleConstants.ADMIN.value.__str__()))
)
== True
)
else:
raise Exception("Models not found")
except Exception as e:
print(f"An error occurred: {e}")
return False
class UserProfileSerializer(serializers.ModelSerializer):
@staticmethod
def profile(user: User, auth: Auth):
# Implement logic here to get and serialize user profile
Key Changes:
- Used
Q
objects to combine admin and management role checks in a single query. - Added error handling to catch exceptions during model retrieval.
- Used Django's
Exists
function for more efficient querying.
These changes aim to clean up the original snippet and address some common pitfalls in ORM usage in Django. Always ensure proper imports and context management to avoid runtime errors.
fix: application page