Files
g0v0-server/app/service/session_manager.py
2025-08-22 08:21:52 +00:00

123 lines
3.4 KiB
Python

"""
API 状态管理 - 模拟 osu! 的 APIState 和会话管理
"""
from __future__ import annotations
from datetime import datetime
from enum import Enum
from pydantic import BaseModel
class APIState(str, Enum):
"""API 连接状态,对应 osu! 的 APIState"""
OFFLINE = "offline"
CONNECTING = "connecting"
REQUIRES_SECOND_FACTOR_AUTH = "requires_second_factor_auth" # 需要二次验证
ONLINE = "online"
FAILING = "failing"
class UserSession(BaseModel):
"""用户会话信息"""
user_id: int
username: str
email: str
session_token: str | None = None
state: APIState = APIState.OFFLINE
requires_verification: bool = False
verification_sent: bool = False
last_verification_attempt: datetime | None = None
failed_attempts: int = 0
ip_address: str | None = None
country_code: str | None = None
is_new_location: bool = False
class SessionManager:
"""会话管理器"""
def __init__(self):
self._sessions: dict[str, UserSession] = {}
def create_session(
self,
user_id: int,
username: str,
email: str,
ip_address: str,
country_code: str | None = None,
is_new_location: bool = False,
) -> UserSession:
"""创建新的用户会话"""
import secrets
session_token = secrets.token_urlsafe(32)
# 根据是否为新位置决定初始状态
if is_new_location:
state = APIState.REQUIRES_SECOND_FACTOR_AUTH
else:
state = APIState.ONLINE
session = UserSession(
user_id=user_id,
username=username,
email=email,
session_token=session_token,
state=state,
requires_verification=is_new_location,
ip_address=ip_address,
country_code=country_code,
is_new_location=is_new_location,
)
self._sessions[session_token] = session
return session
def get_session(self, session_token: str) -> UserSession | None:
"""获取会话"""
return self._sessions.get(session_token)
def update_session_state(self, session_token: str, state: APIState):
"""更新会话状态"""
if session_token in self._sessions:
self._sessions[session_token].state = state
def mark_verification_sent(self, session_token: str):
"""标记验证邮件已发送"""
if session_token in self._sessions:
session = self._sessions[session_token]
session.verification_sent = True
session.last_verification_attempt = datetime.now()
def increment_failed_attempts(self, session_token: str):
"""增加失败尝试次数"""
if session_token in self._sessions:
self._sessions[session_token].failed_attempts += 1
def verify_session(self, session_token: str) -> bool:
"""验证会话成功"""
if session_token in self._sessions:
session = self._sessions[session_token]
session.state = APIState.ONLINE
session.requires_verification = False
return True
return False
def remove_session(self, session_token: str):
"""移除会话"""
self._sessions.pop(session_token, None)
def cleanup_expired_sessions(self):
"""清理过期会话"""
# 这里可以实现清理逻辑
pass
# 全局会话管理器
session_manager = SessionManager()