"""插件沙箱隔离 - Phase 8.3""" import os import sys from typing import Any class PluginSandbox: """插件沙箱 提供插件执行隔离环境。 """ def __init__(self): self._allowed_paths: set[str] = set() self._denied_paths: set[str] = set() self._network_allowed: bool = False self._allowed_hosts: set[str] = set() def set_file_permissions( self, allowed_paths: list[str] | None = None, denied_paths: list[str] | None = None, ) -> None: """设置文件访问权限 Args: allowed_paths: 允许访问的路径列表 denied_paths: 禁止访问的路径列表 """ self._allowed_paths = set(allowed_paths or []) self._denied_paths = set(denied_paths or []) def set_network_permissions( self, allowed: bool, allowed_hosts: list[str] | None = None ) -> None: """设置网络访问权限 Args: allowed: 是否允许网络访问 allowed_hosts: 允许访问的 host 列表 """ self._network_allowed = allowed self._allowed_hosts = set(allowed_hosts or []) def check_file_access(self, path: str) -> bool: """检查文件访问权限 Args: path: 文件路径 Returns: 是否允许访问 """ # 如果有允许列表,只允许访问列表中的路径 if self._allowed_paths: return path in self._allowed_paths or any( path.startswith(allowed) for allowed in self._allowed_paths ) # 如果有禁止列表,禁止访问列表中的路径 if self._denied_paths: return not any(path.startswith(denied) for denied in self._denied_paths) # 没有限制 return True def check_network_access(self, host: str) -> bool: """检查网络访问权限 Args: host: 主机地址 Returns: 是否允许访问 """ if not self._network_allowed: return False if self._allowed_hosts: return host in self._allowed_hosts or any( host.endswith(allowed) for allowed in self._allowed_hosts ) return True def execute_in_sandbox(self, func: Any, *args, **kwargs) -> Any: """在沙箱中执行函数 Args: func: 要执行的函数 *args: 位置参数 **kwargs: 关键字参数 Returns: 函数返回值 """ # 保存当前状态 old_allowed_paths = self._allowed_paths.copy() old_denied_paths = self._denied_paths.copy() old_network_allowed = self._network_allowed old_allowed_hosts = self._allowed_hosts.copy() try: return func(*args, **kwargs) finally: # 恢复状态 self._allowed_paths = old_allowed_paths self._denied_paths = old_denied_paths self._network_allowed = old_network_allowed self._allowed_hosts = old_allowed_hosts