From 6dbaede76b297a2a0f7548e886cbbf18ee422a8e Mon Sep 17 00:00:00 2001 From: ishaanxgupta <124028055+ishaanxgupta@users.noreply.github.com> Date: Sat, 7 Mar 2026 17:55:16 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20[security=20fix]=20Add=20missing?= =?UTF-8?q?=20rate=20limiting=20to=20code=20routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/routes/code.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/api/routes/code.py b/src/api/routes/code.py index b30f122..b12b45b 100644 --- a/src/api/routes/code.py +++ b/src/api/routes/code.py @@ -15,6 +15,7 @@ from fastapi.responses import JSONResponse, StreamingResponse from src.api.dependencies import ( + enforce_rate_limit, get_code_pipeline, require_api_key, ) @@ -34,7 +35,7 @@ router = APIRouter( prefix="/v1/code", tags=["code"], - dependencies=[Depends(require_api_key)], + dependencies=[Depends(require_api_key), Depends(enforce_rate_limit)], ) @@ -52,7 +53,9 @@ def _wrap(request: Request, data: Any, elapsed_ms: float) -> JSONResponse: return resp -def _error(request: Request, detail: str, code: int, elapsed_ms: float = 0) -> JSONResponse: +def _error( + request: Request, detail: str, code: int, elapsed_ms: float = 0 +) -> JSONResponse: body = APIResponse( status=StatusEnum.ERROR, request_id=getattr(request.state, "request_id", None), @@ -66,6 +69,7 @@ def _error(request: Request, detail: str, code: int, elapsed_ms: float = 0) -> J # POST /v1/code/query # ═══════════════════════════════════════════════════════════════════════════ + @router.post( "/query", response_model=APIResponse, @@ -86,8 +90,10 @@ async def code_query(req: CodeQueryRequest, request: Request): answer=result.answer, sources=[ SourceRecord( - domain=s.domain, content=s.content, - score=round(s.score, 3), metadata=s.metadata, + domain=s.domain, + content=s.content, + score=round(s.score, 3), + metadata=s.metadata, ) for s in result.sources ], @@ -106,6 +112,7 @@ async def code_query(req: CodeQueryRequest, request: Request): # POST /v1/code/query_stream # ═══════════════════════════════════════════════════════════════════════════ + @router.post( "/query_stream", summary="Query a codebase with streaming response", @@ -127,6 +134,7 @@ async def code_query_stream(req: CodeQueryRequest, request: Request): # GET /v1/code/directory-tree # ═══════════════════════════════════════════════════════════════════════════ + def _build_tree(file_paths: List[str], repo: str) -> DirectoryNode: """Build a hierarchical tree from flat file paths.""" root = DirectoryNode(name=repo, type="directory", path="", children=[]) @@ -189,6 +197,7 @@ async def directory_tree( # GET /v1/code/repos # ═══════════════════════════════════════════════════════════════════════════ + @router.get( "/repos", response_model=APIResponse,