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

pierrejeambrun 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 dfeeeb4aee5 AIP-84 | Fix Merged Permission for Connections and Pools 
(#47345)
dfeeeb4aee5 is described below

commit dfeeeb4aee5a37add9f64ad3fa8356b902dd15f0
Author: LIU ZHE YOU <[email protected]>
AuthorDate: Tue Mar 4 21:12:29 2025 +0800

    AIP-84 | Fix Merged Permission for Connections and Pools (#47345)
    
    * Fix security
    - requires_access_connection: is_authorized_pool -> is_authorized_connection
    - use lambda instead of new callback function
    - add type hint for requires_access_<entity>
    - user type hint should be BaseUser instead of optional BaseUser
    
    * Fix conftest of api_fastapi
    - retrieve auth_manger from app.state instead of creating a new one
---
 airflow/api_fastapi/core_api/security.py | 31 +++++++++++--------------------
 tests/api_fastapi/conftest.py            | 15 ++++++++++-----
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/airflow/api_fastapi/core_api/security.py 
b/airflow/api_fastapi/core_api/security.py
index b1da04d6791..1b000afa72c 100644
--- a/airflow/api_fastapi/core_api/security.py
+++ b/airflow/api_fastapi/core_api/security.py
@@ -78,54 +78,45 @@ async def get_user_with_exception_handling(request: 
Request) -> BaseUser | None:
 
 def requires_access_dag(method: ResourceMethod, access_entity: DagAccessEntity 
| None = None) -> Callable:
     def inner(
+        user: Annotated[BaseUser, Depends(get_user)],
         dag_id: str | None = None,
-        user: Annotated[BaseUser | None, Depends(get_user)] = None,
     ) -> None:
-        def callback():
-            return get_auth_manager().is_authorized_dag(
+        _requires_access(
+            is_authorized_callback=lambda: 
get_auth_manager().is_authorized_dag(
                 method=method, access_entity=access_entity, 
details=DagDetails(id=dag_id), user=user
             )
-
-        _requires_access(
-            is_authorized_callback=callback,
         )
 
     return inner
 
 
-def requires_access_pool(method: ResourceMethod) -> Callable:
+def requires_access_pool(method: ResourceMethod) -> Callable[[Request, 
BaseUser], None]:
     def inner(
         request: Request,
-        user: Annotated[BaseUser | None, Depends(get_user)] = None,
+        user: Annotated[BaseUser, Depends(get_user)],
     ) -> None:
         pool_name = request.path_params.get("pool_name")
 
-        def callback():
-            return get_auth_manager().is_authorized_pool(
+        _requires_access(
+            is_authorized_callback=lambda: 
get_auth_manager().is_authorized_pool(
                 method=method, details=PoolDetails(name=pool_name), user=user
             )
-
-        _requires_access(
-            is_authorized_callback=callback,
         )
 
     return inner
 
 
-def requires_access_connection(method: ResourceMethod) -> Callable:
+def requires_access_connection(method: ResourceMethod) -> Callable[[Request, 
BaseUser], None]:
     def inner(
         request: Request,
-        user: Annotated[BaseUser | None, Depends(get_user)] = None,
+        user: Annotated[BaseUser, Depends(get_user)],
     ) -> None:
         connection_id = request.path_params.get("connection_id")
 
-        def callback():
-            return get_auth_manager().is_authorized_pool(
+        _requires_access(
+            is_authorized_callback=lambda: 
get_auth_manager().is_authorized_connection(
                 method=method, 
details=ConnectionDetails(conn_id=connection_id), user=user
             )
-
-        _requires_access(
-            is_authorized_callback=callback,
         )
 
     return inner
diff --git a/tests/api_fastapi/conftest.py b/tests/api_fastapi/conftest.py
index dfbd0b4b427..6149168f0bd 100644
--- a/tests/api_fastapi/conftest.py
+++ b/tests/api_fastapi/conftest.py
@@ -18,12 +18,12 @@ from __future__ import annotations
 
 import datetime
 import os
+from typing import TYPE_CHECKING
 
 import pytest
 from fastapi.testclient import TestClient
 
 from airflow.api_fastapi.app import create_app
-from airflow.auth.managers.simple.simple_auth_manager import SimpleAuthManager
 from airflow.auth.managers.simple.user import SimpleAuthManagerUser
 from airflow.models import Connection
 from airflow.models.dag_version import DagVersion
@@ -33,6 +33,9 @@ from airflow.providers.standard.operators.empty import 
EmptyOperator
 from tests_common.test_utils.config import conf_vars
 from tests_common.test_utils.db import clear_db_connections, 
parse_and_sync_to_db
 
+if TYPE_CHECKING:
+    from airflow.auth.managers.simple.simple_auth_manager import 
SimpleAuthManager
+
 
 @pytest.fixture
 def test_client():
@@ -44,7 +47,8 @@ def test_client():
             ): 
"airflow.auth.managers.simple.simple_auth_manager.SimpleAuthManager",
         }
     ):
-        auth_manager = SimpleAuthManager()
+        app = create_app()
+        auth_manager: SimpleAuthManager = app.state.auth_manager
         # set time_very_before to 2014-01-01 00:00:00 and time_very_after to 
tomorrow
         # to make the JWT token always valid for all test cases with 
time_machine
         time_very_before = datetime.datetime(2014, 1, 1, 0, 0, 0)
@@ -57,7 +61,7 @@ def test_client():
                 
**auth_manager.serialize_user(SimpleAuthManagerUser(username="test", 
role="admin")),
             }
         )
-        yield TestClient(create_app(), headers={"Authorization": f"Bearer 
{token}"})
+        yield TestClient(app, headers={"Authorization": f"Bearer {token}"})
 
 
 @pytest.fixture
@@ -75,11 +79,12 @@ def unauthorized_test_client():
             ): 
"airflow.auth.managers.simple.simple_auth_manager.SimpleAuthManager",
         }
     ):
-        auth_manager = SimpleAuthManager()
+        app = create_app()
+        auth_manager: SimpleAuthManager = app.state.auth_manager
         token = auth_manager._get_token_signer().generate_signed_token(
             
auth_manager.serialize_user(SimpleAuthManagerUser(username="dummy", role=None))
         )
-        yield TestClient(create_app(), headers={"Authorization": f"Bearer 
{token}"})
+        yield TestClient(app, headers={"Authorization": f"Bearer {token}"})
 
 
 @pytest.fixture

Reply via email to