Repository navigation
Conversation
Review of the #490 session-restore change, plus fixes found while reviewing session.py as a whole. Restore saved session: - Do not reuse the saved token when --server or --site targets a different server or site than the one it was saved for. - Attach the saved token inside the try block, so a failure falls back to a fresh sign-in instead of aborting the command. Session file: - Create the file with mode 0600 and tighten existing files on save. - Redact user:password in proxy URLs wherever they are logged. - Load optional keys with .get() so a file from another version keeps the session. Logic fixes: - host:port server URLs get the default https scheme before parsing. - logout signs out the saved token on the server; local cleanup still runs if that fails. - _clear_data resets server_url (it previously reset a nonexistent attribute). - Token name prints only when set; certificate prints independently. - Trailing newline is stripped from password and token files. - Proxy applies to https as well as http. - Timeout values of zero or less become 0. - Empty session file is wiped once. - Site name keeps its case; only the "default" check is case-insensitive. Cleanup: remove duplicate credential-type constants, duplicate logging_level assignment, redundant session-file read, and unused exception bindings. Tests: replace was_called()/has_been_called() (always truthy on a mock) with real assertions, fix clear_session which was never collected, and add coverage for the fixes and for _update_session_data, _sign_in, _validate_existing_signin, saved credentials, --no-cookie, and logout. Co-Authored-By: Claude Code <noreply@anthropic.com>
… tests - Read the saved token from TSC's public auth_token property, not _auth_token. - Log validation failures with the shared internal_error message. - Remove connection checks that could not fire after the connection is set. - Remove the unused last_command attribute. - Add tests for _remove_json, _wipe_bad_json and an unreadable session file. Co-Authored-By: Claude Code <noreply@anthropic.com>
…ate session tests - Catch SystemExit from _open_connection_with_opts in session restore and saved-token sign-out so a bad server URL falls back instead of exiting. - Restore the unexpected_server_response message for ServerResponseError. - Sign out the saved token only when there is no live connection. - Patch Session._get_file_path for the whole test module so tests never touch the real ~/tableau_auth.json. - Add tests for connection failures, live-session logout and chmod failure. Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Scheme-relative server URLs break sign-in, and logout ignores explicit HTTP options and can block indefinitely without a finite timeout, preventing local cleanup.
3 open issues
What changed in this PR
This follow-up to #490 hardens saved-session handling in tabcmd and expands regression coverage for authentication and local session storage.
Changes:
- Restricts saved-token reuse to matching servers and sites, preserves site-name casing, and adds server-side logout.
- Tightens session-file permissions, redacts proxy credentials in logs, and improves URL, timeout, and credential-file handling.
- Expands session tests, replaces ineffective mock assertions, and isolates tests from the real session file.
| File | Description |
|---|---|
tests/commands/test_session.py |
Expands authentication, logout, storage, and connection-option tests with isolated session files. |
tabcmd/commands/auth/session.py |
Hardens session restoration, logout, credential storage, and connection handling. |
Review effort: Balanced
…acks - _get_server_base_url: only a leading scheme:// counts as a scheme; handle scheme-relative URLs; reject URLs with no host instead of silently falling back to the saved server or http://localhost. - logout honours --proxy, --no-proxy, --timeout, --certificate and --no-certcheck. --server and --site are not forwarded. - Session probe and logout sign-out default to a 30 second timeout when --timeout is not set. Other commands still wait for the server. - Those two paths raise instead of printing an error and exiting when the connection cannot be opened. Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The 30-second probe timeout persists on the returned session, potentially causing long-running commands to fail unexpectedly; restore the configured timeout and add regression coverage.
2 open issues
2 resolved since last review
Review effort: Balanced
| server = self._open_connection_with_opts( | ||
| raise_on_failure=True, default_timeout=DEFAULT_SESSION_REQUEST_TIMEOUT | ||
| ) |
Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The restore probe’s 30-second timeout persists on the returned server, causing long-running commands using saved sessions to time out unexpectedly when no user timeout was specified.
3 open issues
1 resolved since last review
Review effort: Balanced
| logger.debug(_("tabcmd.launching")) | ||
| session = Session() | ||
| # only the connection options; --server and --site must not redirect the saved token | ||
| session._update_http_options(args) |
The probe used a 30 second timeout, and that value stayed on the server returned to the command. Commands that run with a saved session and no --timeout could then fail on slow responses instead of waiting. Reset the timeout to the configured value once the probe succeeds. Logout also reapplies the requested logging level, since creating the Session resets the root logger to INFO. Co-Authored-By: Claude Code <noreply@anthropic.com>


Follow-up to #490. Addresses the Copilot review comments on that PR and the problems found in a full review of
session.py. Each item is stated as problem, then fix.Saved-session reuse
logoutonly deleted the local file, leaving the token valid on the server. Fix: it signs the saved token out on the server first. A failed server sign-out is logged and does not stop the local cleanup, and a live session is signed out once, not twice.defaultstill maps to the default site, and username and server URL are still lowercased.--serverclears the saved site, so logging in to a new server does not carry over the old site.Session file
~/tableau_auth.jsonwas written with default permissions and holds the token or PAT secret. Fix: it is created with mode 0600. A failedchmodis logged and the write still happens.Cleanups
TOKEN_CRED_TYPE/PASSWORD_CRED_TYPEdefinitions, the unusedlast_command, and several dead checks.auth_tokenproperty instead of a private attribute.Tests
test_session.pygoes from a handful of tests to about 105. Several earlier assertions always passed (was_called()is always truthy on a mock); they now assert real behaviour.~/tableau_auth.json.Sessions saved by older versions have a lowercased site name. If a later command passes
-twith different casing, that session is not reused and the command signs in again.🤖 Generated with Claude Code