From d08b39d4824f6d8f97c63db261e053029391774d Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Sun, 24 Aug 2025 16:34:20 +0000 Subject: [PATCH] refactor(lio): remove unused hmac validation --- README.md | 10 ++++++--- app/router/lio.py | 54 +++-------------------------------------------- 2 files changed, 10 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index bd072d8..fda3fd7 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - **缓存支持**: Redis 缓存令牌和会话信息 - **多种存储后端**: 支持本地存储、Cloudflare R2、AWS S3 - **容器化部署**: Docker 和 Docker Compose 支持 +- **资源文件反向代理**: 可以将 osu! 官方的资源链接(头像、谱面封面、音频等)替换为自定义域名。 ## 快速开始 @@ -45,14 +46,17 @@ docker-compose -f docker-compose-osurx.yml up -d 使用[自定义的 osu!lazer 客户端](https://github.com/GooGuTeam/osu),或者使用 [LazerAuthlibInjection](https://github.com/MingxuanGame/LazerAuthlibInjection),修改服务器设置为服务器的 IP -### 更新数据库 +## 更新数据库 参考[数据库迁移指南](https://github.com/GooGuTeam/g0v0-server/wiki/Migrate-Database) -## 资源文件反向代理 +## 安全 -服务器支持资源文件反向代理功能,可以将 osu! 官方的资源链接(头像、谱面封面、音频等)替换为自定义域名。 +使用 `openssl rand -hex 32` 生成 JWT 密钥,以保证服务器安全和旁观服务器的正常运行 +使用 `openssl rand -hex 40` 生成前端密钥 + +**如果是在公网环境下,请屏蔽对 `/_lio` 路径的外部请求** ## 许可证 diff --git a/app/router/lio.py b/app/router/lio.py index 3558e74..4139aa6 100644 --- a/app/router/lio.py +++ b/app/router/lio.py @@ -23,7 +23,7 @@ from app.utils import utcnow from .notification.server import server -from fastapi import APIRouter, Depends, HTTPException, Query, Request, status +from fastapi import APIRouter, Depends, HTTPException, Request, status from pydantic import BaseModel from redis.asyncio import Redis from sqlalchemy import func, update @@ -104,26 +104,6 @@ class RoomCreateRequest(BaseModel): playlist: list[dict[str, Any]] = [] -def verify_request_signature(request: Request, timestamp: str, body: bytes) -> bool: - """ - Verify HMAC signature for shared interop requests. - - Args: - request: FastAPI request object - timestamp: Request timestamp - body: Request body bytes - - Returns: - bool: True if signature is valid - - Note: - Currently skips verification in development. - In production, implement proper HMAC verification. - """ - # TODO: Implement proper HMAC verification for production - return True - - async def _validate_user_exists(db: Database, user_id: int) -> User: """Validate that a user exists in the database.""" user_result = await db.execute(select(User).where(User.id == user_id)) @@ -474,18 +454,11 @@ async def _transfer_ownership_or_end_room(db: Database, room_id: int, leaving_us @router.post("/multiplayer/rooms") async def create_multiplayer_room( - request: Request, room_data: dict[str, Any], db: Database, - timestamp: str = "", ) -> int: """Create a new multiplayer room with initial playlist.""" try: - # Verify request signature - body = await request.body() - if not verify_request_signature(request, str(timestamp), body): - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid request signature") - # Parse room data if string if isinstance(room_data, str): room_data = json.loads(room_data) @@ -528,19 +501,13 @@ async def create_multiplayer_room( @router.delete("/multiplayer/rooms/{room_id}/users/{user_id}") async def remove_user_from_room( - request: Request, room_id: int, user_id: int, db: Database, - timestamp: int = Query(..., description="Unix 时间戳(秒)", ge=0), ) -> dict[str, Any]: """Remove a user from a multiplayer room.""" try: - # Verify request signature - body = await request.body() now = utcnow() - if not verify_request_signature(request, str(timestamp), body): - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid request signature") # 检查房间是否存在 room_result = await db.execute(select(Room).where(col(Room.id) == room_id)) @@ -634,7 +601,6 @@ async def add_user_to_room( room_id: int, user_id: int, db: Database, - timestamp: str = "", ) -> dict[str, Any]: """Add a user to a multiplayer room.""" logger.debug(f"Adding user {user_id} to room {room_id}") @@ -650,19 +616,13 @@ async def add_user_to_room( logger.debug("Failed to parse user_data from request body") user_data = None - # Verify request signature - if not verify_request_signature(request, timestamp, body): - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid request signature") - # 检查房间是否已结束 - room_result = await db.execute( - select(Room.id, Room.ends_at, Room.channel_id, Room.host_id).where(col(Room.id) == room_id) - ) + room_result = await db.exec(select(Room.ends_at, Room.channel_id, Room.host_id).where(col(Room.id) == room_id)) room_row = room_result.first() if not room_row: raise HTTPException(status_code=404, detail="Room not found") - _, ends_at, channel_id, host_user_id = room_row + ends_at, channel_id, host_user_id = room_row if ends_at is not None: logger.debug(f"User {user_id} attempted to join ended room {room_id}") raise HTTPException(status_code=410, detail="Room has ended and cannot accept new participants") @@ -707,12 +667,10 @@ async def add_user_to_room( @router.post("/beatmaps/ensure") async def ensure_beatmap_present( - request: Request, beatmap_data: BeatmapEnsureRequest, db: Database, redis: Redis = Depends(get_redis), fetcher: Fetcher = Depends(get_fetcher), - timestamp: str = "", ) -> dict[str, Any]: """ 确保谱面在服务器中存在(包括元数据和原始文件缓存)。 @@ -721,11 +679,6 @@ async def ensure_beatmap_present( 避免在需要时才获取导致的延迟。 """ try: - # Verify request signature - body = await request.body() - if not verify_request_signature(request, timestamp, body): - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid request signature") - beatmap_id = beatmap_data.beatmap_id logger.debug(f"Ensuring beatmap {beatmap_id} is present") @@ -757,7 +710,6 @@ class ReplayDataRequest(BaseModel): async def save_replay( req: ReplayDataRequest, storage_service: StorageService = Depends(get_storage_service), - timestamp: str = "", ): replay_data = req.mreplay replay_path = f"replays/{req.score_id}_{req.beatmap_id}_{req.user_id}_lazer_replay.osr"