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 = [ "", "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 world!" var sanitized = SecurityManager.sanitize_input(html_input) assert_false(sanitized.contains(""), "HTML tags should be removed") assert_false(sanitized.contains(""), "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")