fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync - #998

Merged
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635
Mar 12, 2026
Merged

fix(worker): guard against anonymous Bitbucket Server token fallback in account permission sync#998
brendan-kellam merged 4 commits into
mainfrom
brendan/fix-bitbucket-server-permission-sync-SOU-635

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bitbucket Server instances with anonymous access enabled (feature.public.access) silently treat expired/invalid OAuth tokens as anonymous rather than returning a 401
  • This caused account-driven permission syncing to call /rest/api/1.0/repos?permission=REPO_READ, which is guaranteed to return an empty list for anonymous requests, wiping all AccountToRepoPermission records
  • Added isBitbucketServerUserAuthenticated() which calls /rest/api/1.0/profile/recent/repos — an endpoint that always requires authentication even with anonymous access enabled — to detect this condition and abort the sync job before any permissions are touched
  • Also added explicit throws for unsupported provider/code host types in both syncers instead of silently returning empty results

Test plan

  • Verify that an expired Bitbucket Server OAuth token causes the account permission sync job to fail with a clear error message rather than wiping permissions
  • Verify that a valid Bitbucket Server OAuth token allows the sync to proceed as normal
  • Confirm on a Bitbucket Server instance with anonymous access enabled that the auth check correctly detects the anonymous fallback

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where Bitbucket Server repository permissions could be silently wiped when OAuth tokens expired on instances with anonymous access enabled.
    • Added explicit authentication checks for Bitbucket Server access to prevent unauthorized fetches.
    • Enhanced error handling to return clear errors for unsupported code hosts instead of silently continuing.

…in account permission sync
Bitbucket Server instances with anonymous access enabled silently treat
expired/invalid OAuth tokens as anonymous rather than returning a 401.
This caused account-driven permission syncing to receive an empty repo
list (200 OK) and wipe all AccountToRepoPermission records.
Added isBitbucketServerUserAuthenticated() which calls
/rest/api/1.0/profile/recent/repos — an endpoint that always requires
authentication even when anonymous access is enabled — to detect this
condition before fetching repos. Also added explicit throws for
unsupported provider/code host types instead of silently returning
empty results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ebf316-2cb4-4f1f-abf3-24cd2f38783f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e38735 and f4feeba.

📒 Files selected for processing (1)
  • packages/backend/src/bitbucket.ts

Walkthrough

Adds an explicit Bitbucket Server authentication check before fetching repositories and changes permission-sync workflows to throw errors for unsupported code host types; also documents a FIXED changelog entry for an OAuth-token expiration bug that could wipe Bitbucket Server repo permissions.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added FIXED entry documenting a bug where expired OAuth tokens could silently remove Bitbucket Server repository permissions when anonymous access was enabled.
Bitbucket Server auth & API
packages/backend/src/bitbucket.ts
Added and exported isBitbucketServerUserAuthenticated(client) which queries /rest/api/1.0/profile/recent/repos; getReposForAuthenticatedBitbucketServerUser now checks authentication and throws on unauthenticated responses; updated JSDoc API reference path.
Permission syncer error handling
packages/backend/src/ee/accountPermissionSyncer.ts, packages/backend/src/ee/repoPermissionSyncer.ts
Replaced silent no-op/empty-return behavior for unsupported code host types with explicit thrown errors (Unsupported code host type: ...), changing control flow to surface unsupported-provider cases.

Sequence Diagram(s)

sequenceDiagram
participant Syncer as Account/RepoPermissionSyncer
participant Client as BitbucketClient
participant BBServer as Bitbucket Server API
participant DB as Permissions DB
rect rgba(0,128,255,0.5)
Syncer->>Client: isBitbucketServerUserAuthenticated()
end
rect rgba(0,200,83,0.5)
Client->>BBServer: GET /rest/api/1.0/profile/recent/repos
BBServer-->>Client: 200 / 401/403 / other
end
alt 200 OK
Client-->>Syncer: true
Syncer->>Client: getReposForAuthenticatedBitbucketServerUser()
Client->>BBServer: GET /rest/api/1.0/repos/...
BBServer-->>Client: repo list
Client-->>Syncer: repo IDs
Syncer->>DB: update permissions for repos
else 401 or 403
Client-->>Syncer: false
Syncer-->>Syncer: throw authentication error -> abort sync
else other error
Client-->>Syncer: propagate error -> abort sync
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Title check✅ PassedThe PR title accurately describes the main change: adding a guard to prevent anonymous token fallback in Bitbucket Server account permission sync, which aligns with the core bug fix across all modified files.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-server-permission-sync-SOU-635
📝 Coding Plan
  • Generate coding plan for human review comments

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 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`:
- Around line 789-794: The current isBitbucketServerUserAuthenticated conflates
any API error with “not authenticated”; update the implementation so it
distinguishes authentication failures from other errors by inspecting the API
error status (from the result or thrown exception from client.apiClient.GET).
Specifically, call client.apiClient.GET inside a try/catch, treat explicit auth
statuses (401 or 403) as authenticated=false (return false), rethrow or surface
any other errors so callers can handle service-side problems, and return true
only when the call succeeds; refer to isBitbucketServerUserAuthenticated and the
client.apiClient.GET(`/rest/api/1.0/profile/recent/repos`) call to locate where
to apply this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5906002d-018b-4ac7-8c95-f05b8b375d07

📥 Commits

Reviewing files that changed from the base of the PR and between 93199aa and 3e38735.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/backend/src/bitbucket.ts
  • packages/backend/src/ee/accountPermissionSyncer.ts
  • packages/backend/src/ee/repoPermissionSyncer.ts

Comment threadpackages/backend/src/bitbucket.ts
@brendan-kellam
brendan-kellam merged commit 13629e9 into mainMar 12, 2026
6 of 7 checks passed
@brendan-kellam
brendan-kellam deleted the brendan/fix-bitbucket-server-permission-sync-SOU-635 branch March 12, 2026 23:16
@github-actionsgithub-actionsBot mentioned this pull request Mar 12, 2026
Sign up for freeto 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

@brendan-kellam