Use traversal_ids confidentiality filter in notes

Summary

The notes advanced search query currently uses legacy project_id authorization for issue confidentiality filtering. This should be migrated to use the modern traversal_ids-based confidential filters available in the Elastic::Filters class.

Current Implementation

In ee/lib/elastic/latest/note_class_proxy.rb, the confidentiality_filter method (lines 68-145) implements custom confidentiality logic that relies on:

  • Direct project_id terms queries for authorization
  • Manual construction of boolean filters for confidential issues
  • Separate handling for issue and non-issue confidentiality

Key problematic code:

filter[:bool][:should] << {
  bool: {
    must: [
      # ... confidential issue checks ...
      {
        bool: {
          _name: context.name(:user, :issue_author, :issue_assignee, :project_membership),
          should: [
            { term: { "issue.author_id" => current_user.id } },
            { term: { "issue.assignee_id" => current_user.id } },
            { terms: { project_id: project_ids } }  # ← Legacy project_id authorization
          ]
        }
      }
    ]
  }
}

Proposed Solution

Migrate to use the standardized confidentiality filters in ee/lib/search/elastic/filters/confidentiality_filters.rb, which provides:

  • Traversal IDs support: Uses traversal_ids for efficient ancestry-based authorization
  • Unified filtering: Handles both project and group-level confidentiality
  • Better performance: Optimized queries with proper trie-based traversal ID filtering
  • Consistent authorization: Aligns with other search entities (issues, merge requests, etc.)

The ConfidentialityFilters module provides:

  • by_project_confidentiality - Project-level confidentiality with traversal_ids
  • by_group_level_confidentiality - Group-level confidentiality
  • by_combined_confidentiality - Combined project and group filtering

Benefits

  1. Performance: Traversal IDs enable more efficient group-level searches
  2. Consistency: Aligns notes search with other entity types
  3. Maintainability: Removes duplicate confidentiality logic
  4. Scalability: Better support for deeply nested group hierarchies

Implementation Notes

The refactor should:

  1. Replace the custom confidentiality_filter method in NoteClassProxy
  2. Use Search::Elastic::Filters.by_combined_confidentiality or by_project_confidentiality
  3. Ensure proper handling of note-specific fields (issue.confidential, issue.author_id, issue.assignee_id)
  4. Maintain backward compatibility with existing search behavior
  5. Add appropriate tests for group-level note searches with confidential issues
Edited Feb 12, 2026 by Terri Chu
Assignee Loading
Time tracking Loading