diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/helpers/pagination_strategies.rb | 34 | ||||
-rw-r--r-- | lib/api/projects.rb | 4 | ||||
-rw-r--r-- | lib/banzai/pipeline.rb | 2 | ||||
-rw-r--r-- | lib/banzai/renderer.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/auth.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/pagination/keyset.rb | 11 |
6 files changed, 49 insertions, 13 deletions
diff --git a/lib/api/helpers/pagination_strategies.rb b/lib/api/helpers/pagination_strategies.rb index 6bebb4bfeac..823891d6fe7 100644 --- a/lib/api/helpers/pagination_strategies.rb +++ b/lib/api/helpers/pagination_strategies.rb @@ -3,19 +3,24 @@ module API module Helpers module PaginationStrategies - def paginate_with_strategies(relation) - paginator = paginator(relation) + def paginate_with_strategies(relation, request_scope) + paginator = paginator(relation, request_scope) yield(paginator.paginate(relation)).tap do |records, _| paginator.finalize(records) end end - def paginator(relation) - return Gitlab::Pagination::OffsetPagination.new(self) unless keyset_pagination_enabled? + def paginator(relation, request_scope = nil) + return keyset_paginator(relation) if keyset_pagination_enabled? - request_context = Gitlab::Pagination::Keyset::RequestContext.new(self) + offset_paginator(relation, request_scope) + end + + private + def keyset_paginator(relation) + request_context = Gitlab::Pagination::Keyset::RequestContext.new(self) unless Gitlab::Pagination::Keyset.available?(request_context, relation) return error!('Keyset pagination is not yet available for this type of request', 405) end @@ -23,11 +28,28 @@ module API Gitlab::Pagination::Keyset::Pager.new(request_context) end - private + def offset_paginator(relation, request_scope) + offset_limit = limit_for_scope(request_scope) + if Gitlab::Pagination::Keyset.available_for_type?(relation) && offset_limit_exceeded?(offset_limit) + return error!("Offset pagination has a maximum allowed offset of #{offset_limit} " \ + "for requests that return objects of type #{relation.klass}. " \ + "Remaining records can be retrieved using keyset pagination.", 405) + end + + Gitlab::Pagination::OffsetPagination.new(self) + end def keyset_pagination_enabled? params[:pagination] == 'keyset' end + + def limit_for_scope(scope) + (scope || Plan.default).actual_limits.offset_pagination_limit + end + + def offset_limit_exceeded?(offset_limit) + offset_limit.positive? && params[:page] * params[:per_page] > offset_limit + end end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index ee0731a331f..732453cf1c4 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -95,7 +95,7 @@ module API projects = reorder_projects(projects) projects = apply_filters(projects) - records, options = paginate_with_strategies(projects) do |projects| + records, options = paginate_with_strategies(projects, options[:request_scope]) do |projects| projects, options = with_custom_attributes(projects, options) options = options.reverse_merge( @@ -313,7 +313,7 @@ module API get ':id/forks' do forks = ForkProjectsFinder.new(user_project, params: project_finder_params, current_user: current_user).execute - present_projects forks + present_projects forks, request_scope: user_project end desc 'Check pages access of this project' diff --git a/lib/banzai/pipeline.rb b/lib/banzai/pipeline.rb index 8fdbc044861..01cadb11e83 100644 --- a/lib/banzai/pipeline.rb +++ b/lib/banzai/pipeline.rb @@ -9,7 +9,7 @@ module Banzai # Examples: # Pipeline[nil] # => Banzai::Pipeline::FullPipeline # Pipeline[:label] # => Banzai::Pipeline::LabelPipeline - # Pipeline[StatusPage::PostProcessPipeline] # => StatusPage::PostProcessPipeline + # Pipeline[StatusPage::Pipeline::PostProcessPipeline] # => StatusPage::Pipeline::PostProcessPipeline # # Pipeline['label'] # => raises ArgumentError - unsupport type # Pipeline[Project] # => raises ArgumentError - not a subclass of BasePipeline diff --git a/lib/banzai/renderer.rb b/lib/banzai/renderer.rb index 3cb9ec21e8f..fbbd6135959 100644 --- a/lib/banzai/renderer.rb +++ b/lib/banzai/renderer.rb @@ -138,15 +138,18 @@ module Banzai # # html - String to process # context - Hash of options to customize output - # :pipeline - Symbol pipeline type + # :pipeline - Symbol pipeline type - for context transform only, defaults to :full # :project - Project # :user - User object + # :post_process_pipeline - pipeline to use for post_processing - defaults to PostProcessPipeline # # Returns an HTML-safe String def self.post_process(html, context) context = Pipeline[context[:pipeline]].transform_context(context) - pipeline = Pipeline[:post_process] + # Use a passed class for the pipeline or default to PostProcessPipeline + pipeline = context.delete(:post_process_pipeline) || ::Banzai::Pipeline::PostProcessPipeline + if context[:xhtml] pipeline.to_document(html, context).to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_XHTML) else diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 8e14d21f591..44e8c9c04b9 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -337,6 +337,10 @@ module Gitlab REGISTRY_SCOPES end + def resource_bot_scopes + Gitlab::Auth::API_SCOPES + Gitlab::Auth::REPOSITORY_SCOPES + Gitlab::Auth.registry_scopes - [:read_user] + end + private def non_admin_available_scopes diff --git a/lib/gitlab/pagination/keyset.rb b/lib/gitlab/pagination/keyset.rb index 8692f30e165..67a5530d46c 100644 --- a/lib/gitlab/pagination/keyset.rb +++ b/lib/gitlab/pagination/keyset.rb @@ -3,11 +3,18 @@ module Gitlab module Pagination module Keyset + SUPPORTED_TYPES = [ + Project + ].freeze + + def self.available_for_type?(relation) + SUPPORTED_TYPES.include?(relation.klass) + end + def self.available?(request_context, relation) order_by = request_context.page.order_by - # This is only available for Project and order-by id (asc/desc) - return false unless relation.klass == Project + return false unless available_for_type?(relation) return false unless order_by.size == 1 && order_by[:id] true |