Skip to content

feat: store logins with environments and show session status - #271

Open
krowvin wants to merge 3 commits into
mainfrom
environment-login-tokens
Open

krowvin wants to merge 3 commits into
mainfrom
environment-login-tokens

Conversation

@krowvin

@krowvin krowvin commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Logging into a second environment currently overwrites the provider-wide session, and environment checks only inspect API keys. Keep named environments' login sessions with their configuration and show login state, token availability, remaining access/refresh time, refresh expiry, and storage location in env show.

Behavior and storage

~/.config/cwms-cli/
  login.json       # default sessions when ENVIRONMENT is unset
  envs/
    dev.json       # development settings AND login sessions
    prod.json      # production settings AND login sessions

XDG_CONFIG_HOME overrides the config root. Named environment JSON files store sessions in private _logins metadata alongside the existing configuration. Each file indexes sessions by CDA API root, so changing or overriding a URL cannot reuse another URL's token. Separate environment names retain independent sessions even when their API roots match. Named environments do not fall back to the default session file.

  • env show displays local login/token status, access lifetime, refresh time remaining and expiry, and token-file location. It also lists default logins, without network calls.
  • env check and env show --check additionally check named environments' connectivity and credentials using the protected /roles endpoint. A usable saved token takes precedence over the environment's API key. HTTP failures and redirects are not reported as authenticated.
  • login --status inspects the current environment's session; login --token-location prints its path. Neither opens a browser or refreshes tokens. --api-root and explicit custom --token-file are supported; inspection flags cannot be combined with --refresh.
  • Login and refresh preserve environment settings and other saved sessions. env setup preserves login metadata; env delete removes that environment and its sessions together. Tokens are omitted from status output, every export format, and activated-shell variables.
  • Older provider-only files lack a CDA-root association and are not automatically reused. Log in once per environment after upgrading. Explicit custom token files retain the standalone session format and are not automatically selected by other commands.

Validation

  • 447 tests passed in the Python 3.12 .devcontainer, including DSS tests. The full suite used an identical source copy at /tmp/cwms-cli because an existing update test requires that directory suffix: devcontainer exec --workspace-folder . env PYTHONPATH=/tmp/cwms-cli poetry run pytest -q /tmp/cwms-cli/tests.
  • Commit hooks passed: Black, isort, and generated ownership verification. git diff --check passed.
  • Tests cover named/default storage, same-URL environment isolation, switching, explicit/automatic refresh, settings preservation, deletion isolation, export redaction in all five formats, missing/corrupt/expired sessions, offline inspection, refresh failure fallback, and protected-endpoint authentication.

Console demonstration

Captured from real Click commands in the dev container, with an isolated config directory, a fixed clock, fixture OIDC tokens, and a local HTTP server. The HTTP checks are real local requests and each endpoint accepts only its own token; browser/OIDC login is stubbed. This is local validation, not a live CWBI login test. The harness loads actual env export output between commands. Routine stderr logging is omitted; excerpts below omit repeated environment rows where indicated.

$ cwms-cli env export dev --format dotenv
CDA_API_ROOT="http://127.0.0.1:42979/dev"
ENVIRONMENT="dev"
# Loaded exported variables for dev into the demo process.
$ cwms-cli login
You have successfully authenticated against CWBI.
CDA API root: http://127.0.0.1:42979/dev
Your refresh session is good until January 16, 2027 at 10:02 AM UTC.
$ cwms-cli env export prod --format dotenv
CDA_API_ROOT="http://127.0.0.1:42979/prod"
ENVIRONMENT="prod"
# Loaded exported variables for prod into the demo process.
$ cwms-cli login
You have successfully authenticated against CWBI.
CDA API root: http://127.0.0.1:42979/prod
Your refresh session is good until January 16, 2027 at 10:02 AM UTC.
$ cwms-cli env export dev --format dotenv
CDA_API_ROOT="http://127.0.0.1:42979/dev"
ENVIRONMENT="dev"
# Loaded exported variables for dev into the demo process.
$ cwms-cli env show
Current environment: dev

Available environments:
* dev
    API Root: http://127.0.0.1:42979/dev
    Office:   not set
    Status:   no API key
    Login:    saved (not verified)
    Token:    available
    Token file: /tmp/tmplewrobhb/cwms-cli/envs/dev.json
    Access lifetime: 5m remaining
    Refresh session: 1d 2h 2m 3s remaining
    Refresh expires: January 16, 2027 at 10:02 AM UTC
  prod
    API Root: http://127.0.0.1:42979/prod
    Office:   not set
    Status:   no API key
    Login:    saved (not verified)
    Token:    available
    Token file: /tmp/tmplewrobhb/cwms-cli/envs/prod.json
    Access lifetime: 5m remaining
    Refresh session: 1d 2h 2m 3s remaining
    Refresh expires: January 16, 2027 at 10:02 AM UTC
  unsigned
    API Root: http://127.0.0.1:42979/unsigned
    Office:   not set
    Status:   no API key
    Login:    not logged in
    Token:    not available
    Token file: /tmp/tmplewrobhb/cwms-cli/envs/unsigned.json
    Access lifetime: not available
    Refresh session: not available
$ cwms-cli env export prod --format dotenv
CDA_API_ROOT="http://127.0.0.1:42979/prod"
ENVIRONMENT="prod"
# Loaded exported variables for prod into the demo process.
$ cwms-cli env check
Current environment: prod

Available environments:
  dev
    API Root: http://127.0.0.1:42979/dev
    Office:   not set
    Status:   no API key
    Connect:  reachable (3ms)
    Auth:     authenticated
    Login:    saved (not verified)
    Token:    available
    Token file: /tmp/tmplewrobhb/cwms-cli/envs/dev.json
    Access lifetime: 5m remaining
    Refresh session: 1d 2h 2m 3s remaining
    Refresh expires: January 16, 2027 at 10:02 AM UTC
* prod
    API Root: http://127.0.0.1:42979/prod
    Office:   not set
    Status:   no API key
    Connect:  reachable (1ms)
    Auth:     authenticated
    Login:    saved (not verified)
    Token:    available
    Token file: /tmp/tmplewrobhb/cwms-cli/envs/prod.json
    Access lifetime: 5m remaining
    Refresh session: 1d 2h 2m 3s remaining
    Refresh expires: January 16, 2027 at 10:02 AM UTC
# [unsigned row omitted]
# Unset ENVIRONMENT and selected the default API root.
$ cwms-cli login
You have successfully authenticated against CWBI.
CDA API root: http://127.0.0.1:42979/default
Your refresh session is good until January 16, 2027 at 10:02 AM UTC.
$ cwms-cli login --status
CDA API root: http://127.0.0.1:42979/default
Login: saved (not verified)
Access token: available
Token file: /tmp/tmplewrobhb/cwms-cli/login.json
Access lifetime: 5m remaining
Refresh session: 1d 2h 2m 3s remaining
Refresh expires: January 16, 2027 at 10:02 AM UTC
$ cwms-cli env show
No environment currently active
# [named environment rows omitted]

Default logins (no named environment):
    API Root: http://127.0.0.1:42979/default
    Login:    saved (not verified)
    Token:    available
    Token file: /tmp/tmplewrobhb/cwms-cli/login.json
    Access lifetime: 5m remaining
    Refresh session: 1d 2h 2m 3s remaining
    Refresh expires: January 16, 2027 at 10:02 AM UTC
PASS: both environments accepted their own token after switching; no token values printed.

@krowvin krowvin changed the title feat: preserve environment logins and show token status feat: store logins with environments and show session status Sep 23, 2026
@krowvin

krowvin commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator Author

Docs and tests in the same PR bloated this a bit in changes in the diff

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant