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:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/controllers/admin/cohorts_controller.rb14
-rw-r--r--app/controllers/admin/users_controller.rb21
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/autocomplete_controller.rb2
-rw-r--r--app/controllers/chaos_controller.rb9
-rw-r--r--app/controllers/concerns/boards_actions.rb14
-rw-r--r--app/controllers/concerns/boards_responses.rb6
-rw-r--r--app/controllers/concerns/comment_and_close_flag.rb11
-rw-r--r--app/controllers/concerns/integrations_actions.rb4
-rw-r--r--app/controllers/concerns/membership_actions.rb24
-rw-r--r--app/controllers/concerns/multiple_boards_actions.rb1
-rw-r--r--app/controllers/concerns/notes_actions.rb9
-rw-r--r--app/controllers/concerns/redis_tracking.rb16
-rw-r--r--app/controllers/concerns/service_params.rb1
-rw-r--r--app/controllers/concerns/snippets_actions.rb2
-rw-r--r--app/controllers/concerns/spammable_actions.rb57
-rw-r--r--app/controllers/concerns/wiki_actions.rb3
-rw-r--r--app/controllers/dashboard_controller.rb19
-rw-r--r--app/controllers/graphql_controller.rb5
-rw-r--r--app/controllers/groups/boards_controller.rb27
-rw-r--r--app/controllers/groups/email_campaigns_controller.rb61
-rw-r--r--app/controllers/groups/settings/packages_and_registries_controller.rb7
-rw-r--r--app/controllers/groups_controller.rb5
-rw-r--r--app/controllers/help_controller.rb11
-rw-r--r--app/controllers/import/bulk_imports_controller.rb27
-rw-r--r--app/controllers/invites_controller.rb16
-rw-r--r--app/controllers/jira_connect/users_controller.rb2
-rw-r--r--app/controllers/profiles/notifications_controller.rb2
-rw-r--r--app/controllers/profiles/preferences_controller.rb25
-rw-r--r--app/controllers/projects/badges_controller.rb4
-rw-r--r--app/controllers/projects/blob_controller.rb2
-rw-r--r--app/controllers/projects/boards_controller.rb22
-rw-r--r--app/controllers/projects/branches_controller.rb6
-rw-r--r--app/controllers/projects/ci/daily_build_group_report_results_controller.rb20
-rw-r--r--app/controllers/projects/ci/pipeline_editor_controller.rb1
-rw-r--r--app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb25
-rw-r--r--app/controllers/projects/commit_controller.rb4
-rw-r--r--app/controllers/projects/discussions_controller.rb2
-rw-r--r--app/controllers/projects/forks_controller.rb8
-rw-r--r--app/controllers/projects/issues_controller.rb15
-rw-r--r--app/controllers/projects/jobs_controller.rb3
-rw-r--r--app/controllers/projects/learn_gitlab_controller.rb19
-rw-r--r--app/controllers/projects/merge_requests/application_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb5
-rw-r--r--app/controllers/projects/merge_requests_controller.rb35
-rw-r--r--app/controllers/projects/notes_controller.rb17
-rw-r--r--app/controllers/projects/pipelines/tests_controller.rb6
-rw-r--r--app/controllers/projects/pipelines_controller.rb29
-rw-r--r--app/controllers/projects/project_members_controller.rb4
-rw-r--r--app/controllers/projects/security/configuration_controller.rb23
-rw-r--r--app/controllers/projects/services_controller.rb2
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb4
-rw-r--r--app/controllers/projects/settings/repository_controller.rb1
-rw-r--r--app/controllers/projects/templates_controller.rb4
-rw-r--r--app/controllers/projects_controller.rb38
-rw-r--r--app/controllers/registrations/experience_levels_controller.rb10
-rw-r--r--app/controllers/registrations/welcome_controller.rb19
-rw-r--r--app/controllers/registrations_controller.rb6
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/controllers/search_controller.rb7
-rw-r--r--app/controllers/snippets/notes_controller.rb2
-rw-r--r--app/controllers/users_controller.rb53
-rw-r--r--app/controllers/whats_new_controller.rb11
65 files changed, 571 insertions, 247 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 179e6ef60fb..7f7d38a09c5 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -238,11 +238,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
*::ApplicationSettingsHelper.visible_attributes,
*::ApplicationSettingsHelper.external_authorization_service_attributes,
*ApplicationSetting.repository_storages_weighted_attributes,
+ *ApplicationSetting.kroki_formats_attributes.keys.map { |key| "kroki_formats_#{key}".to_sym },
:lets_encrypt_notification_email,
:lets_encrypt_terms_of_service_accepted,
:domain_denylist_file,
:raw_blob_request_limit,
:issues_create_limit,
+ :notes_create_limit,
:default_branch_name,
disabled_oauth_sign_in_sources: [],
import_sources: [],
diff --git a/app/controllers/admin/cohorts_controller.rb b/app/controllers/admin/cohorts_controller.rb
index a26dc554506..9bb73c822b0 100644
--- a/app/controllers/admin/cohorts_controller.rb
+++ b/app/controllers/admin/cohorts_controller.rb
@@ -1,19 +1,11 @@
# frozen_string_literal: true
class Admin::CohortsController < Admin::ApplicationController
- include Analytics::UniqueVisitsHelper
-
- track_unique_visits :index, target_id: 'i_analytics_cohorts'
-
feature_category :devops_reports
+ # Backwards compatibility. Remove it and routing in 14.0
+ # @see https://gitlab.com/gitlab-org/gitlab/-/issues/299303
def index
- if Gitlab::CurrentSettings.usage_ping_enabled
- cohorts_results = Rails.cache.fetch('cohorts', expires_in: 1.day) do
- CohortsService.new.execute
- end
-
- @cohorts = CohortsSerializer.new.represent(cohorts_results)
- end
+ redirect_to admin_users_path(tab: 'cohorts')
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 3fe972d1917..d0761083c8b 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -2,6 +2,7 @@
class Admin::UsersController < Admin::ApplicationController
include RoutableActions
+ include Analytics::UniqueVisitsHelper
before_action :user, except: [:index, :new, :create]
before_action :check_impersonation_availability, only: :impersonate
@@ -15,6 +16,10 @@ class Admin::UsersController < Admin::ApplicationController
@users = @users.includes(:authorized_projects) # rubocop: disable CodeReuse/ActiveRecord
@users = @users.sort_by_attribute(@sort = params[:sort])
@users = @users.page(params[:page])
+
+ @cohorts = load_cohorts
+
+ track_cohorts_visit if params[:tab] == 'cohorts'
end
def show
@@ -307,6 +312,22 @@ class Admin::UsersController < Admin::ApplicationController
def log_impersonation_event
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username })
end
+
+ def load_cohorts
+ if Gitlab::CurrentSettings.usage_ping_enabled
+ cohorts_results = Rails.cache.fetch('cohorts', expires_in: 1.day) do
+ CohortsService.new.execute
+ end
+
+ CohortsSerializer.new.represent(cohorts_results)
+ end
+ end
+
+ def track_cohorts_visit
+ if request.format.html? && request.headers['DNT'] != '1'
+ track_visit('i_analytics_cohorts')
+ end
+ end
end
Admin::UsersController.prepend_if_ee('EE::Admin::UsersController')
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 3cb7373a970..5f14d95ffed 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -556,4 +556,4 @@ class ApplicationController < ActionController::Base
end
end
-ApplicationController.prepend_if_ee('EE::ApplicationController')
+ApplicationController.prepend_ee_mod
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index 9ee69c7c07f..79e45bcf929 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -18,7 +18,7 @@ class AutocompleteController < ApplicationController
.new(params: params, current_user: current_user, project: project, group: group)
.execute
- render json: UserSerializer.new(params).represent(users, project: project)
+ render json: UserSerializer.new(params.merge({ current_user: current_user })).represent(users, project: project)
end
def user
diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb
index e0d1f313fc7..0ec6a2cb38a 100644
--- a/app/controllers/chaos_controller.rb
+++ b/app/controllers/chaos_controller.rb
@@ -23,6 +23,15 @@ class ChaosController < ActionController::Base
do_chaos :kill, Chaos::KillWorker
end
+ def gc
+ gc_stat = Gitlab::Chaos.run_gc
+
+ render json: {
+ worker_id: Prometheus::PidProvider.worker_id,
+ gc_stat: gc_stat
+ }
+ end
+
private
def do_chaos(method, worker, *args)
diff --git a/app/controllers/concerns/boards_actions.rb b/app/controllers/concerns/boards_actions.rb
index b382e338a78..79e6f027c2f 100644
--- a/app/controllers/concerns/boards_actions.rb
+++ b/app/controllers/concerns/boards_actions.rb
@@ -34,16 +34,26 @@ module BoardsActions
def boards
strong_memoize(:boards) do
- Boards::ListService.new(parent, current_user).execute
+ existing_boards = boards_finder.execute
+ if existing_boards.any?
+ existing_boards
+ else
+ # if no board exists, create one
+ [board_create_service.execute.payload]
+ end
end
end
def board
strong_memoize(:board) do
- boards.find(params[:id])
+ board_finder.execute.first
end
end
+ def board_type
+ board_klass.to_type
+ end
+
def serializer
BoardSerializer.new(current_user: current_user)
end
diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb
index d8bc1320db4..6e6686f225c 100644
--- a/app/controllers/concerns/boards_responses.rb
+++ b/app/controllers/concerns/boards_responses.rb
@@ -66,7 +66,11 @@ module BoardsResponses
end
def respond_with_board
- respond_with(@board) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ return render_404 unless @board
+
+ respond_with(@board)
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
end
def serialize_as_json(resource)
diff --git a/app/controllers/concerns/comment_and_close_flag.rb b/app/controllers/concerns/comment_and_close_flag.rb
new file mode 100644
index 00000000000..e2f3272abbc
--- /dev/null
+++ b/app/controllers/concerns/comment_and_close_flag.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module CommentAndCloseFlag
+ extend ActiveSupport::Concern
+
+ included do
+ before_action do
+ push_frontend_feature_flag(:remove_comment_close_reopen, @group)
+ end
+ end
+end
diff --git a/app/controllers/concerns/integrations_actions.rb b/app/controllers/concerns/integrations_actions.rb
index baebedb8e5d..a3ea39d9c3d 100644
--- a/app/controllers/concerns/integrations_actions.rb
+++ b/app/controllers/concerns/integrations_actions.rb
@@ -34,10 +34,6 @@ module IntegrationsActions
end
end
- def custom_integration_projects
- Project.with_custom_integration_compared_to(integration).page(params[:page]).per(20)
- end
-
def test
render json: {}, status: :ok
end
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 816a93f14c6..9e3625d1b36 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -18,18 +18,26 @@ module MembershipActions
def update
update_params = params.require(root_params_key).permit(:access_level, :expires_at)
member = membershipable.members_and_requesters.find(params[:id])
- member = Members::UpdateService
+ result = Members::UpdateService
.new(current_user, update_params)
.execute(member)
- if member.expires?
- render json: {
- expires_in: helpers.distance_of_time_in_words_to_now(member.expires_at),
- expires_soon: member.expires_soon?,
- expires_at_formatted: member.expires_at.to_time.in_time_zone.to_s(:medium)
- }
+ member = result[:member]
+
+ member_data = if member.expires?
+ {
+ expires_in: helpers.distance_of_time_in_words_to_now(member.expires_at),
+ expires_soon: member.expires_soon?,
+ expires_at_formatted: member.expires_at.to_time.in_time_zone.to_s(:medium)
+ }
+ else
+ {}
+ end
+
+ if result[:status] == :success
+ render json: member_data
else
- render json: {}
+ render json: { message: result[:message] }, status: :unprocessable_entity
end
end
diff --git a/app/controllers/concerns/multiple_boards_actions.rb b/app/controllers/concerns/multiple_boards_actions.rb
index 370b8c72bfe..5206f5759d8 100644
--- a/app/controllers/concerns/multiple_boards_actions.rb
+++ b/app/controllers/concerns/multiple_boards_actions.rb
@@ -65,6 +65,7 @@ module MultipleBoardsActions
private
def redirect_to_recent_board
+ return unless board_type == Board.to_type
return if request.format.json? || !parent.multiple_issue_boards_available? || !latest_visited_board
redirect_to board_path(latest_visited_board.board)
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index bfa7a30bc65..036d95622ef 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -31,9 +31,9 @@ module NotesActions
# We know there's more data, so tell the frontend to poll again after 1ms
set_polling_interval_header(interval: 1) if meta[:more]
- # Only present an ETag for the empty response to ensure pagination works
- # as expected
- ::Gitlab::EtagCaching::Middleware.skip!(response) if notes.present?
+ # We might still want to investigate further adjusting ETag caching with paginated notes, but
+ # let's avoid ETag caching for now until we confirm the viability of paginated notes.
+ ::Gitlab::EtagCaching::Middleware.skip!(response)
render json: meta.merge(notes: notes)
end
@@ -243,7 +243,8 @@ module NotesActions
:type,
:note,
:line_code, # LegacyDiffNote
- :position # DiffNote
+ :position, # DiffNote
+ :confidential
).tap do |create_params|
create_params.merge!(
params.permit(:merge_request_diff_head_sha, :in_reply_to_discussion_id)
diff --git a/app/controllers/concerns/redis_tracking.rb b/app/controllers/concerns/redis_tracking.rb
index d71935356b8..a7e75f802a8 100644
--- a/app/controllers/concerns/redis_tracking.rb
+++ b/app/controllers/concerns/redis_tracking.rb
@@ -7,30 +7,26 @@
#
# include RedisTracking
#
-# track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score', feature: :my_feature
-#
-# if the feature flag is enabled by default you should use
-# track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score', feature: :my_feature, feature_default_enabled: true
+# track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score'
#
# You can also pass custom conditions using `if:`, using the same format as with Rails callbacks.
module RedisTracking
extend ActiveSupport::Concern
class_methods do
- def track_redis_hll_event(*controller_actions, name:, feature:, feature_default_enabled: false, if: nil)
+ def track_redis_hll_event(*controller_actions, name:, if: nil)
custom_conditions = Array.wrap(binding.local_variable_get('if'))
conditions = [:trackable_request?, *custom_conditions]
after_action only: controller_actions, if: conditions do
- track_unique_redis_hll_event(name, feature, feature_default_enabled)
+ track_unique_redis_hll_event(name)
end
end
end
private
- def track_unique_redis_hll_event(event_name, feature, feature_default_enabled)
- return unless metric_feature_enabled?(feature, feature_default_enabled)
+ def track_unique_redis_hll_event(event_name)
return unless visitor_id
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: visitor_id)
@@ -40,10 +36,6 @@ module RedisTracking
request.format.html? && request.headers['DNT'] != '1'
end
- def metric_feature_enabled?(feature, default_enabled)
- Feature.enabled?(feature, default_enabled: default_enabled)
- end
-
def visitor_id
return cookies[:visitor_id] if cookies[:visitor_id].present?
return unless current_user
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index c295290a123..3cab198c1f9 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -12,6 +12,7 @@ module ServiceParams
:api_version,
:bamboo_url,
:branches_to_be_notified,
+ :labels_to_be_notified,
:build_key,
:build_type,
:ca_pem,
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index c93e75b438b..0ee8d0c9307 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -15,7 +15,7 @@ module SnippetsActions
skip_before_action :verify_authenticity_token,
if: -> { action_name == 'show' && js_request? }
- track_redis_hll_event :show, name: 'i_snippets_show', feature: :usage_data_i_snippets_show, feature_default_enabled: true
+ track_redis_hll_event :show, name: 'i_snippets_show'
respond_to :html
end
diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb
index 4ec561014a8..b285faee9bc 100644
--- a/app/controllers/concerns/spammable_actions.rb
+++ b/app/controllers/concerns/spammable_actions.rb
@@ -3,9 +3,6 @@
module SpammableActions
extend ActiveSupport::Concern
- include Recaptcha::Verify
- include Gitlab::Utils::StrongMemoize
-
included do
before_action :authorize_submit_spammable!, only: :mark_as_spam
end
@@ -20,17 +17,11 @@ module SpammableActions
private
- def ensure_spam_config_loaded!
- strong_memoize(:spam_config_loaded) do
- Gitlab::Recaptcha.load_configurations!
- end
- end
-
def recaptcha_check_with_fallback(should_redirect = true, &fallback)
if should_redirect && spammable.valid?
redirect_to spammable_path
- elsif render_recaptcha?
- ensure_spam_config_loaded!
+ elsif spammable.render_recaptcha?
+ Gitlab::Recaptcha.load_configurations!
respond_to do |format|
format.html do
@@ -50,33 +41,30 @@ module SpammableActions
end
def spammable_params
- default_params = { request: request }
-
- recaptcha_check = recaptcha_response &&
- ensure_spam_config_loaded! &&
- verify_recaptcha(response: recaptcha_response)
-
- return default_params unless recaptcha_check
-
- { recaptcha_verified: true,
- spam_log_id: params[:spam_log_id] }.merge(default_params)
- end
-
- def recaptcha_response
- # NOTE: This field name comes from `Recaptcha::ClientHelper#recaptcha_tags` in the recaptcha
- # gem, which is called from the HAML `_recaptcha_form.html.haml` form.
+ # NOTE: For the legacy reCAPTCHA implementation based on the HTML/HAML form, the
+ # 'g-recaptcha-response' field name comes from `Recaptcha::ClientHelper#recaptcha_tags` in the
+ # recaptcha gem, which is called from the HAML `_recaptcha_form.html.haml` form.
#
- # It is used in the `Recaptcha::Verify#verify_recaptcha` if the `response` option is not
- # passed explicitly.
+ # It is used in the `Recaptcha::Verify#verify_recaptcha` to extract the value from `params`,
+ # if the `response` option is not passed explicitly.
#
# Instead of relying on this behavior, we are extracting and passing it explicitly. This will
# make it consistent with the newer, modern reCAPTCHA verification process as it will be
# implemented via the GraphQL API and in Vue components via the native reCAPTCHA Javascript API,
# which requires that the recaptcha response param be obtained and passed explicitly.
#
- # After this newer GraphQL/JS API process is fully supported by the backend, we can remove this
- # (and other) HAML-specific support.
- params['g-recaptcha-response']
+ # It can also be expanded to multiple fields when we move to future alternative captcha
+ # implementations such as FriendlyCaptcha. See https://gitlab.com/gitlab-org/gitlab/-/issues/273480
+
+ # After this newer GraphQL/JS API process is fully supported by the backend, we can remove the
+ # check for the 'g-recaptcha-response' field and other HTML/HAML form-specific support.
+ captcha_response = params['g-recaptcha-response']
+
+ {
+ request: request,
+ spam_log_id: params[:spam_log_id],
+ captcha_response: captcha_response
+ }
end
def spammable
@@ -90,11 +78,4 @@ module SpammableActions
def authorize_submit_spammable!
access_denied! unless current_user.admin?
end
-
- def render_recaptcha?
- return false if spammable.errors.count > 1 # re-render "new" template in case there are other errors
- return false unless Gitlab::Recaptcha.enabled?
-
- spammable.needs_recaptcha?
- end
end
diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb
index 1ae90edd8f7..4014e4f0024 100644
--- a/app/controllers/concerns/wiki_actions.rb
+++ b/app/controllers/concerns/wiki_actions.rb
@@ -36,8 +36,7 @@ module WikiActions
# NOTE: We want to include wiki page views in the same counter as the other
# Event-based wiki actions tracked through TrackUniqueEvents, so we use the same event name.
- track_redis_hll_event :show, name: Gitlab::UsageDataCounters::TrackUniqueEvents::WIKI_ACTION.to_s,
- feature: :track_unique_wiki_page_views, feature_default_enabled: true
+ track_redis_hll_event :show, name: Gitlab::UsageDataCounters::TrackUniqueEvents::WIKI_ACTION.to_s
helper_method :view_file_button, :diff_file_html_data
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index a88cf64d842..29cb60ad3cc 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -33,6 +33,21 @@ class DashboardController < Dashboard::ApplicationController
protected
def load_events
+ @events =
+ if params[:filter] == "followed"
+ load_user_events
+ else
+ load_project_events
+ end
+
+ Events::RenderService.new(current_user).execute(@events)
+ end
+
+ def load_user_events
+ UserRecentEventsFinder.new(current_user, current_user.followees, event_filter, params).execute
+ end
+
+ def load_project_events
projects =
if params[:filter] == "starred"
ProjectsFinder.new(current_user: current_user, params: { starred: true }).execute
@@ -40,12 +55,10 @@ class DashboardController < Dashboard::ApplicationController
current_user.authorized_projects
end
- @events = EventCollection
+ EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a
.map(&:present)
-
- Events::RenderService.new(current_user).execute(@events)
end
def set_show_full_reference
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 1852405e7cf..152f07b4c16 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -20,6 +20,7 @@ class GraphqlController < ApplicationController
before_action :authorize_access_api!
before_action(only: [:execute]) { authenticate_sessionless_user!(:api) }
before_action :set_user_last_activity
+ before_action :track_vs_code_usage
# Since we deactivate authentication from the main ApplicationController and
# defer it to :authorize_access_api!, we need to override the bypass session
@@ -64,6 +65,10 @@ class GraphqlController < ApplicationController
Users::ActivityService.new(current_user).execute
end
+ def track_vs_code_usage
+ Gitlab::UsageDataCounters::VSCodeExtensionActivityUniqueCounter.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
+ end
+
def execute_multiplex
GitlabSchema.multiplex(multiplex_queries, context: context)
end
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index 093cdf258b2..fa109021b7d 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -3,6 +3,7 @@
class Groups::BoardsController < Groups::ApplicationController
include BoardsActions
include RecordUserLastActivity
+ include Gitlab::Utils::StrongMemoize
before_action :authorize_read_board!, only: [:index, :show]
before_action :assign_endpoint_vars
@@ -14,10 +15,32 @@ class Groups::BoardsController < Groups::ApplicationController
private
+ def board_klass
+ Board
+ end
+
+ def boards_finder
+ strong_memoize :boards_finder do
+ Boards::ListService.new(parent, current_user)
+ end
+ end
+
+ def board_finder
+ strong_memoize :board_finder do
+ Boards::ListService.new(parent, current_user, board_id: params[:id])
+ end
+ end
+
+ def board_create_service
+ strong_memoize :board_create_service do
+ Boards::CreateService.new(parent, current_user)
+ end
+ end
+
def assign_endpoint_vars
- @boards_endpoint = group_boards_url(group)
+ @boards_endpoint = group_boards_path(group)
@namespace_path = group.to_param
- @labels_endpoint = group_labels_url(group)
+ @labels_endpoint = group_labels_path(group)
end
def authorize_read_board!
diff --git a/app/controllers/groups/email_campaigns_controller.rb b/app/controllers/groups/email_campaigns_controller.rb
new file mode 100644
index 00000000000..cbb0176ea7b
--- /dev/null
+++ b/app/controllers/groups/email_campaigns_controller.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+class Groups::EmailCampaignsController < Groups::ApplicationController
+ include InProductMarketingHelper
+ include Gitlab::Tracking::ControllerConcern
+
+ EMAIL_CAMPAIGNS_SCHEMA_URL = 'iglu:com.gitlab/email_campaigns/jsonschema/1-0-0'
+
+ feature_category :navigation
+
+ before_action :check_params
+
+ def index
+ track_click
+ redirect_to redirect_link
+ end
+
+ private
+
+ def track_click
+ data = {
+ namespace_id: group.id,
+ track: @track,
+ series: @series,
+ subject_line: subject_line(@track, @series)
+ }
+
+ track_self_describing_event(EMAIL_CAMPAIGNS_SCHEMA_URL, data: data)
+ end
+
+ def redirect_link
+ case @track
+ when :create
+ create_track_url
+ when :verify
+ project_pipelines_url(group.projects.first)
+ when :trial
+ 'https://about.gitlab.com/free-trial/'
+ when :team
+ group_group_members_url(group)
+ end
+ end
+
+ def create_track_url
+ [
+ new_project_url,
+ new_project_url(anchor: 'import_project'),
+ help_page_url('user/project/repository/repository_mirroring')
+ ][@series]
+ end
+
+ def check_params
+ @track = params[:track]&.to_sym
+ @series = params[:series]&.to_i
+
+ track_valid = @track.in?(Namespaces::InProductMarketingEmailsService::TRACKS.keys)
+ series_valid = @series.in?(0..Namespaces::InProductMarketingEmailsService::INTERVAL_DAYS.size - 1)
+
+ render_404 unless track_valid && series_valid
+ end
+end
diff --git a/app/controllers/groups/settings/packages_and_registries_controller.rb b/app/controllers/groups/settings/packages_and_registries_controller.rb
index dbc1e68742b..0135c03026c 100644
--- a/app/controllers/groups/settings/packages_and_registries_controller.rb
+++ b/app/controllers/groups/settings/packages_and_registries_controller.rb
@@ -4,11 +4,18 @@ module Groups
module Settings
class PackagesAndRegistriesController < Groups::ApplicationController
before_action :authorize_admin_group!
+ before_action :verify_packages_enabled!
feature_category :package_registry
def index
end
+
+ private
+
+ def verify_packages_enabled!
+ render_404 unless group.packages_feature_enabled?
+ end
end
end
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 068815f7f07..9d7aebe4505 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -30,6 +30,7 @@ class GroupsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issuables_list, @group)
+ push_frontend_feature_flag(:vue_notification_dropdown, @group, default_enabled: :yaml)
end
before_action do
@@ -319,9 +320,7 @@ class GroupsController < Groups::ApplicationController
private
- def successful_creation_hooks
- track_experiment_event(:onboarding_issues, 'created_namespace')
- end
+ def successful_creation_hooks; end
def groups
if @group.supports_events?
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 5a5200452de..e995562f0c4 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -84,7 +84,16 @@ class HelpController < ApplicationController
end
def documentation_base_url
- @documentation_base_url ||= Gitlab::CurrentSettings.current_application_settings.help_page_documentation_base_url.presence
+ @documentation_base_url ||= documentation_base_url_from_yml_configuration || documentation_base_url_from_db
+ end
+
+ # DEPRECATED
+ def documentation_base_url_from_db
+ Gitlab::CurrentSettings.current_application_settings.help_page_documentation_base_url.presence
+ end
+
+ def documentation_base_url_from_yml_configuration
+ ::Gitlab.config.gitlab_docs.host.presence if ::Gitlab.config.gitlab_docs.enabled
end
def documentation_file_path
diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb
index 7394e8bf615..ef32ba4d119 100644
--- a/app/controllers/import/bulk_imports_controller.rb
+++ b/app/controllers/import/bulk_imports_controller.rb
@@ -22,7 +22,13 @@ class Import::BulkImportsController < ApplicationController
def status
respond_to do |format|
format.json do
- render json: { importable_data: serialized_importable_data }
+ data = importable_data
+
+ pagination_headers.each do |header|
+ response.set_header(header, data.headers[header])
+ end
+
+ render json: { importable_data: serialized_data(data.parsed_response) }
end
format.html do
@source_url = session[url_key]
@@ -31,9 +37,8 @@ class Import::BulkImportsController < ApplicationController
end
def create
- BulkImportService.new(current_user, create_params, credentials).execute
-
- render json: :ok
+ result = BulkImportService.new(current_user, create_params, credentials).execute
+ render json: result.to_json(only: [:id])
end
def realtime_changes
@@ -44,8 +49,12 @@ class Import::BulkImportsController < ApplicationController
private
- def serialized_importable_data
- serializer.represent(importable_data, {}, Import::BulkImportEntity)
+ def pagination_headers
+ %w[x-next-page x-page x-per-page x-prev-page x-total x-total-pages]
+ end
+
+ def serialized_data(data)
+ serializer.represent(data, {}, Import::BulkImportEntity)
end
def serializer
@@ -53,7 +62,7 @@ class Import::BulkImportsController < ApplicationController
end
def importable_data
- client.get('groups', query_params).parsed_response
+ client.get('groups', query_params)
end
# Default query string params used to fetch groups from GitLab source instance
@@ -74,7 +83,9 @@ class Import::BulkImportsController < ApplicationController
def client
@client ||= BulkImports::Clients::Http.new(
uri: session[url_key],
- token: session[access_token_key]
+ token: session[access_token_key],
+ per_page: params[:per_page],
+ page: params[:page]
)
end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index ad92645c23e..08a23dc8927 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -6,6 +6,7 @@ class InvitesController < ApplicationController
before_action :member
before_action :ensure_member_exists
before_action :invite_details
+ before_action :set_invite_type, only: :show
skip_before_action :authenticate_user!, only: :decline
helper_method :member?, :current_user_matches_invite?
@@ -15,11 +16,16 @@ class InvitesController < ApplicationController
feature_category :authentication_and_authorization
def show
+ experiment('members/invite_email', actor: member).track(:opened) if initial_invite_email?
+
accept if skip_invitation_prompt?
end
def accept
if member.accept_invite!(current_user)
+ experiment('members/invite_email', actor: member).track(:accepted) if initial_invite_email?
+ session.delete(:invite_type)
+
redirect_to invite_details[:path], notice: _("You have been granted %{member_human_access} access to %{title} %{name}.") %
{ member_human_access: member.human_access, title: invite_details[:title], name: invite_details[:name] }
else
@@ -29,7 +35,7 @@ class InvitesController < ApplicationController
def decline
if member.decline_invite!
- return render layout: 'devise_experimental_onboarding_issues' if !current_user && member.invite_to_unknown_user? && member.created_by
+ return render layout: 'signup_onboarding' if !current_user && member.invite_to_unknown_user? && member.created_by
path =
if current_user
@@ -47,6 +53,14 @@ class InvitesController < ApplicationController
private
+ def set_invite_type
+ session[:invite_type] = params[:invite_type] if params[:invite_type].in?([Members::InviteEmailExperiment::INVITE_TYPE])
+ end
+
+ def initial_invite_email?
+ session[:invite_type] == Members::InviteEmailExperiment::INVITE_TYPE
+ end
+
def skip_invitation_prompt?
!member? && current_user_matches_invite?
end
diff --git a/app/controllers/jira_connect/users_controller.rb b/app/controllers/jira_connect/users_controller.rb
index 571d9f87779..569dc42fed3 100644
--- a/app/controllers/jira_connect/users_controller.rb
+++ b/app/controllers/jira_connect/users_controller.rb
@@ -3,7 +3,7 @@
class JiraConnect::UsersController < ApplicationController
feature_category :integrations
- layout 'devise_experimental_onboarding_issues'
+ layout 'signup_onboarding'
def show
@jira_app_link = params.delete(:return_to)
diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb
index a3e7638cdbc..0a73239709a 100644
--- a/app/controllers/profiles/notifications_controller.rb
+++ b/app/controllers/profiles/notifications_controller.rb
@@ -29,7 +29,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
end
def user_params
- params.require(:user).permit(:notification_email, :notified_of_own_activity)
+ params.require(:user).permit(:notification_email, :email_opted_in, :notified_of_own_activity)
end
private
diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb
index 4d88491e9a8..add5046e213 100644
--- a/app/controllers/profiles/preferences_controller.rb
+++ b/app/controllers/profiles/preferences_controller.rb
@@ -9,23 +9,18 @@ class Profiles::PreferencesController < Profiles::ApplicationController
end
def update
- begin
- result = Users::UpdateService.new(current_user, preferences_params.merge(user: user)).execute
-
- if result[:status] == :success
- flash[:notice] = _('Preferences saved.')
- else
- flash[:alert] = _('Failed to save preferences.')
- end
- rescue ArgumentError => e
- # Raised when `dashboard` is given an invalid value.
- flash[:alert] = _("Failed to save preferences (%{error_message}).") % { error_message: e.message }
- end
+ result = Users::UpdateService.new(current_user, preferences_params.merge(user: user)).execute
+ if result[:status] == :success
+ message = _('Preferences saved.')
- respond_to do |format|
- format.html { redirect_to profile_preferences_path }
- format.js
+ render json: { type: :notice, message: message }
+ else
+ render status: :bad_request, json: { type: :alert, message: _('Failed to save preferences.') }
end
+ rescue ArgumentError => e
+ # Raised when `dashboard` is given an invalid value.
+ message = _("Failed to save preferences (%{error_message}).") % { error_message: e.message }
+ render status: :bad_request, json: { type: :alert, message: message }
end
private
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 855965ca6e1..f75ab5cdbf2 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -9,7 +9,7 @@ class Projects::BadgesController < Projects::ApplicationController
feature_category :continuous_integration
def pipeline
- pipeline_status = Gitlab::Badge::Pipeline::Status
+ pipeline_status = Gitlab::Ci::Badge::Pipeline::Status
.new(project, params[:ref], opts: {
ignore_skipped: params[:ignore_skipped],
key_text: params[:key_text],
@@ -20,7 +20,7 @@ class Projects::BadgesController < Projects::ApplicationController
end
def coverage
- coverage_report = Gitlab::Badge::Coverage::Report
+ coverage_report = Gitlab::Ci::Badge::Coverage::Report
.new(project, params[:ref], opts: {
job: params[:job],
key_text: params[:key_text],
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 8c66f45dd79..3bb00978aac 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -35,7 +35,7 @@ class Projects::BlobController < Projects::ApplicationController
record_experiment_user(:ci_syntax_templates, namespace_id: @project.namespace_id) if params[:file_name] == @project.ci_config_path_or_default
end
- track_redis_hll_event :create, :update, name: 'g_edit_by_sfe', feature: :track_editor_edit_actions, feature_default_enabled: true
+ track_redis_hll_event :create, :update, name: 'g_edit_by_sfe'
feature_category :source_code_management
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index 51c9bf3699a..d2e5d319f96 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -15,6 +15,28 @@ class Projects::BoardsController < Projects::ApplicationController
private
+ def board_klass
+ Board
+ end
+
+ def boards_finder
+ strong_memoize :boards_finder do
+ Boards::ListService.new(parent, current_user)
+ end
+ end
+
+ def board_finder
+ strong_memoize :board_finder do
+ Boards::ListService.new(parent, current_user, board_id: params[:id])
+ end
+ end
+
+ def board_create_service
+ strong_memoize :board_create_service do
+ Boards::CreateService.new(parent, current_user)
+ end
+ end
+
def assign_endpoint_vars
@boards_endpoint = project_boards_path(project)
@bulk_issues_path = bulk_update_project_issues_path(project)
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index a753d5705aa..6f3c96fa654 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -177,10 +177,8 @@ class Projects::BranchesController < Projects::ApplicationController
def fetch_branches_by_mode
return fetch_branches_for_overview if @mode == 'overview'
- # active/stale/all view mode
- @branches = BranchesFinder.new(@repository, params.merge(sort: @sort)).execute
- @branches = @branches.select { |b| b.state.to_s == @mode } if %w[active stale].include?(@mode)
- @branches = Kaminari.paginate_array(@branches).page(params[:page])
+ @branches, @prev_path, @next_path =
+ Projects::BranchesByModeService.new(@project, params.merge(sort: @sort, mode: @mode)).execute
end
def fetch_branches_for_overview
diff --git a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
index d05ab1b4977..aabcb74cefa 100644
--- a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
+++ b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
@@ -40,7 +40,25 @@ class Projects::Ci::DailyBuildGroupReportResultsController < Projects::Applicati
end
def report_results
- Ci::DailyBuildGroupReportResultsFinder.new(**finder_params).execute
+ if ::Gitlab::Ci::Features.use_coverage_data_new_finder?(project)
+ ::Ci::Testing::DailyBuildGroupReportResultsFinder.new(
+ params: new_finder_params,
+ current_user: current_user
+ ).execute
+ else
+ Ci::DailyBuildGroupReportResultsFinder.new(**finder_params).execute
+ end
+ end
+
+ def new_finder_params
+ {
+ project: project,
+ coverage: true,
+ start_date: start_date,
+ end_date: end_date,
+ ref_path: params[:ref_path],
+ sort: true
+ }
end
def finder_params
diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb
index ef9025ae52f..3552915b561 100644
--- a/app/controllers/projects/ci/pipeline_editor_controller.rb
+++ b/app/controllers/projects/ci/pipeline_editor_controller.rb
@@ -4,6 +4,7 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
before_action do
push_frontend_feature_flag(:ci_config_visualization_tab, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:ci_config_merged_tab, @project, default_enabled: :yaml)
end
feature_category :pipeline_authoring
diff --git a/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb b/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb
new file mode 100644
index 00000000000..003441d4b91
--- /dev/null
+++ b/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Projects
+ module Ci
+ module PrometheusMetrics
+ class HistogramsController < Projects::ApplicationController
+ feature_category :pipeline_authoring
+
+ respond_to :json, only: [:create]
+
+ def create
+ result = ::Ci::PrometheusMetrics::ObserveHistogramsService.new(project, permitted_params).execute
+
+ render json: result.payload, status: result.http_status
+ end
+
+ private
+
+ def permitted_params
+ params.permit(histograms: [:name, :value])
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 2e48f2f0e45..ffdd9fca95b 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -18,8 +18,12 @@ class Projects::CommitController < Projects::ApplicationController
before_action :define_commit_vars, only: [:show, :diff_for_path, :diff_files, :pipelines, :merge_requests]
before_action :define_note_vars, only: [:show, :diff_for_path, :diff_files]
before_action :authorize_edit_tree!, only: [:revert, :cherry_pick]
+ before_action only: [:pipelines] do
+ push_frontend_feature_flag(:ci_mini_pipeline_gl_dropdown, @project, type: :development, default_enabled: :yaml)
+ end
BRANCH_SEARCH_LIMIT = 1000
+ COMMIT_DIFFS_PER_PAGE = 75
feature_category :source_code_management
diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb
index b9ab1076999..708b7a6c7ba 100644
--- a/app/controllers/projects/discussions_controller.rb
+++ b/app/controllers/projects/discussions_controller.rb
@@ -18,7 +18,7 @@ class Projects::DiscussionsController < Projects::ApplicationController
end
def unresolve
- discussion.unresolve!
+ Discussions::UnresolveService.new(discussion, current_user).execute
render_discussion
end
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index 1c2930f6e9b..5576d5766c7 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -86,7 +86,7 @@ class Projects::ForksController < Projects::ApplicationController
def fork_service
strong_memoize(:fork_service) do
- ::Projects::ForkService.new(project, current_user, namespace: fork_namespace)
+ ::Projects::ForkService.new(project, current_user, fork_params)
end
end
@@ -96,6 +96,12 @@ class Projects::ForksController < Projects::ApplicationController
end
end
+ def fork_params
+ params.permit(:path, :name, :description, :visibility).tap do |param|
+ param[:namespace] = fork_namespace
+ end
+ end
+
def authorize_fork_namespace!
access_denied! unless fork_namespace && fork_service.valid_fork_target?
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 3a0e40f9745..2816977277a 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -9,6 +9,7 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuesCalendar
include SpammableActions
include RecordUserLastActivity
+ include CommentAndCloseFlag
ISSUES_EXCEPT_ACTIONS = %i[index calendar new create bulk_update import_csv export_csv service_desk].freeze
SET_ISSUEABLES_INDEX_ONLY_ACTIONS = %i[index calendar service_desk].freeze
@@ -41,7 +42,6 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :create_rate_limit, only: [:create]
before_action do
- push_frontend_feature_flag(:vue_issuable_sidebar, project.group)
push_frontend_feature_flag(:tribute_autocomplete, @project)
push_frontend_feature_flag(:vue_issuables_list, project)
push_frontend_feature_flag(:usage_data_design_action, project, default_enabled: true)
@@ -52,6 +52,7 @@ class Projects::IssuesController < Projects::ApplicationController
real_time_enabled = Gitlab::ActionCable::Config.in_app? || Feature.enabled?(real_time_feature_flag, @project)
push_to_gon_attributes(:features, real_time_feature_flag, real_time_enabled)
+ push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml)
record_experiment_user(:invite_members_version_a)
record_experiment_user(:invite_members_version_b)
@@ -60,8 +61,7 @@ class Projects::IssuesController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
before_action :run_null_hypothesis_experiment,
- only: [:index, :new, :create],
- if: -> { Feature.enabled?(:gitlab_experiments) }
+ only: [:index, :new, :create]
respond_to :html
@@ -106,7 +106,7 @@ class Projects::IssuesController < Projects::ApplicationController
build_params = issue_create_params.merge(
merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of],
discussion_to_resolve: params[:discussion_to_resolve],
- confidential: !!Gitlab::Utils.to_boolean(params[:issue][:confidential])
+ confidential: !!Gitlab::Utils.to_boolean(issue_create_params[:confidential])
)
service = ::Issues::BuildService.new(project, current_user, build_params)
@@ -131,7 +131,7 @@ class Projects::IssuesController < Projects::ApplicationController
service = ::Issues::CreateService.new(project, current_user, create_params)
@issue = service.execute
- create_vulnerability_issue_link(issue)
+ create_vulnerability_issue_feedback(issue)
if service.discussions_to_resolve.count(&:resolved?) > 0
flash[:notice] = if service.discussion_to_resolve_id
@@ -145,9 +145,6 @@ class Projects::IssuesController < Projects::ApplicationController
format.html do
recaptcha_check_with_fallback { render :new }
end
- format.js do
- @link = @issue.attachment.url.to_js
- end
end
end
@@ -403,7 +400,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
# Overridden in EE
- def create_vulnerability_issue_link(issue); end
+ def create_vulnerability_issue_feedback(issue); end
end
Projects::IssuesController.prepend_if_ee('EE::Projects::IssuesController')
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index d2703f5cc38..8a2ea51ba9d 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -15,9 +15,6 @@ class Projects::JobsController < Projects::ApplicationController
before_action :verify_api_request!, only: :terminal_websocket_authorize
before_action :authorize_create_proxy_build!, only: :proxy_websocket_authorize
before_action :verify_proxy_request!, only: :proxy_websocket_authorize
- before_action only: :index do
- frontend_experimentation_tracking_data(:jobs_empty_state, 'click_button')
- end
layout 'project'
diff --git a/app/controllers/projects/learn_gitlab_controller.rb b/app/controllers/projects/learn_gitlab_controller.rb
new file mode 100644
index 00000000000..162ba9bd5cb
--- /dev/null
+++ b/app/controllers/projects/learn_gitlab_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Projects::LearnGitlabController < Projects::ApplicationController
+ before_action :authenticate_user!
+ before_action :check_experiment_enabled?
+
+ feature_category :users
+
+ def index
+ push_frontend_experiment(:learn_gitlab_a, subject: current_user)
+ push_frontend_experiment(:learn_gitlab_b, subject: current_user)
+ end
+
+ private
+
+ def check_experiment_enabled?
+ return access_denied! unless helpers.learn_gitlab_experiment_enabled?(project)
+ end
+end
diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb
index 9cac9f37eb7..e74717a44ab 100644
--- a/app/controllers/projects/merge_requests/application_controller.rb
+++ b/app/controllers/projects/merge_requests/application_controller.rb
@@ -20,7 +20,7 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
end
def preloadable_mr_relations
- [:metrics, :assignees, { author: :status }]
+ [:metrics, { assignees: :status }, { author: :status }]
end
def merge_request_params
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 858bdc066c1..e79c19c3b67 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -12,9 +12,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
before_action :build_merge_request, except: [:create]
before_action do
- push_frontend_feature_flag(:merge_request_reviewers, @project, default_enabled: true)
push_frontend_feature_flag(:mr_collapsed_approval_rules, @project)
- push_frontend_feature_flag(:reviewer_approval_rules, @project, default_enabled: :yaml)
end
def new
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 9180b3f6b62..98ef9d918ae 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -122,10 +122,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
end
end
- if render_merge_ref_head_diff?
- return CompareService.new(@project, @merge_request.merge_ref_head.sha)
- .execute(@project, @merge_request.target_branch)
- end
+ return @merge_request.merge_head_diff if render_merge_ref_head_diff?
if @start_sha
@merge_request_diff.compare_with(@start_sha)
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index d452a5e02e2..c9e9a34ad88 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -11,6 +11,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include RecordUserLastActivity
include SourcegraphDecorator
include DiffHelper
+ include CommentAndCloseFlag
skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv]
before_action :apply_diff_view_cookie!, only: [:show]
@@ -22,37 +23,35 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:coverage_reports,
:terraform_reports,
:accessibility_reports,
- :codequality_reports
+ :codequality_reports,
+ :codequality_mr_diff_reports
]
before_action :set_issuables_index, only: [:index]
before_action :authenticate_user!, only: [:assign_related_issues]
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
before_action only: [:show] do
- push_frontend_feature_flag(:multiline_comments, @project, default_enabled: true)
push_frontend_feature_flag(:file_identifier_hash)
push_frontend_feature_flag(:batch_suggestions, @project, default_enabled: true)
push_frontend_feature_flag(:approvals_commented_by, @project, default_enabled: true)
push_frontend_feature_flag(:merge_request_widget_graphql, @project)
push_frontend_feature_flag(:drag_comment_selection, @project, default_enabled: true)
push_frontend_feature_flag(:unified_diff_components, @project, default_enabled: true)
- push_frontend_feature_flag(:default_merge_ref_for_diffs, @project)
- push_frontend_feature_flag(:core_security_mr_widget, @project, default_enabled: true)
+ push_frontend_feature_flag(:default_merge_ref_for_diffs, @project, default_enabled: :yaml)
push_frontend_feature_flag(:core_security_mr_widget_counts, @project)
- push_frontend_feature_flag(:core_security_mr_widget_downloads, @project, default_enabled: true)
push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true)
push_frontend_feature_flag(:diffs_gradual_load, @project, default_enabled: true)
- push_frontend_feature_flag(:codequality_mr_diff, @project)
- push_frontend_feature_flag(:suggestions_custom_commit, @project)
+ push_frontend_feature_flag(:codequality_backend_comparison, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:suggestions_custom_commit, @project, default_enabled: true)
+ push_frontend_feature_flag(:local_file_reviews, default_enabled: :yaml)
+ push_frontend_feature_flag(:paginated_notes, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:ci_mini_pipeline_gl_dropdown, @project, type: :development, default_enabled: :yaml)
record_experiment_user(:invite_members_version_a)
record_experiment_user(:invite_members_version_b)
end
before_action do
- push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
- push_frontend_feature_flag(:merge_request_reviewers, @project, default_enabled: true)
push_frontend_feature_flag(:mr_collapsed_approval_rules, @project)
- push_frontend_feature_flag(:reviewer_approval_rules, @project, default_enabled: :yaml)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
@@ -68,7 +67,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:toggle_award_emoji, :toggle_subscription, :update
]
- feature_category :code_testing, [:test_reports, :coverage_reports]
+ feature_category :code_testing, [:test_reports, :coverage_reports, :codequality_mr_diff_reports]
feature_category :accessibility_testing, [:accessibility_reports]
feature_category :infrastructure_as_code, [:terraform_reports]
@@ -168,6 +167,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
}
end
+ def sast_reports
+ reports_response(merge_request.compare_sast_reports(current_user), head_pipeline)
+ end
+
+ def secret_detection_reports
+ reports_response(merge_request.compare_secret_detection_reports(current_user), head_pipeline)
+ end
+
def context_commits
return render_404 unless project.context_commits_enabled?
@@ -197,6 +204,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
end
+ def codequality_mr_diff_reports
+ reports_response(@merge_request.find_codequality_mr_diff_reports)
+ end
+
def codequality_reports
reports_response(@merge_request.compare_codequality_reports)
end
@@ -491,7 +502,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
params = request.query_parameters
params[:view] = "inline"
- if Feature.enabled?(:default_merge_ref_for_diffs, project)
+ if Feature.enabled?(:default_merge_ref_for_diffs, project, default_enabled: :yaml)
params = params.merge(diff_head: true)
end
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 77fd7688caf..71a93701dc4 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -10,6 +10,7 @@ class Projects::NotesController < Projects::ApplicationController
before_action :authorize_read_note!
before_action :authorize_create_note!, only: [:create]
before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
+ before_action :create_rate_limit, only: [:create]
feature_category :issue_tracking
@@ -90,4 +91,20 @@ class Projects::NotesController < Projects::ApplicationController
def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42383')
end
+
+ def create_rate_limit
+ key = :notes_create
+ return unless rate_limiter.throttled?(key, scope: [current_user], users_allowlist: rate_limit_users_allowlist)
+
+ rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user)
+ render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests
+ end
+
+ def rate_limiter
+ ::Gitlab::ApplicationRateLimiter
+ end
+
+ def rate_limit_users_allowlist
+ Gitlab::CurrentSettings.current_application_settings.notes_create_limit_allowlist
+ end
end
diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb
index 924d52898ea..1702783b10f 100644
--- a/app/controllers/projects/pipelines/tests_controller.rb
+++ b/app/controllers/projects/pipelines/tests_controller.rb
@@ -42,9 +42,13 @@ module Projects
end
def test_suite
- builds.map do |build|
+ suite = builds.map do |build|
build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
end.sum
+
+ Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, project).load!
+
+ suite
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index ae8b3d9b51d..59b14bbb91d 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -13,15 +13,14 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
- push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: true)
push_frontend_feature_flag(:pipelines_security_report_summary, project)
push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: true)
- push_frontend_feature_flag(:graphql_pipeline_header, project, type: :development, default_enabled: false)
- push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: false)
- push_frontend_feature_flag(:new_pipeline_form_prefilled_vars, project, type: :development, default_enabled: true)
+ push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)
+ push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml)
+ push_frontend_feature_flag(:ci_mini_pipeline_gl_dropdown, project, type: :development, default_enabled: :yaml)
+ push_frontend_feature_flag(:jira_for_vulnerabilities, project, type: :development, default_enabled: :yaml)
end
before_action :ensure_pipeline, only: [:show]
- before_action :push_experiment_to_gon, only: :index, if: :html_request?
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
@@ -46,11 +45,7 @@ class Projects::PipelinesController < Projects::ApplicationController
@pipelines_count = limited_pipelines_count(project)
respond_to do |format|
- format.html do
- record_empty_pipeline_experiment
-
- render :index
- end
+ format.html
format.json do
Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
@@ -301,20 +296,6 @@ class Projects::PipelinesController < Projects::ApplicationController
def index_params
params.permit(:scope, :username, :ref, :status)
end
-
- def record_empty_pipeline_experiment
- return unless @pipelines_count.to_i == 0
- return if helpers.has_gitlab_ci?(@project)
-
- record_experiment_user(:pipelines_empty_state)
- end
-
- def push_experiment_to_gon
- return unless current_user
-
- push_frontend_experiment(:pipelines_empty_state, subject: current_user)
- frontend_experimentation_tracking_data(:pipelines_empty_state, 'view', project.namespace_id, subject: current_user)
- end
end
Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController')
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 5972b29a298..a7c7839dc9f 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -8,6 +8,10 @@ class Projects::ProjectMembersController < Projects::ApplicationController
# Authorize
before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access]
+ before_action do
+ push_frontend_feature_flag(:vue_project_members_list, @project, default_enabled: :yaml)
+ end
+
feature_category :authentication_and_authorization
def index
diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb
new file mode 100644
index 00000000000..9366ca7b0ed
--- /dev/null
+++ b/app/controllers/projects/security/configuration_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Projects
+ module Security
+ class ConfigurationController < Projects::ApplicationController
+ feature_category :static_application_security_testing
+
+ def show
+ return render_404 unless feature_enabled?
+
+ render_403 unless can?(current_user, :read_security_configuration, project)
+ end
+
+ private
+
+ def feature_enabled?
+ ::Feature.enabled?(:secure_security_and_compliance_configuration_page_on_ce, @project, default_enabled: :yaml)
+ end
+ end
+ end
+end
+
+Projects::Security::ConfigurationController.prepend_if_ee('EE::Projects::Security::ConfigurationController')
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 6ed9f74297d..b5c73f29784 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -14,7 +14,7 @@ class Projects::ServicesController < Projects::ApplicationController
before_action only: :edit do
push_frontend_feature_flag(:jira_issues_integration, @project, type: :licensed, default_enabled: true)
push_frontend_feature_flag(:jira_vulnerabilities_integration, @project, type: :licensed, default_enabled: true)
- push_frontend_feature_flag(:jira_for_vulnerabilities, @project, type: :development, default_enabled: false)
+ push_frontend_feature_flag(:jira_for_vulnerabilities, @project, type: :development, default_enabled: :yaml)
end
respond_to :html
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 31533dfeea0..34b11c456b9 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -144,8 +144,8 @@ module Projects
def define_badges_variables
@ref = params[:ref] || @project.default_branch || 'master'
- @badges = [Gitlab::Badge::Pipeline::Status,
- Gitlab::Badge::Coverage::Report]
+ @badges = [Gitlab::Ci::Badge::Pipeline::Status,
+ Gitlab::Ci::Badge::Coverage::Report]
@badges.map! do |badge|
badge.new(@project, @ref).metadata
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index dd50ab1bc7a..821560e32ba 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -7,7 +7,6 @@ module Projects
before_action :define_variables, only: [:create_deploy_token]
before_action do
push_frontend_feature_flag(:ajax_new_deploy_token, @project)
- push_frontend_feature_flag(:deploy_keys_on_protected_branches, @project)
end
feature_category :source_code_management, [:show, :cleanup]
diff --git a/app/controllers/projects/templates_controller.rb b/app/controllers/projects/templates_controller.rb
index f4726638777..ab05c9694fd 100644
--- a/app/controllers/projects/templates_controller.rb
+++ b/app/controllers/projects/templates_controller.rb
@@ -24,10 +24,8 @@ class Projects::TemplatesController < Projects::ApplicationController
end
def names
- templates = @template_type.dropdown_names(project)
-
respond_to do |format|
- format.json { render json: templates }
+ format.json { render json: TemplateFinder.all_template_names_array(project, params[:template_type].to_s.pluralize) }
end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 0c40478d877..ebffb62cff3 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -14,7 +14,7 @@ class ProjectsController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
- before_action :whitelist_query_limiting, only: [:create]
+ before_action :whitelist_query_limiting, only: [:show, :create]
before_action :authenticate_user!, except: [:index, :show, :activity, :refs, :resolve, :unfoldered_environment_names]
before_action :redirect_git_extension, only: [:show]
before_action :project, except: [:index, :new, :create, :resolve]
@@ -31,8 +31,11 @@ class ProjectsController < Projects::ApplicationController
# Project Export Rate Limit
before_action :export_rate_limit, only: [:export, :download_export, :generate_new_export]
+ before_action do
+ push_frontend_feature_flag(:vue_notification_dropdown, @project, default_enabled: :yaml)
+ end
+
before_action only: [:edit] do
- push_frontend_feature_flag(:approval_suggestions, @project, default_enabled: true)
push_frontend_feature_flag(:allow_editing_commit_messages, @project)
end
@@ -71,6 +74,7 @@ class ProjectsController < Projects::ApplicationController
@project = ::Projects::CreateService.new(current_user, project_params(attributes: project_params_create_attributes)).execute
if @project.saved?
+ experiment(:new_project_readme, actor: current_user).track(:created, property: active_new_project_tab)
redirect_to(
project_path(@project, custom_import_params),
notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name }
@@ -392,6 +396,14 @@ class ProjectsController < Projects::ApplicationController
]
end
+ def project_setting_attributes
+ %i[
+ show_default_award_emojis
+ squash_option
+ allow_editing_commit_messages
+ ]
+ end
+
def project_params_attributes
[
:allow_merge_on_skipped_pipeline,
@@ -429,11 +441,7 @@ class ProjectsController < Projects::ApplicationController
:suggestion_commit_message,
:packages_enabled,
:service_desk_enabled,
- project_setting_attributes: %i[
- show_default_award_emojis
- squash_option
- allow_editing_commit_messages
- ]
+ project_setting_attributes: project_setting_attributes
] + [project_feature_attributes: project_feature_attributes]
end
@@ -493,17 +501,19 @@ class ProjectsController < Projects::ApplicationController
render_404 unless Gitlab::CurrentSettings.project_export_enabled?
end
+ # Redirect from localhost/group/project.git to localhost/group/project
def redirect_git_extension
- # Redirect from
- # localhost/group/project.git
- # to
- # localhost/group/project
- #
- redirect_to request.original_url.sub(%r{\.git/?\Z}, '') if params[:format] == 'git'
+ return unless params[:format] == 'git'
+
+ # `project` calls `find_routable!`, so this will trigger the usual not-found
+ # behaviour when the user isn't authorized to see the project
+ return unless project
+
+ redirect_to(request.original_url.sub(%r{\.git/?\Z}, ''))
end
def whitelist_query_limiting
- Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42440')
+ Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/20826')
end
def present_project
diff --git a/app/controllers/registrations/experience_levels_controller.rb b/app/controllers/registrations/experience_levels_controller.rb
index 23126983eb5..b6ed0366177 100644
--- a/app/controllers/registrations/experience_levels_controller.rb
+++ b/app/controllers/registrations/experience_levels_controller.rb
@@ -2,9 +2,8 @@
module Registrations
class ExperienceLevelsController < ApplicationController
- layout 'devise_experimental_onboarding_issues'
+ layout 'signup_onboarding'
- before_action :check_experiment_enabled
before_action :ensure_namespace_path_param
feature_category :navigation
@@ -14,9 +13,8 @@ module Registrations
if current_user.save
hide_advanced_issues
- record_experiment_user(:default_to_issues_board)
- if experiment_enabled?(:default_to_issues_board) && learn_gitlab.available?
+ if learn_gitlab.available?
redirect_to namespace_project_board_path(params[:namespace_path], learn_gitlab.project, learn_gitlab.board)
else
redirect_to group_path(params[:namespace_path])
@@ -28,10 +26,6 @@ module Registrations
private
- def check_experiment_enabled
- access_denied! unless experiment_enabled?(:onboarding_issues)
- end
-
def ensure_namespace_path_param
redirect_to root_path unless params[:namespace_path].present?
end
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index 4a6fef56ef5..a1a6a057171 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -16,9 +16,7 @@ module Registrations
result = ::Users::SignupService.new(current_user, update_params).execute
if result[:status] == :success
- process_gitlab_com_tracking
-
- return redirect_to new_users_sign_up_group_path if experiment_enabled?(:onboarding_issues) && show_onboarding_issues_experiment?
+ return redirect_to new_users_sign_up_group_path if show_signup_onboarding?
redirect_to path_for_signed_in_user(current_user)
else
@@ -36,14 +34,6 @@ module Registrations
current_user.role.present? && !current_user.setup_for_company.nil?
end
- def process_gitlab_com_tracking
- return false unless ::Gitlab.com?
- return false unless show_onboarding_issues_experiment?
-
- track_experiment_event(:onboarding_issues, 'signed_up')
- record_experiment_user(:onboarding_issues)
- end
-
def update_params
params.require(:user).permit(:role, :other_role, :setup_for_company)
end
@@ -61,11 +51,8 @@ module Registrations
stored_location_for(user) || dashboard_projects_path
end
- def show_onboarding_issues_experiment?
- !helpers.in_subscription_flow? &&
- !helpers.in_invitation_flow? &&
- !helpers.in_oauth_flow? &&
- !helpers.in_trial_flow?
+ def show_signup_onboarding?
+ false
end
end
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index e7872eeac27..44c08863dd6 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -31,6 +31,8 @@ class RegistrationsController < Devise::RegistrationsController
NotificationService.new.new_instance_access_request(new_user)
end
+ after_request_hook(new_user)
+
yield new_user if block_given?
end
@@ -85,6 +87,10 @@ class RegistrationsController < Devise::RegistrationsController
super
end
+ def after_request_hook(user)
+ # overridden by EE module
+ end
+
def after_sign_up_path_for(user)
Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?))
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index 3cf0a23b7f6..9ad700404ff 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -78,6 +78,8 @@ module Repositories
def update_fetch_statistics
return unless project
return if Gitlab::Database.read_only?
+ return if Feature.enabled?(:disable_git_http_fetch_writes)
+
return unless repo_type.project?
OnboardingProgressService.new(project.namespace).execute(action: :git_read)
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 196b1887ca7..820b00a902e 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -5,11 +5,11 @@ class SearchController < ApplicationController
include SearchHelper
include RedisTracking
- track_redis_hll_event :show, name: 'i_search_total', feature: :search_track_unique_users, feature_default_enabled: true
+ track_redis_hll_event :show, name: 'i_search_total'
around_action :allow_gitaly_ref_name_caching
- before_action :block_anonymous_global_searches
+ before_action :block_anonymous_global_searches, except: :opensearch
skip_before_action :authenticate_user!
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
@@ -67,6 +67,9 @@ class SearchController < ApplicationController
end
# rubocop: enable CodeReuse/ActiveRecord
+ def opensearch
+ end
+
private
# overridden in EE
diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb
index 8532257cb8d..8a4e8edbf3c 100644
--- a/app/controllers/snippets/notes_controller.rb
+++ b/app/controllers/snippets/notes_controller.rb
@@ -23,7 +23,7 @@ class Snippets::NotesController < ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def snippet
- PersonalSnippet.find_by(id: params[:snippet_id])
+ @snippet ||= PersonalSnippet.find_by(id: params[:snippet_id])
end
# rubocop: enable CodeReuse/ActiveRecord
alias_method :noteable, :snippet
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 62208d838c1..54d97f588fc 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class UsersController < ApplicationController
+ include InternalRedirect
include RoutableActions
include RendersMemberAccess
include RendersProjectsList
@@ -13,13 +14,15 @@ class UsersController < ApplicationController
contributed: false,
snippets: true,
calendar: false,
+ followers: false,
+ following: false,
calendar_activities: true
skip_before_action :authenticate_user!
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
- before_action :user, except: [:exists, :suggests]
+ before_action :user, except: [:exists, :suggests, :ssh_keys]
before_action :authorize_read_user_profile!,
- only: [:calendar, :calendar_activities, :groups, :projects, :contributed, :starred, :snippets]
+ only: [:calendar, :calendar_activities, :groups, :projects, :contributed, :starred, :snippets, :followers, :following]
feature_category :users
@@ -41,7 +44,12 @@ class UsersController < ApplicationController
# Get all keys of a user(params[:username]) in a text format
# Helpful for sysadmins to put in respective servers
+ #
+ # Uses `UserFinder` rather than `find_routable!` because this endpoint should
+ # be publicly available regardless of instance visibility settings.
def ssh_keys
+ user = UserFinder.new(params[:username]).find_by_username
+
render plain: user.all_ssh_keys.join("\n")
end
@@ -92,6 +100,18 @@ class UsersController < ApplicationController
present_projects(@starred_projects)
end
+ def followers
+ @user_followers = user.followers.page(params[:page])
+
+ present_users(@user_followers)
+ end
+
+ def following
+ @user_following = user.followees.page(params[:page])
+
+ present_users(@user_following)
+ end
+
def present_projects(projects)
skip_pagination = Gitlab::Utils.to_boolean(params[:skip_pagination])
skip_namespace = Gitlab::Utils.to_boolean(params[:skip_namespace])
@@ -141,6 +161,22 @@ class UsersController < ApplicationController
render json: { exists: exists, suggests: suggestions }
end
+ def follow
+ current_user.follow(user)
+
+ redirect_path = referer_path(request) || @user
+
+ redirect_to redirect_path
+ end
+
+ def unfollow
+ current_user.unfollow(user)
+
+ redirect_path = referer_path(request) || @user
+
+ redirect_to redirect_path
+ end
+
private
def user
@@ -164,7 +200,7 @@ class UsersController < ApplicationController
end
def load_events
- @events = UserRecentEventsFinder.new(current_user, user, params).execute
+ @events = UserRecentEventsFinder.new(current_user, user, nil, params).execute
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end
@@ -211,6 +247,17 @@ class UsersController < ApplicationController
def authorize_read_user_profile!
access_denied! unless can?(current_user, :read_user_profile, user)
end
+
+ def present_users(users)
+ respond_to do |format|
+ format.html { render 'show' }
+ format.json do
+ render json: {
+ html: view_to_html_string("shared/users/index", users: users)
+ }
+ end
+ end
+ end
end
UsersController.prepend_if_ee('EE::UsersController')
diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb
index cba86c65848..12a52f30bd0 100644
--- a/app/controllers/whats_new_controller.rb
+++ b/app/controllers/whats_new_controller.rb
@@ -5,7 +5,6 @@ class WhatsNewController < ApplicationController
skip_before_action :authenticate_user!
- before_action :check_feature_flag
before_action :check_valid_page_param, :set_pagination_headers, unless: -> { has_version_param? }
feature_category :navigation
@@ -13,17 +12,13 @@ class WhatsNewController < ApplicationController
def index
respond_to do |format|
format.js do
- render json: highlight_items
+ render json: highlights.items
end
end
end
private
- def check_feature_flag
- render_404 unless Feature.enabled?(:whats_new_drawer, current_user)
- end
-
def check_valid_page_param
render_404 if current_page < 1
end
@@ -42,10 +37,6 @@ class WhatsNewController < ApplicationController
end
end
- def highlight_items
- highlights.map {|item| Gitlab::WhatsNew::ItemPresenter.present(item) }
- end
-
def set_pagination_headers
response.set_header('X-Next-Page', highlights.next_page)
end