diff options
Diffstat (limited to 'lib/api')
-rw-r--r-- | lib/api/entities/project_with_access.rb | 6 | ||||
-rw-r--r-- | lib/api/groups.rb | 4 | ||||
-rw-r--r-- | lib/api/helpers.rb | 4 | ||||
-rw-r--r-- | lib/api/projects.rb | 27 |
4 files changed, 29 insertions, 12 deletions
diff --git a/lib/api/entities/project_with_access.rb b/lib/api/entities/project_with_access.rb index c53a712a879..ac89cb52e43 100644 --- a/lib/api/entities/project_with_access.rb +++ b/lib/api/entities/project_with_access.rb @@ -26,8 +26,10 @@ module API # rubocop: disable CodeReuse/ActiveRecord def self.preload_relation(projects_relation, options = {}) relation = super(projects_relation, options) - project_ids = relation.select('projects.id') - namespace_ids = relation.select(:namespace_id) + # use reselect to override the existing select and + # prevent an error `subquery has too many columns` + project_ids = relation.reselect('projects.id') + namespace_ids = relation.reselect(:namespace_id) options[:project_members] = options[:current_user] .project_members diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 9b6b28733ff..522a9dd406e 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -128,10 +128,6 @@ module API groups.reorder(group_without_similarity_options) # rubocop: disable CodeReuse/ActiveRecord end - def order_by_similarity? - params[:order_by] == 'similarity' && params[:search].present? - end - def group_without_similarity_options order_options = { params[:order_by] => params[:sort] } order_options['name'] = order_options.delete('similarity') if order_options.has_key?('similarity') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3398d5da7f5..9c347148fd0 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -577,6 +577,10 @@ module API Gitlab::AppLogger.warn("Redis tracking event failed for event: #{event_name}, message: #{error.message}") end + def order_by_similarity?(allow_unauthorized: true) + params[:order_by] == 'similarity' && params[:search].present? && (allow_unauthorized || current_user.present?) + end + protected def project_finder_params_visibility_ce diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 3b1d239398f..3670406862c 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -45,6 +45,20 @@ module API end end + def support_order_by_similarity!(attrs) + return unless params[:order_by] == 'similarity' + + if order_by_similarity?(allow_unauthorized: false) + # Limit to projects the current user is a member of. + # Do not include all public projects because it + # could cause long running queries + attrs[:non_public] = true + attrs[:sort] = params['order_by'] + else + params[:order_by] = route.params['order_by'][:default] + end + end + def delete_project(user_project) destroy_conditionally!(user_project) do ::Projects::DestroyService.new(user_project, current_user, {}).async_execute @@ -93,8 +107,8 @@ module API params :sort_params do optional :order_by, type: String, - values: %w[id name path created_at updated_at last_activity_at] + Helpers::ProjectsHelpers::STATISTICS_SORT_PARAMS, - default: 'created_at', desc: "Return projects ordered by field. #{Helpers::ProjectsHelpers::STATISTICS_SORT_PARAMS.join(', ')} are only available to admins." + values: %w[id name path created_at updated_at last_activity_at similarity] + Helpers::ProjectsHelpers::STATISTICS_SORT_PARAMS, + default: 'created_at', desc: "Return projects ordered by field. #{Helpers::ProjectsHelpers::STATISTICS_SORT_PARAMS.join(', ')} are only available to admins. Similarity is available when searching and is limited to projects the user has access to." optional :sort, type: String, values: %w[asc desc], default: 'desc', desc: 'Return projects sorted in ascending and descending order' end @@ -131,16 +145,17 @@ module API end def load_projects - params = project_finder_params - verify_project_filters!(params) + project_params = project_finder_params + support_order_by_similarity!(project_params) + verify_project_filters!(project_params) - ProjectsFinder.new(current_user: current_user, params: params).execute + ProjectsFinder.new(current_user: current_user, params: project_params).execute end def present_projects(projects, options = {}) verify_statistics_order_by_projects! - projects = reorder_projects(projects) + projects = reorder_projects(projects) unless order_by_similarity?(allow_unauthorized: false) projects = apply_filters(projects) records, options = paginate_with_strategies(projects, options[:request_scope]) do |projects| |