pierrejeambrun commented on code in PR #76453:
URL: https://github.com/apache/airflow/pull/76453#discussion_r4515313243


##########
airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py:
##########
@@ -389,16 +390,34 @@ def test_connection(
                 existing_conn = None
 
         if existing_conn is not None:
-            # Stored credentials are only reused to test the connection's own
-            # host/port; testing a different destination must supply its own.
+            # Stored credentials are only reused to test the stored connection 
itself;
+            # testing a different one must supply its own. Besides host and 
port, the
+            # connection type, schema, login and extra also decide where and 
how a hook
+            # connects (e.g. a URL in schema, or proxies and endpoints in 
extra).
             fields_set = test_body.model_fields_set
             host_changed = "host" in fields_set and not 
_same_endpoint(test_body.host, existing_conn.host)
             port_changed = "port" in fields_set and not 
_same_endpoint(test_body.port, existing_conn.port)
-            if host_changed or port_changed:
+            conn_type_changed = test_body.conn_type != existing_conn.conn_type
+            schema_changed = "schema_" in fields_set and not _same_endpoint(
+                test_body.schema_, existing_conn.schema
+            )
+            login_changed = "login" in fields_set and not 
_same_endpoint(test_body.login, existing_conn.login)
+            # Compare with the stored extra as the API shows it, with its 
secrets masked.
+            extra_changed = "extra" in fields_set and 
json.loads(test_body.extra or "{}") != json.loads(
+                ConnectionResponse.model_validate(existing_conn).extra or "{}"
+            )
+            if (
+                host_changed
+                or port_changed
+                or conn_type_changed
+                or schema_changed
+                or login_changed
+                or extra_changed
+            ):

Review Comment:
   Thanks, done in f5e355f97f8. One difference from the suggestion: `conn_type` 
is still compared on its own and first, because a stored connection without a 
type cannot be read as a `ConnectionResponse`, and building it only once the 
types match keeps that case a 400 rather than a 500.



##########
airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py:
##########
@@ -389,16 +390,34 @@ def test_connection(
                 existing_conn = None
 
         if existing_conn is not None:
-            # Stored credentials are only reused to test the connection's own
-            # host/port; testing a different destination must supply its own.
+            # Stored credentials are only reused to test the stored connection 
itself;
+            # testing a different one must supply its own. Besides host and 
port, the
+            # connection type, schema, login and extra also decide where and 
how a hook
+            # connects (e.g. a URL in schema, or proxies and endpoints in 
extra).
             fields_set = test_body.model_fields_set
             host_changed = "host" in fields_set and not 
_same_endpoint(test_body.host, existing_conn.host)
             port_changed = "port" in fields_set and not 
_same_endpoint(test_body.port, existing_conn.port)
-            if host_changed or port_changed:
+            conn_type_changed = test_body.conn_type != existing_conn.conn_type
+            schema_changed = "schema_" in fields_set and not _same_endpoint(
+                test_body.schema_, existing_conn.schema
+            )
+            login_changed = "login" in fields_set and not 
_same_endpoint(test_body.login, existing_conn.login)
+            # Compare with the stored extra as the API shows it, with its 
secrets masked.
+            extra_changed = "extra" in fields_set and 
json.loads(test_body.extra or "{}") != json.loads(
+                ConnectionResponse.model_validate(existing_conn).extra or "{}"
+            )

Review Comment:
   Good catch that pattern masking depends on what the process has registered. 
Two workers can disagree when a non-sensitive extra value contains a password 
some other connection registered, which is rare and fails closed (a 400 asking 
for credentials). I'd rather not run the request body through `redact` too: a 
new value under a sensitive key like `api_key` would then read as `***` on both 
sides, count as unchanged, and reuse the stored password. That's what this 
check is here to prevent, so I'd keep comparing the raw request against the 
masked stored view.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to