From c4e398bd3135f93962c53629187048b90211c60d Mon Sep 17 00:00:00 2001 From: Lan Date: Tue, 25 Feb 2025 22:55:42 +0800 Subject: [PATCH] fix: share auth --- apps/admin/dependencies.py | 33 +++++++++++++++++++++++++++++++++ apps/base/views.py | 12 ++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/apps/admin/dependencies.py b/apps/admin/dependencies.py index e9aa9b3..f59d4cd 100644 --- a/apps/admin/dependencies.py +++ b/apps/admin/dependencies.py @@ -95,6 +95,39 @@ async def admin_required( raise HTTPException(status_code=401, detail=str(e)) +async def share_required_login( + authorization: str = Header(default=None), request: Request = None +): + """ + 验证分享上传权限 + + 当settings.openUpload为False时,要求用户必须登录并具有管理员权限 + 当settings.openUpload为True时,允许游客上传 + + :param authorization: 认证头信息 + :param request: 请求对象 + :return: 验证结果 + """ + if not settings.openUpload: + try: + if not authorization or not authorization.startswith("Bearer "): + raise HTTPException( + status_code=403, detail="本站未开启游客上传,如需上传请先登录后台" + ) + + token = authorization.split(" ")[1] + try: + payload = verify_token(token) + if not payload.get("is_admin", False): + raise HTTPException(status_code=401, detail="未授权或授权校验失败") + except ValueError as e: + raise HTTPException(status_code=401, detail=str(e)) + except Exception as e: + raise HTTPException(status_code=401, detail="认证失败:" + str(e)) + + return True + + async def get_file_service(): return FileService() diff --git a/apps/base/views.py b/apps/base/views.py index 89dfe78..49eadc7 100644 --- a/apps/base/views.py +++ b/apps/base/views.py @@ -4,7 +4,7 @@ import uuid from fastapi import APIRouter, Form, UploadFile, File, Depends, HTTPException from starlette import status -from apps.admin.dependencies import admin_required +from apps.admin.dependencies import share_required_login from apps.base.models import FileCodes, UploadChunk from apps.base.schemas import SelectFileModel, InitChunkUploadModel, CompleteUploadModel from apps.base.utils import get_expire_info, get_file_path_name, ip_limit, get_chunk_file_path_name @@ -28,7 +28,7 @@ async def create_file_code(code, **kwargs): return await FileCodes.create(code=code, **kwargs) -@share_api.post("/text/", dependencies=[Depends(admin_required)]) +@share_api.post("/text/", dependencies=[Depends(share_required_login)]) async def share_text( text: str = Form(...), expire_value: int = Form(default=1, gt=0), @@ -56,7 +56,7 @@ async def share_text( return APIResponse(detail={"code": code}) -@share_api.post("/file/", dependencies=[Depends(admin_required)]) +@share_api.post("/file/", dependencies=[Depends(share_required_login)]) async def share_file( expire_value: int = Form(default=1, gt=0), expire_style: str = Form(default="day"), @@ -160,7 +160,7 @@ async def download_file(key: str, code: str, ip: str = Depends(ip_limit["error"] chunk_api = APIRouter(prefix="/chunk", tags=["切片"]) -@chunk_api.post("/upload/init/") +@chunk_api.post("/upload/init/", dependencies=[Depends(share_required_login)]) async def init_chunk_upload(data: InitChunkUploadModel): # 秒传检查 existing = await FileCodes.filter(file_hash=data.file_hash).first() @@ -203,7 +203,7 @@ async def init_chunk_upload(data: InitChunkUploadModel): }) -@chunk_api.post("/upload/chunk/{upload_id}/{chunk_index}") +@chunk_api.post("/upload/chunk/{upload_id}/{chunk_index}", dependencies=[Depends(share_required_login)]) async def upload_chunk( upload_id: str, chunk_index: int, @@ -243,7 +243,7 @@ async def upload_chunk( return APIResponse(detail={"chunk_hash": chunk_hash}) -@chunk_api.post("/upload/complete/{upload_id}") +@chunk_api.post("/upload/complete/{upload_id}", dependencies=[Depends(share_required_login)]) async def complete_upload(upload_id: str, data: CompleteUploadModel, ip: str = Depends(ip_limit["upload"])): # 获取上传基本信息 chunk_info = await UploadChunk.filter(upload_id=upload_id, chunk_index=-1).first()