docs(api): more exactly
This commit is contained in:
@@ -23,30 +23,45 @@ security = HTTPBearer()
|
||||
|
||||
oauth2_password = OAuth2PasswordBearer(
|
||||
tokenUrl="oauth/token",
|
||||
scopes={"*": "Allows access to all scopes."},
|
||||
refreshUrl="oauth/token",
|
||||
scopes={"*": "允许访问全部 API。"},
|
||||
description="osu!lazer 或网页客户端密码登录认证,具有全部权限",
|
||||
scheme_name="Password Grant",
|
||||
)
|
||||
|
||||
oauth2_code = OAuth2AuthorizationCodeBearer(
|
||||
authorizationUrl="oauth/authorize",
|
||||
tokenUrl="oauth/token",
|
||||
refreshUrl="oauth/token",
|
||||
scopes={
|
||||
"chat.read": "Allows read chat messages on a user's behalf.",
|
||||
"chat.write": "Allows sending chat messages on a user's behalf.",
|
||||
"chat.write_manage": (
|
||||
"Allows joining and leaving chat channels on a user's behalf."
|
||||
),
|
||||
"delegate": (
|
||||
"Allows acting as the owner of a client; "
|
||||
"only available for Client Credentials Grant."
|
||||
),
|
||||
"forum.write": "Allows creating and editing forum posts on a user's behalf.",
|
||||
"friends.read": "Allows reading of the user's friend list.",
|
||||
"identify": "Allows reading of the public profile of the user (/me).",
|
||||
"public": "Allows reading of publicly available data on behalf of the user.",
|
||||
"chat.read": "允许代表用户读取聊天消息。",
|
||||
"chat.write": "允许代表用户发送聊天消息。",
|
||||
"chat.write_manage": ("允许代表用户加入和离开聊天频道。"),
|
||||
"delegate": ("允许作为客户端的所有者进行操作;仅适用于客户端凭证授权。"),
|
||||
"forum.write": "允许代表用户创建和编辑论坛帖子。",
|
||||
"friends.read": "允许读取用户的好友列表。",
|
||||
"identify": "允许读取用户的公开资料 (/me)。",
|
||||
"public": "允许代表用户读取公开数据。",
|
||||
},
|
||||
description="osu! OAuth 认证 (授权码认证)",
|
||||
scheme_name="Authorization Code Grant",
|
||||
)
|
||||
|
||||
|
||||
async def get_client_user(
|
||||
token: Annotated[str, Depends(oauth2_password)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
):
|
||||
token_record = await get_token_by_access_token(db, token)
|
||||
if not token_record:
|
||||
raise HTTPException(status_code=401, detail="Invalid or expired token")
|
||||
|
||||
user = (await db.exec(select(User).where(User.id == token_record.user_id))).first()
|
||||
if not user:
|
||||
raise HTTPException(status_code=401, detail="Invalid or expired token")
|
||||
return user
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
security_scopes: SecurityScopes,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
@@ -67,11 +82,7 @@ async def get_current_user(
|
||||
settings.osu_web_client_id,
|
||||
)
|
||||
|
||||
if security_scopes.scopes == ["*"]:
|
||||
# client/web only
|
||||
if not token_pw or not is_client:
|
||||
raise HTTPException(status_code=401, detail="Not authenticated")
|
||||
elif not is_client:
|
||||
if not is_client:
|
||||
for scope in security_scopes.scopes:
|
||||
if scope not in token_record.scope.split(","):
|
||||
raise HTTPException(
|
||||
|
||||
@@ -6,7 +6,7 @@ from io import BytesIO
|
||||
from app.database.lazer_user import User
|
||||
from app.dependencies.database import get_db
|
||||
from app.dependencies.storage import get_storage_service
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user
|
||||
from app.storage.base import StorageService
|
||||
|
||||
from .router import router
|
||||
@@ -22,7 +22,7 @@ from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
)
|
||||
async def upload_avatar(
|
||||
content: bytes = File(...),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
storage: StorageService = Depends(get_storage_service),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
|
||||
@@ -5,7 +5,7 @@ import secrets
|
||||
from app.database.auth import OAuthClient, OAuthToken
|
||||
from app.database.lazer_user import User
|
||||
from app.dependencies.database import get_db, get_redis
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user
|
||||
|
||||
from .router import router
|
||||
|
||||
@@ -24,7 +24,7 @@ async def create_oauth_app(
|
||||
name: str = Body(..., max_length=100, description="应用程序名称"),
|
||||
description: str = Body("", description="应用程序描述"),
|
||||
redirect_uris: list[str] = Body(..., description="允许的重定向 URI 列表"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
result = await session.execute( # pyright: ignore[reportDeprecated]
|
||||
@@ -62,7 +62,7 @@ async def create_oauth_app(
|
||||
async def get_oauth_app(
|
||||
client_id: int,
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
oauth_app = await session.get(OAuthClient, client_id)
|
||||
if not oauth_app:
|
||||
@@ -82,7 +82,7 @@ async def get_oauth_app(
|
||||
)
|
||||
async def get_user_oauth_apps(
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
oauth_apps = await session.exec(
|
||||
select(OAuthClient).where(OAuthClient.owner_id == current_user.id)
|
||||
@@ -107,7 +107,7 @@ async def get_user_oauth_apps(
|
||||
async def delete_oauth_app(
|
||||
client_id: int,
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
oauth_client = await session.get(OAuthClient, client_id)
|
||||
if not oauth_client:
|
||||
@@ -138,7 +138,7 @@ async def update_oauth_app(
|
||||
description: str = Body("", description="应用程序新描述"),
|
||||
redirect_uris: list[str] = Body(..., description="新的重定向 URI 列表"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
oauth_client = await session.get(OAuthClient, client_id)
|
||||
if not oauth_client:
|
||||
@@ -170,7 +170,7 @@ async def update_oauth_app(
|
||||
async def refresh_secret(
|
||||
client_id: int,
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
oauth_client = await session.get(OAuthClient, client_id)
|
||||
if not oauth_client:
|
||||
@@ -204,7 +204,7 @@ async def refresh_secret(
|
||||
)
|
||||
async def generate_oauth_code(
|
||||
client_id: int,
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
redirect_uri: str = Body(..., description="授权后重定向的 URI"),
|
||||
scopes: list[str] = Body(..., description="请求的权限范围列表"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from app.database.lazer_user import User
|
||||
from app.dependencies.database import get_db
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user
|
||||
|
||||
from .router import router
|
||||
|
||||
@@ -18,7 +18,7 @@ from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
async def user_rename(
|
||||
new_name: str = Body(..., description="新的用户名"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
"""修改用户名
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Literal
|
||||
from app.database import Beatmap, Beatmapset, BeatmapsetResp, FavouriteBeatmapset, User
|
||||
from app.dependencies.database import get_db
|
||||
from app.dependencies.fetcher import get_fetcher
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user, get_current_user
|
||||
from app.fetcher import Fetcher
|
||||
|
||||
from .router import router
|
||||
@@ -68,7 +68,7 @@ async def get_beatmapset(
|
||||
async def download_beatmapset(
|
||||
beatmapset_id: int = Path(..., description="谱面集 ID"),
|
||||
no_video: bool = Query(True, alias="noVideo", description="是否下载无视频版本"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
if current_user.country_code == "CN":
|
||||
return RedirectResponse(
|
||||
@@ -92,7 +92,7 @@ async def favourite_beatmapset(
|
||||
action: Literal["favourite", "unfavourite"] = Form(
|
||||
description="操作类型:favourite 收藏 / unfavourite 取消收藏"
|
||||
),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
assert current_user.id is not None
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from app.database import Relationship, RelationshipResp, RelationshipType, User
|
||||
from app.dependencies.database import get_db
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user, get_current_user
|
||||
|
||||
from .router import router
|
||||
|
||||
@@ -69,7 +69,7 @@ class AddFriendResp(BaseModel):
|
||||
async def add_relationship(
|
||||
request: Request,
|
||||
target: int = Query(description="目标用户 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
assert current_user.id is not None
|
||||
@@ -143,7 +143,7 @@ async def add_relationship(
|
||||
async def delete_relationship(
|
||||
request: Request,
|
||||
target: int = Path(..., description="目标用户 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
relationship_type = (
|
||||
|
||||
@@ -13,7 +13,7 @@ from app.database.room import APIUploadedRoom, Room, RoomResp
|
||||
from app.database.room_participated_user import RoomParticipatedUser
|
||||
from app.database.score import Score
|
||||
from app.dependencies.database import get_db, get_redis
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user, get_current_user
|
||||
from app.models.room import RoomCategory, RoomStatus
|
||||
from app.service.room import create_playlist_room_from_api
|
||||
from app.signalr.hub import MultiplayerHubs
|
||||
@@ -149,7 +149,7 @@ async def _participate_room(
|
||||
async def create_room(
|
||||
room: APIUploadedRoom,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
assert current_user.id is not None
|
||||
user_id = current_user.id
|
||||
@@ -177,7 +177,7 @@ async def get_room(
|
||||
),
|
||||
),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
redis: Redis = Depends(get_redis),
|
||||
):
|
||||
db_room = (await db.exec(select(Room).where(Room.id == room_id))).first()
|
||||
@@ -198,7 +198,7 @@ async def get_room(
|
||||
async def delete_room(
|
||||
room_id: int = Path(..., description="房间 ID"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
db_room = (await db.exec(select(Room).where(Room.id == room_id))).first()
|
||||
if db_room is None:
|
||||
@@ -219,7 +219,7 @@ async def add_user_to_room(
|
||||
room_id: int = Path(..., description="房间 ID"),
|
||||
user_id: int = Path(..., description="用户 ID"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
db_room = (await db.exec(select(Room).where(Room.id == room_id))).first()
|
||||
if db_room is not None:
|
||||
@@ -242,7 +242,7 @@ async def remove_user_from_room(
|
||||
room_id: int = Path(..., description="房间 ID"),
|
||||
user_id: int = Path(..., description="用户 ID"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
):
|
||||
db_room = (await db.exec(select(Room).where(Room.id == room_id))).first()
|
||||
if db_room is not None:
|
||||
|
||||
@@ -33,7 +33,7 @@ from app.database.score import (
|
||||
from app.dependencies.database import get_db, get_redis
|
||||
from app.dependencies.fetcher import get_fetcher
|
||||
from app.dependencies.storage import get_storage_service
|
||||
from app.dependencies.user import get_current_user
|
||||
from app.dependencies.user import get_client_user, get_current_user
|
||||
from app.fetcher import Fetcher
|
||||
from app.models.room import RoomCategory
|
||||
from app.models.score import (
|
||||
@@ -263,7 +263,7 @@ async def create_solo_score(
|
||||
version_hash: str = Form("", description="游戏版本哈希"),
|
||||
beatmap_hash: str = Form(description="谱面文件哈希"),
|
||||
ruleset_id: int = Form(..., ge=0, le=3, description="ruleset 数字 ID (0-3)"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
assert current_user.id is not None
|
||||
@@ -290,7 +290,7 @@ async def submit_solo_score(
|
||||
beatmap_id: int = Path(description="谱面 ID"),
|
||||
token: int = Path(description="成绩令牌 ID"),
|
||||
info: SoloScoreSubmissionInfo = Body(description="成绩提交信息"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
redis: Redis = Depends(get_redis),
|
||||
fetcher=Depends(get_fetcher),
|
||||
@@ -313,7 +313,7 @@ async def create_playlist_score(
|
||||
beatmap_hash: str = Form(description="游戏版本哈希"),
|
||||
ruleset_id: int = Form(..., ge=0, le=3, description="ruleset 数字 ID (0-3)"),
|
||||
version_hash: str = Form("", description="谱面版本哈希"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
assert current_user.id is not None
|
||||
@@ -386,7 +386,7 @@ async def submit_playlist_score(
|
||||
playlist_id: int,
|
||||
token: int,
|
||||
info: SoloScoreSubmissionInfo,
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
redis: Redis = Depends(get_redis),
|
||||
fetcher: Fetcher = Depends(get_fetcher),
|
||||
@@ -509,7 +509,7 @@ async def show_playlist_score(
|
||||
room_id: int,
|
||||
playlist_id: int,
|
||||
score_id: int,
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
redis: Redis = Depends(get_redis),
|
||||
):
|
||||
@@ -580,7 +580,7 @@ async def get_user_playlist_score(
|
||||
room_id: int,
|
||||
playlist_id: int,
|
||||
user_id: int,
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
score_record = None
|
||||
@@ -616,7 +616,7 @@ async def get_user_playlist_score(
|
||||
)
|
||||
async def pin_score(
|
||||
score_id: int = Path(description="成绩 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
score_record = (
|
||||
@@ -658,7 +658,7 @@ async def pin_score(
|
||||
)
|
||||
async def unpin_score(
|
||||
score_id: int = Path(description="成绩 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
score_record = (
|
||||
@@ -699,7 +699,7 @@ async def reorder_score_pin(
|
||||
score_id: int = Path(description="成绩 ID"),
|
||||
after_score_id: int | None = Body(default=None, description="放在该成绩之后"),
|
||||
before_score_id: int | None = Body(default=None, description="放在该成绩之前"),
|
||||
current_user: User = Security(get_current_user, scopes=["*"]),
|
||||
current_user: User = Security(get_client_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
score_record = (
|
||||
|
||||
Reference in New Issue
Block a user