Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-23 15:08:38 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-23 15:08:38 +0300
commit5ad0cf26551baff8f08af8562a8d45e6ec14d71a (patch)
tree57f1a6bad31bcd11efacd3fdfb9cc92f88fb6a86 /app/controllers
parentf47c768fad17d4c876e96524f83f8306f071db66 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/concerns/page_limiter.rb68
-rw-r--r--app/controllers/explore/projects_controller.rb33
-rw-r--r--app/controllers/projects/snippets_controller.rb24
-rw-r--r--app/controllers/snippets/notes_controller.rb2
-rw-r--r--app/controllers/snippets_controller.rb8
-rw-r--r--app/controllers/uploads_controller.rb2
6 files changed, 118 insertions, 19 deletions
diff --git a/app/controllers/concerns/page_limiter.rb b/app/controllers/concerns/page_limiter.rb
new file mode 100644
index 00000000000..5b078d80fca
--- /dev/null
+++ b/app/controllers/concerns/page_limiter.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+# Include this in your controller and call `limit_pages` in order
+# to configure the limiter.
+#
+# Examples:
+# class MyController < ApplicationController
+# include PageLimiter
+#
+# before_action only: [:index] do
+# limit_pages(500)
+# end
+#
+# # You can override the default response
+# rescue_from PageOutOfBoundsError, with: :page_out_of_bounds
+#
+# def page_out_of_bounds(error)
+# # Page limit number is available as error.message
+# head :ok
+# end
+#
+
+module PageLimiter
+ extend ActiveSupport::Concern
+
+ PageLimiterError = Class.new(StandardError)
+ PageLimitNotANumberError = Class.new(PageLimiterError)
+ PageLimitNotSensibleError = Class.new(PageLimiterError)
+ PageOutOfBoundsError = Class.new(PageLimiterError)
+
+ included do
+ rescue_from PageOutOfBoundsError, with: :default_page_out_of_bounds_response
+ end
+
+ def limit_pages(max_page_number)
+ check_page_number!(max_page_number)
+ end
+
+ private
+
+ # If the page exceeds the defined maximum, raise a PageOutOfBoundsError
+ # If the page doesn't exceed the limit, it does nothing.
+ def check_page_number!(max_page_number)
+ raise PageLimitNotANumberError unless max_page_number.is_a?(Integer)
+ raise PageLimitNotSensibleError unless max_page_number > 0
+
+ if params[:page].present? && params[:page].to_i > max_page_number
+ record_page_limit_interception
+ raise PageOutOfBoundsError.new(max_page_number)
+ end
+ end
+
+ # By default just return a HTTP status code and an empty response
+ def default_page_out_of_bounds_response
+ head :bad_request
+ end
+
+ # Record the page limit being hit in Prometheus
+ def record_page_limit_interception
+ dd = DeviceDetector.new(request.user_agent)
+
+ Gitlab::Metrics.counter(:gitlab_page_out_of_bounds,
+ controller: params[:controller],
+ action: params[:action],
+ bot: dd.bot?
+ )
+ end
+end
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index 271f2b4b57d..a8a76b47bbe 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class Explore::ProjectsController < Explore::ApplicationController
+ include PageLimiter
include ParamsBackwardCompatibility
include RendersMemberAccess
include SortingHelper
@@ -9,6 +10,13 @@ class Explore::ProjectsController < Explore::ApplicationController
before_action :set_non_archived_param
before_action :set_sorting
+ # Limit taken from https://gitlab.com/gitlab-org/gitlab/issues/38357
+ before_action only: [:index, :trending, :starred] do
+ limit_pages(200)
+ end
+
+ rescue_from PageOutOfBoundsError, with: :page_out_of_bounds
+
def index
@projects = load_projects
@@ -53,10 +61,14 @@ class Explore::ProjectsController < Explore::ApplicationController
private
- # rubocop: disable CodeReuse/ActiveRecord
- def load_projects
+ def load_project_counts
@total_user_projects_count = ProjectsFinder.new(params: { non_public: true }, current_user: current_user).execute
@total_starred_projects_count = ProjectsFinder.new(params: { starred: true }, current_user: current_user).execute
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def load_projects
+ load_project_counts
projects = ProjectsFinder.new(current_user: current_user, params: params)
.execute
@@ -80,4 +92,21 @@ class Explore::ProjectsController < Explore::ApplicationController
def sorting_field
Project::SORTING_PREFERENCE_FIELD
end
+
+ def page_out_of_bounds(error)
+ load_project_counts
+ @max_page_number = error.message
+
+ respond_to do |format|
+ format.html do
+ render "page_out_of_bounds", status: :bad_request
+ end
+
+ format.json do
+ render json: {
+ html: view_to_html_string("explore/projects/page_out_of_bounds")
+ }, status: :bad_request
+ end
+ end
+ end
end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index daddd9dd485..d7ae6d2cbb4 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -15,17 +15,17 @@ class Projects::SnippetsController < Projects::ApplicationController
before_action :check_snippets_available!
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
- # Allow read any snippet
- before_action :authorize_read_project_snippet!, except: [:new, :create, :index]
+ # Allow create snippet
+ before_action :authorize_create_snippet!, only: [:new, :create]
- # Allow write(create) snippet
- before_action :authorize_create_project_snippet!, only: [:new, :create]
+ # Allow read any snippet
+ before_action :authorize_read_snippet!, except: [:new, :create, :index]
# Allow modify snippet
- before_action :authorize_update_project_snippet!, only: [:edit, :update]
+ before_action :authorize_update_snippet!, only: [:edit, :update]
# Allow destroy snippet
- before_action :authorize_admin_project_snippet!, only: [:destroy]
+ before_action :authorize_admin_snippet!, only: [:destroy]
respond_to :html
@@ -115,16 +115,16 @@ class Projects::SnippetsController < Projects::ApplicationController
project_snippet_path(@project, @snippet)
end
- def authorize_read_project_snippet!
- return render_404 unless can?(current_user, :read_project_snippet, @snippet)
+ def authorize_read_snippet!
+ return render_404 unless can?(current_user, :read_snippet, @snippet)
end
- def authorize_update_project_snippet!
- return render_404 unless can?(current_user, :update_project_snippet, @snippet)
+ def authorize_update_snippet!
+ return render_404 unless can?(current_user, :update_snippet, @snippet)
end
- def authorize_admin_project_snippet!
- return render_404 unless can?(current_user, :admin_project_snippet, @snippet)
+ def authorize_admin_snippet!
+ return render_404 unless can?(current_user, :admin_snippet, @snippet)
end
def snippet_params
diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb
index 551b37cb3d3..a7e8ef0798b 100644
--- a/app/controllers/snippets/notes_controller.rb
+++ b/app/controllers/snippets/notes_controller.rb
@@ -33,7 +33,7 @@ class Snippets::NotesController < ApplicationController
end
def authorize_read_snippet!
- return render_404 unless can?(current_user, :read_personal_snippet, snippet)
+ return render_404 unless can?(current_user, :read_snippet, snippet)
end
def authorize_create_note!
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index fc073e47368..b6ad5fd02b0 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -126,7 +126,7 @@ class SnippetsController < ApplicationController
end
def authorize_read_snippet!
- return if can?(current_user, :read_personal_snippet, @snippet)
+ return if can?(current_user, :read_snippet, @snippet)
if current_user
render_404
@@ -136,15 +136,15 @@ class SnippetsController < ApplicationController
end
def authorize_update_snippet!
- return render_404 unless can?(current_user, :update_personal_snippet, @snippet)
+ return render_404 unless can?(current_user, :update_snippet, @snippet)
end
def authorize_admin_snippet!
- return render_404 unless can?(current_user, :admin_personal_snippet, @snippet)
+ return render_404 unless can?(current_user, :admin_snippet, @snippet)
end
def authorize_create_snippet!
- return render_404 unless can?(current_user, :create_personal_snippet)
+ return render_404 unless can?(current_user, :create_snippet)
end
def snippet_params
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 67d33648470..0b092d2622b 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -41,6 +41,8 @@ class UploadsController < ApplicationController
case model
when Note
can?(current_user, :read_project, model.project)
+ when Snippet, ProjectSnippet
+ can?(current_user, :read_snippet, model)
when User
# We validate the current user has enough (writing)
# access to itself when a secret is given.