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,281 @@
"""
安全测试模块 - TDD Red阶段
测试SQL注入、XSS、CSRF等安全防护功能。
"""
import pytest
import allure
from typing import Any, Dict, List
@allure.epic("核心框架")
@allure.feature("安全测试模块 - TDD Red阶段")
class TestSecurityModule:
"""安全测试模块测试类 - TDD Red阶段(期望失败)"""
@allure.title("测试SQL注入检测 - TDD Red阶段")
@allure.description("验证SQL注入攻击检测和防护 - 期望失败(Red)")
@allure.severity(allure.severity_level.CRITICAL)
@pytest.mark.smoke
def test_sql_injection_detection(self) -> None:
"""
TDD Red阶段: 测试SQL注入检测
预期结果:
- 能够检测常见的SQL注入攻击
- 返回检测结果和风险等级
"""
from core.security import SQLInjectionDetector
with allure.step("Step 1: 创建SQL注入检测器"):
detector = SQLInjectionDetector()
allure.attach("✅ 创建SQL注入检测器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 测试常见SQL注入攻击"):
test_cases = [
("' OR '1'='1", True),
("'; DROP TABLE users; --", True),
("1' AND 1=1 --", True),
("normal_username", False),
("user@example.com", False),
]
for input_str, expected in test_cases:
result = detector.detect(input_str)
allure.attach(
f"输入: {input_str}, 检测结果: {result.is_injection}, 期望: {expected}",
"步骤2",
allure.attachment_type.TEXT
)
assert result.is_injection == expected, f"检测失败: {input_str}"
@allure.title("测试XSS攻击检测 - TDD Red阶段")
@allure.description("验证XSS攻击检测和防护 - 期望失败(Red)")
@allure.severity(allure.severity_level.CRITICAL)
@pytest.mark.smoke
def test_xss_detection(self) -> None:
"""
TDD Red阶段: 测试XSS攻击检测
预期结果:
- 能够检测常见的XSS攻击
- 支持多种XSS类型检测
"""
from core.security import XSSDetector
with allure.step("Step 1: 创建XSS检测器"):
detector = XSSDetector()
allure.attach("✅ 创建XSS检测器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 测试常见XSS攻击"):
test_cases = [
("<script>alert('xss')</script>", True),
("<img src=x onerror=alert('xss')>", True),
("javascript:alert('xss')", True),
("<div>正常内容</div>", False),
("普通文本", False),
]
for input_str, expected in test_cases:
result = detector.detect(input_str)
allure.attach(
f"输入: {input_str[:30]}..., 检测结果: {result.is_xss}, 期望: {expected}",
"步骤2",
allure.attachment_type.TEXT
)
assert result.is_xss == expected, f"检测失败: {input_str}"
@allure.title("测试CSRF防护 - TDD Red阶段")
@allure.description("验证CSRF防护机制 - 期望失败(Red)")
@allure.severity(allure.severity_level.CRITICAL)
@pytest.mark.smoke
def test_csrf_protection(self) -> None:
"""
TDD Red阶段: 测试CSRF防护
预期结果:
- 能够生成和验证CSRF Token
- 防止跨站请求伪造攻击
"""
from core.security import CSRFProtector
with allure.step("Step 1: 创建CSRF防护器"):
protector = CSRFProtector()
allure.attach("✅ 创建CSRF防护器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 生成CSRF Token"):
token = protector.generate_token("user123")
allure.attach(f"生成Token: {token[:20]}...", "步骤2", allure.attachment_type.TEXT)
assert token is not None and len(token) > 0, "Token生成失败"
with allure.step("Step 3: 验证有效Token"):
is_valid = protector.validate_token("user123", token)
allure.attach(f"验证结果: {is_valid}", "步骤3", allure.attachment_type.TEXT)
assert is_valid is True, "有效Token验证失败"
with allure.step("Step 4: 验证无效Token"):
is_valid = protector.validate_token("user123", "invalid_token")
allure.attach(f"验证结果: {is_valid}", "步骤4", allure.attachment_type.TEXT)
assert is_valid is False, "无效Token应该验证失败"
@allure.title("测试输入净化 - TDD Red阶段")
@allure.description("验证输入数据净化功能 - 期望失败(Red)")
@allure.severity(allure.severity_level.NORMAL)
@pytest.mark.regression
def test_input_sanitization(self) -> None:
"""
TDD Red阶段: 测试输入净化
预期结果:
- 能够移除或转义危险字符
- 保持合法输入不变
"""
from core.security import InputSanitizer
with allure.step("Step 1: 创建输入净化器"):
sanitizer = InputSanitizer()
allure.attach("✅ 创建输入净化器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 测试HTML净化"):
test_cases = [
("<script>alert('xss')</script>", ""),
("<p>正常段落</p>", "<p>正常段落</p>"),
("<img src=x onerror=alert('xss')>", "<img src=x>"),
]
for input_str, expected in test_cases:
result = sanitizer.sanitize_html(input_str)
allure.attach(
f"输入: {input_str[:30]}..., 输出: {result[:30]}...",
"步骤2",
allure.attachment_type.TEXT
)
@allure.title("测试密码强度检查 - TDD Red阶段")
@allure.description("验证密码强度评估功能 - 期望失败(Red)")
@allure.severity(allure.severity_level.NORMAL)
@pytest.mark.regression
def test_password_strength(self) -> None:
"""
TDD Red阶段: 测试密码强度检查
预期结果:
- 能够评估密码强度
- 返回强度等级和建议
"""
from core.security import PasswordStrengthChecker
with allure.step("Step 1: 创建密码强度检查器"):
checker = PasswordStrengthChecker()
allure.attach("✅ 创建密码强度检查器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 测试不同强度密码"):
test_cases = [
("123", "weak"),
("password", "weak"),
("Password123", "medium"),
("P@ssw0rd!2024", "strong"),
]
for password, expected_min_strength in test_cases:
result = checker.check(password)
allure.attach(
f"密码: {password[:10]}..., 强度: {result.strength}",
"步骤2",
allure.attachment_type.TEXT
)
assert result.score > 0, "密码评分应该大于0"
@allure.title("测试安全头部设置 - TDD Red阶段")
@allure.description("验证HTTP安全头部设置 - 期望失败(Red)")
@allure.severity(allure.severity_level.NORMAL)
@pytest.mark.regression
def test_security_headers(self) -> None:
"""
TDD Red阶段: 测试安全头部设置
预期结果:
- 能够生成安全HTTP头部
- 包含必要的安全策略
"""
from core.security import SecurityHeaders
with allure.step("Step 1: 创建安全头部生成器"):
headers = SecurityHeaders()
allure.attach("✅ 创建安全头部生成器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 获取安全头部"):
security_headers = headers.get_headers()
allure.attach(f"安全头部: {security_headers}", "步骤2", allure.attachment_type.TEXT)
assert "X-Content-Type-Options" in security_headers, "缺少X-Content-Type-Options"
assert "X-Frame-Options" in security_headers, "缺少X-Frame-Options"
assert "X-XSS-Protection" in security_headers, "缺少X-XSS-Protection"
@allure.title("测试安全审计日志 - TDD Red阶段")
@allure.description("验证安全事件审计日志 - 期望失败(Red)")
@allure.severity(allure.severity_level.NORMAL)
@pytest.mark.regression
def test_security_audit_log(self) -> None:
"""
TDD Red阶段: 测试安全审计日志
预期结果:
- 能够记录安全事件
- 支持查询和统计
"""
from core.security import SecurityAuditLogger
with allure.step("Step 1: 创建安全审计日志器"):
logger = SecurityAuditLogger()
allure.attach("✅ 创建安全审计日志器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 记录安全事件"):
logger.log_event(
event_type="SQL_INJECTION_ATTEMPT",
source_ip="192.168.1.1",
details={"input": "' OR '1'='1"}
)
logger.log_event(
event_type="XSS_ATTEMPT",
source_ip="192.168.1.2",
details={"input": "<script>alert('xss')</script>"}
)
allure.attach("✅ 记录2个安全事件", "步骤2", allure.attachment_type.TEXT)
with allure.step("Step 3: 查询安全事件"):
events = logger.get_events()
allure.attach(f"事件数量: {len(events)}", "步骤3", allure.attachment_type.TEXT)
assert len(events) == 2, "应该有2个安全事件"
@allure.title("测试综合安全扫描 - TDD Red阶段")
@allure.description("验证综合安全扫描功能 - 期望失败(Red)")
@allure.severity(allure.severity_level.CRITICAL)
@pytest.mark.smoke
def test_comprehensive_security_scan(self) -> None:
"""
TDD Red阶段: 测试综合安全扫描
预期结果:
- 能够扫描多种安全威胁
- 返回详细的扫描报告
"""
from core.security import SecurityScanner
with allure.step("Step 1: 创建安全扫描器"):
scanner = SecurityScanner()
allure.attach("✅ 创建安全扫描器", "步骤1", allure.attachment_type.TEXT)
with allure.step("Step 2: 扫描测试数据"):
test_data = {
"username": "' OR '1'='1",
"comment": "<script>alert('xss')</script>",
"email": "test@example.com",
}
report = scanner.scan(test_data)
allure.attach(f"扫描报告: {report}", "步骤2", allure.attachment_type.TEXT)
assert report.total_scanned > 0, "应该扫描了数据"
assert len(report.threats) > 0, "应该检测到威胁"