fix: allow manage users to access management APIs

This commit is contained in:
jxxghp
2026-07-05 20:23:04 +08:00
parent 93e907d032
commit 36d4434596
5 changed files with 77 additions and 27 deletions
+5 -4
View File
@@ -22,8 +22,9 @@ from app.db.models import User
from app.db.models.downloadhistory import DownloadHistory, DownloadFiles from app.db.models.downloadhistory import DownloadHistory, DownloadFiles
from app.db.models.transferhistory import TransferHistory from app.db.models.transferhistory import TransferHistory
from app.db.user_oper import ( from app.db.user_oper import (
get_current_active_superuser_async, get_current_active_manage_user,
get_current_active_superuser, get_current_active_superuser,
get_current_active_superuser_async,
) )
from app.helper.progress import ProgressHelper from app.helper.progress import ProgressHelper
from app.schemas.types import EventType from app.schemas.types import EventType
@@ -223,7 +224,7 @@ def delete_transfer_history(
deletesrc: Optional[bool] = False, deletesrc: Optional[bool] = False,
deletedest: Optional[bool] = False, deletedest: Optional[bool] = False,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
删除整理记录 删除整理记录
@@ -264,7 +265,7 @@ def delete_transfer_history(
def ai_redo_transfer_history( def ai_redo_transfer_history(
history_id: int, history_id: int,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
手动触发单条历史记录的 AI 重新整理,并返回进度键。 手动触发单条历史记录的 AI 重新整理,并返回进度键。
@@ -293,7 +294,7 @@ def ai_redo_transfer_history(
def batch_ai_redo_transfer_history( def batch_ai_redo_transfer_history(
payload: schemas.BatchTransferHistoryRedoRequest, payload: schemas.BatchTransferHistoryRedoRequest,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
手动触发多条历史记录的 AI 批量重新整理,并返回进度键。 手动触发多条历史记录的 AI 批量重新整理,并返回进度键。
+14 -12
View File
@@ -22,6 +22,8 @@ from app.db.models.siteuserdata import SiteUserData
from app.db.site_oper import SiteOper from app.db.site_oper import SiteOper
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.db.user_oper import ( from app.db.user_oper import (
get_current_active_manage_user,
get_current_active_manage_user_async,
get_current_active_superuser, get_current_active_superuser,
get_current_active_superuser_async, get_current_active_superuser_async,
) )
@@ -37,7 +39,7 @@ router = APIRouter()
@router.get("/", summary="所有站点", response_model=List[schemas.Site]) @router.get("/", summary="所有站点", response_model=List[schemas.Site])
async def read_sites( async def read_sites(
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user_async),
) -> List[dict]: ) -> List[dict]:
""" """
获取站点列表 获取站点列表
@@ -50,7 +52,7 @@ async def add_site(
*, *,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
site_in: schemas.Site, site_in: schemas.Site,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
新增站点 新增站点
@@ -89,7 +91,7 @@ async def update_site(
*, *,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
site_in: schemas.Site, site_in: schemas.Site,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
更新站点信息 更新站点信息
@@ -150,7 +152,7 @@ def reset(
async def update_sites_priority( async def update_sites_priority(
priorities: List[dict], priorities: List[dict],
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
批量更新站点优先级 批量更新站点优先级
@@ -203,7 +205,7 @@ def update_cookie_by_body(
site_id: int, site_id: int,
site_cookie_update: schemas.SiteCookieUpdate, site_cookie_update: schemas.SiteCookieUpdate,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
使用请求体中的用户密码更新站点Cookie 使用请求体中的用户密码更新站点Cookie
@@ -226,7 +228,7 @@ def update_cookie(
password: str, password: str,
code: Optional[str] = None, code: Optional[str] = None,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
使用用户密码更新站点Cookie 使用用户密码更新站点Cookie
@@ -246,7 +248,7 @@ def update_cookie(
def refresh_userdata( def refresh_userdata(
site_id: int, site_id: int,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
刷新站点用户数据 刷新站点用户数据
@@ -273,7 +275,7 @@ def refresh_userdata(
) )
async def read_userdata_latest( async def read_userdata_latest(
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
查询所有站点最新用户数据 查询所有站点最新用户数据
@@ -291,7 +293,7 @@ async def read_userdata(
site_id: int, site_id: int,
workdate: Optional[str] = None, workdate: Optional[str] = None,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
查询站点用户数据 查询站点用户数据
@@ -395,7 +397,7 @@ async def site_resource(
cat: Optional[str] = None, cat: Optional[str] = None,
page: Optional[int] = 0, page: Optional[int] = 0,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
浏览站点资源 浏览站点资源
@@ -543,7 +545,7 @@ async def support_sites(_: User = Depends(get_current_active_superuser_async)):
async def read_site( async def read_site(
site_id: int, site_id: int,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
通过ID获取站点信息 通过ID获取站点信息
@@ -561,7 +563,7 @@ async def read_site(
async def delete_site( async def delete_site(
site_id: int, site_id: int,
db: AsyncSession = Depends(get_async_db), db: AsyncSession = Depends(get_async_db),
_: User = Depends(get_current_active_superuser_async), _: User = Depends(get_current_active_manage_user_async),
) -> Any: ) -> Any:
""" """
删除站点 删除站点
+7 -6
View File
@@ -15,6 +15,7 @@ from app.core.config import settings
from app.core.security import verify_token from app.core.security import verify_token
from app.db.models import User from app.db.models import User
from app.db.user_oper import ( from app.db.user_oper import (
get_current_active_manage_user,
get_current_active_superuser, get_current_active_superuser,
get_current_active_superuser_async, get_current_active_superuser_async,
) )
@@ -91,7 +92,7 @@ def list_files(
fileitem: schemas.FileItem, fileitem: schemas.FileItem,
sort: Optional[str] = "updated_at", sort: Optional[str] = "updated_at",
keyword: Optional[str] = None, keyword: Optional[str] = None,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
查询当前目录下所有目录和文件 查询当前目录下所有目录和文件
@@ -117,7 +118,7 @@ def list_files(
def mkdir( def mkdir(
fileitem: schemas.FileItem, fileitem: schemas.FileItem,
name: str, name: str,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
创建目录 创建目录
@@ -135,7 +136,7 @@ def mkdir(
@router.post("/delete", summary="删除文件或目录", response_model=schemas.Response) @router.post("/delete", summary="删除文件或目录", response_model=schemas.Response)
def delete( def delete(
fileitem: schemas.FileItem, _: User = Depends(get_current_active_superuser) fileitem: schemas.FileItem, _: User = Depends(get_current_active_manage_user)
) -> Any: ) -> Any:
""" """
删除文件或目录 删除文件或目录
@@ -150,7 +151,7 @@ def delete(
@router.post("/download", summary="下载文件") @router.post("/download", summary="下载文件")
def download( def download(
fileitem: schemas.FileItem, _: User = Depends(get_current_active_superuser) fileitem: schemas.FileItem, _: User = Depends(get_current_active_manage_user)
) -> Any: ) -> Any:
""" """
下载文件或目录 下载文件或目录
@@ -166,7 +167,7 @@ def download(
@router.post("/image", summary="预览图片") @router.post("/image", summary="预览图片")
def image( def image(
fileitem: schemas.FileItem, _: User = Depends(get_current_active_superuser) fileitem: schemas.FileItem, _: User = Depends(get_current_active_manage_user)
) -> Any: ) -> Any:
""" """
下载文件或目录 下载文件或目录
@@ -185,7 +186,7 @@ def rename(
fileitem: schemas.FileItem, fileitem: schemas.FileItem,
new_name: str, new_name: str,
recursive: Optional[bool] = False, recursive: Optional[bool] = False,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
重命名文件或目录 重命名文件或目录
+7 -4
View File
@@ -12,7 +12,10 @@ from app.core.security import verify_token, verify_apitoken
from app.db import get_db from app.db import get_db
from app.db.models import User from app.db.models import User
from app.db.models.transferhistory import TransferHistory from app.db.models.transferhistory import TransferHistory
from app.db.user_oper import get_current_active_superuser from app.db.user_oper import (
get_current_active_manage_user,
get_current_active_superuser,
)
from app.helper.directory import DirectoryHelper from app.helper.directory import DirectoryHelper
from app.log import logger from app.log import logger
from app.schemas import ( from app.schemas import (
@@ -182,7 +185,7 @@ def _get_manual_transfer_target_key(
def match_manual_transfer_target_path( def match_manual_transfer_target_path(
transer_item: ManualTransferItem, transer_item: ManualTransferItem,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
根据源文件匹配手动整理目的路径。 根据源文件匹配手动整理目的路径。
@@ -242,7 +245,7 @@ def manual_transfer(
transer_item: ManualTransferItem, transer_item: ManualTransferItem,
background: Optional[bool] = False, background: Optional[bool] = False,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
手动转移,文件或历史记录,支持自定义剧集识别格式 手动转移,文件或历史记录,支持自定义剧集识别格式
@@ -528,7 +531,7 @@ def manual_transfer(
) )
def recommend_episode_format( def recommend_episode_format(
recommend_item: EpisodeFormatRecommendItem, recommend_item: EpisodeFormatRecommendItem,
_: User = Depends(get_current_active_superuser), _: User = Depends(get_current_active_manage_user),
) -> Any: ) -> Any:
""" """
根据目录样本推荐集数定位模板 根据目录样本推荐集数定位模板
+44 -1
View File
@@ -8,13 +8,19 @@ from fastapi import HTTPException
from starlette.requests import Request from starlette.requests import Request
from starlette.responses import Response from starlette.responses import Response
from app.api.endpoints import dashboard as dashboard_endpoint
from app.api.endpoints import history as history_endpoint
from app.api.endpoints import login as login_endpoint from app.api.endpoints import login as login_endpoint
from app.api.endpoints import plugin as plugin_endpoint from app.api.endpoints import plugin as plugin_endpoint
from app.api.endpoints import site as site_endpoint
from app.api.endpoints import storage as storage_endpoint
from app.api.endpoints import system as system_endpoint from app.api.endpoints import system as system_endpoint
from app.api.endpoints import transfer as transfer_endpoint
from app.api.endpoints import user as user_endpoint from app.api.endpoints import user as user_endpoint
from app.api.endpoints import dashboard as dashboard_endpoint
from app.core.security import verify_resource_token from app.core.security import verify_resource_token
from app.db.user_oper import ( from app.db.user_oper import (
get_current_active_manage_user,
get_current_active_manage_user_async,
get_current_active_superuser, get_current_active_superuser,
get_current_active_superuser_async, get_current_active_superuser_async,
get_current_active_user_async, get_current_active_user_async,
@@ -75,6 +81,43 @@ def test_plugin_dashboard_endpoints_require_superuser():
assert _dependency_of(plugin_endpoint.plugin_dashboard, "_") is get_current_active_superuser assert _dependency_of(plugin_endpoint.plugin_dashboard, "_") is get_current_active_superuser
def test_manage_page_endpoints_accept_manage_permission():
"""管理页面接口允许具备 manage 权限的普通用户访问。"""
sync_endpoints = [
storage_endpoint.list_files,
storage_endpoint.mkdir,
storage_endpoint.delete,
storage_endpoint.download,
storage_endpoint.image,
storage_endpoint.rename,
site_endpoint.update_cookie_by_body,
site_endpoint.update_cookie,
site_endpoint.refresh_userdata,
history_endpoint.delete_transfer_history,
history_endpoint.ai_redo_transfer_history,
history_endpoint.batch_ai_redo_transfer_history,
transfer_endpoint.match_manual_transfer_target_path,
transfer_endpoint.manual_transfer,
transfer_endpoint.recommend_episode_format,
]
async_endpoints = [
site_endpoint.read_sites,
site_endpoint.add_site,
site_endpoint.update_site,
site_endpoint.update_sites_priority,
site_endpoint.read_userdata_latest,
site_endpoint.read_userdata,
site_endpoint.site_resource,
site_endpoint.read_site,
site_endpoint.delete_site,
]
for endpoint in sync_endpoints:
assert _dependency_of(endpoint, "_") is get_current_active_manage_user
for endpoint in async_endpoints:
assert _dependency_of(endpoint, "_") is get_current_active_manage_user_async
def test_system_public_setting_allows_only_non_sensitive_keys(monkeypatch): def test_system_public_setting_allows_only_non_sensitive_keys(monkeypatch):
"""公开系统设置接口只能读取明确列入白名单的非敏感配置。""" """公开系统设置接口只能读取明确列入白名单的非敏感配置。"""
calls = [] calls = []