fix: auto-fix code issues (cron)

- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题
- 添加类型注解
This commit is contained in:
OpenClaw Bot
2026-02-27 21:12:04 +08:00
parent 17bda3dbce
commit d767f0dddc
27 changed files with 3636 additions and 4158 deletions

View File

@@ -19,6 +19,7 @@ try:
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
CRYPTO_AVAILABLE = True
except ImportError:
CRYPTO_AVAILABLE = False
@@ -27,6 +28,7 @@ except ImportError:
class AuditActionType(Enum):
"""审计动作类型"""
CREATE = "create"
READ = "read"
UPDATE = "update"
@@ -49,26 +51,29 @@ class AuditActionType(Enum):
class DataSensitivityLevel(Enum):
"""数据敏感度级别"""
PUBLIC = "public" # 公开
INTERNAL = "internal" # 内部
PUBLIC = "public" # 公开
INTERNAL = "internal" # 内部
CONFIDENTIAL = "confidential" # 机密
SECRET = "secret" # 绝密
SECRET = "secret" # 绝密
class MaskingRuleType(Enum):
"""脱敏规则类型"""
PHONE = "phone" # 手机号
EMAIL = "email" # 邮箱
ID_CARD = "id_card" # 身份证号
BANK_CARD = "bank_card" # 银行卡
NAME = "name" # 姓名
ADDRESS = "address" # 地址
CUSTOM = "custom" # 自定义
PHONE = "phone" # 手机号
EMAIL = "email" # 邮箱
ID_CARD = "id_card" # 身份证
BANK_CARD = "bank_card" # 银行卡号
NAME = "name" # 姓名
ADDRESS = "address" # 地址
CUSTOM = "custom" # 自定义
@dataclass
class AuditLog:
"""审计日志条目"""
id: str
action_type: str
user_id: str | None = None
@@ -90,6 +95,7 @@ class AuditLog:
@dataclass
class EncryptionConfig:
"""加密配置"""
id: str
project_id: str
is_enabled: bool = False
@@ -107,6 +113,7 @@ class EncryptionConfig:
@dataclass
class MaskingRule:
"""脱敏规则"""
id: str
project_id: str
name: str
@@ -126,6 +133,7 @@ class MaskingRule:
@dataclass
class DataAccessPolicy:
"""数据访问策略"""
id: str
project_id: str
name: str
@@ -147,6 +155,7 @@ class DataAccessPolicy:
@dataclass
class AccessRequest:
"""访问请求(用于需要审批的访问)"""
id: str
policy_id: str
user_id: str
@@ -166,30 +175,15 @@ class SecurityManager:
# 预定义脱敏规则
DEFAULT_MASKING_RULES = {
MaskingRuleType.PHONE: {
"pattern": r"(\d{3})\d{4}(\d{4})",
"replacement": r"\1****\2"
},
MaskingRuleType.EMAIL: {
"pattern": r"(\w{1,3})\w+(@\w+\.\w+)",
"replacement": r"\1***\2"
},
MaskingRuleType.ID_CARD: {
"pattern": r"(\d{6})\d{8}(\d{4})",
"replacement": r"\1********\2"
},
MaskingRuleType.BANK_CARD: {
"pattern": r"(\d{4})\d+(\d{4})",
"replacement": r"\1 **** **** \2"
},
MaskingRuleType.NAME: {
"pattern": r"([\u4e00-\u9fa5])[\u4e00-\u9fa5]+",
"replacement": r"\1**"
},
MaskingRuleType.PHONE: {"pattern": r"(\d{3})\d{4}(\d{4})", "replacement": r"\1****\2"},
MaskingRuleType.EMAIL: {"pattern": r"(\w{1,3})\w+(@\w+\.\w+)", "replacement": r"\1***\2"},
MaskingRuleType.ID_CARD: {"pattern": r"(\d{6})\d{8}(\d{4})", "replacement": r"\1********\2"},
MaskingRuleType.BANK_CARD: {"pattern": r"(\d{4})\d+(\d{4})", "replacement": r"\1 **** **** \2"},
MaskingRuleType.NAME: {"pattern": r"([\u4e00-\u9fa5])[\u4e00-\u9fa5]+", "replacement": r"\1**"},
MaskingRuleType.ADDRESS: {
"pattern": r"([\u4e00-\u9fa5]{2,})([\u4e00-\u9fa5]+路|街|巷|号)(.+)",
"replacement": r"\1\2***"
}
"replacement": r"\1\2***",
},
}
def __init__(self, db_path: str = "insightflow.db"):
@@ -200,7 +194,7 @@ class SecurityManager:
self._local = {}
self._init_db()
def _init_db(self):
def _init_db(self) -> None:
"""初始化数据库表"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
@@ -308,9 +302,7 @@ class SecurityManager:
def _generate_id(self) -> str:
"""生成唯一ID"""
return hashlib.sha256(
f"{datetime.now().isoformat()}{secrets.token_hex(16)}".encode()
).hexdigest()[:32]
return hashlib.sha256(f"{datetime.now().isoformat()}{secrets.token_hex(16)}".encode()).hexdigest()[:32]
# ==================== 审计日志 ====================
@@ -326,7 +318,7 @@ class SecurityManager:
before_value: str | None = None,
after_value: str | None = None,
success: bool = True,
error_message: str | None = None
error_message: str | None = None,
) -> AuditLog:
"""记录审计日志"""
log = AuditLog(
@@ -341,22 +333,34 @@ class SecurityManager:
before_value=before_value,
after_value=after_value,
success=success,
error_message=error_message
error_message=error_message,
)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
INSERT INTO audit_logs
(id, action_type, user_id, user_ip, user_agent, resource_type, resource_id,
action_details, before_value, after_value, success, error_message, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
log.id, log.action_type, log.user_id, log.user_ip, log.user_agent,
log.resource_type, log.resource_id, log.action_details,
log.before_value, log.after_value, int(log.success),
log.error_message, log.created_at
))
""",
(
log.id,
log.action_type,
log.user_id,
log.user_ip,
log.user_agent,
log.resource_type,
log.resource_id,
log.action_details,
log.before_value,
log.after_value,
int(log.success),
log.error_message,
log.created_at,
),
)
conn.commit()
conn.close()
@@ -372,7 +376,7 @@ class SecurityManager:
end_time: str | None = None,
success: bool | None = None,
limit: int = 100,
offset: int = 0
offset: int = 0,
) -> list[AuditLog]:
"""查询审计日志"""
conn = sqlite3.connect(self.db_path)
@@ -429,18 +433,14 @@ class SecurityManager:
after_value=row[9],
success=bool(row[10]),
error_message=row[11],
created_at=row[12]
created_at=row[12],
)
logs.append(log)
conn.close()
return logs
def get_audit_stats(
self,
start_time: str | None = None,
end_time: str | None = None
) -> dict[str, Any]:
def get_audit_stats(self, start_time: str | None = None, end_time: str | None = None) -> dict[str, Any]:
"""获取审计统计"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
@@ -460,12 +460,7 @@ class SecurityManager:
cursor.execute(query, params)
rows = cursor.fetchall()
stats = {
"total_actions": 0,
"success_count": 0,
"failure_count": 0,
"action_breakdown": {}
}
stats = {"total_actions": 0, "success_count": 0, "failure_count": 0, "action_breakdown": {}}
for action_type, success, count in rows:
stats["total_actions"] += count
@@ -500,11 +495,7 @@ class SecurityManager:
)
return base64.urlsafe_b64encode(kdf.derive(password.encode()))
def enable_encryption(
self,
project_id: str,
master_password: str
) -> EncryptionConfig:
def enable_encryption(self, project_id: str, master_password: str) -> EncryptionConfig:
"""启用项目加密"""
if not CRYPTO_AVAILABLE:
raise RuntimeError("cryptography library not available")
@@ -523,43 +514,54 @@ class SecurityManager:
encryption_type="aes-256-gcm",
key_derivation="pbkdf2",
master_key_hash=key_hash,
salt=salt
salt=salt,
)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# 检查是否已存在配置
cursor.execute(
"SELECT id FROM encryption_configs WHERE project_id = ?",
(project_id,)
)
cursor.execute("SELECT id FROM encryption_configs WHERE project_id = ?", (project_id,))
existing = cursor.fetchone()
if existing:
cursor.execute("""
cursor.execute(
"""
UPDATE encryption_configs
SET is_enabled = 1, encryption_type = ?, key_derivation = ?,
master_key_hash = ?, salt = ?, updated_at = ?
WHERE project_id = ?
""", (
config.encryption_type, config.key_derivation,
config.master_key_hash, config.salt,
config.updated_at, project_id
))
""",
(
config.encryption_type,
config.key_derivation,
config.master_key_hash,
config.salt,
config.updated_at,
project_id,
),
)
config.id = existing[0]
else:
cursor.execute("""
cursor.execute(
"""
INSERT INTO encryption_configs
(id, project_id, is_enabled, encryption_type, key_derivation,
master_key_hash, salt, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
config.id, config.project_id, int(config.is_enabled),
config.encryption_type, config.key_derivation,
config.master_key_hash, config.salt,
config.created_at, config.updated_at
))
""",
(
config.id,
config.project_id,
int(config.is_enabled),
config.encryption_type,
config.key_derivation,
config.master_key_hash,
config.salt,
config.created_at,
config.updated_at,
),
)
conn.commit()
conn.close()
@@ -569,16 +571,12 @@ class SecurityManager:
action_type=AuditActionType.ENCRYPTION_ENABLE,
resource_type="project",
resource_id=project_id,
action_details={"encryption_type": config.encryption_type}
action_details={"encryption_type": config.encryption_type},
)
return config
def disable_encryption(
self,
project_id: str,
master_password: str
) -> bool:
def disable_encryption(self, project_id: str, master_password: str) -> bool:
"""禁用项目加密"""
# 验证密码
if not self.verify_encryption_password(project_id, master_password):
@@ -587,29 +585,24 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
UPDATE encryption_configs
SET is_enabled = 0, updated_at = ?
WHERE project_id = ?
""", (datetime.now().isoformat(), project_id))
""",
(datetime.now().isoformat(), project_id),
)
conn.commit()
conn.close()
# 记录审计日志
self.log_audit(
action_type=AuditActionType.ENCRYPTION_DISABLE,
resource_type="project",
resource_id=project_id
)
self.log_audit(action_type=AuditActionType.ENCRYPTION_DISABLE, resource_type="project", resource_id=project_id)
return True
def verify_encryption_password(
self,
project_id: str,
password: str
) -> bool:
def verify_encryption_password(self, project_id: str, password: str) -> bool:
"""验证加密密码"""
if not CRYPTO_AVAILABLE:
return False
@@ -617,10 +610,7 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"SELECT master_key_hash, salt FROM encryption_configs WHERE project_id = ?",
(project_id,)
)
cursor.execute("SELECT master_key_hash, salt FROM encryption_configs WHERE project_id = ?", (project_id,))
row = cursor.fetchone()
conn.close()
@@ -638,10 +628,7 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"SELECT * FROM encryption_configs WHERE project_id = ?",
(project_id,)
)
cursor.execute("SELECT * FROM encryption_configs WHERE project_id = ?", (project_id,))
row = cursor.fetchone()
conn.close()
@@ -657,15 +644,10 @@ class SecurityManager:
master_key_hash=row[5],
salt=row[6],
created_at=row[7],
updated_at=row[8]
updated_at=row[8],
)
def encrypt_data(
self,
data: str,
password: str,
salt: str | None = None
) -> tuple[str, str]:
def encrypt_data(self, data: str, password: str, salt: str | None = None) -> tuple[str, str]:
"""加密数据"""
if not CRYPTO_AVAILABLE:
raise RuntimeError("cryptography library not available")
@@ -679,12 +661,7 @@ class SecurityManager:
return base64.b64encode(encrypted).decode(), salt
def decrypt_data(
self,
encrypted_data: str,
password: str,
salt: str
) -> str:
def decrypt_data(self, encrypted_data: str, password: str, salt: str) -> str:
"""解密数据"""
if not CRYPTO_AVAILABLE:
raise RuntimeError("cryptography library not available")
@@ -705,7 +682,7 @@ class SecurityManager:
pattern: str | None = None,
replacement: str | None = None,
description: str | None = None,
priority: int = 0
priority: int = 0,
) -> MaskingRule:
"""创建脱敏规则"""
# 使用预定义规则或自定义规则
@@ -722,22 +699,33 @@ class SecurityManager:
pattern=pattern or "",
replacement=replacement or "****",
description=description,
priority=priority
priority=priority,
)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
INSERT INTO masking_rules
(id, project_id, name, rule_type, pattern, replacement,
is_active, priority, description, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
rule.id, rule.project_id, rule.name, rule.rule_type,
rule.pattern, rule.replacement, int(rule.is_active),
rule.priority, rule.description, rule.created_at, rule.updated_at
))
""",
(
rule.id,
rule.project_id,
rule.name,
rule.rule_type,
rule.pattern,
rule.replacement,
int(rule.is_active),
rule.priority,
rule.description,
rule.created_at,
rule.updated_at,
),
)
conn.commit()
conn.close()
@@ -747,16 +735,12 @@ class SecurityManager:
action_type=AuditActionType.DATA_MASKING,
resource_type="project",
resource_id=project_id,
action_details={"action": "create_rule", "rule_name": name}
action_details={"action": "create_rule", "rule_name": name},
)
return rule
def get_masking_rules(
self,
project_id: str,
active_only: bool = True
) -> list[MaskingRule]:
def get_masking_rules(self, project_id: str, active_only: bool = True) -> list[MaskingRule]:
"""获取脱敏规则"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
@@ -775,27 +759,25 @@ class SecurityManager:
rules = []
for row in rows:
rules.append(MaskingRule(
id=row[0],
project_id=row[1],
name=row[2],
rule_type=row[3],
pattern=row[4],
replacement=row[5],
is_active=bool(row[6]),
priority=row[7],
description=row[8],
created_at=row[9],
updated_at=row[10]
))
rules.append(
MaskingRule(
id=row[0],
project_id=row[1],
name=row[2],
rule_type=row[3],
pattern=row[4],
replacement=row[5],
is_active=bool(row[6]),
priority=row[7],
description=row[8],
created_at=row[9],
updated_at=row[10],
)
)
return rules
def update_masking_rule(
self,
rule_id: str,
**kwargs
) -> MaskingRule | None:
def update_masking_rule(self, rule_id: str, **kwargs) -> MaskingRule | None:
"""更新脱敏规则"""
allowed_fields = ["name", "pattern", "replacement", "is_active", "priority", "description"]
@@ -818,11 +800,14 @@ class SecurityManager:
params.append(datetime.now().isoformat())
params.append(rule_id)
cursor.execute(f"""
cursor.execute(
f"""
UPDATE masking_rules
SET {', '.join(set_clauses)}
WHERE id = ?
""", params)
""",
params,
)
conn.commit()
conn.close()
@@ -848,7 +833,7 @@ class SecurityManager:
priority=row[7],
description=row[8],
created_at=row[9],
updated_at=row[10]
updated_at=row[10],
)
def delete_masking_rule(self, rule_id: str) -> bool:
@@ -864,12 +849,7 @@ class SecurityManager:
return success
def apply_masking(
self,
text: str,
project_id: str,
rule_types: list[MaskingRuleType] | None = None
) -> str:
def apply_masking(self, text: str, project_id: str, rule_types: list[MaskingRuleType] | None = None) -> str:
"""应用脱敏规则到文本"""
rules = self.get_masking_rules(project_id)
@@ -884,22 +864,14 @@ class SecurityManager:
continue
try:
masked_text = re.sub(
rule.pattern,
rule.replacement,
masked_text
)
masked_text = re.sub(rule.pattern, rule.replacement, masked_text)
except re.error:
# 忽略无效的正则表达式
continue
return masked_text
def apply_masking_to_entity(
self,
entity_data: dict[str, Any],
project_id: str
) -> dict[str, Any]:
def apply_masking_to_entity(self, entity_data: dict[str, Any], project_id: str) -> dict[str, Any]:
"""对实体数据应用脱敏"""
masked_data = entity_data.copy()
@@ -924,7 +896,7 @@ class SecurityManager:
allowed_ips: list[str] | None = None,
time_restrictions: dict | None = None,
max_access_count: int | None = None,
require_approval: bool = False
require_approval: bool = False,
) -> DataAccessPolicy:
"""创建数据访问策略"""
policy = DataAccessPolicy(
@@ -937,36 +909,43 @@ class SecurityManager:
allowed_ips=json.dumps(allowed_ips) if allowed_ips else None,
time_restrictions=json.dumps(time_restrictions) if time_restrictions else None,
max_access_count=max_access_count,
require_approval=require_approval
require_approval=require_approval,
)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
INSERT INTO data_access_policies
(id, project_id, name, description, allowed_users, allowed_roles,
allowed_ips, time_restrictions, max_access_count, require_approval,
is_active, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
policy.id, policy.project_id, policy.name, policy.description,
policy.allowed_users, policy.allowed_roles, policy.allowed_ips,
policy.time_restrictions, policy.max_access_count,
int(policy.require_approval), int(policy.is_active),
policy.created_at, policy.updated_at
))
""",
(
policy.id,
policy.project_id,
policy.name,
policy.description,
policy.allowed_users,
policy.allowed_roles,
policy.allowed_ips,
policy.time_restrictions,
policy.max_access_count,
int(policy.require_approval),
int(policy.is_active),
policy.created_at,
policy.updated_at,
),
)
conn.commit()
conn.close()
return policy
def get_access_policies(
self,
project_id: str,
active_only: bool = True
) -> list[DataAccessPolicy]:
def get_access_policies(self, project_id: str, active_only: bool = True) -> list[DataAccessPolicy]:
"""获取数据访问策略"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
@@ -983,38 +962,34 @@ class SecurityManager:
policies = []
for row in rows:
policies.append(DataAccessPolicy(
id=row[0],
project_id=row[1],
name=row[2],
description=row[3],
allowed_users=row[4],
allowed_roles=row[5],
allowed_ips=row[6],
time_restrictions=row[7],
max_access_count=row[8],
require_approval=bool(row[9]),
is_active=bool(row[10]),
created_at=row[11],
updated_at=row[12]
))
policies.append(
DataAccessPolicy(
id=row[0],
project_id=row[1],
name=row[2],
description=row[3],
allowed_users=row[4],
allowed_roles=row[5],
allowed_ips=row[6],
time_restrictions=row[7],
max_access_count=row[8],
require_approval=bool(row[9]),
is_active=bool(row[10]),
created_at=row[11],
updated_at=row[12],
)
)
return policies
def check_access_permission(
self,
policy_id: str,
user_id: str,
user_ip: str | None = None
self, policy_id: str, user_id: str, user_ip: str | None = None
) -> tuple[bool, str | None]:
"""检查访问权限"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"SELECT * FROM data_access_policies WHERE id = ? AND is_active = 1",
(policy_id,)
)
cursor.execute("SELECT * FROM data_access_policies WHERE id = ? AND is_active = 1", (policy_id,))
row = cursor.fetchone()
conn.close()
@@ -1034,7 +1009,7 @@ class SecurityManager:
require_approval=bool(row[9]),
is_active=bool(row[10]),
created_at=row[11],
updated_at=row[12]
updated_at=row[12],
)
# 检查用户白名单
@@ -1074,11 +1049,14 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
SELECT * FROM access_requests
WHERE policy_id = ? AND user_id = ? AND status = 'approved'
AND (expires_at IS NULL OR expires_at > ?)
""", (policy_id, user_id, datetime.now().isoformat()))
""",
(policy_id, user_id, datetime.now().isoformat()),
)
request = cursor.fetchone()
conn.close()
@@ -1104,11 +1082,7 @@ class SecurityManager:
return ip == pattern
def create_access_request(
self,
policy_id: str,
user_id: str,
request_reason: str | None = None,
expires_hours: int = 24
self, policy_id: str, user_id: str, request_reason: str | None = None, expires_hours: int = 24
) -> AccessRequest:
"""创建访问请求"""
request = AccessRequest(
@@ -1116,21 +1090,28 @@ class SecurityManager:
policy_id=policy_id,
user_id=user_id,
request_reason=request_reason,
expires_at=(datetime.now() + timedelta(hours=expires_hours)).isoformat()
expires_at=(datetime.now() + timedelta(hours=expires_hours)).isoformat(),
)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
INSERT INTO access_requests
(id, policy_id, user_id, request_reason, status, expires_at, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
request.id, request.policy_id, request.user_id,
request.request_reason, request.status, request.expires_at,
request.created_at
))
""",
(
request.id,
request.policy_id,
request.user_id,
request.request_reason,
request.status,
request.expires_at,
request.created_at,
),
)
conn.commit()
conn.close()
@@ -1138,10 +1119,7 @@ class SecurityManager:
return request
def approve_access_request(
self,
request_id: str,
approved_by: str,
expires_hours: int = 24
self, request_id: str, approved_by: str, expires_hours: int = 24
) -> AccessRequest | None:
"""批准访问请求"""
conn = sqlite3.connect(self.db_path)
@@ -1150,11 +1128,14 @@ class SecurityManager:
expires_at = (datetime.now() + timedelta(hours=expires_hours)).isoformat()
approved_at = datetime.now().isoformat()
cursor.execute("""
cursor.execute(
"""
UPDATE access_requests
SET status = 'approved', approved_by = ?, approved_at = ?, expires_at = ?
WHERE id = ?
""", (approved_by, approved_at, expires_at, request_id))
""",
(approved_by, approved_at, expires_at, request_id),
)
conn.commit()
@@ -1175,23 +1156,22 @@ class SecurityManager:
approved_by=row[5],
approved_at=row[6],
expires_at=row[7],
created_at=row[8]
created_at=row[8],
)
def reject_access_request(
self,
request_id: str,
rejected_by: str
) -> AccessRequest | None:
def reject_access_request(self, request_id: str, rejected_by: str) -> AccessRequest | None:
"""拒绝访问请求"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
cursor.execute(
"""
UPDATE access_requests
SET status = 'rejected', approved_by = ?
WHERE id = ?
""", (rejected_by, request_id))
""",
(rejected_by, request_id),
)
conn.commit()
@@ -1211,7 +1191,7 @@ class SecurityManager:
approved_by=row[5],
approved_at=row[6],
expires_at=row[7],
created_at=row[8]
created_at=row[8],
)