Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Fix OIDC re-login#559

Merged
mangelajo merged 1 commit intomainfrom
oidc-reauth
Jul 9, 2025
Merged

Fix OIDC re-login#559
mangelajo merged 1 commit intomainfrom
oidc-reauth

Conversation

@mangelajo
Copy link
Copy Markdown
Member

@mangelajo mangelajo commented Jul 8, 2025

  • A token expired exception triggers re-login
  • re-login works

Fixes: #539
Fixes: #538

Summary by CodeRabbit

  • New Features

    • Improved error handling for commands that interact with leases and exporters, now prompting automatic reauthentication if your session token has expired.
    • Clearer error messages are shown when reauthentication is required or fails during command execution.
  • Bug Fixes

    • Commands now handle token expiration more gracefully, reducing disruption during CLI operations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 8, 2025

Walkthrough

This change introduces a unified mechanism for handling token expiration and automatic OIDC re-authentication across CLI commands. It adds a decorator that detects expired tokens, triggers re-authentication using a new relogin_client function, and updates exception handling to propagate configuration context. The logic is applied to relevant CLI commands and client configuration methods.

Changes

File(s) Change Summary
jumpstarter_cli_common/exceptions.py Added handle_exceptions_with_reauthentication decorator factory for token expiry and re-authentication logic.
jumpstarter_cli/get.py, create.py, delete.py, shell.py, update.py Switched CLI commands to use new exception decorator with relogin_client for re-authentication on expiry.
jumpstarter_cli/login.py Refactored login to fix config kind bug; added relogin_client for OIDC re-authentication.
jumpstarter/common/exceptions.py Enhanced JumpstarterException to carry config context; added ReauthenticationFailed exception class.
jumpstarter/config/client.py Decorated async client methods to attach config to exceptions on token expiry; updated context manager logic.

Sequence Diagram(s)

sequenceDiagram
    participant CLI_Command
    participant Decorator
    participant ClientConfig
    participant relogin_client
    participant OIDC_Provider

    CLI_Command->>Decorator: Execute command (e.g., get_leases)
    Decorator->>ClientConfig: Call async method (e.g., list_leases)
    ClientConfig-->>Decorator: Raises ConnectionError (token expired)
    Decorator->>relogin_client: relogin_client(config)
    relogin_client->>OIDC_Provider: Perform OIDC re-authentication
    OIDC_Provider-->>relogin_client: Return new tokens
    relogin_client->>ClientConfig: Update config with new token
    Decorator->>CLI_Command: Raise ClickExceptionRed (prompt user to retry)
Loading

Assessment against linked issues

Objective Addressed Explanation
Fix UnboundLocalError in login flow when re-authenticating (#539)
Implement automatic OIDC re-authentication on token expiry for CLI commands (#538)
Ensure expired token exceptions propagate config context for recovery (#538, #539)
Add explicit exception for re-authentication failures (#538)

Poem

A token expired, oh what a plight!
But now the CLI makes it right.
With re-login magic, errors are tamed,
No more confusion, no user blamed.
The bunny hops, credentials renewed—
Jumpstarter’s flow is now improved! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 912dee2 and 0def592.

📒 Files selected for processing (9)
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py (2 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/create.py (2 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/delete.py (2 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/get.py (3 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/login.py (6 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py (2 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/update.py (2 hunks)
  • packages/jumpstarter/jumpstarter/common/exceptions.py (2 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (10 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/jumpstarter/jumpstarter/common/exceptions.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/jumpstarter-cli/jumpstarter_cli/get.py
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py
  • packages/jumpstarter/jumpstarter/config/client.py
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/jumpstarter-cli/jumpstarter_cli/shell.py (2)
packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py (1)
  • handle_exceptions_with_reauthentication (49-72)
packages/jumpstarter-cli/jumpstarter_cli/login.py (2)
  • login (39-138)
  • relogin_client (141-155)
packages/jumpstarter-cli/jumpstarter_cli/login.py (1)
packages/jumpstarter/jumpstarter/common/exceptions.py (1)
  • ReauthenticationFailed (72-75)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
🔇 Additional comments (7)
packages/jumpstarter-cli/jumpstarter_cli/delete.py (1)

3-3: LGTM: Clean integration of re-authentication mechanism.

The changes correctly integrate the new re-authentication functionality by:

  • Updating the exception handler import to the new decorator factory
  • Importing the relogin_client function
  • Applying the decorator with the appropriate callback

This follows the consistent pattern across all CLI command files.

Also applies to: 7-7, 23-23

packages/jumpstarter-cli/jumpstarter_cli/update.py (1)

5-5: LGTM: Consistent implementation across CLI commands.

The changes mirror the pattern used in other CLI command files, properly integrating the re-authentication mechanism with the update_lease command.

Also applies to: 10-10, 25-25

packages/jumpstarter-cli/jumpstarter_cli/shell.py (1)

6-6: LGTM: Proper integration of re-authentication for shell command.

The changes follow the established pattern for enabling automatic re-authentication when tokens expire during shell command execution.

Also applies to: 9-9, 24-24

packages/jumpstarter-cli/jumpstarter_cli/create.py (1)

5-5: LGTM: Consistent integration with create command.

The changes maintain the consistent pattern across all CLI commands, properly enabling re-authentication for lease creation operations.

Also applies to: 10-10, 25-25

packages/jumpstarter-cli/jumpstarter_cli/login.py (3)

5-9: LGTM: Necessary imports for enhanced functionality.

The added imports support the new TLS configuration handling and re-authentication mechanism. All imports are properly used in the code.

Also applies to: 11-11, 15-15


59-70: Good fix for the tuple configuration issue.

The introduction of config_kind variable properly addresses the reported issue where config was unexpectedly a tuple. This change ensures consistent tracking of configuration type throughout the function and fixes the AttributeError: 'tuple' object has no attribute 'tls' error mentioned in the PR objectives.

Also applies to: 130-130


98-98: Excellent fix for TLS configuration initialization.

The TLS configuration is now properly initialized when creating new configs, which directly addresses the --insecure-tls-config flag issue reported in the PR objectives. This ensures that config.tls.insecure assignment works correctly.

Also applies to: 107-107

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@netlify
Copy link
Copy Markdown

netlify Bot commented Jul 8, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 0def592
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/686e923091dc930008887d44
😎 Deploy Preview https://deploy-preview-559--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mangelajo mangelajo force-pushed the oidc-reauth branch 2 times, most recently from 12d61a8 to 4929415 Compare July 8, 2025 16:00
@mangelajo mangelajo requested a review from bennyz July 8, 2025 16:03
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12d61a8 and 4929415.

📒 Files selected for processing (6)
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py (2 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/config_client.py (5 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/get.py (3 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/login.py (3 hunks)
  • packages/jumpstarter/jumpstarter/common/exceptions.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/jumpstarter-cli/jumpstarter_cli/get.py
  • packages/jumpstarter/jumpstarter/common/exceptions.py
  • packages/jumpstarter-cli/jumpstarter_cli/config_client.py
  • packages/jumpstarter/jumpstarter/config/client.py
🧰 Additional context used
🪛 GitHub Check: ruff
packages/jumpstarter-cli/jumpstarter_cli/login.py

[failure] 141-141: Ruff (W292)
packages/jumpstarter-cli/jumpstarter_cli/login.py:141:74: W292 No newline at end of file

🪛 GitHub Actions: Lint
packages/jumpstarter-cli/jumpstarter_cli/login.py

[warning] 141-141: Ruff: No newline at end of file (W292)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
🔇 Additional comments (2)
packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py (1)

7-7: LGTM: Import addition supports new exception handling.

The addition of ConnectionError to the imports is necessary for the new token expiration handling logic.

packages/jumpstarter-cli/jumpstarter_cli/login.py (1)

53-132: LGTM: Login function refactoring maintains functionality.

The refactoring to use config_kind variable improves code organization and readability while maintaining the same functionality. The logic flow remains correct.

Comment thread packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py Outdated
Comment thread packages/jumpstarter-cli/jumpstarter_cli/login.py Outdated
@michalskrivanek
Copy link
Copy Markdown
Contributor

michalskrivanek commented Jul 9, 2025

what am i doing wrong when i see:
│ jumpstarter/packages/jumpstarter-cli/jumpstarter_cli/login.py:66 in login │ │ │ │ 63 │ │ # we are creating a new config │ │ 64 │ │ case (kind, value): │ │ 65 │ │ │ config_kind = kind │ │ ❱ 66 │ │ │ config.tls.insecure = insecure_tls_config │ │ 67 │ │ │ if namespace is None: │ │ 68 │ │ │ │ if nointeractive: │ │ 69 │ │ │ │ │ raise click.UsageError("Namespace is required in non-interactive mod │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ AttributeError: 'tuple' object has no attribute 'tls'

when trying jmp login --insecure-tls-config

@mangelajo
Copy link
Copy Markdown
Member Author

what am i doing wrong when i see: │ jumpstarter/packages/jumpstarter-cli/jumpstarter_cli/login.py:66 in login │ │ │ │ 63 │ │ # we are creating a new config │ │ 64 │ │ case (kind, value): │ │ 65 │ │ │ config_kind = kind │ │ ❱ 66 │ │ │ config.tls.insecure = insecure_tls_config │ │ 67 │ │ │ if namespace is None: │ │ 68 │ │ │ │ if nointeractive: │ │ 69 │ │ │ │ │ raise click.UsageError("Namespace is required in non-interactive mod │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ AttributeError: 'tuple' object has no attribute 'tls'

when trying jmp login --insecure-tls-config

Thanks, let me check ... probably what am I doing wrong here :D ...

@mangelajo
Copy link
Copy Markdown
Member Author

what am i doing wrong when i see: │ jumpstarter/packages/jumpstarter-cli/jumpstarter_cli/login.py:66 in login │ │ │ │ 63 │ │ # we are creating a new config │ │ 64 │ │ case (kind, value): │ │ 65 │ │ │ config_kind = kind │ │ ❱ 66 │ │ │ config.tls.insecure = insecure_tls_config │ │ 67 │ │ │ if namespace is None: │ │ 68 │ │ │ │ if nointeractive: │ │ 69 │ │ │ │ │ raise click.UsageError("Namespace is required in non-interactive mod │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ AttributeError: 'tuple' object has no attribute 'tls'

when trying jmp login --insecure-tls-config

I tested and it should work now with the latest change.

We have some E2E testing for this, but it doesn't cover the interactive part because it's a bit hard to do.

https://github.com/jumpstarter-dev/jumpstarter-e2e/blob/main/tests.bats#L40

I think I can at least add the flag to be tested at some point too

@mangelajo mangelajo enabled auto-merge July 9, 2025 09:28
@mangelajo mangelajo disabled auto-merge July 9, 2025 09:38
@mangelajo
Copy link
Copy Markdown
Member Author

ha, I broke more stuff... fixing,

@mangelajo mangelajo marked this pull request as draft July 9, 2025 13:25
* A token expired exception triggers re-login
* re-login works
@mangelajo mangelajo marked this pull request as ready for review July 9, 2025 16:01
@mangelajo mangelajo merged commit 637d0eb into main Jul 9, 2025
18 checks passed
@mangelajo mangelajo deleted the oidc-reauth branch July 9, 2025 16:25
@coderabbitai coderabbitai Bot mentioned this pull request Jul 20, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Jan 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OIDC manual re-authentication fails OIDC re-authentication on token expiry

3 participants