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

uranusjr 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 a005969e63 Always use self.appbuilder.get_session in security managers 
(#30233)
a005969e63 is described below

commit a005969e63b0db67e2a6d9467bde98b201d3d461
Author: Tzu-ping Chung <[email protected]>
AuthorDate: Mon Mar 27 16:36:17 2023 +0800

    Always use self.appbuilder.get_session in security managers (#30233)
---
 airflow/www/security.py | 47 +++++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/airflow/www/security.py b/airflow/www/security.py
index c152c43cec..72b2b95acb 100644
--- a/airflow/www/security.py
+++ b/airflow/www/security.py
@@ -213,7 +213,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
     def _get_root_dag_id(self, dag_id):
         if "." in dag_id:
             dm = (
-                self.get_session.query(DagModel.dag_id, DagModel.root_dag_id)
+                self.appbuilder.get_session.query(DagModel.dag_id, 
DagModel.root_dag_id)
                 .filter(DagModel.dag_id == dag_id)
                 .first()
             )
@@ -258,7 +258,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
 
         :param role_name: the name of a role in the ab_role table
         """
-        session = self.get_session
+        session = self.appbuilder.get_session
         role = session.query(Role).filter(Role.name == role_name).first()
         if role:
             self.log.info("Deleting role '%s'", role_name)
@@ -462,7 +462,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
     def clean_perms(self):
         """FAB leaves faulty permissions that need to be cleaned up"""
         self.log.debug("Cleaning faulty perms")
-        sesh = self.get_session
+        sesh = self.appbuilder.get_session
         perms = sesh.query(Permission).filter(
             or_(
                 Permission.action == None,  # noqa
@@ -495,7 +495,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
         perm = None
         if action and resource:
             perm = (
-                self.get_session.query(self.permission_model)
+                self.appbuilder.get_session.query(self.permission_model)
                 .filter_by(action=action, resource=resource)
                 .first()
             )
@@ -513,12 +513,12 @@ class AirflowSecurityManager(SecurityManager, 
LoggingMixin):
         for role in custom_roles:
             self.add_permission_to_role(role, website_permission)
 
-        self.get_session.commit()
+        self.appbuilder.get_session.commit()
 
     def get_all_permissions(self) -> set[tuple[str, str]]:
         """Returns all permissions as a set of tuples with the action and 
resource names"""
         return set(
-            self.get_session.query(self.permission_model)
+            self.appbuilder.get_session.query(self.permission_model)
             .join(self.permission_model.action)
             .join(self.permission_model.resource)
             .with_entities(self.action_model.name, self.resource_model.name)
@@ -533,7 +533,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
         return {
             (action_name, resource_name): viewmodel
             for action_name, resource_name, viewmodel in (
-                self.get_session.query(self.permission_model)
+                self.appbuilder.get_session.query(self.permission_model)
                 .join(self.permission_model.action)
                 .join(self.permission_model.resource)
                 
.filter(~self.resource_model.name.like(f"{permissions.RESOURCE_DAG_PREFIX}%"))
@@ -546,8 +546,8 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
         """Returns a dict with a key of role name and value of role with early 
loaded permissions"""
         return {
             r.name: r
-            for r in (
-                
self.get_session.query(self.role_model).options(joinedload(self.role_model.permissions)).all()
+            for r in 
self.appbuilder.get_session.query(self.role_model).options(
+                joinedload(self.role_model.permissions)
             )
         }
 
@@ -584,20 +584,19 @@ class AirflowSecurityManager(SecurityManager, 
LoggingMixin):
 
         :return: None.
         """
-        dag_resources = (
-            self.get_session.query(Resource)
-            .filter(Resource.name.like(f"{permissions.RESOURCE_DAG_PREFIX}%"))
-            .all()
+        session = self.appbuilder.get_session
+        dag_resources = session.query(Resource).filter(
+            Resource.name.like(f"{permissions.RESOURCE_DAG_PREFIX}%")
         )
         resource_ids = [resource.id for resource in dag_resources]
-        perms = 
self.get_session.query(Permission).filter(~Permission.resource_id.in_(resource_ids)).all()
 
+        perms = 
session.query(Permission).filter(~Permission.resource_id.in_(resource_ids))
         perms = [p for p in perms if p.action and p.resource]
 
         admin = self.find_role("Admin")
         admin.permissions = list(set(admin.permissions) | set(perms))
 
-        self.get_session.commit()
+        session.commit()
 
     def sync_roles(self):
         """
@@ -739,12 +738,20 @@ class AirflowSecurityManager(SecurityManager, 
LoggingMixin):
         return True
 
 
+class FakeAppBuilder:
+    """Stand-in class to replace a Flask App Builder.
+
+    The only purpose is to provide the ``self.appbuilder.get_session`` 
interface
+    for ``ApplessAirflowSecurityManager`` so it can be used without a real 
Flask
+    app, which is slow to create.
+    """
+
+    def __init__(self, session: Session | None = None) -> None:
+        self.get_session = session
+
+
 class ApplessAirflowSecurityManager(AirflowSecurityManager):
     """Security Manager that doesn't need the whole flask app"""
 
     def __init__(self, session: Session | None = None):
-        self.session = session
-
-    @property
-    def get_session(self):
-        return self.session
+        self.appbuilder = FakeAppBuilder(session)

Reply via email to