feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
@@ -0,0 +1,284 @@
"""
API测试器核心模块
"""
import requests
import time
from typing import Dict, Any, Optional, List
from dataclasses import dataclass, field
from .validation import ValidationEngine, ValidationRule
from .auth_manager import AuthManager
from config.settings import config
from utils.logger import TestLogger
from utils.reporter import TestResult as ReportTestResult, TestSummary
@dataclass
class TestResult:
"""测试结果"""
passed: bool
test_name: str
error_message: str = ""
response_time: float = 0.0
status_code: int = 0
request_data: Dict[str, Any] = field(default_factory=dict)
response_data: Dict[str, Any] = field(default_factory=dict)
class APITester:
"""API测试器"""
def __init__(self, logger: TestLogger = None, auto_auth: bool = True):
"""
初始化API测试器
Args:
logger: 日志记录器
auto_auth: 是否自动认证
"""
self.logger = logger or TestLogger("api_tester", config.logging_file, config.logging_level)
self.session = requests.Session()
self.auth_manager = AuthManager(self.logger)
self.validation_engine = ValidationEngine()
self.auto_auth = auto_auth
# 配置会话
self.session.headers.update({
"Content-Type": "application/json",
"Accept": "application/json"
})
# 如果启用自动认证,尝试登录
if auto_auth:
self._ensure_authenticated()
def _ensure_authenticated(self) -> bool:
"""
确保已认证
Returns:
是否认证成功
"""
return self.auth_manager.ensure_authenticated()
def _update_auth_header(self) -> None:
"""更新认证请求头"""
auth_header = self.auth_manager.get_auth_header(auto_refresh=True)
self.session.headers.update(auth_header)
def set_token(self, token: str) -> None:
"""
设置认证令牌(已弃用,建议使用AuthManager
Args:
token: JWT令牌
"""
self.logger.warning("set_token方法已弃用,建议使用AuthManager")
self.session.headers.update({
"Authorization": f"Bearer {token}"
})
self.logger.info(f"已设置认证令牌")
def clear_token(self) -> None:
"""清除认证令牌(已弃用,建议使用AuthManager"""
self.logger.warning("clear_token方法已弃用,建议使用AuthManager")
self.session.headers.pop("Authorization", None)
self.logger.info(f"已清除认证令牌")
def login(self, username: str = None, password: str = None) -> bool:
"""
用户登录
Args:
username: 用户名
password: 密码
Returns:
是否登录成功
"""
return self.auth_manager.login(username, password)
def request(
self,
method: str,
endpoint: str,
data: Dict[str, Any] = None,
params: Dict[str, Any] = None,
headers: Dict[str, str] = None,
expected_status: int = 200,
test_name: str = None,
require_auth: bool = True
) -> TestResult:
"""
发送HTTP请求
Args:
method: HTTP方法(GET, POST, PUT, DELETE
endpoint: API端点
data: 请求体数据
params: URL参数
headers: 请求头
expected_status: 期望的状态码
test_name: 测试名称
require_auth: 是否需要认证
Returns:
测试结果
"""
if test_name is None:
test_name = f"{method} {endpoint}"
url = f"{config.api_base_url}{endpoint}"
# 如果需要认证,确保已认证并更新认证头
if require_auth and self.auto_auth:
if not self._ensure_authenticated():
return TestResult(
passed=False,
test_name=test_name,
error_message="认证失败"
)
self._update_auth_header()
self.logger.log_test_start(test_name)
self.logger.log_request(method, url, data, headers)
try:
start_time = time.time()
if method.upper() == "GET":
response = self.session.get(
url,
params=params,
headers=headers,
timeout=config.api_timeout
)
elif method.upper() == "POST":
response = self.session.post(
url,
json=data,
params=params,
headers=headers,
timeout=config.api_timeout
)
elif method.upper() == "PUT":
response = self.session.put(
url,
json=data,
params=params,
headers=headers,
timeout=config.api_timeout
)
elif method.upper() == "DELETE":
response = self.session.delete(
url,
params=params,
headers=headers,
timeout=config.api_timeout
)
else:
raise ValueError(f"不支持的HTTP方法: {method}")
response_time = (time.time() - start_time) * 1000
try:
response_data = response.json()
except:
response_data = {"raw": response.text}
self.logger.log_response(response.status_code, response_time, response_data)
# 验证状态码
passed, error = self.validation_engine.validate_status_code(expected_status, response.status_code)
if passed:
self.logger.log_test_end(test_name, True, response_time)
return TestResult(
passed=True,
test_name=test_name,
response_time=response_time,
status_code=response.status_code,
request_data=data or params or {},
response_data=response_data
)
else:
self.logger.log_test_end(test_name, False, response_time)
return TestResult(
passed=False,
test_name=test_name,
error_message=error,
response_time=response_time,
status_code=response.status_code,
request_data=data or params or {},
response_data=response_data
)
except requests.exceptions.Timeout:
error_msg = "请求超时"
self.logger.error(f"{test_name} - {error_msg}")
return TestResult(
passed=False,
test_name=test_name,
error_message=error_msg,
response_time=config.api_timeout * 1000
)
except requests.exceptions.ConnectionError:
error_msg = "连接错误"
self.logger.error(f"{test_name} - {error_msg}")
return TestResult(
passed=False,
test_name=test_name,
error_message=error_msg
)
except Exception as e:
self.logger.log_error(e)
return TestResult(
passed=False,
test_name=test_name,
error_message=f"未知错误: {str(e)}"
)
def validate(
self,
test_result: TestResult,
validation_rules: List[ValidationRule]
) -> TestResult:
"""
验证测试结果
Args:
test_result: 测试结果
validation_rules: 验证规则列表
Returns:
验证后的测试结果
"""
if not test_result.passed:
return test_result
for rule in validation_rules:
if rule.rule_type == "status_code":
passed, error = rule.validate(test_result.status_code)
elif rule.rule_type == "response_time":
passed, error = rule.validate(test_result.response_time)
elif rule.rule_type in ["contains", "equals", "json_path", "regex", "header", "schema"]:
passed, error = rule.validate(actual_data=test_result.response_data)
else:
passed, error = False, f"未知的验证规则: {rule.rule_type}"
self.logger.log_validation(rule.rule_type, passed, error)
if not passed:
test_result.passed = False
test_result.error_message = error
break
return test_result
def close(self) -> None:
"""关闭会话"""
self.session.close()
self.logger.info("已关闭测试会话")