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."""

Reply via email to