117 lines
3.6 KiB
Python
117 lines
3.6 KiB
Python
|
|
from fastapi import Depends, HTTPException
|
|||
|
|
from database.creator import get_db_session
|
|||
|
|
from provider.loveac.authme import fetch_user_by_token
|
|||
|
|
from provider.aufe.isim import ISIMClient
|
|||
|
|
from provider.aufe.client import AUFEConnection
|
|||
|
|
from database.user import User
|
|||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|||
|
|
from typing import Dict
|
|||
|
|
from database.isim import ISIMRoomBinding
|
|||
|
|
from sqlalchemy import select
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 全局ISIM客户端池
|
|||
|
|
_isim_clients: Dict[str, ISIMClient] = {}
|
|||
|
|
|
|||
|
|
def get_cached_isim_client(user_id: str) -> ISIMClient:
|
|||
|
|
"""
|
|||
|
|
获取缓存的ISIM客户端
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_id: 用户ID
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
ISIMClient: 缓存的ISIM客户端实例,如果未找到则返回None
|
|||
|
|
"""
|
|||
|
|
return _isim_clients.get(user_id)
|
|||
|
|
|
|||
|
|
def cache_isim_client(user_id: str, client: ISIMClient) -> None:
|
|||
|
|
"""
|
|||
|
|
缓存ISIM客户端
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_id: 用户ID
|
|||
|
|
client: ISIM客户端实例
|
|||
|
|
"""
|
|||
|
|
_isim_clients[user_id] = client
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def get_isim_client(
|
|||
|
|
user: User = Depends(fetch_user_by_token),
|
|||
|
|
session: AsyncSession = Depends(get_db_session),
|
|||
|
|
) -> ISIMClient:
|
|||
|
|
from loguru import logger
|
|||
|
|
"""
|
|||
|
|
获取ISIM客户端实例
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user: 用户对象(通过认证令牌获取)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
ISIMClient: ISIM客户端实例
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 认证失败时抛出
|
|||
|
|
"""
|
|||
|
|
if not user:
|
|||
|
|
raise HTTPException(status_code=400, detail="无效的令牌或用户不存在")
|
|||
|
|
|
|||
|
|
# 首先检查是否已有缓存的ISIM客户端
|
|||
|
|
cached_client = get_cached_isim_client(user.userid)
|
|||
|
|
if cached_client:
|
|||
|
|
# 检查缓存的客户端是否仍然有效
|
|||
|
|
try:
|
|||
|
|
if cached_client.is_session_valid():
|
|||
|
|
from loguru import logger
|
|||
|
|
logger.info(f"复用缓存的ISIM客户端: user_id={user.userid}")
|
|||
|
|
return cached_client
|
|||
|
|
except Exception as e:
|
|||
|
|
from loguru import logger
|
|||
|
|
logger.warning(f"缓存的ISIM客户端无效,将重新创建: {str(e)}")
|
|||
|
|
|
|||
|
|
# 创建或获取VPN连接
|
|||
|
|
aufe = AUFEConnection.create_or_get_connection("vpn.aufe.edu.cn", user.userid)
|
|||
|
|
|
|||
|
|
# 检查VPN登录状态
|
|||
|
|
if not aufe.login_status():
|
|||
|
|
userid = user.userid
|
|||
|
|
easyconnect_password = user.easyconnect_password
|
|||
|
|
if not await aufe.login(userid, easyconnect_password):
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=400,
|
|||
|
|
detail="VPN登录失败,请检查用户名和密码",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 检查UAAP登录状态
|
|||
|
|
if not aufe.uaap_login_status():
|
|||
|
|
userid = user.userid
|
|||
|
|
password = user.password
|
|||
|
|
if not await aufe.uaap_login(userid, password):
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=400,
|
|||
|
|
detail="大学登录失败,请检查用户名和密码",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 创建新的ISIM客户端
|
|||
|
|
isim_client = ISIMClient(aufe)
|
|||
|
|
|
|||
|
|
|
|||
|
|
result_query = await session.execute(
|
|||
|
|
select(ISIMRoomBinding).where(ISIMRoomBinding.userid == user.userid)
|
|||
|
|
)
|
|||
|
|
binding_record = result_query.scalars().first()
|
|||
|
|
if binding_record:
|
|||
|
|
logger.info(f"找到用户({user.userid})绑定记录,进行启动再绑定")
|
|||
|
|
await isim_client.bind_room(
|
|||
|
|
building_code=binding_record.building_code,
|
|||
|
|
floor_code=binding_record.floor_code,
|
|||
|
|
room_code=binding_record.room_code,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 缓存客户端
|
|||
|
|
cache_isim_client(user.userid, isim_client)
|
|||
|
|
|
|||
|
|
logger.info(f"创建并缓存新的ISIM客户端: user_id={user.userid}")
|
|||
|
|
|
|||
|
|
return isim_client
|