Skip to content

Commit de8815b

Browse files
dheerajturagachoo121600
authored andcommitted
Fix airflowctl auth login reporting success when keyring backend is unavailable (apache#61296)
1 parent 62aa59f commit de8815b

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

airflow-ctl/src/airflowctl/api/client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ def save(self):
149149
keyring.set_password("airflowctl", f"api_token_{self.api_environment}", self.api_token)
150150
except NoKeyringError as e:
151151
log.error(e)
152+
raise AirflowCtlKeyringException(
153+
"Keyring backend is not available. Cannot save credentials."
154+
) from e
152155
except TypeError as e:
153156
# This happens when the token is None, which is not allowed by keyring
154157
if self.api_token is None and self.client_kind == ClientKind.CLI:

airflow-ctl/tests/airflow_ctl/ctl/commands/test_auth_command.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,36 @@ def test_login_with_username_and_password(self, mock_keyring, api_client_maker):
106106
mock.call("airflowctl", "api_token_production", "TEST_TOKEN"),
107107
]
108108
)
109+
110+
@patch("airflowctl.api.client.keyring")
111+
def test_login_with_username_and_password_no_keyring_backend(self, mock_keyring, api_client_maker):
112+
"""Test that login fails when no keyring backend is available."""
113+
from keyring.errors import NoKeyringError
114+
115+
api_client = api_client_maker(
116+
path="/auth/token/cli",
117+
response_json=self.login_response.model_dump(),
118+
expected_http_status_code=201,
119+
kind=ClientKind.AUTH,
120+
)
121+
122+
mock_keyring.set_password.side_effect = NoKeyringError("no backend")
123+
with (
124+
patch("sys.stdin", io.StringIO("test_password")),
125+
patch("airflowctl.ctl.cli_config.getpass.getpass", return_value="test_password"),
126+
pytest.raises(SystemExit, match="1"),
127+
):
128+
auth_command.login(
129+
self.parser.parse_args(
130+
[
131+
"auth",
132+
"login",
133+
"--api-url",
134+
"http://localhost:8080",
135+
"--username",
136+
"test_user",
137+
"--password",
138+
]
139+
),
140+
api_client=api_client,
141+
)

0 commit comments

Comments
 (0)