JelyFishhhhhh commented on code in PR #73797:
URL: https://github.com/apache/airflow/pull/73797#discussion_r4265838922


##########
airflow-core/src/airflow/providers_manager.py:
##########
@@ -270,6 +270,21 @@ class ConnectionFormWidgetInfo(NamedTuple):
     is_sensitive: bool
 
 
+def _is_sensitive_form_field(field: Any) -> bool:

Review Comment:
   You're right: the field is unbound, so `field.field_class.widget` is always 
the class default, and a subclass is already rejected by the 
`allowed_field_classes` check. I've reverted to the original expression and 
removed that sentence from the description.
   
   I also dropped the `asb.py` widget change. It doesn't affect `is_sensitive`, 
and the UI takes the password format for a hook widget from its field class, 
not its widget.
   
   ---
   Drafted-by: Claude Code (Opus 5.5) (no human review before posting)



##########
shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py:
##########
@@ -54,24 +54,33 @@ def to_dict(self) -> dict[str, Any]: ...
         "access_token",
         "api_key",
         "apikey",
+        "app_key",
         "auth_header",
         "authorization",
         "bearer",
+        "certificate",
         "connection_string",
+        "credential",

Review Comment:
   Agreed, and it was wider than those two: the new names also matched 
`certificate_data`, `certificate_path`, `SSLServerCertificate`, 
`credential_pem_file`, `extra_credential` and `service_principal_oauth` in 
other providers.
   
   They are now a separate `DEFAULT_SENSITIVE_FIELD_NAMES` set, matched against 
the whole field name and its `extra__<conn_type>__<name>` form, so none of 
those match any more. `test_hiding_whole_field_names` fails against main and 
against the earlier substring version.
   
   I kept this to the allowlist rather than switching to the `format: password` 
declarations. That changes where the masker gets its field list from, so it 
seems better as a separate change.
   
   ---
   Drafted-by: Claude Code (Opus 5.5) (no human review before posting)



##########
airflow-core/tests/unit/always/test_providers_manager.py:
##########
@@ -263,6 +263,42 @@ def test_connection_form_widgets(self, 
yaml_ui_metadata_counts):
             # widgets loaded from YAML metadata only
             assert len(connections_form_widgets) == yaml_widgets
 
+    def test_sensitive_connection_fields_are_redactable(self):
+        """
+        Every connection field a provider declares as sensitive must be in the 
redaction allowlist.
+
+        Providers already state which fields are secret; this asserts 
``DEFAULT_SENSITIVE_FIELDS``
+        never drifts apart from them.
+        """
+        pytest.importorskip("flask_appbuilder", reason="connection form 
widgets need flask_appbuilder")
+
+        from airflow._shared.secrets_masker import DEFAULT_SENSITIVE_FIELDS
+        from airflow._shared.secrets_masker.secrets_masker import SecretsMasker
+
+        # Check the shipped defaults rather than the process-wide masker, whose
+        # sensitive_variables_fields is only populated once settings have been 
configured.
+        masker = SecretsMasker()
+        masker.sensitive_variables_fields = list(DEFAULT_SENSITIVE_FIELDS)
+
+        # "config" is too generic a field name to add to the allowlist; 
apprise's
+        # "config" field is handled separately.

Review Comment:
   Agreed that apprise `config` isn't covered by this PR. That's intentional: 
it's being handled as a separate change, so I've left the wording here as it is 
and will update it if needed once that change is in.
   
   ---
   Drafted-by: Claude Code (Opus 5.5) (no human review before posting)



##########
airflow-core/tests/unit/always/test_providers_manager.py:
##########
@@ -263,6 +263,42 @@ def test_connection_form_widgets(self, 
yaml_ui_metadata_counts):
             # widgets loaded from YAML metadata only
             assert len(connections_form_widgets) == yaml_widgets
 
+    def test_sensitive_connection_fields_are_redactable(self):
+        """
+        Every connection field a provider declares as sensitive must be in the 
redaction allowlist.
+
+        Providers already state which fields are secret; this asserts 
``DEFAULT_SENSITIVE_FIELDS``
+        never drifts apart from them.
+        """
+        pytest.importorskip("flask_appbuilder", reason="connection form 
widgets need flask_appbuilder")
+
+        from airflow._shared.secrets_masker import DEFAULT_SENSITIVE_FIELDS

Review Comment:
   Done, both are imported at the top of the file now.
   
   ---
   Drafted-by: Claude Code (Opus 5.5) (no human review before posting)



##########
airflow-core/tests/unit/always/test_providers_manager.py:
##########
@@ -263,6 +263,42 @@ def test_connection_form_widgets(self, 
yaml_ui_metadata_counts):
             # widgets loaded from YAML metadata only
             assert len(connections_form_widgets) == yaml_widgets
 
+    def test_sensitive_connection_fields_are_redactable(self):

Review Comment:
   Good point, added `@pytest.mark.execution_timeout(120)`.
   
   ---
   Drafted-by: Claude Code (Opus 5.5) (no human review before posting)



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