mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-02 12:37:35 +08:00
334 lines
13 KiB
Python
334 lines
13 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
完整的多用户数据隔离测试
|
||
"""
|
||
|
||
import requests
|
||
import json
|
||
import sqlite3
|
||
import time
|
||
|
||
BASE_URL = "http://localhost:8080"
|
||
|
||
def create_test_users():
|
||
"""创建测试用户"""
|
||
print("🧪 创建测试用户")
|
||
print("-" * 40)
|
||
|
||
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']:
|
||
print(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:
|
||
print(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']:
|
||
print(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']:
|
||
print(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:
|
||
print(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']:
|
||
print(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}'}
|
||
})
|
||
print(f" ✅ {user['username']}: 登录成功,用户ID: {user_id}")
|
||
else:
|
||
print(f" ❌ {user['username']}: 登录失败")
|
||
else:
|
||
print(f" ❌ {user['username']}: 注册失败 - {register_response.json()['message']}")
|
||
|
||
except Exception as e:
|
||
print(f" ❌ {user['username']}: 创建失败 - {e}")
|
||
|
||
return created_users
|
||
|
||
def test_cookie_isolation(users):
|
||
"""测试Cookie数据隔离"""
|
||
print("\n🧪 测试Cookie数据隔离")
|
||
print("-" * 40)
|
||
|
||
if len(users) < 2:
|
||
print("❌ 需要至少2个用户进行隔离测试")
|
||
return False
|
||
|
||
user1, user2 = users[0], users[1]
|
||
|
||
# 用户1添加cookies
|
||
print(f"1️⃣ {user1['username']} 添加cookies...")
|
||
cookies1 = [
|
||
{"id": "test_cookie_user1_1", "value": "cookie_value_1"},
|
||
{"id": "test_cookie_user1_2", "value": "cookie_value_2"}
|
||
]
|
||
|
||
for cookie in cookies1:
|
||
response = requests.post(f"{BASE_URL}/cookies",
|
||
json=cookie,
|
||
headers=user1['headers'])
|
||
if response.status_code == 200:
|
||
print(f" ✅ 添加cookie: {cookie['id']}")
|
||
else:
|
||
print(f" ❌ 添加cookie失败: {cookie['id']}")
|
||
|
||
# 用户2添加cookies
|
||
print(f"\n2️⃣ {user2['username']} 添加cookies...")
|
||
cookies2 = [
|
||
{"id": "test_cookie_user2_1", "value": "cookie_value_3"},
|
||
{"id": "test_cookie_user2_2", "value": "cookie_value_4"}
|
||
]
|
||
|
||
for cookie in cookies2:
|
||
response = requests.post(f"{BASE_URL}/cookies",
|
||
json=cookie,
|
||
headers=user2['headers'])
|
||
if response.status_code == 200:
|
||
print(f" ✅ 添加cookie: {cookie['id']}")
|
||
else:
|
||
print(f" ❌ 添加cookie失败: {cookie['id']}")
|
||
|
||
# 验证用户1只能看到自己的cookies
|
||
print(f"\n3️⃣ 验证 {user1['username']} 的cookie隔离...")
|
||
response1 = requests.get(f"{BASE_URL}/cookies", headers=user1['headers'])
|
||
if response1.status_code == 200:
|
||
user1_cookies = response1.json()
|
||
user1_cookie_ids = set(user1_cookies)
|
||
expected_user1 = {"test_cookie_user1_1", "test_cookie_user1_2"}
|
||
|
||
if expected_user1.issubset(user1_cookie_ids):
|
||
print(f" ✅ {user1['username']} 能看到自己的cookies")
|
||
else:
|
||
print(f" ❌ {user1['username']} 看不到自己的cookies")
|
||
|
||
if "test_cookie_user2_1" not in user1_cookie_ids and "test_cookie_user2_2" not in user1_cookie_ids:
|
||
print(f" ✅ {user1['username']} 看不到其他用户的cookies")
|
||
else:
|
||
print(f" ❌ {user1['username']} 能看到其他用户的cookies(隔离失败)")
|
||
|
||
# 验证用户2只能看到自己的cookies
|
||
print(f"\n4️⃣ 验证 {user2['username']} 的cookie隔离...")
|
||
response2 = requests.get(f"{BASE_URL}/cookies", headers=user2['headers'])
|
||
if response2.status_code == 200:
|
||
user2_cookies = response2.json()
|
||
user2_cookie_ids = set(user2_cookies)
|
||
expected_user2 = {"test_cookie_user2_1", "test_cookie_user2_2"}
|
||
|
||
if expected_user2.issubset(user2_cookie_ids):
|
||
print(f" ✅ {user2['username']} 能看到自己的cookies")
|
||
else:
|
||
print(f" ❌ {user2['username']} 看不到自己的cookies")
|
||
|
||
if "test_cookie_user1_1" not in user2_cookie_ids and "test_cookie_user1_2" not in user2_cookie_ids:
|
||
print(f" ✅ {user2['username']} 看不到其他用户的cookies")
|
||
else:
|
||
print(f" ❌ {user2['username']} 能看到其他用户的cookies(隔离失败)")
|
||
|
||
return True
|
||
|
||
def test_cross_user_access(users):
|
||
"""测试跨用户访问权限"""
|
||
print("\n🧪 测试跨用户访问权限")
|
||
print("-" * 40)
|
||
|
||
if len(users) < 2:
|
||
print("❌ 需要至少2个用户进行权限测试")
|
||
return False
|
||
|
||
user1, user2 = users[0], users[1]
|
||
|
||
# 用户1尝试访问用户2的cookie
|
||
print(f"1️⃣ {user1['username']} 尝试访问 {user2['username']} 的cookie...")
|
||
|
||
# 尝试获取用户2的关键字
|
||
response = requests.get(f"{BASE_URL}/keywords/test_cookie_user2_1", headers=user1['headers'])
|
||
if response.status_code == 403:
|
||
print(f" ✅ 跨用户访问被正确拒绝 (403)")
|
||
elif response.status_code == 404:
|
||
print(f" ✅ 跨用户访问被拒绝 (404)")
|
||
else:
|
||
print(f" ❌ 跨用户访问未被拒绝 (状态码: {response.status_code})")
|
||
|
||
# 尝试更新用户2的cookie状态
|
||
response = requests.put(f"{BASE_URL}/cookies/test_cookie_user2_1/status",
|
||
json={"enabled": False},
|
||
headers=user1['headers'])
|
||
if response.status_code == 403:
|
||
print(f" ✅ 跨用户操作被正确拒绝 (403)")
|
||
elif response.status_code == 404:
|
||
print(f" ✅ 跨用户操作被拒绝 (404)")
|
||
else:
|
||
print(f" ❌ 跨用户操作未被拒绝 (状态码: {response.status_code})")
|
||
|
||
return True
|
||
|
||
def cleanup_test_data(users):
|
||
"""清理测试数据"""
|
||
print("\n🧹 清理测试数据")
|
||
print("-" * 40)
|
||
|
||
try:
|
||
conn = sqlite3.connect('xianyu_data.db')
|
||
cursor = conn.cursor()
|
||
|
||
# 清理测试cookies
|
||
cursor.execute('DELETE FROM cookies WHERE id LIKE "test_cookie_%"')
|
||
cookie_count = cursor.rowcount
|
||
|
||
# 清理测试用户
|
||
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 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()
|
||
|
||
print(f"✅ 清理完成:")
|
||
print(f" • 测试cookies: {cookie_count} 条")
|
||
print(f" • 测试用户: {user_count} 条")
|
||
print(f" • 邮箱验证码: {email_count} 条")
|
||
print(f" • 图形验证码: {captcha_count} 条")
|
||
|
||
except Exception as e:
|
||
print(f"❌ 清理失败: {e}")
|
||
|
||
def main():
|
||
"""主测试函数"""
|
||
print("🚀 多用户数据隔离完整测试")
|
||
print("=" * 60)
|
||
|
||
try:
|
||
# 创建测试用户
|
||
users = create_test_users()
|
||
|
||
if len(users) < 2:
|
||
print("\n❌ 测试失败:无法创建足够的测试用户")
|
||
return False
|
||
|
||
print(f"\n✅ 成功创建 {len(users)} 个测试用户")
|
||
|
||
# 测试Cookie数据隔离
|
||
cookie_isolation_success = test_cookie_isolation(users)
|
||
|
||
# 测试跨用户访问权限
|
||
cross_access_success = test_cross_user_access(users)
|
||
|
||
# 清理测试数据
|
||
cleanup_test_data(users)
|
||
|
||
print("\n" + "=" * 60)
|
||
if cookie_isolation_success and cross_access_success:
|
||
print("🎉 多用户数据隔离测试全部通过!")
|
||
|
||
print("\n📋 测试总结:")
|
||
print("✅ 用户注册和登录功能正常")
|
||
print("✅ Cookie数据完全隔离")
|
||
print("✅ 跨用户访问被正确拒绝")
|
||
print("✅ 用户权限验证正常")
|
||
|
||
print("\n🔒 安全特性:")
|
||
print("• 每个用户只能看到自己的数据")
|
||
print("• 跨用户访问被严格禁止")
|
||
print("• API层面权限验证完整")
|
||
print("• 数据库层面用户绑定正确")
|
||
|
||
return True
|
||
else:
|
||
print("❌ 多用户数据隔离测试失败!")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"\n💥 测试异常: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
if __name__ == "__main__":
|
||
main()
|