feat(auth): support trusted device (#52)
New API to maintain sessions and devices:
- GET /api/private/admin/sessions
- DELETE /api/private/admin/sessions/{session_id}
- GET /api/private/admin/trusted-devices
- DELETE /api/private/admin/trusted-devices/{device_id}
Auth:
web clients request `/oauth/token` and `/api/v2/session/verify` with `X-UUID` header to save the client as trusted device.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,122 +0,0 @@
|
||||
"""
|
||||
数据库清理调度器 - 定时清理过期数据
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from app.dependencies.database import engine
|
||||
from app.log import logger
|
||||
from app.service.database_cleanup_service import DatabaseCleanupService
|
||||
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
|
||||
class DatabaseCleanupScheduler:
|
||||
"""数据库清理调度器"""
|
||||
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
self.task = None
|
||||
|
||||
async def start(self):
|
||||
"""启动调度器"""
|
||||
if self.running:
|
||||
return
|
||||
|
||||
self.running = True
|
||||
self.task = asyncio.create_task(self._run_scheduler())
|
||||
logger.debug("Database cleanup scheduler started")
|
||||
|
||||
async def stop(self):
|
||||
"""停止调度器"""
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
self.running = False
|
||||
if self.task:
|
||||
self.task.cancel()
|
||||
try:
|
||||
await self.task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
logger.debug("Database cleanup scheduler stopped")
|
||||
|
||||
async def _run_scheduler(self):
|
||||
"""运行调度器"""
|
||||
while self.running:
|
||||
try:
|
||||
# 每小时运行一次清理
|
||||
await asyncio.sleep(3600) # 3600秒 = 1小时
|
||||
|
||||
if not self.running:
|
||||
break
|
||||
|
||||
await self._run_cleanup()
|
||||
|
||||
except asyncio.CancelledError:
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(f"Database cleanup scheduler error: {e!s}")
|
||||
# 发生错误后等待5分钟再继续
|
||||
await asyncio.sleep(300)
|
||||
|
||||
async def _run_cleanup(self):
|
||||
"""执行清理任务"""
|
||||
try:
|
||||
async with AsyncSession(engine) as db:
|
||||
logger.debug("Starting scheduled database cleanup...")
|
||||
|
||||
# 清理过期的验证码
|
||||
expired_codes = await DatabaseCleanupService.cleanup_expired_verification_codes(db)
|
||||
|
||||
# 清理过期的登录会话
|
||||
expired_sessions = await DatabaseCleanupService.cleanup_expired_login_sessions(db)
|
||||
|
||||
# 清理1小时前未验证的登录会话
|
||||
unverified_sessions = await DatabaseCleanupService.cleanup_unverified_login_sessions(db, 1)
|
||||
|
||||
# 只在有清理记录时输出总结
|
||||
total_cleaned = expired_codes + expired_sessions + unverified_sessions
|
||||
if total_cleaned > 0:
|
||||
logger.debug(
|
||||
f"Scheduled cleanup completed - codes: {expired_codes}, "
|
||||
f"sessions: {expired_sessions}, unverified: {unverified_sessions}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during scheduled database cleanup: {e!s}")
|
||||
|
||||
async def run_manual_cleanup(self):
|
||||
"""手动运行完整清理"""
|
||||
try:
|
||||
async with AsyncSession(engine) as db:
|
||||
logger.debug("Starting manual database cleanup...")
|
||||
results = await DatabaseCleanupService.run_full_cleanup(db)
|
||||
total = sum(results.values())
|
||||
if total > 0:
|
||||
logger.debug(f"Manual cleanup completed, total records cleaned: {total}")
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"Error during manual database cleanup: {e!s}")
|
||||
return {}
|
||||
|
||||
|
||||
# 全局实例
|
||||
database_cleanup_scheduler = DatabaseCleanupScheduler()
|
||||
|
||||
|
||||
async def start_database_cleanup_scheduler():
|
||||
"""启动数据库清理调度器"""
|
||||
await database_cleanup_scheduler.start()
|
||||
|
||||
|
||||
async def stop_database_cleanup_scheduler():
|
||||
"""停止数据库清理调度器"""
|
||||
await database_cleanup_scheduler.stop()
|
||||
|
||||
|
||||
async def run_manual_database_cleanup():
|
||||
"""手动运行数据库清理"""
|
||||
return await database_cleanup_scheduler.run_manual_cleanup()
|
||||
Reference in New Issue
Block a user