From 25c0f91bb9e1af7a9ba7d2ffcbd396af5558c10f Mon Sep 17 00:00:00 2001 From: Jessie Young Date: Tue, 21 Oct 2025 13:07:29 -0700 Subject: [PATCH 1/2] Add backend support for @@ special users autocomplete - Add special_users endpoint to AutocompleteController - Filter users by maintainer+ access level - Add rate limiting for new endpoint --- app/controllers/autocomplete_controller.rb | 53 ++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 370daf8c54304e..8f453f0fb6503c 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -7,15 +7,15 @@ class AutocompleteController < ApplicationController :users, :award_emojis, :merge_request_target_branches, :merge_request_source_branches ] before_action :check_search_rate_limit!, only: :projects - before_action :check_autocomplete_users_rate_limit!, only: :users + before_action :check_autocomplete_users_rate_limit!, only: [:users, :special_users] - feature_category :user_profile, [:users, :user] + feature_category :user_profile, [:users, :user, :special_users] feature_category :groups_and_projects, [:projects] feature_category :team_planning, [:award_emojis] feature_category :code_review_workflow, [:merge_request_target_branches, :merge_request_source_branches] feature_category :continuous_delivery, [:deploy_keys_with_owners] - urgency :low, [:merge_request_target_branches, :merge_request_source_branches, :deploy_keys_with_owners, :users] + urgency :low, [:merge_request_target_branches, :merge_request_source_branches, :deploy_keys_with_owners, :users, :special_users] urgency :low, [:award_emojis] urgency :medium, [:projects] @@ -44,6 +44,27 @@ def users render json: presented_users end + # POC: Special users endpoint for @@ autocomplete + # Returns users filtered by access level (maintainer and above) + def special_users + group = Autocomplete::GroupFinder + .new(current_user, project, params) + .execute + + users = Autocomplete::UsersFinder + .new(params: params, current_user: current_user, project: project, group: group) + .execute + + # Filter users based on access level + filtered_users = filter_special_users(users) + + presented_users = UserSerializer + .new(params.merge({ current_user: current_user })) + .represent(filtered_users, project: project) + + render json: presented_users + end + def user user = UserFinder.new(params[:id]).find_by_id! @@ -121,6 +142,32 @@ def check_autocomplete_users_rate_limit! check_rate_limit!(:autocomplete_users_unauthenticated, scope: request.ip) end end + + # POC: Filter users by access level (maintainer and above) + # In a production implementation, this could be: + # - Moved to a separate service class + # - Made configurable via params (e.g., minimum_access_level) + # - Optimized with database queries instead of filtering in memory + def filter_special_users(users) + return users unless project || params[:group_id] + + users.select do |user| + if project + # Check project membership + member = project.team.member(user) + member && member.access_level >= Gitlab::Access::MAINTAINER + elsif params[:group_id] + # Check group membership + group = Group.find_by_id(params[:group_id]) + next false unless group + + member = group.members.find_by(user_id: user.id) + member && member.access_level >= Gitlab::Access::MAINTAINER + else + false + end + end + end end AutocompleteController.prepend_mod_with('AutocompleteController') -- GitLab From b2456d6db92217a79be867522908614fee2c0a24 Mon Sep 17 00:00:00 2001 From: Jessie Young Date: Tue, 21 Oct 2025 13:09:08 -0700 Subject: [PATCH 2/2] Add route for @@ special users endpoint --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index c410d349eb493d..437d2fed837e70 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -105,6 +105,7 @@ scope path: '-' do # Autocomplete get '/autocomplete/users' => 'autocomplete#users' + get '/autocomplete/special_users' => 'autocomplete#special_users' get '/autocomplete/users/:id' => 'autocomplete#user' get '/autocomplete/projects' => 'autocomplete#projects' get '/autocomplete/award_emojis' => 'autocomplete#award_emojis' -- GitLab