summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-19 23:18:09 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-19 23:18:09 +0000
commit6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch)
treedc4d20fe6064752c0bd323187252c77e0a89144b /app/controllers
parent9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff)
downloadgitlab-ce-6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde.tar.gz
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/abuse_reports_controller.rb5
-rw-r--r--app/controllers/acme_challenges_controller.rb2
-rw-r--r--app/controllers/admin/application_settings_controller.rb28
-rw-r--r--app/controllers/admin/applications_controller.rb11
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb19
-rw-r--r--app/controllers/admin/cohorts_controller.rb17
-rw-r--r--app/controllers/admin/dashboard_controller.rb9
-rw-r--r--app/controllers/admin/hook_logs_controller.rb37
-rw-r--r--app/controllers/admin/hooks_controller.rb4
-rw-r--r--app/controllers/admin/plan_limits_controller.rb39
-rw-r--r--app/controllers/admin/runners_controller.rb10
-rw-r--r--app/controllers/admin/spam_logs_controller.rb2
-rw-r--r--app/controllers/admin/topics_controller.rb12
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/boards/issues_controller.rb8
-rw-r--r--app/controllers/chaos_controller.rb2
-rw-r--r--app/controllers/concerns/accepts_pending_invitations.rb7
-rw-r--r--app/controllers/concerns/dependency_proxy/group_access.rb2
-rw-r--r--app/controllers/concerns/harbor/access.rb2
-rw-r--r--app/controllers/concerns/integrations/hooks_execution.rb95
-rw-r--r--app/controllers/concerns/issuable_actions.rb5
-rw-r--r--app/controllers/concerns/membership_actions.rb6
-rw-r--r--app/controllers/concerns/packages_access.rb2
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb12
-rw-r--r--app/controllers/concerns/verifies_with_email.rb59
-rw-r--r--app/controllers/concerns/web_hooks/hook_actions.rb85
-rw-r--r--app/controllers/concerns/web_hooks/hook_execution_notice.rb20
-rw-r--r--app/controllers/concerns/web_hooks/hook_log_actions.rb44
-rw-r--r--app/controllers/groups/observability_controller.rb45
-rw-r--r--app/controllers/groups/runners_controller.rb7
-rw-r--r--app/controllers/groups/settings/applications_controller.rb12
-rw-r--r--app/controllers/groups/settings/repository_controller.rb16
-rw-r--r--app/controllers/groups_controller.rb7
-rw-r--r--app/controllers/health_controller.rb10
-rw-r--r--app/controllers/help_controller.rb23
-rw-r--r--app/controllers/ide_controller.rb1
-rw-r--r--app/controllers/import/github_controller.rb2
-rw-r--r--app/controllers/jira_connect/oauth_callbacks_controller.rb2
-rw-r--r--app/controllers/jira_connect/subscriptions_controller.rb11
-rw-r--r--app/controllers/jwt_controller.rb6
-rw-r--r--app/controllers/metrics_controller.rb2
-rw-r--r--app/controllers/oauth/applications_controller.rb11
-rw-r--r--app/controllers/profiles/personal_access_tokens_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb2
-rw-r--r--app/controllers/projects/blame_controller.rb5
-rw-r--r--app/controllers/projects/cycle_analytics_controller.rb16
-rw-r--r--app/controllers/projects/environments_controller.rb34
-rw-r--r--app/controllers/projects/google_cloud/base_controller.rb28
-rw-r--r--app/controllers/projects/google_cloud/configuration_controller.rb2
-rw-r--r--app/controllers/projects/google_cloud/databases_controller.rb129
-rw-r--r--app/controllers/projects/google_cloud/deployments_controller.rb12
-rw-r--r--app/controllers/projects/google_cloud/gcp_regions_controller.rb6
-rw-r--r--app/controllers/projects/google_cloud/revoke_oauth_controller.rb4
-rw-r--r--app/controllers/projects/google_cloud/service_accounts_controller.rb14
-rw-r--r--app/controllers/projects/graphs_controller.rb16
-rw-r--r--app/controllers/projects/hook_logs_controller.rb27
-rw-r--r--app/controllers/projects/hooks_controller.rb4
-rw-r--r--app/controllers/projects/incidents_controller.rb3
-rw-r--r--app/controllers/projects/integrations/shimos_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb26
-rw-r--r--app/controllers/projects/jobs_controller.rb9
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb17
-rw-r--r--app/controllers/projects/merge_requests/drafts_controller.rb30
-rw-r--r--app/controllers/projects/merge_requests_controller.rb24
-rw-r--r--app/controllers/projects/packages/package_files_controller.rb1
-rw-r--r--app/controllers/projects/pipelines/tests_controller.rb3
-rw-r--r--app/controllers/projects/pipelines_controller.rb25
-rw-r--r--app/controllers/projects/runners_controller.rb6
-rw-r--r--app/controllers/projects/settings/integration_hook_logs_controller.rb10
-rw-r--r--app/controllers/projects/settings/integrations_controller.rb13
-rw-r--r--app/controllers/projects/settings/merge_requests_controller.rb67
-rw-r--r--app/controllers/projects/settings/repository_controller.rb5
-rw-r--r--app/controllers/projects/uploads_controller.rb10
-rw-r--r--app/controllers/projects_controller.rb25
-rw-r--r--app/controllers/registrations_controller.rb22
-rw-r--r--app/controllers/repositories/git_http_client_controller.rb6
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/controllers/search_controller.rb18
78 files changed, 882 insertions, 444 deletions
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
index 206a5b11e4b..0de2115d4d6 100644
--- a/app/controllers/abuse_reports_controller.rb
+++ b/app/controllers/abuse_reports_controller.rb
@@ -30,10 +30,7 @@ class AbuseReportsController < ApplicationController
private
def report_params
- params.require(:abuse_report).permit(%i(
- message
- user_id
- ))
+ params.require(:abuse_report).permit(:message, :user_id)
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/acme_challenges_controller.rb b/app/controllers/acme_challenges_controller.rb
index 67a39d8870b..4a7706db94e 100644
--- a/app/controllers/acme_challenges_controller.rb
+++ b/app/controllers/acme_challenges_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class AcmeChallengesController < ActionController::Base
def show
if acme_order
@@ -15,3 +16,4 @@ class AcmeChallengesController < ActionController::Base
@acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token])
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 6f21b123eb0..b75a7c4a2dd 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -18,23 +18,23 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end
feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
- :general, :reporting, :metrics_and_profiling, :network,
- :preferences, :update, :reset_health_check_token
- ]
+ :general, :reporting, :metrics_and_profiling, :network,
+ :preferences, :update, :reset_health_check_token
+ ]
feature_category :metrics, [
- :create_self_monitoring_project,
- :status_create_self_monitoring_project,
- :delete_self_monitoring_project,
- :status_delete_self_monitoring_project
- ]
+ :create_self_monitoring_project,
+ :status_create_self_monitoring_project,
+ :delete_self_monitoring_project,
+ :status_delete_self_monitoring_project
+ ]
urgency :low, [
- :create_self_monitoring_project,
- :status_create_self_monitoring_project,
- :delete_self_monitoring_project,
- :status_delete_self_monitoring_project,
- :reset_error_tracking_access_token
- ]
+ :create_self_monitoring_project,
+ :status_create_self_monitoring_project,
+ :delete_self_monitoring_project,
+ :status_delete_self_monitoring_project,
+ :reset_error_tracking_access_token
+ ]
feature_category :source_code_management, [:repository, :clear_repository_check_states]
feature_category :continuous_integration, [:ci_cd, :reset_registration_token]
diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb
index b0d7c8cb8f2..d66b3cb4366 100644
--- a/app/controllers/admin/applications_controller.rb
+++ b/app/controllers/admin/applications_controller.rb
@@ -14,7 +14,7 @@ class Admin::ApplicationsController < Admin::ApplicationController
end
def show
- @created = get_created_session
+ @created = get_created_session if Feature.disabled?('hash_oauth_secrets')
end
def new
@@ -30,9 +30,14 @@ class Admin::ApplicationsController < Admin::ApplicationController
if @application.persisted?
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
- set_created_session
+ if Feature.enabled?('hash_oauth_secrets')
+ @created = true
+ render :show
+ else
+ set_created_session
- redirect_to admin_application_url(@application)
+ redirect_to admin_application_url(@application)
+ end
else
render :new
end
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index a53e832329f..251ba9e29f2 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -57,14 +57,15 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
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: [])
+ 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
end
diff --git a/app/controllers/admin/cohorts_controller.rb b/app/controllers/admin/cohorts_controller.rb
index 468a1077694..ce3d769f35e 100644
--- a/app/controllers/admin/cohorts_controller.rb
+++ b/app/controllers/admin/cohorts_controller.rb
@@ -1,15 +1,20 @@
# frozen_string_literal: true
class Admin::CohortsController < Admin::ApplicationController
- include RedisTracking
+ include ProductAnalyticsTracking
feature_category :devops_reports
urgency :low
+ track_custom_event :index,
+ name: 'i_analytics_cohorts',
+ action: 'perform_analytics_usage_action',
+ label: 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly',
+ destinations: %i[redis_hll snowplow]
+
def index
@cohorts = load_cohorts
- track_cohorts_visit
end
private
@@ -22,7 +27,11 @@ class Admin::CohortsController < Admin::ApplicationController
CohortsSerializer.new.represent(cohorts_results)
end
- def track_cohorts_visit
- track_unique_redis_hll_event('i_analytics_cohorts') if trackable_html_request?
+ def tracking_namespace_source
+ nil
+ end
+
+ def tracking_project_source
+ nil
end
end
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index 8fe106249c3..37dde065e70 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -14,14 +14,7 @@ class Admin::DashboardController < Admin::ApplicationController
@groups = Group.order_id_desc.with_route.limit(10)
@notices = Gitlab::ConfigChecker::PumaRuggedChecker.check
@notices += Gitlab::ConfigChecker::ExternalDatabaseChecker.check
- @redis_versions = [
- Gitlab::Redis::Queues,
- Gitlab::Redis::SharedState,
- Gitlab::Redis::Cache,
- Gitlab::Redis::TraceChunks,
- Gitlab::Redis::RateLimiting,
- Gitlab::Redis::Sessions
- ].map(&:version).uniq
+ @redis_versions = Gitlab::Redis::ALL_CLASSES.map(&:version).uniq
end
def stats
diff --git a/app/controllers/admin/hook_logs_controller.rb b/app/controllers/admin/hook_logs_controller.rb
index aa13673095d..a283d3abb0b 100644
--- a/app/controllers/admin/hook_logs_controller.rb
+++ b/app/controllers/admin/hook_logs_controller.rb
@@ -1,34 +1,17 @@
# frozen_string_literal: true
-class Admin::HookLogsController < Admin::ApplicationController
- include ::Integrations::HooksExecution
+module Admin
+ class HookLogsController < Admin::ApplicationController
+ include WebHooks::HookLogActions
- before_action :hook, only: [:show, :retry]
- before_action :hook_log, only: [:show, :retry]
+ private
- respond_to :html
+ def hook
+ @hook ||= SystemHook.find(params[:hook_id])
+ end
- feature_category :integrations
- urgency :low, [:retry]
-
- def show
- end
-
- def retry
- result = hook.execute(hook_log.request_data, hook_log.trigger)
-
- set_hook_execution_notice(result)
-
- redirect_to edit_admin_hook_path(@hook)
- end
-
- private
-
- def hook
- @hook ||= SystemHook.find(params[:hook_id])
- end
-
- def hook_log
- @hook_log ||= hook.web_hook_logs.find(params[:id])
+ def after_retry_redirect_path
+ edit_admin_hook_path(hook)
+ end
end
end
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index 810801d4209..1dc6c68d8ca 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Admin::HooksController < Admin::ApplicationController
- include ::Integrations::HooksExecution
+ include ::WebHooks::HookActions
before_action :hook_logs, only: :edit
@@ -27,7 +27,7 @@ class Admin::HooksController < Admin::ApplicationController
end
def hook_logs
- @hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
+ @hook_logs ||= hook.web_hook_logs.recent.page(params[:page]).without_count
end
def hook_param_names
diff --git a/app/controllers/admin/plan_limits_controller.rb b/app/controllers/admin/plan_limits_controller.rb
index 7bfbabe8dfc..2cebc059830 100644
--- a/app/controllers/admin/plan_limits_controller.rb
+++ b/app/controllers/admin/plan_limits_controller.rb
@@ -28,24 +28,25 @@ class Admin::PlanLimitsController < Admin::ApplicationController
end
def plan_limits_params
- params.require(:plan_limits).permit(%i[
- plan_id
- conan_max_file_size
- helm_max_file_size
- maven_max_file_size
- npm_max_file_size
- nuget_max_file_size
- pypi_max_file_size
- terraform_module_max_file_size
- generic_packages_max_file_size
- ci_pipeline_size
- ci_active_jobs
- ci_active_pipelines
- ci_project_subscriptions
- ci_pipeline_schedules
- ci_needs_size_limit
- ci_registered_group_runners
- ci_registered_project_runners
- ])
+ params.require(:plan_limits)
+ .permit(%i[
+ plan_id
+ conan_max_file_size
+ helm_max_file_size
+ maven_max_file_size
+ npm_max_file_size
+ nuget_max_file_size
+ pypi_max_file_size
+ terraform_module_max_file_size
+ generic_packages_max_file_size
+ ci_pipeline_size
+ ci_active_jobs
+ ci_active_pipelines
+ ci_project_subscriptions
+ ci_pipeline_schedules
+ ci_needs_size_limit
+ ci_registered_group_runners
+ ci_registered_project_runners
+ ])
end
end
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 24d7bd9ca7b..a0f72f5e58c 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -8,6 +8,10 @@ class Admin::RunnersController < Admin::ApplicationController
push_frontend_feature_flag(:admin_runners_bulk_delete)
end
+ before_action only: [:show] do
+ push_frontend_feature_flag(:enforce_runner_token_expires_at)
+ end
+
feature_category :runner
urgency :low
@@ -22,7 +26,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def update
- if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
respond_to do |format|
format.html { redirect_to edit_admin_runner_path(@runner) }
end
@@ -39,7 +43,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def resume
- if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: true).success?
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
@@ -47,7 +51,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def pause
- if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: false).success?
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb
index e4e866a8b60..3a55fc4b951 100644
--- a/app/controllers/admin/spam_logs_controller.rb
+++ b/app/controllers/admin/spam_logs_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Admin::SpamLogsController < Admin::ApplicationController
- feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
+ feature_category :instance_resiliency
# rubocop: disable CodeReuse/ActiveRecord
def index
diff --git a/app/controllers/admin/topics_controller.rb b/app/controllers/admin/topics_controller.rb
index 69bcfdf4791..e97ead12f71 100644
--- a/app/controllers/admin/topics_controller.rb
+++ b/app/controllers/admin/topics_controller.rb
@@ -49,16 +49,12 @@ class Admin::TopicsController < Admin::ApplicationController
source_topic = Projects::Topic.find(merge_params[:source_topic_id])
target_topic = Projects::Topic.find(merge_params[:target_topic_id])
- begin
- ::Topics::MergeService.new(source_topic, target_topic).execute
- rescue ArgumentError => e
- return render status: :bad_request, json: { type: :alert, message: e.message }
- end
+ response = ::Topics::MergeService.new(source_topic, target_topic).execute
+ return render status: :bad_request, json: { type: :alert, message: response.message } if response.error?
message = _('Topic %{source_topic} was successfully merged into topic %{target_topic}.')
- redirect_to admin_topics_path,
- status: :found,
- notice: message % { source_topic: source_topic.name, target_topic: target_topic.name }
+ flash[:toast] = message % { source_topic: source_topic.name, target_topic: target_topic.name }
+ redirect_to admin_topics_path, status: :found
end
private
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 5cc0c8f3970..1a57d271271 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -105,7 +105,7 @@ class Admin::UsersController < Admin::ApplicationController
return redirect_back_or_admin_user(notice: _("Error occurred. A blocked user cannot be deactivated")) if user.blocked?
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: ::User::MINIMUM_INACTIVE_DAYS }) 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 }) unless user.can_be_deactivated?
user.deactivate
redirect_back_or_admin_user(notice: _("Successfully deactivated"))
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb
index 11377df7a10..5028544795c 100644
--- a/app/controllers/boards/issues_controller.rb
+++ b/app/controllers/boards/issues_controller.rb
@@ -77,10 +77,10 @@ module Boards
:milestone,
:assignees,
project: [
- :route,
- {
- namespace: [:route]
- }
+ :route,
+ {
+ namespace: [:route]
+ }
],
labels: [:priorities],
notes: [:award_emoji, :author]
diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb
index 4e5af1945a4..6139168d29f 100644
--- a/app/controllers/chaos_controller.rb
+++ b/app/controllers/chaos_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class ChaosController < ActionController::Base
before_action :validate_chaos_secret, unless: :development_or_test?
@@ -93,3 +94,4 @@ class ChaosController < ActionController::Base
Rails.env.development? || Rails.env.test?
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/concerns/accepts_pending_invitations.rb b/app/controllers/concerns/accepts_pending_invitations.rb
index 53dec698fa0..1723058c217 100644
--- a/app/controllers/concerns/accepts_pending_invitations.rb
+++ b/app/controllers/concerns/accepts_pending_invitations.rb
@@ -8,7 +8,6 @@ module AcceptsPendingInvitations
if user.pending_invitations.load.any?
user.accept_pending_invitations!
- clear_stored_location_for(user: user)
after_pending_invitations_hook
end
end
@@ -16,10 +15,4 @@ module AcceptsPendingInvitations
def after_pending_invitations_hook
# no-op
end
-
- def clear_stored_location_for(user:)
- session_key = stored_location_key_for(user)
-
- session.delete(session_key)
- end
end
diff --git a/app/controllers/concerns/dependency_proxy/group_access.rb b/app/controllers/concerns/dependency_proxy/group_access.rb
index 45392625e45..e9fb2563e42 100644
--- a/app/controllers/concerns/dependency_proxy/group_access.rb
+++ b/app/controllers/concerns/dependency_proxy/group_access.rb
@@ -20,3 +20,5 @@ module DependencyProxy
end
end
end
+
+DependencyProxy::GroupAccess.prepend_mod_with('DependencyProxy::GroupAccess')
diff --git a/app/controllers/concerns/harbor/access.rb b/app/controllers/concerns/harbor/access.rb
index 70de72f15fc..211566aeda7 100644
--- a/app/controllers/concerns/harbor/access.rb
+++ b/app/controllers/concerns/harbor/access.rb
@@ -17,7 +17,7 @@ module Harbor
private
def harbor_registry_enabled!
- render_404 unless Feature.enabled?(:harbor_registry_integration)
+ render_404 unless Feature.enabled?(:harbor_registry_integration, defined?(group) ? group : project)
end
def authorize_read_harbor_registry!
diff --git a/app/controllers/concerns/integrations/hooks_execution.rb b/app/controllers/concerns/integrations/hooks_execution.rb
deleted file mode 100644
index fb26840168f..00000000000
--- a/app/controllers/concerns/integrations/hooks_execution.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: true
-
-module Integrations::HooksExecution
- extend ActiveSupport::Concern
-
- included do
- attr_writer :hooks, :hook
- end
-
- def index
- self.hooks = relation.select(&:persisted?)
- self.hook = relation.new
- end
-
- def create
- self.hook = relation.new(hook_params)
- hook.save
-
- unless hook.valid?
- self.hooks = relation.select(&:persisted?)
- flash[:alert] = hook.errors.full_messages.join.html_safe
- end
-
- redirect_to action: :index
- end
-
- def update
- if hook.update(hook_params)
- flash[:notice] = _('Hook was successfully updated.')
- redirect_to action: :index
- else
- render 'edit'
- end
- end
-
- def destroy
- destroy_hook(hook)
-
- redirect_to action: :index, status: :found
- end
-
- def edit
- redirect_to(action: :index) unless hook
- end
-
- private
-
- def hook_params
- permitted = hook_param_names + trigger_values
- permitted << { url_variables: [:key, :value] }
-
- ps = params.require(:hook).permit(*permitted).to_h
-
- ps[:url_variables] = ps[:url_variables].to_h { [_1[:key], _1[:value].presence] } if ps.key?(:url_variables)
-
- if action_name == 'update' && ps.key?(:url_variables)
- supplied = ps[:url_variables]
- ps[:url_variables] = hook.url_variables.merge(supplied).compact
- end
-
- ps
- end
-
- def hook_param_names
- %i[enable_ssl_verification token url push_events_branch_filter]
- end
-
- def destroy_hook(hook)
- result = WebHooks::DestroyService.new(current_user).execute(hook)
-
- if result[:status] == :success
- flash[:notice] =
- if result[:async]
- _("%{hook_type} was scheduled for deletion") % { hook_type: hook.model_name.human }
- else
- _("%{hook_type} was deleted") % { hook_type: hook.model_name.human }
- end
- else
- flash[:alert] = result[:message]
- end
- end
-
- def set_hook_execution_notice(result)
- http_status = result[:http_status]
- message = result[:message]
-
- if http_status && http_status >= 200 && http_status < 400
- flash[:notice] = "Hook executed successfully: HTTP #{http_status}"
- elsif http_status
- flash[:alert] = "Hook executed successfully but returned HTTP #{http_status} #{message}"
- else
- flash[:alert] = "Hook execution failed: #{message}"
- end
- end
-end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index f1d80e37674..7c3401a7e90 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -193,7 +193,10 @@ module IssuableActions
end
def render_cached_discussions(discussions, serializer, cache_context)
- render_cached(discussions, with: serializer, cache_context: -> (_) { cache_context }, context: self)
+ render_cached(discussions,
+ with: serializer,
+ cache_context: -> (_) { cache_context },
+ context: self)
end
def paginated_discussions
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index fb11bece79c..8a67b62f28b 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -150,7 +150,11 @@ module MembershipActions
when 'only'
[:inherited]
else
- [:inherited, :direct]
+ if Feature.enabled?(:webui_members_inherited_users, current_user)
+ [:inherited, :direct, :shared_from_groups]
+ else
+ [:inherited, :direct]
+ end
end
end
end
diff --git a/app/controllers/concerns/packages_access.rb b/app/controllers/concerns/packages_access.rb
index 6df2e064bb2..a7d16a5bc88 100644
--- a/app/controllers/concerns/packages_access.rb
+++ b/app/controllers/concerns/packages_access.rb
@@ -15,6 +15,6 @@ module PackagesAccess
end
def verify_read_package!
- authorize_read_package!(project)
+ access_denied! unless can?(current_user, :read_package, project&.packages_policy_subject)
end
end
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
index 260b433cc6f..8e936782e5a 100644
--- a/app/controllers/concerns/product_analytics_tracking.rb
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -66,7 +66,17 @@ module ProductAnalyticsTracking
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
+ 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
}
Feature.enabled?(events_to_ff[event.to_sym], tracking_namespace_source)
diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb
index 1a3e7136481..782cae53c3f 100644
--- a/app/controllers/concerns/verifies_with_email.rb
+++ b/app/controllers/concerns/verifies_with_email.rb
@@ -7,11 +7,9 @@ module VerifiesWithEmail
extend ActiveSupport::Concern
include ActionView::Helpers::DateHelper
- TOKEN_LENGTH = 6
- TOKEN_VALID_FOR_MINUTES = 60
-
included do
prepend_before_action :verify_with_email, only: :create, unless: -> { two_factor_enabled? }
+ skip_before_action :required_signup_info, only: :successful_verification
end
def verify_with_email
@@ -76,7 +74,8 @@ module VerifiesWithEmail
def send_verification_instructions(user)
return if send_rate_limited?(user)
- raw_token, encrypted_token = generate_token
+ service = Users::EmailVerification::GenerateTokenService.new(attr: :unlock_token)
+ raw_token, encrypted_token = service.execute
user.unlock_token = encrypted_token
user.lock_access!({ send_instructions: false })
send_verification_instructions_email(user, raw_token)
@@ -88,27 +87,20 @@ module VerifiesWithEmail
Notify.verification_instructions_email(
user.id,
token: token,
- expires_in: TOKEN_VALID_FOR_MINUTES).deliver_later
+ expires_in: Users::EmailVerification::ValidateTokenService::TOKEN_VALID_FOR_MINUTES).deliver_later
log_verification(user, :instructions_sent)
end
def verify_token(user, token)
- return handle_verification_failure(user, :rate_limited) if verification_rate_limited?(user)
- return handle_verification_failure(user, :invalid) unless valid_token?(user, token)
- return handle_verification_failure(user, :expired) if expired_token?(user)
-
- handle_verification_success(user)
- end
-
- def generate_token
- raw_token = SecureRandom.random_number(10**TOKEN_LENGTH).to_s.rjust(TOKEN_LENGTH, '0')
- encrypted_token = digest_token(raw_token)
- [raw_token, encrypted_token]
- end
+ service = Users::EmailVerification::ValidateTokenService.new(attr: :unlock_token, user: user, token: token)
+ result = service.execute
- def digest_token(token)
- Devise.token_generator.digest(User, :unlock_token, token)
+ if result[:status] == :success
+ handle_verification_success(user)
+ else
+ handle_verification_failure(user, result[:reason], result[:message])
+ end
end
def render_sign_in_rate_limited
@@ -122,44 +114,17 @@ module VerifiesWithEmail
distance_of_time_in_words(interval_in_seconds)
end
- def verification_rate_limited?(user)
- Gitlab::ApplicationRateLimiter.throttled?(:email_verification, scope: user.unlock_token)
- end
-
def send_rate_limited?(user)
Gitlab::ApplicationRateLimiter.throttled?(:email_verification_code_send, scope: user)
end
- def expired_token?(user)
- user.locked_at < (Time.current - TOKEN_VALID_FOR_MINUTES.minutes)
- end
-
- def valid_token?(user, token)
- user.unlock_token == digest_token(token)
- end
-
- def handle_verification_failure(user, reason)
- message = case reason
- when :rate_limited
- s_("IdentityVerification|You've reached the maximum amount of tries. "\
- 'Wait %{interval} or resend a new code and try again.') % { interval: email_verification_interval }
- when :expired
- s_('IdentityVerification|The code has expired. Resend a new code and try again.')
- when :invalid
- s_('IdentityVerification|The code is incorrect. Enter it again, or resend a new code.')
- end
-
+ def handle_verification_failure(user, reason, message)
user.errors.add(:base, message)
log_verification(user, :failed_attempt, reason)
prompt_for_email_verification(user)
end
- def email_verification_interval
- interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:email_verification][:interval]
- distance_of_time_in_words(interval_in_seconds)
- end
-
def handle_verification_success(user)
user.unlock_access!
log_verification(user, :successful)
diff --git a/app/controllers/concerns/web_hooks/hook_actions.rb b/app/controllers/concerns/web_hooks/hook_actions.rb
new file mode 100644
index 00000000000..ea11f13c7ef
--- /dev/null
+++ b/app/controllers/concerns/web_hooks/hook_actions.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module WebHooks
+ module HookActions
+ extend ActiveSupport::Concern
+ include HookExecutionNotice
+
+ included do
+ attr_writer :hooks, :hook
+ end
+
+ def index
+ self.hooks = relation.select(&:persisted?)
+ self.hook = relation.new
+ end
+
+ def create
+ self.hook = relation.new(hook_params)
+ hook.save
+
+ unless hook.valid?
+ self.hooks = relation.select(&:persisted?)
+ flash[:alert] = hook.errors.full_messages.join.html_safe
+ end
+
+ redirect_to action: :index
+ end
+
+ def update
+ if hook.update(hook_params)
+ flash[:notice] = _('Hook was successfully updated.')
+ redirect_to action: :index
+ else
+ render 'edit'
+ end
+ end
+
+ def destroy
+ destroy_hook(hook)
+
+ redirect_to action: :index, status: :found
+ end
+
+ def edit
+ redirect_to(action: :index) unless hook
+ end
+
+ private
+
+ def hook_params
+ permitted = hook_param_names + trigger_values
+ permitted << { url_variables: [:key, :value] }
+
+ ps = params.require(:hook).permit(*permitted).to_h
+
+ ps[:url_variables] = ps[:url_variables].to_h { [_1[:key], _1[:value].presence] } if ps.key?(:url_variables)
+
+ if action_name == 'update' && ps.key?(:url_variables)
+ supplied = ps[:url_variables]
+ ps[:url_variables] = hook.url_variables.merge(supplied).compact
+ end
+
+ ps
+ end
+
+ def hook_param_names
+ %i[enable_ssl_verification token url push_events_branch_filter]
+ 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
+ else
+ flash[:alert] = result[:message]
+ end
+ end
+ end
+end
diff --git a/app/controllers/concerns/web_hooks/hook_execution_notice.rb b/app/controllers/concerns/web_hooks/hook_execution_notice.rb
new file mode 100644
index 00000000000..d651313b30d
--- /dev/null
+++ b/app/controllers/concerns/web_hooks/hook_execution_notice.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module WebHooks
+ module HookExecutionNotice
+ private
+
+ def set_hook_execution_notice(result)
+ http_status = result[:http_status]
+ message = result[:message]
+
+ if http_status && http_status >= 200 && http_status < 400
+ flash[:notice] = "Hook executed successfully: HTTP #{http_status}"
+ elsif http_status
+ flash[:alert] = "Hook executed successfully but returned HTTP #{http_status} #{message}"
+ else
+ flash[:alert] = "Hook execution failed: #{message}"
+ end
+ end
+ end
+end
diff --git a/app/controllers/concerns/web_hooks/hook_log_actions.rb b/app/controllers/concerns/web_hooks/hook_log_actions.rb
new file mode 100644
index 00000000000..f3378d7c857
--- /dev/null
+++ b/app/controllers/concerns/web_hooks/hook_log_actions.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module WebHooks
+ module HookLogActions
+ extend ActiveSupport::Concern
+ include HookExecutionNotice
+
+ included do
+ before_action :hook, only: [:show, :retry]
+ before_action :hook_log, only: [:show, :retry]
+
+ respond_to :html
+
+ feature_category :integrations
+ urgency :low, [:retry]
+ end
+
+ def show
+ hide_search_settings
+ end
+
+ def retry
+ execute_hook
+ redirect_to after_retry_redirect_path
+ end
+
+ private
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def hook_log
+ @hook_log ||= hook.web_hook_logs.find(params[:id])
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def execute_hook
+ result = hook.execute(hook_log.request_data, hook_log.trigger)
+ set_hook_execution_notice(result)
+ end
+
+ def hide_search_settings
+ @hide_search_settings ||= true
+ end
+ end
+end
diff --git a/app/controllers/groups/observability_controller.rb b/app/controllers/groups/observability_controller.rb
new file mode 100644
index 00000000000..5b6503494c4
--- /dev/null
+++ b/app/controllers/groups/observability_controller.rb
@@ -0,0 +1,45 @@
+# 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']
+
+ # 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) | [ObservabilityController.observability_url, "'self'"]
+
+ p.frame_src(*frame_src_values)
+ end
+
+ before_action :check_observability_allowed, only: :index
+
+ def index
+ # Format: https://observe.gitlab.com/-/GROUP_ID
+ @observability_iframe_src = "#{ObservabilityController.observability_url}/-/#{@group.id}"
+
+ # Uncomment below for testing with local GDK
+ # @observability_iframe_src = "#{ObservabilityController.observability_url}/9970?groupId=14485840"
+
+ render layout: 'group', locals: { base_layout: 'layouts/fullscreen' }
+ end
+
+ private
+
+ def self.observability_url
+ return ENV['OVERRIDE_OBSERVABILITY_URL'] if ENV['OVERRIDE_OBSERVABILITY_URL']
+ # TODO Make observability URL configurable https://gitlab.com/gitlab-org/opstrace/opstrace-ui/-/issues/80
+ return "https://staging.observe.gitlab.com" if Gitlab.staging?
+
+ "https://observe.gitlab.com"
+ end
+
+ def check_observability_allowed
+ return render_404 unless self.class.observability_url.present?
+
+ render_404 unless can?(current_user, :read_observability, @group)
+ end
+ end
+end
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index aeb54527c69..652f12e34ba 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -5,12 +5,17 @@ class Groups::RunnersController < Groups::ApplicationController
before_action :authorize_admin_group_runners!, only: [:edit, :update, :destroy, :pause, :resume]
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
+ before_action only: [:show] do
+ push_frontend_feature_flag(:enforce_runner_token_expires_at)
+ end
+
feature_category :runner
urgency :low
def index
finder = Ci::RunnersFinder.new(current_user: current_user, params: { group: @group })
@group_runners_limited_count = finder.execute.except(:limit, :offset).page.total_count_with_limit(:all, limit: 1000)
+ @group_runner_registration_token = @group.runners_token if can?(current_user, :register_group_runners, group)
Gitlab::Tracking.event(self.class.name, 'index', user: current_user, namespace: @group)
end
@@ -22,7 +27,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def update
- if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
redirect_to group_runner_path(@group, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
diff --git a/app/controllers/groups/settings/applications_controller.rb b/app/controllers/groups/settings/applications_controller.rb
index bfe61696e0f..3557d485422 100644
--- a/app/controllers/groups/settings/applications_controller.rb
+++ b/app/controllers/groups/settings/applications_controller.rb
@@ -16,7 +16,7 @@ module Groups
end
def show
- @created = get_created_session
+ @created = get_created_session if Feature.disabled?('hash_oauth_secrets')
end
def edit
@@ -28,9 +28,15 @@ module Groups
if @application.persisted?
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
- set_created_session
+ if Feature.enabled?('hash_oauth_secrets')
- redirect_to group_settings_application_url(@group, @application)
+ @created = true
+ render :show
+ else
+ set_created_session
+
+ redirect_to group_settings_application_url(@group, @application)
+ end
else
set_index_vars
render :index
diff --git a/app/controllers/groups/settings/repository_controller.rb b/app/controllers/groups/settings/repository_controller.rb
index b0431c31179..cb62ea2a543 100644
--- a/app/controllers/groups/settings/repository_controller.rb
+++ b/app/controllers/groups/settings/repository_controller.rb
@@ -5,8 +5,9 @@ module Groups
class RepositoryController < Groups::ApplicationController
layout 'group_settings'
skip_cross_project_access_check :show
- before_action :authorize_create_deploy_token!
- before_action :define_deploy_token_variables
+ before_action :authorize_create_deploy_token!, only: :create_deploy_token
+ before_action :authorize_access!, only: :show
+ before_action :define_deploy_token_variables, if: -> { can?(current_user, :create_deploy_token, @group) }
before_action do
push_frontend_feature_flag(:ajax_new_deploy_token, @group)
end
@@ -16,13 +17,13 @@ module Groups
def create_deploy_token
result = Groups::DeployTokens::CreateService.new(@group, current_user, deploy_token_params).execute
- @new_deploy_token = result[:deploy_token]
if result[:status] == :success
+ @created_deploy_token = result[:deploy_token]
respond_to do |format|
format.json do
# IMPORTANT: It's a security risk to expose the token value more than just once here!
- json = API::Entities::DeployTokenWithToken.represent(@new_deploy_token).as_json
+ json = API::Entities::DeployTokenWithToken.represent(@created_deploy_token).as_json
render json: json, status: result[:http_status]
end
format.html do
@@ -31,6 +32,7 @@ module Groups
end
end
else
+ @new_deploy_token = result[:deploy_token]
respond_to do |format|
format.json { render json: { message: result[:message] }, status: result[:http_status] }
format.html do
@@ -43,6 +45,10 @@ module Groups
private
+ def authorize_access!
+ authorize_admin_group!
+ end
+
def define_deploy_token_variables
@deploy_tokens = @group.deploy_tokens.active
@@ -55,3 +61,5 @@ module Groups
end
end
end
+
+Groups::Settings::RepositoryController.prepend_mod
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 32b187c3260..9316204d89c 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -49,9 +49,9 @@ class GroupsController < Groups::ApplicationController
layout :determine_layout
feature_category :subgroups, [
- :index, :new, :create, :show, :edit, :update,
- :destroy, :details, :transfer, :activity
- ]
+ :index, :new, :create, :show, :edit, :update,
+ :destroy, :details, :transfer, :activity
+ ]
feature_category :team_planning, [:issues, :issues_calendar, :preview_markdown]
feature_category :code_review, [:merge_requests, :unfoldered_environment_names]
@@ -276,6 +276,7 @@ class GroupsController < Groups::ApplicationController
:avatar,
:description,
:emails_disabled,
+ :show_diff_preview_in_email,
:mentions_disabled,
:lfs_enabled,
:name,
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index 071378f266e..5fac7c0d663 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class HealthController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
include RequiresWhitelistedMonitoringClient
@@ -11,13 +12,7 @@ class HealthController < ActionController::Base
ALL_CHECKS = [
*CHECKS,
Gitlab::HealthChecks::DbCheck,
- Gitlab::HealthChecks::Redis::RedisCheck,
- Gitlab::HealthChecks::Redis::CacheCheck,
- Gitlab::HealthChecks::Redis::QueuesCheck,
- Gitlab::HealthChecks::Redis::SharedStateCheck,
- Gitlab::HealthChecks::Redis::TraceChunksCheck,
- Gitlab::HealthChecks::Redis::RateLimitingCheck,
- Gitlab::HealthChecks::Redis::SessionsCheck,
+ *Gitlab::HealthChecks::Redis::ALL_INSTANCE_CHECKS,
Gitlab::HealthChecks::GitalyCheck
].freeze
@@ -45,3 +40,4 @@ class HealthController < ActionController::Base
render json: result.json, status: result.http_status
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 1508531828d..9635e476510 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -12,8 +12,7 @@ class HelpController < ApplicationController
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m.freeze
def index
- # Remove YAML frontmatter so that it doesn't look weird
- @help_index = File.read(path_to_doc('index.md')).sub(YAML_FRONT_MATTER_REGEXP, '')
+ @help_index = get_markdown_without_frontmatter(path_to_doc('index.md'))
# Prefix Markdown links with `help/` unless they are external links.
# '//' not necessarily part of URL, e.g., mailto:mail@example.com
@@ -59,8 +58,25 @@ class HelpController < ApplicationController
@instance_configuration = InstanceConfiguration.new
end
+ def drawers
+ @clean_path = Rack::Utils.clean_path_info(params[:markdown_file])
+ @path = path_to_doc("#{@clean_path}.md")
+
+ if File.exist?(@path)
+ render :drawers, formats: :html, layout: false
+ else
+ head :not_found
+ end
+ end
+
private
+ # Remove YAML frontmatter so that it doesn't look weird
+ helper_method :get_markdown_without_frontmatter
+ def get_markdown_without_frontmatter(path)
+ File.read(path).gsub(YAML_FRONT_MATTER_REGEXP, '')
+ end
+
def redirect_to_documentation_website?
Gitlab::UrlSanitizer.valid_web?(documentation_url)
end
@@ -100,8 +116,7 @@ class HelpController < ApplicationController
path = path_to_doc("#{@path}.md")
if File.exist?(path)
- # Remove YAML frontmatter so that it doesn't look weird
- @markdown = File.read(path).gsub(YAML_FRONT_MATTER_REGEXP, '')
+ @markdown = get_markdown_without_frontmatter(path)
render :show, formats: :html
else
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index 9fcb8385312..58a985cbc46 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -13,6 +13,7 @@ class IdeController < ApplicationController
push_frontend_feature_flag(:build_service_proxy)
push_frontend_feature_flag(:schema_linting)
push_frontend_feature_flag(:reject_unsigned_commits_by_gitlab)
+ push_frontend_feature_flag(:vscode_web_ide, current_user)
define_index_vars
end
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 9cc58ce542c..8a3e6809736 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -130,7 +130,7 @@ class Import::GithubController < Import::BaseController
if sanitized_filter_param
client.search_repos_by_name(sanitized_filter_param, pagination_options)[:items]
else
- client.octokit.repos(nil, pagination_options)
+ client.repos(pagination_options)
end
else
filtered(client.repos)
diff --git a/app/controllers/jira_connect/oauth_callbacks_controller.rb b/app/controllers/jira_connect/oauth_callbacks_controller.rb
index f603a563402..e1a47a12b6d 100644
--- a/app/controllers/jira_connect/oauth_callbacks_controller.rb
+++ b/app/controllers/jira_connect/oauth_callbacks_controller.rb
@@ -7,5 +7,7 @@
class JiraConnect::OauthCallbacksController < ApplicationController
feature_category :integrations
+ skip_before_action :authenticate_user!
+
def index; end
end
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index 623113f8413..9305f46c39e 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -64,10 +64,12 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
private
def allow_self_managed_content_security_policy
+ return unless Feature.enabled?(:jira_connect_oauth_self_managed)
+
return unless current_jira_installation.instance_url?
request.content_security_policy.directives['connect-src'] ||= []
- request.content_security_policy.directives['connect-src'] << Gitlab::Utils.append_path(current_jira_installation.instance_url, '/-/jira_connect/oauth_application_ids')
+ request.content_security_policy.directives['connect-src'].concat(allowed_instance_connect_src)
end
def create_service
@@ -77,4 +79,11 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
def allow_rendering_in_iframe
response.headers.delete('X-Frame-Options')
end
+
+ def allowed_instance_connect_src
+ [
+ Gitlab::Utils.append_path(current_jira_installation.instance_url, '/-/jira_connect/'),
+ Gitlab::Utils.append_path(current_jira_installation.instance_url, '/api/')
+ ]
+ end
end
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 84f5632854b..7211eebdb4b 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -78,7 +78,11 @@ class JwtController < ApplicationController
end
def additional_params
- { scopes: scopes_param, deploy_token: @authentication_result.deploy_token }.compact
+ {
+ scopes: scopes_param,
+ deploy_token: @authentication_result.deploy_token,
+ auth_type: @authentication_result.type
+ }.compact
end
# We have to parse scope here, because Docker Client does not send an array of scopes,
diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb
index a0c307a0a03..bfd6181a940 100644
--- a/app/controllers/metrics_controller.rb
+++ b/app/controllers/metrics_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
include RequiresWhitelistedMonitoringClient
@@ -34,3 +35,4 @@ class MetricsController < ActionController::Base
)
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index a996bad3fac..ff466fd5fbb 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -25,7 +25,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
end
def show
- @created = get_created_session
+ @created = get_created_session if Feature.disabled?('hash_oauth_secrets')
end
def create
@@ -34,9 +34,14 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
if @application.persisted?
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
- set_created_session
+ if Feature.enabled?('hash_oauth_secrets')
+ @created = true
+ render :show
+ else
+ set_created_session
- redirect_to oauth_application_url(@application)
+ redirect_to oauth_application_url(@application)
+ end
else
set_index_vars
render :index
diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb
index 07d786ab060..8ed67c26f19 100644
--- a/app/controllers/profiles/personal_access_tokens_controller.rb
+++ b/app/controllers/profiles/personal_access_tokens_controller.rb
@@ -65,7 +65,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
add_pagination_headers(tokens)
end
- ::API::Entities::PersonalAccessTokenWithDetails.represent(tokens)
+ ::PersonalAccessTokenSerializer.new.represent(tokens)
end
def add_pagination_headers(relation)
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index dd1ac526b89..e3704b77adc 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -137,7 +137,7 @@ class ProfilesController < Profiles::ApplicationController
:pronouns,
:pronunciation,
:validation_password,
- status: [:emoji, :message, :availability]
+ status: [:emoji, :message, :availability, :clear_status_after]
]
end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index 5bfda526fb0..2a20c67a23d 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -23,11 +23,10 @@ class Projects::BlameController < Projects::ApplicationController
environment_params[:find_latest] = true
@environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
- blame_service = Projects::BlameService.new(@blob, @commit, params.permit(:page))
+ blame_service = Projects::BlameService.new(@blob, @commit, params.permit(:page, :no_pagination))
@blame = Gitlab::View::Presenter::Factory.new(blame_service.blame, project: @project, path: @path, page: blame_service.page).fabricate!
-
- render locals: { blame_pagination: blame_service.pagination }
+ @blame_pagination = blame_service.pagination
end
end
diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb
index 6160dafb177..63c1378ad11 100644
--- a/app/controllers/projects/cycle_analytics_controller.rb
+++ b/app/controllers/projects/cycle_analytics_controller.rb
@@ -5,13 +5,17 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
include ActionView::Helpers::TextHelper
include CycleAnalyticsParams
include GracefulTimeoutHandling
- include RedisTracking
+ include ProductAnalyticsTracking
extend ::Gitlab::Utils::Override
before_action :authorize_read_cycle_analytics!
before_action :load_value_stream, only: :show
- track_redis_hll_event :show, name: 'p_analytics_valuestream'
+ track_custom_event :show,
+ name: 'p_analytics_valuestream',
+ action: 'perform_analytics_usage_action',
+ label: 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly',
+ destinations: %i[redis_hll snowplow]
feature_category :planning_analytics
urgency :low
@@ -54,4 +58,12 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
permissions: @cycle_analytics.permissions(user: current_user)
}
end
+
+ def tracking_namespace_source
+ project.namespace
+ end
+
+ def tracking_project_source
+ project
+ end
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 7ef9fd9daed..4f037cc843e 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -5,7 +5,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController
# into app/controllers/projects/metrics_dashboard_controller.rb
# See https://gitlab.com/gitlab-org/gitlab/-/issues/226002 for more details.
+ MIN_SEARCH_LENGTH = 3
+
include MetricsDashboard
+ include ProductAnalyticsTracking
layout 'project'
@@ -26,6 +29,18 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action :expire_etag_cache, only: [:index], unless: -> { request.format.json? }
after_action :expire_etag_cache, only: [:cancel_auto_stop]
+ track_event :index,
+ :folder,
+ :show,
+ :new,
+ :edit,
+ :create,
+ :update,
+ :stop,
+ :cancel_auto_stop,
+ :terminal,
+ name: 'users_visiting_environments_pages'
+
feature_category :continuous_delivery
urgency :low
@@ -35,12 +50,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
- @environments = project.environments
- .with_state(params[:scope] || :available)
+ @environments = search_environments.with_state(params[:scope] || :available)
+ environments_count_by_state = search_environments.count_by_state
Gitlab::PollingInterval.set_header(response, interval: 3_000)
- environments_count_by_state = project.environments.count_by_state
-
render json: {
environments: serialize_environments(request, response, params[:nested]),
review_app: serialize_review_app,
@@ -59,7 +72,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
- folder_environments = project.environments.where(environment_type: params[:id])
+ folder_environments = search_environments(type: params[:id])
+
@environments = folder_environments.with_state(params[:scope] || :available)
.order(:name)
@@ -236,6 +250,16 @@ class Projects::EnvironmentsController < Projects::ApplicationController
@environment ||= project.environments.find(params[:id])
end
+ def search_environments(type: nil)
+ search = params[:search] if params[:search] && params[:search].length >= MIN_SEARCH_LENGTH
+
+ @search_environments ||=
+ Environments::EnvironmentsFinder.new(project,
+ current_user,
+ type: type,
+ search: search).execute
+ end
+
def metrics_params
params.require([:start, :end])
end
diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb
index d1eb86c5e49..dfb73821b0f 100644
--- a/app/controllers/projects/google_cloud/base_controller.rb
+++ b/app/controllers/projects/google_cloud/base_controller.rb
@@ -12,7 +12,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
def admin_project_google_cloud!
unless can?(current_user, :admin_project_google_cloud, project)
- track_event('admin_project_google_cloud!', 'error_access_denied', 'invalid_user')
+ track_event(:error_invalid_user)
access_denied!
end
end
@@ -20,11 +20,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
def google_oauth2_enabled!
config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
if config.app_id.blank? || config.app_secret.blank?
- track_event(
- 'google_oauth2_enabled!',
- 'error_access_denied',
- { reason: 'google_oauth2_not_configured', config: config }
- )
+ track_event(:error_google_oauth2_not_enabled)
access_denied! 'This GitLab instance not configured for Google Oauth2.'
end
end
@@ -35,7 +31,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
enabled_for_project = Feature.enabled?(:incubation_5mp_google_cloud, project)
feature_is_enabled = enabled_for_user || enabled_for_group || enabled_for_project
unless feature_is_enabled
- track_event('feature_flag_enabled!', 'error_access_denied', 'feature_flag_not_enabled')
+ track_event(:error_feature_flag_not_enabled)
access_denied!
end
end
@@ -69,16 +65,14 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
end
- def track_event(action, label, property)
- options = { label: label, project: project, user: current_user }
-
- if property.is_a?(String)
- options[:property] = property
- else
- options[:extra] = property
- end
-
- Gitlab::Tracking.event('Projects::GoogleCloud', action, **options)
+ def track_event(action, label = nil)
+ Gitlab::Tracking.event(
+ self.class.name,
+ action.to_s,
+ label: label,
+ project: project,
+ user: current_user
+ )
end
def gcp_projects
diff --git a/app/controllers/projects/google_cloud/configuration_controller.rb b/app/controllers/projects/google_cloud/configuration_controller.rb
index 8d252c35031..06a6674d578 100644
--- a/app/controllers/projects/google_cloud/configuration_controller.rb
+++ b/app/controllers/projects/google_cloud/configuration_controller.rb
@@ -16,7 +16,7 @@ module Projects
revokeOauthUrl: revoke_oauth_url
}
@js_data = js_data.to_json
- track_event('configuration#index', 'success', js_data)
+ track_event(:render_page)
end
private
diff --git a/app/controllers/projects/google_cloud/databases_controller.rb b/app/controllers/projects/google_cloud/databases_controller.rb
index 7b1cf6e5ce1..8f7554f248b 100644
--- a/app/controllers/projects/google_cloud/databases_controller.rb
+++ b/app/controllers/projects/google_cloud/databases_controller.rb
@@ -3,14 +3,139 @@
module Projects
module GoogleCloud
class DatabasesController < Projects::GoogleCloud::BaseController
+ before_action :validate_gcp_token!
+ before_action :validate_product, only: :new
+
def index
js_data = {
configurationUrl: project_google_cloud_configuration_path(project),
deploymentsUrl: project_google_cloud_deployments_path(project),
- databasesUrl: project_google_cloud_databases_path(project)
+ databasesUrl: project_google_cloud_databases_path(project),
+ cloudsqlPostgresUrl: new_project_google_cloud_database_path(project, :postgres),
+ cloudsqlMysqlUrl: new_project_google_cloud_database_path(project, :mysql),
+ cloudsqlSqlserverUrl: new_project_google_cloud_database_path(project, :sqlserver),
+ cloudsqlInstances: ::GoogleCloud::GetCloudsqlInstancesService.new(project).execute,
+ emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg')
}
@js_data = js_data.to_json
- track_event('databases#index', 'success', js_data)
+
+ track_event(:render_page)
+ end
+
+ def new
+ product = permitted_params[:product].to_sym
+
+ @title = title(product)
+
+ @js_data = {
+ gcpProjects: gcp_projects,
+ refs: refs,
+ cancelPath: project_google_cloud_databases_path(project),
+ formTitle: form_title(product),
+ formDescription: description(product),
+ databaseVersions: Projects::GoogleCloud::CloudsqlHelper::VERSIONS[product],
+ tiers: Projects::GoogleCloud::CloudsqlHelper::TIERS
+ }.to_json
+
+ track_event(:render_form)
+ render template: 'projects/google_cloud/databases/cloudsql_form', formats: :html
+ end
+
+ def create
+ enable_response = ::GoogleCloud::EnableCloudsqlService
+ .new(project, current_user, enable_service_params)
+ .execute
+
+ if enable_response[:status] == :error
+ track_event(:error_enable_cloudsql_services)
+ flash[:error] = error_message(enable_response[:message])
+ else
+ permitted_params = params.permit(:gcp_project, :ref, :database_version, :tier)
+ create_response = ::GoogleCloud::CreateCloudsqlInstanceService
+ .new(project, current_user, create_service_params(permitted_params))
+ .execute
+
+ if create_response[:status] == :error
+ track_event(:error_create_cloudsql_instance)
+ flash[:warning] = error_message(create_response[:message])
+ else
+ track_event(:create_cloudsql_instance, permitted_params.to_s)
+ flash[:notice] = success_message
+ end
+ end
+
+ redirect_to project_google_cloud_databases_path(project)
+ end
+
+ private
+
+ def enable_service_params
+ { google_oauth2_token: token_in_session }
+ end
+
+ def create_service_params(permitted_params)
+ {
+ google_oauth2_token: token_in_session,
+ gcp_project_id: permitted_params[:gcp_project],
+ environment_name: permitted_params[:ref],
+ database_version: permitted_params[:database_version],
+ tier: permitted_params[:tier]
+ }
+ end
+
+ def error_message(message)
+ format(s_("CloudSeed|Google Cloud Error - %{message}"), message: message)
+ end
+
+ def success_message
+ s_('CloudSeed|Cloud SQL instance creation request successful. Expected resolution time is ~5 minutes.')
+ end
+
+ def validate_product
+ not_found unless permitted_params[:product].in?(%w[postgres mysql sqlserver])
+ end
+
+ def permitted_params
+ params.permit(:product)
+ end
+
+ def title(product)
+ case product
+ when :postgres
+ s_('CloudSeed|Create Postgres Instance')
+ when :mysql
+ s_('CloudSeed|Create MySQL Instance')
+ else
+ s_('CloudSeed|Create MySQL Instance')
+ end
+ end
+
+ def form_title(product)
+ case product
+ when :postgres
+ s_('CloudSeed|Cloud SQL for Postgres')
+ when :mysql
+ s_('CloudSeed|Cloud SQL for MySQL')
+ else
+ s_('CloudSeed|Cloud SQL for SQL Server')
+ end
+ end
+
+ def description(product)
+ case product
+ when :postgres
+ s_('CloudSeed|Cloud SQL instances are fully managed, relational PostgreSQL databases. '\
+ 'Google handles replication, patch management, and database management '\
+ 'to ensure availability and performance.')
+ when :mysql
+ s_('Cloud SQL instances are fully managed, relational MySQL databases. '\
+ 'Google handles replication, patch management, and database management '\
+ 'to ensure availability and performance.')
+ else
+ s_('Cloud SQL instances are fully managed, relational SQL Server databases. ' \
+ 'Google handles replication, patch management, and database management ' \
+ 'to ensure availability and performance.')
+ end
end
end
end
diff --git a/app/controllers/projects/google_cloud/deployments_controller.rb b/app/controllers/projects/google_cloud/deployments_controller.rb
index 1ac4697a63f..f6cc8d5eafb 100644
--- a/app/controllers/projects/google_cloud/deployments_controller.rb
+++ b/app/controllers/projects/google_cloud/deployments_controller.rb
@@ -12,7 +12,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project)
}
@js_data = js_data.to_json
- track_event('deployments#index', 'success', js_data)
+ track_event(:render_page)
end
def cloud_run
@@ -21,7 +21,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
.new(project, current_user, params).execute
if enable_cloud_run_response[:status] == :error
- track_event('deployments#cloud_run', 'error_enable_cloud_run', enable_cloud_run_response)
+ track_event(:error_enable_services)
flash[:error] = enable_cloud_run_response[:message]
redirect_to project_google_cloud_deployments_path(project)
else
@@ -30,17 +30,17 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
.new(project, current_user, params).execute
if generate_pipeline_response[:status] == :error
- track_event('deployments#cloud_run', 'error_generate_pipeline', generate_pipeline_response)
+ track_event(:error_generate_cloudrun_pipeline)
flash[:error] = 'Failed to generate pipeline'
redirect_to project_google_cloud_deployments_path(project)
else
cloud_run_mr_params = cloud_run_mr_params(generate_pipeline_response[:branch_name])
- track_event('deployments#cloud_run', 'success', cloud_run_mr_params)
+ track_event(:generate_cloudrun_pipeline)
redirect_to project_new_merge_request_path(project, merge_request: cloud_run_mr_params)
end
end
- rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => e
- track_event('deployments#cloud_run', 'error_gcp', e)
+ rescue Google::Apis::Error => e
+ track_event(:error_google_api)
flash[:warning] = _('Google Cloud Error - %{error}') % { error: e }
redirect_to project_google_cloud_deployments_path(project)
end
diff --git a/app/controllers/projects/google_cloud/gcp_regions_controller.rb b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
index 39f33624804..2f0bc05030f 100644
--- a/app/controllers/projects/google_cloud/gcp_regions_controller.rb
+++ b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
@@ -15,13 +15,13 @@ class Projects::GoogleCloud::GcpRegionsController < Projects::GoogleCloud::BaseC
cancelPath: project_google_cloud_configuration_path(project)
}
@js_data = js_data.to_json
- track_event('gcp_regions#index', 'success', js_data)
+ track_event(:render_form)
end
def create
permitted_params = params.permit(:ref, :gcp_region)
- response = GoogleCloud::GcpRegionAddOrReplaceService.new(project).execute(permitted_params[:ref], permitted_params[:gcp_region])
- track_event('gcp_regions#create', 'success', response)
+ GoogleCloud::GcpRegionAddOrReplaceService.new(project).execute(permitted_params[:ref], permitted_params[:gcp_region])
+ track_event(:configure_region)
redirect_to project_google_cloud_configuration_path(project), notice: _('GCP region configured')
end
end
diff --git a/app/controllers/projects/google_cloud/revoke_oauth_controller.rb b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
index 1a9a2daf4f2..dbf91806722 100644
--- a/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
+++ b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
@@ -9,10 +9,10 @@ class Projects::GoogleCloud::RevokeOauthController < Projects::GoogleCloud::Base
if response.success?
redirect_message = { notice: s_('GoogleCloud|Google OAuth2 token revocation requested') }
- track_event('revoke_oauth#create', 'success', response.to_json)
+ track_event(:revoke_oauth)
else
redirect_message = { alert: s_('GoogleCloud|Google OAuth2 token revocation request failed') }
- track_event('revoke_oauth#create', 'error', response.to_json)
+ track_event(:error)
end
session.delete(GoogleApi::CloudPlatform::Client.session_key_for_token)
diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb
index 7f25054177e..89d624764df 100644
--- a/app/controllers/projects/google_cloud/service_accounts_controller.rb
+++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb
@@ -5,7 +5,7 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
def index
if gcp_projects.empty?
- track_event('service_accounts#index', 'error_form', 'no_gcp_projects')
+ track_event(:error_no_gcp_projects)
flash[:warning] = _('No Google Cloud projects - You need at least one Google Cloud project')
redirect_to project_google_cloud_configuration_path(project)
else
@@ -16,10 +16,10 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
}
@js_data = js_data.to_json
- track_event('service_accounts#index', 'success', js_data)
+ track_event(:render_form)
end
- rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => e
- track_event('service_accounts#index', 'error_gcp', e)
+ rescue Google::Apis::Error => e
+ track_event(:error_google_api)
flash[:warning] = _('Google Cloud Error - %{error}') % { error: e }
redirect_to project_google_cloud_configuration_path(project)
end
@@ -35,10 +35,10 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
environment_name: permitted_params[:ref]
).execute
- track_event('service_accounts#create', 'success', response)
+ track_event(:create_service_account)
redirect_to project_google_cloud_configuration_path(project), notice: response.message
- rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => e
- track_event('service_accounts#create', 'error_gcp', e)
+ rescue Google::Apis::Error => e
+ track_event(:error_google_api)
flash[:warning] = _('Google Cloud Error - %{error}') % { error: e }
redirect_to project_google_cloud_configuration_path(project)
end
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index 63309cce1e5..47557133ac8 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -2,14 +2,18 @@
class Projects::GraphsController < Projects::ApplicationController
include ExtractsPath
- include RedisTracking
+ include ProductAnalyticsTracking
# Authorize
before_action :require_non_empty_project
before_action :assign_ref_vars
before_action :authorize_read_repository_graphs!
- track_redis_hll_event :charts, name: 'p_analytics_repo'
+ track_custom_event :charts,
+ name: 'p_analytics_repo',
+ action: 'perform_analytics_usage_action',
+ label: 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly',
+ destinations: %i[redis_hll snowplow]
feature_category :source_code_management, [:show, :commits, :languages, :charts]
urgency :low, [:show]
@@ -102,6 +106,14 @@ class Projects::GraphsController < Projects::ApplicationController
render json: @log.to_json
end
+
+ def tracking_namespace_source
+ project.namespace
+ end
+
+ def tracking_project_source
+ project
+ end
end
Projects::GraphsController.prepend_mod
diff --git a/app/controllers/projects/hook_logs_controller.rb b/app/controllers/projects/hook_logs_controller.rb
index 0ca3d71f728..3ab4c34737d 100644
--- a/app/controllers/projects/hook_logs_controller.rb
+++ b/app/controllers/projects/hook_logs_controller.rb
@@ -1,40 +1,19 @@
# frozen_string_literal: true
class Projects::HookLogsController < Projects::ApplicationController
- include ::Integrations::HooksExecution
-
before_action :authorize_admin_project!
- before_action :hook, only: [:show, :retry]
- before_action :hook_log, only: [:show, :retry]
-
- respond_to :html
+ include WebHooks::HookLogActions
layout 'project_settings'
- feature_category :integrations
- urgency :low, [:retry]
-
- def show
- end
-
- def retry
- execute_hook
- redirect_to edit_project_hook_path(@project, @hook)
- end
-
private
- def execute_hook
- result = hook.execute(hook_log.request_data, hook_log.trigger)
- set_hook_execution_notice(result)
- end
-
def hook
@hook ||= @project.hooks.find(params[:hook_id])
end
- def hook_log
- @hook_log ||= hook.web_hook_logs.find(params[:id])
+ def after_retry_redirect_path
+ edit_project_hook_path(@project, hook)
end
end
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index 50f388324f1..22b6bf6faf0 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Projects::HooksController < Projects::ApplicationController
- include ::Integrations::HooksExecution
+ include ::WebHooks::HookActions
# Authorize
before_action :authorize_admin_project!
@@ -35,7 +35,7 @@ class Projects::HooksController < Projects::ApplicationController
end
def hook_logs
- @hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
+ @hook_logs ||= hook.web_hook_logs.recent.page(params[:page]).without_count
end
def trigger_values
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 36b52533e78..cbf0c756e1e 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -11,6 +11,7 @@ class Projects::IncidentsController < Projects::ApplicationController
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:work_items_hierarchy, @project)
+ push_frontend_feature_flag(:remove_user_attributes_projects, @project)
end
feature_category :incident_management
@@ -28,7 +29,7 @@ class Projects::IncidentsController < Projects::ApplicationController
.inc_relations_for_view
.iid_in(params[:id])
.without_order
- .first
+ .take # rubocop:disable CodeReuse/ActiveRecord
end
end
diff --git a/app/controllers/projects/integrations/shimos_controller.rb b/app/controllers/projects/integrations/shimos_controller.rb
index 827dbb8f3f9..6c8313d0805 100644
--- a/app/controllers/projects/integrations/shimos_controller.rb
+++ b/app/controllers/projects/integrations/shimos_controller.rb
@@ -12,7 +12,7 @@ module Projects
private
def ensure_renderable
- render_404 unless Feature.enabled?(:shimo_integration, project) && project.has_shimo? && project.shimo_integration&.render?
+ render_404 unless project.has_shimo? && project.shimo_integration&.render?
end
end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index d19db2b11ab..800a7df2566 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -42,6 +42,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:incident_timeline, project)
+ push_frontend_feature_flag(:remove_user_attributes_projects, project)
end
before_action only: [:index, :show] do
@@ -53,6 +54,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:realtime_labels, project)
push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:work_items_hierarchy, project)
+ push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
push_force_frontend_feature_flag(:work_items_create_from_markdown, project&.work_items_create_from_markdown_feature_flag_enabled?)
end
@@ -63,19 +65,19 @@ class Projects::IssuesController < Projects::ApplicationController
alias_method :designs, :show
feature_category :team_planning, [
- :index, :calendar, :show, :new, :create, :edit, :update,
- :destroy, :move, :reorder, :designs, :toggle_subscription,
- :discussions, :bulk_update, :realtime_changes,
- :toggle_award_emoji, :mark_as_spam, :related_branches,
- :can_create_branch, :create_merge_request
- ]
+ :index, :calendar, :show, :new, :create, :edit, :update,
+ :destroy, :move, :reorder, :designs, :toggle_subscription,
+ :discussions, :bulk_update, :realtime_changes,
+ :toggle_award_emoji, :mark_as_spam, :related_branches,
+ :can_create_branch, :create_merge_request
+ ]
urgency :low, [
- :index, :calendar, :show, :new, :create, :edit, :update,
- :destroy, :move, :reorder, :designs, :toggle_subscription,
- :discussions, :bulk_update, :realtime_changes,
- :toggle_award_emoji, :mark_as_spam, :related_branches,
- :can_create_branch, :create_merge_request
- ]
+ :index, :calendar, :show, :new, :create, :edit, :update,
+ :destroy, :move, :reorder, :designs, :toggle_subscription,
+ :discussions, :bulk_update, :realtime_changes,
+ :toggle_award_emoji, :mark_as_spam, :related_branches,
+ :can_create_branch, :create_merge_request
+ ]
feature_category :service_desk, [:service_desk]
urgency :low, [:service_desk]
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 7878ace5015..557ac566733 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -20,6 +20,9 @@ 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'
@@ -120,11 +123,13 @@ class Projects::JobsController < Projects::ApplicationController
end
def erase
- if @build.erase(erased_by: current_user)
+ service_response = Ci::BuildEraseService.new(@build, current_user).execute
+
+ if service_response.success?
redirect_to project_job_path(project, @build),
notice: _("Job has been successfully erased!")
else
- respond_422
+ head service_response.http_status
end
end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 279fd4c457e..a68c2ffa06d 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -29,6 +29,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
render_diffs
end
+ # rubocop: disable Metrics/AbcSize
def diffs_batch
diff_options_hash = diff_options
diff_options_hash[:paths] = params[:paths] if params[:paths]
@@ -61,21 +62,11 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
options[:allow_tree_conflicts]
]
- if Feature.enabled?(:etag_merge_request_diff_batches, @merge_request.project)
- return unless stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
- end
+ return unless stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
- if diff_options_hash[:paths].blank?
- render_cached(
- diffs,
- with: PaginatedDiffSerializer.new(current_user: current_user),
- cache_context: -> (_) { [Digest::SHA256.hexdigest(cache_context.to_s)] },
- **options
- )
- else
- render json: PaginatedDiffSerializer.new(current_user: current_user).represent(diffs, options)
- end
+ render json: PaginatedDiffSerializer.new(current_user: current_user).represent(diffs, options)
end
+ # rubocop: enable Metrics/AbcSize
def diffs_metadata
diffs = @compare.diffs(diff_options)
diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb
index ff6b6bfaf27..74bb3ad1a63 100644
--- a/app/controllers/projects/merge_requests/drafts_controller.rb
+++ b/app/controllers/projects/merge_requests/drafts_controller.rb
@@ -49,8 +49,24 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
def publish
result = DraftNotes::PublishService.new(merge_request, current_user).execute(draft_note(allow_nil: true))
- if Feature.enabled?(:mr_review_submit_comment, @project) && create_note_params[:note]
- Notes::CreateService.new(@project, current_user, create_note_params).execute
+ if Feature.enabled?(:mr_review_submit_comment, @project)
+ if create_note_params[:note]
+ ::Notes::CreateService.new(@project, current_user, create_note_params).execute
+
+ merge_request_activity_counter.track_submit_review_comment(user: current_user)
+ end
+
+ if Gitlab::Utils.to_boolean(approve_params[:approve])
+ unless merge_request.approved_by?(current_user)
+ success = ::MergeRequests::ApprovalService.new(project: @project, current_user: current_user, params: approve_params).execute(merge_request)
+
+ unless success
+ return render json: { message: _('An error occurred while approving, please try again.') }, status: :internal_server_error
+ end
+ end
+
+ merge_request_activity_counter.track_submit_review_approve(user: current_user)
+ end
end
if result[:status] == :success
@@ -115,6 +131,10 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
end
end
+ def approve_params
+ params.permit(:approve)
+ end
+
def prepare_notes_for_rendering(notes)
return [] unless notes
@@ -147,4 +167,10 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
def authorize_create_note!
access_denied! unless can?(current_user, :create_note, merge_request)
end
+
+ def merge_request_activity_counter
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
+ end
end
+
+Projects::MergeRequests::DraftsController.prepend_mod
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 870c57fd6f3..5a212e9a152 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -45,6 +45,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:paginated_mr_discussions, project)
push_frontend_feature_flag(:mr_review_submit_comment, project)
push_frontend_feature_flag(:mr_experience_survey, project)
+ push_frontend_feature_flag(:remove_user_attributes_projects, @project)
end
before_action do
@@ -56,11 +57,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
after_action :log_merge_request_show, only: [:show]
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
- ]
+ :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
+ ]
feature_category :code_testing, [:test_reports, :coverage_reports]
feature_category :code_quality, [:codequality_reports, :codequality_mr_diff_reports]
@@ -219,7 +220,13 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def context_commits
# Get commits from repository
# or from cache if already merged
- commits = ContextCommitsFinder.new(project, @merge_request, { search: params[:search], limit: params[:limit], offset: params[:offset] }).execute
+ commits = ContextCommitsFinder.new(project, @merge_request, {
+ search: params[:search],
+ author: params[:author],
+ committed_before: convert_date_to_epoch(params[:committed_before]),
+ committed_after: convert_date_to_epoch(params[:committed_after]),
+ limit: params[:limit]
+ }).execute
render json: CommitEntity.represent(commits, { type: :full, request: merge_request })
end
@@ -552,6 +559,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
diffs_metadata_project_json_merge_request_path(project, merge_request, 'json', params)
end
+
+ def convert_date_to_epoch(date)
+ Date.strptime(date, "%Y-%m-%d")&.to_time&.to_i if date
+ rescue Date::Error, TypeError
+ end
end
Projects::MergeRequestsController.prepend_mod_with('Projects::MergeRequestsController')
diff --git a/app/controllers/projects/packages/package_files_controller.rb b/app/controllers/projects/packages/package_files_controller.rb
index 32aadb4fcf4..1aa91ee1189 100644
--- a/app/controllers/projects/packages/package_files_controller.rb
+++ b/app/controllers/projects/packages/package_files_controller.rb
@@ -11,6 +11,7 @@ module Projects
def download
package_file = project.package_files.find(params[:id])
+ package_file.package.touch_last_downloaded_at
send_upload(package_file.file, attachment: package_file.file_name)
end
end
diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb
index 8ac370b1bd4..d77cf095a4f 100644
--- a/app/controllers/projects/pipelines/tests_controller.rb
+++ b/app/controllers/projects/pipelines/tests_controller.rb
@@ -51,7 +51,8 @@ module Projects
def test_suite
suite = builds.sum do |build|
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report = build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report.get_suite(build.test_suite_name)
end
Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, project).load!
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index b2aa1d9f4ca..2a8f7171f9c 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -3,6 +3,7 @@
class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
include RedisTracking
+ include ProductAnalyticsTracking
include ProjectStatsRefreshConflictsGuard
include ZuoraCSP
@@ -25,6 +26,7 @@ class Projects::PipelinesController < Projects::ApplicationController
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
@@ -32,8 +34,11 @@ class Projects::PipelinesController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
- # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/345074
- track_redis_hll_event :charts, name: 'p_analytics_pipelines'
+ track_custom_event :charts,
+ name: 'p_analytics_pipelines',
+ action: 'perform_analytics_usage_action',
+ label: 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly',
+ destinations: %i[redis_hll snowplow]
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_pipelines', if: -> { should_track_ci_cd_pipelines? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', if: -> { should_track_ci_cd_deployment_frequency? }
@@ -46,10 +51,10 @@ class Projects::PipelinesController < Projects::ApplicationController
POLLING_INTERVAL = 10_000
feature_category :continuous_integration, [
- :charts, :show, :config_variables, :stage, :cancel, :retry,
- :builds, :dag, :failures, :status,
- :index, :create, :new, :destroy
- ]
+ :charts, :show, :config_variables, :stage, :cancel, :retry,
+ :builds, :dag, :failures, :status,
+ :index, :create, :new, :destroy
+ ]
feature_category :code_testing, [:test_report]
feature_category :build_artifacts, [:downloadable_artifacts]
@@ -371,6 +376,14 @@ class Projects::PipelinesController < Projects::ApplicationController
def should_track_ci_cd_change_failure_rate?
params[:chart] == 'change-failure-rate'
end
+
+ def tracking_namespace_source
+ project.namespace
+ end
+
+ def tracking_project_source
+ project
+ end
end
Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController')
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index ba9576795ec..ee12b85b3a4 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -15,7 +15,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def update
- if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
redirect_to project_runner_path(@project, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
@@ -31,7 +31,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def resume
- if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: true).success?
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
@@ -39,7 +39,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def pause
- if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
+ if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: false).success?
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
diff --git a/app/controllers/projects/settings/integration_hook_logs_controller.rb b/app/controllers/projects/settings/integration_hook_logs_controller.rb
index 1e42fbce4c4..3a921ecad0d 100644
--- a/app/controllers/projects/settings/integration_hook_logs_controller.rb
+++ b/app/controllers/projects/settings/integration_hook_logs_controller.rb
@@ -7,13 +7,13 @@ module Projects
before_action :integration, only: [:show, :retry]
- def retry
- execute_hook
- redirect_to edit_project_settings_integration_path(@project, @integration)
- end
-
private
+ override :after_retry_redirect_path
+ def after_retry_redirect_path
+ edit_project_settings_integration_path(@project, @integration)
+ end
+
def integration
@integration ||= @project.find_or_initialize_integration(params[:integration_id])
end
diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb
index 03ef434456f..2bbcd9fe20c 100644
--- a/app/controllers/projects/settings/integrations_controller.rb
+++ b/app/controllers/projects/settings/integrations_controller.rb
@@ -11,7 +11,7 @@ module Projects
before_action :integration, only: [:edit, :update, :test]
before_action :default_integration, only: [:edit, :update]
before_action :web_hook_logs, only: [:edit, :update]
- before_action -> { check_rate_limit!(:project_testing_integration, scope: [@project, current_user]) }, only: :test
+ before_action -> { check_test_rate_limit! }, only: :test
respond_to :html
@@ -124,7 +124,7 @@ module Projects
def web_hook_logs
return unless integration.try(:service_hook).present?
- @web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page])
+ @web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page]).without_count
end
def ensure_integration_enabled
@@ -140,6 +140,15 @@ module Projects
def use_inherited_settings?(attributes)
default_integration && attributes[:inherit_from_id] == default_integration.id.to_s
end
+
+ def check_test_rate_limit!
+ check_rate_limit!(:project_testing_integration, scope: [@project, current_user]) do
+ render json: {
+ error: true,
+ message: _('This endpoint has been requested too many times. Try again later.')
+ }, status: :ok
+ end
+ end
end
end
end
diff --git a/app/controllers/projects/settings/merge_requests_controller.rb b/app/controllers/projects/settings/merge_requests_controller.rb
new file mode 100644
index 00000000000..93e10695767
--- /dev/null
+++ b/app/controllers/projects/settings/merge_requests_controller.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module Projects
+ module Settings
+ class MergeRequestsController < Projects::ApplicationController
+ layout 'project_settings'
+
+ before_action :merge_requests_enabled?
+ before_action :present_project, only: [:edit]
+ before_action :authorize_admin_project!
+
+ feature_category :code_review
+
+ def update
+ result = ::Projects::UpdateService.new(@project, current_user, project_params).execute
+
+ if result[:status] == :success
+ flash[:notice] = format(_("Project '%{project_name}' was successfully updated."), project_name: @project.name)
+ redirect_to project_settings_merge_requests_path(@project)
+ else
+ # Refresh the repo in case anything changed
+ @repository = @project.repository.reset
+
+ flash[:alert] = result[:message]
+ @project.reset
+ render 'show'
+ end
+ end
+
+ private
+
+ def merge_requests_enabled?
+ render_404 unless @project.merge_requests_enabled?
+ end
+
+ def project_params
+ params.require(:project)
+ .permit(project_params_attributes)
+ end
+
+ def project_setting_attributes
+ %i[
+ squash_option
+ allow_editing_commit_messages
+ mr_default_target_self
+ ]
+ end
+
+ def project_params_attributes
+ [
+ :allow_merge_on_skipped_pipeline,
+ :resolve_outdated_diff_discussions,
+ :only_allow_merge_if_all_discussions_are_resolved,
+ :only_allow_merge_if_pipeline_succeeds,
+ :printing_merge_request_link_enabled,
+ :remove_source_branch_after_merge,
+ :merge_method,
+ :merge_commit_template_or_default,
+ :squash_commit_template_or_default,
+ :suggestion_commit_message
+ ] + [project_setting_attributes: project_setting_attributes]
+ end
+ end
+ end
+end
+
+Projects::Settings::MergeRequestsController.prepend_mod_with('Projects::Settings::MergeRequestsController')
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index a178b8f7aa3..43c6451577a 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -34,13 +34,13 @@ module Projects
def create_deploy_token
result = Projects::DeployTokens::CreateService.new(@project, current_user, deploy_token_params).execute
- @new_deploy_token = result[:deploy_token]
if result[:status] == :success
+ @created_deploy_token = result[:deploy_token]
respond_to do |format|
format.json do
# IMPORTANT: It's a security risk to expose the token value more than just once here!
- json = API::Entities::DeployTokenWithToken.represent(@new_deploy_token).as_json
+ json = API::Entities::DeployTokenWithToken.represent(@created_deploy_token).as_json
render json: json, status: result[:http_status]
end
format.html do
@@ -49,6 +49,7 @@ module Projects
end
end
else
+ @new_deploy_token = result[:deploy_token]
respond_to do |format|
format.json { render json: { message: result[:message] }, status: result[:http_status] }
format.html do
diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb
index a364668ea5f..8f4987a07f6 100644
--- a/app/controllers/projects/uploads_controller.rb
+++ b/app/controllers/projects/uploads_controller.rb
@@ -35,14 +35,4 @@ class Projects::UploadsController < Projects::ApplicationController
Project.find_by_full_path("#{namespace}/#{id}")
end
-
- # Overrides ApplicationController#build_canonical_path since there are
- # multiple routes that match project uploads:
- # https://gitlab.com/gitlab-org/gitlab/issues/196396
- def build_canonical_path(project)
- return super unless action_name == 'show'
- return super unless params[:secret] && params[:filename]
-
- show_namespace_project_uploads_url(project.namespace.to_param, project.to_param, params[:secret], params[:filename])
- end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 8a6bcb4b3fc..5ceedbc1e01 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -12,6 +12,8 @@ class ProjectsController < Projects::ApplicationController
include SourcegraphDecorator
include PlanningHierarchy
+ REFS_LIMIT = 100
+
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
@@ -54,9 +56,9 @@ class ProjectsController < Projects::ApplicationController
layout :determine_layout
feature_category :projects, [
- :index, :show, :new, :create, :edit, :update, :transfer,
- :destroy, :archive, :unarchive, :toggle_star, :activity
- ]
+ :index, :show, :new, :create, :edit, :update, :transfer,
+ :destroy, :archive, :unarchive, :toggle_star, :activity
+ ]
feature_category :source_code_management, [:remove_fork, :housekeeping, :refs]
feature_category :team_planning, [:preview_markdown, :new_issuable_address]
@@ -309,6 +311,8 @@ class ProjectsController < Projects::ApplicationController
find_tags = true
find_commits = true
+ use_gitaly_pagination = Feature.enabled?(:use_gitaly_pagination_for_refs, @project)
+
unless find_refs.nil?
find_branches = find_refs.include?('branches')
find_tags = find_refs.include?('tags')
@@ -318,13 +322,21 @@ class ProjectsController < Projects::ApplicationController
options = {}
if find_branches
- branches = BranchesFinder.new(@repository, refs_params).execute.take(100).map(&:name)
+ branches = BranchesFinder.new(@repository, refs_params.merge(per_page: REFS_LIMIT))
+ .execute(gitaly_pagination: use_gitaly_pagination)
+ .take(REFS_LIMIT)
+ .map(&:name)
+
options['Branches'] = branches
end
if find_tags && @repository.tag_count.nonzero?
- tags = TagsFinder.new(@repository, refs_params).execute
- options['Tags'] = tags.take(100).map(&:name)
+ tags = TagsFinder.new(@repository, refs_params.merge(per_page: REFS_LIMIT))
+ .execute(gitaly_pagination: use_gitaly_pagination)
+ .take(REFS_LIMIT)
+ .map(&:name)
+
+ options['Tags'] = tags
end
# If reference is commit id - we should add it to branch/tag selectbox
@@ -430,6 +442,7 @@ class ProjectsController < Projects::ApplicationController
if Feature.enabled?(:split_operations_visibility_permissions, project)
%i[
environments_access_level feature_flags_access_level releases_access_level
+ monitor_access_level
]
else
%i[operations_access_level]
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 33d2c482795..0bd266bb490 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -32,6 +32,7 @@ class RegistrationsController < Devise::RegistrationsController
def create
set_user_state
+ token = set_custom_confirmation_token
super do |new_user|
accept_pending_invitations if new_user.persisted?
@@ -39,6 +40,7 @@ class RegistrationsController < Devise::RegistrationsController
persist_accepted_terms_if_required(new_user)
set_role_required(new_user)
track_experiment_event(new_user)
+ send_custom_confirmation_instructions(new_user, token)
if pending_approval?
NotificationService.new.new_instance_access_request(new_user)
@@ -118,8 +120,10 @@ class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
Gitlab::AppLogger.info(user_created_message)
return new_user_session_path(anchor: 'login-pane') if resource.blocked_pending_approval?
+ return dashboard_projects_path if Feature.enabled?(:soft_email_confirmation)
+ return identity_verification_redirect_path if custom_confirmation_enabled?(resource)
- Feature.enabled?(:soft_email_confirmation) ? dashboard_projects_path : users_almost_there_path(email: resource.email)
+ users_almost_there_path(email: resource.email)
end
private
@@ -236,6 +240,22 @@ class RegistrationsController < Devise::RegistrationsController
# signing up and becoming users
experiment(:logged_out_marketing_header, actor: new_user).track(:signed_up) if new_user.persisted?
end
+
+ def identity_verification_redirect_path
+ # overridden by EE module
+ end
+
+ def custom_confirmation_enabled?(resource)
+ # overridden by EE module
+ end
+
+ def set_custom_confirmation_token
+ # overridden by EE module
+ end
+
+ def send_custom_confirmation_instructions(user, token)
+ # overridden by EE module
+ end
end
RegistrationsController.prepend_mod_with('RegistrationsController')
diff --git a/app/controllers/repositories/git_http_client_controller.rb b/app/controllers/repositories/git_http_client_controller.rb
index fbf5d82a45b..a5ca17db113 100644
--- a/app/controllers/repositories/git_http_client_controller.rb
+++ b/app/controllers/repositories/git_http_client_controller.rb
@@ -3,7 +3,7 @@
module Repositories
class GitHttpClientController < Repositories::ApplicationController
include ActionController::HttpAuthentication::Basic
- include KerberosSpnegoHelper
+ include KerberosHelper
include Gitlab::Utils::StrongMemoize
attr_reader :authentication_result, :redirected_path
@@ -49,7 +49,7 @@ module Repositories
if handle_basic_authentication(login, password)
return # Allow access
end
- elsif allow_kerberos_spnego_auth? && spnego_provided?
+ elsif allow_kerberos_auth? && spnego_provided?
kerberos_user = find_kerberos_user
if kerberos_user
@@ -91,7 +91,7 @@ module Repositories
def send_challenges
challenges = []
challenges << 'Basic realm="GitLab"' if allow_basic_auth?
- challenges << spnego_challenge if allow_kerberos_spnego_auth?
+ challenges << spnego_challenge if allow_kerberos_auth?
headers['Www-Authenticate'] = challenges.join("\n") if challenges.any?
end
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index c3c6a51239d..144ec4c0de9 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -83,7 +83,7 @@ module Repositories
return if Gitlab::Database.read_only?
return unless repo_type.project?
- OnboardingProgressService.async(project.namespace_id).execute(action: :git_pull)
+ Onboarding::ProgressService.async(project.namespace_id).execute(action: :git_pull)
return if Feature.enabled?(:disable_git_http_fetch_writes)
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 5843e13c7cd..9f87ad6aaf6 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -57,7 +57,25 @@ class SearchController < ApplicationController
@search_highlight = @search_service.search_highlight
end
+ Gitlab::Metrics::GlobalSearchSlis.record_apdex(
+ elapsed: @global_search_duration_s,
+ search_type: @search_type,
+ search_level: @search_level,
+ search_scope: @scope
+ )
+
increment_search_counters
+ ensure
+ if @search_type
+ # If we raise an error somewhere in the @global_search_duration_s benchmark block, we will end up here
+ # with a 200 status code, but an empty @global_search_duration_s.
+ Gitlab::Metrics::GlobalSearchSlis.record_error_rate(
+ error: @global_search_duration_s.nil? || (status < 200 || status >= 400),
+ search_type: @search_type,
+ search_level: @search_level,
+ search_scope: @scope
+ )
+ end
end
def count