Skip to content

feat(jira): Support installing through the API pipeline modal#116500

Open
evanpurkhiser wants to merge 1 commit into
masterfrom
evanpurkhiser/feat-jira-support-installing-through-the-api-pipeline-modal
Open

feat(jira): Support installing through the API pipeline modal#116500
evanpurkhiser wants to merge 1 commit into
masterfrom
evanpurkhiser/feat-jira-support-installing-through-the-api-pipeline-modal

Conversation

@evanpurkhiser
Copy link
Copy Markdown
Member

VDY-123: Jira Cloud: API-driven integration setup

Adds the API-mode pipeline machinery for Jira Cloud alongside the existing server-rendered configure flow, without changing the entry point yet. This is the first of three deploy-safe steps: the legacy JiraExtensionConfigurationView and the /extensions/jira/configure/ URL are left untouched, so nothing changes for users until the frontend can drive the modal and the configure URL is later swapped to a redirect.

  • JiraInitialDataSerializer unsigns the Marketplace signed_params blob, decodes the nested metadata JSON, and binds external_id and metadata to top-level pipeline state.
  • Unlike MS Teams, which auto-advances silently, JiraConfirmInstallStep is an interactive confirmation step: it exposes the Jira workspace (base_url) and the Sentry organization so the user can verify them before completing the install. A copied install link could otherwise connect an attacker's Jira workspace to a victim's org, so the confirmation screen lets the user catch a mismatch. The frontend follow-up renders this step; this PR only adds the backend get_step_data / handle_post.
  • build_integration now reads top-level state, falling back to the nested state["jira"] the legacy view binds. The installed webhook's raw Atlassian payload path (clientKey, oauthClientId, ...) is preserved.

Also sets can_add_externally so the externally-initiated Marketplace install is allowed through the pipeline endpoint while can_add = False keeps the in-app install button hidden — matching the MS Teams backend.

Follows the same three-PR structure as MS Teams (#116490): backend (this PR) → frontend → backend cleanup (swap the configure URL to a redirect and drop the legacy view).

@evanpurkhiser evanpurkhiser requested a review from a team as a code owner May 29, 2026 17:29
@evanpurkhiser evanpurkhiser requested review from Christinarlong and GabeVillalobos and removed request for a team May 29, 2026 17:29
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 29, 2026
Comment thread src/sentry/integrations/jira/integration.py
Comment thread src/sentry/integrations/jira/integration.py
@evanpurkhiser evanpurkhiser force-pushed the evanpurkhiser/feat-jira-support-installing-through-the-api-pipeline-modal branch from f93cb75 to fdd1c20 Compare May 29, 2026 18:34
Add the API-mode pipeline machinery for Jira Cloud alongside the existing
server-rendered configure flow, without changing the entry point yet. This
is the first of three deploy-safe steps: the legacy
`JiraExtensionConfigurationView` and the `/extensions/jira/configure/` URL
are left untouched, so nothing changes for users until the frontend can
drive the modal and the configure URL is later swapped to a redirect.

- `JiraInitialDataSerializer` unsigns the Marketplace `signed_params` blob,
  decodes the nested `metadata` JSON, and binds `external_id` and `metadata`
  to top-level pipeline state.
- Unlike MS Teams, which auto-advances silently, `JiraConfirmInstallStep` is
  interactive: it exposes the Jira workspace and Sentry organization so the
  user can confirm before completing the install. A copied install link
  could otherwise connect an attacker's Jira workspace to a victim's org.
- `build_integration` now reads top-level state, falling back to the nested
  `state["jira"]` the legacy view binds; the `installed` webhook's raw
  Atlassian payload path is preserved.

Also sets `can_add_externally` so the externally-initiated Marketplace
install is allowed through the pipeline endpoint while `can_add = False`
keeps the in-app install button hidden.
@evanpurkhiser evanpurkhiser force-pushed the evanpurkhiser/feat-jira-support-installing-through-the-api-pipeline-modal branch from fdd1c20 to f0b7a7e Compare May 29, 2026 20:19
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f0b7a7e. Configure here.



# 24 hours to finish installation
INSTALL_EXPIRATION_TIME = 60 * 60 * 24
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Duplicated INSTALL_EXPIRATION_TIME constant risks silent drift

Low Severity

INSTALL_EXPIRATION_TIME is now defined independently in both integration.py and views/extension_configuration.py with the same value (60 * 60 * 24). The new API pipeline serializer and the legacy configure view each use their own copy to unsign the same signed_params blob. If one is changed without the other, links valid for the API path could silently expire for the legacy path or vice versa. The constant could be imported from a single source (e.g., alongside SALT in the views __init__.py).

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f0b7a7e. Configure here.

Copy link
Copy Markdown
Contributor

@Christinarlong Christinarlong left a comment

Choose a reason for hiding this comment

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

These changes make sense. I'm not sure if the transition to forge will require us to redo these steps/views again but I dont really have much context to the forge specifics 🥲

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants