fix(worker): guard against stale public flags when Bitbucket Server feature.public.access is disabled#999
Conversation
…eature.public.access is disabled When feature.public.access is turned off on a Bitbucket Server instance, per-repo public flags are not reset, so repos that were previously public still appear as public: true in the API. This caused Sourcebot to treat those repos as publicly accessible in the permission filter, potentially exposing them to users who no longer have access. Fix by making a single unauthenticated probe request to one of the reportedly-public repos during compilation. If the probe fails, the feature flag is assumed disabled and all repos are treated as private. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
WalkthroughThis pull request fixes a bug where Bitbucket Server repositories are incorrectly treated as public when the instance-level feature.public.access setting is disabled. A new function probes anonymous access capability to Bitbucket Server, and visibility logic is updated to check both per-repo and server-wide public access settings. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/backend/src/bitbucket.ts (2)
793-797: Consider logging when the probe is skipped due to missing identifiers.When
projectKeyorrepoSlugis missing, the function silently returnsfalse, treating it as if public access is disabled. While defaulting to the safer assumption is appropriate, logging a warning here would help diagnose unexpected behavior if a repo from the API has malformed data.🔧 Suggested improvement
const projectKey = publicRepo.project?.key; const repoSlug = publicRepo.slug; if (!projectKey || !repoSlug) { + logger.warn(`Cannot probe public access: repo missing projectKey or repoSlug`); return false; }🤖 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 793 - 797, When projectKey or repoSlug extracted from publicRepo are missing, add a warning log before returning false: log which identifier is missing and include identifying context from publicRepo (e.g., publicRepo.id, publicRepo.name or the raw object) so callers can diagnose malformed API data; implement this in the same block handling projectKey/repoSlug (use the existing logger instance such as logger or processLogger), then return false as before.
800-805: Consider adding a timeout to the probe request.The unauthenticated fetch has no explicit timeout. If the server is slow or unresponsive, this could delay the entire connection sync. Consider adding an
AbortSignalwith a reasonable timeout (e.g., 10-30 seconds).🔧 Suggested improvement
+ const PROBE_TIMEOUT_MS = 15000; const url = `${serverUrl}/rest/api/1.0/projects/${projectKey}/repos/${repoSlug}`; try { const response = await fetch(url, { headers: { Accept: 'application/json' }, // Intentionally no Authorization header - we want to test anonymous access + signal: AbortSignal.timeout(PROBE_TIMEOUT_MS), }); return response.ok; } catch (e) {🤖 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 800 - 805, The anonymous probe fetch currently has no timeout and can hang; wrap the request in an AbortController with a short timeout (e.g., 10–30s), pass controller.signal to fetch, and clear the timeout after the response is received. Locate the try block that calls fetch(url, { headers: { Accept: 'application/json' } }) (the anonymous probe returning response.ok) and add the AbortController logic and a setTimeout that calls controller.abort(), and ensure any abort errors are handled so the function returns false or propagates a controlled error as appropriate.
🤖 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/bitbucket.ts`:
- Around line 793-797: When projectKey or repoSlug extracted from publicRepo are
missing, add a warning log before returning false: log which identifier is
missing and include identifying context from publicRepo (e.g., publicRepo.id,
publicRepo.name or the raw object) so callers can diagnose malformed API data;
implement this in the same block handling projectKey/repoSlug (use the existing
logger instance such as logger or processLogger), then return false as before.
- Around line 800-805: The anonymous probe fetch currently has no timeout and
can hang; wrap the request in an AbortController with a short timeout (e.g.,
10–30s), pass controller.signal to fetch, and clear the timeout after the
response is received. Locate the try block that calls fetch(url, { headers: {
Accept: 'application/json' } }) (the anonymous probe returning response.ok) and
add the AbortController logic and a setTimeout that calls controller.abort(),
and ensure any abort errors are handled so the function returns false or
propagates a controlled error as appropriate.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 79ae73bf-a40c-46d4-9f4a-864bb8f566eb
📒 Files selected for processing (3)
CHANGELOG.mdpackages/backend/src/bitbucket.tspackages/backend/src/repoCompileUtils.ts
Summary
feature.public.accessis disabled on a Bitbucket Server instance, per-repopublicflags are not reset by Bitbucket — repos that were previously public remainpublic: truein the API response.getRepoPermissionFilterForUser) to treat those repos as genuinely public, potentially exposing them to users who no longer have access on the code host.feature.public.accessflag is assumed disabled and all repos on that instance are treated as private.Test plan
feature.public.access=trueand public repos correctly marks those repos asisPublic: truefeature.public.access=false(but stalepublic: truerepo flags) marks all repos asisPublic: false🤖 Generated with Claude Code
Summary by CodeRabbit