summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 14:22:11 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 14:22:11 +0000
commit0c872e02b2c822e3397515ec324051ff540f0cd5 (patch)
treece2fb6ce7030e4dad0f4118d21ab6453e5938cdd /app/controllers
parentf7e05a6853b12f02911494c4b3fe53d9540d74fc (diff)
downloadgitlab-ce-0c872e02b2c822e3397515ec324051ff540f0cd5.tar.gz
Add latest changes from gitlab-org/gitlab@15-7-stable-eev15.7.0-rc42
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/application_settings/appearances_controller.rb1
-rw-r--r--app/controllers/admin/application_settings_controller.rb16
-rw-r--r--app/controllers/admin/background_jobs_controller.rb6
-rw-r--r--app/controllers/admin/background_migrations_controller.rb98
-rw-r--r--app/controllers/admin/batched_jobs_controller.rb34
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb154
-rw-r--r--app/controllers/admin/ci/variables_controller.rb80
-rw-r--r--app/controllers/admin/groups_controller.rb5
-rw-r--r--app/controllers/admin/plan_limits_controller.rb1
-rw-r--r--app/controllers/admin/projects_controller.rb8
-rw-r--r--app/controllers/admin/spam_logs_controller.rb2
-rw-r--r--app/controllers/admin/system_info_controller.rb10
-rw-r--r--app/controllers/admin/users_controller.rb14
-rw-r--r--app/controllers/application_controller.rb20
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb2
-rw-r--r--app/controllers/concerns/controller_with_cross_project_access_check.rb4
-rw-r--r--app/controllers/concerns/creates_commit.rb2
-rw-r--r--app/controllers/concerns/cycle_analytics_params.rb5
-rw-r--r--app/controllers/concerns/enforces_two_factor_authentication.rb18
-rw-r--r--app/controllers/concerns/impersonation.rb4
-rw-r--r--app/controllers/concerns/import/github_oauth.rb1
-rw-r--r--app/controllers/concerns/integrations/params.rb4
-rw-r--r--app/controllers/concerns/invisible_captcha_on_signup.rb2
-rw-r--r--app/controllers/concerns/issuable_actions.rb18
-rw-r--r--app/controllers/concerns/issuable_collections.rb4
-rw-r--r--app/controllers/concerns/issues_calendar.rb4
-rw-r--r--app/controllers/concerns/labels_as_hash.rb4
-rw-r--r--app/controllers/concerns/lfs_request.rb22
-rw-r--r--app/controllers/concerns/membership_actions.rb16
-rw-r--r--app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb4
-rw-r--r--app/controllers/concerns/metrics_dashboard.rb4
-rw-r--r--app/controllers/concerns/milestone_actions.rb24
-rw-r--r--app/controllers/concerns/notes_actions.rb38
-rw-r--r--app/controllers/concerns/oauth_applications.rb6
-rw-r--r--app/controllers/concerns/observability/content_security_policy.rb25
-rw-r--r--app/controllers/concerns/page_limiter.rb9
-rw-r--r--app/controllers/concerns/paginated_collection.rb4
-rw-r--r--app/controllers/concerns/preferred_language_switcher.rb2
-rw-r--r--app/controllers/concerns/preview_markdown.rb8
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb68
-rw-r--r--app/controllers/concerns/record_user_last_activity.rb5
-rw-r--r--app/controllers/concerns/render_service_results.rb24
-rw-r--r--app/controllers/concerns/renders_ldap_servers.rb12
-rw-r--r--app/controllers/concerns/routable_actions.rb10
-rw-r--r--app/controllers/concerns/snippets/blobs_actions.rb17
-rw-r--r--app/controllers/concerns/sorting_preference.rb4
-rw-r--r--app/controllers/concerns/sourcegraph_decorator.rb4
-rw-r--r--app/controllers/concerns/uploads_actions.rb24
-rw-r--r--app/controllers/concerns/verifies_with_email.rb10
-rw-r--r--app/controllers/concerns/vscode_cdn_csp.rb17
-rw-r--r--app/controllers/concerns/web_hooks/hook_actions.rb19
-rw-r--r--app/controllers/dashboard/snippets_controller.rb2
-rw-r--r--app/controllers/dashboard/todos_controller.rb39
-rw-r--r--app/controllers/explore/snippets_controller.rb2
-rw-r--r--app/controllers/google_api/authorizations_controller.rb11
-rw-r--r--app/controllers/graphql_controller.rb6
-rw-r--r--app/controllers/groups/application_controller.rb22
-rw-r--r--app/controllers/groups/boards_controller.rb10
-rw-r--r--app/controllers/groups/dependency_proxy_for_containers_controller.rb2
-rw-r--r--app/controllers/groups/observability_controller.rb23
-rw-r--r--app/controllers/groups/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/groups/usage_quotas_controller.rb28
-rw-r--r--app/controllers/groups/variables_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/ide_controller.rb1
-rw-r--r--app/controllers/import/bitbucket_controller.rb23
-rw-r--r--app/controllers/import/bulk_imports_controller.rb2
-rw-r--r--app/controllers/import/fogbugz_controller.rb4
-rw-r--r--app/controllers/import/gitea_controller.rb26
-rw-r--r--app/controllers/import/github_controller.rb48
-rw-r--r--app/controllers/jira_connect/app_descriptor_controller.rb6
-rw-r--r--app/controllers/jira_connect/application_controller.rb26
-rw-r--r--app/controllers/jira_connect/cors_preflight_checks_controller.rb16
-rw-r--r--app/controllers/jira_connect/events_controller.rb7
-rw-r--r--app/controllers/jira_connect/installations_controller.rb12
-rw-r--r--app/controllers/jira_connect/oauth_application_ids_controller.rb3
-rw-r--r--app/controllers/jira_connect/public_keys_controller.rb4
-rw-r--r--app/controllers/jira_connect/subscriptions_controller.rb10
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/passwords_controller.rb4
-rw-r--r--app/controllers/profiles/keys_controller.rb2
-rw-r--r--app/controllers/profiles/preferences_controller.rb3
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb16
-rw-r--r--app/controllers/projects/autocomplete_sources_controller.rb2
-rw-r--r--app/controllers/projects/badges_controller.rb30
-rw-r--r--app/controllers/projects/blame_controller.rb2
-rw-r--r--app/controllers/projects/blob_controller.rb3
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/ci/daily_build_group_report_results_controller.rb2
-rw-r--r--app/controllers/projects/clusters_controller.rb1
-rw-r--r--app/controllers/projects/commit_controller.rb2
-rw-r--r--app/controllers/projects/commits_controller.rb14
-rw-r--r--app/controllers/projects/compare_controller.rb4
-rw-r--r--app/controllers/projects/environments_controller.rb6
-rw-r--r--app/controllers/projects/find_file_controller.rb2
-rw-r--r--app/controllers/projects/forks_controller.rb4
-rw-r--r--app/controllers/projects/graphs_controller.rb38
-rw-r--r--app/controllers/projects/incidents_controller.rb1
-rw-r--r--app/controllers/projects/issues_controller.rb15
-rw-r--r--app/controllers/projects/jobs_controller.rb3
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb13
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb8
-rw-r--r--app/controllers/projects/merge_requests_controller.rb153
-rw-r--r--app/controllers/projects/metrics_dashboard_controller.rb4
-rw-r--r--app/controllers/projects/ml/candidates_controller.rb23
-rw-r--r--app/controllers/projects/ml/experiments_controller.rb1
-rw-r--r--app/controllers/projects/network_controller.rb10
-rw-r--r--app/controllers/projects/performance_monitoring/dashboards_controller.rb4
-rw-r--r--app/controllers/projects/pipelines_controller.rb5
-rw-r--r--app/controllers/projects/protected_branches_controller.rb6
-rw-r--r--app/controllers/projects/raw_controller.rb4
-rw-r--r--app/controllers/projects/refs_controller.rb20
-rw-r--r--app/controllers/projects/registry/repositories_controller.rb4
-rw-r--r--app/controllers/projects/runner_projects_controller.rb2
-rw-r--r--app/controllers/projects/service_desk_controller.rb2
-rw-r--r--app/controllers/projects/service_ping_controller.rb6
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb13
-rw-r--r--app/controllers/projects/settings/integrations_controller.rb4
-rw-r--r--app/controllers/projects/settings/repository_controller.rb8
-rw-r--r--app/controllers/projects/snippets/application_controller.rb2
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/controllers/projects/tree_controller.rb3
-rw-r--r--app/controllers/projects/variables_controller.rb2
-rw-r--r--app/controllers/projects/work_items_controller.rb3
-rw-r--r--app/controllers/projects_controller.rb38
-rw-r--r--app/controllers/registrations/welcome_controller.rb8
-rw-r--r--app/controllers/registrations_controller.rb39
-rw-r--r--app/controllers/repositories/lfs_locks_api_controller.rb8
-rw-r--r--app/controllers/repositories/lfs_storage_controller.rb2
-rw-r--r--app/controllers/search_controller.rb25
-rw-r--r--app/controllers/snippets/application_controller.rb2
-rw-r--r--app/controllers/snippets/notes_controller.rb2
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/controllers/web_ide/remote_ide_controller.rb53
136 files changed, 1082 insertions, 798 deletions
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
index 0de2115d4d6..80aca7e21ce 100644
--- a/app/controllers/abuse_reports_controller.rb
+++ b/app/controllers/abuse_reports_controller.rb
@@ -3,7 +3,7 @@
class AbuseReportsController < ApplicationController
before_action :set_user, only: [:new]
- feature_category :users
+ feature_category :insider_threat
def new
@abuse_report = AbuseReport.new
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index 6f80ed3c172..5357558434e 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Admin::AbuseReportsController < Admin::ApplicationController
- feature_category :users
+ feature_category :insider_threat
def index
@abuse_reports = AbuseReportsFinder.new(params).execute
diff --git a/app/controllers/admin/application_settings/appearances_controller.rb b/app/controllers/admin/application_settings/appearances_controller.rb
index cf765c96a8f..1a8447185a7 100644
--- a/app/controllers/admin/application_settings/appearances_controller.rb
+++ b/app/controllers/admin/application_settings/appearances_controller.rb
@@ -68,6 +68,7 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
def allowed_appearance_params
%i[
title
+ short_title
description
logo
logo_cache
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index ec9441c2b9b..b8c1bc266f7 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -40,9 +40,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
feature_category :pages, [:lets_encrypt_terms_of_service]
feature_category :error_tracking, [:reset_error_tracking_access_token]
- VALID_SETTING_PANELS = %w(general repository
+ VALID_SETTING_PANELS = %w[general repository
ci_cd reporting metrics_and_profiling
- network preferences).freeze
+ network preferences].freeze
# The current size of a sidekiq job's jid is 24 characters. The size of the
# jid is an internal detail of Sidekiq, and they do not guarantee that it'll
@@ -150,9 +150,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
}
end
- if @application_setting.self_monitoring_project_id.present?
- return render status: :ok, json: self_monitoring_data
- end
+ return render status: :ok, json: self_monitoring_data if @application_setting.self_monitoring_project_id.present?
render status: :bad_request, json: {
message: _('Self-monitoring project does not exist. Please check logs ' \
@@ -236,7 +234,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
params[:application_setting][:restricted_visibility_levels]&.delete("")
if params[:application_setting].key?(:required_instance_ci_template)
- params[:application_setting][:required_instance_ci_template] = nil if params[:application_setting][:required_instance_ci_template].empty?
+ if params[:application_setting][:required_instance_ci_template].empty?
+ params[:application_setting][:required_instance_ci_template] = nil
+ end
end
remove_blank_params_for!(:elasticsearch_aws_secret_access_key, :eks_secret_access_key)
@@ -290,9 +290,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
.new(@application_setting, current_user, application_setting_params)
.execute
- if recheck_user_consent?
- session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent?
- end
+ session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent? if recheck_user_consent?
redirect_path = referer_path(request) || general_admin_application_settings_path
diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb
index 4eda35d66f6..43d2c983823 100644
--- a/app/controllers/admin/background_jobs_controller.rb
+++ b/app/controllers/admin/background_jobs_controller.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
-class Admin::BackgroundJobsController < Admin::ApplicationController
- feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
+module Admin
+ class BackgroundJobsController < ApplicationController
+ feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
+ end
end
diff --git a/app/controllers/admin/background_migrations_controller.rb b/app/controllers/admin/background_migrations_controller.rb
index c6c9e0ced22..b904196c5ab 100644
--- a/app/controllers/admin/background_migrations_controller.rb
+++ b/app/controllers/admin/background_migrations_controller.rb
@@ -1,66 +1,68 @@
# frozen_string_literal: true
-class Admin::BackgroundMigrationsController < Admin::ApplicationController
- feature_category :database
- urgency :low
-
- around_action :support_multiple_databases
-
- def index
- @relations_by_tab = {
- 'queued' => batched_migration_class.queued.queue_order,
- 'failed' => batched_migration_class.with_status(:failed).queue_order,
- 'finished' => batched_migration_class.with_status(:finished).queue_order.reverse_order
- }
-
- @current_tab = @relations_by_tab.key?(params[:tab]) ? params[:tab] : 'queued'
- @migrations = @relations_by_tab[@current_tab].page(params[:page])
- @successful_rows_counts = batched_migration_class.successful_rows_counts(@migrations.map(&:id))
- @databases = Gitlab::Database.db_config_names
- end
+module Admin
+ class BackgroundMigrationsController < ApplicationController
+ feature_category :database
+ urgency :low
+
+ around_action :support_multiple_databases
+
+ def index
+ @relations_by_tab = {
+ 'queued' => batched_migration_class.queued.queue_order,
+ 'failed' => batched_migration_class.with_status(:failed).queue_order,
+ 'finished' => batched_migration_class.with_status(:finished).queue_order.reverse_order
+ }
+
+ @current_tab = @relations_by_tab.key?(params[:tab]) ? params[:tab] : 'queued'
+ @migrations = @relations_by_tab[@current_tab].page(params[:page])
+ @successful_rows_counts = batched_migration_class.successful_rows_counts(@migrations.map(&:id))
+ @databases = Gitlab::Database.db_config_names
+ end
- def show
- @migration = batched_migration_class.find(params[:id])
+ def show
+ @migration = batched_migration_class.find(params[:id])
- @failed_jobs = @migration.batched_jobs.with_status(:failed).page(params[:page])
- end
+ @failed_jobs = @migration.batched_jobs.with_status(:failed).page(params[:page])
+ end
- def pause
- migration = batched_migration_class.find(params[:id])
- migration.pause!
+ def pause
+ migration = batched_migration_class.find(params[:id])
+ migration.pause!
- redirect_back fallback_location: { action: 'index' }
- end
+ redirect_back fallback_location: { action: 'index' }
+ end
- def resume
- migration = batched_migration_class.find(params[:id])
- migration.execute!
+ def resume
+ migration = batched_migration_class.find(params[:id])
+ migration.execute!
- redirect_back fallback_location: { action: 'index' }
- end
+ redirect_back fallback_location: { action: 'index' }
+ end
- def retry
- migration = batched_migration_class.find(params[:id])
- migration.retry_failed_jobs! if migration.failed?
+ def retry
+ migration = batched_migration_class.find(params[:id])
+ migration.retry_failed_jobs! if migration.failed?
- redirect_back fallback_location: { action: 'index' }
- end
+ redirect_back fallback_location: { action: 'index' }
+ end
- private
+ private
- def support_multiple_databases
- Gitlab::Database::SharedModel.using_connection(base_model.connection) do
- yield
+ def support_multiple_databases
+ Gitlab::Database::SharedModel.using_connection(base_model.connection) do
+ yield
+ end
end
- end
- def base_model
- @selected_database = params[:database] || Gitlab::Database::MAIN_DATABASE_NAME
+ def base_model
+ @selected_database = params[:database] || Gitlab::Database::MAIN_DATABASE_NAME
- Gitlab::Database.database_base_models[@selected_database]
- end
+ Gitlab::Database.database_base_models[@selected_database]
+ end
- def batched_migration_class
- @batched_migration_class ||= Gitlab::Database::BackgroundMigration::BatchedMigration
+ def batched_migration_class
+ @batched_migration_class ||= Gitlab::Database::BackgroundMigration::BatchedMigration
+ end
end
end
diff --git a/app/controllers/admin/batched_jobs_controller.rb b/app/controllers/admin/batched_jobs_controller.rb
index 0a00ba13dc8..10b5f68d630 100644
--- a/app/controllers/admin/batched_jobs_controller.rb
+++ b/app/controllers/admin/batched_jobs_controller.rb
@@ -1,28 +1,30 @@
# frozen_string_literal: true
-class Admin::BatchedJobsController < Admin::ApplicationController
- feature_category :database
- urgency :low
+module Admin
+ class BatchedJobsController < ApplicationController
+ feature_category :database
+ urgency :low
- around_action :support_multiple_databases
+ around_action :support_multiple_databases
- def show
- @job = Gitlab::Database::BackgroundMigration::BatchedJob.find(params[:id])
+ def show
+ @job = Gitlab::Database::BackgroundMigration::BatchedJob.find(params[:id])
- @transition_logs = @job.batched_job_transition_logs
- end
+ @transition_logs = @job.batched_job_transition_logs
+ end
- private
+ private
- def support_multiple_databases
- Gitlab::Database::SharedModel.using_connection(base_model.connection) do
- yield
+ def support_multiple_databases
+ Gitlab::Database::SharedModel.using_connection(base_model.connection) do
+ yield
+ end
end
- end
- def base_model
- @selected_database = params[:database] || Gitlab::Database::MAIN_DATABASE_NAME
+ def base_model
+ @selected_database = params[:database] || Gitlab::Database::MAIN_DATABASE_NAME
- Gitlab::Database.database_base_models[@selected_database]
+ Gitlab::Database.database_base_models[@selected_database]
+ end
end
end
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index bdf0c6aedb9..093c5667a24 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -1,104 +1,106 @@
# frozen_string_literal: true
-class Admin::BroadcastMessagesController < Admin::ApplicationController
- include BroadcastMessagesHelper
+module Admin
+ class BroadcastMessagesController < ApplicationController
+ include BroadcastMessagesHelper
- before_action :find_broadcast_message, only: [:edit, :update, :destroy]
- before_action :find_broadcast_messages, only: [:index, :create]
- before_action :push_features, only: [:index, :edit]
+ before_action :find_broadcast_message, only: [:edit, :update, :destroy]
+ before_action :find_broadcast_messages, only: [:index, :create]
+ before_action :push_features, only: [:index, :edit]
- feature_category :onboarding
- urgency :low
+ feature_category :onboarding
+ urgency :low
- def index
- @broadcast_message = BroadcastMessage.new
- end
-
- def edit
- end
+ def index
+ @broadcast_message = BroadcastMessage.new
+ end
- def create
- @broadcast_message = BroadcastMessage.new(broadcast_message_params)
- success = @broadcast_message.save
+ def edit
+ end
- respond_to do |format|
- format.json do
- if success
- render json: @broadcast_message, status: :ok
- else
- render json: { errors: @broadcast_message.errors.full_messages }, status: :bad_request
+ def create
+ @broadcast_message = BroadcastMessage.new(broadcast_message_params)
+ success = @broadcast_message.save
+
+ respond_to do |format|
+ format.json do
+ if success
+ render json: @broadcast_message, status: :ok
+ else
+ render json: { errors: @broadcast_message.errors.full_messages }, status: :bad_request
+ end
end
- end
- format.html do
- if success
- redirect_to admin_broadcast_messages_path, notice: _('Broadcast Message was successfully created.')
- else
- render :index
+ format.html do
+ if success
+ redirect_to admin_broadcast_messages_path, notice: _('Broadcast Message was successfully created.')
+ else
+ render :index
+ end
end
end
end
- end
- def update
- success = @broadcast_message.update(broadcast_message_params)
+ def update
+ success = @broadcast_message.update(broadcast_message_params)
- respond_to do |format|
- format.json do
- if success
- render json: @broadcast_message, status: :ok
- else
- render json: { errors: @broadcast_message.errors.full_messages }, status: :bad_request
+ respond_to do |format|
+ format.json do
+ if success
+ render json: @broadcast_message, status: :ok
+ else
+ render json: { errors: @broadcast_message.errors.full_messages }, status: :bad_request
+ end
end
- end
- format.html do
- if success
- redirect_to admin_broadcast_messages_path, notice: _('Broadcast Message was successfully updated.')
- else
- render :edit
+ format.html do
+ if success
+ redirect_to admin_broadcast_messages_path, notice: _('Broadcast Message was successfully updated.')
+ else
+ render :edit
+ end
end
end
end
- end
- def destroy
- @broadcast_message.destroy
+ def destroy
+ @broadcast_message.destroy
- respond_to do |format|
- format.html { redirect_back_or_default(default: { action: 'index' }) }
- format.js { head :ok }
+ respond_to do |format|
+ format.html { redirect_back_or_default(default: { action: 'index' }) }
+ format.js { head :ok }
+ end
end
- end
- def preview
- @broadcast_message = BroadcastMessage.new(broadcast_message_params)
- render partial: 'admin/broadcast_messages/preview'
- end
+ def preview
+ @broadcast_message = BroadcastMessage.new(broadcast_message_params)
+ render partial: 'admin/broadcast_messages/preview'
+ end
- protected
+ protected
- def find_broadcast_message
- @broadcast_message = BroadcastMessage.find(params[:id])
- end
+ def find_broadcast_message
+ @broadcast_message = BroadcastMessage.find(params[:id])
+ end
- def find_broadcast_messages
- @broadcast_messages = BroadcastMessage.order(ends_at: :desc).page(params[:page]) # rubocop: disable CodeReuse/ActiveRecord
- end
+ def find_broadcast_messages
+ @broadcast_messages = BroadcastMessage.order(ends_at: :desc).page(params[:page]) # rubocop: disable CodeReuse/ActiveRecord
+ end
- def broadcast_message_params
- params.require(:broadcast_message)
- .permit(%i(
- theme
- ends_at
- message
- starts_at
- target_path
- broadcast_type
- dismissable
- ), target_access_levels: []).reverse_merge!(target_access_levels: [])
- end
+ def broadcast_message_params
+ params.require(:broadcast_message)
+ .permit(%i[
+ theme
+ ends_at
+ message
+ starts_at
+ target_path
+ broadcast_type
+ dismissable
+ ], target_access_levels: []).reverse_merge!(target_access_levels: [])
+ end
- def push_features
- push_frontend_feature_flag(:vue_broadcast_messages, current_user)
- push_frontend_feature_flag(:role_targeted_broadcast_messages, current_user)
+ def push_features
+ push_frontend_feature_flag(:vue_broadcast_messages, current_user)
+ push_frontend_feature_flag(:role_targeted_broadcast_messages, current_user)
+ end
end
end
diff --git a/app/controllers/admin/ci/variables_controller.rb b/app/controllers/admin/ci/variables_controller.rb
index 7d643435ddb..ef50d7362c4 100644
--- a/app/controllers/admin/ci/variables_controller.rb
+++ b/app/controllers/admin/ci/variables_controller.rb
@@ -1,50 +1,54 @@
# frozen_string_literal: true
-class Admin::Ci::VariablesController < Admin::ApplicationController
- feature_category :pipeline_authoring
-
- def show
- respond_to do |format|
- format.json { render_instance_variables }
- end
- end
-
- def update
- service = Ci::UpdateInstanceVariablesService.new(variables_params)
-
- if service.execute
- respond_to do |format|
- format.json { render_instance_variables }
+module Admin
+ module Ci
+ class VariablesController < ApplicationController
+ feature_category :pipeline_authoring
+
+ def show
+ respond_to do |format|
+ format.json { render_instance_variables }
+ end
end
- else
- respond_to do |format|
- format.json { render_error(service.errors) }
+
+ def update
+ service = ::Ci::UpdateInstanceVariablesService.new(variables_params)
+
+ if service.execute
+ respond_to do |format|
+ format.json { render_instance_variables }
+ end
+ else
+ respond_to do |format|
+ format.json { render_error(service.errors) }
+ end
+ end
end
- end
- end
- private
+ private
- def variables
- @variables ||= Ci::InstanceVariable.all
- end
+ def variables
+ @variables ||= ::Ci::InstanceVariable.all
+ end
- def render_instance_variables
- render status: :ok,
- json: {
- variables: Ci::InstanceVariableSerializer.new.represent(variables)
- }
- end
+ def render_instance_variables
+ render status: :ok,
+ json: {
+ variables: ::Ci::InstanceVariableSerializer.new.represent(variables)
+ }
+ end
- def render_error(errors)
- render status: :bad_request, json: errors
- end
+ def render_error(errors)
+ render status: :bad_request, json: errors
+ end
- def variables_params
- params.permit(variables_attributes: Array(variable_params_attributes))
- end
+ def variables_params
+ params.permit(variables_attributes: Array(variable_params_attributes))
+ end
- def variable_params_attributes
- %i[id variable_type key secret_value protected masked _destroy]
+ def variable_params_attributes
+ %i[id variable_type key secret_value protected masked raw _destroy]
+ end
+ end
end
end
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index 1395d4bb3b7..8005babe19e 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -51,6 +51,10 @@ class Admin::GroupsController < Admin::ApplicationController
@group.build_admin_note unless @group.admin_note
if @group.update(group_params)
+ unless Gitlab::Utils.to_boolean(group_params['runner_registration_enabled'])
+ Ci::Runners::ResetRegistrationTokenService.new(@group, current_user).execute
+ end
+
redirect_to [:admin, @group], notice: _('Group was successfully updated.')
else
render "edit"
@@ -91,6 +95,7 @@ class Admin::GroupsController < Admin::ApplicationController
:name,
:path,
:request_access_enabled,
+ :runner_registration_enabled,
:visibility_level,
:require_two_factor_authentication,
:two_factor_grace_period,
diff --git a/app/controllers/admin/plan_limits_controller.rb b/app/controllers/admin/plan_limits_controller.rb
index 2cebc059830..ea52198432c 100644
--- a/app/controllers/admin/plan_limits_controller.rb
+++ b/app/controllers/admin/plan_limits_controller.rb
@@ -47,6 +47,7 @@ class Admin::PlanLimitsController < Admin::ApplicationController
ci_needs_size_limit
ci_registered_group_runners
ci_registered_project_runners
+ pipeline_hierarchy_size
])
end
end
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 3f3c3581555..9e841487508 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -13,9 +13,7 @@ class Admin::ProjectsController < Admin::ApplicationController
params[:sort] ||= 'latest_activity_desc'
@sort = params[:sort]
- if params[:last_repository_check_failed].present? && params[:archived].nil?
- params[:archived] = true
- end
+ params[:archived] = true if params[:last_repository_check_failed].present? && params[:archived].nil?
@projects = Admin::ProjectsFinder.new(params: params, current_user: current_user).execute
@@ -57,9 +55,7 @@ class Admin::ProjectsController < Admin::ApplicationController
namespace = Namespace.find_by(id: params[:new_namespace_id])
::Projects::TransferService.new(@project, current_user, params.dup).execute(namespace)
- if @project.errors[:new_namespace].present?
- flash[:alert] = @project.errors[:new_namespace].first
- end
+ flash[:alert] = @project.errors[:new_namespace].first if @project.errors[:new_namespace].present?
@project.reset
redirect_to admin_project_path(@project)
diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb
index 3a55fc4b951..180f4634136 100644
--- a/app/controllers/admin/spam_logs_controller.rb
+++ b/app/controllers/admin/spam_logs_controller.rb
@@ -5,7 +5,7 @@ class Admin::SpamLogsController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def index
- @spam_logs = SpamLog.order(id: :desc).page(params[:page])
+ @spam_logs = SpamLog.includes(:user).order(id: :desc).page(params[:page])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb
index 41f95addc66..96fb73cedfe 100644
--- a/app/controllers/admin/system_info_controller.rb
+++ b/app/controllers/admin/system_info_controller.rb
@@ -59,11 +59,11 @@ class Admin::SystemInfoController < Admin::ApplicationController
begin
disk = Sys::Filesystem.stat(mount.mount_point)
@disks.push({
- bytes_total: disk.bytes_total,
- bytes_used: disk.bytes_used,
- disk_name: mount.name,
- mount_path: disk.path
- })
+ bytes_total: disk.bytes_total,
+ bytes_used: disk.bytes_used,
+ disk_name: mount.name,
+ mount_path: disk.path
+ })
rescue Sys::Filesystem::Error
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 2c8b4888d5d..5f6e3f0062f 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -88,17 +88,25 @@ class Admin::UsersController < Admin::ApplicationController
end
def activate
- return redirect_back_or_admin_user(notice: _("Error occurred. A blocked user must be unblocked to be activated")) if user.blocked?
+ if user.blocked?
+ return redirect_back_or_admin_user(notice: _("Error occurred. A blocked user must be unblocked to be activated"))
+ end
user.activate
redirect_back_or_admin_user(notice: _("Successfully activated"))
end
def deactivate
- return redirect_back_or_admin_user(notice: _("Error occurred. A blocked user cannot be deactivated")) if user.blocked?
+ if user.blocked?
+ return redirect_back_or_admin_user(notice: _("Error occurred. A blocked user cannot be deactivated"))
+ end
+
return redirect_back_or_admin_user(notice: _("Successfully deactivated")) if user.deactivated?
return redirect_back_or_admin_user(notice: _("Internal users cannot be deactivated")) if user.internal?
- return redirect_back_or_admin_user(notice: _("The user you are trying to deactivate has been active in the past %{minimum_inactive_days} days and cannot be deactivated") % { minimum_inactive_days: Gitlab::CurrentSettings.deactivate_dormant_users_period }) unless user.can_be_deactivated?
+
+ unless user.can_be_deactivated?
+ return redirect_back_or_admin_user(notice: _("The user you are trying to deactivate has been active in the past %{minimum_inactive_days} days and cannot be deactivated") % { minimum_inactive_days: Gitlab::CurrentSettings.deactivate_dormant_users_period })
+ end
user.deactivate
redirect_back_or_admin_user(notice: _("Successfully deactivated"))
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 4de6b5de42a..e64d3110c3a 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -158,7 +158,7 @@ class ApplicationController < ActionController::Base
protected
def workhorse_excluded_content_types
- @workhorse_excluded_content_types ||= %w(text/html application/json)
+ @workhorse_excluded_content_types ||= %w[text/html application/json]
end
def append_info_to_payload(payload)
@@ -179,9 +179,7 @@ class ApplicationController < ActionController::Base
payload[:queue_duration_s] = request.env[::Gitlab::Middleware::RailsQueueDuration::GITLAB_RAILS_QUEUE_DURATION_KEY]
- if Feature.enabled?(:log_response_length)
- payload[:response_bytes] = response.body_parts.sum(&:bytesize)
- end
+ payload[:response_bytes] = response.body_parts.sum(&:bytesize) if Feature.enabled?(:log_response_length)
store_cloudflare_headers!(payload, request)
end
@@ -349,9 +347,7 @@ class ApplicationController < ActionController::Base
def check_password_expiration
return if session[:impersonator_id] || !current_user&.allow_password_authentication?
- if current_user&.password_expired?
- redirect_to new_profile_password_path
- end
+ redirect_to new_profile_password_path if current_user&.password_expired?
end
def active_user_check
@@ -426,8 +422,8 @@ class ApplicationController < ActionController::Base
# accepting the terms.
redirect_path = if request.get?
request.fullpath
- else
- URI(request.referer).path if request.referer
+ elsif request.referer
+ URI(request.referer).path
end
flash[:notice] = message
@@ -529,7 +525,7 @@ class ApplicationController < ActionController::Base
end
def set_page_title_header
- # Per https://tools.ietf.org/html/rfc5987, headers need to be ISO-8859-1, not UTF-8
+ # Per https://www.rfc-editor.org/rfc/rfc5987, headers need to be ISO-8859-1, not UTF-8
response.headers['Page-Title'] = Addressable::URI.encode_component(page_title('GitLab'))
end
@@ -565,9 +561,7 @@ class ApplicationController < ActionController::Base
session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent?
- if session[:ask_for_usage_stats_consent]
- disable_usage_stats
- end
+ disable_usage_stats if session[:ask_for_usage_stats_consent]
end
def disable_usage_stats
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 817f82085e6..b4a36b7db22 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -23,6 +23,8 @@ module AuthenticatesWithTwoFactor
session[:otp_user_id] = user.id
session[:user_password_hash] = Digest::SHA256.hexdigest(user.encrypted_password)
+
+ add_gon_variables
push_frontend_feature_flag(:webauthn)
if Feature.enabled?(:webauthn)
diff --git a/app/controllers/concerns/controller_with_cross_project_access_check.rb b/app/controllers/concerns/controller_with_cross_project_access_check.rb
index 3f72f092683..eace8e9464b 100644
--- a/app/controllers/concerns/controller_with_cross_project_access_check.rb
+++ b/app/controllers/concerns/controller_with_cross_project_access_check.rb
@@ -9,9 +9,7 @@ module ControllerWithCrossProjectAccessCheck
end
def cross_project_check
- if Gitlab::CrossProjectAccess.find_check(self)&.should_run?(self)
- authorize_cross_project_page!
- end
+ authorize_cross_project_page! if Gitlab::CrossProjectAccess.find_check(self)&.should_run?(self)
end
def authorize_cross_project_page!
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index b6ba1b13cc3..53bb11090c8 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -78,7 +78,7 @@ module CreatesCommit
_("You can now submit a merge request to get this change into the original branch.")
end
- flash[:notice] += " " + mr_message
+ flash[:notice] += " #{mr_message}"
end
end
end
diff --git a/app/controllers/concerns/cycle_analytics_params.rb b/app/controllers/concerns/cycle_analytics_params.rb
index 70bcefe339c..5199d879595 100644
--- a/app/controllers/concerns/cycle_analytics_params.rb
+++ b/app/controllers/concerns/cycle_analytics_params.rb
@@ -23,7 +23,10 @@ module CycleAnalyticsParams
opts[:from] = params[:from] || start_date(params)
opts[:to] = params[:to] if params[:to]
opts[:end_event_filter] = params[:end_event_filter] if params[:end_event_filter]
- opts[:use_aggregated_data_collector] = params[:use_aggregated_data_collector] if params[:use_aggregated_data_collector]
+ if params[:use_aggregated_data_collector]
+ opts[:use_aggregated_data_collector] = params[:use_aggregated_data_collector]
+ end
+
opts.merge!(params.slice(*::Gitlab::Analytics::CycleAnalytics::RequestParams::FINDER_PARAM_NAMES))
opts.merge!(date_range(params))
end
diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb
index b1b6e21644e..c8de041d5bd 100644
--- a/app/controllers/concerns/enforces_two_factor_authentication.rb
+++ b/app/controllers/concerns/enforces_two_factor_authentication.rb
@@ -10,19 +10,12 @@
module EnforcesTwoFactorAuthentication
extend ActiveSupport::Concern
- MFA_HELP_PAGE = Rails.application.routes.url_helpers.help_page_url(
- 'user/profile/account/two_factor_authentication.html',
- anchor: 'enable-two-factor-authentication'
- )
-
included do
before_action :check_two_factor_requirement, except: [:route_not_found]
# to include this in controllers inheriting from `ActionController::Metal`
# we need to add this block
- if respond_to?(:helper_method)
- helper_method :two_factor_grace_period_expired?, :two_factor_skippable?
- end
+ helper_method :two_factor_grace_period_expired?, :two_factor_skippable? if respond_to?(:helper_method)
end
def check_two_factor_requirement
@@ -33,7 +26,7 @@ module EnforcesTwoFactorAuthentication
when GraphqlController
render_error(
_("Authentication error: enable 2FA in your profile settings to continue using GitLab: %{mfa_help_page}") %
- { mfa_help_page: MFA_HELP_PAGE },
+ { mfa_help_page: mfa_help_page_url },
status: :unauthorized
)
else
@@ -84,6 +77,13 @@ module EnforcesTwoFactorAuthentication
def two_factor_verifier
@two_factor_verifier ||= Gitlab::Auth::TwoFactorAuthVerifier.new(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
+
+ def mfa_help_page_url
+ Rails.application.routes.url_helpers.help_page_url(
+ 'user/profile/account/two_factor_authentication.html',
+ anchor: 'enable-two-factor-authentication'
+ )
+ end
end
EnforcesTwoFactorAuthentication.prepend_mod_with('EnforcesTwoFactorAuthentication')
diff --git a/app/controllers/concerns/impersonation.rb b/app/controllers/concerns/impersonation.rb
index 539dd9ad69d..e562cf5dbe4 100644
--- a/app/controllers/concerns/impersonation.rb
+++ b/app/controllers/concerns/impersonation.rb
@@ -3,11 +3,11 @@
module Impersonation
include Gitlab::Utils::StrongMemoize
- SESSION_KEYS_TO_DELETE = %w(
+ SESSION_KEYS_TO_DELETE = %w[
github_access_token gitea_access_token gitlab_access_token
bitbucket_token bitbucket_refresh_token bitbucket_server_personal_access_token
bulk_import_gitlab_access_token fogbugz_token
- ).freeze
+ ].freeze
def current_user
user = super
diff --git a/app/controllers/concerns/import/github_oauth.rb b/app/controllers/concerns/import/github_oauth.rb
index d53022aabf2..c233f5d09fa 100644
--- a/app/controllers/concerns/import/github_oauth.rb
+++ b/app/controllers/concerns/import/github_oauth.rb
@@ -53,6 +53,7 @@ module Import
def authorize_url
state = SecureRandom.base64(64)
session[auth_state_key] = state
+ session[:auth_on_failure_path] = "#{new_project_path}#import_project"
if Feature.enabled?(:remove_legacy_github_client)
oauth_client.auth_code.authorize_url(
redirect_uri: callback_import_url,
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 30de4a86bec..74d998503b7 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -88,7 +88,9 @@ module Integrations
param_values = return_value[:integration]
if param_values.is_a?(ActionController::Parameters)
- if action_name == 'update' && integration.chat? && param_values['webhook'] == BaseChatNotification::SECRET_MASK
+ if %w[update test].include?(action_name) && integration.chat? &&
+ param_values['webhook'] == BaseChatNotification::SECRET_MASK
+
param_values.delete('webhook')
end
diff --git a/app/controllers/concerns/invisible_captcha_on_signup.rb b/app/controllers/concerns/invisible_captcha_on_signup.rb
index c7fd6d08744..b78869e02d0 100644
--- a/app/controllers/concerns/invisible_captcha_on_signup.rb
+++ b/app/controllers/concerns/invisible_captcha_on_signup.rb
@@ -13,7 +13,7 @@ module InvisibleCaptchaOnSignup
invisible_captcha_honeypot_counter.increment
log_request('Invisible_Captcha_Honeypot_Request')
- head(200)
+ head(:ok)
end
def on_timestamp_spam_callback
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index bea184e44b9..0669f051457 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -146,13 +146,17 @@ module IssuableActions
finder = Issuable::DiscussionsListService.new(current_user, issuable, finder_params_for_issuable)
discussion_notes = finder.execute
- response.headers['X-Next-Page-Cursor'] = finder.paginator.cursor_for_next_page if finder.paginator.present? && finder.paginator.has_next_page?
+ if finder.paginator.present? && finder.paginator.has_next_page?
+ response.headers['X-Next-Page-Cursor'] = finder.paginator.cursor_for_next_page
+ end
case issuable
when MergeRequest
render_mr_discussions(discussion_notes, discussion_serializer, discussion_cache_context)
when Issue
- render json: discussion_serializer.represent(discussion_notes, context: self) if stale?(etag: [discussion_cache_context, discussion_notes])
+ if stale?(etag: [discussion_cache_context, discussion_notes])
+ render json: discussion_serializer.represent(discussion_notes, context: self)
+ end
else
render json: discussion_serializer.represent(discussion_notes, context: self)
end
@@ -173,7 +177,7 @@ module IssuableActions
def render_cached_discussions(discussions, serializer, cache_context)
render_cached(discussions,
with: serializer,
- cache_context: -> (_) { cache_context },
+ cache_context: ->(_) { cache_context },
context: self)
end
@@ -230,15 +234,11 @@ module IssuableActions
end
def authorize_destroy_issuable!
- unless can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable)
- access_denied!
- end
+ access_denied! unless can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable)
end
def authorize_admin_issuable!
- unless can?(current_user, :"admin_#{resource_name}", parent)
- access_denied!
- end
+ access_denied! unless can?(current_user, :"admin_#{resource_name}", parent)
end
def authorize_update_issuable!
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index de38d26e3fe..7b0d8cf8dcb 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -14,7 +14,9 @@ module IssuableCollections
private
def show_alert_if_search_is_disabled
- return if current_user || params[:search].blank? || !html_request? || Feature.disabled?(:disable_anonymous_search, type: :ops)
+ if current_user || params[:search].blank? || !html_request? || Feature.disabled?(:disable_anonymous_search, type: :ops)
+ return
+ end
flash.now[:notice] = _('You must sign in to search for specific terms.')
end
diff --git a/app/controllers/concerns/issues_calendar.rb b/app/controllers/concerns/issues_calendar.rb
index 51d6d3cf05a..692ac5e700b 100644
--- a/app/controllers/concerns/issues_calendar.rb
+++ b/app/controllers/concerns/issues_calendar.rb
@@ -16,9 +16,7 @@ module IssuesCalendar
# the content as a file (even ignoring the Content-Disposition
# header). We want to display the content inline when accessed
# from GitLab, similarly to the RSS feed.
- if request.referer&.start_with?(::Settings.gitlab.base_url)
- response.headers['Content-Type'] = 'text/plain'
- end
+ response.headers['Content-Type'] = 'text/plain' if request.referer&.start_with?(::Settings.gitlab.base_url)
end
end
end
diff --git a/app/controllers/concerns/labels_as_hash.rb b/app/controllers/concerns/labels_as_hash.rb
index e428520f709..601d3bf50eb 100644
--- a/app/controllers/concerns/labels_as_hash.rb
+++ b/app/controllers/concerns/labels_as_hash.rb
@@ -16,9 +16,7 @@ module LabelsAsHash
if already_set_labels.present?
titles = already_set_labels.map(&:title)
label_hashes.each do |hash|
- if titles.include?(hash['title'])
- hash[:set] = true
- end
+ hash[:set] = true if titles.include?(hash['title'])
end
end
end
diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb
index 97df3c7caea..1653b40bad5 100644
--- a/app/controllers/concerns/lfs_request.rb
+++ b/app/controllers/concerns/lfs_request.rb
@@ -78,25 +78,27 @@ module LfsRequest
end
def lfs_download_access?
- strong_memoize(:lfs_download_access) do
- ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code? || deploy_token_can_download_code?
- end
+ ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code? || deploy_token_can_download_code?
end
+ strong_memoize_attr :lfs_download_access?, :lfs_download_access
def deploy_token_can_download_code?
deploy_token.present? &&
- deploy_token.project == project &&
- deploy_token.active? &&
+ deploy_token.has_access_to?(project) &&
deploy_token.read_repository?
end
def lfs_upload_access?
- strong_memoize(:lfs_upload_access) do
- next false unless has_authentication_ability?(:push_code)
- next false if limit_exceeded?
+ return false unless has_authentication_ability?(:push_code)
+ return false if limit_exceeded?
- lfs_deploy_token? || can?(user, :push_code, project) || can?(deploy_token, :push_code, project)
- end
+ lfs_deploy_token? || can?(user, :push_code,
+project) || can?(deploy_token, :push_code, project) || any_branch_allows_collaboration?
+ end
+ strong_memoize_attr :lfs_upload_access?, :lfs_upload_access
+
+ def any_branch_allows_collaboration?
+ project.merge_requests_allowing_push_to_user(user).any?
end
def lfs_deploy_token?
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 8a67b62f28b..28d0af7a118 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -40,17 +40,15 @@ module MembershipActions
respond_to do |format|
format.html do
message =
- begin
- case membershipable
- when Namespace
- if skip_subresources
- _("User was successfully removed from group.")
- else
- _("User was successfully removed from group and any subgroups and projects.")
- end
+ case membershipable
+ when Namespace
+ if skip_subresources
+ _("User was successfully removed from group.")
else
- _("User was successfully removed from project.")
+ _("User was successfully removed from group and any subgroups and projects.")
end
+ else
+ _("User was successfully removed from project.")
end
redirect_to members_page_url, notice: message
diff --git a/app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb b/app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb
index 65237b552ca..ea9fd2de961 100644
--- a/app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb
+++ b/app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb
@@ -12,9 +12,7 @@ module Metrics::Dashboard::PrometheusApiProxy
variable_substitution_result =
proxy_variable_substitution_service.new(proxyable, permit_params).execute
- if variable_substitution_result[:status] == :error
- return error_response(variable_substitution_result)
- end
+ return error_response(variable_substitution_result) if variable_substitution_result[:status] == :error
prometheus_result = ::Prometheus::ProxyService.new(
proxyable,
diff --git a/app/controllers/concerns/metrics_dashboard.rb b/app/controllers/concerns/metrics_dashboard.rb
index 28d0692d748..d4e8e95e016 100644
--- a/app/controllers/concerns/metrics_dashboard.rb
+++ b/app/controllers/concerns/metrics_dashboard.rb
@@ -118,9 +118,7 @@ module MetricsDashboard
def decoded_params
params = metrics_dashboard_params
- if params[:dashboard_path]
- params[:dashboard_path] = CGI.unescape(params[:dashboard_path])
- end
+ params[:dashboard_path] = CGI.unescape(params[:dashboard_path]) if params[:dashboard_path]
params
end
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index 0a859bd3af9..e1967c50d70 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -8,9 +8,9 @@ module MilestoneActions
format.html { redirect_to milestone_redirect_path }
format.json do
render json: tabs_json("shared/milestones/_issues_tab", {
- issues: @milestone.sorted_issues(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables
- show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
- })
+ issues: @milestone.sorted_issues(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
+ })
end
end
end
@@ -20,9 +20,9 @@ module MilestoneActions
format.html { redirect_to milestone_redirect_path }
format.json do
render json: tabs_json("shared/milestones/_merge_requests_tab", {
- merge_requests: @milestone.sorted_merge_requests(current_user).preload_milestoneish_associations, # rubocop:disable Gitlab/ModuleWithInstanceVariables
- show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
- })
+ merge_requests: @milestone.sorted_merge_requests(current_user).preload_milestoneish_associations, # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
+ })
end
end
end
@@ -32,8 +32,8 @@ module MilestoneActions
format.html { redirect_to milestone_redirect_path }
format.json do
render json: tabs_json("shared/milestones/_participants_tab", {
- users: @milestone.issue_participants_visible_by_user(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
- })
+ users: @milestone.issue_participants_visible_by_user(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ })
end
end
end
@@ -46,10 +46,10 @@ module MilestoneActions
milestone_labels = @milestone.issue_labels_visible_by_user(current_user)
render json: tabs_json("shared/milestones/_labels_tab", {
- labels: milestone_labels.map do |label|
- label.present(issuable_subject: @milestone.resource_parent)
- end
- })
+ labels: milestone_labels.map do |label|
+ label.present(issuable_subject: @milestone.resource_parent)
+ end
+ })
end
end
end
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index b595c3c6790..a41e2d840ac 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -89,9 +89,7 @@ module NotesActions
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def destroy
- if note.editable?
- Notes::DestroyService.new(project, current_user).execute(note)
- end
+ Notes::DestroyService.new(project, current_user).execute(note) if note.editable?
respond_to do |format|
format.js { head :ok }
@@ -258,15 +256,14 @@ module NotesActions
end
def last_fetched_at
- strong_memoize(:last_fetched_at) do
- microseconds = request.headers['X-Last-Fetched-At'].to_i
+ microseconds = request.headers['X-Last-Fetched-At'].to_i
- seconds = microseconds / MICROSECOND
- frac = microseconds % MICROSECOND
+ seconds = microseconds / MICROSECOND
+ frac = microseconds % MICROSECOND
- Time.zone.at(seconds, frac)
- end
+ Time.zone.at(seconds, frac)
end
+ strong_memoize_attr :last_fetched_at
def notes_filter
current_user&.notes_filter_for(params[:target_type])
@@ -285,23 +282,22 @@ module NotesActions
end
def note_project
- strong_memoize(:note_project) do
- next nil unless project
+ return unless project
- note_project_id = params[:note_project_id]
+ note_project_id = params[:note_project_id]
- the_project =
- if note_project_id.present?
- Project.find(note_project_id)
- else
- project
- end
+ the_project =
+ if note_project_id.present?
+ Project.find(note_project_id)
+ else
+ project
+ end
- next access_denied! unless can?(current_user, :create_note, the_project)
+ return access_denied! unless can?(current_user, :create_note, the_project)
- the_project
- end
+ the_project
end
+ strong_memoize_attr :note_project
def return_discussion?
Gitlab::Utils.to_boolean(params[:return_discussion])
diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb
index 8e63cc391ff..5b6fe933fda 100644
--- a/app/controllers/concerns/oauth_applications.rb
+++ b/app/controllers/concerns/oauth_applications.rb
@@ -12,9 +12,7 @@ module OauthApplications
def prepare_scopes
scopes = params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
- if scopes
- params[:doorkeeper_application][:scopes] = scopes.join(' ')
- end
+ params[:doorkeeper_application][:scopes] = scopes.join(' ') if scopes
end
def set_created_session
@@ -30,7 +28,7 @@ module OauthApplications
end
def permitted_params
- %i{name redirect_uri scopes confidential}
+ %i[name redirect_uri scopes confidential]
end
def application_params
diff --git a/app/controllers/concerns/observability/content_security_policy.rb b/app/controllers/concerns/observability/content_security_policy.rb
new file mode 100644
index 00000000000..eccd1e1e3ef
--- /dev/null
+++ b/app/controllers/concerns/observability/content_security_policy.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Observability
+ module ContentSecurityPolicy
+ extend ActiveSupport::Concern
+
+ included do
+ content_security_policy do |p|
+ next if p.directives.blank? || Gitlab::Observability.observability_url.blank?
+
+ default_frame_src = p.directives['frame-src'] || p.directives['default-src']
+
+ # When ObservabilityUI is not authenticated, it needs to be able
+ # to redirect to the GL sign-in page, hence '/users/sign_in' and '/oauth/authorize'
+ frame_src_values = Array.wrap(default_frame_src) | [Gitlab::Observability.observability_url,
+ Gitlab::Utils.append_path(Gitlab.config.gitlab.url,
+'/users/sign_in'),
+ Gitlab::Utils.append_path(Gitlab.config.gitlab.url,
+'/oauth/authorize')]
+
+ p.frame_src(*frame_src_values)
+ end
+ end
+ end
+end
diff --git a/app/controllers/concerns/page_limiter.rb b/app/controllers/concerns/page_limiter.rb
index 362b02e5856..1d044a41899 100644
--- a/app/controllers/concerns/page_limiter.rb
+++ b/app/controllers/concerns/page_limiter.rb
@@ -44,10 +44,11 @@ module PageLimiter
raise PageLimitNotANumberError unless max_page_number.is_a?(Integer)
raise PageLimitNotSensibleError unless max_page_number > 0
- if params[:page].present? && params[:page].to_i > max_page_number
- record_page_limit_interception
- raise PageOutOfBoundsError, max_page_number
- end
+ return if params[:page].blank?
+ return if params[:page].to_i <= max_page_number
+
+ record_page_limit_interception
+ raise PageOutOfBoundsError, max_page_number
end
# By default just return a HTTP status code and an empty response
diff --git a/app/controllers/concerns/paginated_collection.rb b/app/controllers/concerns/paginated_collection.rb
index fcee4493314..94a52dd0f89 100644
--- a/app/controllers/concerns/paginated_collection.rb
+++ b/app/controllers/concerns/paginated_collection.rb
@@ -10,9 +10,7 @@ module PaginatedCollection
out_of_range = collection.current_page > total_pages
- if out_of_range
- redirect_to(url_for(safe_params.merge(page: total_pages, only_path: true)))
- end
+ redirect_to(url_for(safe_params.merge(page: total_pages, only_path: true))) if out_of_range
out_of_range
end
diff --git a/app/controllers/concerns/preferred_language_switcher.rb b/app/controllers/concerns/preferred_language_switcher.rb
index 9711e57cf7a..00cd0f9d1d5 100644
--- a/app/controllers/concerns/preferred_language_switcher.rb
+++ b/app/controllers/concerns/preferred_language_switcher.rb
@@ -16,3 +16,5 @@ module PreferredLanguageSwitcher
Gitlab::CurrentSettings.default_preferred_language
end
end
+
+PreferredLanguageSwitcher.prepend_mod
diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb
index 7af114313a1..a7655efe7a9 100644
--- a/app/controllers/concerns/preview_markdown.rb
+++ b/app/controllers/concerns/preview_markdown.rb
@@ -45,7 +45,13 @@ module PreviewMarkdown
when 'projects' then projects_filter_params
when 'timeline_events' then timeline_events_filter_params
else {}
- end.merge(requested_path: params[:path], ref: params[:ref])
+ end.merge(
+ requested_path: params[:path],
+ ref: params[:ref],
+ # Disable comments in markdown for IE browsers because comments in IE
+ # could allow script execution.
+ allow_comments: !browser.ie?
+ )
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
index dfa159ccfd7..b01320ce3ec 100644
--- a/app/controllers/concerns/product_analytics_tracking.rb
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -16,7 +16,7 @@ module ProductAnalyticsTracking
end
end
- def track_custom_event(*controller_actions, name:, conditions: nil, action:, label:, destinations: [:redis_hll], &block)
+ def track_custom_event(*controller_actions, name:, action:, label:, conditions: nil, destinations: [:redis_hll], &block)
custom_conditions = [:trackable_html_request?, *conditions]
after_action only: controller_actions, if: custom_conditions do
@@ -30,15 +30,15 @@ module ProductAnalyticsTracking
def route_events_to(destinations, name, &block)
track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll)
- if destinations.include?(:snowplow) && event_enabled?(name)
- Gitlab::Tracking.event(
- self.class.to_s,
- name,
- namespace: tracking_namespace_source,
- user: current_user,
- context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context]
- )
- end
+ return unless destinations.include?(:snowplow) && event_enabled?(name)
+
+ Gitlab::Tracking.event(
+ self.class.to_s,
+ name,
+ namespace: tracking_namespace_source,
+ user: current_user,
+ context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context]
+ )
end
def route_custom_events_to(destinations, name, action, label, &block)
@@ -64,30 +64,32 @@ module ProductAnalyticsTracking
def event_enabled?(event)
events_to_ff = {
- g_analytics_valuestream: :route_hll_to_snowplow,
-
- i_search_paid: :route_hll_to_snowplow_phase2,
- i_search_total: :route_hll_to_snowplow_phase2,
- i_search_advanced: :route_hll_to_snowplow_phase2,
- i_ecosystem_jira_service_list_issues: :route_hll_to_snowplow_phase2,
- users_viewing_analytics_group_devops_adoption: :route_hll_to_snowplow_phase2,
- i_analytics_dev_ops_adoption: :route_hll_to_snowplow_phase2,
- i_analytics_dev_ops_score: :route_hll_to_snowplow_phase2,
- p_analytics_merge_request: :route_hll_to_snowplow_phase2,
- i_analytics_instance_statistics: :route_hll_to_snowplow_phase2,
- g_analytics_contribution: :route_hll_to_snowplow_phase2,
- p_analytics_pipelines: :route_hll_to_snowplow_phase2,
- p_analytics_code_reviews: :route_hll_to_snowplow_phase2,
- p_analytics_valuestream: :route_hll_to_snowplow_phase2,
- p_analytics_insights: :route_hll_to_snowplow_phase2,
- p_analytics_issues: :route_hll_to_snowplow_phase2,
- p_analytics_repo: :route_hll_to_snowplow_phase2,
- g_analytics_insights: :route_hll_to_snowplow_phase2,
- g_analytics_issues: :route_hll_to_snowplow_phase2,
- g_analytics_productivity: :route_hll_to_snowplow_phase2,
- i_analytics_cohorts: :route_hll_to_snowplow_phase2
+ g_analytics_valuestream: '',
+
+ i_search_paid: :_phase2,
+ i_search_total: :_phase2,
+ i_search_advanced: :_phase2,
+ i_ecosystem_jira_service_list_issues: :_phase2,
+ users_viewing_analytics_group_devops_adoption: :_phase2,
+ i_analytics_dev_ops_adoption: :_phase2,
+ i_analytics_dev_ops_score: :_phase2,
+ p_analytics_merge_request: :_phase2,
+ i_analytics_instance_statistics: :_phase2,
+ g_analytics_contribution: :_phase2,
+ p_analytics_pipelines: :_phase2,
+ p_analytics_code_reviews: :_phase2,
+ p_analytics_valuestream: :_phase2,
+ p_analytics_insights: :_phase2,
+ p_analytics_issues: :_phase2,
+ p_analytics_repo: :_phase2,
+ g_analytics_insights: :_phase2,
+ g_analytics_issues: :_phase2,
+ g_analytics_productivity: :_phase2,
+ i_analytics_cohorts: :_phase2,
+
+ g_compliance_dashboard: :_phase4
}
- Feature.enabled?(events_to_ff[event.to_sym], tracking_namespace_source)
+ Feature.enabled?("route_hll_to_snowplow#{events_to_ff[event.to_sym]}", tracking_namespace_source)
end
end
diff --git a/app/controllers/concerns/record_user_last_activity.rb b/app/controllers/concerns/record_user_last_activity.rb
index 29164df4516..6ac87d8f27b 100644
--- a/app/controllers/concerns/record_user_last_activity.rb
+++ b/app/controllers/concerns/record_user_last_activity.rb
@@ -18,9 +18,8 @@ module RecordUserLastActivity
def set_user_last_activity
return unless request.get?
return if Gitlab::Database.read_only?
+ return unless current_user && current_user.last_activity_on != Date.today
- if current_user && current_user.last_activity_on != Date.today
- Users::ActivityService.new(current_user).execute
- end
+ Users::ActivityService.new(current_user).execute
end
end
diff --git a/app/controllers/concerns/render_service_results.rb b/app/controllers/concerns/render_service_results.rb
index 0149a71d9f5..83b880096be 100644
--- a/app/controllers/concerns/render_service_results.rb
+++ b/app/controllers/concerns/render_service_results.rb
@@ -5,25 +5,25 @@ module RenderServiceResults
def success_response(result)
render({
- status: result[:http_status],
- json: result[:body]
- })
+ status: result[:http_status],
+ json: result[:body]
+ })
end
def continue_polling_response
render({
- status: :no_content,
- json: {
- status: _('processing'),
- message: _('Not ready yet. Try again later.')
- }
- })
+ status: :no_content,
+ json: {
+ status: _('processing'),
+ message: _('Not ready yet. Try again later.')
+ }
+ })
end
def error_response(result)
render({
- status: result[:http_status] || :bad_request,
- json: { status: result[:status], message: result[:message] }
- })
+ status: result[:http_status] || :bad_request,
+ json: { status: result[:status], message: result[:message] }
+ })
end
end
diff --git a/app/controllers/concerns/renders_ldap_servers.rb b/app/controllers/concerns/renders_ldap_servers.rb
index cc83ff47048..8c3d9fd4d5c 100644
--- a/app/controllers/concerns/renders_ldap_servers.rb
+++ b/app/controllers/concerns/renders_ldap_servers.rb
@@ -8,12 +8,10 @@ module RendersLdapServers
end
def ldap_servers
- @ldap_servers ||= begin
- if Gitlab::Auth::Ldap::Config.sign_in_enabled?
- Gitlab::Auth::Ldap::Config.available_servers
- else
- []
- end
- end
+ @ldap_servers ||= if Gitlab::Auth::Ldap::Config.sign_in_enabled?
+ Gitlab::Auth::Ldap::Config.available_servers
+ else
+ []
+ end
end
end
diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb
index e34d6b09c24..28e1fa473b3 100644
--- a/app/controllers/concerns/routable_actions.rb
+++ b/app/controllers/concerns/routable_actions.rb
@@ -46,13 +46,13 @@ module RoutableActions
return unless request.get?
canonical_path = routable.full_path
- if canonical_path != routable_full_path
- if !request.xhr? && request.format.html? && canonical_path.casecmp(routable_full_path) != 0
- flash[:notice] = "#{routable.class.to_s.titleize} '#{routable_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
- end
+ return unless canonical_path != routable_full_path
- redirect_to build_canonical_path(routable), status: :moved_permanently
+ if !request.xhr? && request.format.html? && canonical_path.casecmp(routable_full_path) != 0
+ flash[:notice] = "#{routable.class.to_s.titleize} '#{routable_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
end
+
+ redirect_to build_canonical_path(routable), status: :moved_permanently
end
end
diff --git a/app/controllers/concerns/snippets/blobs_actions.rb b/app/controllers/concerns/snippets/blobs_actions.rb
index b510594ad63..2a0491b4df8 100644
--- a/app/controllers/concerns/snippets/blobs_actions.rb
+++ b/app/controllers/concerns/snippets/blobs_actions.rb
@@ -25,14 +25,13 @@ module Snippets::BlobsActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def blob
- strong_memoize(:blob) do
- assign_ref_vars
+ assign_ref_vars
- next unless @commit
+ return unless @commit
- @repo.blob_at(@commit.id, @path)
- end
+ @repo.blob_at(@commit.id, @path)
end
+ strong_memoize_attr :blob
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def ensure_blob
@@ -40,11 +39,11 @@ module Snippets::BlobsActions
end
def ensure_repository
- unless snippet.repo_exists?
- Gitlab::AppLogger.error(message: "Snippet raw blob attempt with no repo", snippet: snippet.id)
+ return if snippet.repo_exists?
- respond_422
- end
+ Gitlab::AppLogger.error(message: "Snippet raw blob attempt with no repo", snippet: snippet.id)
+
+ respond_422
end
def snippet_id
diff --git a/app/controllers/concerns/sorting_preference.rb b/app/controllers/concerns/sorting_preference.rb
index 6278b489028..300c1d6d779 100644
--- a/app/controllers/concerns/sorting_preference.rb
+++ b/app/controllers/concerns/sorting_preference.rb
@@ -45,9 +45,7 @@ module SortingPreference
return sort_param if Gitlab::Database.read_only?
- if user_preference[field] != sort_param
- user_preference.update(field => sort_param)
- end
+ user_preference.update(field => sort_param) if user_preference[field] != sort_param
sort_param
end
diff --git a/app/controllers/concerns/sourcegraph_decorator.rb b/app/controllers/concerns/sourcegraph_decorator.rb
index 061990a4361..4aeace1ca67 100644
--- a/app/controllers/concerns/sourcegraph_decorator.rb
+++ b/app/controllers/concerns/sourcegraph_decorator.rb
@@ -22,8 +22,8 @@ module SourcegraphDecorator
return unless sourcegraph_enabled?
gon.push({
- sourcegraph: { url: Gitlab::CurrentSettings.sourcegraph_url }
- })
+ sourcegraph: { url: Gitlab::CurrentSettings.sourcegraph_url }
+ })
end
def sourcegraph_enabled?
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index e98d36854f1..0ba13896631 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -5,7 +5,7 @@ module UploadsActions
include Gitlab::Utils::StrongMemoize
include SendFileUpload
- UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze
+ UPLOAD_MOUNTS = %w[avatar attachment file logo header_logo favicon].freeze
included do
prepend_before_action :set_request_format_from_path_extension
@@ -73,11 +73,11 @@ module UploadsActions
def set_request_format_from_path_extension
path = request.headers['action_dispatch.original_path'] || request.headers['PATH_INFO']
- if match = path&.match(/\.(\w+)\z/)
- format = Mime[match.captures.first]
+ return unless match = path&.match(/\.(\w+)\z/)
- request.format = format.symbol if format
- end
+ format = Mime[match.captures.first]
+
+ request.format = format.symbol if format
end
def content_disposition
@@ -102,14 +102,13 @@ module UploadsActions
end
def uploader
- strong_memoize(:uploader) do
- if uploader_mounted?
- model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
- else
- build_uploader_from_upload || build_uploader_from_params
- end
+ if uploader_mounted?
+ model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
+ else
+ build_uploader_from_upload || build_uploader_from_params
end
end
+ strong_memoize_attr :uploader
# rubocop: disable CodeReuse/ActiveRecord
def build_uploader_from_upload
@@ -163,8 +162,9 @@ module UploadsActions
end
def model
- strong_memoize(:model) { find_model }
+ find_model
end
+ strong_memoize_attr :model
def workhorse_authorize_request?
action_name == 'authorize'
diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb
index ac1475597ff..3cada24a81a 100644
--- a/app/controllers/concerns/verifies_with_email.rb
+++ b/app/controllers/concerns/verifies_with_email.rb
@@ -28,7 +28,7 @@ module VerifiesWithEmail
if user.unlock_token
# Prompt for the token if it already has been set
prompt_for_email_verification(user)
- elsif user.access_locked? || !AuthenticationEvent.initial_login_or_known_ip_address?(user, request.ip)
+ elsif user.access_locked? || !trusted_ip_address?(user)
# require email verification if:
# - their account has been locked because of too many failed login attempts, or
# - they have logged in before, but never from the current ip address
@@ -68,7 +68,7 @@ module VerifiesWithEmail
# After successful verification and calling sign_in, devise redirects the
# user to this path. Override it to show the successful verified page.
def after_sign_in_path_for(resource)
- if action_name == 'create' && session[:verification_user_id]
+ if action_name == 'create' && session[:verification_user_id] == resource.id
return users_successful_verification_path
end
@@ -133,6 +133,12 @@ module VerifiesWithEmail
sign_in(user)
end
+ def trusted_ip_address?(user)
+ return true if Feature.disabled?(:check_ip_address_for_email_verification)
+
+ AuthenticationEvent.initial_login_or_known_ip_address?(user, request.ip)
+ end
+
def prompt_for_email_verification(user)
session[:verification_user_id] = user.id
self.resource = user
diff --git a/app/controllers/concerns/vscode_cdn_csp.rb b/app/controllers/concerns/vscode_cdn_csp.rb
new file mode 100644
index 00000000000..dc8cea966e5
--- /dev/null
+++ b/app/controllers/concerns/vscode_cdn_csp.rb
@@ -0,0 +1,17 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+module VSCodeCDNCSP
+ extend ActiveSupport::Concern
+
+ included do
+ content_security_policy do |policy|
+ next if policy.directives.blank?
+
+ default_src = Array(policy.directives['default-src'] || [])
+ policy.directives['frame-src'] ||= default_src
+ policy.directives['frame-src'].concat(['https://*.vscode-cdn.net/'])
+ end
+ end
+end
+# rubocop:enable Naming/FileName
diff --git a/app/controllers/concerns/web_hooks/hook_actions.rb b/app/controllers/concerns/web_hooks/hook_actions.rb
index 75065ef9d24..f61600af951 100644
--- a/app/controllers/concerns/web_hooks/hook_actions.rb
+++ b/app/controllers/concerns/web_hooks/hook_actions.rb
@@ -18,7 +18,9 @@ module WebHooks
self.hook = relation.new(hook_params)
hook.save
- unless hook.valid?
+ if hook.valid?
+ flash[:notice] = _('Webhook was created')
+ else
self.hooks = relation.select(&:persisted?)
flash[:alert] = hook.errors.full_messages.to_sentence.html_safe
end
@@ -28,8 +30,8 @@ module WebHooks
def update
if hook.update(hook_params)
- flash[:notice] = _('Hook was successfully updated.')
- redirect_to action: :index
+ flash[:notice] = _('Webhook was updated')
+ redirect_to action: :edit
else
render 'edit'
end
@@ -66,21 +68,14 @@ module WebHooks
end
def hook_param_names
- param_names = %i[enable_ssl_verification token url push_events_branch_filter]
- param_names.push(:branch_filter_strategy) if Feature.enabled?(:enhanced_webhook_support_regex)
- param_names
+ %i[enable_ssl_verification token url push_events_branch_filter branch_filter_strategy]
end
def destroy_hook(hook)
result = WebHooks::DestroyService.new(current_user).execute(hook)
if result[:status] == :success
- flash[:notice] =
- if result[:async]
- format(_("%{hook_type} was scheduled for deletion"), hook_type: hook.model_name.human)
- else
- format(_("%{hook_type} was deleted"), hook_type: hook.model_name.human)
- end
+ flash[:notice] = result[:async] ? _('Webhook was scheduled for deletion') : _('Webhook was deleted')
else
flash[:alert] = result[:message]
end
diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb
index 5a885349467..d72a5e44b9f 100644
--- a/app/controllers/dashboard/snippets_controller.rb
+++ b/app/controllers/dashboard/snippets_controller.rb
@@ -7,7 +7,7 @@ class Dashboard::SnippetsController < Dashboard::ApplicationController
skip_cross_project_access_check :index
- feature_category :snippets
+ feature_category :source_code_management
def index
@snippet_counts = Snippets::CountService
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index d2434d4b0ba..3005d19f8ed 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -3,6 +3,7 @@
class Dashboard::TodosController < Dashboard::ApplicationController
include ActionView::Helpers::NumberHelper
include PaginatedCollection
+ include Gitlab::Utils::StrongMemoize
before_action :authorize_read_project!, only: :index
before_action :authorize_read_group!, only: :index
@@ -64,19 +65,19 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def authorize_read_project!
project_id = params[:project_id]
- if project_id.present?
- project = Project.find(project_id)
- render_404 unless can?(current_user, :read_project, project)
- end
+ return unless project_id.present?
+
+ project = Project.find(project_id)
+ render_404 unless can?(current_user, :read_project, project)
end
def authorize_read_group!
group_id = params[:group_id]
- if group_id.present?
- group = Group.find(group_id)
- render_404 unless can?(current_user, :read_group, group)
- end
+ return unless group_id.present?
+
+ group = Group.find(group_id)
+ render_404 unless can?(current_user, :read_group, group)
end
def find_todos
@@ -99,14 +100,28 @@ class Dashboard::TodosController < Dashboard::ApplicationController
end
def todo_params
- aliased_action_id(
+ aliased_params(
params.permit(:action_id, :author_id, :project_id, :type, :sort, :state, :group_id)
)
end
+ strong_memoize_attr :todo_params
+
+ def aliased_params(original_params)
+ alias_issue_type(original_params)
+ alias_action_id(original_params)
+
+ original_params
+ end
+
+ def alias_issue_type(original_params)
+ return unless original_params[:type] == Issue.name
+
+ original_params[:type] = [Issue.name, WorkItem.name]
+ end
- def aliased_action_id(original_params)
- return original_params unless original_params[:action_id].to_i == ::Todo::MENTIONED
+ def alias_action_id(original_params)
+ return unless original_params[:action_id].to_i == ::Todo::MENTIONED
- original_params.merge(action_id: [::Todo::MENTIONED, ::Todo::DIRECTLY_ADDRESSED])
+ original_params[:action_id] = [::Todo::MENTIONED, ::Todo::DIRECTLY_ADDRESSED]
end
end
diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb
index 617cc2e7f3d..dee94b53cc1 100644
--- a/app/controllers/explore/snippets_controller.rb
+++ b/app/controllers/explore/snippets_controller.rb
@@ -3,7 +3,7 @@
class Explore::SnippetsController < Explore::ApplicationController
include Gitlab::NoteableMetadata
- feature_category :snippets
+ feature_category :source_code_management
def index
@snippets = SnippetsFinder.new(current_user, explore: true)
diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb
index 5080ee5fbbe..536c5e347e7 100644
--- a/app/controllers/google_api/authorizations_controller.rb
+++ b/app/controllers/google_api/authorizations_controller.rb
@@ -48,14 +48,13 @@ module GoogleApi
end
def redirect_uri_from_session
- strong_memoize(:redirect_uri_from_session) do
- if params[:state].present?
- session[session_key_for_redirect_uri(params[:state])]
- else
- nil
- end
+ if params[:state].present?
+ session[session_key_for_redirect_uri(params[:state])]
+ else
+ nil
end
end
+ strong_memoize_attr :redirect_uri_from_session
def session_key_for_redirect_uri(state)
GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(state)
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 5ffd525c170..942cb9beed4 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -70,6 +70,12 @@ class GraphqlController < ApplicationController
end
end
+ rescue_from Gitlab::Auth::TooManyIps do |exception|
+ log_exception(exception)
+
+ render_error(exception.message, status: :forbidden)
+ end
+
rescue_from Gitlab::Graphql::Variables::Invalid do |exception|
render_error(exception.message, status: :unprocessable_entity)
end
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index f8cfa996447..5440908aee7 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -96,6 +96,28 @@ class Groups::ApplicationController < ApplicationController
def validate_root_group!
render_404 unless group.root?
end
+
+ def authorize_action!(action)
+ access_denied! unless can?(current_user, action, group)
+ end
+
+ def respond_to_missing?(method, *args)
+ case method.to_s
+ when /\Aauthorize_(.*)!\z/
+ true
+ else
+ super
+ end
+ end
+
+ def method_missing(method_sym, *arguments, &block)
+ case method_sym.to_s
+ when /\Aauthorize_(.*)!\z/
+ authorize_action!(Regexp.last_match(1).to_sym)
+ else
+ super
+ end
+ end
end
Groups::ApplicationController.prepend_mod_with('Groups::ApplicationController')
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index e1ba86220c7..6bb807be1c4 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -20,16 +20,14 @@ class Groups::BoardsController < Groups::ApplicationController
private
def board_finder
- strong_memoize :board_finder do
- Boards::BoardsFinder.new(parent, current_user, board_id: params[:id])
- end
+ Boards::BoardsFinder.new(parent, current_user, board_id: params[:id])
end
+ strong_memoize_attr :board_finder
def board_create_service
- strong_memoize :board_create_service do
- Boards::CreateService.new(parent, current_user)
- end
+ Boards::CreateService.new(parent, current_user)
end
+ strong_memoize_attr :board_create_service
def authorize_read_board!
access_denied! unless can?(current_user, :read_issue_board, group)
diff --git a/app/controllers/groups/dependency_proxy_for_containers_controller.rb b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
index 2e9e0b12d2f..427df9a7129 100644
--- a/app/controllers/groups/dependency_proxy_for_containers_controller.rb
+++ b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
@@ -117,7 +117,7 @@ class Groups::DependencyProxyForContainersController < ::Groups::DependencyProxy
end
def blob_file_name
- @blob_file_name ||= params[:sha].sub('sha256:', '') + '.gz'
+ @blob_file_name ||= "#{params[:sha].sub('sha256:', '')}.gz"
end
def manifest_file_name
diff --git a/app/controllers/groups/observability_controller.rb b/app/controllers/groups/observability_controller.rb
index 4b1f2b582ce..3baa5e830ff 100644
--- a/app/controllers/groups/observability_controller.rb
+++ b/app/controllers/groups/observability_controller.rb
@@ -1,18 +1,9 @@
# frozen_string_literal: true
module Groups
class ObservabilityController < Groups::ApplicationController
- feature_category :tracing
-
- content_security_policy do |p|
- next if p.directives.blank?
-
- default_frame_src = p.directives['frame-src'] || p.directives['default-src']
+ include ::Observability::ContentSecurityPolicy
- # When ObservabilityUI is not authenticated, it needs to be able to redirect to the GL sign-in page, hence 'self'
- frame_src_values = Array.wrap(default_frame_src) | [observability_url, "'self'"]
-
- p.frame_src(*frame_src_values)
- end
+ feature_category :tracing
before_action :check_observability_allowed
@@ -34,16 +25,8 @@ module Groups
render 'observability', layout: 'group', locals: { base_layout: 'layouts/fullscreen' }
end
- def self.observability_url
- Gitlab::Observability.observability_url
- end
-
- def observability_url
- self.class.observability_url
- end
-
def check_observability_allowed
- return render_404 unless observability_url.present?
+ return render_404 unless Gitlab::Observability.observability_url.present?
render_404 unless can?(current_user, :read_observability, @group)
end
diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb
index b1afac1f1c7..1dfa8cdf133 100644
--- a/app/controllers/groups/settings/ci_cd_controller.rb
+++ b/app/controllers/groups/settings/ci_cd_controller.rb
@@ -15,6 +15,8 @@ module Groups
urgency :low
def show
+ @entity = :group
+ @variable_limit = ::Plan.default.actual_limits.group_ci_variables
end
def update
diff --git a/app/controllers/groups/usage_quotas_controller.rb b/app/controllers/groups/usage_quotas_controller.rb
new file mode 100644
index 00000000000..29878f0001d
--- /dev/null
+++ b/app/controllers/groups/usage_quotas_controller.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Groups
+ class UsageQuotasController < Groups::ApplicationController
+ before_action :authorize_read_usage_quotas!
+ before_action :verify_usage_quotas_enabled!
+
+ feature_category :subscription_cost_management
+ urgency :low
+
+ def index
+ # To be used in ee/app/controllers/ee/groups/usage_quotas_controller.rb
+ @seat_count_data = seat_count_data
+ end
+
+ private
+
+ def verify_usage_quotas_enabled!
+ render_404 unless Feature.enabled?(:usage_quotas_for_all_editions, group)
+ render_404 if group.has_parent?
+ end
+
+ # To be overriden in ee/app/controllers/ee/groups/usage_quotas_controller.rb
+ def seat_count_data; end
+ end
+end
+
+Groups::UsageQuotasController.prepend_mod
diff --git a/app/controllers/groups/variables_controller.rb b/app/controllers/groups/variables_controller.rb
index 220b0b4509c..9ddf6c80c70 100644
--- a/app/controllers/groups/variables_controller.rb
+++ b/app/controllers/groups/variables_controller.rb
@@ -50,7 +50,7 @@ module Groups
end
def variable_params_attributes
- %i[id variable_type key secret_value protected masked _destroy]
+ %i[id variable_type key secret_value protected masked raw _destroy]
end
def authorize_admin_build!
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 3f516c24a69..0a487bb2508 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -386,7 +386,7 @@ class GroupsController < Groups::ApplicationController
override :has_project_list?
def has_project_list?
- %w(details show index).include?(action_name)
+ %w[details show index].include?(action_name)
end
def captcha_enabled?
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index fcf6871d137..8a8c41e65b9 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class IdeController < ApplicationController
+ include VSCodeCDNCSP
include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP
include Gitlab::Utils::StrongMemoize
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index 75193309a4e..1d05cee02d4 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -49,6 +49,14 @@ class Import::BitbucketController < Import::BaseController
namespace_path = params[:new_namespace].presence || repo_owner
target_namespace = find_or_create_namespace(namespace_path, current_user)
+ Gitlab::Tracking.event(
+ self.class.name,
+ 'create',
+ label: 'import_access_level',
+ user: current_user,
+ extra: { user_role: user_role(current_user, target_namespace), import_type: 'bitbucket' }
+ )
+
if current_user.can?(:create_projects, target_namespace)
# The token in a session can be expired, we need to get most recent one because
# Bitbucket::Connection class refreshes it.
@@ -89,6 +97,21 @@ class Import::BitbucketController < Import::BaseController
private
+ def user_role(user, namespace)
+ if current_user.id == namespace&.owner_id
+ Gitlab::Access.options_with_owner.key(Gitlab::Access::OWNER)
+ else
+ access_level = current_user&.group_members&.find_by(source_id: namespace&.id)&.access_level
+
+ case access_level
+ when nil
+ 'Not a member'
+ else
+ Gitlab::Access.human_access(access_level)
+ end
+ end
+ end
+
def oauth_client
@oauth_client ||= OAuth2::Client.new(provider.app_id, provider.app_secret, options)
end
diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb
index 655fc7854fe..9a7118ce498 100644
--- a/app/controllers/import/bulk_imports_controller.rb
+++ b/app/controllers/import/bulk_imports_controller.rb
@@ -135,7 +135,7 @@ class Import::BulkImportsController < ApplicationController
session[url_key],
allow_localhost: allow_local_requests?,
allow_local_network: allow_local_requests?,
- schemes: %w(http https)
+ schemes: %w[http https]
)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
clear_session_data
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index 7b580234227..77043e174b4 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -114,7 +114,7 @@ class Import::FogbugzController < Import::BaseController
end
def user_map_params
- params.permit(users: %w(name email gitlab_user))
+ params.permit(users: %w[name email gitlab_user])
end
def verify_fogbugz_import_enabled
@@ -126,7 +126,7 @@ class Import::FogbugzController < Import::BaseController
params[:uri],
allow_localhost: allow_local_requests?,
allow_local_network: allow_local_requests?,
- schemes: %w(http https)
+ schemes: %w[http https]
)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
redirect_to new_import_fogbugz_url, alert: _('Specified URL cannot be used: "%{reason}"') % { reason: e.message }
diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb
index 4b4ac07b389..61e32650db3 100644
--- a/app/controllers/import/gitea_controller.rb
+++ b/app/controllers/import/gitea_controller.rb
@@ -16,12 +16,27 @@ class Import::GiteaController < Import::GithubController
super
end
- # We need to re-expose controller's internal method 'status' as action.
- # rubocop:disable Lint/UselessMethodDefinition
def status
- super
+ # Request repos to display error page if provider token is invalid
+ # Improving in https://gitlab.com/gitlab-org/gitlab/-/issues/25859
+ client_repos
+
+ respond_to do |format|
+ format.json do
+ render json: { imported_projects: serialized_imported_projects,
+ provider_repos: serialized_provider_repos,
+ incompatible_repos: serialized_incompatible_repos }
+ end
+
+ format.html do
+ if params[:namespace_id].present?
+ @namespace = Namespace.find_by_id(params[:namespace_id])
+
+ render_404 unless current_user.can?(:create_projects, @namespace)
+ end
+ end
+ end
end
- # rubocop:enable Lint/UselessMethodDefinition
protected
@@ -61,7 +76,6 @@ class Import::GiteaController < Import::GithubController
@client_repos ||= filtered(client.repos)
end
- override :client
def client
@client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], **client_options)
end
@@ -78,7 +92,7 @@ class Import::GiteaController < Import::GithubController
provider_url,
allow_localhost: allow_local_requests?,
allow_local_network: allow_local_requests?,
- schemes: %w(http https)
+ schemes: %w[http https]
)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
session[access_token_key] = nil
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 92763e09ba3..cb58b5974ca 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -15,6 +15,8 @@ class Import::GithubController < Import::BaseController
rescue_from Octokit::TooManyRequests, with: :provider_rate_limit
rescue_from Gitlab::GithubImport::RateLimitError, with: :rate_limit_threshold_exceeded
+ delegate :client, to: :client_proxy, private: true
+
PAGE_LENGTH = 25
def new
@@ -46,7 +48,22 @@ class Import::GithubController < Import::BaseController
# Improving in https://gitlab.com/gitlab-org/gitlab-foss/issues/55585
client_repos
- super
+ respond_to do |format|
+ format.json do
+ render json: { imported_projects: serialized_imported_projects,
+ provider_repos: serialized_provider_repos,
+ incompatible_repos: serialized_incompatible_repos,
+ page_info: client_repos_response[:page_info] }
+ end
+
+ format.html do
+ if params[:namespace_id].present?
+ @namespace = Namespace.find_by_id(params[:namespace_id])
+
+ render_404 unless current_user.can?(:create_projects, @namespace)
+ end
+ end
+ end
end
def create
@@ -126,24 +143,18 @@ class Import::GithubController < Import::BaseController
end
end
- def client
- @client ||= if Feature.enabled?(:remove_legacy_github_client)
- Gitlab::GithubImport::Client.new(session[access_token_key])
- else
- Gitlab::LegacyGithubImport::Client.new(session[access_token_key], **client_options)
- end
+ def client_proxy
+ @client_proxy ||= Gitlab::GithubImport::Clients::Proxy.new(
+ session[access_token_key], client_options
+ )
+ end
+
+ def client_repos_response
+ @client_repos_response ||= client_proxy.repos(sanitized_filter_param, pagination_options)
end
def client_repos
- @client_repos ||= if Feature.enabled?(:remove_legacy_github_client)
- if sanitized_filter_param
- client.search_repos_by_name(sanitized_filter_param, pagination_options)[:items]
- else
- client.repos(pagination_options)
- end
- else
- filtered(client.repos)
- end
+ client_repos_response[:repos]
end
def sanitized_filter_param
@@ -213,6 +224,11 @@ class Import::GithubController < Import::BaseController
def pagination_options
{
+ before: params[:before].presence,
+ after: params[:after].presence,
+ first: PAGE_LENGTH,
+ # TODO: remove after rollout FF github_client_fetch_repos_via_graphql
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/385649
page: [1, params[:page].to_i].max,
per_page: PAGE_LENGTH
}
diff --git a/app/controllers/jira_connect/app_descriptor_controller.rb b/app/controllers/jira_connect/app_descriptor_controller.rb
index 16bd73f5ab6..3c50d54fa10 100644
--- a/app/controllers/jira_connect/app_descriptor_controller.rb
+++ b/app/controllers/jira_connect/app_descriptor_controller.rb
@@ -28,7 +28,7 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController
type: 'jwt'
},
modules: modules,
- scopes: %w(READ WRITE DELETE),
+ scopes: %w[READ WRITE DELETE],
apiVersion: 1,
apiMigrations: {
'context-qsh': true,
@@ -76,7 +76,7 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController
jiraDevelopmentTool: {
actions: {
createBranch: {
- templateUrl: new_jira_connect_branch_url + '?issue_key={issue.key}&issue_summary={issue.summary}'
+ templateUrl: "#{new_jira_connect_branch_url}?issue_key={issue.key}&issue_summary={issue.summary}"
}
},
key: 'gitlab-development-tool',
@@ -84,7 +84,7 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController
name: { value: 'GitLab' },
url: HOME_URL,
logoUrl: logo_url,
- capabilities: %w(branch commit pull_request)
+ capabilities: %w[branch commit pull_request]
}
}
end
diff --git a/app/controllers/jira_connect/application_controller.rb b/app/controllers/jira_connect/application_controller.rb
index b9f0ea795e1..e26d69314cd 100644
--- a/app/controllers/jira_connect/application_controller.rb
+++ b/app/controllers/jira_connect/application_controller.rb
@@ -3,11 +3,6 @@
class JiraConnect::ApplicationController < ApplicationController
include Gitlab::Utils::StrongMemoize
- CORS_ALLOWED_METHODS = {
- '/-/jira_connect/oauth_application_id' => %i[GET OPTIONS],
- '/-/jira_connect/subscriptions/*' => %i[DELETE OPTIONS]
- }.freeze
-
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
before_action :verify_atlassian_jwt!
@@ -65,25 +60,4 @@ class JiraConnect::ApplicationController < ApplicationController
def auth_token
params[:jwt] || request.headers['Authorization']&.split(' ', 2)&.last
end
-
- def cors_allowed_methods
- CORS_ALLOWED_METHODS[resource]
- end
-
- def resource
- request.path.gsub(%r{/\d+$}, '/*')
- end
-
- def set_cors_headers
- return unless allow_cors_request?
-
- response.set_header('Access-Control-Allow-Origin', Gitlab::CurrentSettings.jira_connect_proxy_url)
- response.set_header('Access-Control-Allow-Methods', cors_allowed_methods.join(', '))
- end
-
- def allow_cors_request?
- return false if cors_allowed_methods.nil?
-
- !Gitlab.com? && Gitlab::CurrentSettings.jira_connect_proxy_url.present?
- end
end
diff --git a/app/controllers/jira_connect/cors_preflight_checks_controller.rb b/app/controllers/jira_connect/cors_preflight_checks_controller.rb
deleted file mode 100644
index 3f30c1e04df..00000000000
--- a/app/controllers/jira_connect/cors_preflight_checks_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module JiraConnect
- class CorsPreflightChecksController < ApplicationController
- feature_category :integrations
-
- skip_before_action :verify_atlassian_jwt!
- before_action :set_cors_headers
-
- def index
- return render_404 unless allow_cors_request?
-
- render plain: '', content_type: 'text/plain'
- end
- end
-end
diff --git a/app/controllers/jira_connect/events_controller.rb b/app/controllers/jira_connect/events_controller.rb
index 394fdc9b2f6..fa1e1f505eb 100644
--- a/app/controllers/jira_connect/events_controller.rb
+++ b/app/controllers/jira_connect/events_controller.rb
@@ -31,7 +31,10 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
end
def update_installation
- current_jira_installation.update(update_params)
+ JiraConnectInstallations::UpdateService.execute(
+ current_jira_installation,
+ update_params
+ ).success?
end
def create_params
@@ -56,7 +59,7 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
def jwt_verification_claims
{
- aud: jira_connect_base_url(protocol: 'https'),
+ aud: Gitlab.config.jira_connect.enforce_jira_base_url_https ? jira_connect_base_url(protocol: 'https') : jira_connect_base_url,
iss: transformed_params[:client_key],
qsh: Atlassian::Jwt.create_query_string_hash(request.url, request.method, jira_connect_base_url)
}
diff --git a/app/controllers/jira_connect/installations_controller.rb b/app/controllers/jira_connect/installations_controller.rb
index 401bc4f9c87..44dbf90f5fb 100644
--- a/app/controllers/jira_connect/installations_controller.rb
+++ b/app/controllers/jira_connect/installations_controller.rb
@@ -6,11 +6,12 @@ class JiraConnect::InstallationsController < JiraConnect::ApplicationController
end
def update
- if current_jira_installation.update(installation_params)
+ result = update_installation
+ if result.success?
render json: installation_json(current_jira_installation)
else
render(
- json: { errors: current_jira_installation.errors },
+ json: { errors: result.message },
status: :unprocessable_entity
)
end
@@ -18,6 +19,13 @@ class JiraConnect::InstallationsController < JiraConnect::ApplicationController
private
+ def update_installation
+ JiraConnectInstallations::UpdateService.execute(
+ current_jira_installation,
+ installation_params
+ )
+ end
+
def installation_json(installation)
{
gitlab_com: installation.instance_url.blank?,
diff --git a/app/controllers/jira_connect/oauth_application_ids_controller.rb b/app/controllers/jira_connect/oauth_application_ids_controller.rb
index 3e788e2282e..de520337af3 100644
--- a/app/controllers/jira_connect/oauth_application_ids_controller.rb
+++ b/app/controllers/jira_connect/oauth_application_ids_controller.rb
@@ -5,7 +5,6 @@ module JiraConnect
feature_category :integrations
skip_before_action :verify_atlassian_jwt!
- before_action :set_cors_headers
def show
if show_application_id?
@@ -20,7 +19,7 @@ module JiraConnect
def show_application_id?
return if Gitlab.com?
- Feature.enabled?(:jira_connect_oauth_self_managed) && jira_connect_application_key.present?
+ jira_connect_application_key.present?
end
def jira_connect_application_key
diff --git a/app/controllers/jira_connect/public_keys_controller.rb b/app/controllers/jira_connect/public_keys_controller.rb
index b3144993edb..09003f8478f 100644
--- a/app/controllers/jira_connect/public_keys_controller.rb
+++ b/app/controllers/jira_connect/public_keys_controller.rb
@@ -10,7 +10,9 @@ module JiraConnect
skip_before_action :authenticate_user!
def show
- return render_404 if Feature.disabled?(:jira_connect_oauth_self_managed) || !Gitlab.com?
+ if Feature.disabled?(:jira_connect_oauth_self_managed) || !Gitlab.config.jira_connect.enable_public_keys_storage
+ return render_404
+ end
render plain: public_key.key
end
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index 9a732cadd94..ff7477a94d6 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -1,19 +1,20 @@
# frozen_string_literal: true
class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
+ ALLOWED_IFRAME_ANCESTORS = [:self, 'https://*.atlassian.net', 'https://*.jira.com'].freeze
layout 'jira_connect'
content_security_policy do |p|
next if p.directives.blank?
# rubocop: disable Lint/PercentStringArray
- script_src_values = Array.wrap(p.directives['script-src']) | %w('self' https://connect-cdn.atl-paas.net)
- style_src_values = Array.wrap(p.directives['style-src']) | %w('self' 'unsafe-inline')
+ script_src_values = Array.wrap(p.directives['script-src']) | %w['self' https://connect-cdn.atl-paas.net]
+ style_src_values = Array.wrap(p.directives['style-src']) | %w['self' 'unsafe-inline']
# rubocop: enable Lint/PercentStringArray
# *.jira.com is needed for some legacy Jira Cloud instances, new ones will use *.atlassian.net
# https://support.atlassian.com/organization-administration/docs/ip-addresses-and-domains-for-atlassian-cloud-products/
- p.frame_ancestors :self, 'https://*.atlassian.net', 'https://*.jira.com'
+ p.frame_ancestors(*(ALLOWED_IFRAME_ANCESTORS + Gitlab.config.jira_connect.additional_iframe_ancestors))
p.script_src(*script_src_values)
p.style_src(*style_src_values)
end
@@ -27,7 +28,6 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
before_action :verify_qsh_claim!, only: :index
before_action :allow_self_managed_content_security_policy, only: :index
before_action :authenticate_user!, only: :create
- before_action :set_cors_headers
def index
@subscriptions = current_jira_installation.subscriptions.preload_namespace_route
@@ -65,8 +65,6 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
private
def allow_self_managed_content_security_policy
- return unless Feature.enabled?(:jira_connect_oauth_self_managed_setting)
-
return unless current_jira_installation.instance_url?
request.content_security_policy.directives['connect-src'] ||= []
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index f3f0ddd968a..8650b6cbc6f 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -119,6 +119,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
identity_linker ||= auth_module::IdentityLinker.new(current_user, oauth, session)
link_identity(identity_linker)
+ set_remember_me(current_user)
if identity_linker.changed?
redirect_identity_linked
@@ -169,6 +170,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# available in the logs for this request.
Gitlab::ApplicationContext.push(user: user)
log_audit_event(user, with: oauth['provider'])
+ Gitlab::Tracking.event(self.class.name, "#{oauth['provider']}_sso", user: user) if new_user
set_remember_me(user)
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index 1216353be36..38cdb16c350 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -58,8 +58,8 @@ class PasswordsController < Devise::PasswordsController
def check_password_authentication_available
if resource
return if resource.allow_password_authentication?
- else
- return if Gitlab::CurrentSettings.password_authentication_enabled?
+ elsif Gitlab::CurrentSettings.password_authentication_enabled?
+ return
end
redirect_to after_sending_reset_password_instructions_path_for(resource_name),
diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb
index 90d5f945d78..39e8f6c500d 100644
--- a/app/controllers/profiles/keys_controller.rb
+++ b/app/controllers/profiles/keys_controller.rb
@@ -37,6 +37,6 @@ class Profiles::KeysController < Profiles::ApplicationController
private
def key_params
- params.require(:key).permit(:title, :key, :expires_at)
+ params.require(:key).permit(:title, :key, :usage_type, :expires_at)
end
end
diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb
index a57c87bf691..974e7104c07 100644
--- a/app/controllers/profiles/preferences_controller.rb
+++ b/app/controllers/profiles/preferences_controller.rb
@@ -57,7 +57,8 @@ class Profiles::PreferencesController < Profiles::ApplicationController
:render_whitespace_in_code,
:markdown_surround_selection,
:markdown_automatic_lists,
- :use_legacy_web_ide
+ :use_legacy_web_ide,
+ :use_new_navigation
]
end
end
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index 0933f2bb7ea..03b7cc9f892 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -97,7 +97,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def skip
if two_factor_grace_period_expired?
- redirect_to new_profile_two_factor_auth_path, alert: s_('Cannot skip two factor authentication setup')
+ redirect_to new_profile_two_factor_auth_path, alert: _('Cannot skip two factor authentication setup')
else
session[:skip_two_factor] = current_user.otp_grace_period_started_at + two_factor_grace_period.hours
redirect_to root_path
@@ -186,9 +186,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def u2f_registrations
current_user.u2f_registrations.map do |u2f_registration|
{
- name: u2f_registration.name,
- created_at: u2f_registration.created_at,
- delete_path: profile_u2f_registration_path(u2f_registration)
+ name: u2f_registration.name,
+ created_at: u2f_registration.created_at,
+ delete_path: profile_u2f_registration_path(u2f_registration)
}
end
end
@@ -196,9 +196,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def webauthn_registrations
current_user.webauthn_registrations.map do |webauthn_registration|
{
- name: webauthn_registration.name,
- created_at: webauthn_registration.created_at,
- delete_path: profile_webauthn_registration_path(webauthn_registration)
+ name: webauthn_registration.name,
+ created_at: webauthn_registration.created_at,
+ delete_path: profile_webauthn_registration_path(webauthn_registration)
}
end
end
@@ -216,7 +216,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
group_links = groups.map { |group| view_context.link_to group.full_name, group_path(group) }.to_sentence
leave_group_links = groups.map { |group| view_context.link_to (s_("leave %{group_name}") % { group_name: group.full_name }), leave_group_members_path(group), remote: false, method: :delete }.to_sentence
- s_(%{The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}.})
+ s_(%(The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}.))
.html_safe % { group_links: group_links.html_safe, leave_group_links: leave_group_links.html_safe }
end
diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb
index 7755effe1da..ef20c71cd77 100644
--- a/app/controllers/projects/autocomplete_sources_controller.rb
+++ b/app/controllers/projects/autocomplete_sources_controller.rb
@@ -7,7 +7,7 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController
feature_category :team_planning, [:issues, :labels, :milestones, :commands, :contacts]
feature_category :code_review, [:merge_requests]
feature_category :users, [:members]
- feature_category :snippets, [:snippets]
+ feature_category :source_code_management, [:snippets]
urgency :low, [:merge_requests, :members]
urgency :low, [:issues, :labels, :milestones, :commands, :contacts]
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 42bd87e1c01..dbbffc4c283 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -13,10 +13,10 @@ class Projects::BadgesController < Projects::ApplicationController
def pipeline
pipeline_status = Gitlab::Ci::Badge::Pipeline::Status
.new(project, params[:ref], opts: {
- ignore_skipped: params[:ignore_skipped],
- key_text: params[:key_text],
- key_width: params[:key_width]
- })
+ ignore_skipped: params[:ignore_skipped],
+ key_text: params[:key_text],
+ key_width: params[:key_width]
+ })
render_badge pipeline_status
end
@@ -24,13 +24,13 @@ class Projects::BadgesController < Projects::ApplicationController
def coverage
coverage_report = Gitlab::Ci::Badge::Coverage::Report
.new(project, params[:ref], opts: {
- job: params[:job],
- key_text: params[:key_text],
- key_width: params[:key_width],
- min_good: params[:min_good],
- min_acceptable: params[:min_acceptable],
- min_medium: params[:min_medium]
- })
+ job: params[:job],
+ key_text: params[:key_text],
+ key_width: params[:key_width],
+ min_good: params[:min_good],
+ min_acceptable: params[:min_acceptable],
+ min_medium: params[:min_medium]
+ })
render_badge coverage_report
end
@@ -38,10 +38,10 @@ class Projects::BadgesController < Projects::ApplicationController
def release
latest_release = Gitlab::Ci::Badge::Release::LatestRelease
.new(project, current_user, opts: {
- key_text: params[:key_text],
- key_width: params[:key_width],
- order_by: params[:order_by]
- })
+ key_text: params[:key_text],
+ key_width: params[:key_width],
+ order_by: params[:order_by]
+ })
render_badge latest_release
end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index 01ed5473b41..cfff281604e 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -7,7 +7,7 @@ class Projects::BlameController < Projects::ApplicationController
before_action :require_non_empty_project
before_action :assign_ref_vars
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
feature_category :source_code_management
urgency :low, [:show]
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index f5188e28b81..4eda76f4f21 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -18,7 +18,8 @@ class Projects::BlobController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:show]
before_action :require_non_empty_project, except: [:new, :create]
- before_action :authorize_download_code!
+ before_action :authorize_download_code!, except: [:show]
+ before_action :authorize_read_code!, only: [:show]
# We need to assign the blob vars before `authorize_edit_tree!` so we can
# validate access to a specific ref.
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 27969cb1a75..7b01e4db42a 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -6,7 +6,7 @@ class Projects::BranchesController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project, except: :create
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :authorize_push_code!, only: [:new, :create, :destroy, :destroy_all_merged]
# Support legacy URLs
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 b2b5e096105..37138afc719 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
@@ -25,7 +25,7 @@ class Projects::Ci::DailyBuildGroupReportResultsController < Projects::Applicati
{
date: 'date',
group_name: 'group_name',
- param_type => -> (record) { record.data[param_type] }
+ param_type => ->(record) { record.data[param_type] }
}
).render
end
diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb
index 30d001d0ac5..b781365b3c3 100644
--- a/app/controllers/projects/clusters_controller.rb
+++ b/app/controllers/projects/clusters_controller.rb
@@ -5,7 +5,6 @@ class Projects::ClustersController < Clusters::ClustersController
before_action :repository
before_action do
- push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:show_gitlab_agent_feedback, type: :ops)
end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 870320a79d9..583b572d4b1 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -12,7 +12,7 @@ class Projects::CommitController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :authorize_read_pipeline!, only: [:pipelines]
before_action :commit
before_action :define_commit_vars, only: [:show, :diff_for_path, :diff_files, :pipelines, :merge_requests]
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index f4125fd0a15..c006d56ae81 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -12,7 +12,7 @@ class Projects::CommitsController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching
before_action :require_non_empty_project
before_action :assign_ref_vars, except: :commits_root
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :validate_ref!, except: :commits_root
before_action :set_commits, except: :commits_root
@@ -28,6 +28,8 @@ class Projects::CommitsController < Projects::ApplicationController
@merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
.find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
+ @ref_type = ref_type
+
respond_to do |format|
format.html
format.atom { render layout: 'xml' }
@@ -73,18 +75,20 @@ class Projects::CommitsController < Projects::ApplicationController
search = permitted_params[:search]
author = permitted_params[:author]
+ # fully_qualified_ref is available in some situations when the use_ref_type_parameter FF is enabled
+ ref = @fully_qualified_ref || @ref
@commits =
if search.present?
- @repository.find_commits_by_message(search, @ref, @path, @limit, @offset)
+ @repository.find_commits_by_message(search, ref, @path, @limit, @offset)
elsif author.present?
- @repository.commits(@ref, author: author, path: @path, limit: @limit, offset: @offset)
+ @repository.commits(ref, author: author, path: @path, limit: @limit, offset: @offset)
else
- @repository.commits(@ref, path: @path, limit: @limit, offset: @offset)
+ @repository.commits(ref, path: @path, limit: @limit, offset: @offset)
end
@commits.each(&:lazy_author) # preload authors
- @commits = @commits.with_markdown_cache.with_latest_pipeline(@ref)
+ @commits = @commits.with_markdown_cache.with_latest_pipeline(ref)
@commits = set_commits_for_rendering(@commits)
end
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 61308f24412..266edd506d5 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -10,7 +10,7 @@ class Projects::CompareController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
# Defining ivars
before_action :define_diffs, only: [:show, :diff_for_path]
before_action :define_environment, only: [:show]
@@ -95,7 +95,7 @@ class Projects::CompareController < Projects::ApplicationController
target_project = target_projects(source_project).find_by_id(compare_params[:from_project_id])
# Just ignore the field if it points at a non-existent or hidden project
- next source_project unless target_project && can?(current_user, :download_code, target_project)
+ next source_project unless target_project && can?(current_user, :read_code, target_project)
target_project
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 67f2f85ce65..537fd3854c4 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -14,11 +14,11 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
authorize_metrics_dashboard!
-
- push_frontend_feature_flag(:prometheus_computed_alerts)
- push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
end
+ before_action only: [:show] do
+ push_frontend_feature_flag(:environment_details_vue, @project)
+ end
before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
before_action :authorize_stop_environment!, only: [:stop]
diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb
index c6bc115e737..b5099d555ae 100644
--- a/app/controllers/projects/find_file_controller.rb
+++ b/app/controllers/projects/find_file_controller.rb
@@ -8,7 +8,7 @@ class Projects::FindFileController < Projects::ApplicationController
before_action :require_non_empty_project
before_action :assign_ref_vars
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
feature_category :source_code_management
urgency :low, [:show, :list]
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index 3208a5076e7..ff3dc71b6cc 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -9,9 +9,9 @@ class Projects::ForksController < Projects::ApplicationController
# Authorize
before_action :disable_query_limiting, only: [:create]
before_action :require_non_empty_project
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :authenticate_user!, only: [:new, :create]
- before_action :authorize_fork_project!, only: [:new, :create]
+ before_action :authorize_fork_project!, except: [:index]
before_action :authorize_fork_namespace!, only: [:create]
feature_category :source_code_management
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index 6da70b5e157..d072381933a 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -21,11 +21,24 @@ class Projects::GraphsController < Projects::ApplicationController
feature_category :continuous_integration, [:ci]
urgency :low, [:ci]
+ MAX_COMMITS = 6000
+
def show
+ @ref_type = ref_type
+
respond_to do |format|
format.html
format.json do
- fetch_graph
+ commits = @project.repository.commits(ref, limit: MAX_COMMITS, skip_merges: true)
+ log = commits.map do |commit|
+ {
+ author_name: commit.author_name,
+ author_email: commit.author_email,
+ date: commit.committed_date.strftime("%Y-%m-%d")
+ }
+ end
+
+ render json: Gitlab::Json.dump(log)
end
end
end
@@ -50,9 +63,13 @@ class Projects::GraphsController < Projects::ApplicationController
private
+ def ref
+ @fully_qualified_ref || @ref
+ end
+
def get_commits
@commits_limit = 2000
- @commits = @project.repository.commits(@ref, limit: @commits_limit, skip_merges: true)
+ @commits = @project.repository.commits(ref, limit: @commits_limit, skip_merges: true)
@commits_graph = Gitlab::Graphs::Commits.new(@commits)
@commits_per_week_days = @commits_graph.commits_per_week_days
@commits_per_time = @commits_graph.commits_per_time
@@ -76,7 +93,7 @@ class Projects::GraphsController < Projects::ApplicationController
base_params: {
start_date: date_today - report_window,
end_date: date_today,
- ref_path: @project.repository.expand_ref(@ref),
+ ref_path: @project.repository.expand_ref(ref),
param_type: 'coverage'
},
download_path: namespace_project_ci_daily_build_group_report_results_path(
@@ -92,21 +109,6 @@ class Projects::GraphsController < Projects::ApplicationController
}
end
- def fetch_graph
- @commits = @project.repository.commits(@ref, limit: 6000, skip_merges: true)
- @log = []
-
- @commits.each do |commit|
- @log << {
- author_name: commit.author_name,
- author_email: commit.author_email,
- date: commit.committed_date.strftime("%Y-%m-%d")
- }
- end
-
- render json: Gitlab::Json.dump(@log)
- end
-
def tracking_namespace_source
project.namespace
end
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 599505dcb6d..3842a88d15b 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -8,6 +8,7 @@ class Projects::IncidentsController < Projects::ApplicationController
before_action :load_incident, only: [:show]
before_action do
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
+ push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index ee845cd001e..631e697dd2f 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -7,6 +7,7 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuableCollections
include IssuesCalendar
include RecordUserLastActivity
+ include ::Observability::ContentSecurityPolicy
ISSUES_EXCEPT_ACTIONS = %i[index calendar new create bulk_update import_csv export_csv service_desk].freeze
SET_ISSUABLES_INDEX_ONLY_ACTIONS = %i[index calendar service_desk].freeze
@@ -19,7 +20,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :disable_query_limiting, only: [:create_merge_request, :move, :bulk_update]
before_action :check_issues_available!
before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
- before_action :redirect_if_task, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
+ before_action :redirect_if_work_item, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
after_action :log_issue_show, only: :show
@@ -37,7 +38,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :authorize_create_merge_request_from!, only: [:create_merge_request]
before_action :authorize_import_issues!, only: [:import_csv]
- before_action :authorize_download_code!, only: [:related_branches]
+ before_action :authorize_read_code!, only: [:related_branches]
before_action do
push_frontend_feature_flag(:preserve_unchanged_markdown, project)
@@ -55,8 +56,10 @@ class Projects::IssuesController < Projects::ApplicationController
before_action only: :show do
push_frontend_feature_flag(:issue_assignees_widget, project)
push_frontend_feature_flag(:work_items_mvc, project&.group)
+ push_force_frontend_feature_flag(:work_items_mvc, project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
+ push_frontend_feature_flag(:use_iid_in_work_items_path, project)
push_force_frontend_feature_flag(:work_items_create_from_markdown, project&.work_items_create_from_markdown_feature_flag_enabled?)
end
@@ -432,8 +435,8 @@ class Projects::IssuesController < Projects::ApplicationController
# Overridden in EE
def create_vulnerability_issue_feedback(issue); end
- def redirect_if_task
- return unless issue.task?
+ def redirect_if_work_item
+ return unless allowed_work_item?
if Feature.enabled?(:use_iid_in_work_items_path, project.group)
redirect_to project_work_items_path(project, issue.iid, params: request.query_parameters.merge(iid_path: true))
@@ -441,6 +444,10 @@ class Projects::IssuesController < Projects::ApplicationController
redirect_to project_work_items_path(project, issue.id, params: request.query_parameters)
end
end
+
+ def allowed_work_item?
+ issue.task?
+ end
end
Projects::IssuesController.prepend_mod_with('Projects::IssuesController')
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 557ac566733..c6d442a6f27 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -20,9 +20,6 @@ class Projects::JobsController < Projects::ApplicationController
before_action :verify_proxy_request!, only: :proxy_websocket_authorize
before_action :push_job_log_jump_to_failures, only: [:show]
before_action :reject_if_build_artifacts_size_refreshing!, only: [:erase]
- before_action do
- push_frontend_feature_flag(:graphql_job_app, project, type: :development)
- end
layout 'project'
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 93e2298ca98..cba0056ccd5 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -4,6 +4,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
include DiffForPath
include DiffHelper
include RendersCommits
+ include ::Observability::ContentSecurityPolicy
skip_before_action :merge_request
before_action :authorize_create_merge_request_from!
@@ -19,6 +20,10 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
:branch_to
]
+ before_action do
+ push_frontend_feature_flag(:mr_compare_dropdowns, project)
+ end
+
def new
define_new_vars
end
@@ -89,6 +94,14 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
render layout: false
end
+ def target_projects
+ projects = MergeRequestTargetProjectFinder
+ .new(current_user: current_user, source_project: @project, project_feature: :repository)
+ .execute(include_routes: true).limit(20).search(params[:search])
+
+ render json: ProjectSerializer.new.represent(projects)
+ end
+
private
def build_merge_request
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index c88dbc70ed5..83377f67723 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -60,17 +60,11 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
options[:merge_conflicts_in_diff]
]
- if Feature.enabled?(:check_etags_diffs_batch_before_write_cache, merge_request.project) && !stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
- return
- end
+ return unless stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
diffs.unfold_diff_files(unfoldable_positions)
diffs.write_cache
- if Feature.disabled?(:check_etags_diffs_batch_before_write_cache, merge_request.project) && !stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
- return
- end
-
render json: PaginatedDiffSerializer.new(current_user: current_user).represent(diffs, options)
end
# rubocop: enable Metrics/AbcSize
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 4ba79d43f27..3ab1f7d1d32 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -11,10 +11,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include SourcegraphDecorator
include DiffHelper
include Gitlab::Cache::Helpers
+ include ::Observability::ContentSecurityPolicy
prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) }
skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv]
- before_action :apply_diff_view_cookie!, only: [:show]
+ before_action :apply_diff_view_cookie!, only: [:show, :diffs]
before_action :disable_query_limiting, only: [:assign_related_issues, :update]
before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort]
before_action :authorize_read_actual_head_pipeline!, only: [
@@ -30,7 +31,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action :authenticate_user!, only: [:assign_related_issues]
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
- before_action only: [:show] do
+ before_action only: [:show, :diffs] do
push_frontend_feature_flag(:core_security_mr_widget_counts, project)
push_frontend_feature_flag(:issue_assignees_widget, @project)
push_frontend_feature_flag(:refactor_security_extension, @project)
@@ -40,21 +41,22 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:mr_review_submit_comment, project)
push_frontend_feature_flag(:mr_experience_survey, project)
push_frontend_feature_flag(:realtime_reviewers, project)
+ push_frontend_feature_flag(:realtime_mr_status_change, project)
end
before_action do
push_frontend_feature_flag(:permit_all_shared_groups_for_approval, @project)
end
- around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
+ around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :diffs, :discussions]
- after_action :log_merge_request_show, only: [:show]
+ after_action :log_merge_request_show, only: [:show, :diffs]
feature_category :code_review, [
:assign_related_issues, :bulk_update, :cancel_auto_merge,
:commit_change_content, :commits, :context_commits, :destroy,
:discussions, :edit, :index, :merge, :rebase, :remove_wip,
- :show, :toggle_award_emoji, :toggle_subscription, :update
+ :show, :diffs, :toggle_award_emoji, :toggle_subscription, :update
]
feature_category :code_testing, [:test_reports, :coverage_reports]
@@ -67,6 +69,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
urgency :low, [
:index,
:show,
+ :diffs,
:commits,
:bulk_update,
:edit,
@@ -100,74 +103,13 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
end
- # rubocop:disable Metrics/AbcSize
def show
- close_merge_request_if_no_source_project
- @merge_request.check_mergeability(async: true)
-
- respond_to do |format|
- format.html do
- # use next to appease Rubocop
- next render('invalid') if target_branch_missing?
-
- preload_assignees_for_render(@merge_request)
-
- # Build a note object for comment form
- @note = @project.notes.new(noteable: @merge_request)
-
- @noteable = @merge_request
- @commits_count = @merge_request.commits_count + @merge_request.context_commits_count
- @diffs_count = get_diffs_count
- @issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
- @current_user_data = Gitlab::Json.dump(UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity))
- @show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
- @file_by_file_default = current_user&.view_diffs_file_by_file
- @coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json) if @merge_request.has_coverage_reports?
- @update_current_user_path = expose_path(api_v4_user_preferences_path)
- @endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
- @endpoint_diff_batch_url = endpoint_diff_batch_url(@project, @merge_request)
-
- set_pipeline_variables
-
- @number_of_pipelines = @pipelines.size
-
- render
- end
-
- format.json do
- Gitlab::PollingInterval.set_header(response, interval: 10_000)
-
- if params[:serializer] == 'sidebar_extras'
- cache_context = [
- params[:serializer],
- current_user&.cache_key,
- @merge_request.merge_request_assignees.map(&:cache_key),
- @merge_request.merge_request_reviewers.map(&:cache_key)
- ]
-
- render_cached(@merge_request,
- with: serializer,
- cache_context: -> (_) { [Digest::SHA256.hexdigest(cache_context.to_s)] },
- serializer: params[:serializer])
- else
- render json: serializer.represent(@merge_request, serializer: params[:serializer])
- end
- end
-
- format.patch do
- break render_404 unless @merge_request.diff_refs
-
- send_git_patch @project.repository, @merge_request.diff_refs
- end
-
- format.diff do
- break render_404 unless @merge_request.diff_refs
+ show_merge_request
+ end
- send_git_diff @project.repository, @merge_request.diff_refs
- end
- end
+ def diffs
+ show_merge_request
end
- # rubocop:enable Metrics/AbcSize
def commits
# Get context commits from repository
@@ -412,6 +354,77 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
private
+ def show_merge_request
+ close_merge_request_if_no_source_project
+ @merge_request.check_mergeability(async: true)
+
+ respond_to do |format|
+ format.html do
+ # use next to appease Rubocop
+ next render('invalid') if target_branch_missing?
+
+ render_html_page
+ end
+
+ format.json do
+ Gitlab::PollingInterval.set_header(response, interval: 10_000)
+
+ if params[:serializer] == 'sidebar_extras'
+ cache_context = [
+ params[:serializer],
+ current_user&.cache_key,
+ @merge_request.merge_request_assignees.map(&:cache_key),
+ @merge_request.merge_request_reviewers.map(&:cache_key)
+ ]
+
+ render_cached(@merge_request,
+ with: serializer,
+ cache_context: ->(_) { [Digest::SHA256.hexdigest(cache_context.to_s)] },
+ serializer: params[:serializer])
+ else
+ render json: serializer.represent(@merge_request, serializer: params[:serializer])
+ end
+ end
+
+ format.patch do
+ break render_404 unless @merge_request.diff_refs
+
+ send_git_patch @project.repository, @merge_request.diff_refs
+ end
+
+ format.diff do
+ break render_404 unless @merge_request.diff_refs
+
+ send_git_diff @project.repository, @merge_request.diff_refs
+ end
+ end
+ end
+
+ def render_html_page
+ preload_assignees_for_render(@merge_request)
+
+ # Build a note object for comment form
+ @note = @project.notes.new(noteable: @merge_request)
+
+ @noteable = @merge_request
+ @commits_count = @merge_request.commits_count + @merge_request.context_commits_count
+ @diffs_count = get_diffs_count
+ @issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
+ @current_user_data = Gitlab::Json.dump(UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity))
+ @show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
+ @file_by_file_default = current_user&.view_diffs_file_by_file
+ @coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json) if @merge_request.has_coverage_reports?
+ @update_current_user_path = expose_path(api_v4_user_preferences_path)
+ @endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
+ @endpoint_diff_batch_url = endpoint_diff_batch_url(@project, @merge_request)
+
+ set_pipeline_variables
+
+ @number_of_pipelines = @pipelines.size
+
+ render
+ end
+
def get_diffs_count
if show_only_context_commits?
@merge_request.context_commits_diff.raw_diffs.size
diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb
index b78ee6ca917..08757d11912 100644
--- a/app/controllers/projects/metrics_dashboard_controller.rb
+++ b/app/controllers/projects/metrics_dashboard_controller.rb
@@ -9,10 +9,6 @@ module Projects
include Gitlab::Utils::StrongMemoize
before_action :authorize_metrics_dashboard!
- before_action do
- push_frontend_feature_flag(:prometheus_computed_alerts)
- push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
- end
feature_category :metrics
urgency :low
diff --git a/app/controllers/projects/ml/candidates_controller.rb b/app/controllers/projects/ml/candidates_controller.rb
new file mode 100644
index 00000000000..b702edb858e
--- /dev/null
+++ b/app/controllers/projects/ml/candidates_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Projects
+ module Ml
+ class CandidatesController < ApplicationController
+ before_action :check_feature_flag
+
+ feature_category :mlops
+
+ def show
+ @candidate = ::Ml::Candidate.with_project_id_and_iid(@project.id, params['iid'])
+
+ render_404 unless @candidate.present?
+ end
+
+ private
+
+ def check_feature_flag
+ render_404 unless Feature.enabled?(:ml_experiment_tracking, @project)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/ml/experiments_controller.rb b/app/controllers/projects/ml/experiments_controller.rb
index 749586791ac..c82a959d612 100644
--- a/app/controllers/projects/ml/experiments_controller.rb
+++ b/app/controllers/projects/ml/experiments_controller.rb
@@ -3,7 +3,6 @@
module Projects
module Ml
class ExperimentsController < ::Projects::ApplicationController
- include Projects::Ml::ExperimentsHelper
before_action :check_feature_flag
feature_category :mlops
diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb
index 84ac9fb01fd..aa0838752e2 100644
--- a/app/controllers/projects/network_controller.rb
+++ b/app/controllers/projects/network_controller.rb
@@ -6,7 +6,7 @@ class Projects::NetworkController < Projects::ApplicationController
before_action :require_non_empty_project
before_action :assign_ref_vars
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :assign_options
before_action :assign_commit
@@ -14,7 +14,13 @@ class Projects::NetworkController < Projects::ApplicationController
urgency :low, [:show]
def show
- @url = project_network_path(@project, @ref, @options.merge(format: :json))
+ @url = if Feature.enabled?(:use_ref_type_parameter, @project)
+ project_network_path(@project, @ref, @options.merge(format: :json, ref_type: ref_type))
+ else
+ project_network_path(@project, @ref, @options.merge(format: :json))
+ end
+
+ @ref_type = ref_type
@commit_url = project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")
respond_to do |format|
diff --git a/app/controllers/projects/performance_monitoring/dashboards_controller.rb b/app/controllers/projects/performance_monitoring/dashboards_controller.rb
index 8acbc17aef3..d043f8d0b9f 100644
--- a/app/controllers/projects/performance_monitoring/dashboards_controller.rb
+++ b/app/controllers/projects/performance_monitoring/dashboards_controller.rb
@@ -70,7 +70,7 @@ module Projects
end
def validate_required_params!
- params.require(%i(branch file_name dashboard commit_message))
+ params.require(%i[branch file_name dashboard commit_message])
end
def redirect_safe_branch_name
@@ -78,7 +78,7 @@ module Projects
end
def dashboard_params
- params.permit(%i(branch file_name dashboard commit_message)).to_h
+ params.permit(%i[branch file_name dashboard commit_message]).to_h
end
def file_content_params
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 7d1a75ae449..db77127cb0a 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -24,11 +24,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :ensure_pipeline, only: [:show, :downloadable_artifacts]
before_action :reject_if_build_artifacts_size_refreshing!, only: [:destroy]
- before_action do
- push_frontend_feature_flag(:pipeline_tabs_vue, @project)
- push_frontend_feature_flag(:run_pipeline_graphql, @project)
- end
-
# 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? }
diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb
index 8c70ef446a2..baa4607dcb6 100644
--- a/app/controllers/projects/protected_branches_controller.rb
+++ b/app/controllers/projects/protected_branches_controller.rb
@@ -1,6 +1,12 @@
# frozen_string_literal: true
class Projects::ProtectedBranchesController < Projects::ProtectedRefsController
+ def show
+ super
+
+ render 'protected_branches/show'
+ end
+
protected
def project_refs
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index 9707b70f26f..924de0ee7ea 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -12,7 +12,7 @@ class Projects::RawController < Projects::ApplicationController
before_action :set_ref_and_path
before_action :require_non_empty_project
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :check_show_rate_limit!, only: [:show], unless: :external_storage_request?
before_action :redirect_to_external_storage, only: :show, if: :static_objects_external_storage_enabled?
@@ -21,7 +21,7 @@ class Projects::RawController < Projects::ApplicationController
def show
@blob = @repository.blob_at(@ref, @path, limit: Gitlab::Git::Blob::LFS_POINTER_MAX_SIZE)
- send_blob(@repository, @blob, inline: (params[:inline] != 'false'), allow_caching: Guest.can?(:download_code, @project))
+ send_blob(@repository, @blob, inline: (params[:inline] != 'false'), allow_caching: Guest.can?(:read_code, @project))
end
private
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index 72af3280a39..8ac6d872aae 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -9,7 +9,7 @@ class Projects::RefsController < Projects::ApplicationController
before_action :require_non_empty_project
before_action :validate_ref_id
before_action :assign_ref_vars
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
feature_category :source_code_management
urgency :low, [:switch, :logs_tree]
@@ -24,9 +24,17 @@ class Projects::RefsController < Projects::ApplicationController
when "blob"
project_blob_path(@project, @id)
when "graph"
- project_network_path(@project, @id, @options)
+ if Feature.enabled?(:use_ref_type_parameter, @project)
+ project_network_path(@project, @id, ref_type: ref_type)
+ else
+ project_network_path(@project, @id, @options)
+ end
when "graphs"
- project_graph_path(@project, @id)
+ if Feature.enabled?(:use_ref_type_parameter, @project)
+ project_graph_path(@project, @id, ref_type: ref_type)
+ else
+ project_graph_path(@project, @id)
+ end
when "find_file"
project_find_file_path(@project, @id)
when "graphs_commits"
@@ -34,7 +42,11 @@ class Projects::RefsController < Projects::ApplicationController
when "badges"
project_settings_ci_cd_path(@project, ref: @id)
else
- project_commits_path(@project, @id)
+ if Feature.enabled?(:use_ref_type_parameter, @project)
+ project_commits_path(@project, @id, ref_type: ref_type)
+ else
+ project_commits_path(@project, @id)
+ end
end
redirect_to new_path
diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb
index ffe95bf4fee..6c663c4694a 100644
--- a/app/controllers/projects/registry/repositories_controller.rb
+++ b/app/controllers/projects/registry/repositories_controller.rb
@@ -23,10 +23,6 @@ module Projects
def destroy
image.delete_scheduled!
- unless Feature.enabled?(:container_registry_delete_repository_with_cron_worker)
- DeleteContainerRepositoryWorker.perform_async(current_user.id, image.id) # rubocop:disable CodeReuse/Worker
- end
-
track_package_event(:delete_repository, :container)
respond_to do |format|
diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb
index 5946c43b134..6f896244acb 100644
--- a/app/controllers/projects/runner_projects_controller.rb
+++ b/app/controllers/projects/runner_projects_controller.rb
@@ -11,7 +11,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
- return head(403) unless can?(current_user, :assign_runner, @runner)
+ return head(:forbidden) unless can?(current_user, :assign_runner, @runner)
path = project_runners_path(project)
diff --git a/app/controllers/projects/service_desk_controller.rb b/app/controllers/projects/service_desk_controller.rb
index aa0e70121df..8f576b8d72b 100644
--- a/app/controllers/projects/service_desk_controller.rb
+++ b/app/controllers/projects/service_desk_controller.rb
@@ -29,7 +29,7 @@ class Projects::ServiceDeskController < Projects::ApplicationController
end
def allowed_update_attributes
- %i(issue_template_key outgoing_name project_key)
+ %i[issue_template_key outgoing_name project_key]
end
def service_desk_attributes
diff --git a/app/controllers/projects/service_ping_controller.rb b/app/controllers/projects/service_ping_controller.rb
index 43c249afd8e..cfc322b47e7 100644
--- a/app/controllers/projects/service_ping_controller.rb
+++ b/app/controllers/projects/service_ping_controller.rb
@@ -10,7 +10,7 @@ class Projects::ServicePingController < Projects::ApplicationController
Gitlab::UsageDataCounters::WebIdeCounter.increment_previews_count
- head(200)
+ head(:ok)
end
def web_ide_clientside_preview_success
@@ -20,12 +20,12 @@ class Projects::ServicePingController < Projects::ApplicationController
Gitlab::UsageDataCounters::EditorUniqueCounter.track_live_preview_edit_action(author: current_user,
project: project)
- head(200)
+ head(:ok)
end
def web_ide_pipelines_count
Gitlab::UsageDataCounters::WebIdeCounter.increment_pipelines_count
- head(200)
+ head(:ok)
end
end
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 8aef1c3d24d..cf07de4dc29 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -18,6 +18,9 @@ module Projects
urgency :low
def show
+ @entity = :project
+ @variable_limit = ::Plan.default.actual_limits.project_ci_variables
+
if Feature.enabled?(:ci_pipeline_triggers_settings_vue_ui, @project)
triggers = ::Ci::TriggerSerializer.new.represent(
@project.triggers, current_user: current_user, project: @project
@@ -122,11 +125,13 @@ module Projects
.page(params[:specific_page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
.with_tags
- @shared_runners = ::Ci::Runner.instance_type.active.with_tags
-
- @shared_runners_count = @shared_runners.count(:all)
+ active_shared_runners = ::Ci::Runner.instance_type.active
+ @shared_runners_count = active_shared_runners.count
+ @shared_runners = active_shared_runners.page(params[:shared_runners_page]).per(NUMBER_OF_RUNNERS_PER_PAGE).with_tags
- @group_runners = ::Ci::Runner.belonging_to_parent_group_of_project(@project.id).with_tags
+ parent_group_runners = ::Ci::Runner.belonging_to_parent_group_of_project(@project.id)
+ @group_runners_count = parent_group_runners.count
+ @group_runners = parent_group_runners.page(params[:group_runners_page]).per(NUMBER_OF_RUNNERS_PER_PAGE).with_tags
end
def define_ci_variables
diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb
index 2bbcd9fe20c..16c1373df2b 100644
--- a/app/controllers/projects/settings/integrations_controller.rb
+++ b/app/controllers/projects/settings/integrations_controller.rb
@@ -79,7 +79,7 @@ module Projects
return {
error: true,
message: _('Validations failed.'),
- service_response: integration.errors.full_messages.join(','),
+ service_response: integration.errors.full_messages.join(', '),
test_failed: false
}
end
@@ -90,7 +90,7 @@ module Projects
return {
error: true,
message: s_('Integrations|Connection failed. Check your integration settings.'),
- service_response: result[:message].to_s,
+ service_response: result[:result].to_s,
test_failed: true
}
end
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index 90988645d3a..6d099aa8b3d 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -95,6 +95,14 @@ module Projects
@protected_tags_count = @protected_tags.reduce(0) { |sum, tag| sum + tag.matching(@project.repository.tag_names).size }
+ if Feature.enabled?(:group_protected_branches)
+ @protected_group_branches = if @project.root_namespace.is_a?(Group)
+ @project.root_namespace.protected_branches.order(:name).page(params[:page])
+ else
+ []
+ end
+ end
+
load_gon_index
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/snippets/application_controller.rb b/app/controllers/projects/snippets/application_controller.rb
index 8ee12bf3795..b8faf464531 100644
--- a/app/controllers/projects/snippets/application_controller.rb
+++ b/app/controllers/projects/snippets/application_controller.rb
@@ -4,7 +4,7 @@ class Projects::Snippets::ApplicationController < Projects::ApplicationControlle
include FindSnippet
include SnippetAuthorizations
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 847b1baca10..3c1735c728c 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -7,7 +7,7 @@ class Projects::TagsController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :authorize_admin_tag!, only: [:new, :create, :destroy]
feature_category :source_code_management
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index fea2689db14..737a6290431 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -13,11 +13,10 @@ class Projects::TreeController < Projects::ApplicationController
before_action :require_non_empty_project, except: [:new, :create]
before_action :assign_ref_vars
before_action :assign_dir_vars, only: [:create_dir]
- before_action :authorize_download_code!
+ before_action :authorize_read_code!
before_action :authorize_edit_tree!, only: [:create_dir]
before_action do
- push_frontend_feature_flag(:lazy_load_commits, @project)
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:file_line_blame, @project)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb
index a8f062bd7c1..a83ccccbeae 100644
--- a/app/controllers/projects/variables_controller.rb
+++ b/app/controllers/projects/variables_controller.rb
@@ -47,6 +47,6 @@ class Projects::VariablesController < Projects::ApplicationController
end
def variable_params_attributes
- %i[id variable_type key secret_value protected masked environment_scope _destroy]
+ %i[id variable_type key secret_value protected masked raw environment_scope _destroy]
end
end
diff --git a/app/controllers/projects/work_items_controller.rb b/app/controllers/projects/work_items_controller.rb
index a7e59a28fb7..a118c6986f7 100644
--- a/app/controllers/projects/work_items_controller.rb
+++ b/app/controllers/projects/work_items_controller.rb
@@ -3,6 +3,7 @@
class Projects::WorkItemsController < Projects::ApplicationController
before_action do
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
+ push_force_frontend_feature_flag(:work_items_mvc, project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:use_iid_in_work_items_path, project)
end
@@ -10,3 +11,5 @@ class Projects::WorkItemsController < Projects::ApplicationController
feature_category :team_planning
urgency :low
end
+
+Projects::WorkItemsController.prepend_mod
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a5dacbf7f2f..886819fe778 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -26,7 +26,7 @@ class ProjectsController < Projects::ApplicationController
before_action :verify_git_import_enabled, only: [:create]
before_action :project_export_enabled, only: [:export, :download_export, :remove_export, :generate_new_export]
before_action :present_project, only: [:edit]
- before_action :authorize_download_code!, only: [:refs]
+ before_action :authorize_read_code!, only: [:refs]
# Authorize
before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export]
@@ -37,21 +37,17 @@ class ProjectsController < Projects::ApplicationController
before_action :check_export_rate_limit!, only: [:export, :download_export, :generate_new_export]
before_action do
- push_frontend_feature_flag(:lazy_load_commits, @project)
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:file_line_blame, @project)
push_frontend_feature_flag(:increase_page_size_exponentially, @project)
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies)
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
+ push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:package_registry_access_level)
end
- before_action only: :edit do
- push_frontend_feature_flag(:split_operations_visibility_permissions, @project)
- end
-
layout :determine_layout
feature_category :projects, [
@@ -369,7 +365,7 @@ class ProjectsController < Projects::ApplicationController
def render_landing_page
Gitlab::Tracking.event('project_overview', 'render', user: current_user, project: @project.project)
- if can?(current_user, :download_code, @project)
+ if can?(current_user, :read_code, @project)
return render 'projects/no_repo' unless @project.repository_exists?
render 'projects/empty' if @project.empty_repo?
@@ -433,17 +429,11 @@ class ProjectsController < Projects::ApplicationController
security_and_compliance_access_level
container_registry_access_level
releases_access_level
- ] + operations_feature_attributes
- end
-
- def operations_feature_attributes
- if Feature.enabled?(:split_operations_visibility_permissions, project)
- %i[
- environments_access_level feature_flags_access_level monitor_access_level infrastructure_access_level
- ]
- else
- %i[operations_access_level]
- end
+ environments_access_level
+ feature_flags_access_level
+ monitor_access_level
+ infrastructure_access_level
+ ]
end
def project_setting_attributes
@@ -520,14 +510,6 @@ class ProjectsController < Projects::ApplicationController
false
end
- def project_view_files?
- if current_user
- current_user.project_view == 'files'
- else
- project_view_files_allowed?
- end
- end
-
# Override extract_ref from ExtractsPath, which returns the branch and file path
# for the blob/tree, which in this case is just the root of the default branch.
# This way we avoid to access the repository.ref_names.
@@ -540,10 +522,6 @@ class ProjectsController < Projects::ApplicationController
project.repository.root_ref
end
- def project_view_files_allowed?
- !project.empty_repo? && can?(current_user, :download_code, project)
- end
-
def build_canonical_path(project)
params[:namespace_id] = project.namespace.to_param
params[:id] = project.to_param
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index a49b82319da..4a42632a980 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -14,12 +14,16 @@ module Registrations
def show
return redirect_to path_for_signed_in_user(current_user) if completed_welcome_step?
+
+ track_event('render')
end
def update
result = ::Users::SignupService.new(current_user, update_params).execute
if result[:status] == :success
+ track_event('successfully_submitted_form')
+
return redirect_to issues_dashboard_path(assignee_username: current_user.username) if show_tasks_to_be_done?
return redirect_to update_success_path if show_signup_onboarding?
@@ -86,6 +90,10 @@ module Registrations
# overridden in EE
def update_success_path
end
+
+ # overridden in EE
+ def track_event(category)
+ end
end
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 995303a631a..11f9f1cf0c6 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -15,10 +15,10 @@ class RegistrationsController < Devise::RegistrationsController
layout 'devise'
prepend_before_action :check_captcha, only: :create
+ before_action :ensure_first_name_and_last_name_not_empty, only: :create
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :init_preferred_language, only: :new
before_action :load_recaptcha, only: :new
- before_action :set_invite_params, only: :new
before_action only: [:create] do
check_rate_limit!(:user_sign_up, scope: request.ip)
end
@@ -32,11 +32,11 @@ class RegistrationsController < Devise::RegistrationsController
def new
@resource = build_resource
+ set_invite_params
end
def create
- set_user_state
- set_custom_confirmation_token
+ set_resource_fields
super do |new_user|
accept_pending_invitations if new_user.persisted?
@@ -111,8 +111,11 @@ class RegistrationsController < Devise::RegistrationsController
super
end
+ # overridden by EE module
def after_request_hook(user)
- # overridden by EE module
+ return unless user.persisted?
+
+ Gitlab::Tracking.event(self.class.name, 'successfully_submitted_form', user: user)
end
def after_sign_up_path_for(user)
@@ -132,6 +135,7 @@ class RegistrationsController < Devise::RegistrationsController
return identity_verification_redirect_path if custom_confirmation_enabled?
+ Gitlab::Tracking.event(self.class.name, 'render', user: resource)
users_almost_there_path(email: resource.email)
end
@@ -172,6 +176,21 @@ class RegistrationsController < Devise::RegistrationsController
render action: 'new'
end
+ def ensure_first_name_and_last_name_not_empty
+ # The key here will be affected by feature flag 'arkose_labs_signup_challenge'
+ # When flag is disabled, the key will be 'user' because #check_captcha will remove 'new_' prefix
+ # When flag is enabled, #check_captcha will be skipped, so the key will have 'new_' prefix
+ first_name = params.dig(resource_name, :first_name) || params.dig("new_#{resource_name}", :first_name)
+ last_name = params.dig(resource_name, :last_name) || params.dig("new_#{resource_name}", :last_name)
+
+ return if first_name.present? && last_name.present?
+
+ resource.errors.add(_('First name'), _("cannot be blank")) if first_name.blank?
+ resource.errors.add(_('Last name'), _("cannot be blank")) if last_name.blank?
+
+ render action: 'new'
+ end
+
def pending_approval?
return false unless Gitlab::CurrentSettings.require_admin_approval_after_user_signup
@@ -211,18 +230,22 @@ class RegistrationsController < Devise::RegistrationsController
Gitlab::Recaptcha.load_configurations!
end
- def set_user_state
+ # overridden by EE module
+ def set_resource_fields
return unless set_blocked_pending_approval?
resource.state = User::BLOCKED_PENDING_APPROVAL_STATE
end
+ # overridden by EE module
def set_blocked_pending_approval?
Gitlab::CurrentSettings.require_admin_approval_after_user_signup
end
def set_invite_params
- @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
+ if resource.email.blank? && params[:invite_email].present?
+ resource.email = @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
+ end
end
def after_pending_invitations_hook
@@ -251,10 +274,6 @@ class RegistrationsController < Devise::RegistrationsController
# overridden by EE module
end
- def set_custom_confirmation_token
- # overridden by EE module
- end
-
def send_custom_confirmation_instructions
# overridden by EE module
end
diff --git a/app/controllers/repositories/lfs_locks_api_controller.rb b/app/controllers/repositories/lfs_locks_api_controller.rb
index f36126d67ff..ea858d63236 100644
--- a/app/controllers/repositories/lfs_locks_api_controller.rb
+++ b/app/controllers/repositories/lfs_locks_api_controller.rb
@@ -54,9 +54,9 @@ module Repositories
def error_payload(message, custom_attrs = {})
custom_attrs.merge({
- message: message,
- documentation_url: help_url
- })
+ message: message,
+ documentation_url: help_url
+ })
end
def split_by_owner(locks)
@@ -72,7 +72,7 @@ module Repositories
end
def upload_request?
- %w(create unlock verify).include?(params[:action])
+ %w[create unlock verify].include?(params[:action])
end
def lfs_params
diff --git a/app/controllers/repositories/lfs_storage_controller.rb b/app/controllers/repositories/lfs_storage_controller.rb
index d54b51b463a..22f1a81b95b 100644
--- a/app/controllers/repositories/lfs_storage_controller.rb
+++ b/app/controllers/repositories/lfs_storage_controller.rb
@@ -49,7 +49,7 @@ module Repositories
validate_uploaded_file!
if store_file!(oid, size)
- head 200, content_type: LfsRequest::CONTENT_TYPE
+ head :ok, content_type: LfsRequest::CONTENT_TYPE
else
render plain: 'Unprocessable entity', status: :unprocessable_entity
end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 5351e3e9e77..66968b34380 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -8,6 +8,7 @@ class SearchController < ApplicationController
include SearchRateLimitable
RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete, :aggregations].freeze
+ CODE_SEARCH_LITERALS = %w[blob: extension: path: filename:].freeze
track_custom_event :show,
name: 'i_search_total',
@@ -32,7 +33,10 @@ class SearchController < ApplicationController
before_action only: :show do
push_frontend_feature_flag(:search_page_vertical_nav, current_user)
end
-
+ before_action only: :show do
+ update_scope_for_code_search
+ end
+ before_action :elasticsearch_in_use, only: :show
rescue_from ActiveRecord::QueryCanceled, with: :render_timeout
layout 'search'
@@ -43,6 +47,7 @@ class SearchController < ApplicationController
def show
@project = search_service.project
@group = search_service.group
+ @search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
return unless search_term_valid?
@@ -51,15 +56,11 @@ class SearchController < ApplicationController
@search_term = params[:search]
@sort = params[:sort] || default_sort
- @search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
-
@search_level = @search_service.level
@search_type = search_type
@global_search_duration_s = Benchmark.realtime do
@scope = @search_service.scope
- @without_count = @search_service.without_count?
- @show_snippets = @search_service.show_snippets?
@search_results = @search_service.search_results
@search_objects = @search_service.search_objects
@search_highlight = @search_service.search_highlight
@@ -118,8 +119,22 @@ class SearchController < ApplicationController
def opensearch
end
+ def elasticsearch_in_use
+ search_service.respond_to?(:use_elasticsearch?) && search_service.use_elasticsearch?
+ end
+ strong_memoize_attr :elasticsearch_in_use
+
private
+ def update_scope_for_code_search
+ return if params[:scope] == 'blobs'
+ return unless params[:search].present?
+
+ if CODE_SEARCH_LITERALS.any? { |literal| literal.in? params[:search] }
+ redirect_to search_path(safe_params.except(:controller, :action).merge(scope: 'blobs'))
+ end
+ end
+
# overridden in EE
def default_sort
'created_desc'
diff --git a/app/controllers/snippets/application_controller.rb b/app/controllers/snippets/application_controller.rb
index f259f4569ef..64adc4e6611 100644
--- a/app/controllers/snippets/application_controller.rb
+++ b/app/controllers/snippets/application_controller.rb
@@ -4,7 +4,7 @@ class Snippets::ApplicationController < ApplicationController
include FindSnippet
include SnippetAuthorizations
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb
index 8a4e8edbf3c..9e23eef4178 100644
--- a/app/controllers/snippets/notes_controller.rb
+++ b/app/controllers/snippets/notes_controller.rb
@@ -8,7 +8,7 @@ class Snippets::NotesController < ApplicationController
before_action :authorize_read_snippet!, only: [:show, :index]
before_action :authorize_create_note!, only: [:create]
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0f03333d793..f23e513e419 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -31,8 +31,7 @@ class UsersController < ApplicationController
:followers, :following, :calendar, :calendar_activities,
:exists, :activity, :follow, :unfollow, :ssh_keys]
- feature_category :snippets, [:snippets]
- feature_category :source_code_management, [:gpg_keys]
+ feature_category :source_code_management, [:snippets, :gpg_keys]
# TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914
urgency :low, [:show, :calendar_activities, :contributed, :activity, :projects, :groups, :calendar, :snippets]
diff --git a/app/controllers/web_ide/remote_ide_controller.rb b/app/controllers/web_ide/remote_ide_controller.rb
new file mode 100644
index 00000000000..fe70e78b1e5
--- /dev/null
+++ b/app/controllers/web_ide/remote_ide_controller.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'uri'
+
+module WebIde
+ class RemoteIdeController < ApplicationController
+ include VSCodeCDNCSP
+
+ rescue_from URI::InvalidComponentError, with: :render_404
+
+ before_action :allow_remote_ide_content_security_policy
+
+ feature_category :remote_development
+
+ urgency :low
+
+ def index
+ return render_404 unless Feature.enabled?(:vscode_web_ide, current_user)
+
+ render layout: 'fullscreen', locals: { minimal: true, data: root_element_data }
+ end
+
+ private
+
+ def allow_remote_ide_content_security_policy
+ return if request.content_security_policy.directives.blank?
+
+ default_src = Array(request.content_security_policy.directives['default-src'] || [])
+
+ request.content_security_policy.directives['connect-src'] ||= default_src
+ request.content_security_policy.directives['connect-src'].concat(connect_src_urls)
+ end
+
+ def connect_src_urls
+ # It's okay if "port" is null
+ host, port = params.require(:remote_host).split(':')
+
+ # This could throw URI::InvalidComponentError. We go ahead and let it throw
+ # and let the controller recover with a bad_request response
+ %w[ws wss http https].map { |scheme| URI::Generic.build(scheme: scheme, host: host, port: port).to_s }
+ end
+
+ def root_element_data
+ {
+ connection_token: params.fetch(:connection_token, ''),
+ remote_host: params.require(:remote_host),
+ remote_path: params.fetch(:remote_path, ''),
+ return_url: params.fetch(:return_url, ''),
+ csp_nonce: content_security_policy_nonce
+ }
+ end
+ end
+end