mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-02 12:37:35 +08:00
348 lines
13 KiB
Python
348 lines
13 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
完整的多用户数据隔离测试
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import time
|
|
import sqlite3
|
|
from loguru import logger
|
|
|
|
BASE_URL = "http://localhost:8080"
|
|
|
|
def create_test_users():
|
|
"""创建测试用户"""
|
|
logger.info("创建测试用户...")
|
|
|
|
users = [
|
|
{"username": "testuser1", "email": "user1@test.com", "password": "test123456"},
|
|
{"username": "testuser2", "email": "user2@test.com", "password": "test123456"}
|
|
]
|
|
|
|
created_users = []
|
|
|
|
for user in users:
|
|
try:
|
|
# 清理可能存在的用户
|
|
conn = sqlite3.connect('xianyu_data.db')
|
|
cursor = conn.cursor()
|
|
cursor.execute('DELETE FROM users WHERE username = ? OR email = ?', (user['username'], user['email']))
|
|
cursor.execute('DELETE FROM email_verifications WHERE email = ?', (user['email'],))
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
# 生成验证码
|
|
session_id = f"test_{user['username']}_{int(time.time())}"
|
|
|
|
# 生成图形验证码
|
|
captcha_response = requests.post(f"{BASE_URL}/generate-captcha",
|
|
json={'session_id': session_id})
|
|
if not captcha_response.json()['success']:
|
|
logger.error(f"图形验证码生成失败: {user['username']}")
|
|
continue
|
|
|
|
# 获取图形验证码
|
|
conn = sqlite3.connect('xianyu_data.db')
|
|
cursor = conn.cursor()
|
|
cursor.execute('SELECT code FROM captcha_codes WHERE session_id = ? ORDER BY created_at DESC LIMIT 1',
|
|
(session_id,))
|
|
captcha_result = cursor.fetchone()
|
|
conn.close()
|
|
|
|
if not captcha_result:
|
|
logger.error(f"无法获取图形验证码: {user['username']}")
|
|
continue
|
|
|
|
captcha_code = captcha_result[0]
|
|
|
|
# 验证图形验证码
|
|
verify_response = requests.post(f"{BASE_URL}/verify-captcha",
|
|
json={'session_id': session_id, 'captcha_code': captcha_code})
|
|
if not verify_response.json()['success']:
|
|
logger.error(f"图形验证码验证失败: {user['username']}")
|
|
continue
|
|
|
|
# 发送邮箱验证码
|
|
email_response = requests.post(f"{BASE_URL}/send-verification-code",
|
|
json={'email': user['email'], 'session_id': session_id})
|
|
if not email_response.json()['success']:
|
|
logger.error(f"邮箱验证码发送失败: {user['username']}")
|
|
continue
|
|
|
|
# 获取邮箱验证码
|
|
conn = sqlite3.connect('xianyu_data.db')
|
|
cursor = conn.cursor()
|
|
cursor.execute('SELECT code FROM email_verifications WHERE email = ? ORDER BY created_at DESC LIMIT 1',
|
|
(user['email'],))
|
|
email_result = cursor.fetchone()
|
|
conn.close()
|
|
|
|
if not email_result:
|
|
logger.error(f"无法获取邮箱验证码: {user['username']}")
|
|
continue
|
|
|
|
email_code = email_result[0]
|
|
|
|
# 注册用户
|
|
register_response = requests.post(f"{BASE_URL}/register",
|
|
json={
|
|
'username': user['username'],
|
|
'email': user['email'],
|
|
'verification_code': email_code,
|
|
'password': user['password']
|
|
})
|
|
|
|
if register_response.json()['success']:
|
|
logger.info(f"用户注册成功: {user['username']}")
|
|
|
|
# 登录获取token
|
|
login_response = requests.post(f"{BASE_URL}/login",
|
|
json={'username': user['username'], 'password': user['password']})
|
|
|
|
if login_response.json()['success']:
|
|
token = login_response.json()['token']
|
|
user_id = login_response.json()['user_id']
|
|
created_users.append({
|
|
'username': user['username'],
|
|
'user_id': user_id,
|
|
'token': token,
|
|
'headers': {'Authorization': f'Bearer {token}'}
|
|
})
|
|
logger.info(f"用户登录成功: {user['username']}")
|
|
else:
|
|
logger.error(f"用户登录失败: {user['username']}")
|
|
else:
|
|
logger.error(f"用户注册失败: {user['username']} - {register_response.json()['message']}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"创建用户失败: {user['username']} - {e}")
|
|
|
|
return created_users
|
|
|
|
def test_cards_isolation(users):
|
|
"""测试卡券管理的用户隔离"""
|
|
logger.info("测试卡券管理的用户隔离...")
|
|
|
|
if len(users) < 2:
|
|
logger.error("需要至少2个用户进行隔离测试")
|
|
return False
|
|
|
|
user1, user2 = users[0], users[1]
|
|
|
|
# 用户1创建卡券
|
|
card1_data = {
|
|
"name": "用户1的卡券",
|
|
"type": "text",
|
|
"text_content": "这是用户1的卡券内容",
|
|
"description": "用户1创建的测试卡券"
|
|
}
|
|
|
|
response1 = requests.post(f"{BASE_URL}/cards", json=card1_data, headers=user1['headers'])
|
|
if response1.status_code == 200:
|
|
card1_id = response1.json()['id']
|
|
logger.info(f"用户1创建卡券成功: ID={card1_id}")
|
|
else:
|
|
logger.error(f"用户1创建卡券失败: {response1.text}")
|
|
return False
|
|
|
|
# 用户2创建卡券
|
|
card2_data = {
|
|
"name": "用户2的卡券",
|
|
"type": "text",
|
|
"text_content": "这是用户2的卡券内容",
|
|
"description": "用户2创建的测试卡券"
|
|
}
|
|
|
|
response2 = requests.post(f"{BASE_URL}/cards", json=card2_data, headers=user2['headers'])
|
|
if response2.status_code == 200:
|
|
card2_id = response2.json()['id']
|
|
logger.info(f"用户2创建卡券成功: ID={card2_id}")
|
|
else:
|
|
logger.error(f"用户2创建卡券失败: {response2.text}")
|
|
return False
|
|
|
|
# 验证用户1只能看到自己的卡券
|
|
response1_list = requests.get(f"{BASE_URL}/cards", headers=user1['headers'])
|
|
if response1_list.status_code == 200:
|
|
user1_cards = response1_list.json()
|
|
user1_card_names = [card['name'] for card in user1_cards]
|
|
|
|
if "用户1的卡券" in user1_card_names and "用户2的卡券" not in user1_card_names:
|
|
logger.info("✅ 用户1卡券隔离验证通过")
|
|
else:
|
|
logger.error("❌ 用户1卡券隔离验证失败")
|
|
return False
|
|
else:
|
|
logger.error(f"获取用户1卡券列表失败: {response1_list.text}")
|
|
return False
|
|
|
|
# 验证用户2只能看到自己的卡券
|
|
response2_list = requests.get(f"{BASE_URL}/cards", headers=user2['headers'])
|
|
if response2_list.status_code == 200:
|
|
user2_cards = response2_list.json()
|
|
user2_card_names = [card['name'] for card in user2_cards]
|
|
|
|
if "用户2的卡券" in user2_card_names and "用户1的卡券" not in user2_card_names:
|
|
logger.info("✅ 用户2卡券隔离验证通过")
|
|
else:
|
|
logger.error("❌ 用户2卡券隔离验证失败")
|
|
return False
|
|
else:
|
|
logger.error(f"获取用户2卡券列表失败: {response2_list.text}")
|
|
return False
|
|
|
|
# 验证跨用户访问被拒绝
|
|
response_cross = requests.get(f"{BASE_URL}/cards/{card2_id}", headers=user1['headers'])
|
|
if response_cross.status_code == 403 or response_cross.status_code == 404:
|
|
logger.info("✅ 跨用户卡券访问被正确拒绝")
|
|
else:
|
|
logger.error("❌ 跨用户卡券访问未被拒绝")
|
|
return False
|
|
|
|
return True
|
|
|
|
def test_user_settings(users):
|
|
"""测试用户设置功能"""
|
|
logger.info("测试用户设置功能...")
|
|
|
|
if len(users) < 2:
|
|
logger.error("需要至少2个用户进行设置测试")
|
|
return False
|
|
|
|
user1, user2 = users[0], users[1]
|
|
|
|
# 用户1设置主题颜色
|
|
setting1_data = {"value": "#ff0000", "description": "用户1的红色主题"}
|
|
response1 = requests.put(f"{BASE_URL}/user-settings/theme_color",
|
|
json=setting1_data, headers=user1['headers'])
|
|
|
|
if response1.status_code == 200:
|
|
logger.info("用户1主题颜色设置成功")
|
|
else:
|
|
logger.error(f"用户1主题颜色设置失败: {response1.text}")
|
|
return False
|
|
|
|
# 用户2设置主题颜色
|
|
setting2_data = {"value": "#00ff00", "description": "用户2的绿色主题"}
|
|
response2 = requests.put(f"{BASE_URL}/user-settings/theme_color",
|
|
json=setting2_data, headers=user2['headers'])
|
|
|
|
if response2.status_code == 200:
|
|
logger.info("用户2主题颜色设置成功")
|
|
else:
|
|
logger.error(f"用户2主题颜色设置失败: {response2.text}")
|
|
return False
|
|
|
|
# 验证用户1的设置
|
|
response1_get = requests.get(f"{BASE_URL}/user-settings/theme_color", headers=user1['headers'])
|
|
if response1_get.status_code == 200:
|
|
user1_color = response1_get.json()['value']
|
|
if user1_color == "#ff0000":
|
|
logger.info("✅ 用户1主题颜色隔离验证通过")
|
|
else:
|
|
logger.error(f"❌ 用户1主题颜色错误: {user1_color}")
|
|
return False
|
|
else:
|
|
logger.error(f"获取用户1主题颜色失败: {response1_get.text}")
|
|
return False
|
|
|
|
# 验证用户2的设置
|
|
response2_get = requests.get(f"{BASE_URL}/user-settings/theme_color", headers=user2['headers'])
|
|
if response2_get.status_code == 200:
|
|
user2_color = response2_get.json()['value']
|
|
if user2_color == "#00ff00":
|
|
logger.info("✅ 用户2主题颜色隔离验证通过")
|
|
else:
|
|
logger.error(f"❌ 用户2主题颜色错误: {user2_color}")
|
|
return False
|
|
else:
|
|
logger.error(f"获取用户2主题颜色失败: {response2_get.text}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def cleanup_test_data(users):
|
|
"""清理测试数据"""
|
|
logger.info("清理测试数据...")
|
|
|
|
try:
|
|
conn = sqlite3.connect('xianyu_data.db')
|
|
cursor = conn.cursor()
|
|
|
|
# 清理测试用户
|
|
test_usernames = [user['username'] for user in users]
|
|
if test_usernames:
|
|
placeholders = ','.join(['?' for _ in test_usernames])
|
|
cursor.execute(f'DELETE FROM users WHERE username IN ({placeholders})', test_usernames)
|
|
user_count = cursor.rowcount
|
|
else:
|
|
user_count = 0
|
|
|
|
# 清理测试卡券
|
|
cursor.execute('DELETE FROM cards WHERE name LIKE "用户%的卡券"')
|
|
card_count = cursor.rowcount
|
|
|
|
# 清理测试验证码
|
|
cursor.execute('DELETE FROM email_verifications WHERE email LIKE "%@test.com"')
|
|
email_count = cursor.rowcount
|
|
|
|
cursor.execute('DELETE FROM captcha_codes WHERE session_id LIKE "test_%"')
|
|
captcha_count = cursor.rowcount
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
logger.info(f"清理完成: 用户{user_count}个, 卡券{card_count}个, 邮箱验证码{email_count}个, 图形验证码{captcha_count}个")
|
|
|
|
except Exception as e:
|
|
logger.error(f"清理失败: {e}")
|
|
|
|
def main():
|
|
"""主测试函数"""
|
|
print("🚀 完整的多用户数据隔离测试")
|
|
print("=" * 60)
|
|
|
|
try:
|
|
# 创建测试用户
|
|
users = create_test_users()
|
|
|
|
if len(users) < 2:
|
|
print("❌ 测试失败:无法创建足够的测试用户")
|
|
return False
|
|
|
|
print(f"✅ 成功创建 {len(users)} 个测试用户")
|
|
|
|
# 测试卡券管理隔离
|
|
cards_success = test_cards_isolation(users)
|
|
|
|
# 测试用户设置
|
|
settings_success = test_user_settings(users)
|
|
|
|
# 清理测试数据
|
|
cleanup_test_data(users)
|
|
|
|
print("\n" + "=" * 60)
|
|
if cards_success and settings_success:
|
|
print("🎉 完整的多用户数据隔离测试全部通过!")
|
|
|
|
print("\n📋 测试总结:")
|
|
print("✅ 卡券管理完全隔离")
|
|
print("✅ 用户设置完全隔离")
|
|
print("✅ 跨用户访问被正确拒绝")
|
|
print("✅ 数据库层面用户绑定正确")
|
|
|
|
return True
|
|
else:
|
|
print("❌ 多用户数据隔离测试失败!")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"💥 测试异常: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
main()
|