mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-26 15:07:25 +08:00
revert(api): remove verification endpoint follow-up changes
Keep this PR focused on wxO adapter tenant validation via model-list fetch and drop API-layer validation endpoint and request-redaction changes.
This commit is contained in:
@ -39,6 +39,9 @@ from pydantic import AfterValidator, BaseModel, Field, ValidationInfo, model_val
|
||||
from langflow.services.database.models.deployment_provider_account.schemas import (
|
||||
DeploymentProviderKey,
|
||||
)
|
||||
from langflow.services.database.models.deployment_provider_account.utils import (
|
||||
validate_provider_url,
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Shared validation helpers
|
||||
@ -79,6 +82,10 @@ NonEmptyStr = Annotated[str, AfterValidator(_strip_nonempty)]
|
||||
"""String type that strips whitespace and rejects empty/whitespace-only values."""
|
||||
|
||||
|
||||
ValidatedUrl = Annotated[str, AfterValidator(validate_provider_url)]
|
||||
"""URL type that enforces HTTPS and normalizes."""
|
||||
|
||||
|
||||
def _validate_flow_version_ids(values: list[UUID] | None) -> list[UUID] | None:
|
||||
"""AfterValidator for optional flow_version_ids query parameter."""
|
||||
if values is None:
|
||||
|
||||
@ -8,14 +8,13 @@ import warnings
|
||||
from contextlib import asynccontextmanager, suppress
|
||||
from http import HTTPStatus
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from typing import TYPE_CHECKING, 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
|
||||
@ -79,11 +78,6 @@ 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)
|
||||
@ -566,13 +560,6 @@ 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):
|
||||
|
||||
@ -134,24 +134,6 @@ 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"]
|
||||
|
||||
Reference in New Issue
Block a user