summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/abuse_reports_controller.rb16
-rw-r--r--app/controllers/admin/application_settings/appearances_controller.rb15
-rw-r--r--app/controllers/admin/jobs_controller.rb4
-rw-r--r--app/controllers/admin/runners_controller.rb32
-rw-r--r--app/controllers/admin/users_controller.rb6
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/autocomplete_controller.rb2
-rw-r--r--app/controllers/concerns/analytics/cycle_analytics/stage_actions.rb16
-rw-r--r--app/controllers/concerns/analytics/cycle_analytics/value_stream_actions.rb32
-rw-r--r--app/controllers/concerns/ci/auth_build_trace.rb22
-rw-r--r--app/controllers/concerns/clientside_preview_csp.rb17
-rw-r--r--app/controllers/concerns/issuable_actions.rb19
-rw-r--r--app/controllers/concerns/issuable_collections.rb10
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb10
-rw-r--r--app/controllers/concerns/membership_actions.rb16
-rw-r--r--app/controllers/concerns/metrics_dashboard.rb2
-rw-r--r--app/controllers/concerns/preferred_language_switcher.rb2
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb6
-rw-r--r--app/controllers/concerns/record_user_last_activity.rb3
-rw-r--r--app/controllers/concerns/requires_whitelisted_monitoring_client.rb2
-rw-r--r--app/controllers/concerns/send_file_upload.rb23
-rw-r--r--app/controllers/concerns/sends_blob.rb18
-rw-r--r--app/controllers/concerns/verifies_with_email.rb3
-rw-r--r--app/controllers/concerns/zuora_csp.rb26
-rw-r--r--app/controllers/dashboard_controller.rb15
-rw-r--r--app/controllers/graphql_controller.rb3
-rw-r--r--app/controllers/groups/autocomplete_sources_controller.rb2
-rw-r--r--app/controllers/groups/email_campaigns_controller.rb4
-rw-r--r--app/controllers/groups/runners_controller.rb2
-rw-r--r--app/controllers/groups/usage_quotas_controller.rb5
-rw-r--r--app/controllers/groups_controller.rb5
-rw-r--r--app/controllers/ide_controller.rb1
-rw-r--r--app/controllers/import/bulk_imports_controller.rb5
-rw-r--r--app/controllers/import/github_controller.rb25
-rw-r--r--app/controllers/jira_connect/public_keys_controller.rb10
-rw-r--r--app/controllers/jira_connect/subscriptions_controller.rb1
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb8
-rw-r--r--app/controllers/profiles/avatars_controller.rb2
-rw-r--r--app/controllers/profiles/emails_controller.rb2
-rw-r--r--app/controllers/profiles/groups_controller.rb2
-rw-r--r--app/controllers/profiles/keys_controller.rb12
-rw-r--r--app/controllers/profiles/preferences_controller.rb2
-rw-r--r--app/controllers/profiles/saved_replies_controller.rb13
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb36
-rw-r--r--app/controllers/profiles_controller.rb3
-rw-r--r--app/controllers/projects/airflow/dags_controller.rb38
-rw-r--r--app/controllers/projects/analytics/cycle_analytics/stages_controller.rb30
-rw-r--r--app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb11
-rw-r--r--app/controllers/projects/application_controller.rb15
-rw-r--r--app/controllers/projects/artifacts_controller.rb24
-rw-r--r--app/controllers/projects/autocomplete_sources_controller.rb4
-rw-r--r--app/controllers/projects/blob_controller.rb26
-rw-r--r--app/controllers/projects/branches_controller.rb28
-rw-r--r--app/controllers/projects/ci/pipeline_editor_controller.rb3
-rw-r--r--app/controllers/projects/commit_controller.rb1
-rw-r--r--app/controllers/projects/commits_controller.rb2
-rw-r--r--app/controllers/projects/cycle_analytics_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb2
-rw-r--r--app/controllers/projects/google_cloud/databases_controller.rb2
-rw-r--r--app/controllers/projects/google_cloud/deployments_controller.rb4
-rw-r--r--app/controllers/projects/issues_controller.rb19
-rw-r--r--app/controllers/projects/jobs_controller.rb11
-rw-r--r--app/controllers/projects/learn_gitlab_controller.rb32
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb6
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb8
-rw-r--r--app/controllers/projects/merge_requests/drafts_controller.rb26
-rw-r--r--app/controllers/projects/merge_requests_controller.rb25
-rw-r--r--app/controllers/projects/ml/experiments_controller.rb36
-rw-r--r--app/controllers/projects/network_controller.rb6
-rw-r--r--app/controllers/projects/notes_controller.rb3
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb8
-rw-r--r--app/controllers/projects/pipelines_controller.rb3
-rw-r--r--app/controllers/projects/project_members_controller.rb14
-rw-r--r--app/controllers/projects/raw_controller.rb2
-rw-r--r--app/controllers/projects/refs_controller.rb18
-rw-r--r--app/controllers/projects/releases_controller.rb4
-rw-r--r--app/controllers/projects/repositories_controller.rb9
-rw-r--r--app/controllers/projects/service_ping_controller.rb18
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb5
-rw-r--r--app/controllers/projects/settings/repository_controller.rb15
-rw-r--r--app/controllers/projects_controller.rb18
-rw-r--r--app/controllers/registrations_controller.rb16
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/controllers/root_controller.rb4
-rw-r--r--app/controllers/search_controller.rb6
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/controllers/users/unsubscribes_controller.rb2
-rw-r--r--app/controllers/users_controller.rb5
-rw-r--r--app/controllers/whats_new_controller.rb2
89 files changed, 590 insertions, 391 deletions
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
index eec56682300..f6b4fbac8d5 100644
--- a/app/controllers/abuse_reports_controller.rb
+++ b/app/controllers/abuse_reports_controller.rb
@@ -19,6 +19,13 @@ class AbuseReportsController < ApplicationController
reported_from_url: report_params[:reported_from_url]
)
+ Gitlab::Tracking.event(
+ 'ReportAbuse',
+ 'select_abuse_category',
+ property: report_params[:category],
+ user: @user
+ )
+
render :new
end
@@ -29,6 +36,13 @@ class AbuseReportsController < ApplicationController
if @abuse_report.save
@abuse_report.notify
+ Gitlab::Tracking.event(
+ 'ReportAbuse',
+ 'submit_form',
+ property: @abuse_report.category,
+ user: @abuse_report.user
+ )
+
message = _("Thank you for your report. A GitLab administrator will look into it shortly.")
redirect_to root_path, notice: message
elsif report_params[:user_id].present?
@@ -41,7 +55,7 @@ class AbuseReportsController < ApplicationController
private
def report_params
- params.require(:abuse_report).permit(:message, :user_id, :category, :reported_from_url)
+ params.require(:abuse_report).permit(:message, :user_id, :category, :reported_from_url, links_to_spam: [])
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/admin/application_settings/appearances_controller.rb b/app/controllers/admin/application_settings/appearances_controller.rb
index 3cb31ff756f..719e8e4a913 100644
--- a/app/controllers/admin/application_settings/appearances_controller.rb
+++ b/app/controllers/admin/application_settings/appearances_controller.rb
@@ -46,6 +46,15 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
redirect_to admin_application_settings_appearances_path, notice: _('Header logo was successfully removed.')
end
+ def pwa_icon
+ @appearance.remove_pwa_icon!
+
+ @appearance.save
+
+ redirect_to admin_application_settings_appearances_path,
+ notice: _('Progressive Web App (PWA) icon was successfully removed.')
+ end
+
def favicon
@appearance.remove_favicon!
@appearance.save
@@ -68,12 +77,16 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
def allowed_appearance_params
%i[
title
- pwa_short_name
description
+ pwa_name
+ pwa_short_name
+ pwa_description
logo
logo_cache
header_logo
header_logo_cache
+ pwa_icon
+ pwa_icon_cache
favicon
favicon_cache
new_project_guidelines
diff --git a/app/controllers/admin/jobs_controller.rb b/app/controllers/admin/jobs_controller.rb
index ef9264d1615..5ea8c672993 100644
--- a/app/controllers/admin/jobs_controller.rb
+++ b/app/controllers/admin/jobs_controller.rb
@@ -6,6 +6,10 @@ class Admin::JobsController < Admin::ApplicationController
feature_category :continuous_integration
urgency :low
+ before_action do
+ push_frontend_feature_flag(:admin_jobs_vue)
+ end
+
def index
# We need all builds for tabs counters
@all_builds = Ci::JobsFinder.new(current_user: current_user).execute
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 96fe0c9331d..21a3a0aea0b 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -3,7 +3,11 @@
class Admin::RunnersController < Admin::ApplicationController
include RunnerSetupScripts
- before_action :runner, except: [:index, :tag_list, :runner_setup_scripts]
+ before_action :runner, except: [:index, :new, :tag_list, :runner_setup_scripts]
+
+ before_action only: [:index] do
+ push_frontend_feature_flag(:create_runner_workflow, current_user)
+ end
feature_category :runner
urgency :low
@@ -18,6 +22,10 @@ class Admin::RunnersController < Admin::ApplicationController
assign_projects
end
+ def new
+ render_404 unless Feature.enabled?(:create_runner_workflow, current_user)
+ end
+
def update
if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
respond_to do |format|
@@ -29,28 +37,6 @@ class Admin::RunnersController < Admin::ApplicationController
end
end
- def destroy
- Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
-
- redirect_to admin_runners_path, status: :found
- end
-
- def resume
- 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.')
- end
- end
-
- def pause
- 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.')
- end
- end
-
def tag_list
tags = Autocomplete::ActsAsTaggableOn::TagsFinder.new(params: params).execute
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 4f379d8a75b..00b17bf381f 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -7,7 +7,6 @@ class Admin::UsersController < Admin::ApplicationController
before_action :user, except: [:index, :new, :create]
before_action :check_impersonation_availability, only: :impersonate
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
- before_action :check_ban_user_feature_flag, only: [:ban]
feature_category :user_management
@@ -359,6 +358,7 @@ class Admin::UsersController < Admin::ApplicationController
:skype,
:theme_id,
:twitter,
+ :discord,
:username,
:website_url,
:note,
@@ -377,10 +377,6 @@ class Admin::UsersController < Admin::ApplicationController
access_denied! unless Gitlab.config.gitlab.impersonation_enabled
end
- def check_ban_user_feature_flag
- access_denied! unless Feature.enabled?(:ban_user_feature_flag)
- end
-
def log_impersonation_event
Gitlab::AppLogger.info(format(_("User %{current_user_username} has started impersonating %{username}"), current_user_username: current_user.username, username: user.username))
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 36aae42e21f..353f9098b95 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -69,7 +69,7 @@ class ApplicationController < ActionController::Base
:masked_page_url
def self.endpoint_id_for_action(action_name)
- "#{self.name}##{action_name}"
+ "#{name}##{action_name}"
end
rescue_from Encoding::CompatibilityError do |exception|
@@ -510,8 +510,6 @@ class ApplicationController < ActionController::Base
end
def set_locale(&block)
- return Gitlab::I18n.with_user_locale(current_user, &block) unless Feature.enabled?(:preferred_language_switcher)
-
if current_user
Gitlab::I18n.with_user_locale(current_user, &block)
else
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index 668b2ebaf9e..01cc1ef21c6 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -6,7 +6,7 @@ class AutocompleteController < ApplicationController
skip_before_action :authenticate_user!, only: [:users, :award_emojis, :merge_request_target_branches]
before_action :check_search_rate_limit!, only: [:users, :projects]
- feature_category :users, [:users, :user]
+ feature_category :user_profile, [:users, :user]
feature_category :projects, [:projects]
feature_category :team_planning, [:award_emojis]
feature_category :code_review_workflow, [:merge_request_target_branches]
diff --git a/app/controllers/concerns/analytics/cycle_analytics/stage_actions.rb b/app/controllers/concerns/analytics/cycle_analytics/stage_actions.rb
index eebc40f33f4..b0220b17cf9 100644
--- a/app/controllers/concerns/analytics/cycle_analytics/stage_actions.rb
+++ b/app/controllers/concerns/analytics/cycle_analytics/stage_actions.rb
@@ -7,9 +7,11 @@ module Analytics
extend ActiveSupport::Concern
included do
+ extend ::Gitlab::Utils::Override
include CycleAnalyticsParams
- before_action :validate_params, only: %i[median]
+ before_action :validate_params, except: %i[index]
+ before_action :authorize_stage, except: %i[index]
end
def index
@@ -44,11 +46,11 @@ module Analytics
private
- def parent
+ def namespace
raise NotImplementedError
end
- def value_stream_class
+ def authorize_stage
raise NotImplementedError
end
@@ -64,7 +66,7 @@ module Analytics
end
def stage
- @stage ||= ::Analytics::CycleAnalytics::StageFinder.new(parent: parent, stage_id: params[:id]).execute
+ @stage ||= ::Analytics::CycleAnalytics::StageFinder.new(parent: namespace, stage_id: params[:id]).execute
end
def data_collector
@@ -75,7 +77,7 @@ module Analytics
end
def value_stream
- @value_stream ||= value_stream_class.build_default_value_stream(parent)
+ @value_stream ||= Analytics::CycleAnalytics::ValueStream.build_default_value_stream(namespace)
end
def list_params
@@ -83,7 +85,7 @@ module Analytics
end
def list_service
- Analytics::CycleAnalytics::Stages::ListService.new(parent: parent, current_user: current_user, params: list_params)
+ Analytics::CycleAnalytics::Stages::ListService.new(parent: namespace, current_user: current_user, params: list_params)
end
def cycle_analytics_configuration(stages)
@@ -94,3 +96,5 @@ module Analytics
end
end
end
+
+Analytics::CycleAnalytics::StageActions.prepend_mod_with('Analytics::CycleAnalytics::StageActions')
diff --git a/app/controllers/concerns/analytics/cycle_analytics/value_stream_actions.rb b/app/controllers/concerns/analytics/cycle_analytics/value_stream_actions.rb
new file mode 100644
index 00000000000..f10b23d1664
--- /dev/null
+++ b/app/controllers/concerns/analytics/cycle_analytics/value_stream_actions.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Analytics
+ module CycleAnalytics
+ module ValueStreamActions
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :authorize
+ end
+
+ def index
+ # FOSS users can only see the default value stream
+ value_streams = [Analytics::CycleAnalytics::ValueStream.build_default_value_stream(namespace)]
+
+ render json: Analytics::CycleAnalytics::ValueStreamSerializer.new.represent(value_streams)
+ end
+
+ private
+
+ def namespace
+ raise NotImplementedError
+ end
+
+ def authorize
+ authorize_read_cycle_analytics!
+ end
+ end
+ end
+end
+
+Analytics::CycleAnalytics::ValueStreamActions.prepend_mod_with('Analytics::CycleAnalytics::ValueStreamActions')
diff --git a/app/controllers/concerns/ci/auth_build_trace.rb b/app/controllers/concerns/ci/auth_build_trace.rb
new file mode 100644
index 00000000000..0370a382eb8
--- /dev/null
+++ b/app/controllers/concerns/ci/auth_build_trace.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Ci
+ module AuthBuildTrace
+ extend ActiveSupport::Concern
+
+ def authorize_read_build_trace!
+ return if can?(current_user, :read_build_trace, build)
+
+ if build.debug_mode?
+ access_denied!(
+ _('You must have developer or higher permissions in the associated project to view job logs when debug ' \
+ "trace is enabled. To disable debug trace, set the 'CI_DEBUG_TRACE' and 'CI_DEBUG_SERVICES' variables to " \
+ "'false' in your pipeline configuration or CI/CD settings. If you must view this job log, " \
+ 'a project maintainer or owner must add you to the project with developer permissions or higher.')
+ )
+ else
+ access_denied!(_('The current user is not authorized to access the job log.'))
+ end
+ end
+ end
+end
diff --git a/app/controllers/concerns/clientside_preview_csp.rb b/app/controllers/concerns/clientside_preview_csp.rb
deleted file mode 100644
index 6892c441b67..00000000000
--- a/app/controllers/concerns/clientside_preview_csp.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module ClientsidePreviewCSP
- extend ActiveSupport::Concern
-
- included do
- content_security_policy do |p|
- next if p.directives.blank?
- next unless Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?
-
- default_frame_src = p.directives['frame-src'] || p.directives['default-src']
- frame_src_values = Array.wrap(default_frame_src) | [Gitlab::CurrentSettings.web_ide_clientside_preview_bundler_url].compact
-
- p.frame_src(*frame_src_values)
- end
- end
-end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 0669f051457..e1381b4173f 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -90,7 +90,7 @@ module IssuableActions
end
def destroy
- Issuable::DestroyService.new(project: issuable.project, current_user: current_user).execute(issuable)
+ Issuable::DestroyService.new(container: issuable.project, current_user: current_user).execute(issuable)
name = issuable.human_class_name
flash[:notice] = "The #{name} was successfully deleted."
@@ -246,7 +246,21 @@ module IssuableActions
end
def bulk_update_params
- params.require(:update).permit(bulk_update_permitted_keys)
+ clean_bulk_update_params(
+ params.require(:update).permit(bulk_update_permitted_keys)
+ )
+ end
+
+ def clean_bulk_update_params(permitted_params)
+ permitted_params.delete_if do |k, v|
+ next if k == :issuable_ids
+
+ if v.is_a?(Array)
+ v.compact.empty?
+ else
+ v.blank?
+ end
+ end
end
def bulk_update_permitted_keys
@@ -254,7 +268,6 @@ module IssuableActions
:issuable_ids,
:assignee_id,
:milestone_id,
- :sprint_id,
:state_event,
:subscription_event,
assignee_ids: [],
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 5060ce69d9c..a202808e2c3 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -14,18 +14,8 @@ module IssuableCollections
private
- def show_alert_if_search_is_disabled
- if current_user || params[:search].blank? || !html_request? || Feature.disabled?(:disable_anonymous_search, type: :ops)
- return
- end
-
- flash.now[:notice] = _('You must sign in to search for specific terms.')
- end
-
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def set_issuables_index
- show_alert_if_search_is_disabled
-
@issuables = issuables_collection
set_pagination
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index b8249345a54..31445eb3eca 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -7,14 +7,12 @@ module IssuableCollectionsAction
included do
before_action :check_search_rate_limit!, only: [:issues, :merge_requests], if: -> {
- params[:search].present? && Feature.enabled?(:rate_limit_issuable_searches)
+ params[:search].present?
}
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def issues
- show_alert_if_search_is_disabled
-
@issues = issuables_collection
.non_archived
.page(params[:page])
@@ -28,11 +26,13 @@ module IssuableCollectionsAction
end
def merge_requests
- show_alert_if_search_is_disabled
-
@merge_requests = issuables_collection.page(params[:page])
@issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @merge_requests).data
+ rescue ActiveRecord::QueryCanceled => exception # rubocop:disable Database/RescueQueryCanceled
+ log_exception(exception)
+
+ @search_timeout_occurred = true
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 7c6e449b509..773e4c15d6e 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -6,7 +6,7 @@ module MembershipActions
def update
update_params = params.require(root_params_key).permit(:access_level, :expires_at)
- member = membershipable.members_and_requesters.find(params[:id])
+ member = members_and_requesters.find(params[:id])
result = Members::UpdateService
.new(current_user, update_params)
.execute(member)
@@ -30,7 +30,7 @@ module MembershipActions
end
def destroy
- member = membershipable.members_and_requesters.find(params[:id])
+ member = members_and_requesters.find(params[:id])
skip_subresources = !ActiveRecord::Type::Boolean.new.cast(params.delete(:remove_sub_memberships))
# !! is used in case unassign_issuables contains empty string which would result in nil
unassign_issuables = !!ActiveRecord::Type::Boolean.new.cast(params.delete(:unassign_issuables))
@@ -71,7 +71,7 @@ module MembershipActions
end
def approve_access_request
- access_requester = membershipable.requesters.find(params[:id])
+ access_requester = requesters.find(params[:id])
Members::ApproveAccessRequestService
.new(current_user, params)
.execute(access_requester)
@@ -81,7 +81,7 @@ module MembershipActions
# rubocop: disable CodeReuse/ActiveRecord
def leave
- member = membershipable.members_and_requesters.find_by!(user_id: current_user.id)
+ member = members_and_requesters.find_by!(user_id: current_user.id)
Members::DestroyService.new(current_user).execute(member)
notice =
@@ -140,6 +140,14 @@ module MembershipActions
raise NotImplementedError
end
+ def members_and_requesters
+ membershipable.members_and_requesters
+ end
+
+ def requesters
+ membershipable.requesters
+ end
+
def requested_relations(inherited_permissions = :with_inherited_permissions)
case params[inherited_permissions].presence
when 'exclude'
diff --git a/app/controllers/concerns/metrics_dashboard.rb b/app/controllers/concerns/metrics_dashboard.rb
index d4e8e95e016..338c3af235b 100644
--- a/app/controllers/concerns/metrics_dashboard.rb
+++ b/app/controllers/concerns/metrics_dashboard.rb
@@ -37,7 +37,7 @@ module MetricsDashboard
def all_dashboards
dashboard_finder
.find_all_paths(project_for_dashboard)
- .map(&method(:amend_dashboard))
+ .map { |dashboard| amend_dashboard(dashboard) }
end
def amend_dashboard(dashboard)
diff --git a/app/controllers/concerns/preferred_language_switcher.rb b/app/controllers/concerns/preferred_language_switcher.rb
index 00cd0f9d1d5..872652100c9 100644
--- a/app/controllers/concerns/preferred_language_switcher.rb
+++ b/app/controllers/concerns/preferred_language_switcher.rb
@@ -6,8 +6,6 @@ module PreferredLanguageSwitcher
private
def init_preferred_language
- return unless Feature.enabled?(:preferred_language_switcher)
-
cookies[:preferred_language] = preferred_language
end
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
index b01320ce3ec..5696e441ad0 100644
--- a/app/controllers/concerns/product_analytics_tracking.rb
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -5,6 +5,8 @@ module ProductAnalyticsTracking
include RedisTracking
extend ActiveSupport::Concern
+ MIGRATED_EVENTS = ['g_analytics_valuestream'].freeze
+
class_methods do
# TODO: Remove once all the events are migrated to #track_custom_event
# during https://gitlab.com/groups/gitlab-org/-/epics/8641
@@ -63,9 +65,9 @@ module ProductAnalyticsTracking
end
def event_enabled?(event)
- events_to_ff = {
- g_analytics_valuestream: '',
+ return true if MIGRATED_EVENTS.include?(event)
+ events_to_ff = {
i_search_paid: :_phase2,
i_search_total: :_phase2,
i_search_advanced: :_phase2,
diff --git a/app/controllers/concerns/record_user_last_activity.rb b/app/controllers/concerns/record_user_last_activity.rb
index 6ac87d8f27b..501590d33d9 100644
--- a/app/controllers/concerns/record_user_last_activity.rb
+++ b/app/controllers/concerns/record_user_last_activity.rb
@@ -20,6 +20,7 @@ module RecordUserLastActivity
return if Gitlab::Database.read_only?
return unless current_user && current_user.last_activity_on != Date.today
- Users::ActivityService.new(current_user).execute
+ # TODO: add namespace & project - https://gitlab.com/gitlab-org/gitlab/-/issues/387952
+ Users::ActivityService.new(author: current_user).execute
end
end
diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
index e98c1a30887..ef3d281589a 100644
--- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
+++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
@@ -22,7 +22,7 @@ module RequiresWhitelistedMonitoringClient
end
def ip_whitelist
- @ip_whitelist ||= Settings.monitoring.ip_whitelist.map(&IPAddr.method(:new))
+ @ip_whitelist ||= Settings.monitoring.ip_whitelist.map { |ip| IPAddr.new(ip) }
end
def valid_token?
diff --git a/app/controllers/concerns/send_file_upload.rb b/app/controllers/concerns/send_file_upload.rb
index c91edb74d6b..2141b257b40 100644
--- a/app/controllers/concerns/send_file_upload.rb
+++ b/app/controllers/concerns/send_file_upload.rb
@@ -63,21 +63,32 @@ module SendFileUpload
private
def image_scaling_request?(file_upload)
- avatar_safe_for_scaling?(file_upload) &&
- scaling_allowed_by_feature_flags?(file_upload) &&
- valid_image_scaling_width?
+ (avatar_safe_for_scaling?(file_upload) || pwa_icon_safe_for_scaling?(file_upload)) &&
+ scaling_allowed_by_feature_flags?(file_upload)
+ end
+
+ def pwa_icon_safe_for_scaling?(file_upload)
+ file_upload.try(:image_safe_for_scaling?) &&
+ mounted_as_pwa_icon?(file_upload) &&
+ valid_image_scaling_width?(Appearance::ALLOWED_PWA_ICON_SCALER_WIDTHS)
end
def avatar_safe_for_scaling?(file_upload)
- file_upload.try(:image_safe_for_scaling?) && mounted_as_avatar?(file_upload)
+ file_upload.try(:image_safe_for_scaling?) &&
+ mounted_as_avatar?(file_upload) &&
+ valid_image_scaling_width?(Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS)
end
def mounted_as_avatar?(file_upload)
file_upload.try(:mounted_as)&.to_sym == :avatar
end
- def valid_image_scaling_width?
- Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS.include?(params[:width]&.to_i)
+ def mounted_as_pwa_icon?(file_upload)
+ file_upload.try(:mounted_as)&.to_sym == :pwa_icon
+ end
+
+ def valid_image_scaling_width?(allowed_scalar_widths)
+ allowed_scalar_widths.include?(params[:width]&.to_i)
end
def scaling_allowed_by_feature_flags?(file_upload)
diff --git a/app/controllers/concerns/sends_blob.rb b/app/controllers/concerns/sends_blob.rb
index 3cf260c9f1b..3303b704ebe 100644
--- a/app/controllers/concerns/sends_blob.rb
+++ b/app/controllers/concerns/sends_blob.rb
@@ -27,12 +27,7 @@ module SendsBlob
private
def cached_blob?(blob, allow_caching: false)
- stale =
- if Feature.enabled?(:improve_blobs_cache_headers)
- stale?(strong_etag: blob.id)
- else
- stale?(etag: blob.id)
- end
+ stale = stale?(strong_etag: blob.id)
max_age =
if @ref && @commit && @ref == @commit.id # rubocop:disable Gitlab/ModuleWithInstanceVariables
@@ -47,14 +42,9 @@ module SendsBlob
end
# Because we are opinionated we set the cache headers ourselves.
- if Feature.enabled?(:improve_blobs_cache_headers)
- expires_in(max_age,
- public: allow_caching, must_revalidate: true, stale_if_error: 5.minutes,
- stale_while_revalidate: 1.minute, 's-maxage': 1.minute)
- else
- response.cache_control[:public] = allow_caching
- response.cache_control[:max_age] = max_age
- end
+ expires_in(max_age,
+ public: allow_caching, must_revalidate: true, stale_if_error: 5.minutes,
+ stale_while_revalidate: 1.minute, 's-maxage': 1.minute)
!stale
end
diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb
index 82388090350..fb48c0d8ba5 100644
--- a/app/controllers/concerns/verifies_with_email.rb
+++ b/app/controllers/concerns/verifies_with_email.rb
@@ -163,6 +163,7 @@ module VerifiesWithEmail
end
def require_email_verification_enabled?(user)
- Feature.enabled?(:require_email_verification, user)
+ Feature.enabled?(:require_email_verification, user) &&
+ Feature.disabled?(:skip_require_email_verification, user, type: :ops)
end
end
diff --git a/app/controllers/concerns/zuora_csp.rb b/app/controllers/concerns/zuora_csp.rb
deleted file mode 100644
index 5f9be11d7b9..00000000000
--- a/app/controllers/concerns/zuora_csp.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module ZuoraCSP
- extend ActiveSupport::Concern
-
- ZUORA_URL = 'https://*.zuora.com'
-
- included do
- content_security_policy do |policy|
- next if policy.directives.blank?
-
- default_script_src = policy.directives['script-src'] || policy.directives['default-src']
- script_src_values = Array.wrap(default_script_src) | ["'self'", "'unsafe-eval'", ZUORA_URL]
-
- default_frame_src = policy.directives['frame-src'] || policy.directives['default-src']
- frame_src_values = Array.wrap(default_frame_src) | ["'self'", ZUORA_URL]
-
- default_child_src = policy.directives['child-src'] || policy.directives['default-src']
- child_src_values = Array.wrap(default_child_src) | ["'self'", ZUORA_URL]
-
- policy.script_src(*script_src_values)
- policy.frame_src(*frame_src_values)
- policy.child_src(*child_src_values)
- end
- end
-end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 3d9184979d7..b003ca564f3 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -14,7 +14,7 @@ class DashboardController < Dashboard::ApplicationController
respond_to :html
- feature_category :users, [:activity]
+ feature_category :user_profile, [:activity]
feature_category :team_planning, [:issues, :issues_calendar]
feature_category :code_review_workflow, [:merge_requests]
@@ -36,17 +36,20 @@ class DashboardController < Dashboard::ApplicationController
def load_events
@events =
- if params[:filter] == "followed"
- load_user_events
- else
+ case params[:filter]
+ when "projects", "starred"
load_project_events
+ when "followed"
+ load_user_events(current_user.followees)
+ else
+ load_user_events(current_user)
end
Events::RenderService.new(current_user).execute(@events)
end
- def load_user_events
- UserRecentEventsFinder.new(current_user, current_user.followees, event_filter, params).execute
+ def load_user_events(user)
+ UserRecentEventsFinder.new(current_user, user, event_filter, params).execute
end
def load_project_events
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 942cb9beed4..2f01bdecd23 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -144,7 +144,8 @@ class GraphqlController < ApplicationController
def set_user_last_activity
return unless current_user
- Users::ActivityService.new(current_user).execute
+ # TODO: add namespace & project - https://gitlab.com/gitlab-org/gitlab/-/issues/387951
+ Users::ActivityService.new(author: current_user).execute
end
def track_vs_code_usage
diff --git a/app/controllers/groups/autocomplete_sources_controller.rb b/app/controllers/groups/autocomplete_sources_controller.rb
index 6936733c4f7..3cad9e1fbad 100644
--- a/app/controllers/groups/autocomplete_sources_controller.rb
+++ b/app/controllers/groups/autocomplete_sources_controller.rb
@@ -46,6 +46,8 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def target
+ # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/388541
+ # type_id is a misnomer. QuickActions::TargetService actually requires an iid.
QuickActions::TargetService
.new(nil, current_user, group: @group)
.execute(params[:type], params[:type_id])
diff --git a/app/controllers/groups/email_campaigns_controller.rb b/app/controllers/groups/email_campaigns_controller.rb
index 38087e3fc11..8ae429de490 100644
--- a/app/controllers/groups/email_campaigns_controller.rb
+++ b/app/controllers/groups/email_campaigns_controller.rb
@@ -3,7 +3,7 @@
class Groups::EmailCampaignsController < Groups::ApplicationController
EMAIL_CAMPAIGNS_SCHEMA_URL = 'iglu:com.gitlab/email_campaigns/jsonschema/1-0-0'
- feature_category :navigation
+ feature_category :experimentation_activation
urgency :low
before_action :check_params
@@ -44,7 +44,7 @@ class Groups::EmailCampaignsController < Groups::ApplicationController
when :team, :team_short
group_group_members_url(group)
when :admin_verify
- project_settings_ci_cd_path(group.projects.first, ci_runner_templates: true, anchor: 'js-runners-settings')
+ project_settings_ci_cd_path(group.projects.first, anchor: 'js-runners-settings')
end
end
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index 18b055b3f05..859bb0adb4e 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -9,8 +9,6 @@ class Groups::RunnersController < Groups::ApplicationController
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)
diff --git a/app/controllers/groups/usage_quotas_controller.rb b/app/controllers/groups/usage_quotas_controller.rb
index b660eb3af99..4f858cd130a 100644
--- a/app/controllers/groups/usage_quotas_controller.rb
+++ b/app/controllers/groups/usage_quotas_controller.rb
@@ -4,6 +4,7 @@ module Groups
class UsageQuotasController < Groups::ApplicationController
before_action :authorize_read_usage_quotas!
before_action :verify_usage_quotas_enabled!
+ before_action :push_frontend_feature_flags
feature_category :subscription_cost_management
urgency :low
@@ -15,6 +16,10 @@ module Groups
private
+ def push_frontend_feature_flags
+ push_frontend_feature_flag(:usage_quotas_for_all_editions, @group)
+ end
+
def verify_usage_quotas_enabled!
render_404 unless group.usage_quotas_enabled?
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index e440b60ad1f..8f7a2c177b7 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -36,9 +36,14 @@ class GroupsController < Groups::ApplicationController
before_action only: :issues do
push_frontend_feature_flag(:or_issuable_queries, group)
+ push_frontend_feature_flag(:frontend_caching, group)
push_force_frontend_feature_flag(:work_items, group.work_items_feature_flag_enabled?)
end
+ before_action only: :show do
+ push_frontend_feature_flag(:show_group_readme, group)
+ end
+
helper_method :captcha_required?
skip_cross_project_access_check :index, :new, :create, :edit, :update,
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index bedeae3cf54..d0e14000d8e 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -2,7 +2,6 @@
class IdeController < ApplicationController
include VSCodeCDNCSP
- include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP
include Gitlab::Utils::StrongMemoize
diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb
index e9705c45116..f4eea3abd32 100644
--- a/app/controllers/import/bulk_imports_controller.rb
+++ b/app/controllers/import/bulk_imports_controller.rb
@@ -53,6 +53,7 @@ class Import::BulkImportsController < ApplicationController
end
def create
+ return render json: { success: false }, status: :too_many_requests if throttled_request?
return render json: { success: false }, status: :unprocessable_entity unless valid_create_params?
responses = create_params.map do |entry|
@@ -204,4 +205,8 @@ class Import::BulkImportsController < ApplicationController
def current_user_bulk_imports
current_user.bulk_imports.gitlab
end
+
+ def throttled_request?
+ ::Gitlab::ApplicationRateLimiter.throttled_request?(request, current_user, :bulk_import, scope: current_user)
+ end
end
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 9a8f6a74653..0bee1faccf5 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -79,13 +79,7 @@ class Import::GithubController < Import::BaseController
def realtime_changes
Gitlab::PollingInterval.set_header(response, interval: 3_000)
- render json: already_added_projects.map { |project|
- {
- id: project.id,
- import_status: project.import_status,
- stats: ::Gitlab::GithubImport::ObjectCounter.summary(project)
- }
- }
+ render json: Import::GithubRealtimeRepoSerializer.new.represent(already_added_projects)
end
def cancel
@@ -99,6 +93,23 @@ class Import::GithubController < Import::BaseController
end
end
+ def cancel_all
+ projects_to_cancel = Project.imported_from(provider_name).created_by(current_user).is_importing
+
+ canceled = projects_to_cancel.map do |project|
+ # #reset is called to make sure project was not finished/canceled brefore calling service
+ result = Import::Github::CancelProjectImportService.new(project.reset, current_user).execute
+
+ {
+ id: project.id,
+ status: result[:status],
+ error: result[:message]
+ }.compact
+ end
+
+ render json: canceled
+ end
+
protected
override :importable_repos
diff --git a/app/controllers/jira_connect/public_keys_controller.rb b/app/controllers/jira_connect/public_keys_controller.rb
index 09003f8478f..4505ab16926 100644
--- a/app/controllers/jira_connect/public_keys_controller.rb
+++ b/app/controllers/jira_connect/public_keys_controller.rb
@@ -10,9 +10,7 @@ module JiraConnect
skip_before_action :authenticate_user!
def show
- if Feature.disabled?(:jira_connect_oauth_self_managed) || !Gitlab.config.jira_connect.enable_public_keys_storage
- return render_404
- end
+ return render_404 unless public_key_storage_enabled?
render plain: public_key.key
end
@@ -22,5 +20,11 @@ module JiraConnect
def public_key
JiraConnect::PublicKey.find(params[:id])
end
+
+ def public_key_storage_enabled?
+ return true if Gitlab.config.jira_connect.enable_public_keys_storage
+
+ Gitlab::CurrentSettings.jira_connect_public_key_storage_enabled?
+ end
end
end
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index ff7477a94d6..a206e7fbbd8 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -21,7 +21,6 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
before_action do
push_frontend_feature_flag(:jira_connect_oauth, @user)
- push_frontend_feature_flag(:jira_connect_oauth_self_managed, @user)
end
before_action :allow_rendering_in_iframe, only: :index
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 5bd3b74af1f..4046433f8ea 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -61,14 +61,6 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
handle_omniauth
end
- def authentiq
- if params['sid']
- handle_service_ticket oauth['provider'], params['sid']
- end
-
- handle_omniauth
- end
-
def auth0
if oauth['uid'].blank?
fail_auth0_login
diff --git a/app/controllers/profiles/avatars_controller.rb b/app/controllers/profiles/avatars_controller.rb
index 55a2904ce83..829a87b7d0a 100644
--- a/app/controllers/profiles/avatars_controller.rb
+++ b/app/controllers/profiles/avatars_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Profiles::AvatarsController < Profiles::ApplicationController
- feature_category :users
+ feature_category :user_profile
def destroy
@user = current_user
diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb
index 7e332d9a498..c88616b6d6c 100644
--- a/app/controllers/profiles/emails_controller.rb
+++ b/app/controllers/profiles/emails_controller.rb
@@ -7,7 +7,7 @@ class Profiles::EmailsController < Profiles::ApplicationController
before_action -> { check_rate_limit!(:profile_resend_email_confirmation, scope: current_user, redirect_back: true) },
only: [:resend_confirmation_instructions]
- feature_category :users
+ feature_category :user_profile
urgency :low, [:index]
def index
diff --git a/app/controllers/profiles/groups_controller.rb b/app/controllers/profiles/groups_controller.rb
index 5962b10c44b..fdd76a7f7be 100644
--- a/app/controllers/profiles/groups_controller.rb
+++ b/app/controllers/profiles/groups_controller.rb
@@ -3,7 +3,7 @@
class Profiles::GroupsController < Profiles::ApplicationController
include RoutableActions
- feature_category :users
+ feature_category :user_profile
def update
group = find_routable!(Group, params[:id], request.fullpath)
diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb
index 39e8f6c500d..31c758ac763 100644
--- a/app/controllers/profiles/keys_controller.rb
+++ b/app/controllers/profiles/keys_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Profiles::KeysController < Profiles::ApplicationController
- feature_category :users
+ feature_category :user_profile
urgency :low, [:create, :index]
def index
@@ -34,6 +34,16 @@ class Profiles::KeysController < Profiles::ApplicationController
end
end
+ def revoke
+ @key = current_user.keys.find(params[:id])
+ Keys::RevokeService.new(current_user).execute(@key)
+
+ respond_to do |format|
+ format.html { redirect_to profile_keys_url, status: :found }
+ format.js { head :ok }
+ end
+ end
+
private
def key_params
diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb
index 974e7104c07..7786bad4251 100644
--- a/app/controllers/profiles/preferences_controller.rb
+++ b/app/controllers/profiles/preferences_controller.rb
@@ -3,7 +3,7 @@
class Profiles::PreferencesController < Profiles::ApplicationController
before_action :user
- feature_category :users
+ feature_category :user_profile
urgency :low, [:show]
urgency :medium, [:update]
diff --git a/app/controllers/profiles/saved_replies_controller.rb b/app/controllers/profiles/saved_replies_controller.rb
new file mode 100644
index 00000000000..5ac5d645efb
--- /dev/null
+++ b/app/controllers/profiles/saved_replies_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Profiles
+ class SavedRepliesController < Profiles::ApplicationController
+ feature_category :user_profile
+
+ before_action do
+ render_404 unless Feature.enabled?(:saved_replies, current_user)
+
+ @hide_search_settings = true
+ end
+ end
+end
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index c36f03d3e69..aded295bfab 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -3,7 +3,7 @@
class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
skip_before_action :check_two_factor_requirement
before_action :ensure_verified_primary_email, only: [:show, :create]
- before_action :validate_current_password, only: [:create, :codes, :destroy], if: :current_password_required?
+ before_action :validate_current_password, only: [:create, :codes, :destroy, :create_webauthn], if: :current_password_required?
before_action :update_current_user_otp!, only: [:show]
helper_method :current_password_required?
@@ -21,8 +21,13 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def create
otp_validation_result =
::Users::ValidateManualOtpService.new(current_user).execute(params[:pin_code])
+ validated = (otp_validation_result[:status] == :success)
- if otp_validation_result[:status] == :success
+ if validated && current_user.otp_backup_codes? && Feature.enabled?(:webauthn_without_totp)
+ ActiveSession.destroy_all_but_current(current_user, session)
+ Users::UpdateService.new(current_user, user: current_user, otp_required_for_login: true).execute!
+ redirect_to profile_two_factor_auth_path, notice: _("Your Time-based OTP device was registered!")
+ elsif validated
ActiveSession.destroy_all_but_current(current_user, session)
Users::UpdateService.new(current_user, user: current_user, otp_required_for_login: true).execute! do |user|
@@ -64,10 +69,27 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def create_webauthn
@webauthn_registration = Webauthn::RegisterService.new(current_user, device_registration_params, session[:challenge]).execute
+
+ notice = _("Your WebAuthn device was registered!")
if @webauthn_registration.persisted?
session.delete(:challenge)
- redirect_to profile_two_factor_auth_path, notice: s_("Your WebAuthn device was registered!")
+ if Feature.enabled?(:webauthn_without_totp)
+
+ if current_user.otp_backup_codes?
+ redirect_to profile_two_factor_auth_path, notice: notice
+ else
+
+ Users::UpdateService.new(current_user, user: current_user).execute! do |user|
+ @codes = current_user.generate_otp_backup_codes!
+ end
+ helpers.dismiss_two_factor_auth_recovery_settings_check
+ flash[:notice] = notice
+ render 'create'
+ end
+ else
+ redirect_to profile_two_factor_auth_path, notice: notice
+ end
else
@qr_code = build_qr_code
@@ -119,11 +141,17 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
end
def validate_current_password
+ return if Feature.disabled?(:webauthn_without_totp) && params[:action] == 'create_webauthn'
return if current_user.valid_password?(params[:current_password])
current_user.increment_failed_attempts!
- @error = { message: _('You must provide a valid current password') }
+ error_message = { message: _('You must provide a valid current password.') }
+ if params[:action] == 'create_webauthn'
+ @webauthn_error = error_message
+ else
+ @error = error_message
+ end
setup_show_page
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index e3704b77adc..45b274fc920 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -14,7 +14,7 @@ class ProfilesController < Profiles::ApplicationController
push_frontend_feature_flag(:webauthn)
end
- feature_category :users, [:show, :update, :reset_incoming_email_token, :reset_feed_token,
+ feature_category :user_profile, [:show, :update, :reset_incoming_email_token, :reset_feed_token,
:reset_static_object_token, :update_username]
feature_category :authentication_and_authorization, [:audit_log]
@@ -127,6 +127,7 @@ class ProfilesController < Profiles::ApplicationController
:commit_email,
:skype,
:twitter,
+ :discord,
:username,
:website_url,
:organization,
diff --git a/app/controllers/projects/airflow/dags_controller.rb b/app/controllers/projects/airflow/dags_controller.rb
new file mode 100644
index 00000000000..9d1f0b0d63b
--- /dev/null
+++ b/app/controllers/projects/airflow/dags_controller.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Projects
+ module Airflow
+ class DagsController < ::Projects::ApplicationController
+ before_action :check_feature_flag
+ before_action :authorize_read_airflow_dags!
+
+ feature_category :dataops
+
+ MAX_DAGS_PER_PAGE = 15
+ def index
+ page = params[:page].to_i
+ page = 1 if page <= 0
+
+ @dags = ::Airflow::Dags.by_project_id(@project.id)
+
+ return unless @dags.any?
+
+ @dags = @dags.page(page).per(MAX_DAGS_PER_PAGE)
+ return redirect_to(url_for(page: @dags.total_pages)) if @dags.out_of_range?
+
+ @pagination = {
+ page: page,
+ is_last_page: @dags.last_page?,
+ per_page: MAX_DAGS_PER_PAGE,
+ total_items: @dags.total_count
+ }
+ end
+
+ private
+
+ def check_feature_flag
+ render_404 unless Feature.enabled?(:airflow_dags, @project)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
index ab2cf3abdde..a61b774f9c8 100644
--- a/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
+++ b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
@@ -3,7 +3,6 @@
class Projects::Analytics::CycleAnalytics::StagesController < Projects::ApplicationController
include ::Analytics::CycleAnalytics::StageActions
include Gitlab::Utils::StrongMemoize
- extend ::Gitlab::Utils::Override
respond_to :json
@@ -11,20 +10,14 @@ class Projects::Analytics::CycleAnalytics::StagesController < Projects::Applicat
before_action :authorize_read_cycle_analytics!
before_action :only_default_value_stream_is_allowed!
- before_action :authorize_stage!, only: [:median, :count, :average, :records]
urgency :low
private
- override :parent
- def parent
- @project
- end
-
- override :value_stream_class
- def value_stream_class
- Analytics::CycleAnalytics::ProjectValueStream
+ override :namespace
+ def namespace
+ @project.project_namespace
end
override :cycle_analytics_configuration
@@ -33,7 +26,9 @@ class Projects::Analytics::CycleAnalytics::StagesController < Projects::Applicat
end
def only_default_value_stream_is_allowed!
- render_404 if params[:value_stream_id] != Analytics::CycleAnalytics::Stages::BaseService::DEFAULT_VALUE_STREAM_NAME
+ return if requests_default_value_stream?
+
+ render_403
end
def permitted_stage?(stage)
@@ -42,11 +37,20 @@ class Projects::Analytics::CycleAnalytics::StagesController < Projects::Applicat
def permissions
strong_memoize(:permissions) do
- Gitlab::CycleAnalytics::Permissions.new(user: current_user, project: parent).get
+ Gitlab::CycleAnalytics::Permissions.new(user: current_user, project: @project).get
end
end
- def authorize_stage!
+ def authorize_stage
render_403 unless permitted_stage?(stage)
end
+
+ def requests_default_value_stream?
+ default_name = Analytics::CycleAnalytics::Stages::BaseService::DEFAULT_VALUE_STREAM_NAME
+
+ params[:value_stream_id] == default_name
+ end
end
+
+mod = 'Projects::Analytics::CycleAnalytics::StagesController'
+Projects::Analytics::CycleAnalytics::StagesController.prepend_mod_with(mod) # rubocop: disable Cop/InjectEnterpriseEditionModule
diff --git a/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb b/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb
index 60bcd1d7238..f58730f1d33 100644
--- a/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb
+++ b/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb
@@ -1,17 +1,16 @@
# frozen_string_literal: true
class Projects::Analytics::CycleAnalytics::ValueStreamsController < Projects::ApplicationController
+ include ::Analytics::CycleAnalytics::ValueStreamActions
+
respond_to :json
feature_category :planning_analytics
urgency :low
- before_action :authorize_read_cycle_analytics!
-
- def index
- # FOSS users can only see the default value stream
- value_streams = [Analytics::CycleAnalytics::ProjectValueStream.build_default_value_stream(@project)]
+ private
- render json: Analytics::CycleAnalytics::ValueStreamSerializer.new.represent(value_streams)
+ def namespace
+ project.project_namespace
end
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 25b83aed78a..62233c8c3c9 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -32,21 +32,6 @@ class Projects::ApplicationController < ApplicationController
->(project) { !project.pending_delete? }
end
- def authorize_read_build_trace!
- return if can?(current_user, :read_build_trace, build)
-
- if build.debug_mode?
- access_denied!(
- _('You must have developer or higher permissions in the associated project to view job logs when debug trace ' \
- "is enabled. To disable debug trace, set the 'CI_DEBUG_TRACE' and 'CI_DEBUG_SERVICES' variables to 'false' " \
- 'in your pipeline configuration or CI/CD settings. If you must view this job log, a project maintainer ' \
- 'or owner must add you to the project with developer permissions or higher.')
- )
- else
- access_denied!(_('The current user is not authorized to access the job log.'))
- end
- end
-
def build_canonical_path(project)
params[:namespace_id] = project.namespace.to_param
params[:project_id] = project.to_param
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index 3201538a393..5f8060ad756 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class Projects::ArtifactsController < Projects::ApplicationController
+ include Ci::AuthBuildTrace
include ExtractsPath
include RendersBlob
include SendFileUpload
@@ -11,6 +12,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
layout 'project'
before_action :authorize_read_build!
before_action :authorize_read_build_trace!, only: [:download]
+ before_action :authorize_read_job_artifacts!, only: [:download]
before_action :authorize_update_build!, only: [:keep]
before_action :authorize_destroy_artifacts!, only: [:destroy]
before_action :extract_ref_name_and_path
@@ -40,10 +42,10 @@ class Projects::ArtifactsController < Projects::ApplicationController
end
def download
- return render_404 unless artifacts_file
+ return render_404 unless artifact_file
- log_artifacts_filesize(artifacts_file.model)
- send_upload(artifacts_file, attachment: artifacts_file.filename, proxy: params[:proxy])
+ log_artifacts_filesize(artifact_file.model)
+ send_upload(artifact_file, attachment: artifact_file.filename, proxy: params[:proxy])
end
def browse
@@ -82,11 +84,11 @@ class Projects::ArtifactsController < Projects::ApplicationController
def raw
return render_404 unless zip_artifact?
- return render_404 unless artifacts_file
+ return render_404 unless artifact_file
path = Gitlab::Ci::Build::Artifacts::Path.new(params[:path])
- send_artifacts_entry(artifacts_file, path)
+ send_artifacts_entry(artifact_file, path)
end
def keep
@@ -153,8 +155,12 @@ class Projects::ArtifactsController < Projects::ApplicationController
project.latest_successful_build_for_ref(params[:job], @ref_name)
end
- def artifacts_file
- @artifacts_file ||= build&.artifacts_file_for_type(params[:file_type] || :archive)
+ def job_artifact
+ @job_artifact ||= build&.artifact_for_type(params[:file_type] || :archive)
+ end
+
+ def artifact_file
+ @artifact_file ||= job_artifact&.file
end
def zip_artifact?
@@ -175,4 +181,8 @@ class Projects::ArtifactsController < Projects::ApplicationController
super
end
+
+ def authorize_read_job_artifacts!
+ return access_denied! unless can?(current_user, :read_job_artifacts, job_artifact)
+ end
end
diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb
index 000203079cc..ffe6071ab3c 100644
--- a/app/controllers/projects/autocomplete_sources_controller.rb
+++ b/app/controllers/projects/autocomplete_sources_controller.rb
@@ -6,7 +6,7 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController
feature_category :team_planning, [:issues, :labels, :milestones, :commands, :contacts]
feature_category :code_review_workflow, [:merge_requests]
- feature_category :users, [:members]
+ feature_category :user_profile, [:members]
feature_category :source_code_management, [:snippets]
urgency :low, [:merge_requests, :members]
@@ -54,6 +54,8 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController
# type_id is not required in general
target_type = params.require(:type)
+ # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/388541
+ # type_id is a misnomer. QuickActions::TargetService actually requires an iid.
QuickActions::TargetService
.new(project, current_user)
.execute(target_type, params[:type_id])
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 4eda76f4f21..59cea00e26b 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -239,6 +239,8 @@ class Projects::BlobController < Projects::ApplicationController
@last_commit = @repository.last_commit_for_path(@commit.id, @blob.path, literal_pathspec: true)
@code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path)
+ allow_lfs_direct_download
+
render 'show'
end
@@ -282,6 +284,30 @@ class Projects::BlobController < Projects::ApplicationController
def visitor_id
current_user&.id
end
+
+ def allow_lfs_direct_download
+ return unless directly_downloading_lfs_object? && content_security_policy_enabled?
+ return unless (lfs_object = @project.lfs_objects.find_by_oid(@blob.lfs_oid))
+
+ request.content_security_policy.directives['connect-src'] ||= []
+ request.content_security_policy.directives['connect-src'] << lfs_src(lfs_object)
+ end
+
+ def directly_downloading_lfs_object?
+ Gitlab.config.lfs.enabled &&
+ !Gitlab.config.lfs.object_store.proxy_download &&
+ @blob&.stored_externally?
+ end
+
+ def content_security_policy_enabled?
+ Gitlab.config.gitlab.content_security_policy.enabled
+ end
+
+ def lfs_src(lfs_object)
+ file = lfs_object.file
+ file = file.cdn_enabled_url(request.remote_ip) if file.respond_to?(:cdn_enabled_url)
+ file.url
+ end
end
Projects::BlobController.prepend_mod
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 7b01e4db42a..f19f143816f 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -19,8 +19,10 @@ class Projects::BranchesController < Projects::ApplicationController
def index
respond_to do |format|
format.html do
- @mode = params[:state].presence || 'overview'
- @sort = sort_value_for_mode
+ @mode = fetch_mode
+ next render_404 unless @mode
+
+ @sort = sort_param || default_sort
@overview_max_branches = 5
# Fetch branches for the specified mode
@@ -128,11 +130,7 @@ class Projects::BranchesController < Projects::ApplicationController
private
- def sort_value_for_mode
- custom_sort || default_sort
- end
-
- def custom_sort
+ def sort_param
sort = params[:sort].presence
unless sort.in?(supported_sort_options)
@@ -144,11 +142,11 @@ class Projects::BranchesController < Projects::ApplicationController
end
def default_sort
- 'stale' == @mode ? sort_value_oldest_updated : sort_value_recently_updated
+ 'stale' == @mode ? SORT_UPDATED_OLDEST : SORT_UPDATED_RECENT
end
def supported_sort_options
- [nil, sort_value_name, sort_value_oldest_updated, sort_value_recently_updated]
+ [nil, SORT_NAME, SORT_UPDATED_OLDEST, SORT_UPDATED_RECENT]
end
# It can be expensive to calculate the diverging counts for each
@@ -206,15 +204,23 @@ class Projects::BranchesController < Projects::ApplicationController
limit = @overview_max_branches + 1
@active_branches =
- BranchesFinder.new(@repository, { per_page: limit, sort: sort_value_recently_updated })
+ BranchesFinder.new(@repository, { per_page: limit, sort: SORT_UPDATED_RECENT })
.execute(gitaly_pagination: true).select(&:active?)
@stale_branches =
- BranchesFinder.new(@repository, { per_page: limit, sort: sort_value_oldest_updated })
+ BranchesFinder.new(@repository, { per_page: limit, sort: SORT_UPDATED_OLDEST })
.execute(gitaly_pagination: true).select(&:stale?)
@branches = @active_branches + @stale_branches
end
+ def fetch_mode
+ state = params[:state].presence
+
+ return 'overview' unless state
+
+ state.presence_in(%w[active stale all overview])
+ end
+
def confidential_issue_project
return if params[:confidential_issue_project_id].blank?
diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb
index 1942a5fef7b..3a2bc445737 100644
--- a/app/controllers/projects/ci/pipeline_editor_controller.rb
+++ b/app/controllers/projects/ci/pipeline_editor_controller.rb
@@ -2,6 +2,9 @@
class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
+ before_action do
+ push_frontend_feature_flag(:ci_job_assistant_drawer, @project)
+ end
feature_category :pipeline_authoring
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 583b572d4b1..252b203b38a 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -31,6 +31,7 @@ class Projects::CommitController < Projects::ApplicationController
respond_to do |format|
format.html do
+ @ref = params[:id]
render locals: { pagination_params: params.permit(:page) }
end
format.diff do
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index c006d56ae81..3acc71d5dd3 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -75,7 +75,7 @@ class Projects::CommitsController < Projects::ApplicationController
search = permitted_params[:search]
author = permitted_params[:author]
- # fully_qualified_ref is available in some situations when the use_ref_type_parameter FF is enabled
+ # fully_qualified_ref is available in some situations from ExtractsRef
ref = @fully_qualified_ref || @ref
@commits =
if search.present?
diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb
index 63c1378ad11..9fe44659250 100644
--- a/app/controllers/projects/cycle_analytics_controller.rb
+++ b/app/controllers/projects/cycle_analytics_controller.rb
@@ -48,7 +48,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
end
def load_value_stream
- @value_stream = Analytics::CycleAnalytics::ProjectValueStream.build_default_value_stream(@project)
+ @value_stream = Analytics::CycleAnalytics::ValueStream.build_default_value_stream(@project.project_namespace)
end
def cycle_analytics_json
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index ea1288c0b20..9a88a8160b6 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -19,6 +19,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action only: [:show] do
push_frontend_feature_flag(:environment_details_vue, @project)
end
+
before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
before_action :authorize_stop_environment!, only: [:stop]
@@ -57,6 +58,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
render json: {
environments: serialize_environments(request, response, params[:nested]),
review_app: serialize_review_app,
+ can_stop_stale_environments: can?(current_user, :stop_environment, @project),
available_count: environments_count_by_state[:available],
stopped_count: environments_count_by_state[:stopped]
}
diff --git a/app/controllers/projects/google_cloud/databases_controller.rb b/app/controllers/projects/google_cloud/databases_controller.rb
index b511a85b0b8..9c20f10809c 100644
--- a/app/controllers/projects/google_cloud/databases_controller.rb
+++ b/app/controllers/projects/google_cloud/databases_controller.rb
@@ -51,7 +51,7 @@ module Projects
if enable_response[:status] == :error
track_event(:error_enable_cloudsql_services)
- flash[:error] = error_message(enable_response[:message])
+ flash[:alert] = error_message(enable_response[:message])
else
create_response = ::GoogleCloud::CreateCloudsqlInstanceService
.new(project, current_user, create_service_params)
diff --git a/app/controllers/projects/google_cloud/deployments_controller.rb b/app/controllers/projects/google_cloud/deployments_controller.rb
index fae8dbd59c7..92c99ad4271 100644
--- a/app/controllers/projects/google_cloud/deployments_controller.rb
+++ b/app/controllers/projects/google_cloud/deployments_controller.rb
@@ -22,7 +22,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
if enable_cloud_run_response[:status] == :error
track_event(:error_enable_services)
- flash[:error] = enable_cloud_run_response[:message]
+ flash[:alert] = enable_cloud_run_response[:message]
redirect_to project_google_cloud_deployments_path(project)
else
params = { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN }
@@ -31,7 +31,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
if generate_pipeline_response[:status] == :error
track_event(:error_generate_cloudrun_pipeline)
- flash[:error] = 'Failed to generate pipeline'
+ flash[:alert] = '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])
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 06c16297ce8..21227d62023 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -28,8 +28,7 @@ class Projects::IssuesController < Projects::ApplicationController
SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !index_html_request?
}
before_action :check_search_rate_limit!, if: ->(c) {
- SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !index_html_request? &&
- params[:search].present? && Feature.enabled?(:rate_limit_issuable_searches)
+ SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !index_html_request? && params[:search].present?
}
# Allow write(create) issue
@@ -47,6 +46,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:preserve_unchanged_markdown, project)
push_frontend_feature_flag(:content_editor_on_issues, project)
+ push_frontend_feature_flag(:service_desk_new_note_email_native_attachments, project)
end
before_action only: [:index, :show] do
@@ -55,6 +55,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action only: :index do
push_frontend_feature_flag(:or_issuable_queries, project)
+ push_frontend_feature_flag(:frontend_caching, project&.group)
end
before_action only: :show do
@@ -64,7 +65,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?)
push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
push_frontend_feature_flag(:use_iid_in_work_items_path, project&.group)
- push_force_frontend_feature_flag(:work_items_create_from_markdown, project&.work_items_create_from_markdown_feature_flag_enabled?)
+ push_frontend_feature_flag(:incident_event_tags, project)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
@@ -127,7 +128,7 @@ class Projects::IssuesController < Projects::ApplicationController
discussion_to_resolve: params[:discussion_to_resolve],
confidential: !!Gitlab::Utils.to_boolean(issue_params[:confidential])
)
- service = ::Issues::BuildService.new(project: project, current_user: current_user, params: build_params)
+ service = ::Issues::BuildService.new(container: project, current_user: current_user, params: build_params)
@issue = @noteable = service.execute
@@ -155,7 +156,7 @@ class Projects::IssuesController < Projects::ApplicationController
)
spam_params = ::Spam::SpamParams.new_from_request(request: request)
- service = ::Issues::CreateService.new(project: project, current_user: current_user, params: create_params, spam_params: spam_params)
+ service = ::Issues::CreateService.new(container: project, current_user: current_user, params: create_params, spam_params: spam_params)
result = service.execute
# Only irrecoverable errors such as unauthorized user won't contain an issue in the response
@@ -190,7 +191,7 @@ class Projects::IssuesController < Projects::ApplicationController
new_project = Project.find(params[:move_to_project_id])
return render_404 unless issue.can_move?(current_user, new_project)
- @issue = ::Issues::MoveService.new(project: project, current_user: current_user).execute(issue, new_project)
+ @issue = ::Issues::MoveService.new(container: project, current_user: current_user).execute(issue, new_project)
end
respond_to do |format|
@@ -204,7 +205,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
def reorder
- service = ::Issues::ReorderService.new(project: project, current_user: current_user, params: reorder_params)
+ service = ::Issues::ReorderService.new(container: project, current_user: current_user, params: reorder_params)
if service.execute(issue)
head :ok
@@ -215,7 +216,7 @@ class Projects::IssuesController < Projects::ApplicationController
def related_branches
@related_branches = ::Issues::RelatedBranchesService
- .new(project: project, current_user: current_user)
+ .new(container: project, current_user: current_user)
.execute(issue)
.map { |branch| branch.merge(link: branch_link(branch)) }
@@ -370,7 +371,7 @@ class Projects::IssuesController < Projects::ApplicationController
def update_service
spam_params = ::Spam::SpamParams.new_from_request(request: request)
- ::Issues::UpdateService.new(project: project, current_user: current_user, params: issue_params, spam_params: spam_params)
+ ::Issues::UpdateService.new(container: project, current_user: current_user, params: issue_params, spam_params: spam_params)
end
def finder_type
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index c6d442a6f27..3fea5c694f7 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
class Projects::JobsController < Projects::ApplicationController
+ include Ci::AuthBuildTrace
include SendFileUpload
include ContinueParams
include ProjectStatsRefreshConflictsGuard
urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :erase, :raw]
- before_action :find_job_as_build, except: [:index, :play, :show]
- before_action :find_job_as_processable, only: [:play, :show]
+ before_action :find_job_as_build, except: [:index, :play, :show, :retry]
+ before_action :find_job_as_processable, only: [:play, :show, :retry]
before_action :authorize_read_build_trace!, only: [:trace, :raw]
before_action :authorize_read_build!
before_action :authorize_update_build!,
@@ -76,7 +77,11 @@ class Projects::JobsController < Projects::ApplicationController
response = Ci::RetryJobService.new(project, current_user).execute(@build)
if response.success?
- redirect_to build_path(response[:job])
+ if @build.is_a?(::Ci::Build)
+ redirect_to build_path(response[:job])
+ else
+ head :ok
+ end
else
respond_422
end
diff --git a/app/controllers/projects/learn_gitlab_controller.rb b/app/controllers/projects/learn_gitlab_controller.rb
deleted file mode 100644
index 6fe009c8a28..00000000000
--- a/app/controllers/projects/learn_gitlab_controller.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class Projects::LearnGitlabController < Projects::ApplicationController
- before_action :authenticate_user!
- before_action :check_experiment_enabled?
- before_action :enable_invite_for_help_continuous_onboarding_experiment
- before_action :enable_video_tutorials_continuous_onboarding_experiment
-
- feature_category :users
- urgency :low, [:index]
-
- def index
- end
-
- private
-
- def check_experiment_enabled?
- return access_denied! unless helpers.learn_gitlab_enabled?(project)
- end
-
- def enable_invite_for_help_continuous_onboarding_experiment
- return unless current_user.can?(:admin_group_member, project.namespace)
-
- experiment(:invite_for_help_continuous_onboarding, namespace: project.namespace) do |e|
- e.candidate {}
- end
- end
-
- def enable_video_tutorials_continuous_onboarding_experiment
- experiment(:video_tutorials_continuous_onboarding, namespace: project&.namespace).publish
- end
-end
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index cba0056ccd5..3b399e3294e 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -20,10 +20,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
:branch_to
]
- before_action do
- push_frontend_feature_flag(:mr_compare_dropdowns, project)
- end
-
def new
define_new_vars
end
@@ -97,7 +93,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
def target_projects
projects = MergeRequestTargetProjectFinder
.new(current_user: current_user, source_project: @project, project_feature: :repository)
- .execute(include_routes: true).limit(20).search(params[:search])
+ .execute(include_routes: false, search: params[:search]).limit(20)
render json: ProjectSerializer.new.represent(projects)
end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 1c546d70df9..6ca885cee4c 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -61,6 +61,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
options[:merge_ref_head_diff]
]
+ expires_in(1.day) if cache_with_max_age?
+
return unless stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
Gitlab::Metrics.measure(:diffs_unfold) do
@@ -238,4 +240,10 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
.track_mr_diffs_single_file_action(merge_request: @merge_request, user: current_user)
end
+
+ def cache_with_max_age?
+ @merge_request.diffs_batch_cache_with_max_age? &&
+ params[:ck].present? &&
+ render_merge_ref_head_diff?
+ end
end
diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb
index 74bb3ad1a63..ca6ab83b877 100644
--- a/app/controllers/projects/merge_requests/drafts_controller.rb
+++ b/app/controllers/projects/merge_requests/drafts_controller.rb
@@ -49,24 +49,22 @@ 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)
- if create_note_params[:note]
- ::Notes::CreateService.new(@project, current_user, create_note_params).execute
+ 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
+ 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)
+ 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
+ unless success
+ return render json: { message: _('An error occurred while approving, please try again.') }, status: :internal_server_error
end
-
- merge_request_activity_counter.track_submit_review_approve(user: current_user)
end
+
+ merge_request_activity_counter.track_submit_review_approve(user: current_user)
end
if result[:status] == :success
@@ -145,7 +143,7 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
user_ids = notes.map(&:author_id)
project.team.max_member_access_for_user_ids(user_ids)
- notes.map(&method(:render_draft_note))
+ notes.map { |note| render_draft_note(note) }
end
def render_draft_note(note)
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index b0920b3fbdb..d92ef3de6d9 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -28,9 +28,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:codequality_mr_diff_reports
]
before_action :set_issuables_index, only: [:index]
- before_action :check_search_rate_limit!, only: [:index], if: -> {
- params[:search].present? && Feature.enabled?(:rate_limit_issuable_searches)
- }
+ before_action :check_search_rate_limit!, only: [:index], if: -> { params[:search].present? }
before_action :authenticate_user!, only: [:assign_related_issues]
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
@@ -40,9 +38,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:refactor_security_extension, @project)
push_frontend_feature_flag(:refactor_code_quality_inline_findings, project)
push_frontend_feature_flag(:moved_mr_sidebar, project)
- push_frontend_feature_flag(:mr_review_submit_comment, project)
push_frontend_feature_flag(:mr_experience_survey, project)
- push_frontend_feature_flag(:realtime_reviewers, project)
push_frontend_feature_flag(:realtime_mr_status_change, project)
end
@@ -282,11 +278,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
case result[:count]
when 0
- flash[:error] = "Failed to assign you issues related to the merge request"
- when 1
- flash[:notice] = "1 issue has been assigned to you"
+ flash[:alert] = _("Failed to assign you issues related to the merge request.")
else
- flash[:notice] = "#{result[:count]} issues have been assigned to you"
+ flash[:notice] = n_("An issue has been assigned to you.", "%d issues have been assigned to you.", result[:count])
end
redirect_to(merge_request_path(@merge_request))
@@ -356,10 +350,20 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
private
+ # NOTE: Remove this disable with add_prepared_state_to_mr FF removal
+ # rubocop: disable Metrics/AbcSize
def show_merge_request
close_merge_request_if_no_source_project
@merge_request.check_mergeability(async: true)
+ # NOTE: Remove the created_at check when removing the FF check
+ if ::Feature.enabled?(:add_prepared_state_to_mr, @merge_request.project) &&
+ @merge_request.created_at < 5.minutes.ago &&
+ !@merge_request.prepared?
+
+ @merge_request.prepare
+ end
+
respond_to do |format|
format.html do
# use next to appease Rubocop
@@ -401,6 +405,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
end
end
+ # rubocop: enable Metrics/AbcSize
def render_html_page
preload_assignees_for_render(@merge_request)
@@ -419,6 +424,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@update_current_user_path = expose_path(api_v4_user_preferences_path)
@endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
@endpoint_diff_batch_url = endpoint_diff_batch_url(@project, @merge_request)
+ @diffs_batch_cache_key = @merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
set_pipeline_variables
@@ -576,6 +582,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def endpoint_diff_batch_url(project, merge_request)
per_page = current_user&.view_diffs_file_by_file ? '1' : '5'
params = request.query_parameters.merge(view: 'inline', diff_head: true, w: show_whitespace, page: '0', per_page: per_page)
+ params[:ck] = merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
diffs_batch_project_json_merge_request_path(project, merge_request, 'json', params)
end
diff --git a/app/controllers/projects/ml/experiments_controller.rb b/app/controllers/projects/ml/experiments_controller.rb
index 1e1c4b1587c..00b965542f6 100644
--- a/app/controllers/projects/ml/experiments_controller.rb
+++ b/app/controllers/projects/ml/experiments_controller.rb
@@ -3,6 +3,8 @@
module Projects
module Ml
class ExperimentsController < ::Projects::ApplicationController
+ include Projects::Ml::ExperimentsHelper
+
before_action :check_feature_flag
feature_category :mlops
@@ -11,7 +13,12 @@ module Projects
MAX_CANDIDATES_PER_PAGE = 30
def index
- @experiments = ::Ml::Experiment.by_project_id(@project.id).page(params[:page]).per(MAX_EXPERIMENTS_PER_PAGE)
+ paginator = ::Ml::Experiment.by_project_id(@project.id)
+ .with_candidate_count
+ .keyset_paginate(cursor: params[:cursor], per_page: MAX_EXPERIMENTS_PER_PAGE)
+
+ @experiments = paginator.records
+ @page_info = page_info(paginator)
end
def show
@@ -19,26 +26,17 @@ module Projects
return redirect_to project_ml_experiments_path(@project) unless @experiment.present?
- page = params[:page].to_i
- page = 1 if page == 0
-
- @candidates = @experiment.candidates
- .including_relationships
- .page(page)
- .per(MAX_CANDIDATES_PER_PAGE)
-
- return unless @candidates
-
- return redirect_to(url_for(page: @candidates.total_pages)) if @candidates.out_of_range?
+ find_params = params
+ .transform_keys(&:underscore)
+ .permit(:name, :order_by, :sort, :order_by_type)
- @pagination = {
- page: page,
- is_last_page: @candidates.last_page?,
- per_page: MAX_CANDIDATES_PER_PAGE,
- total_items: @candidates.total_count
- }
+ paginator = CandidateFinder
+ .new(@experiment, find_params)
+ .execute
+ .keyset_paginate(cursor: params[:cursor], per_page: MAX_CANDIDATES_PER_PAGE)
- @candidates.each(&:artifact_lazy)
+ @candidates = paginator.records.each(&:artifact_lazy)
+ @page_info = page_info(paginator)
end
private
diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb
index aa0838752e2..f3c63b1b97b 100644
--- a/app/controllers/projects/network_controller.rb
+++ b/app/controllers/projects/network_controller.rb
@@ -14,11 +14,7 @@ class Projects::NetworkController < Projects::ApplicationController
urgency :low, [:show]
def show
- @url = if Feature.enabled?(:use_ref_type_parameter, @project)
- project_network_path(@project, @ref, @options.merge(format: :json, ref_type: ref_type))
- else
- project_network_path(@project, @ref, @options.merge(format: :json))
- end
+ @url = project_network_path(@project, @ref, @options.merge(format: :json, ref_type: ref_type))
@ref_type = ref_type
@commit_url = project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 9d3506d49b0..054e8c302c9 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -12,7 +12,8 @@ class Projects::NotesController < Projects::ApplicationController
before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
feature_category :team_planning
- urgency :low
+ urgency :medium, [:index]
+ urgency :low, [:create, :update, :destroy, :resolve, :unresolve, :toggle_award_emoji, :outdated_line_change]
def delete_attachment
note.remove_attachment!
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index 31030d958df..19d031bd59b 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -41,7 +41,9 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
end
def update
- if schedule.update(schedule_params)
+ response = Ci::PipelineSchedules::UpdateService.new(schedule, current_user, schedule_params).execute
+
+ if response.success?
redirect_to project_pipeline_schedules_path(@project)
else
render :edit
@@ -63,7 +65,9 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
end
def take_ownership
- if schedule.update(owner: current_user)
+ response = Ci::PipelineSchedules::TakeOwnershipService.new(schedule, current_user).execute
+
+ if response.success?
redirect_to pipeline_schedules_path(@project)
else
redirect_to pipeline_schedules_path(@project), alert: _("Failed to change the owner")
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index db77127cb0a..10f58a9f479 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -5,7 +5,6 @@ class Projects::PipelinesController < Projects::ApplicationController
include RedisTracking
include ProductAnalyticsTracking
include ProjectStatsRefreshConflictsGuard
- include ZuoraCSP
urgency :low, [
:index, :new, :builds, :show, :failures, :create,
@@ -220,6 +219,8 @@ class Projects::PipelinesController < Projects::ApplicationController
def config_variables
respond_to do |format|
format.json do
+ # Even if the parameter name is `sha`, it is actually a ref name. We always send `ref` to the endpoint.
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/389065
result = Ci::ListConfigVariablesService.new(@project, current_user).execute(params[:sha])
result.nil? ? head(:no_content) : render(json: result)
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index cd9c6efb106..543ffa637e1 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -47,7 +47,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
def membershipable_members
- project.members
+ query_members_via_project_namespace_enabled? ? project.namespace_members : project.members
end
def plain_source_type
@@ -65,6 +65,18 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def root_params_key
:project_member
end
+
+ def members_and_requesters
+ query_members_via_project_namespace_enabled? ? project.namespace_members_and_requesters : super
+ end
+
+ def requesters
+ query_members_via_project_namespace_enabled? ? project.namespace_requesters : super
+ end
+
+ def query_members_via_project_namespace_enabled?
+ Feature.enabled?(:project_members_index_by_project_namespace, project)
+ end
end
Projects::ProjectMembersController.prepend_mod_with('Projects::ProjectMembersController')
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index 924de0ee7ea..895a9a00624 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -10,7 +10,7 @@ class Projects::RawController < Projects::ApplicationController
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:blob) }
- before_action :set_ref_and_path
+ before_action :assign_ref_vars
before_action :require_non_empty_project
before_action :authorize_read_code!
before_action :check_show_rate_limit!, only: [:show], unless: :external_storage_request?
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index 8ac6d872aae..4c2bd2a9d42 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -24,17 +24,9 @@ class Projects::RefsController < Projects::ApplicationController
when "blob"
project_blob_path(@project, @id)
when "graph"
- if Feature.enabled?(:use_ref_type_parameter, @project)
- project_network_path(@project, @id, ref_type: ref_type)
- else
- project_network_path(@project, @id, @options)
- end
+ project_network_path(@project, @id, ref_type: ref_type)
when "graphs"
- if Feature.enabled?(:use_ref_type_parameter, @project)
- project_graph_path(@project, @id, ref_type: ref_type)
- else
- project_graph_path(@project, @id)
- end
+ project_graph_path(@project, @id, ref_type: ref_type)
when "find_file"
project_find_file_path(@project, @id)
when "graphs_commits"
@@ -42,11 +34,7 @@ class Projects::RefsController < Projects::ApplicationController
when "badges"
project_settings_ci_cd_path(@project, ref: @id)
else
- if Feature.enabled?(:use_ref_type_parameter, @project)
- project_commits_path(@project, @id, ref_type: ref_type)
- else
- project_commits_path(@project, @id)
- end
+ project_commits_path(@project, @id, ref_type: ref_type)
end
redirect_to new_path
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index da414d068a6..7c569df7267 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -9,6 +9,10 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :authorize_create_release!, only: :new
before_action :validate_suffix_path, :fetch_latest_tag, only: :latest_permalink
+ prepend_before_action(only: [:downloads]) do
+ authenticate_sessionless_user!(:download)
+ end
+
feature_category :release_orchestration
urgency :low
diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb
index 33ce37ef4fb..1cd4c5b6137 100644
--- a/app/controllers/projects/repositories_controller.rb
+++ b/app/controllers/projects/repositories_controller.rb
@@ -47,8 +47,13 @@ class Projects::RepositoriesController < Projects::ApplicationController
end
def set_cache_headers
- expires_in cache_max_age(archive_metadata['CommitId']), public: Guest.can?(:download_code, project)
- fresh_when(etag: archive_metadata['ArchivePath'])
+ commit_id = archive_metadata['CommitId']
+
+ expires_in(cache_max_age(commit_id),
+ public: Guest.can?(:download_code, project), must_revalidate: true, stale_if_error: 5.minutes,
+ stale_while_revalidate: 1.minute, 's-maxage': 1.minute)
+
+ fresh_when(strong_etag: [commit_id, archive_metadata['ArchivePath']])
end
def archive_not_modified?
diff --git a/app/controllers/projects/service_ping_controller.rb b/app/controllers/projects/service_ping_controller.rb
index cfc322b47e7..8c16b6b230e 100644
--- a/app/controllers/projects/service_ping_controller.rb
+++ b/app/controllers/projects/service_ping_controller.rb
@@ -5,24 +5,6 @@ class Projects::ServicePingController < Projects::ApplicationController
feature_category :web_ide
- def web_ide_clientside_preview
- return render_404 unless Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?
-
- Gitlab::UsageDataCounters::WebIdeCounter.increment_previews_count
-
- head(:ok)
- end
-
- def web_ide_clientside_preview_success
- return render_404 unless Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?
-
- Gitlab::UsageDataCounters::WebIdeCounter.increment_previews_success_count
- Gitlab::UsageDataCounters::EditorUniqueCounter.track_live_preview_edit_action(author: current_user,
- project: project)
-
- head(:ok)
- end
-
def web_ide_pipelines_count
Gitlab::UsageDataCounters::WebIdeCounter.increment_pipelines_count
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index f8133c5836d..4ca665679c0 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -4,7 +4,6 @@ module Projects
module Settings
class CiCdController < Projects::ApplicationController
include RunnerSetupScripts
- include ZuoraCSP
NUMBER_OF_RUNNERS_PER_PAGE = 20
@@ -13,6 +12,10 @@ module Projects
before_action :check_builds_available!
before_action :define_variables
+ before_action do
+ push_frontend_feature_flag(:ci_inbound_job_token_scope, @project)
+ end
+
helper_method :highlight_badge
feature_category :continuous_integration
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index 6d099aa8b3d..74d730db026 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -88,25 +88,20 @@ module Projects
# rubocop: disable CodeReuse/ActiveRecord
def define_protected_refs
- @protected_branches = @project.protected_branches.order(:name).page(params[:page])
+ @protected_branches = fetch_protected_branches(@project)
@protected_tags = @project.protected_tags.order(:name).page(params[:page])
@protected_branch = @project.protected_branches.new
@protected_tag = @project.protected_tags.new
@protected_tags_count = @protected_tags.reduce(0) { |sum, tag| sum + tag.matching(@project.repository.tag_names).size }
-
- if Feature.enabled?(:group_protected_branches)
- @protected_group_branches = if @project.root_namespace.is_a?(Group)
- @project.root_namespace.protected_branches.order(:name).page(params[:page])
- else
- []
- end
- end
-
load_gon_index
end
# rubocop: enable CodeReuse/ActiveRecord
+ def fetch_protected_branches(project)
+ project.protected_branches.sorted_by_name.page(params[:page])
+ end
+
def remote_mirror
@remote_mirror = project.remote_mirrors.first_or_initialize
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index ee2c268ff33..71ad747b6b1 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -45,7 +45,6 @@ class ProjectsController < Projects::ApplicationController
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
- push_frontend_feature_flag(:package_registry_access_level)
end
layout :determine_layout
@@ -223,7 +222,22 @@ class ProjectsController < Projects::ApplicationController
end
def housekeeping
- ::Repositories::HousekeepingService.new(@project, :gc).execute
+ task = if params[:prune].present?
+ :prune
+ else
+ :eager
+ end
+
+ ::Repositories::HousekeepingService.new(@project, task).execute do
+ ::Gitlab::Audit::Auditor.audit(
+ name: 'manually_trigger_housekeeping',
+ author: current_user,
+ scope: @project,
+ target: @project,
+ message: "Housekeeping task: #{task}",
+ created_at: DateTime.current
+ )
+ end
redirect_to(
project_path(@project),
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 0800d635d92..ed0e019d02b 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -115,6 +115,7 @@ class RegistrationsController < Devise::RegistrationsController
def after_request_hook(user)
return unless user.persisted?
+ track_creation user: user
Gitlab::Tracking.event(self.class.name, 'successfully_submitted_form', user: user)
end
@@ -145,6 +146,11 @@ class RegistrationsController < Devise::RegistrationsController
users_sign_up_welcome_path(glm_tracking_params)
end
+ def track_creation(user:)
+ label = user_invited? ? 'invited' : 'signup'
+ Gitlab::Tracking.event(self.class.name, 'create_user', label: label, user: user)
+ end
+
def ensure_destroy_prerequisites_met
if current_user.solo_owned_groups.present?
redirect_to profile_account_path,
@@ -252,9 +258,15 @@ class RegistrationsController < Devise::RegistrationsController
end
end
- def after_pending_invitations_hook
- member_id = session.delete(:originating_member_id)
+ def user_invited?
+ !!member_id
+ end
+ def member_id
+ @member_id ||= session.delete(:originating_member_id)
+ end
+
+ def after_pending_invitations_hook
return unless member_id
# if invited multiple times to different projects, only the email clicked will be counted as accepted
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index 144ec4c0de9..bd3461d8331 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -116,7 +116,7 @@ module Repositories
end
def log_user_activity
- Users::ActivityService.new(user).execute
+ Users::ActivityService.new(author: user, project: project, namespace: project&.namespace).execute
end
end
end
diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb
index 97b6671a82a..71da9bdcbc4 100644
--- a/app/controllers/root_controller.rb
+++ b/app/controllers/root_controller.rb
@@ -41,8 +41,10 @@ class RootController < Dashboard::ProjectsController
when 'stars'
flash.keep
redirect_to(starred_dashboard_projects_path)
- when 'project_activity'
+ when 'your_activity'
redirect_to(activity_dashboard_path)
+ when 'project_activity'
+ redirect_to(activity_dashboard_path(filter: 'projects'))
when 'starred_project_activity'
redirect_to(activity_dashboard_path(filter: 'starred'))
when 'followed_user_activity'
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 38c773fa31d..1ca34dee3d6 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -24,6 +24,8 @@ class SearchController < ApplicationController
before_action :block_anonymous_global_searches, :check_scope_global_search_enabled, except: :opensearch
skip_before_action :authenticate_user!
+ skip_before_action :default_cache_headers, only: :count
+
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
search_term_present && !params[:project_id].present?
@@ -31,7 +33,7 @@ class SearchController < ApplicationController
before_action :check_search_rate_limit!, only: search_rate_limited_endpoints
before_action only: :show do
- push_frontend_feature_flag(:search_page_vertical_nav, current_user)
+ push_frontend_feature_flag(:search_blobs_language_aggregation, current_user)
end
before_action only: :show do
update_scope_for_code_search
@@ -65,6 +67,8 @@ class SearchController < ApplicationController
@search_highlight = @search_service_presenter.search_highlight
end
+ return if @search_results.respond_to?(:failed?) && @search_results.failed?
+
Gitlab::Metrics::GlobalSearchSlis.record_apdex(
elapsed: @global_search_duration_s,
search_type: @search_type,
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 699dcf1adac..b6aba04c877 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -289,7 +289,7 @@ class SessionsController < Devise::SessionsController
def log_user_activity(user)
login_counter.increment
- Users::ActivityService.new(user).execute
+ Users::ActivityService.new(author: user).execute
end
def load_recaptcha
diff --git a/app/controllers/users/unsubscribes_controller.rb b/app/controllers/users/unsubscribes_controller.rb
index 9ac07083cd5..73388b16006 100644
--- a/app/controllers/users/unsubscribes_controller.rb
+++ b/app/controllers/users/unsubscribes_controller.rb
@@ -4,7 +4,7 @@ module Users
class UnsubscribesController < ApplicationController
skip_before_action :authenticate_user!
- feature_category :users
+ feature_category :user_profile
def show
@user = get_user
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index f23e513e419..9546f71cd37 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -26,8 +26,11 @@ class UsersController < ApplicationController
before_action only: [:exists] do
check_rate_limit!(:username_exists, scope: request.ip)
end
+ before_action only: [:show] do
+ push_frontend_feature_flag(:profile_tabs_vue, current_user)
+ end
- feature_category :users, [:show, :activity, :groups, :projects, :contributed, :starred,
+ feature_category :user_profile, [:show, :activity, :groups, :projects, :contributed, :starred,
:followers, :following, :calendar, :calendar_activities,
:exists, :activity, :follow, :unfollow, :ssh_keys]
diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb
index 4decd7f1bee..03b9c49de96 100644
--- a/app/controllers/whats_new_controller.rb
+++ b/app/controllers/whats_new_controller.rb
@@ -8,7 +8,7 @@ class WhatsNewController < ApplicationController
before_action :check_whats_new_enabled
before_action :check_valid_page_param, :set_pagination_headers
- feature_category :navigation
+ feature_category :onboarding
urgency :low
def index