Skip to content

Commit a30cc59

Browse files
authored
πŸ§‘β€πŸ’» Handle already logged in state (#103)
* Handle already logged in state * Update * Update * Add test * Update test * Add verify token tests * Format * Update login.py * Update test_notify_already_logged_in_user * Update login message for exp session and add test for token expiration
1 parent 1fa3661 commit a30cc59

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

β€Žsrc/fastapi_cloud_cli/commands/login.pyβ€Ž

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88

99
from fastapi_cloud_cli.config import Settings
1010
from fastapi_cloud_cli.utils.api import APIClient
11-
from fastapi_cloud_cli.utils.auth import AuthConfig, write_auth_config
11+
from fastapi_cloud_cli.utils.auth import (
12+
AuthConfig,
13+
get_auth_token,
14+
is_logged_in,
15+
is_token_expired,
16+
write_auth_config,
17+
)
1218
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
1319

1420
logger = logging.getLogger(__name__)
@@ -76,6 +82,20 @@ def login() -> Any:
7682
"""
7783
Login to FastAPI Cloud. πŸš€
7884
"""
85+
token = get_auth_token()
86+
if token is not None and is_token_expired(token):
87+
with get_rich_toolkit(minimal=True) as toolkit:
88+
toolkit.print("Your session has expired. Logging in again...")
89+
toolkit.print_line()
90+
91+
if is_logged_in():
92+
with get_rich_toolkit(minimal=True) as toolkit:
93+
toolkit.print("You are already logged in.")
94+
toolkit.print(
95+
"Run [bold]fastapi logout[/bold] first if you want to switch accounts."
96+
)
97+
return
98+
7999
with get_rich_toolkit() as toolkit, APIClient() as client:
80100
toolkit.print_title("Login to FastAPI Cloud", tag="FastAPI")
81101

β€Žtests/test_cli_login.pyβ€Ž

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import time
12
from pathlib import Path
23
from unittest.mock import patch
34

@@ -9,6 +10,7 @@
910

1011
from fastapi_cloud_cli.cli import app
1112
from fastapi_cloud_cli.config import Settings
13+
from tests.utils import create_jwt_token
1214

1315
runner = CliRunner()
1416
settings = Settings.get()
@@ -162,3 +164,54 @@ def test_fetch_access_token_handles_500_error(respx_mock: respx.MockRouter) -> N
162164
with APIClient() as client:
163165
with pytest.raises(httpx.HTTPStatusError):
164166
_fetch_access_token(client, "test_device_code", 5)
167+
168+
169+
@pytest.mark.respx(base_url=settings.base_api_url)
170+
def test_notify_already_logged_in_user(
171+
respx_mock: respx.MockRouter, logged_in_cli: None
172+
) -> None:
173+
result = runner.invoke(app, ["login"])
174+
175+
assert result.exit_code == 0
176+
assert "You are already logged in." in result.output
177+
assert "Run fastapi logout first if you want to switch accounts." in result.output
178+
179+
180+
@pytest.mark.respx(base_url=settings.base_api_url)
181+
def test_notify_expired_token_user(
182+
respx_mock: respx.MockRouter, temp_auth_config: Path
183+
) -> None:
184+
past_exp = int(time.time()) - 3600
185+
expired_token = create_jwt_token({"sub": "test_user_12345", "exp": past_exp})
186+
187+
temp_auth_config.write_text(f'{{"access_token": "{expired_token}"}}')
188+
189+
with patch("fastapi_cloud_cli.commands.login.typer.launch") as mock_open:
190+
respx_mock.post(
191+
"/login/device/authorization", data={"client_id": settings.client_id}
192+
).mock(
193+
return_value=Response(
194+
200,
195+
json={
196+
"verification_uri_complete": "http://test.com",
197+
"verification_uri": "http://test.com",
198+
"user_code": "1234",
199+
"device_code": "5678",
200+
},
201+
)
202+
)
203+
respx_mock.post(
204+
"/login/device/token",
205+
data={
206+
"device_code": "5678",
207+
"client_id": settings.client_id,
208+
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
209+
},
210+
).mock(return_value=Response(200, json={"access_token": "new_token_1234"}))
211+
212+
result = runner.invoke(app, ["login"])
213+
214+
assert result.exit_code == 0
215+
assert "Your session has expired. Logging in again..." in result.output
216+
assert "Now you are logged in!" in result.output
217+
assert mock_open.called

0 commit comments

Comments
Β (0)