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