feat(backend): add Bitbucket Server (Data Center) permission syncing#938
Conversation
Adds account-driven and repo-driven permission sync support for Bitbucket Server (Data Center), mirroring the existing GitHub, GitLab, and Bitbucket Cloud implementations. - Extend BitbucketServerIdentityProviderConfig to support purpose: "account_linking" and accountLinkingRequired field - Request REPO_READ OAuth scope when permission syncing is enabled - Add bitbucket-server token refresh support via /rest/oauth2/latest/token - Add bitbucketServer/bitbucket-server to permission sync constants - Add getReposForAuthenticatedBitbucketServerUser and getUserPermissionsForServerRepo to bitbucket.ts - Add bitbucket-server branch to accountPermissionSyncer - Add bitbucketServer branch to repoPermissionSyncer - Update docs to reflect new account_linking purpose support Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds Bitbucket Server (on‑prem) support for permission syncing (account- and repo-driven), exports Bitbucket Server client helpers, extends identity provider schemas/types for account linking and baseUrl, updates permission syncers/constants/repo metadata, and adjusts SSO/token flows to optionally request REPO_READ when permission syncing is enabled. Changes
Sequence Diagram(s)sequenceDiagram
participant Scheduler as Scheduler
participant AccountSync as AccountPermissionSyncer
participant BBServer as Bitbucket Server API
participant DB as Database
Note over Scheduler,AccountSync: Account-driven permission sync
Scheduler->>AccountSync: trigger account sync for user
AccountSync->>DB: load user's linked account (bitbucket-server) & token
AccountSync->>BBServer: list accessible repos (paginated)
BBServer-->>AccountSync: repo list (ids)
AccountSync->>DB: map external repo IDs -> local repo IDs
AccountSync-->>DB: insert/update user repo permissions
sequenceDiagram
participant RepoSync as RepoPermissionSyncer
participant BBServer as Bitbucket Server API
participant DB as Database
participant AccountResolver as Local Account Resolver
Note over RepoSync,BBServer: Repo-driven permission sync
RepoSync->>DB: load repo metadata (hostUrl, projectKey, repoSlug)
RepoSync->>BBServer: fetch explicit user permissions for repo
BBServer-->>RepoSync: permission entries (users/groups)
RepoSync->>AccountResolver: resolve external userIds -> local accounts (provider: bitbucket-server)
AccountResolver-->>RepoSync: matched local account IDs
RepoSync->>DB: update repo permission mappings (isPartialSync = true)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/backend/src/ee/repoPermissionSyncer.ts`:
- Around line 295-324: The code handling Bitbucket Server repos must validate
that repo.displayName contains both projectKey and repoSlug before
destructuring; in the branch where repo.external_codeHostType ===
'bitbucketServer' (inside the function in repoPermissionSyncer.ts), add a check
that repo.displayName includes a '/' (or split result has length >= 2) and throw
a clear Error (e.g., `Repo ${id} has invalid displayName`) if not, then safely
assign const [projectKey, repoSlug] = repo.displayName.split('/', 2) and proceed
to call createBitbucketServerClient and getUserPermissionsForServerRepo only
when repoSlug is defined to avoid constructing invalid API paths.
In `@packages/web/src/ee/features/permissionSyncing/tokenRefresh.ts`:
- Around line 221-227: The constructed token URLs drop any context path because
the URL calls use absolute paths (e.g. '/rest/...'); change the URL construction
to use relative paths so the baseUrl's pathname is preserved—e.g. replace new
URL('/login/oauth/access_token', baseUrl) / new URL('/rest/oauth2/latest/token',
baseUrl) / new URL('/oauth/token', baseUrl) with new
URL('login/oauth/access_token', baseUrl) / new URL('rest/oauth2/latest/token',
baseUrl) / new URL('oauth/token', baseUrl) respectively (referencing the
provider, baseUrl and url variables in tokenRefresh.ts) so context-path
deployments like https://example.com/bitbucket yield URLs under that context.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
CHANGELOG.mddocs/docs/configuration/idp.mdxdocs/snippets/schemas/v3/identityProvider.schema.mdxdocs/snippets/schemas/v3/index.schema.mdxpackages/backend/src/bitbucket.tspackages/backend/src/constants.tspackages/backend/src/ee/accountPermissionSyncer.tspackages/backend/src/ee/repoPermissionSyncer.tspackages/schemas/src/v3/identityProvider.schema.tspackages/schemas/src/v3/identityProvider.type.tspackages/schemas/src/v3/index.schema.tspackages/schemas/src/v3/index.type.tspackages/web/src/ee/features/permissionSyncing/tokenRefresh.tspackages/web/src/ee/features/sso/sso.tsschemas/v3/identityProvider.json
…Metadata Instead of deriving projectKey and repoSlug from the displayName at permission sync time, write them into codeHostMetadata.bitbucketServer during connection compile, and read from there in repoPermissionSyncer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/backend/src/ee/repoPermissionSyncer.ts (1)
295-329: LGTM — well-structured Bitbucket Server branch with one minor observation.Using
codeHostMetadata.bitbucketServer(strongly-typed, schema-validated) instead ofdisplayName.split('/')is the right call here — it avoids string parsing fragility entirely.One minor note on Line 315:
credentials.tokenis passed without a prior existence check. If it isundefined,createBitbucketServerClientsilently falls back to anonymous access (nouser, notoken→ empty auth string), and the subsequentgetUserPermissionsForServerRepocall will then receive a 403 from the Bitbucket Server permissions endpoints, failing the job. The failure path is acceptable, but an early guard would surface the misconfiguration more clearly at the point of origin, consistent with thehostUrlcheck just above:🛡️ Optional early guard for missing token
const hostUrl = credentials.hostUrl; if (!hostUrl) { throw new Error(`No host URL found for Bitbucket Server repo ${id}`); } + + if (!credentials.token) { + throw new Error(`No access token found for Bitbucket Server repo ${id}`); + } const client = createBitbucketServerClient(hostUrl, /* user = */ undefined, credentials.token);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/backend/src/ee/repoPermissionSyncer.ts` around lines 295 - 329, Add an explicit guard for a missing Bitbucket Server credentials.token before calling createBitbucketServerClient: in the branch handling external_codeHostType === 'bitbucketServer' (around the hostUrl check), verify credentials.token exists and throw a clear Error like the hostUrl check if it's undefined (so createBitbucketServerClient + getUserPermissionsForServerRepo are not invoked with anonymous auth); reference the symbols repo/id, credentials.token, createBitbucketServerClient, and getUserPermissionsForServerRepo when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/backend/src/ee/repoPermissionSyncer.ts`:
- Around line 295-329: Add an explicit guard for a missing Bitbucket Server
credentials.token before calling createBitbucketServerClient: in the branch
handling external_codeHostType === 'bitbucketServer' (around the hostUrl check),
verify credentials.token exists and throw a clear Error like the hostUrl check
if it's undefined (so createBitbucketServerClient +
getUserPermissionsForServerRepo are not invoked with anonymous auth); reference
the symbols repo/id, credentials.token, createBitbucketServerClient, and
getUserPermissionsForServerRepo when making the change.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/backend/src/ee/repoPermissionSyncer.tspackages/backend/src/repoCompileUtils.tspackages/shared/src/types.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/backend/src/bitbucket.ts (1)
710-757:getUserPermissionsForServerReporequires REPO_ADMIN / PROJECT_ADMIN – document this constraintBoth endpoints called here have strict access requirements per the Atlassian Bitbucket Server REST API docs:
GET .../repos/{slug}/permissions/users— the authenticated user must have REPO_ADMIN permission for the specified repository or a higher project or global permission.- The project-level
GET .../projects/{key}/permissions/usersendpoint likewise requires PROJECT_ADMIN permission or higher.These calls will return 401/403 for any non-admin token (including end-user OAuth tokens from account-linking flows). The
clientpassed byrepoPermissionSyncermust therefore be constructed with a dedicated service-account or admin token. Neither the function docblock nor the call sites document this requirement.Consider adding an explicit
@requiresnote to the JSDoc, e.g.:+ * `@requires` The BitbucketClient must be authenticated with a token that holds + * REPO_ADMIN (or PROJECT_ADMIN / global ADMIN) permission, as both permission + * listing endpoints reject non-admin callers with 403.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/backend/src/bitbucket.ts` around lines 710 - 757, Add documentation and runtime guidance that getUserPermissionsForServerRepo requires an admin/service account token: update the JSDoc for getUserPermissionsForServerRepo to include an `@requires` note stating the client must have REPO_ADMIN (or PROJECT_ADMIN/global) privileges and list the two endpoints used (/repos/{slug}/permissions/users and /projects/{key}/permissions/users). Also update the repoPermissionSyncer call site(s) to ensure the BitbucketClient passed is constructed with a service-account/admin token (or clearly comment why the existing client meets this requirement), and optionally surface a clearer error (wrap or rethrow) when the client receives 401/403 so callers can detect insufficient privileges promptly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/backend/src/bitbucket.ts`:
- Line 266: Replace usages of error.type with JSON.stringify(error) and remove
the stray space before the opening parenthesis in the throw expression;
specifically, in the cloudGetRepos and serverGetRepos error handling blocks (the
throw new Error(...) statements that currently interpolate ${error.type}),
update them to throw new Error(`Failed to fetch projects for workspace
${workspace}: ${JSON.stringify(error)}`) (and the corresponding repo-fetch error
messages) so error details are consistently serialized for debugging.
---
Nitpick comments:
In `@packages/backend/src/bitbucket.ts`:
- Around line 710-757: Add documentation and runtime guidance that
getUserPermissionsForServerRepo requires an admin/service account token: update
the JSDoc for getUserPermissionsForServerRepo to include an `@requires` note
stating the client must have REPO_ADMIN (or PROJECT_ADMIN/global) privileges and
list the two endpoints used (/repos/{slug}/permissions/users and
/projects/{key}/permissions/users). Also update the repoPermissionSyncer call
site(s) to ensure the BitbucketClient passed is constructed with a
service-account/admin token (or clearly comment why the existing client meets
this requirement), and optionally surface a clearer error (wrap or rethrow) when
the client receives 401/403 so callers can detect insufficient privileges
promptly.
…e tabs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/docs/connections/bitbucket-data-center.mdx`:
- Around line 98-103: The docker run example in the Bitbucket Data Center docs
uses C-style comment syntax ("/* additional args */") which is invalid in bash;
update the code blocks containing the docker run command (the triple-backtick
bash blocks showing "docker run \ -e BITBUCKET_TOKEN=<ACCESS_TOKEN> \ /*
additional args */ \ ghcr.io/sourcebot-dev/sourcebot:latest") by removing the
C-style comment and either (a) omit the placeholder entirely leaving the
backslash line out, or (b) replace it with a bash-safe placeholder (e.g.,
another continuation line with a descriptive token or move a prose note below
the block explaining where to add additional args), so the command is valid when
copied and run.
- Line 77: The two instructions listing permissions are inconsistent: the step
that currently reads "Give it a name and grant it **Project read** and
**Repository read** permissions." should match the other tab which lists
"**Repository read** and **Project read**"; pick one canonical order and update
both occurrences so the phrase/step text is identical (search for the permission
sentence in the Bitbucket Data Center doc and replace the alternate ordering to
ensure both tabs show the same permission sequence).
- Around line 71-135: Add a new section to the Bitbucket Data Center docs
explaining how to enable permission syncing and account linking using the
identityProvider block: describe adding an identityProvider object with purpose:
"account_linking", setting accountLinkingRequired, and configuring the OAuth
scopes (including REPO_READ) needed for permission sync; reference the
identityProvider, purpose: "account_linking", accountLinkingRequired and
REPO_READ symbols and show where to place this block in the connection config
(analogous to the Bitbucket Cloud docs), and mention that tokens used for
account_linking must have the REPO_READ scope and any required OAuth client
details for Bitbucket Server/Data Center.
- Add Bitbucket Data Center to permission-syncing.mdx with prerequisites, partial coverage warning, and notes - Update platform support table to show 🟠 Partial for Bitbucket Data Center - Add connection prerequisites to all code host sections - Update IDP links to point to specific subsections per code host - Update idp.mdx so all code hosts consistently mention additional OAuth scopes needed for permission syncing (matching GitLab's style) - Update bitbucket-data-center.mdx auth section with tabs for user account vs project/repository tokens, and add Note about admin permissions required Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (2)
docs/docs/connections/bitbucket-data-center.mdx (2)
102-107:⚠️ Potential issue | 🟡 MinorUse valid shell syntax in
docker runexamples.Line 105 and Line 135 use C-style comments (
/* ... */), which are invalid in bash and will break pasted commands.Suggested doc fix
docker run \ -e BITBUCKET_TOKEN=<ACCESS_TOKEN> \ - /* additional args */ \ ghcr.io/sourcebot-dev/sourcebot:latestdocker run \ -e BITBUCKET_TOKEN=<ACCESS_TOKEN> \ - /* additional args */ \ ghcr.io/sourcebot-dev/sourcebot:latestAlso applies to: 132-137
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docs/connections/bitbucket-data-center.mdx` around lines 102 - 107, Replace the invalid C-style comment "/* additional args */" used inside the docker run examples with valid shell-friendly placeholders or comments (e.g., use a hash-prefixed comment or an ellipsis) so the bash command is copy-pasteable; update both docker run blocks that contain BITBUCKET_TOKEN=<ACCESS_TOKEN> and the "/* additional args */" token (the fenced codeblocks showing the docker run command) to use a POSIX shell comment or plain explanatory placeholder instead.
81-81:⚠️ Potential issue | 🟡 MinorKeep permission order consistent across both tabs.
Line 81 and Line 112 list the same permissions in different orders; align them to one canonical phrase for readability.
Also applies to: 112-112
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docs/connections/bitbucket-data-center.mdx` at line 81, Align the permission wording in both step descriptions so they read the same; change the second occurrence that lists "Repository read and Project read" to the canonical phrase "Project read and Repository read" so both the step starting "In Bitbucket Data Center, navigate to your profile → Manage account → HTTP access tokens" and the later duplicate step use the identical permission order and phrasing for readability.
🧹 Nitpick comments (2)
docs/docs/features/permission-syncing.mdx (1)
65-66: Standardize “user-driven” / “repo-driven” hyphenation in link labels.Small readability nit: these compound modifiers are clearer and more consistent when hyphenated in prose.
Also applies to: 79-80, 104-105, 124-126
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docs/features/permission-syncing.mdx` around lines 65 - 66, The link labels use inconsistent hyphenation for compound modifiers; update all occurrences of the link text "User driven syncing" (and any variations like "User driven" in link labels) to "User-driven syncing" and ensure any "repo driven" or similar compound modifiers in link labels are changed to "repo-driven" for consistency across the document (e.g., the two list items showing links to /docs/features/permission-syncing should use "User-driven syncing" and any other link labels elsewhere such as the ones noted around the repo/oauth text should be updated similarly).docs/docs/connections/bitbucket-data-center.mdx (1)
81-82: Call out admin permissions directly in the step text when permission syncing is enabled.The global note at Line 74 is good, but these setup steps currently read like read-only permissions are sufficient. Adding an inline conditional note here would reduce misconfiguration risk.
Suggested wording tweak
- Give it a name and grant it **Project read** and **Repository read** permissions. + Give it a name and grant it **Project read** and **Repository read** permissions. + If permission syncing is enabled, also grant **Project Admin** and **Repository Admin** permissions.Also applies to: 112-113
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docs/connections/bitbucket-data-center.mdx` around lines 81 - 82, Update the token-creation step that begins "In Bitbucket Data Center, navigate to your profile → Manage account → HTTP access tokens and click Create token..." to add an inline note that if permission syncing is enabled the token must have admin-level (Project admin/Repository admin or equivalent) permissions instead of just read, and make the same inline wording change in the other equivalent token-creation step later in the document (the one currently mirroring lines 112-113) so both spots explicitly call out admin permissions when permission syncing is enabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@docs/docs/connections/bitbucket-data-center.mdx`:
- Around line 102-107: Replace the invalid C-style comment "/* additional args
*/" used inside the docker run examples with valid shell-friendly placeholders
or comments (e.g., use a hash-prefixed comment or an ellipsis) so the bash
command is copy-pasteable; update both docker run blocks that contain
BITBUCKET_TOKEN=<ACCESS_TOKEN> and the "/* additional args */" token (the fenced
codeblocks showing the docker run command) to use a POSIX shell comment or plain
explanatory placeholder instead.
- Line 81: Align the permission wording in both step descriptions so they read
the same; change the second occurrence that lists "Repository read and Project
read" to the canonical phrase "Project read and Repository read" so both the
step starting "In Bitbucket Data Center, navigate to your profile → Manage
account → HTTP access tokens" and the later duplicate step use the identical
permission order and phrasing for readability.
---
Nitpick comments:
In `@docs/docs/connections/bitbucket-data-center.mdx`:
- Around line 81-82: Update the token-creation step that begins "In Bitbucket
Data Center, navigate to your profile → Manage account → HTTP access tokens and
click Create token..." to add an inline note that if permission syncing is
enabled the token must have admin-level (Project admin/Repository admin or
equivalent) permissions instead of just read, and make the same inline wording
change in the other equivalent token-creation step later in the document (the
one currently mirroring lines 112-113) so both spots explicitly call out admin
permissions when permission syncing is enabled.
In `@docs/docs/features/permission-syncing.mdx`:
- Around line 65-66: The link labels use inconsistent hyphenation for compound
modifiers; update all occurrences of the link text "User driven syncing" (and
any variations like "User driven" in link labels) to "User-driven syncing" and
ensure any "repo driven" or similar compound modifiers in link labels are
changed to "repo-driven" for consistency across the document (e.g., the two list
items showing links to /docs/features/permission-syncing should use "User-driven
syncing" and any other link labels elsewhere such as the ones noted around the
repo/oauth text should be updated similarly).
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
docs/docs/configuration/idp.mdxdocs/docs/connections/bitbucket-data-center.mdxdocs/docs/features/permission-syncing.mdx
…ver repo-driven sync Repo-driven syncing for Bitbucket Server now only covers users with direct repo-level grants. Project-level and group-level access remains covered by account-driven syncing, consistent with the Bitbucket Cloud approach. This avoids redundant API calls (one per repo for the same project) that could cause rate limiting issues at scale. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Using absolute paths (e.g. '/rest/...') with new URL() drops any pathname from the base URL. Normalize the base to end with '/' and use relative paths so deployments with a context path (e.g. https://example.com/bitbucket) resolve correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t error messages Replace error.type interpolation with JSON.stringify(error) for consistent and complete error serialization. Also remove stray space before parenthesis in one throw expression. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
BitbucketServerIdentityProviderConfigto supportpurpose: "account_linking"andaccountLinkingRequired(previously only"sso"was supported)REPO_READOAuth scope when permission syncing is enabledbitbucket-servertoken refresh support viaPOST /rest/oauth2/latest/tokenbitbucketServer/bitbucket-servertoPERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES/PERMISSION_SYNC_SUPPORTED_IDENTITY_PROVIDERSgetReposForAuthenticatedBitbucketServerUserandgetUserPermissionsForServerRepotobitbucket.ts, following the sameBitbucketClientparameter pattern as the Cloud equivalentsbitbucket-serverbranch toaccountPermissionSyncerandbitbucketServerbranch torepoPermissionSynceraccount_linkingpurpose support for Bitbucket ServerTest plan
purpose: account_linkingin config forbitbucket-server, log in, confirm OAuth token is stored inAccounttableaccountPermissionSyncerand verifyAccountToRepoPermissionrows are created for the user's accessible Bitbucket Server reposrepoPermissionSyncerfor abitbucketServerrepo and verifyAccountToRepoPermissionrows for users with direct/project permissionsyarn workspace @sourcebot/web tsc --noEmitpasses with no new errors🤖 Generated with Claude Code
Mintlify
0 threads from 0 users in Mintlify
Summary by CodeRabbit
New Features
Documentation