This is an automated email from the ASF dual-hosted git repository.

potiuk 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 a61b5e893a Fix issues related to access_control={} (#34114)
a61b5e893a is described below

commit a61b5e893af83d3022aa8265f230b52c5b2ad93d
Author: Sam Wheating <[email protected]>
AuthorDate: Wed Sep 6 17:57:31 2023 -0700

    Fix issues related to access_control={} (#34114)
    
    * allow empty access control on dags
    
    * Add test which demonstrates loss of information during ser/de
    
    * Keep empty value when serializing access_control dict
---
 airflow/models/dag.py                         | 2 +-
 airflow/serialization/serialized_objects.py   | 8 ++++++++
 airflow/www/security.py                       | 2 +-
 tests/serialization/test_dag_serialization.py | 9 +++++++++
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/airflow/models/dag.py b/airflow/models/dag.py
index 642d617804..2cdcfc197a 100644
--- a/airflow/models/dag.py
+++ b/airflow/models/dag.py
@@ -779,7 +779,7 @@ class DAG(LoggingMixin):
         will be replaced with 'can_read', in {'role2': {'can_dag_read', 
'can_dag_edit'}}
         'can_dag_edit' will be replaced with 'can_edit', etc.
         """
-        if not access_control:
+        if access_control is None:
             return None
         new_perm_mapping = {
             permissions.DEPRECATED_ACTION_CAN_DAG_READ: 
permissions.ACTION_CAN_READ,
diff --git a/airflow/serialization/serialized_objects.py 
b/airflow/serialization/serialized_objects.py
index a7a712cf11..fa8e638d80 100644
--- a/airflow/serialization/serialized_objects.py
+++ b/airflow/serialization/serialized_objects.py
@@ -1400,6 +1400,14 @@ class SerializedDAG(DAG, BaseSerialization):
 
         return dag
 
+    @classmethod
+    def _is_excluded(cls, var: Any, attrname: str, op: DAGNode):
+        # {} is explicitly different from None in the case of DAG-level access 
control
+        # and as a result we need to preserve empty dicts through 
serialization for this field
+        if attrname == "_access_control" and var is not None:
+            return False
+        return super()._is_excluded(var, attrname, op)
+
     @classmethod
     def to_dict(cls, var: Any) -> dict:
         """Stringifies DAGs and operators contained by var and returns a dict 
of var."""
diff --git a/airflow/www/security.py b/airflow/www/security.py
index 7dcf2c30d0..d7ccea66de 100644
--- a/airflow/www/security.py
+++ b/airflow/www/security.py
@@ -603,7 +603,7 @@ class AirflowSecurityManager(SecurityManagerOverride, 
SecurityManager, LoggingMi
                 if (action_name, dag_resource_name) not in perms:
                     self._merge_perm(action_name, dag_resource_name)
 
-            if dag.access_control:
+            if dag.access_control is not None:
                 self.sync_perm_for_dag(dag_resource_name, dag.access_control)
 
     def update_admin_permission(self) -> None:
diff --git a/tests/serialization/test_dag_serialization.py 
b/tests/serialization/test_dag_serialization.py
index 7ecadf9d2a..f1c109e77b 100644
--- a/tests/serialization/test_dag_serialization.py
+++ b/tests/serialization/test_dag_serialization.py
@@ -430,6 +430,15 @@ class TestStringifiedDAGs:
                 print(task["task_id"], k, v)
         assert actual == expected
 
+    def test_dag_serialization_preserves_empty_access_roles(self):
+        """Verify that an explicitly empty access_control dict is preserved."""
+        dag = collect_dags(["airflow/example_dags"])["simple_dag"]
+        dag.access_control = {}
+        serialized_dag = SerializedDAG.to_dict(dag)
+        SerializedDAG.validate_schema(serialized_dag)
+
+        assert serialized_dag["dag"]["_access_control"] == {"__type": "dict", 
"__var": {}}
+
     def test_dag_serialization_unregistered_custom_timetable(self):
         """Verify serialization fails without timetable registration."""
         dag = 
get_timetable_based_simple_dag(CustomSerializationTimetable("bar"))

Reply via email to