diff --git a/platform/backend/app/api/articles.py b/platform/backend/app/api/articles.py index 7708b57..844e579 100644 --- a/platform/backend/app/api/articles.py +++ b/platform/backend/app/api/articles.py @@ -1,3 +1,4 @@ +import re from fastapi import APIRouter, HTTPException, Query, Depends, Body from sqlalchemy.orm import Session from sqlalchemy import or_ @@ -171,6 +172,8 @@ def get_optimization_report(publish_date: str = None, current_user: User = Depen """获取合规优化报告""" if not publish_date: publish_date = date.today().isoformat() + if not re.match(r'^\d{4}-\d{2}-\d{2}$', publish_date): + raise HTTPException(status_code=400, detail="Invalid date format (expected YYYY-MM-DD)") PROJECT_ROOT = Path('/root/openclaw-workspace/projects/yu-zhi-ran') report_path = PROJECT_ROOT / "automation" / "data" / "drafts" / publish_date / "optimization_report.json" if not report_path.exists(): diff --git a/platform/backend/app/api/optimizer_logs.py b/platform/backend/app/api/optimizer_logs.py index 1cd9a65..c1271b3 100644 --- a/platform/backend/app/api/optimizer_logs.py +++ b/platform/backend/app/api/optimizer_logs.py @@ -1,3 +1,4 @@ +import re from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from pathlib import Path @@ -58,6 +59,11 @@ def get_logs( """ if not type or not date: raise HTTPException(status_code=400, detail="type and date parameters are required") + _ALLOWED_LOG_TYPES = {"creator", "collector", "optimizer", "sources", "metrics", "trends", "rank_tracker"} + if type not in _ALLOWED_LOG_TYPES: + raise HTTPException(status_code=400, detail=f"Invalid log type: {type}") + if not re.match(r'^\d{4}-\d{2}-\d{2}$', date): + raise HTTPException(status_code=400, detail="Invalid date format (expected YYYY-MM-DD)") logs_dir = PROJECT_ROOT / "automation" / "logs" filename = f"{type}_{date}.log" log_path = logs_dir / filename diff --git a/platform/backend/app/api/platform_config.py b/platform/backend/app/api/platform_config.py index e70ecad..54a7e5e 100644 --- a/platform/backend/app/api/platform_config.py +++ b/platform/backend/app/api/platform_config.py @@ -5,7 +5,7 @@ from typing import List, Optional from ..database import get_db from ..models import PlatformConfig from ..schemas import PlatformConfigCreate, PlatformConfigUpdate, PlatformConfigResponse -from .auth import get_current_user +from .auth import get_current_admin router = APIRouter(prefix="/api/platform-config", tags=["platform-config"]) @@ -14,7 +14,7 @@ router = APIRouter(prefix="/api/platform-config", tags=["platform-config"]) def list_platforms( active_only: bool = True, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): query = db.query(PlatformConfig) if active_only: @@ -26,7 +26,7 @@ def list_platforms( def create_platform( data: PlatformConfigCreate, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): existing = db.query(PlatformConfig).filter(PlatformConfig.platform == data.platform).first() if existing: @@ -39,7 +39,7 @@ def create_platform( @router.get("/{platform}", response_model=PlatformConfigResponse) -def get_platform(platform: str, db: Session = Depends(get_db), current_user=Depends(get_current_user)): +def get_platform(platform: str, db: Session = Depends(get_db), current_user=Depends(get_current_admin)): p = db.query(PlatformConfig).filter(PlatformConfig.platform == platform).first() if not p: raise HTTPException(status_code=404, detail="平台不存在") @@ -47,7 +47,7 @@ def get_platform(platform: str, db: Session = Depends(get_db), current_user=Depe @router.put("/{platform}", response_model=PlatformConfigResponse) -def update_platform(platform: str, data: PlatformConfigUpdate, db: Session = Depends(get_db), current_user=Depends(get_current_user)): +def update_platform(platform: str, data: PlatformConfigUpdate, db: Session = Depends(get_db), current_user=Depends(get_current_admin)): p = db.query(PlatformConfig).filter(PlatformConfig.platform == platform).first() if not p: raise HTTPException(status_code=404, detail="平台不存在") @@ -59,7 +59,7 @@ def update_platform(platform: str, data: PlatformConfigUpdate, db: Session = Dep @router.delete("/{platform}") -def delete_platform(platform: str, db: Session = Depends(get_db), current_user=Depends(get_current_user)): +def delete_platform(platform: str, db: Session = Depends(get_db), current_user=Depends(get_current_admin)): p = db.query(PlatformConfig).filter(PlatformConfig.platform == platform).first() if not p: raise HTTPException(status_code=404, detail="平台不存在") diff --git a/platform/backend/app/api/system.py b/platform/backend/app/api/system.py index 38d5762..663cd3c 100644 --- a/platform/backend/app/api/system.py +++ b/platform/backend/app/api/system.py @@ -17,7 +17,7 @@ from ..core.collector import run_collector, get_collector_status, _running_proce import threading from ..core.sync import sync_all_topics from ..core.scheduler import scheduler -from .auth import get_current_user, org_filter +from .auth import get_current_user, get_current_admin, org_filter PROJECT_ROOT = Path(__file__).resolve().parents[4] if os.getenv('PROJECT_ROOT'): @@ -211,8 +211,14 @@ def review_status(): return {"status": "idle", "message": "当前无运行中的审查任务"} return status +_ALLOWED_LOG_TYPES = {"creator", "collector", "optimizer", "sources", "metrics", "trends", "rank_tracker"} + @router.get("/logs/{log_date}", dependencies=[Depends(get_current_user)]) def get_logs(log_date: str, log_type: str = "creator"): + if log_type not in _ALLOWED_LOG_TYPES: + raise HTTPException(status_code=400, detail=f"Invalid log_type: {log_type}") + if not re.match(r'^\d{4}-\d{2}-\d{2}$', log_date): + raise HTTPException(status_code=400, detail="Invalid log_date format (expected YYYY-MM-DD)") log_file = LOGS_DIR / f"{log_type}_{log_date}.log" if not log_file.exists(): raise HTTPException(status_code=404, detail=f"Log file not found: {log_file}") diff --git a/platform/backend/app/api/topic_config.py b/platform/backend/app/api/topic_config.py index 8c35a32..d3fca38 100644 --- a/platform/backend/app/api/topic_config.py +++ b/platform/backend/app/api/topic_config.py @@ -9,7 +9,7 @@ from ..schemas import ( TopicFieldBase, TopicFieldResponse, TopicConfigFieldBase, TopicConfigFieldResponse ) -from .auth import get_current_user +from .auth import get_current_admin router = APIRouter(prefix="/api/topic-config", tags=["topic-config"]) @@ -18,7 +18,7 @@ router = APIRouter(prefix="/api/topic-config", tags=["topic-config"]) def list_fields( include_inactive: bool = False, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): query = db.query(TopicField) if not include_inactive: @@ -30,7 +30,7 @@ def list_fields( def create_field( data: TopicFieldBase, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): existing = db.query(TopicField).filter(TopicField.name == data.name).first() if existing: @@ -47,7 +47,7 @@ def update_field( field_id: int, data: TopicFieldBase, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): field = db.query(TopicField).filter(TopicField.id == field_id).first() if not field: @@ -63,7 +63,7 @@ def update_field( def delete_field( field_id: int, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): field = db.query(TopicField).filter(TopicField.id == field_id).first() if not field: @@ -77,7 +77,7 @@ def delete_field( def get_scoring_fields( field_id: int, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): field = db.query(TopicField).filter(TopicField.id == field_id).first() if not field: @@ -92,7 +92,7 @@ def create_scoring_field( field_id: int, data: TopicConfigFieldBase, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): field = db.query(TopicField).filter(TopicField.id == field_id).first() if not field: @@ -117,7 +117,7 @@ def update_scoring_field( config_id: int, data: TopicConfigFieldBase, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): cfg = db.query(TopicConfigField).filter(TopicConfigField.id == config_id).first() if not cfg: @@ -133,7 +133,7 @@ def update_scoring_field( def delete_scoring_field( config_id: int, db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): cfg = db.query(TopicConfigField).filter(TopicConfigField.id == config_id).first() if not cfg: @@ -148,7 +148,7 @@ def batch_create_scoring_fields( field_id: int, fields: List[TopicConfigFieldBase], db: Session = Depends(get_db), - current_user=Depends(get_current_user) + current_user=Depends(get_current_admin) ): field = db.query(TopicField).filter(TopicField.id == field_id).first() if not field: diff --git a/platform/backend/app/api/topics.py b/platform/backend/app/api/topics.py index 23c7622..46060b3 100644 --- a/platform/backend/app/api/topics.py +++ b/platform/backend/app/api/topics.py @@ -167,7 +167,7 @@ def create_topic( try: num = int(max_topic.id[1:]) + 1 topic_id = f"T{num:03d}" - except: + except (ValueError, TypeError): topic_id = f"T{datetime.now().strftime('%m%d%H%M')}" else: topic_id = f"T{datetime.now().strftime('%m%d%H%M')}"