#!/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()