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


##########
airflow-core/tests/unit/api_fastapi/auth/middlewares/test_refresh_token.py:
##########
@@ -146,15 +146,15 @@ async def test_dispatch_with_refreshed_user(
             pytest.param("http", "", False, id="http-no-local-ssl-cert"),
         ],
     )
+    
@patch("airflow.api_fastapi.auth.middlewares.refresh_token.request_cookie_is_secure")
     
@patch("airflow.api_fastapi.auth.middlewares.refresh_token.get_auth_manager")
     
@patch("airflow.api_fastapi.auth.middlewares.refresh_token.resolve_user_from_token")
-    @patch("airflow.api_fastapi.auth.middlewares.refresh_token.conf")
     @pytest.mark.asyncio
     async def test_dispatch_cookie_secure_flag(

Review Comment:
   `mock_request_cookie_is_secure` is mocking the secure flag. `"scheme", 
"ssl_cert"` parametrization isn't doing anything now, can be removed.



##########
providers/fab/src/airflow/providers/fab/auth_manager/fab_auth_manager.py:
##########
@@ -373,11 +373,14 @@ def build_public_user(self, *, session: Session = 
NEW_SESSION) -> AnonymousUser
 
     def get_fastapi_middlewares(self) -> list[tuple[_MiddlewareFactory[Any], 
dict[str, Any]]]:
         """Register the FAB public-access middleware when public access is 
configured."""
+        middleware = super().get_fastapi_middlewares() if AIRFLOW_V_3_3_PLUS 
else []

Review Comment:
   Condition isn't good there, 3.3.1 was just released, this will be shipped in 
3.3.2 I guess.



##########
airflow-core/src/airflow/api_fastapi/auth/middlewares/refresh_token.py:
##########
@@ -45,58 +50,114 @@ class JWTRefreshMiddleware(BaseHTTPMiddleware):
 
     async def dispatch(self, request: Request, call_next):
         new_token = None
-        current_token = request.cookies.get(COOKIE_NAME_JWT_TOKEN)
+        current_user = None
+        new_user = None
         try:
-            if current_token is not None:
-                try:
-                    new_user, current_user = await 
self._refresh_user(current_token)
-                    if user := (new_user or current_user):
-                        # Stamp the trust sentinel alongside the user so 
`get_user()`
-                        # can distinguish this trusted assignment from a stray 
write
-                        # by unrelated middleware.
-                        request.state.user = user
-                        request.state.user_authenticated_via = 
USER_INJECTED_BY_TRUSTED_MIDDLEWARE
-                    if new_user:
-                        # If we created a new user, serialize it and set it as 
a cookie
-                        new_token = get_auth_manager().generate_jwt(new_user)
-                except (HTTPException, 
AuthManagerRefreshTokenExpiredException):
-                    # Receive a HTTPException when the Airflow token is expired
-                    # Receive a AuthManagerRefreshTokenExpiredException when 
the potential underlying refresh
-                    # token used by the auth manager is expired
-                    new_token = ""
+            try:
+                new_user, current_user = await self._refresh_user(request)
+            except (HTTPException, AuthManagerRefreshTokenExpiredException):
+                # Receive a HTTPException when the Airflow token is expired
+                # Receive a AuthManagerRefreshTokenExpiredException when the 
potential underlying refresh
+                # token used by the auth manager is expired
+                new_token = ""
+
+            if user := (new_user or current_user):
+                # Stamp the trust sentinel alongside the user so `get_user()`
+                # can distinguish this trusted assignment from a stray write
+                # by unrelated middleware.
+                request.state.user = user
+                request.state.user_authenticated_via = 
USER_INJECTED_BY_TRUSTED_MIDDLEWARE
 
             response = await call_next(request)
 
-            if new_token is not None:
+            if new_user or new_token is not None:
+                secure = request_cookie_is_secure(request)
                 cookie_path = get_cookie_path()
-                secure = request.base_url.scheme == "https" or 
bool(conf.get("api", "ssl_cert", fallback=""))
-                response.set_cookie(
-                    COOKIE_NAME_JWT_TOKEN,
-                    new_token,
-                    path=cookie_path,
-                    httponly=True,
-                    secure=secure,
-                    samesite="lax",
-                    max_age=0 if new_token == "" else None,
-                )
-                # Clear any stale _token cookie at root path "/".
-                # Older Airflow instances may have set the cookie there;
-                # without this, the root-path cookie keeps being sent on
-                # every request, causing an infinite redirect loop.
-                if cookie_path != "/":
-                    response.delete_cookie(

Review Comment:
   delete cookie was replaced with a call to `set_cookie`. It's not exactly the 
same, can we keep `delete_cookie`. (expires isn't passed down)
   



##########
providers/fab/tests/unit/fab/auth_manager/test_fab_auth_manager.py:
##########
@@ -328,8 +329,12 @@ def test_get_fastapi_middlewares_disabled(self, flask_app, 
auth_manager_with_app
         """No middleware is registered when public access is not configured."""
         previous = flask_app.config.get("AUTH_ROLE_PUBLIC")
         flask_app.config["AUTH_ROLE_PUBLIC"] = None
+        base_middleware = []
+        if AIRFLOW_V_3_4_PLUS:

Review Comment:
   Why AIRFLOW_V_3_4_PLUS here? 



##########
airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py:
##########
@@ -180,7 +180,17 @@ def get_fastapi_middlewares(self) -> 
list[tuple[_MiddlewareFactory[Any], dict[st
         unauthenticated requests when public access is configured) should 
override this
         method.
         """
-        return []
+        return [self._get_jwt_refresh_middleware()]
+
+    def _get_jwt_refresh_middleware(self) -> tuple[_MiddlewareFactory[Any], 
dict[str, Any]]:
+        """
+        Return the JWTRefreshMiddleware to refresh the Airflow JWT token.
+
+        :important: The JWTRefreshMiddleware should be included in 
get_fastapi_middlewares()
+        """
+        from airflow.api_fastapi.auth.middlewares.refresh_token import 
JWTRefreshMiddleware

Review Comment:
   Why a local import?



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