fix(api): rename verify endpoint and redact 422 request input

Rename the deployment provider credential verification route to /deployments/providers/verify and sanitize RequestValidationError responses so raw request payloads are not echoed back in 422 errors. Update route/tests accordingly, including regression coverage for input redaction.
This commit is contained in:
Hamza Rashid
2026-04-02 21:50:26 +00:00
committed by himavarshagoutham
parent 0d60609104
commit e598dc954c
2 changed files with 32 additions and 1 deletions

View File

@ -8,13 +8,14 @@ import warnings
from contextlib import asynccontextmanager, suppress
from http import HTTPStatus
from pathlib import Path
from typing import TYPE_CHECKING, cast
from typing import TYPE_CHECKING, Any, cast
from urllib.parse import urlencode
import anyio
import httpx
import sqlalchemy
from fastapi import FastAPI, HTTPException, Request, Response, status
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
@ -78,6 +79,11 @@ async def log_exception_to_telemetry(exc: Exception, context: str) -> None:
await logger.awarning(f"Failed to log {context} exception to telemetry")
def _sanitize_validation_errors(errors: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""Strip request payload echoes from validation errors to avoid leaking submitted data."""
return [{key: value for key, value in error.items() if key != "input"} for error in errors]
class RequestCancelledMiddleware(BaseHTTPMiddleware):
def __init__(self, app) -> None:
super().__init__(app)
@ -560,6 +566,13 @@ def create_app():
# Discover and register additional routers from plugins (langflow.plugins entry-point)
load_plugin_routes(app)
@app.exception_handler(RequestValidationError)
async def request_validation_exception_handler(_request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": _sanitize_validation_errors(exc.errors())},
)
@app.exception_handler(Exception)
async def exception_handler(_request: Request, exc: Exception):
if isinstance(exc, HTTPException):

View File

@ -134,6 +134,24 @@ async def test_create_project_validation_error(client: AsyncClient, logged_in_he
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
async def test_create_project_validation_error_does_not_echo_request_input(client: AsyncClient, logged_in_headers):
"""Regression test: request-validation 422 responses must not echo submitted payloads."""
sensitive_marker = "secret-api-key-should-not-echo"
response = await client.post(
"api/v1/projects/",
# Send a JSON string (instead of object) to trigger RequestValidationError consistently.
content=json.dumps(sensitive_marker),
headers={**logged_in_headers, "Content-Type": "application/json"},
)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
detail = response.json()["detail"]
assert isinstance(detail, list)
assert detail
assert all("input" not in error for error in detail)
assert sensitive_marker not in response.text
async def test_delete_project_then_404(client: AsyncClient, logged_in_headers, basic_case):
create_resp = await client.post("api/v1/projects/", json=basic_case, headers=logged_in_headers)
proj_id = create_resp.json()["id"]