Fix code Advanced Search for Planner role in private projects

What does this MR do and why?

A Planner member of a private project gets no Advanced Search (Elasticsearch) results for code (blobs), and the language filter sidebar is empty. This MR fixes that.

ProjectPolicy gives Planners read_code, and BlobPolicy uses read_code. Search was stricter than the policy. The Elasticsearch membership filters use PRIVATE_FEATURES_MIN_ACCESS_LEVEL_FOR_PRIVATE_PROJECT[:repository], which is Reporter for private projects.

The fix is in ee/lib/elastic/latest/git_class_proxy.rb:

  • The 'blob' branch of elastic_search now passes the same relaxed_feature_access rule that commit search uses. This covers results and counts.
  • blob_aggregations passes it too, so the language facet works.
  • The constant COMMIT_RELAXED_FEATURE_ACCESS is renamed to REPOSITORY_RELAXED_FEATURE_ACCESS, because commits and blobs now share it. note_class_proxy.rb also uses it for comments on commits, so it now uses the new name.

ee/lib/search/elastic/filters.rb is unchanged. The relaxed-rule handling and dedup from the commit MR already cover this, so query bodies for non-Planner roles are unchanged.

No feature flag, same as the commit MR: this is a small alignment of search with an existing policy. No database or UI changes.

Scope: Advanced Search for code only. Zoekt exact code search is still unsupported for Planners in private projects, tracked in #602978 (closed).

Background and why not lower the shared constant

Commit search had the same bug. It was fixed in !253191 (merged) with relaxed_feature_access for the repository feature (Planner minimum, ENABLED and PRIVATE feature access levels). That MR left blobs out of scope on purpose, and git_class_proxy_spec pinned Planner to 0 results for blob search.

Lowering PRIVATE_FEATURES_MIN_ACCESS_LEVEL_FOR_PRIVATE_PROJECT[:repository] would be simpler, but that constant is also read by Project.filter_by_feature_visibility and Search::GroupsFinder, so the change would reach beyond Advanced Search.

Tests

  • The global, group and project blob visibility specs (ee/spec/services/ee/search/*_service_blobs_visibility_spec.rb) now have separate Advanced Search and Zoekt contexts.
    • Advanced Search uses permission_table_for_repository_access, the same table the commit visibility specs use. It has Planner rows and a private | enabled block.
    • Zoekt keeps permission_table_for_guest_feature_access_and_non_private_project_only, since Zoekt is unchanged.
  • git_class_proxy_spec flips the Planner blob row to 1 result. It also adds a blob_aggregations example for a private project: Guest gets no buckets, Planner gets buckets.
  • Reverting the lib change makes exactly the private-project Planner rows fail.

Docs

The footnote in doc/user/permissions.md now reads: "Users with the Planner role cannot use exact code search in private projects." It links to #602978 (closed) instead of the epic.

References

Screenshots or screen recordings

No UI changes.

How to set up and validate locally

  1. Enable Elasticsearch and Advanced Search in the GDK.
  2. Create a private project with a repository and some code.
  3. Add a user to the project with the Planner role.
  4. Index the project.
  5. Sign in as that user and search code, scoped to the project, the group, and globally.
  6. Confirm results are returned and the language filter sidebar shows languages. Before this change, both were empty.
  7. Repeat as a Guest member and confirm no code results are returned.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

🤖 Generated with Claude Code

Edited by Ravi Kumar

Merge request reports

Loading
Loading