summaryrefslogtreecommitdiff
path: root/app/controllers/concerns
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/concerns')
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb4
-rw-r--r--app/controllers/concerns/confirm_email_warning.rb25
-rw-r--r--app/controllers/concerns/group_tree.rb20
-rw-r--r--app/controllers/concerns/invisible_captcha.rb51
-rw-r--r--app/controllers/concerns/issuable_actions.rb25
-rw-r--r--app/controllers/concerns/issuable_collections.rb61
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb2
-rw-r--r--app/controllers/concerns/notes_actions.rb7
-rw-r--r--app/controllers/concerns/requires_whitelisted_monitoring_client.rb2
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb2
-rw-r--r--app/controllers/concerns/sorting_preference.rb85
-rw-r--r--app/controllers/concerns/toggle_award_emoji.rb19
-rw-r--r--app/controllers/concerns/uploads_actions.rb2
-rw-r--r--app/controllers/concerns/with_performance_bar.rb4
14 files changed, 205 insertions, 104 deletions
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 4926062f9ca..8c8f0b3a22e 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -55,7 +55,7 @@ module AuthenticatesWithTwoFactor
remember_me(user) if user_params[:remember_me] == '1'
user.save!
- sign_in(user, message: :two_factor_authenticated)
+ sign_in(user, message: :two_factor_authenticated, event: :authentication)
else
user.increment_failed_attempts!
Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=OTP")
@@ -72,7 +72,7 @@ module AuthenticatesWithTwoFactor
session.delete(:challenge)
remember_me(user) if user_params[:remember_me] == '1'
- sign_in(user, message: :two_factor_authenticated)
+ sign_in(user, message: :two_factor_authenticated, event: :authentication)
else
user.increment_failed_attempts!
Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=U2F")
diff --git a/app/controllers/concerns/confirm_email_warning.rb b/app/controllers/concerns/confirm_email_warning.rb
new file mode 100644
index 00000000000..5a4b5897a4f
--- /dev/null
+++ b/app/controllers/concerns/confirm_email_warning.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module ConfirmEmailWarning
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :set_confirm_warning, if: -> { Feature.enabled?(:soft_email_confirmation) }
+ end
+
+ protected
+
+ def set_confirm_warning
+ return unless current_user
+ return if current_user.confirmed?
+ return if peek_request? || json_request? || !request.get?
+
+ email = current_user.unconfirmed_email || current_user.email
+
+ flash.now[:warning] = _("Please check your email (%{email}) to verify that you own this address. Didn't receive it? %{resend_link}. Wrong email address? %{update_link}.").html_safe % {
+ email: email,
+ resend_link: view_context.link_to(_('Resend it'), user_confirmation_path(user: { email: email }), method: :post),
+ update_link: view_context.link_to(_('Update it'), profile_path)
+ }
+ end
+end
diff --git a/app/controllers/concerns/group_tree.rb b/app/controllers/concerns/group_tree.rb
index e9a7d6a3152..d076c62c707 100644
--- a/app/controllers/concerns/group_tree.rb
+++ b/app/controllers/concerns/group_tree.rb
@@ -32,18 +32,14 @@ module GroupTree
def filtered_groups_with_ancestors(groups)
filtered_groups = groups.search(params[:filter]).page(params[:page])
- if Group.supports_nested_objects?
- # We find the ancestors by ID of the search results here.
- # Otherwise the ancestors would also have filters applied,
- # which would cause them not to be preloaded.
- #
- # Pagination needs to be applied before loading the ancestors to
- # make sure ancestors are not cut off by pagination.
- Gitlab::ObjectHierarchy.new(Group.where(id: filtered_groups.select(:id)))
- .base_and_ancestors
- else
- filtered_groups
- end
+ # We find the ancestors by ID of the search results here.
+ # Otherwise the ancestors would also have filters applied,
+ # which would cause them not to be preloaded.
+ #
+ # Pagination needs to be applied before loading the ancestors to
+ # make sure ancestors are not cut off by pagination.
+ Gitlab::ObjectHierarchy.new(Group.where(id: filtered_groups.select(:id)))
+ .base_and_ancestors
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/controllers/concerns/invisible_captcha.rb b/app/controllers/concerns/invisible_captcha.rb
new file mode 100644
index 00000000000..45c0a5c58ef
--- /dev/null
+++ b/app/controllers/concerns/invisible_captcha.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module InvisibleCaptcha
+ extend ActiveSupport::Concern
+
+ included do
+ invisible_captcha only: :create, on_spam: :on_honeypot_spam_callback, on_timestamp_spam: :on_timestamp_spam_callback
+ end
+
+ def on_honeypot_spam_callback
+ return unless Feature.enabled?(:invisible_captcha)
+
+ invisible_captcha_honeypot_counter.increment
+ log_request('Invisible_Captcha_Honeypot_Request')
+
+ head(200)
+ end
+
+ def on_timestamp_spam_callback
+ return unless Feature.enabled?(:invisible_captcha)
+
+ invisible_captcha_timestamp_counter.increment
+ log_request('Invisible_Captcha_Timestamp_Request')
+
+ redirect_to new_user_session_path, alert: InvisibleCaptcha.timestamp_error_message
+ end
+
+ def invisible_captcha_honeypot_counter
+ @invisible_captcha_honeypot_counter ||=
+ Gitlab::Metrics.counter(:bot_blocked_by_invisible_captcha_honeypot,
+ 'Counter of blocked sign up attempts with filled honeypot')
+ end
+
+ def invisible_captcha_timestamp_counter
+ @invisible_captcha_timestamp_counter ||=
+ Gitlab::Metrics.counter(:bot_blocked_by_invisible_captcha_timestamp,
+ 'Counter of blocked sign up attempts with invalid timestamp')
+ end
+
+ def log_request(message)
+ request_information = {
+ message: message,
+ env: :invisible_captcha_signup_bot_detected,
+ remote_ip: request.ip,
+ request_method: request.request_method,
+ path: request.fullpath
+ }
+
+ Gitlab::AuthLogger.error(request_information)
+ end
+end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 6fa2f75be33..b86e4451a7e 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -98,13 +98,12 @@ module IssuableActions
render json: { notice: "#{quantity} #{resource_name.pluralize(quantity)} updated" }
end
- # rubocop: disable CodeReuse/ActiveRecord
+ # rubocop:disable CodeReuse/ActiveRecord
def discussions
- notes = issuable.discussion_notes
- .inc_relations_for_view
- .with_notes_filter(notes_filter)
- .includes(:noteable)
- .fresh
+ notes = NotesFinder.new(current_user, finder_params_for_issuable).execute
+ .inc_relations_for_view
+ .includes(:noteable)
+ .fresh
if notes_filter != UserPreference::NOTES_FILTERS[:only_comments]
notes = ResourceEvents::MergeIntoNotesService.new(issuable, current_user).execute(notes)
@@ -117,7 +116,7 @@ module IssuableActions
render json: discussion_serializer.represent(discussions, context: self)
end
- # rubocop: enable CodeReuse/ActiveRecord
+ # rubocop:enable CodeReuse/ActiveRecord
private
@@ -128,7 +127,8 @@ module IssuableActions
# GitLab Geo does not expect database UPDATE or INSERT statements to happen
# on GET requests.
# This is just a fail-safe in case notes_filter is sent via GET request in GitLab Geo.
- if Gitlab::Database.read_only?
+ # In some cases, we also force the filter to not be persisted with the `persist_filter` param
+ if Gitlab::Database.read_only? || params[:persist_filter] == 'false'
notes_filter_param || current_user&.notes_filter_for(issuable)
else
notes_filter = current_user&.set_notes_filter(notes_filter_param, issuable) || notes_filter_param
@@ -222,4 +222,13 @@ module IssuableActions
def parent
@project || @group # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def finder_params_for_issuable
+ {
+ target: @issuable,
+ notes_filter: notes_filter
+ }.tap { |new_params| new_params[:project] = project if respond_to?(:project, true) }
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
end
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 21b3949e361..8ea77b994de 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -2,8 +2,8 @@
module IssuableCollections
extend ActiveSupport::Concern
- include CookiesHelper
include SortingHelper
+ include SortingPreference
include Gitlab::IssuableMetadata
include Gitlab::Utils::StrongMemoize
@@ -127,47 +127,8 @@ module IssuableCollections
'opened'
end
- def set_sort_order
- set_sort_order_from_user_preference || set_sort_order_from_cookie || default_sort_order
- end
-
- def set_sort_order_from_user_preference
- return unless current_user
- return unless issuable_sorting_field
-
- user_preference = current_user.user_preference
-
- sort_param = params[:sort]
- sort_param ||= user_preference[issuable_sorting_field]
-
- return sort_param if Gitlab::Database.read_only?
-
- if user_preference[issuable_sorting_field] != sort_param
- user_preference.update(issuable_sorting_field => sort_param)
- end
-
- sort_param
- end
-
- # Implement issuable_sorting_field method on controllers
- # to choose which column to store the sorting parameter.
- def issuable_sorting_field
- nil
- end
-
- def set_sort_order_from_cookie
- sort_param = params[:sort] if params[:sort].present?
- # fallback to legacy cookie value for backward compatibility
- sort_param ||= cookies['issuable_sort']
- sort_param ||= cookies[remember_sorting_key]
-
- sort_value = update_cookie_value(sort_param)
- set_secure_cookie(remember_sorting_key, sort_value)
- sort_value
- end
-
- def remember_sorting_key
- @remember_sorting_key ||= "#{collection_type.downcase}_sort"
+ def legacy_sort_cookie_name
+ 'issuable_sort'
end
def default_sort_order
@@ -178,26 +139,14 @@ module IssuableCollections
end
end
- # Update old values to the actual ones.
- def update_cookie_value(value)
- case value
- when 'id_asc' then sort_value_oldest_created
- when 'id_desc' then sort_value_recently_created
- when 'downvotes_asc' then sort_value_popularity
- when 'downvotes_desc' then sort_value_popularity
- else value
- end
- end
-
def finder
@finder ||= issuable_finder_for(finder_type)
end
def collection_type
- @collection_type ||= case finder_type.name
- when 'IssuesFinder'
+ @collection_type ||= if finder_type <= IssuesFinder
'Issue'
- when 'MergeRequestsFinder'
+ elsif finder_type <= MergeRequestsFinder
'MergeRequest'
end
end
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index 4ad287c4a13..0a6f684a9fc 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -32,7 +32,7 @@ module IssuableCollectionsAction
private
- def issuable_sorting_field
+ def sorting_field
case action_name
when 'issues'
Issue::SORTING_PREFERENCE_FIELD
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index 0098c4cdf4c..4b7899d469b 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -73,6 +73,11 @@ module NotesActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def update
@note = Notes::UpdateService.new(project, current_user, update_note_params).execute(note)
+ unless @note
+ head :gone
+ return
+ end
+
prepare_notes_for_rendering([@note])
respond_to do |format|
@@ -243,7 +248,7 @@ module NotesActions
end
def notes_finder
- @notes_finder ||= NotesFinder.new(project, current_user, finder_params)
+ @notes_finder ||= NotesFinder.new(current_user, finder_params)
end
def note_serializer
diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
index f47ead2f0da..2e9905997db 100644
--- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
+++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
@@ -28,7 +28,7 @@ module RequiresWhitelistedMonitoringClient
def valid_token?
token = params[:token].presence || request.headers['TOKEN']
token.present? &&
- ActiveSupport::SecurityUtils.variable_size_secure_compare(
+ ActiveSupport::SecurityUtils.secure_compare(
token,
Gitlab::CurrentSettings.health_check_access_token
)
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index 590eefc6dab..4304b8565ce 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -13,7 +13,7 @@ module SessionlessAuthentication
end
def sessionless_user?
- current_user && !session.keys.include?('warden.user.user.key')
+ current_user && !session.key?('warden.user.user.key')
end
def sessionless_sign_in(user)
diff --git a/app/controllers/concerns/sorting_preference.rb b/app/controllers/concerns/sorting_preference.rb
new file mode 100644
index 00000000000..a51b68147d5
--- /dev/null
+++ b/app/controllers/concerns/sorting_preference.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module SortingPreference
+ include SortingHelper
+ include CookiesHelper
+
+ def set_sort_order
+ set_sort_order_from_user_preference || set_sort_order_from_cookie || params[:sort] || default_sort_order
+ end
+
+ # Implement sorting_field method on controllers
+ # to choose which column to store the sorting parameter.
+ def sorting_field
+ nil
+ end
+
+ # Implement default_sort_order method on controllers
+ # to choose which default sort should be applied if
+ # sort param is not provided.
+ def default_sort_order
+ nil
+ end
+
+ # Implement legacy_sort_cookie_name method on controllers
+ # to set sort from cookie for backwards compatibility.
+ def legacy_sort_cookie_name
+ nil
+ end
+
+ private
+
+ def set_sort_order_from_user_preference
+ return unless current_user
+ return unless sorting_field
+
+ user_preference = current_user.user_preference
+
+ sort_param = params[:sort]
+ sort_param ||= user_preference[sorting_field]
+
+ return sort_param if Gitlab::Database.read_only?
+
+ if user_preference[sorting_field] != sort_param
+ user_preference.update(sorting_field => sort_param)
+ end
+
+ sort_param
+ end
+
+ def set_sort_order_from_cookie
+ return unless legacy_sort_cookie_name
+
+ sort_param = params[:sort] if params[:sort].present?
+ # fallback to legacy cookie value for backward compatibility
+ sort_param ||= cookies[legacy_sort_cookie_name]
+ sort_param ||= cookies[remember_sorting_key]
+
+ sort_value = update_cookie_value(sort_param)
+ set_secure_cookie(remember_sorting_key, sort_value)
+ sort_value
+ end
+
+ # Convert sorting_field to legacy cookie name for backwards compatibility
+ # :merge_requests_sort => 'mergerequest_sort'
+ # :issues_sort => 'issue_sort'
+ def remember_sorting_key
+ @remember_sorting_key ||= sorting_field
+ .to_s
+ .split('_')[0..-2]
+ .map(&:singularize)
+ .join('')
+ .concat('_sort')
+ end
+
+ # Update old values to the actual ones.
+ def update_cookie_value(value)
+ case value
+ when 'id_asc' then sort_value_oldest_created
+ when 'id_desc' then sort_value_recently_created
+ when 'downvotes_asc' then sort_value_popularity
+ when 'downvotes_desc' then sort_value_popularity
+ else value
+ end
+ end
+end
diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb
index 97b343f8b1a..24d178781d6 100644
--- a/app/controllers/concerns/toggle_award_emoji.rb
+++ b/app/controllers/concerns/toggle_award_emoji.rb
@@ -7,12 +7,9 @@ module ToggleAwardEmoji
authenticate_user!
name = params.require(:name)
- if awardable.user_can_award?(current_user)
- awardable.toggle_award_emoji(name, current_user)
-
- todoable = to_todoable(awardable)
- TodoService.new.new_award_emoji(todoable, current_user) if todoable
+ service = AwardEmojis::ToggleService.new(awardable, name, current_user).execute
+ if service[:status] == :success
render json: { ok: true }
else
render json: { ok: false }
@@ -21,18 +18,6 @@ module ToggleAwardEmoji
private
- def to_todoable(awardable)
- case awardable
- when Note
- # we don't create todos for personal snippet comments for now
- awardable.for_personal_snippet? ? nil : awardable.noteable
- when MergeRequest, Issue
- awardable
- when Snippet
- nil
- end
- end
-
def awardable
raise NotImplementedError
end
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index 59f6d3452a3..f5d35379e10 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -90,7 +90,7 @@ module UploadsActions
return unless uploader = build_uploader
upload_paths = uploader.upload_paths(params[:filename])
- upload = Upload.find_by(uploader: uploader_class.to_s, path: upload_paths)
+ upload = Upload.find_by(model: model, uploader: uploader_class.to_s, path: upload_paths)
upload&.build_uploader
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb
index 77c3d476ac6..4e0ae3c59eb 100644
--- a/app/controllers/concerns/with_performance_bar.rb
+++ b/app/controllers/concerns/with_performance_bar.rb
@@ -3,10 +3,6 @@
module WithPerformanceBar
extend ActiveSupport::Concern
- included do
- include Peek::Rblineprof::CustomControllerHelpers
- end
-
def peek_enabled?
return false unless Gitlab::PerformanceBar.enabled?(current_user)