This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 1163e92068e Fix dag access control for dag_id in query param (#60935)
1163e92068e is described below
commit 1163e92068e0abe2feead1211c40edcf03cd1288
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Fri Jan 23 01:05:17 2026 +0100
Fix dag access control for dag_id in query param (#60935)
* Fix dag access control for dag_id in query param
* Fix CI
---
airflow-core/src/airflow/api_fastapi/core_api/security.py | 2 +-
.../api_fastapi/core_api/routes/public/test_dag_warning.py | 2 +-
.../unit/api_fastapi/core_api/routes/ui/test_backfills.py | 2 +-
.../unit/api_fastapi/core_api/routes/ui/test_structure.py | 10 +++++-----
airflow-core/tests/unit/api_fastapi/core_api/test_security.py | 3 +++
5 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/security.py
b/airflow-core/src/airflow/api_fastapi/core_api/security.py
index 3b92e845e73..875513c8b2e 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/security.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/security.py
@@ -152,7 +152,7 @@ def requires_access_dag(
request: Request,
user: GetUserDep,
) -> None:
- dag_id: str | None = request.path_params.get("dag_id")
+ dag_id = request.path_params.get("dag_id") or
request.query_params.get("dag_id")
dag_id = dag_id if dag_id != "~" else None
team_name = DagModel.get_team_name(dag_id) if dag_id else None
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_warning.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_warning.py
index 0d9eb862e29..68fb9473d4d 100644
---
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_warning.py
+++
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dag_warning.py
@@ -89,7 +89,7 @@ class TestGetDagWarnings:
],
)
def test_get_dag_warnings(self, test_client, query_params,
expected_total_entries, expected_messages):
- with assert_queries_count(3):
+ with assert_queries_count(3 if query_params.get("dag_id") is None else
4):
response = test_client.get("/dagWarnings", params=query_params)
assert response.status_code == 200
response_json = response.json()
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py
index 63a15042dbb..b14ef9cf1a0 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py
@@ -153,7 +153,7 @@ class TestListBackfills(TestBackfillEndpoint):
expected_response = []
for backfill in response_params:
expected_response.append(backfill_responses[backfill])
- with assert_queries_count(2):
+ with assert_queries_count(2 if test_params.get("dag_id") is None else
3):
response = test_client.get("/backfills", params=test_params)
assert response.status_code == 200
assert response.json() == {
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_structure.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_structure.py
index ded50d54a30..f4a56db93e4 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_structure.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_structure.py
@@ -303,7 +303,7 @@ class TestStructureDataEndpoint:
},
],
},
- 3,
+ 6,
),
(
{
@@ -311,7 +311,7 @@ class TestStructureDataEndpoint:
"root": "unknown_task",
},
{"edges": [], "nodes": []},
- 3,
+ 6,
),
(
{
@@ -336,7 +336,7 @@ class TestStructureDataEndpoint:
},
],
},
- 3,
+ 6,
),
(
{"dag_id": DAG_ID_EXTERNAL_TRIGGER, "external_dependencies":
True},
@@ -375,7 +375,7 @@ class TestStructureDataEndpoint:
},
],
},
- 10,
+ 13,
),
],
)
@@ -572,7 +572,7 @@ class TestStructureDataEndpoint:
],
}
- with assert_queries_count(10):
+ with assert_queries_count(13):
response = test_client.get("/structure/structure_data",
params=params)
assert response.status_code == 200
assert response.json() == expected
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/test_security.py
b/airflow-core/tests/unit/api_fastapi/core_api/test_security.py
index b0000147438..5aaf509b66b 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/test_security.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/test_security.py
@@ -154,6 +154,7 @@ class TestFastApiSecurity:
mock_get_auth_manager.return_value = auth_manager
fastapi_request = Mock()
fastapi_request.path_params = {}
+ fastapi_request.query_params = {}
requires_access_dag("GET", DagAccessEntity.CODE)(fastapi_request,
Mock())
@@ -167,9 +168,11 @@ class TestFastApiSecurity:
mock_get_auth_manager.return_value = auth_manager
fastapi_request = Mock()
fastapi_request.path_params = {}
+ fastapi_request.query_params = {}
mock_request = Mock()
mock_request.path_params.return_value = {}
+ mock_request.query_params.return_value = {}
with pytest.raises(HTTPException, match="Forbidden"):
requires_access_dag("GET", DagAccessEntity.CODE)(fastapi_request,
Mock())