chore: translate Chinese comments to English in ClickZetta Volume storage module (#25037)

This commit is contained in:
-LAN-
2025-09-03 10:57:58 +08:00
committed by GitHub
parent 60c5bdd62f
commit c3820f55f4
3 changed files with 205 additions and 205 deletions

View File

@@ -1,7 +1,7 @@
"""ClickZetta Volume权限管理机制
"""ClickZetta Volume permission management mechanism
该模块提供Volume权限检查、验证和管理功能。
根据ClickZetta的权限模型不同Volume类型有不同的权限要求。
This module provides Volume permission checking, validation and management features.
According to ClickZetta's permission model, different Volume types have different permission requirements.
"""
import logging
@@ -12,29 +12,29 @@ logger = logging.getLogger(__name__)
class VolumePermission(Enum):
"""Volume权限类型枚举"""
"""Volume permission type enumeration"""
READ = "SELECT" # 对应ClickZettaSELECT权限
WRITE = "INSERT,UPDATE,DELETE" # 对应ClickZetta的写权限
LIST = "SELECT" # 列出文件需要SELECT权限
DELETE = "INSERT,UPDATE,DELETE" # 删除文件需要写权限
USAGE = "USAGE" # External Volume需要的基本权限
READ = "SELECT" # Corresponds to ClickZetta's SELECT permission
WRITE = "INSERT,UPDATE,DELETE" # Corresponds to ClickZetta's write permissions
LIST = "SELECT" # Listing files requires SELECT permission
DELETE = "INSERT,UPDATE,DELETE" # Deleting files requires write permissions
USAGE = "USAGE" # Basic permission required for External Volume
class VolumePermissionManager:
"""Volume权限管理器"""
"""Volume permission manager"""
def __init__(self, connection_or_config, volume_type: str | None = None, volume_name: Optional[str] = None):
"""初始化权限管理器
"""Initialize permission manager
Args:
connection_or_config: ClickZetta连接对象或配置字典
volume_type: Volume类型 (user|table|external)
volume_name: Volume名称 (用于external volume)
connection_or_config: ClickZetta connection object or configuration dictionary
volume_type: Volume type (user|table|external)
volume_name: Volume name (for external volume)
"""
# 支持两种初始化方式:连接对象或配置字典
# Support two initialization methods: connection object or configuration dictionary
if isinstance(connection_or_config, dict):
# 从配置字典创建连接
# Create connection from configuration dictionary
import clickzetta # type: ignore[import-untyped]
config = connection_or_config
@@ -50,7 +50,7 @@ class VolumePermissionManager:
self._volume_type = config.get("volume_type", volume_type)
self._volume_name = config.get("volume_name", volume_name)
else:
# 直接使用连接对象
# Use connection object directly
self._connection = connection_or_config
self._volume_type = volume_type
self._volume_name = volume_name
@@ -61,14 +61,14 @@ class VolumePermissionManager:
raise ValueError("volume_type is required")
self._permission_cache: dict[str, set[str]] = {}
self._current_username = None # 将从连接中获取当前用户名
self._current_username = None # Will get current username from connection
def check_permission(self, operation: VolumePermission, dataset_id: Optional[str] = None) -> bool:
"""检查用户是否有执行特定操作的权限
"""Check if user has permission to perform specific operation
Args:
operation: 要执行的操作类型
dataset_id: 数据集ID (用于table volume)
operation: Type of operation to perform
dataset_id: Dataset ID (for table volume)
Returns:
True if user has permission, False otherwise
@@ -89,20 +89,20 @@ class VolumePermissionManager:
return False
def _check_user_volume_permission(self, operation: VolumePermission) -> bool:
"""检查User Volume权限
"""Check User Volume permission
User Volume权限规则:
- 用户对自己的User Volume有全部权限
- 只要用户能够连接到ClickZetta就默认具有User Volume的基本权限
- 更注重连接身份验证,而不是复杂的权限检查
User Volume permission rules:
- User has full permissions on their own User Volume
- As long as user can connect to ClickZetta, they have basic User Volume permissions by default
- Focus more on connection authentication rather than complex permission checking
"""
try:
# 获取当前用户名
# Get current username
current_user = self._get_current_username()
# 检查基本连接状态
# Check basic connection status
with self._connection.cursor() as cursor:
# 简单的连接测试,如果能执行查询说明用户有基本权限
# Simple connection test, if query can be executed user has basic permissions
cursor.execute("SELECT 1")
result = cursor.fetchone()
@@ -121,17 +121,17 @@ class VolumePermissionManager:
except Exception as e:
logger.exception("User Volume permission check failed")
# 对于User Volume,如果权限检查失败,可能是配置问题,给出更友好的错误提示
# For User Volume, if permission check fails, it might be a configuration issue, provide friendlier error message
logger.info("User Volume permission check failed, but permission checking is disabled in this version")
return False
def _check_table_volume_permission(self, operation: VolumePermission, dataset_id: Optional[str]) -> bool:
"""检查Table Volume权限
"""Check Table Volume permission
Table Volume权限规则:
- Table Volume权限继承对应表的权限
- SELECT权限 -> 可以READ/LIST文件
- INSERT,UPDATE,DELETE权限 -> 可以WRITE/DELETE文件
Table Volume permission rules:
- Table Volume permissions inherit from corresponding table permissions
- SELECT permission -> can READ/LIST files
- INSERT,UPDATE,DELETE permissions -> can WRITE/DELETE files
"""
if not dataset_id:
logger.warning("dataset_id is required for table volume permission check")
@@ -140,11 +140,11 @@ class VolumePermissionManager:
table_name = f"dataset_{dataset_id}" if not dataset_id.startswith("dataset_") else dataset_id
try:
# 检查表权限
# Check table permissions
permissions = self._get_table_permissions(table_name)
required_permissions = set(operation.value.split(","))
# 检查是否有所需的所有权限
# Check if has all required permissions
has_permission = required_permissions.issubset(permissions)
logger.debug(
@@ -163,22 +163,22 @@ class VolumePermissionManager:
return False
def _check_external_volume_permission(self, operation: VolumePermission) -> bool:
"""检查External Volume权限
"""Check External Volume permission
External Volume权限规则:
- 尝试获取对External Volume的权限
- 如果权限检查失败,进行备选验证
- 对于开发环境,提供更宽松的权限检查
External Volume permission rules:
- Try to get permissions for External Volume
- If permission check fails, perform fallback verification
- For development environment, provide more lenient permission checking
"""
if not self._volume_name:
logger.warning("volume_name is required for external volume permission check")
return False
try:
# 检查External Volume权限
# Check External Volume permissions
permissions = self._get_external_volume_permissions(self._volume_name)
# External Volume权限映射:根据操作类型确定所需权限
# External Volume permission mapping: determine required permissions based on operation type
required_permissions = set()
if operation in [VolumePermission.READ, VolumePermission.LIST]:
@@ -186,7 +186,7 @@ class VolumePermissionManager:
elif operation in [VolumePermission.WRITE, VolumePermission.DELETE]:
required_permissions.add("write")
# 检查是否有所需的所有权限
# Check if has all required permissions
has_permission = required_permissions.issubset(permissions)
logger.debug(
@@ -198,11 +198,11 @@ class VolumePermissionManager:
has_permission,
)
# 如果权限检查失败,尝试备选验证
# If permission check fails, try fallback verification
if not has_permission:
logger.info("Direct permission check failed for %s, trying fallback verification", self._volume_name)
# 备选验证尝试列出Volume来验证基本访问权限
# Fallback verification: try listing Volume to verify basic access permissions
try:
with self._connection.cursor() as cursor:
cursor.execute("SHOW VOLUMES")
@@ -222,13 +222,13 @@ class VolumePermissionManager:
return False
def _get_table_permissions(self, table_name: str) -> set[str]:
"""获取用户对指定表的权限
"""Get user permissions for specified table
Args:
table_name: 表名
table_name: Table name
Returns:
用户对该表的权限集合
Set of user permissions for this table
"""
cache_key = f"table:{table_name}"
@@ -239,18 +239,18 @@ class VolumePermissionManager:
try:
with self._connection.cursor() as cursor:
# 使用正确的ClickZetta语法检查当前用户权限
# Use correct ClickZetta syntax to check current user permissions
cursor.execute("SHOW GRANTS")
grants = cursor.fetchall()
# 解析权限结果,查找对该表的权限
# Parse permission results, find permissions for this table
for grant in grants:
if len(grant) >= 3: # 典型格式: (privilege, object_type, object_name, ...)
if len(grant) >= 3: # Typical format: (privilege, object_type, object_name, ...)
privilege = grant[0].upper()
object_type = grant[1].upper() if len(grant) > 1 else ""
object_name = grant[2] if len(grant) > 2 else ""
# 检查是否是对该表的权限
# Check if it's permission for this table
if (
object_type == "TABLE"
and object_name == table_name
@@ -263,7 +263,7 @@ class VolumePermissionManager:
else:
permissions.add(privilege)
# 如果没有找到明确的权限,尝试执行一个简单的查询来验证权限
# If no explicit permissions found, try executing a simple query to verify permissions
if not permissions:
try:
cursor.execute(f"SELECT COUNT(*) FROM {table_name} LIMIT 1")
@@ -273,15 +273,15 @@ class VolumePermissionManager:
except Exception as e:
logger.warning("Could not check table permissions for %s: %s", table_name, e)
# 安全默认:权限检查失败时拒绝访问
# Safe default: deny access when permission check fails
pass
# 缓存权限信息
# Cache permission information
self._permission_cache[cache_key] = permissions
return permissions
def _get_current_username(self) -> str:
"""获取当前用户名"""
"""Get current username"""
if self._current_username:
return self._current_username
@@ -298,7 +298,7 @@ class VolumePermissionManager:
return "unknown"
def _get_user_permissions(self, username: str) -> set[str]:
"""获取用户的基本权限集合"""
"""Get user's basic permission set"""
cache_key = f"user_permissions:{username}"
if cache_key in self._permission_cache:
@@ -308,17 +308,17 @@ class VolumePermissionManager:
try:
with self._connection.cursor() as cursor:
# 使用正确的ClickZetta语法检查当前用户权限
# Use correct ClickZetta syntax to check current user permissions
cursor.execute("SHOW GRANTS")
grants = cursor.fetchall()
# 解析权限结果,查找用户的基本权限
# Parse permission results, find user's basic permissions
for grant in grants:
if len(grant) >= 3: # 典型格式: (privilege, object_type, object_name, ...)
if len(grant) >= 3: # Typical format: (privilege, object_type, object_name, ...)
privilege = grant[0].upper()
object_type = grant[1].upper() if len(grant) > 1 else ""
# 收集所有相关权限
# Collect all relevant permissions
if privilege in ["SELECT", "INSERT", "UPDATE", "DELETE", "ALL"]:
if privilege == "ALL":
permissions.update(["SELECT", "INSERT", "UPDATE", "DELETE"])
@@ -327,21 +327,21 @@ class VolumePermissionManager:
except Exception as e:
logger.warning("Could not check user permissions for %s: %s", username, e)
# 安全默认:权限检查失败时拒绝访问
# Safe default: deny access when permission check fails
pass
# 缓存权限信息
# Cache permission information
self._permission_cache[cache_key] = permissions
return permissions
def _get_external_volume_permissions(self, volume_name: str) -> set[str]:
"""获取用户对指定External Volume的权限
"""Get user permissions for specified External Volume
Args:
volume_name: External Volume名称
volume_name: External Volume name
Returns:
用户对该Volume的权限集合
Set of user permissions for this Volume
"""
cache_key = f"external_volume:{volume_name}"
@@ -352,15 +352,15 @@ class VolumePermissionManager:
try:
with self._connection.cursor() as cursor:
# 使用正确的ClickZetta语法检查Volume权限
# Use correct ClickZetta syntax to check Volume permissions
logger.info("Checking permissions for volume: %s", volume_name)
cursor.execute(f"SHOW GRANTS ON VOLUME {volume_name}")
grants = cursor.fetchall()
logger.info("Raw grants result for %s: %s", volume_name, grants)
# 解析权限结果
# 格式: (granted_type, privilege, conditions, granted_on, object_name, granted_to,
# Parse permission results
# Format: (granted_type, privilege, conditions, granted_on, object_name, granted_to,
# grantee_name, grantor_name, grant_option, granted_time)
for grant in grants:
logger.info("Processing grant: %s", grant)
@@ -378,7 +378,7 @@ class VolumePermissionManager:
object_name,
)
# 检查是否是对该Volume的权限或者是层级权限
# Check if it's permission for this Volume or hierarchical permission
if (
granted_type == "PRIVILEGE" and granted_on == "VOLUME" and object_name.endswith(volume_name)
) or (granted_type == "OBJECT_HIERARCHY" and granted_on == "VOLUME"):
@@ -399,14 +399,14 @@ class VolumePermissionManager:
logger.info("Final permissions for %s: %s", volume_name, permissions)
# 如果没有找到明确的权限尝试查看Volume列表来验证基本权限
# If no explicit permissions found, try viewing Volume list to verify basic permissions
if not permissions:
try:
cursor.execute("SHOW VOLUMES")
volumes = cursor.fetchall()
for volume in volumes:
if len(volume) > 0 and volume[0] == volume_name:
permissions.add("read") # 至少有读权限
permissions.add("read") # At least has read permission
logger.debug("Volume %s found in SHOW VOLUMES, assuming read permission", volume_name)
break
except Exception:
@@ -414,7 +414,7 @@ class VolumePermissionManager:
except Exception as e:
logger.warning("Could not check external volume permissions for %s: %s", volume_name, e)
# 在权限检查失败时尝试基本的Volume访问验证
# When permission check fails, try basic Volume access verification
try:
with self._connection.cursor() as cursor:
cursor.execute("SHOW VOLUMES")
@@ -423,30 +423,30 @@ class VolumePermissionManager:
if len(volume) > 0 and volume[0] == volume_name:
logger.info("Basic volume access verified for %s", volume_name)
permissions.add("read")
permissions.add("write") # 假设有写权限
permissions.add("write") # Assume has write permission
break
except Exception as basic_e:
logger.warning("Basic volume access check failed for %s: %s", volume_name, basic_e)
# 最后的备选方案:假设有基本权限
# Last fallback: assume basic permissions
permissions.add("read")
# 缓存权限信息
# Cache permission information
self._permission_cache[cache_key] = permissions
return permissions
def clear_permission_cache(self):
"""清空权限缓存"""
"""Clear permission cache"""
self._permission_cache.clear()
logger.debug("Permission cache cleared")
def get_permission_summary(self, dataset_id: Optional[str] = None) -> dict[str, bool]:
"""获取权限摘要
"""Get permission summary
Args:
dataset_id: 数据集ID (用于table volume)
dataset_id: Dataset ID (for table volume)
Returns:
权限摘要字典
Permission summary dictionary
"""
summary = {}
@@ -456,43 +456,43 @@ class VolumePermissionManager:
return summary
def check_inherited_permission(self, file_path: str, operation: VolumePermission) -> bool:
"""检查文件路径的权限继承
"""Check permission inheritance for file path
Args:
file_path: 文件路径
operation: 要执行的操作
file_path: File path
operation: Operation to perform
Returns:
True if user has permission, False otherwise
"""
try:
# 解析文件路径
# Parse file path
path_parts = file_path.strip("/").split("/")
if not path_parts:
logger.warning("Invalid file path for permission inheritance check")
return False
# 对于Table Volume,第一层是dataset_id
# For Table Volume, first layer is dataset_id
if self._volume_type == "table":
if len(path_parts) < 1:
return False
dataset_id = path_parts[0]
# 检查对dataset的权限
# Check permissions for dataset
has_dataset_permission = self.check_permission(operation, dataset_id)
if not has_dataset_permission:
logger.debug("Permission denied for dataset %s", dataset_id)
return False
# 检查路径遍历攻击
# Check path traversal attack
if self._contains_path_traversal(file_path):
logger.warning("Path traversal attack detected: %s", file_path)
return False
# 检查是否访问敏感目录
# Check if accessing sensitive directory
if self._is_sensitive_path(file_path):
logger.warning("Access to sensitive path denied: %s", file_path)
return False
@@ -501,20 +501,20 @@ class VolumePermissionManager:
return True
elif self._volume_type == "user":
# User Volume的权限继承
# User Volume permission inheritance
current_user = self._get_current_username()
# 检查是否试图访问其他用户的目录
# Check if attempting to access other user's directory
if len(path_parts) > 1 and path_parts[0] != current_user:
logger.warning("User %s attempted to access %s's directory", current_user, path_parts[0])
return False
# 检查基本权限
# Check basic permissions
return self.check_permission(operation)
elif self._volume_type == "external":
# External Volume的权限继承
# 检查对External Volume的权限
# External Volume permission inheritance
# Check permissions for External Volume
return self.check_permission(operation)
else:
@@ -526,8 +526,8 @@ class VolumePermissionManager:
return False
def _contains_path_traversal(self, file_path: str) -> bool:
"""检查路径是否包含路径遍历攻击"""
# 检查常见的路径遍历模式
"""Check if path contains path traversal attack"""
# Check common path traversal patterns
traversal_patterns = [
"../",
"..\\",
@@ -547,18 +547,18 @@ class VolumePermissionManager:
if pattern in file_path_lower:
return True
# 检查绝对路径
# Check absolute path
if file_path.startswith("/") or file_path.startswith("\\"):
return True
# 检查Windows驱动器路径
# Check Windows drive path
if len(file_path) >= 2 and file_path[1] == ":":
return True
return False
def _is_sensitive_path(self, file_path: str) -> bool:
"""检查路径是否为敏感路径"""
"""Check if path is sensitive path"""
sensitive_patterns = [
"passwd",
"shadow",
@@ -582,11 +582,11 @@ class VolumePermissionManager:
return any(pattern in file_path_lower for pattern in sensitive_patterns)
def validate_operation(self, operation: str, dataset_id: Optional[str] = None) -> bool:
"""验证操作权限
"""Validate operation permission
Args:
operation: 操作名称 (save|load|exists|delete|scan)
dataset_id: 数据集ID
operation: Operation name (save|load|exists|delete|scan)
dataset_id: Dataset ID
Returns:
True if operation is allowed, False otherwise
@@ -611,7 +611,7 @@ class VolumePermissionManager:
class VolumePermissionError(Exception):
"""Volume权限错误异常"""
"""Volume permission error exception"""
def __init__(self, message: str, operation: str, volume_type: str, dataset_id: Optional[str] = None):
self.operation = operation
@@ -623,15 +623,15 @@ class VolumePermissionError(Exception):
def check_volume_permission(
permission_manager: VolumePermissionManager, operation: str, dataset_id: Optional[str] = None
) -> None:
"""权限检查装饰器函数
"""Permission check decorator function
Args:
permission_manager: 权限管理器
operation: 操作名称
dataset_id: 数据集ID
permission_manager: Permission manager
operation: Operation name
dataset_id: Dataset ID
Raises:
VolumePermissionError: 如果没有权限
VolumePermissionError: If no permission
"""
if not permission_manager.validate_operation(operation, dataset_id):
error_message = f"Permission denied for operation '{operation}' on {permission_manager._volume_type} volume"