| | |
| | | def get_current_user(token: str = Depends(oauth2_scheme)): |
| | | try: |
| | | payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) |
| | | expired_time = payload.get("lex") |
| | | if not expired_time: |
| | | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="令牌无效或已过期", |
| | | headers={"WWW-Authenticate": "Bearer"}) |
| | | if datetime.strptime(expired_time, "%Y-%m-%d %H:%M:%S") < datetime.now(): |
| | | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="系统授权已过期!", |
| | | headers={"WWW-Authenticate": "Bearer"}) |
| | | |
| | | username: str = payload.get("sub") |
| | | if username is None: |
| | | raise HTTPException( |
| | |
| | | from sqlalchemy.ext.asyncio import AsyncSession |
| | | from app.api import Response, pwd_context, get_current_user |
| | | from app.config.config import settings |
| | | from app.config.const import chat_server, RAGFLOW, workflow_server, DIFY, TMP_DICT |
| | | from app.config.const import chat_server, RAGFLOW, workflow_server, DIFY, TMP_DICT, SYSTEM_ID, SYSTEM_STATUS_ON |
| | | from app.models import SystemDataModel |
| | | from app.models.app_token_model import AppToken |
| | | from app.models.base_model import get_db |
| | | from app.models.postgresql_base_model import get_pdb |
| | |
| | | except Exception as e: |
| | | return Response(code=500, msg=f"Failed to login with {app['id']}: {str(e)}") |
| | | """ |
| | | system = db.query(SystemDataModel).filter_by(id=SYSTEM_ID).first() |
| | | if not system or system.status != SYSTEM_STATUS_ON: |
| | | return Response(code=400, msg="系统状态异常,请授权激活后操作!") |
| | | # 创建本地token |
| | | access_token = create_access_token(data={"sub": user.username, "user_id": user.id}) |
| | | access_token = create_access_token(data={"sub": user.username, "user_id": user.id, "lex": system.expired_at.strftime('%Y-%m-%d %H:%M:%S')}) |
| | | |
| | | # await update_token(db, user.id, access_token, token_dict) |
| | | # await update_user_token(db, user.id, token_dict) |
| | |
| | | from app.api import Response, get_current_user |
| | | from app.models.base_model import get_db |
| | | from app.models.role_model import RoleData, RoleModel |
| | | from app.models.system import SystemData |
| | | from app.models.system import SystemData, SystemLicense |
| | | from app.models.user_model import UserModel |
| | | from app.service.system import services_get_system_data, services_update_system_data, service_upload_logo_image |
| | | from app.service.system import services_get_system_data, services_update_system_data, service_upload_logo_image, \ |
| | | services_update_system_license |
| | | |
| | | system_router = APIRouter() |
| | | |
| | |
| | | if not file_name: |
| | | return Response(code=500, msg="failed", data={"logo": ""}) |
| | | return Response(code=200, msg="successfully", data={"logo": file_name}) |
| | | |
| | | |
| | | @system_router.put("/license", response_model=Response) |
| | | async def api_update_system_license(system: SystemLicense, db=Depends(get_db)): |
| | | |
| | | msg = await services_update_system_license(db, system.licenseCode) |
| | | if msg: |
| | | return Response(code=400, msg=msg, data={}) |
| | | return Response(code=200, msg="successfully", data={}) |
| | | |
| | |
| | | from app.models.public_api_model import DfToken |
| | | from app.service.v2.api_token import DfTokenDao |
| | | from app.service.v2.initialize_data import dialog_menu_sync, create_menu_sync, user_update_app |
| | | from app.task.sync_resources import sync_knowledge, sync_dialog, sync_agent, sync_llm, sync_resource |
| | | # from app.task.sync_resources import sync_knowledge, sync_dialog, sync_agent, sync_llm, sync_resource |
| | | from fastapi import Depends, APIRouter, File, UploadFile |
| | | from sqlalchemy.orm import Session |
| | | from app.config.const import smart_message_error, http_400, http_500, http_200, complex_dialog_chat |
| | |
| | | |
| | | ###-------------------------------system------------------------------------------------- |
| | | SYSTEM_ID = 1 |
| | | SYSTEM_STATUS_EXPIRED = 2 |
| | | SYSTEM_STATUS_ON = 1 |
| | | SYSTEM_STATUS_OFF = 0 |
| | | |
| | | ### --------------------------------complex mode---------------------------------------------- |
| | | complex_dialog_chat = 1 # 文档和基础对话 |
| | |
| | | smart_system: |
| | | title: SmartAI大模型平台 |
| | | desc: SmartAI大模型平台 |
| | | version: 1.0.3 |
| | |
| | | from app.models.base_model import SessionLocal |
| | | from app.service.v2.initialize_data import dialog_menu_sync, default_group_sync, default_role_sync, \ |
| | | basic_agent_sync, admin_account_sync, sync_rg_api_token, sync_complex_api_token |
| | | basic_agent_sync, admin_account_sync, sync_rg_api_token, sync_complex_api_token, system_license_sync |
| | | from app.task.sync_account_token import sync_token |
| | | |
| | | |
| | |
| | | await sync_rg_api_token(db) # rg token |
| | | await sync_token() # 账号token登录 |
| | | await sync_complex_api_token(db) # 账号token登录 |
| | | await system_license_sync(db) # 同步系统license |
| | | |
| | | except Exception as e: |
| | | print(e) |
| | |
| | | id = Column(Integer, primary_key=True, index=True) |
| | | title = Column(String(255)) |
| | | desc = Column(String(1000)) |
| | | version = Column(String(32)) |
| | | machine_id = Column(String(255)) |
| | | license_code = Column(String(1000)) |
| | | status = Column(Integer, default=0) |
| | | expired_at = Column(DateTime) |
| | | created_at = Column(DateTime, default=datetime.now()) |
| | | updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) |
| | | |
| | |
| | | # 'id': self.id, |
| | | 'title': self.title, |
| | | 'desc': self.desc, |
| | | 'version': self.version, |
| | | 'machine_id': self.machine_id, |
| | | 'license_code': self.license_code, |
| | | 'status': self.status, |
| | | 'expired_at': self.expired_at.strftime('%Y-%m-%d %H:%M') if self.expired_at else '', |
| | | } |
| | | |
| | | def __repr__(self): |
| | |
| | | title: str |
| | | desc: str |
| | | logo: str |
| | | |
| | | class SystemLicense(BaseModel): |
| | | licenseCode: str |
| | | |
New file |
| | |
| | | -----BEGIN PUBLIC KEY----- |
| | | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8Jak4kGIkOE2kyI0oTcb |
| | | w3yk7OfZ78g1RGvxKlYbKWz93Prxi1pvywXHOnrL/IYDCaNFOybFy5aMbqqvqXOx |
| | | 0LBCqwmB9F07AiEysmhH5m5OxlS9XsxGZb1WeRmobRbge3Hxl59DmUKvD/7Gdsre |
| | | JnDeSWxeaS/zIqLVUsvV3301B08biIywMAKamBQyuJNTPK1ir8iy6peSLPi022zk |
| | | Nl+Rm4ToOrF00oqwB8z5BOTdDcJW/eFlieOyTnWSAFBTIXAB9uqZSjn37kyLKYDh |
| | | yVqB71T/wQvMRip4PPFpCE4UCGGhLHHsKPhtCgxHj6YqE7vUCuGBXP/aagzpWC/H |
| | | ywIDAQAB |
| | | -----END PUBLIC KEY----- |
| | |
| | | import os |
| | | import shutil |
| | | import uuid |
| | | from datetime import datetime |
| | | |
| | | import yaml |
| | | from fastapi import UploadFile |
| | | |
| | | from datetime import datetime |
| | | from fastapi import UploadFile |
| | | from Log import logger |
| | | from app.api import pwd_context |
| | | from app.config.const import SYSTEM_ID, ENV_CONF_PATH, APP_STATIC_PATH |
| | | from app.config.const import SYSTEM_ID, ENV_CONF_PATH, APP_STATIC_PATH, APP_SERVICE_PATH, SYSTEM_STATUS_ON |
| | | from app.models.system import SystemDataModel |
| | | from cryptography.hazmat.primitives import serialization |
| | | from cryptography.hazmat.primitives.asymmetric import padding |
| | | from cryptography.hazmat.primitives import hashes |
| | | import base64 |
| | | import json |
| | | |
| | | from app.utils.common import get_machine_id |
| | | |
| | | |
| | | async def services_get_system_data(db): |
| | |
| | | with open(os.path.join(ENV_CONF_PATH, "system.yaml"), 'r', encoding='utf-8') as file: |
| | | # 加载JSON数据 |
| | | config = yaml.safe_load(file) |
| | | system = SystemDataModel(id=SYSTEM_ID, title=config["smart_system"]["title"], desc=config["smart_system"]["desc"]) |
| | | system = SystemDataModel(id=SYSTEM_ID, title=config["smart_system"]["title"], desc=config["smart_system"]["desc"], version=config["smart_system"]["version"]) |
| | | db.add(system) |
| | | db.commit() |
| | | db.refresh(system) |
| | |
| | | except Exception as e: |
| | | logger.error(f"保存失败: {str(e)}") |
| | | return "" |
| | | |
| | | |
| | | async def services_update_system_license(db, license_code): |
| | | try: |
| | | with open(os.path.join(APP_SERVICE_PATH, "pom/public_key.pem"), "rb") as f: |
| | | public_key = serialization.load_pem_public_key(f.read()) |
| | | license_data, signature = base64.b64decode(license_code).split(b"-----", 1) |
| | | # print(license_data) |
| | | public_key.verify( |
| | | signature, |
| | | license_data, |
| | | padding.PSS( |
| | | mgf=padding.MGF1(hashes.SHA256()), |
| | | salt_length=padding.PSS.MAX_LENGTH |
| | | ), |
| | | hashes.SHA256() |
| | | ) |
| | | license_dict = json.loads(license_data.decode('utf-8')) |
| | | # print(license_dict) |
| | | expiration_date = datetime.fromisoformat(license_dict['expiration_date']) |
| | | if expiration_date < datetime.now(): |
| | | return "授权码已过期" |
| | | system = db.query(SystemDataModel).filter_by(id=SYSTEM_ID).first() |
| | | if license_dict['machine_id'] != get_machine_id() or system.machine_id != license_dict['machine_id']: |
| | | return "授权码无效" |
| | | system.license_code = license_code |
| | | system.expired_at = expiration_date |
| | | system.status = SYSTEM_STATUS_ON |
| | | system.updated_at = datetime.now() |
| | | # db.query(SystemDataModel).filter_by(id=SYSTEM_ID).update({"license_code": license_code, "expired_at": expiration_date, "status": 1, "updated_at": datetime.now()}) |
| | | db.commit() |
| | | return "" |
| | | except Exception as e: |
| | | return f"验证失败: {str(e)}" |
| | |
| | | from app.config.agent_base_url import RG_APP_TOKEN_LIST, RG_APP_NEW_TOKEN, DF_CHAT_API_KEY |
| | | # from app.api import pwd_context |
| | | from app.config.const import DIFY, ENV_CONF_PATH, RAGFLOW, smart_server, chat_server, workflow_server, TMP_DICT, \ |
| | | rg_api_token, Dialog_STATSU_ON |
| | | rg_api_token, Dialog_STATSU_ON, SYSTEM_ID |
| | | from app.models import MenuCapacityModel, WebMenuModel, GroupModel, RoleModel, DialogModel, UserModel, UserAppModel, \ |
| | | cipher_suite, UserTokenModel, ApiTokenModel, ComplexChatModel |
| | | cipher_suite, UserTokenModel, ApiTokenModel, ComplexChatModel, SystemDataModel |
| | | from app.service.auth import UserAppDao |
| | | from app.service.bisheng import BishengService |
| | | from app.service.difyService import DifyService |
| | |
| | | from app.service.v2.app_register import AppRegisterDao |
| | | from app.config.config import settings |
| | | from app.service.v2.chat import get_app_token |
| | | from app.utils.common import get_machine_id |
| | | from app.utils.password_handle import generate_password, password_encrypted, password_decrypted |
| | | |
| | | pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
| | |
| | | except Exception as e: |
| | | print(e) |
| | | db.rollback() |
| | | |
| | | |
| | | async def system_license_sync(db): |
| | | with open(os.path.join(ENV_CONF_PATH, "system.yaml") , 'r', encoding='utf-8') as file: |
| | | # 加载JSON数据 |
| | | config = json.load(file) |
| | | try: |
| | | system = db.query(SystemDataModel).filter_by(id=SYSTEM_ID).first() |
| | | if system: |
| | | system.version = config["smart_system"].get("version") |
| | | else: |
| | | system = SystemDataModel(id=SYSTEM_ID, version=config["smart_system"].get("version"), title=config["smart_system"].get("title"), desc=config["smart_system"].get("desc"), machine_id=get_machine_id()) |
| | | db.add(system) |
| | | db.commit() |
| | | except Exception as e: |
| | | print(e) |
| | | db.rollback() |
New file |
| | |
| | | import asyncio |
| | | import base64 |
| | | import json |
| | | import os |
| | | |
| | | from datetime import datetime |
| | | from cryptography.hazmat.primitives import serialization |
| | | from cryptography.hazmat.primitives.asymmetric import padding |
| | | from cryptography.hazmat.primitives import hashes |
| | | from app.config.const import SYSTEM_ID, SYSTEM_STATUS_EXPIRED, SYSTEM_STATUS_ON, APP_SERVICE_PATH |
| | | from app.models import SystemDataModel |
| | | from app.models.base_model import SessionLocal |
| | | from app.utils.common import get_machine_id |
| | | |
| | | |
| | | async def sync_system_license(): |
| | | print("-------------------------------------------") |
| | | db = SessionLocal() |
| | | try: |
| | | system = db.query(SystemDataModel).filter_by(id=SYSTEM_ID).first() |
| | | if not system: |
| | | return |
| | | machine_id = get_machine_id() |
| | | if system.machine_id: |
| | | if system.machine_id != machine_id: |
| | | system.machine_id = machine_id |
| | | if system.status == SYSTEM_STATUS_ON: |
| | | system.status = SYSTEM_STATUS_EXPIRED |
| | | else: |
| | | if system.status == SYSTEM_STATUS_ON: |
| | | if not system.license_code or system.expired_at < datetime.now(): |
| | | system.status = SYSTEM_STATUS_EXPIRED |
| | | else: |
| | | try: |
| | | with open(os.path.join(APP_SERVICE_PATH, "pom/public_key.pem"), "rb") as f: |
| | | public_key = serialization.load_pem_public_key(f.read()) |
| | | license_data, signature = base64.b64decode(system.license_code).split(b"-----", 1) |
| | | # print(license_data) |
| | | public_key.verify( |
| | | signature, |
| | | license_data, |
| | | padding.PSS( |
| | | mgf=padding.MGF1(hashes.SHA256()), |
| | | salt_length=padding.PSS.MAX_LENGTH |
| | | ), |
| | | hashes.SHA256() |
| | | ) |
| | | license_dict = json.loads(license_data.decode('utf-8')) |
| | | # print(license_dict) |
| | | expiration_date = datetime.fromisoformat(license_dict['expiration_date']) |
| | | system.expired_at = expiration_date |
| | | if expiration_date < datetime.now(): |
| | | system.status = SYSTEM_STATUS_EXPIRED |
| | | except Exception as e: |
| | | print(e) |
| | | system.status = SYSTEM_STATUS_EXPIRED |
| | | else: |
| | | if system.status == SYSTEM_STATUS_ON: |
| | | system.status = SYSTEM_STATUS_EXPIRED |
| | | db.commit() |
| | | except Exception as e: |
| | | print(e) |
| | | finally: |
| | | db.close() |
| | | |
| | | |
| | | def sync_resource(): |
| | | asyncio.run(sync_system_license()) |
| | |
| | | import pytz |
| | | import platform |
| | | import subprocess |
| | | |
| | | from datetime import datetime |
| | | |
| | | |
| | | def current_time(): |
| | | tz = pytz.timezone('Asia/Shanghai') |
| | | return datetime.now(tz) |
| | | |
| | | |
| | | def get_machine_id(): |
| | | """获取机器的唯一标识""" |
| | | if platform.system() == "Windows": |
| | | # Windows 系统 |
| | | command = "wmic csproduct get UUID" |
| | | process = subprocess.Popen(command.split(), stdout=subprocess.PIPE) |
| | | output, _ = process.communicate() |
| | | machine_id = output.decode().strip().split("\n")[1].strip() |
| | | elif platform.system() == "Darwin": |
| | | # macOS 系统 |
| | | command = "system_profiler SPHardwareDataType | grep 'Hardware UUID' | awk '{print $4}'" |
| | | process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) |
| | | output, _ = process.communicate() |
| | | machine_id = output.decode().strip() |
| | | else: |
| | | # Linux 系统 |
| | | machine_id = open("/etc/machine-id").read().strip() |
| | | # print(machine_id) |
| | | return machine_id |
| | |
| | | sync_resources_from_json |
| | | from app.init_config.init_run_data import sync_default_data |
| | | from app.task.sync_account_token import start_sync_token_task |
| | | from app.task.sync_system import sync_resource |
| | | |
| | | init_db() |
| | | |
| | |
| | | scheduler = BackgroundScheduler() |
| | | scheduler.add_job(sync_agents_v2, 'interval', minutes=60, id="sync_resource_data") |
| | | scheduler.add_job(start_sync_token_task, 'interval', minutes=5, id="sync_token_1") |
| | | scheduler.add_job(sync_resource, 'interval', minutes=5, id="sync_resource_1") |
| | | |
| | | scheduler.start() |
| | | |