创建新工程

This commit is contained in:
moyin
2025-12-05 19:00:14 +08:00
commit ff4fa5fffd
227 changed files with 32804 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
extends GutTest
## 安全管理器测试
## 测试安全验证、输入过滤和防护措施
var security_manager: SecurityManager
func before_each():
"""每个测试前的设置"""
security_manager = SecurityManager.new()
func after_each():
"""每个测试后的清理"""
if security_manager:
security_manager.queue_free()
## 测试输入验证 - 有效输入
func test_validate_input_valid():
"""测试有效输入的验证"""
# 测试有效用户名
var result = SecurityManager.validate_input("TestUser123", "username")
assert_true(result.valid, "Valid username should pass validation")
assert_eq(result.sanitized, "TestUser123", "Valid username should not be modified")
# 测试有效角色名
result = SecurityManager.validate_input("MyCharacter", "character_name")
assert_true(result.valid, "Valid character name should pass validation")
assert_eq(result.sanitized, "MyCharacter", "Valid character name should not be modified")
# 测试有效消息
result = SecurityManager.validate_input("Hello, world!", "message")
assert_true(result.valid, "Valid message should pass validation")
assert_eq(result.sanitized, "Hello, world!", "Valid message should not be modified")
## 测试输入验证 - 无效输入
func test_validate_input_invalid():
"""测试无效输入的验证"""
# 测试空输入
var result = SecurityManager.validate_input("", "username")
assert_false(result.valid, "Empty username should fail validation")
assert_true(result.error.length() > 0, "Should provide error message")
# 测试过长输入
var long_string = "a".repeat(100)
result = SecurityManager.validate_input(long_string, "character_name")
assert_false(result.valid, "Overly long character name should fail validation")
# 测试过短角色名
result = SecurityManager.validate_input("a", "character_name")
assert_false(result.valid, "Too short character name should fail validation")
## 测试恶意内容检测
func test_malicious_content_detection():
"""测试恶意内容检测"""
# 测试脚本注入
var malicious_inputs = [
"<script>alert('xss')</script>",
"javascript:alert('xss')",
"onload=alert('xss')",
"eval(malicious_code)",
"document.cookie"
]
for malicious_input in malicious_inputs:
var result = SecurityManager.validate_input(malicious_input, "message")
assert_false(result.valid, "Malicious input should be rejected: " + malicious_input)
assert_true(result.error.contains("不安全内容"), "Should indicate unsafe content")
## 测试SQL注入检测
func test_sql_injection_detection():
"""测试SQL注入检测"""
var injection_inputs = [
"'; DROP TABLE users; --",
"' OR '1'='1",
"UNION SELECT * FROM passwords",
"INSERT INTO users VALUES"
]
for injection_input in injection_inputs:
var result = SecurityManager.validate_input(injection_input, "message")
assert_false(result.valid, "SQL injection should be rejected: " + injection_input)
## 测试过度重复字符检测
func test_excessive_repetition_detection():
"""测试过度重复字符检测"""
# 创建70%重复字符的字符串
var repetitive_string = "a".repeat(70) + "b".repeat(30)
var result = SecurityManager.validate_input(repetitive_string, "message")
assert_false(result.valid, "Excessive repetition should be rejected")
assert_true(result.error.contains("重复字符"), "Should indicate repetition issue")
## 测试输入清理
func test_input_sanitization():
"""测试输入清理功能"""
# 测试HTML标签移除
var html_input = "Hello <b>world</b>!"
var sanitized = SecurityManager.sanitize_input(html_input)
assert_false(sanitized.contains("<b>"), "HTML tags should be removed")
assert_false(sanitized.contains("</b>"), "HTML tags should be removed")
assert_true(sanitized.contains("Hello"), "Text content should be preserved")
assert_true(sanitized.contains("world"), "Text content should be preserved")
# 测试多余空格处理
var spaced_input = "Hello world !"
sanitized = SecurityManager.sanitize_input(spaced_input)
assert_false(sanitized.contains(" "), "Multiple spaces should be reduced")
assert_true(sanitized.contains("Hello world"), "Should contain single spaces")
## 测试消息格式验证
func test_message_format_validation():
"""测试网络消息格式验证"""
# 测试有效消息
var valid_message = {
"type": "auth_request",
"data": {"username": "test"},
"timestamp": Time.get_unix_time_from_system()
}
assert_true(SecurityManager.validate_message_format(valid_message), "Valid message should pass")
# 测试缺少字段的消息
var invalid_message = {
"type": "auth_request"
# 缺少 data 和 timestamp
}
assert_false(SecurityManager.validate_message_format(invalid_message), "Invalid message should fail")
# 测试无效消息类型
var invalid_type_message = {
"type": "malicious_type",
"data": {},
"timestamp": Time.get_unix_time_from_system()
}
assert_false(SecurityManager.validate_message_format(invalid_type_message), "Invalid message type should fail")
# 测试时间戳过旧
var old_message = {
"type": "auth_request",
"data": {},
"timestamp": Time.get_unix_time_from_system() - 400 # 超过5分钟
}
assert_false(SecurityManager.validate_message_format(old_message), "Old timestamp should fail")
## 测试会话管理
func test_session_management():
"""测试会话管理功能"""
# 创建会话
var session_token = security_manager.create_session("client123", "testuser")
assert_true(session_token.length() > 0, "Should generate session token")
# 验证会话
assert_true(security_manager.validate_session(session_token), "New session should be valid")
# 使会话无效
security_manager.invalidate_session(session_token)
assert_false(security_manager.validate_session(session_token), "Invalidated session should be invalid")
## 测试失败尝试记录
func test_failed_attempt_recording():
"""测试失败尝试记录和锁定机制"""
var client_id = "test_client"
# 记录多次失败尝试
for i in range(4): # 4次失败还未达到锁定阈值
var should_lock = security_manager.record_failed_attempt(client_id)
assert_false(should_lock, "Should not lock before reaching max attempts")
# 第5次失败应该触发锁定
var should_lock = security_manager.record_failed_attempt(client_id)
assert_true(should_lock, "Should lock after max failed attempts")
# 检查锁定状态
assert_true(security_manager.is_locked(client_id), "Client should be locked")
# 清除失败尝试
security_manager.clear_failed_attempts(client_id)
assert_false(security_manager.is_locked(client_id), "Client should be unlocked after clearing attempts")
## 测试安全统计
func test_security_statistics():
"""测试安全统计功能"""
# 创建一些会话和失败尝试
security_manager.create_session("client1", "user1")
security_manager.create_session("client2", "user2")
security_manager.record_failed_attempt("client3")
var stats = security_manager.get_security_stats()
assert_true(stats.has("active_sessions"), "Stats should include active sessions")
assert_true(stats.has("failed_attempts"), "Stats should include failed attempts")
assert_true(stats.has("locked_clients"), "Stats should include locked clients")
assert_eq(stats.active_sessions, 2, "Should have 2 active sessions")
assert_eq(stats.failed_attempts, 1, "Should have 1 failed attempt record")
## 测试会话超时
func test_session_timeout():
"""测试会话超时机制"""
# 创建会话
var session_token = security_manager.create_session("client123", "testuser")
# 修改会话超时时间为很短的时间进行测试
security_manager.session_timeout = 0.1 # 0.1秒
# 等待超时
await get_tree().create_timer(0.2).timeout
# 验证会话应该已过期
assert_false(security_manager.validate_session(session_token), "Session should expire after timeout")
## 测试边界情况
func test_edge_cases():
"""测试边界情况"""
# 测试null输入
var result = SecurityManager.validate_input(null, "username")
assert_false(result.valid, "Null input should be rejected")
# 测试空白字符输入
result = SecurityManager.validate_input(" ", "character_name")
assert_false(result.valid, "Whitespace-only input should be rejected")
# 测试边界长度
var min_length_name = "ab" # 最小长度
result = SecurityManager.validate_input(min_length_name, "character_name")
assert_true(result.valid, "Minimum length name should be valid")
var max_length_name = "a".repeat(20) # 最大长度
result = SecurityManager.validate_input(max_length_name, "character_name")
assert_true(result.valid, "Maximum length name should be valid")