This is an automated email from the ASF dual-hosted git repository.
gopidesupavan 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 dab70fbcf20 Require edit rights for async connection test updates
(#68127)
dab70fbcf20 is described below
commit dab70fbcf20ff6f2815785db2a8640965a543177
Author: GPK <[email protected]>
AuthorDate: Thu Jun 11 21:47:45 2026 +0100
Require edit rights for async connection test updates (#68127)
* Require edit rights for async connection test updates
* Fix mypy
---
.../core_api/routes/public/connections.py | 8 ++++++--
.../core_api/routes/public/test_connections.py | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py
index 7df7dd91908..a1827253180 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py
@@ -17,7 +17,7 @@
from __future__ import annotations
import os
-from typing import Annotated
+from typing import TYPE_CHECKING, Annotated
from fastapi import Depends, Header, HTTPException, Query, status
from fastapi.exceptions import RequestValidationError
@@ -71,6 +71,9 @@ from airflow.secrets.environment_variables import
CONN_ENV_PREFIX
from airflow.utils.db import create_default_connections as
db_create_default_connections
from airflow.utils.strings import get_random_string
+if TYPE_CHECKING:
+ from airflow.api_fastapi.auth.managers.base_auth_manager import
ResourceMethod
+
connections_router = AirflowRouter(tags=["Connection"], prefix="/connections")
@@ -353,8 +356,9 @@ def enqueue_connection_test(
else:
effective_team = test_body.team_name
+ auth_method: ResourceMethod = "PUT" if existing is not None and
test_body.commit_on_success else "POST"
if not get_auth_manager().is_authorized_connection(
- method="POST",
+ method=auth_method,
details=ConnectionDetails(conn_id=test_body.connection_id,
team_name=effective_team),
user=user,
):
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
index 4dd16d3b30b..6930039e1ab 100644
---
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
+++
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
@@ -25,6 +25,7 @@ import pytest
from sqlalchemy import func, select
from sqlalchemy.orm import Session
+from airflow.api_fastapi.auth.managers.base_auth_manager import BaseAuthManager
from airflow.api_fastapi.core_api.datamodels.common import BulkActionResponse,
BulkBody
from airflow.api_fastapi.core_api.datamodels.connections import ConnectionBody
from airflow.api_fastapi.core_api.services.public.connections import
BulkConnectionService
@@ -1302,6 +1303,27 @@ class TestAsyncConnectionTest(TestConnectionEndpoint):
assert ct is not None
assert ct.commit_on_success is True
+
@mock.patch("airflow.api_fastapi.core_api.routes.public.connections.get_auth_manager",
autospec=True)
+ @mock.patch.dict(os.environ, {"AIRFLOW__CORE__TEST_CONNECTION": "Enabled"})
+ def
test_post_commit_on_success_existing_connection_requires_edit_permission(
+ self, mock_get_auth_manager, test_client, session
+ ):
+ """POST /connections/enqueue-test requires edit permission when it can
update a connection."""
+ self.create_connection()
+ mock_auth_manager = mock.create_autospec(BaseAuthManager,
instance=True)
+ mock_get_auth_manager.return_value = mock_auth_manager
+ mock_auth_manager.is_authorized_connection.side_effect = lambda *,
method, details, user: (
+ method == "POST"
+ )
+ body = {**self.TEST_REQUEST_BODY, "commit_on_success": True}
+
+ response = test_client.post("/connections/enqueue-test", json=body)
+
+ assert response.status_code == 403
+ mock_auth_manager.is_authorized_connection.assert_called_once()
+ assert
mock_auth_manager.is_authorized_connection.call_args.kwargs["method"] == "PUT"
+ assert session.scalar(select(ConnectionTestRequest)) is None
+
@mock.patch.dict(os.environ, {"AIRFLOW__CORE__TEST_CONNECTION": "Enabled"})
def test_post_returns_409_for_duplicate_active_test(self, test_client,
session):
"""POST returns 409 when there's already an active test for the same
connection_id."""