diff --git a/strix/interface/platform_cli.py b/strix/interface/platform_cli.py index a4dc88af..1b79ebfa 100644 --- a/strix/interface/platform_cli.py +++ b/strix/interface/platform_cli.py @@ -31,6 +31,8 @@ AUTH_PATH = Path.home() / ".strix" / "platform-auth.json" _HTTP_TIMEOUT_S = 30 _DEFAULT_POLL_INTERVAL_S = 5 +_MAX_POLL_INTERVAL_S = 60 +_MAX_EXPIRES_IN_S = 30 * 60 _LOGIN_USAGE = ( "Usage:\n strix login [--no-browser] [--scopes SCOPE ...] [--workspace WORKSPACE]\n" @@ -182,8 +184,14 @@ def _run_device_flow( or "" ) device_code = str(authorization.get("device_code") or "") - expires_in = _as_positive_int(authorization.get("expires_in"), default=300) - interval = _as_positive_int(authorization.get("interval"), default=_DEFAULT_POLL_INTERVAL_S) + expires_in = _as_positive_int( + authorization.get("expires_in"), default=300, maximum=_MAX_EXPIRES_IN_S + ) + interval = _as_positive_int( + authorization.get("interval"), + default=_DEFAULT_POLL_INTERVAL_S, + maximum=_MAX_POLL_INTERVAL_S, + ) if not device_code or not verification_uri: raise PlatformAuthError("the server returned an incomplete device authorization") @@ -420,12 +428,14 @@ def _json_object(response: requests.Response) -> dict[str, Any]: return cast("dict[str, Any]", data) -def _as_positive_int(value: Any, *, default: int) -> int: +def _as_positive_int(value: Any, *, default: int, maximum: int) -> int: try: parsed = int(value) except (TypeError, ValueError, OverflowError): return default - return parsed if parsed > 0 else default + if parsed <= 0: + return default + return min(parsed, maximum) def _error_detail(response: requests.Response) -> str: diff --git a/strix/utils/secret_files.py b/strix/utils/secret_files.py index b2170bf9..5ba0fc1c 100644 --- a/strix/utils/secret_files.py +++ b/strix/utils/secret_files.py @@ -28,4 +28,9 @@ def write_secret_text(path: Path, text: str) -> None: tmp.unlink() raise - tmp.replace(path) + try: + tmp.replace(path) + except BaseException: + with contextlib.suppress(OSError): + tmp.unlink() + raise