133 lines
5.4 KiB
Python
133 lines
5.4 KiB
Python
|
|
#!/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()
|