Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions airflow-core/src/airflow/api_fastapi/logging/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ async def log_action(
masked_body_json = {}

if has_json_body:
request_body = await request.json()
if isinstance(request_body, dict):
# Non-dict bodies fall through to the endpoint's own 422.
parsed_body = await request.json()
if isinstance(parsed_body, dict):
request_body = parsed_body
masked_body_json = {k: secrets_masker.redact(v, k) for k, v in request_body.items()}

if event_name in skip_dry_run_events and request_body.get("dry_run", True):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,28 @@ def test_post_should_respond_422_for_invalid_conn_id(self, test_client, body):
]
}

@pytest.mark.parametrize(
"body",
[
[{"connection_id": TEST_CONN_ID, "conn_type": TEST_CONN_TYPE}],
'{"connection_id": "a"}',
42,
],
ids=["list", "string", "number"],
)
def test_post_should_respond_422_for_non_dict_json_body(self, test_client, session, body):
"""The audit-log dependency reads the body before validation, so a non-object body still gets a 422."""
response = test_client.post("/connections", json=body)
assert response.status_code == 422
assert response.json()["detail"][0]["loc"] == ["body"]
_check_last_log(
session,
dag_id=None,
event="post_connection",
logical_date=None,
expected_extra={"method": "POST"},
)

@conf_vars({("core", "multi_team"): "False"})
def test_post_rejects_team_name_when_multi_team_disabled(self, test_client):
response = test_client.post(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,24 @@ def test_post_should_respond_422_when_key_too_large(self, test_client):
]
}

@pytest.mark.parametrize(
"body",
[[{"key": "new variable key", "value": "new variable value"}], '{"key": "a"}', 42],
ids=["list", "string", "number"],
)
def test_post_should_respond_422_for_non_dict_json_body(self, test_client, session, body):
"""The audit-log dependency reads the body before validation, so a non-object body still gets a 422."""
response = test_client.post("/variables", json=body)
assert response.status_code == 422
assert response.json()["detail"][0]["loc"] == ["body"]
check_last_log(
session,
dag_id=None,
event="post_variable",
logical_date=None,
expected_extra={"method": "POST"},
)

@conf_vars({("core", "multi_team"): "False"})
def test_post_rejects_team_name_when_multi_team_disabled(self, test_client):
body = {
Expand Down