mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-04-10 14:09:43 +08:00
feat: enable auth in all api
This commit is contained in:
@@ -1,45 +1,19 @@
|
||||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
|
||||
from module.database.user import AuthDB
|
||||
from module.security.jwt import create_access_token, decode_token
|
||||
from module.security import create_access_token, get_current_user, update_user_info, auth_user
|
||||
from module.models.user import User
|
||||
|
||||
from .program import router
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")
|
||||
|
||||
|
||||
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
||||
if not token:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
payload = decode_token(token)
|
||||
if not payload:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
username = payload.get("sub")
|
||||
with AuthDB() as user_db:
|
||||
user = user_db.get_user(username)
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid username")
|
||||
return user
|
||||
|
||||
|
||||
async def get_token_data(token: str = Depends(oauth2_scheme)):
|
||||
payload = decode_token(token)
|
||||
if not payload:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
return payload
|
||||
|
||||
|
||||
@router.post("/api/v1/auth/login", response_model=dict, tags=["auth"])
|
||||
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
|
||||
username = form_data.username
|
||||
password = form_data.password
|
||||
with AuthDB() as db:
|
||||
if not db.auth_user(username, password):
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid username or password")
|
||||
token = create_access_token({"sub": username})
|
||||
return {"access_token": token, "token_type": "bearer", "expire": 86400}
|
||||
auth_user(username, password)
|
||||
token = create_access_token({"sub": username})
|
||||
return {"access_token": token, "token_type": "bearer", "expire": 86400}
|
||||
|
||||
|
||||
@router.get("/api/v1/auth/refresh_token", response_model=dict, tags=["auth"])
|
||||
@@ -62,12 +36,8 @@ async def logout(
|
||||
|
||||
|
||||
@router.post("/api/v1/auth/update", response_model=dict, tags=["auth"])
|
||||
async def update_user(data: User, current_user: User = Depends(get_current_user)):
|
||||
async def update_user(user_data: User, current_user: User = Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
try:
|
||||
with AuthDB() as db:
|
||||
db.update_user(current_user.username, data)
|
||||
return {"message": "update success"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
return update_user_info(user_data, current_user)
|
||||
|
||||
|
||||
@@ -1,42 +1,57 @@
|
||||
from fastapi import Depends, HTTPException, status
|
||||
|
||||
from .log import router
|
||||
|
||||
from module.models import BangumiData
|
||||
from module.database import BangumiDatabase
|
||||
from module.manager import TorrentManager
|
||||
from module.security import get_current_user
|
||||
|
||||
|
||||
@router.get("/api/v1/bangumi/getAll", tags=["bangumi"], response_model=list[BangumiData])
|
||||
async def get_all_data():
|
||||
async def get_all_data(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with TorrentManager() as torrent:
|
||||
return torrent.search_all()
|
||||
|
||||
|
||||
@router.get("/api/v1/bangumi/getData/{bangumi_id}", tags=["bangumi"], response_model=BangumiData)
|
||||
async def get_data(bangumi_id: str):
|
||||
async def get_data(bangumi_id: str, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with TorrentManager() as torrent:
|
||||
return torrent.search_data(bangumi_id)
|
||||
|
||||
|
||||
@router.post("/api/v1/bangumi/updateData", tags=["bangumi"])
|
||||
async def update_data(data: BangumiData):
|
||||
async def update_data(data: BangumiData, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with TorrentManager() as torrent:
|
||||
return torrent.update_rule(data)
|
||||
|
||||
|
||||
@router.delete("/api/v1/bangumi/deleteData/{bangumi_id}", tags=["bangumi"])
|
||||
async def delete_data(bangumi_id: str):
|
||||
async def delete_data(bangumi_id: str, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with TorrentManager() as torrent:
|
||||
return torrent.delete_data(bangumi_id)
|
||||
|
||||
|
||||
@router.delete("/api/v1/bangumi/deleteRule/{bangumi_id}", tags=["bangumi"])
|
||||
async def delete_rule(bangumi_id: str, file: bool = False):
|
||||
async def delete_rule(bangumi_id: str, file: bool = False, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with TorrentManager() as torrent:
|
||||
return torrent.delete_rule(bangumi_id, file)
|
||||
|
||||
|
||||
@router.get("/api/v1/bangumi/resetAll", tags=["bangumi"])
|
||||
async def reset_all():
|
||||
async def reset_all(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
with BangumiDatabase() as database:
|
||||
database.delete_all()
|
||||
return {"status": "ok"}
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
import logging
|
||||
|
||||
from fastapi import Depends, HTTPException, status
|
||||
|
||||
from .bangumi import router
|
||||
|
||||
from module.conf import settings
|
||||
from module.models import Config
|
||||
from module.security import get_current_user
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@router.get("/api/v1/getConfig", tags=["config"], response_model=Config)
|
||||
async def get_config():
|
||||
async def get_config(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
return settings
|
||||
|
||||
|
||||
@router.post("/api/v1/updateConfig", tags=["config"])
|
||||
async def update_config(config: Config):
|
||||
async def update_config(config: Config, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
try:
|
||||
settings.save(config_dict=config.dict())
|
||||
settings.load()
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
from fastapi import Depends, HTTPException, status
|
||||
|
||||
from .config import router
|
||||
|
||||
from module.models.api import *
|
||||
from module.models import BangumiData
|
||||
from module.manager import SeasonCollector
|
||||
from module.rss import analyser
|
||||
from module.security import get_current_user
|
||||
|
||||
|
||||
def link_process(link):
|
||||
@@ -11,7 +14,9 @@ def link_process(link):
|
||||
|
||||
|
||||
@router.post("/api/v1/download/analysis", tags=["download"])
|
||||
async def analysis(link: RssLink):
|
||||
async def analysis(link: RssLink, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
data = link_process(link.rss_link)
|
||||
if data:
|
||||
return data[0]
|
||||
@@ -20,7 +25,9 @@ async def analysis(link: RssLink):
|
||||
|
||||
|
||||
@router.post("/api/v1/download/collection", tags=["download"])
|
||||
async def download_collection(data: BangumiData):
|
||||
async def download_collection(data: BangumiData, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
if data:
|
||||
with SeasonCollector() as collector:
|
||||
collector.collect_season(data, data.rss_link[0])
|
||||
@@ -30,7 +37,9 @@ async def download_collection(data: BangumiData):
|
||||
|
||||
|
||||
@router.post("/api/v1/download/subscribe", tags=["download"])
|
||||
async def subscribe(data: BangumiData):
|
||||
async def subscribe(data: BangumiData, current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
if data:
|
||||
with SeasonCollector() as collector:
|
||||
collector.subscribe_season(data)
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import os
|
||||
from fastapi import Response
|
||||
from fastapi import Response, HTTPException, Depends, status
|
||||
|
||||
from .auth import router
|
||||
|
||||
from module.conf import LOG_PATH
|
||||
from module.security import get_current_user
|
||||
|
||||
|
||||
@router.get("/api/v1/log", tags=["log"])
|
||||
async def get_log():
|
||||
async def get_log(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
if os.path.isfile(LOG_PATH):
|
||||
with open(LOG_PATH, "r") as f:
|
||||
return Response(f.read(), media_type="text/plain")
|
||||
@@ -16,7 +19,9 @@ async def get_log():
|
||||
|
||||
|
||||
@router.get("/api/v1/log/clear", tags=["log"])
|
||||
async def clear_log():
|
||||
async def clear_log(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
if os.path.isfile(LOG_PATH):
|
||||
with open(LOG_PATH, "w") as f:
|
||||
f.write("")
|
||||
|
||||
@@ -2,12 +2,11 @@ import signal
|
||||
import logging
|
||||
import os
|
||||
|
||||
from fastapi.exceptions import HTTPException
|
||||
|
||||
|
||||
from fastapi import HTTPException, status, Depends
|
||||
from fastapi import FastAPI
|
||||
|
||||
from module.core import Program
|
||||
from module.security import get_current_user
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
program = Program()
|
||||
@@ -25,7 +24,9 @@ async def shutdown():
|
||||
|
||||
|
||||
@router.get("/api/v1/restart", tags=["program"])
|
||||
async def restart():
|
||||
async def restart(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
try:
|
||||
program.restart()
|
||||
return {"status": "ok"}
|
||||
@@ -36,7 +37,9 @@ async def restart():
|
||||
|
||||
|
||||
@router.get("/api/v1/start", tags=["program"])
|
||||
async def start():
|
||||
async def start(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
try:
|
||||
program.start()
|
||||
return {"status": "ok"}
|
||||
@@ -47,13 +50,17 @@ async def start():
|
||||
|
||||
|
||||
@router.get("/api/v1/stop", tags=["program"])
|
||||
async def stop():
|
||||
async def stop(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
program.stop()
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@router.get("/api/v1/status", tags=["program"])
|
||||
async def status():
|
||||
async def status(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
if not program.is_running:
|
||||
return {"status": "stop"}
|
||||
else:
|
||||
@@ -61,7 +68,9 @@ async def status():
|
||||
|
||||
|
||||
@router.get("/api/v1/shutdown", tags=["program"])
|
||||
async def shutdown_program():
|
||||
async def shutdown_program(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
program.stop()
|
||||
logger.info("Shutting down program...")
|
||||
os.kill(os.getpid(), signal.SIGINT)
|
||||
@@ -70,10 +79,14 @@ async def shutdown_program():
|
||||
|
||||
# Check status
|
||||
@router.get("/api/v1/check/downloader", tags=["check"])
|
||||
async def check_downloader_status():
|
||||
async def check_downloader_status(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
return program.check_downloader()
|
||||
|
||||
|
||||
@router.get("/api/v1/check/rss", tags=["check"])
|
||||
async def check_rss_status():
|
||||
async def check_rss_status(current_user=Depends(get_current_user)):
|
||||
if not current_user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
return program.check_analyser()
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
from .bangumi import BangumiDatabase
|
||||
from .user import AuthDB
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
from .jwt import create_access_token
|
||||
from .api import get_current_user, get_token_data, auth_user, update_user_info
|
||||
|
||||
46
src/module/security/api.py
Normal file
46
src/module/security/api.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
|
||||
from .jwt import decode_token
|
||||
|
||||
from module.database import AuthDB
|
||||
from module.models.user import User
|
||||
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")
|
||||
|
||||
|
||||
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
||||
if not token:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
payload = decode_token(token)
|
||||
if not payload:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
username = payload.get("sub")
|
||||
with AuthDB() as user_db:
|
||||
user = user_db.get_user(username)
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid username")
|
||||
return user
|
||||
|
||||
|
||||
async def get_token_data(token: str = Depends(oauth2_scheme)):
|
||||
payload = decode_token(token)
|
||||
if not payload:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")
|
||||
return payload
|
||||
|
||||
|
||||
def update_user_info(user_data: User, current_user):
|
||||
try:
|
||||
with AuthDB() as db:
|
||||
db.update_user(current_user.username, user_data)
|
||||
return {"message": "update success"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
def auth_user(username, password):
|
||||
with AuthDB() as db:
|
||||
if not db.auth_user(username, password):
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid username or password")
|
||||
Reference in New Issue
Block a user