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 7b315cbc2ed Auth Manager should raise an invalid token error when the 
payload cann… (#48056)
7b315cbc2ed is described below

commit 7b315cbc2ed41ac36c637bf61b91e6a47ddd1b7a
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Sat Mar 22 01:17:59 2025 +0100

    Auth Manager should raise an invalid token error when the payload cann… 
(#48056)
    
    * Auth Manager should raise an invida token error when the payload cannot 
be deserialize
    
    * Fix test caching issue
---
 .../api_fastapi/auth/managers/base_auth_manager.py |  7 ++++-
 .../auth/managers/test_base_auth_manager.py        | 31 +++++++++++++++++++---
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git 
a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py 
b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
index aa8272deb4d..4aa03243605 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
@@ -101,11 +101,16 @@ class BaseAuthManager(Generic[T], LoggingMixin, 
metaclass=ABCMeta):
         """Verify the JWT token is valid and create a user object from it if 
valid."""
         try:
             payload: dict[str, Any] = await 
self._get_token_validator().avalidated_claims(token)
-            return self.deserialize_user(payload)
         except InvalidTokenError as e:
             log.error("JWT token is not valid: %s", e)
             raise e
 
+        try:
+            return self.deserialize_user(payload)
+        except (ValueError, KeyError) as e:
+            log.error("Couldn't deserialize user from token, JWT token is not 
valid: %s", e)
+            raise InvalidTokenError(str(e))
+
     def generate_jwt(
         self, user: T, *, expiration_time_in_seconds: int = 
conf.getint("api_auth", "jwt_expiration_time")
     ) -> str:
diff --git 
a/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py 
b/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
index 1af476e695e..8b7c5d1f8cc 100644
--- 
a/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
+++ 
b/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any
 from unittest.mock import AsyncMock, MagicMock, Mock, patch
 
 import pytest
+from jwt import InvalidTokenError
 
 from airflow.api_fastapi.auth.managers.base_auth_manager import 
BaseAuthManager, T
 from airflow.api_fastapi.auth.managers.models.base_user import BaseUser
@@ -178,16 +179,19 @@ class TestBaseAuthManager:
         
mock_filter_authorized_menu_items.assert_called_once_with(list(MenuItem), 
user=user)
         assert results == []
 
-    @patch("airflow.api_fastapi.auth.managers.base_auth_manager.JWTValidator", 
autospec=True)
+    @patch(
+        
"airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager._get_token_validator",
+        autospec=True,
+    )
     @patch.object(EmptyAuthManager, "deserialize_user")
     @pytest.mark.asyncio
-    async def test_get_user_from_token(self, mock_deserialize_user, 
mock_jwt_validator, auth_manager):
+    async def test_get_user_from_token(self, mock_deserialize_user, 
mock__get_token_validator, auth_manager):
         token = "token"
         payload = {}
         user = BaseAuthManagerUserTest(name="test")
         signer = AsyncMock(spec=JWTValidator)
         signer.avalidated_claims.return_value = payload
-        mock_jwt_validator.return_value = signer
+        mock__get_token_validator.return_value = signer
         mock_deserialize_user.return_value = user
 
         result = await auth_manager.get_user_from_token(token)
@@ -196,6 +200,27 @@ class TestBaseAuthManager:
         signer.avalidated_claims.assert_called_once_with(token)
         assert result == user
 
+    @patch(
+        
"airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager._get_token_validator",
+        autospec=True,
+    )
+    @patch.object(EmptyAuthManager, "deserialize_user")
+    @pytest.mark.asyncio
+    async def test_get_user_from_token_invalid_token_payload(
+        self, mock_deserialize_user, mock__get_token_validator, auth_manager
+    ):
+        token = "token"
+        payload = {}
+        signer = AsyncMock(spec=JWTValidator)
+        signer.avalidated_claims.return_value = payload
+        mock__get_token_validator.return_value = signer
+        mock_deserialize_user.side_effect = ValueError("Some error 
deserializing the user")
+
+        with pytest.raises(InvalidTokenError, match="Some error deserializing 
the user"):
+            await auth_manager.get_user_from_token(token)
+        mock_deserialize_user.assert_called_once_with(payload)
+        signer.avalidated_claims.assert_called_once_with(token)
+
     @patch("airflow.api_fastapi.auth.managers.base_auth_manager.JWTGenerator", 
autospec=True)
     @patch.object(EmptyAuthManager, "serialize_user")
     def test_generate_jwt_token(self, mock_serialize_user, mock_jwt_generator, 
auth_manager):

Reply via email to