BodyBalanceEvaluation/backend/tools/test_license_system.py

133 lines
5.4 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
授权系统快速验证脚本
- 直接验证 LicenseManager 的功能机器指纹授权状态签名与有效性
- 尝试条件允许时通过 Flask 测试客户端验证授权相关API
"""
import os
import sys
import json
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # backend 目录
def main():
# 允许从backend导入
if BASE_DIR not in sys.path:
sys.path.append(BASE_DIR)
# 导入配置与授权管理器
from devices.utils.config_manager import ConfigManager
from devices.utils.license_manager import LicenseManager
cfg = ConfigManager()
# 确保LICENSE配置项存在并指向开发文件
cfg.set_config_value('LICENSE', 'path', 'trial_license_bind.json')
cfg.set_config_value('LICENSE', 'public_key', 'license_public_key.pem')
cfg.set_config_value('LICENSE', 'grace_days', '7')
lm = LicenseManager(cfg)
# 1) 机器指纹
machine_id = lm.get_machine_id()
print(f"Machine ID: {machine_id}")
# 2) 授权状态
status = lm.get_license_status(force_reload=True)
print("License Status:")
print(json.dumps({
'valid': status.valid,
'message': status.message,
'license_type': status.license_type,
'license_id': status.license_id,
'expires_at': status.expires_at.isoformat() if status.expires_at else None,
'features': status.features,
}, ensure_ascii=False, indent=2))
# 3) 验证授权文件(示例/开发文件通常为占位签名,会失败属正常)
dev_license_path = os.path.join(BASE_DIR, 'dev_license.json')
ok, msg = lm.verify_license_file(dev_license_path)
print(f"Verify dev_license.json -> ok={ok}, msg={msg}")
sample_license_path = os.path.join(BASE_DIR, 'sample_license.json')
if os.path.exists(sample_license_path):
ok2, msg2 = lm.verify_license_file(sample_license_path)
print(f"Verify sample_license.json -> ok={ok2}, msg={msg2}")
else:
print("sample_license.json not found; skip signature test for sample.")
# 3.1) 如果存在通过工具生成的试用授权文件,验证其签名(应为成功)
trial_license_path = os.path.join(BASE_DIR, 'trial_license.json')
if os.path.exists(trial_license_path):
ok3, msg3 = lm.verify_license_file(trial_license_path)
print(f"Verify trial_license.json -> ok={ok3}, msg={msg3}")
else:
print("trial_license.json not found; skip trial license verification.")
# 3.2) 验证绑定机器ID的试用授权文件如存在应成功
trial_bind_path = os.path.join(BASE_DIR, 'trial_license_bind.json')
if os.path.exists(trial_bind_path):
ok4, msg4 = lm.verify_license_file(trial_bind_path)
print(f"Verify trial_license_bind.json -> ok={ok4}, msg={msg4}")
else:
print("trial_license_bind.json not found; skip bind license verification.")
# 4) 尝试通过 Flask 测试客户端访问授权API如果 main.py 可正常导入)
try:
from main import AppServer
server = AppServer(debug=True)
# 手动注入授权管理器与状态,避免调用 init_app 引发硬件初始化
server.license_manager = lm
server.config_manager = cfg
server.license_status = status
client = server.app.test_client()
# /api/license/info
resp = client.get('/api/license/info')
print("GET /api/license/info ->", resp.status_code)
try:
print(json.dumps(resp.get_json(), ensure_ascii=False, indent=2))
except Exception:
print(resp.data.decode('utf-8', errors='ignore'))
# /api/license/activation-request
resp2 = client.post('/api/license/activation-request', json={
'company_name': '测试公司',
'contact_info': 'test@example.com'
})
print("POST /api/license/activation-request ->", resp2.status_code)
try:
print(json.dumps(resp2.get_json(), ensure_ascii=False, indent=2))
except Exception:
print(resp2.data.decode('utf-8', errors='ignore'))
# /api/license/verify 使用占位签名文件,会返回失败用于验证路径与流程
# 优先使用通过工具生成的 trial_license.json如存在否则使用 dev_license.json
# 优先顺序trial_license_bind.json -> trial_license.json -> dev_license.json
if os.path.exists(trial_bind_path):
post_file_path = trial_bind_path
elif os.path.exists(trial_license_path):
post_file_path = trial_license_path
else:
post_file_path = dev_license_path
with open(post_file_path, 'rb') as f:
data = {
'license_file': (f, os.path.basename(post_file_path))
}
resp3 = client.post('/api/license/verify', content_type='multipart/form-data', data=data)
print("POST /api/license/verify ->", resp3.status_code)
try:
print(json.dumps(resp3.get_json(), ensure_ascii=False, indent=2))
except Exception:
print(resp3.data.decode('utf-8', errors='ignore'))
except Exception as e:
print(f"Skip API tests due to import error or environment issue: {e}")
if __name__ == '__main__':
main()