From bb4355fbe076a021667d86cb0ff9f5386093fc09 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 7 Jul 2024 08:09:26 +0800 Subject: [PATCH] fix permissions --- app/api/endpoints/download.py | 14 +++++++------- app/api/endpoints/history.py | 2 +- app/api/endpoints/plugin.py | 22 +++++++++++++--------- app/api/endpoints/search.py | 8 ++++++-- app/api/endpoints/site.py | 19 ++++++++++--------- app/api/endpoints/storage.py | 9 +++++---- app/api/endpoints/transfer.py | 3 ++- app/db/user_oper.py | 6 +++++- 8 files changed, 49 insertions(+), 34 deletions(-) diff --git a/app/api/endpoints/download.py b/app/api/endpoints/download.py index 22a01bf0..55354db0 100644 --- a/app/api/endpoints/download.py +++ b/app/api/endpoints/download.py @@ -9,7 +9,7 @@ from app.core.context import MediaInfo, Context, TorrentInfo from app.core.metainfo import MetaInfo from app.core.security import verify_token from app.db.models.user import User -from app.db.user_oper import get_current_active_user +from app.db.user_oper import get_current_active_user, check_user_permission router = APIRouter() @@ -95,22 +95,22 @@ def start( @router.get("/stop/{hashString}", summary="暂停任务", response_model=schemas.Response) -def stop( - hashString: str, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: +def stop(hashString: str) -> Any: """ 暂停下载任务 """ + # 检查用户权限 + check_user_permission(permission='downloading.manage') ret = DownloadChain().set_downloading(hashString, "stop") return schemas.Response(success=True if ret else False) @router.delete("/{hashString}", summary="删除下载任务", response_model=schemas.Response) -def info( - hashString: str, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: +def delete(hashString: str) -> Any: """ 删除下载任务 """ + # 检查用户权限 + check_user_permission(permission='downloading.manage') ret = DownloadChain().remove_downloading(hashString) return schemas.Response(success=True if ret else False) diff --git a/app/api/endpoints/history.py b/app/api/endpoints/history.py index 241f8502..4756b455 100644 --- a/app/api/endpoints/history.py +++ b/app/api/endpoints/history.py @@ -77,7 +77,7 @@ def delete_transfer_history(history_in: schemas.TransferHistory, deletesrc: bool = False, deletedest: bool = False, db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 删除转移历史记录 """ diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index 8ef66fbe..4a080234 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -6,6 +6,7 @@ from app import schemas from app.core.plugin import PluginManager from app.core.security import verify_token from app.db.systemconfig_oper import SystemConfigOper +from app.db.user_oper import get_current_active_superuser from app.helper.plugin import PluginHelper from app.scheduler import Scheduler from app.schemas.types import SystemConfigKey @@ -37,7 +38,8 @@ def remove_plugin_api(plugin_id: str): @router.get("/", summary="所有插件", response_model=List[schemas.Plugin]) -def all_plugins(_: schemas.TokenPayload = Depends(verify_token), state: str = "all") -> List[schemas.Plugin]: +def all_plugins(_: schemas.TokenPayload = Depends(get_current_active_superuser), + state: str = "all") -> List[schemas.Plugin]: """ 查询所有插件清单,包括本地插件和在线插件,插件状态:installed, market, all """ @@ -83,7 +85,7 @@ def all_plugins(_: schemas.TokenPayload = Depends(verify_token), state: str = "a @router.get("/installed", summary="已安装插件", response_model=List[str]) -def installed(_: schemas.TokenPayload = Depends(verify_token)) -> Any: +def installed(_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 查询用户已安装插件清单 """ @@ -102,7 +104,7 @@ def statistic(_: schemas.TokenPayload = Depends(verify_token)) -> Any: def install(plugin_id: str, repo_url: str = "", force: bool = False, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 安装插件 """ @@ -131,7 +133,7 @@ def install(plugin_id: str, @router.get("/form/{plugin_id}", summary="获取插件表单页面") def plugin_form(plugin_id: str, - _: schemas.TokenPayload = Depends(verify_token)) -> dict: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> dict: """ 根据插件ID获取插件配置表单 """ @@ -143,7 +145,7 @@ def plugin_form(plugin_id: str, @router.get("/page/{plugin_id}", summary="获取插件数据页面") -def plugin_page(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: +def plugin_page(plugin_id: str, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> List[dict]: """ 根据插件ID获取插件数据页面 """ @@ -177,7 +179,8 @@ def plugin_dashboard(plugin_id: str, key: str, user_agent: Annotated[str | None, @router.get("/reset/{plugin_id}", summary="重置插件配置及数据", response_model=schemas.Response) -def reset_plugin(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)) -> Any: +def reset_plugin(plugin_id: str, + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 根据插件ID重置插件配置及数据 """ @@ -198,7 +201,8 @@ def reset_plugin(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token) @router.get("/{plugin_id}", summary="获取插件配置") -def plugin_config(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)) -> dict: +def plugin_config(plugin_id: str, + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> dict: """ 根据插件ID获取插件配置信息 """ @@ -207,7 +211,7 @@ def plugin_config(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token @router.put("/{plugin_id}", summary="更新插件配置", response_model=schemas.Response) def set_plugin_config(plugin_id: str, conf: dict, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 更新插件配置 """ @@ -224,7 +228,7 @@ def set_plugin_config(plugin_id: str, conf: dict, @router.delete("/{plugin_id}", summary="卸载插件", response_model=schemas.Response) def uninstall_plugin(plugin_id: str, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 卸载插件 """ diff --git a/app/api/endpoints/search.py b/app/api/endpoints/search.py index 345f0b10..ecd64714 100644 --- a/app/api/endpoints/search.py +++ b/app/api/endpoints/search.py @@ -7,6 +7,7 @@ from app.chain.media import MediaChain from app.chain.search import SearchChain from app.core.config import settings from app.core.security import verify_token +from app.db.user_oper import check_user_permission from app.schemas.types import MediaType router = APIRouter() @@ -25,11 +26,12 @@ def search_latest(_: schemas.TokenPayload = Depends(verify_token)) -> Any: def search_by_id(mediaid: str, mtype: str = None, area: str = "title", - season: str = None, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + season: str = None) -> Any: """ 根据TMDBID/豆瓣ID精确搜索站点资源 tmdb:/douban:/bangumi: """ + # 检查用户权限 + check_user_permission(permission='resource.search') if mtype: mtype = MediaType(mtype) if season: @@ -95,6 +97,8 @@ def search_by_title(keyword: str = None, """ 根据名称模糊搜索站点资源,支持分页,关键词为空是返回首页资源 """ + # 检查用户权限 + check_user_permission(permission='resource.search') torrents = SearchChain().search_by_title(title=keyword, page=page, site=site) if not torrents: return schemas.Response(success=False, message="未搜索到任何资源") diff --git a/app/api/endpoints/site.py b/app/api/endpoints/site.py index eabeabf4..a601e7b3 100644 --- a/app/api/endpoints/site.py +++ b/app/api/endpoints/site.py @@ -26,7 +26,7 @@ router = APIRouter() @router.get("/", summary="所有站点", response_model=List[schemas.Site]) def read_sites(db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> List[dict]: """ 获取站点列表 """ @@ -38,7 +38,7 @@ def add_site( *, db: Session = Depends(get_db), site_in: schemas.Site, - _: schemas.TokenPayload = Depends(verify_token) + _: schemas.TokenPayload = Depends(get_current_active_superuser) ) -> Any: """ 新增站点 @@ -75,7 +75,7 @@ def update_site( *, db: Session = Depends(get_db), site_in: schemas.Site, - _: schemas.TokenPayload = Depends(verify_token) + _: schemas.TokenPayload = Depends(get_current_active_superuser) ) -> Any: """ 更新站点信息 @@ -96,7 +96,7 @@ def update_site( @router.get("/cookiecloud", summary="CookieCloud同步", response_model=schemas.Response) def cookie_cloud_sync(background_tasks: BackgroundTasks, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 运行CookieCloud同步站点信息 """ @@ -127,7 +127,7 @@ def reset(db: Session = Depends(get_db), def update_sites_priority( priorities: List[dict], db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 批量更新站点优先级 """ @@ -145,7 +145,7 @@ def update_cookie( password: str, code: str = None, db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 使用用户密码更新站点Cookie """ @@ -205,7 +205,7 @@ def site_icon(site_id: int, @router.get("/resource/{site_id}", summary="站点资源", response_model=List[schemas.TorrentInfo]) def site_resource(site_id: int, db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 浏览站点资源 """ @@ -257,7 +257,8 @@ def read_site_by_domain( @router.get("/rss", summary="所有订阅站点", response_model=List[schemas.Site]) -def read_rss_sites(db: Session = Depends(get_db)) -> List[dict]: +def read_rss_sites(db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: """ 获取站点列表 """ @@ -278,7 +279,7 @@ def read_rss_sites(db: Session = Depends(get_db)) -> List[dict]: def read_site( site_id: int, db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token) + _: schemas.TokenPayload = Depends(get_current_active_superuser) ) -> Any: """ 通过ID获取站点信息 diff --git a/app/api/endpoints/storage.py b/app/api/endpoints/storage.py index 2bed0d48..5d0497e4 100644 --- a/app/api/endpoints/storage.py +++ b/app/api/endpoints/storage.py @@ -10,6 +10,7 @@ from app.chain.transfer import TransferChain from app.core.config import settings from app.core.metainfo import MetaInfoPath from app.core.security import verify_token, verify_uri_token +from app.db.user_oper import get_current_active_superuser from app.helper.progress import ProgressHelper from app.schemas.types import ProgressKey @@ -41,7 +42,7 @@ def check(_: schemas.TokenPayload = Depends(verify_token)) -> Any: @router.post("/list", summary="所有目录和文件", response_model=List[schemas.FileItem]) def list(fileitem: schemas.FileItem, sort: str = 'updated_at', - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 查询当前目录下所有目录和文件 :param fileitem: 文件项 @@ -60,7 +61,7 @@ def list(fileitem: schemas.FileItem, @router.post("/mkdir", summary="创建目录", response_model=schemas.Response) def mkdir(fileitem: schemas.FileItem, name: str, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 创建目录 :param fileitem: 文件项 @@ -77,7 +78,7 @@ def mkdir(fileitem: schemas.FileItem, @router.post("/delete", summary="删除文件或目录", response_model=schemas.Response) def delete(fileitem: schemas.FileItem, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 删除文件或目录 :param fileitem: 文件项 @@ -109,7 +110,7 @@ def download(fileitem: schemas.FileItem, def rename(fileitem: schemas.FileItem, new_name: str, recursive: bool = False, - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 重命名文件或目录 :param fileitem: 文件项 diff --git a/app/api/endpoints/transfer.py b/app/api/endpoints/transfer.py index f11b1bf0..7529bcf5 100644 --- a/app/api/endpoints/transfer.py +++ b/app/api/endpoints/transfer.py @@ -12,6 +12,7 @@ from app.core.metainfo import MetaInfoPath from app.core.security import verify_token, verify_apitoken from app.db import get_db from app.db.models.transferhistory import TransferHistory +from app.db.user_oper import get_current_active_superuser from app.schemas import MediaType, FileItem router = APIRouter() @@ -63,7 +64,7 @@ def manual_transfer(fileitem: FileItem = None, min_filesize: int = 0, scrape: bool = None, db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: + _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 手动转移,文件或历史记录,支持自定义剧集识别格式 :param fileitem: 文件信息 diff --git a/app/db/user_oper.py b/app/db/user_oper.py index 0007f7e2..79934579 100644 --- a/app/db/user_oper.py +++ b/app/db/user_oper.py @@ -48,7 +48,7 @@ def get_current_active_superuser( return current_user -def get_current_active_permission_user( +def check_user_permission( permission: str, current_user: User = Depends(get_current_user) ) -> User: @@ -57,9 +57,13 @@ def get_current_active_permission_user( """ if not current_user.is_active: raise HTTPException(status_code=403, detail="用户未激活") + if current_user.is_superuser: + return current_user if not current_user.permissions: raise HTTPException(status_code=400, detail="用户权限不足") permission_dict = json.loads(current_user.permissions) + if permission_dict.get("admin"): + return current_user for key in permission.split("."): if key not in permission_dict or not permission_dict[key]: raise HTTPException(status_code=400, detail="用户权限不足")