Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-19 17:16:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-19 17:16:28 +0300
commite4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch)
tree2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /app/controllers
parentffda4e7bcac36987f936b4ba515995a6698698f0 (diff)
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/application_settings/appearances_controller.rb2
-rw-r--r--app/controllers/admin/application_settings_controller.rb10
-rw-r--r--app/controllers/admin/runners_controller.rb19
-rw-r--r--app/controllers/admin/users_controller.rb7
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/clusters/clusters_controller.rb1
-rw-r--r--app/controllers/concerns/integrations/params.rb2
-rw-r--r--app/controllers/concerns/internal_redirect.rb2
-rw-r--r--app/controllers/concerns/issuable_actions.rb5
-rw-r--r--app/controllers/concerns/membership_actions.rb2
-rw-r--r--app/controllers/concerns/metrics_dashboard.rb126
-rw-r--r--app/controllers/concerns/observability/content_security_policy.rb21
-rw-r--r--app/controllers/concerns/onboarding/status.rb41
-rw-r--r--app/controllers/concerns/preview_markdown.rb4
-rw-r--r--app/controllers/concerns/redirects_for_missing_path_on_tree.rb4
-rw-r--r--app/controllers/concerns/requires_allowlisted_monitoring_client.rb (renamed from app/controllers/concerns/requires_whitelisted_monitoring_client.rb)16
-rw-r--r--app/controllers/concerns/uploads_actions.rb17
-rw-r--r--app/controllers/concerns/verifies_with_email.rb8
-rw-r--r--app/controllers/explore/projects_controller.rb9
-rw-r--r--app/controllers/graphql_controller.rb33
-rw-r--r--app/controllers/groups/milestones_controller.rb4
-rw-r--r--app/controllers/groups/runners_controller.rb20
-rw-r--r--app/controllers/groups/settings/ci_cd_controller.rb1
-rw-r--r--app/controllers/groups/uploads_controller.rb2
-rw-r--r--app/controllers/health_check_controller.rb2
-rw-r--r--app/controllers/health_controller.rb2
-rw-r--r--app/controllers/import/base_controller.rb2
-rw-r--r--app/controllers/import/bitbucket_server_controller.rb4
-rw-r--r--app/controllers/metrics_controller.rb2
-rw-r--r--app/controllers/oauth/authorizations_controller.rb2
-rw-r--r--app/controllers/organizations/application_controller.rb2
-rw-r--r--app/controllers/organizations/organizations_controller.rb4
-rw-r--r--app/controllers/profiles/accounts_controller.rb1
-rw-r--r--app/controllers/profiles/notifications_controller.rb2
-rw-r--r--app/controllers/projects/alerting/notifications_controller.rb2
-rw-r--r--app/controllers/projects/blob_controller.rb15
-rw-r--r--app/controllers/projects/environments_controller.rb10
-rw-r--r--app/controllers/projects/forks_controller.rb11
-rw-r--r--app/controllers/projects/grafana_api_controller.rb46
-rw-r--r--app/controllers/projects/incidents_controller.rb1
-rw-r--r--app/controllers/projects/issues_controller.rb4
-rw-r--r--app/controllers/projects/jobs_controller.rb6
-rw-r--r--app/controllers/projects/merge_requests/conflicts_controller.rb14
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb20
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb11
-rw-r--r--app/controllers/projects/merge_requests/drafts_controller.rb27
-rw-r--r--app/controllers/projects/merge_requests_controller.rb75
-rw-r--r--app/controllers/projects/milestones_controller.rb4
-rw-r--r--app/controllers/projects/ml/candidates_controller.rb10
-rw-r--r--app/controllers/projects/ml/experiments_controller.rb9
-rw-r--r--app/controllers/projects/ml/models_controller.rb20
-rw-r--r--app/controllers/projects/notes_controller.rb23
-rw-r--r--app/controllers/projects/pages_controller.rb10
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb25
-rw-r--r--app/controllers/projects/pipelines_controller.rb5
-rw-r--r--app/controllers/projects/runners_controller.rb16
-rw-r--r--app/controllers/projects/service_desk/custom_email_controller.rb84
-rw-r--r--app/controllers/projects/service_desk_controller.rb6
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb4
-rw-r--r--app/controllers/projects/tracing_controller.rb19
-rw-r--r--app/controllers/projects/tree_controller.rb35
-rw-r--r--app/controllers/projects/uploads_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb6
-rw-r--r--app/controllers/registrations/welcome_controller.rb53
-rw-r--r--app/controllers/registrations_controller.rb3
-rw-r--r--app/controllers/uploads_controller.rb2
-rw-r--r--app/controllers/users_controller.rb45
67 files changed, 566 insertions, 438 deletions
diff --git a/app/controllers/admin/application_settings/appearances_controller.rb b/app/controllers/admin/application_settings/appearances_controller.rb
index 719e8e4a913..1a1e85d48da 100644
--- a/app/controllers/admin/application_settings/appearances_controller.rb
+++ b/app/controllers/admin/application_settings/appearances_controller.rb
@@ -69,7 +69,7 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
@appearance = Appearance.current || Appearance.new
end
- # Only allow a trusted parameter "white list" through.
+ # Only allow a trusted parameter "allow list" through.
def appearance_params
params.require(:appearance).permit(allowed_appearance_params)
end
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index dff1c04311d..f0b6d86d48d 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -30,7 +30,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
feature_category :continuous_integration, [:ci_cd, :reset_registration_token]
urgency :low, [:ci_cd, :reset_registration_token]
feature_category :service_ping, [:usage_data, :service_usage_data]
- feature_category :integrations, [:integrations]
+ feature_category :integrations, [:integrations, :slack_app_manifest_share, :slack_app_manifest_download]
feature_category :pages, [:lets_encrypt_terms_of_service]
feature_category :error_tracking, [:reset_error_tracking_access_token]
@@ -114,6 +114,14 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url
end
+ def slack_app_manifest_share
+ redirect_to Slack::Manifest.share_url
+ end
+
+ def slack_app_manifest_download
+ send_data Slack::Manifest.to_json, type: :json, disposition: 'attachment', filename: 'slack_manifest.json'
+ end
+
private
def set_application_setting
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index f63616a2bea..b368ba6e495 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -3,32 +3,23 @@
class Admin::RunnersController < Admin::ApplicationController
include RunnerSetupScripts
- before_action :runner, except: [:index, :new, :tag_list, :runner_setup_scripts]
-
- before_action only: [:index] do
- push_frontend_feature_flag(:create_runner_workflow_for_admin, current_user)
- end
+ before_action :runner, only: [:show, :edit, :register, :update]
feature_category :runner
urgency :low
- def index
- end
+ def index; end
- def show
- end
+ def show; end
def edit
assign_projects
end
- def new
- render_404 unless Feature.enabled?(:create_runner_workflow_for_admin, current_user)
- end
+ def new; end
def register
- render_404 unless Feature.enabled?(:create_runner_workflow_for_admin, current_user) &&
- runner.registration_available?
+ render_404 unless runner.registration_available?
end
def update
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 3c96e49499f..b75ca2649c3 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -159,7 +159,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def unlock
- if update_user(&:unlock_access!)
+ if unlock_user
redirect_back_or_admin_user(notice: _("Successfully unlocked"))
else
redirect_back_or_admin_user(alert: _("Error occurred. User was not unlocked"))
@@ -401,6 +401,11 @@ class Admin::UsersController < Admin::ApplicationController
_("You cannot impersonate a user who cannot log in")
end
end
+
+ # method overriden in EE
+ def unlock_user
+ update_user(&:unlock_access!)
+ end
end
Admin::UsersController.prepend_mod_with('Admin::UsersController')
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 08e4f4956df..8588273a41f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -181,7 +181,7 @@ class ApplicationController < ActionController::Base
payload[:queue_duration_s] = request.env[::Gitlab::Middleware::RailsQueueDuration::GITLAB_RAILS_QUEUE_DURATION_KEY]
- payload[:response_bytes] = response.body_parts.sum(&:bytesize) if Feature.enabled?(:log_response_length)
+ payload[:response_bytes] = response.body_parts.sum(&:bytesize)
store_cloudflare_headers!(payload, request)
end
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index 2f6331a6822..b012a4e003e 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -2,7 +2,6 @@
class Clusters::ClustersController < Clusters::BaseController
include RoutableActions
- include MetricsDashboard
before_action :cluster, only: [:cluster_status, :show, :update, :destroy, :clear_cache]
before_action :user_cluster, only: [:connect]
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 19e458307a1..53dd06ce638 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -43,6 +43,8 @@ module Integrations
:external_wiki_url,
:google_iap_service_account_json,
:google_iap_audience_client_id,
+ :group_confidential_mention_events,
+ :group_mention_events,
:incident_events,
:inherit_from_id,
# We're using `issues_events` and `merge_requests_events`
diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb
index b803be67d2e..c3aa487c805 100644
--- a/app/controllers/concerns/internal_redirect.rb
+++ b/app/controllers/concerns/internal_redirect.rb
@@ -6,7 +6,7 @@ module InternalRedirect
def safe_redirect_path(path)
return unless path
# Verify that the string starts with a `/` and a known route character.
- return unless path =~ %r{\A/[-\w].*\z}
+ return unless %r{\A/[-\w].*\z}.match?(path)
uri = URI(path)
# Ignore anything path of the redirect except for the path, querystring and,
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 0ad8a08960a..a326fa308ad 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -12,6 +12,7 @@ module IssuableActions
before_action :authorize_destroy_issuable!, only: :destroy
before_action :check_destroy_confirmation!, only: :destroy
before_action :authorize_admin_issuable!, only: :bulk_update
+ before_action :set_application_context!, only: :show
end
def show
@@ -226,6 +227,10 @@ module IssuableActions
render_404 unless can?(current_user, :"update_#{resource_name}", issuable)
end
+ def set_application_context!
+ # no-op. The logic is defined in EE module.
+ end
+
def bulk_update_params
clean_bulk_update_params(
params.require(:update).permit(bulk_update_permitted_keys)
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 31675a58163..0c15c4d0d3f 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -16,7 +16,7 @@ module MembershipActions
member_data = if member.expires?
{
expires_soon: member.expires_soon?,
- expires_at_formatted: member.expires_at.to_time.in_time_zone.to_s(:medium)
+ expires_at_formatted: member.expires_at.to_time.in_time_zone.to_fs(:medium)
}
else
{}
diff --git a/app/controllers/concerns/metrics_dashboard.rb b/app/controllers/concerns/metrics_dashboard.rb
deleted file mode 100644
index 7a84c597424..00000000000
--- a/app/controllers/concerns/metrics_dashboard.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-# Provides an action which fetches a metrics dashboard according
-# to the parameters specified by the controller.
-module MetricsDashboard
- include RenderServiceResults
- include ChecksCollaboration
- include EnvironmentsHelper
-
- extend ActiveSupport::Concern
-
- def metrics_dashboard
- return not_found if Feature.enabled?(:remove_monitor_metrics)
-
- result = dashboard_finder.find(
- project_for_dashboard,
- current_user,
- decoded_params
- )
-
- if result
- result[:all_dashboards] = all_dashboards if include_all_dashboards?
- result[:metrics_data] = metrics_data(project_for_dashboard, environment_for_dashboard)
- end
-
- respond_to do |format|
- if result.nil?
- format.json { continue_polling_response }
- elsif result[:status] == :success
- format.json { render dashboard_success_response(result) }
- else
- format.json { render dashboard_error_response(result) }
- end
- end
- end
-
- private
-
- def all_dashboards
- dashboard_finder
- .find_all_paths(project_for_dashboard)
- .map { |dashboard| amend_dashboard(dashboard) }
- end
-
- def amend_dashboard(dashboard)
- project_dashboard = project_for_dashboard && !dashboard[:out_of_the_box_dashboard]
-
- dashboard[:can_edit] = project_dashboard ? can_edit?(dashboard) : false
- dashboard[:project_blob_path] = project_dashboard ? dashboard_project_blob_path(dashboard) : nil
- dashboard[:starred] = starred_dashboards.include?(dashboard[:path])
- dashboard[:user_starred_path] = project_for_dashboard ? user_starred_path(project_for_dashboard, dashboard[:path]) : nil
-
- dashboard
- end
-
- def user_starred_path(project, path)
- expose_path(api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: path }))
- end
-
- def dashboard_project_blob_path(dashboard)
- project_blob_path(project_for_dashboard, File.join(project_for_dashboard.default_branch, dashboard.fetch(:path, "")))
- end
-
- def can_edit?(dashboard)
- can_collaborate_with_project?(project_for_dashboard, ref: project_for_dashboard.default_branch)
- end
-
- # Override in class to provide arguments to the finder.
- def metrics_dashboard_params
- {}
- end
-
- # Override in class if response requires complete list of
- # dashboards in addition to requested dashboard body.
- def include_all_dashboards?
- false
- end
-
- def dashboard_finder
- ::Gitlab::Metrics::Dashboard::Finder
- end
-
- def starred_dashboards
- @starred_dashboards ||=
- if project_for_dashboard.present?
- ::Metrics::UsersStarredDashboardsFinder
- .new(user: current_user, project: project_for_dashboard)
- .execute
- .map(&:dashboard_path)
- .to_set
- else
- Set.new
- end
- end
-
- # Project is not defined for group and admin level clusters.
- def project_for_dashboard
- defined?(project) ? project : nil
- end
-
- def environment_for_dashboard
- defined?(environment) ? environment : nil
- end
-
- def dashboard_success_response(result)
- {
- status: :ok,
- json: result.slice(:all_dashboards, :dashboard, :status, :metrics_data)
- }
- end
-
- def dashboard_error_response(result)
- {
- status: result[:http_status] || :bad_request,
- json: result.slice(:all_dashboards, :message, :status)
- }
- end
-
- def decoded_params
- params = metrics_dashboard_params
-
- params[:dashboard_path] = CGI.unescape(params[:dashboard_path]) if params[:dashboard_path]
-
- params
- end
-end
diff --git a/app/controllers/concerns/observability/content_security_policy.rb b/app/controllers/concerns/observability/content_security_policy.rb
index 1e25dc492a0..e51d986d36c 100644
--- a/app/controllers/concerns/observability/content_security_policy.rb
+++ b/app/controllers/concerns/observability/content_security_policy.rb
@@ -5,26 +5,23 @@ module Observability
extend ActiveSupport::Concern
included do
- content_security_policy_with_context do |p|
- current_group = if defined?(group)
- group
- else
- defined?(project) ? project&.group : nil
- end
-
- next if p.directives.blank? || !Feature.enabled?(:observability_group_tab, current_group)
+ content_security_policy do |p|
+ next if p.directives.blank?
default_frame_src = p.directives['frame-src'] || p.directives['default-src']
-
- # When ObservabilityUI is not authenticated, it needs to be able
- # to redirect to the GL sign-in page, hence '/users/sign_in' and '/oauth/authorize'
+ # When Gitlab Observability Backend is not authenticated, it needs to be able
+ # to redirect to the GitLab sign-in page, hence '/users/sign_in' and '/oauth/authorize'
frame_src_values = Array.wrap(default_frame_src) | [
Gitlab::Observability.observability_url,
Gitlab::Utils.append_path(Gitlab.config.gitlab.url, '/users/sign_in'),
Gitlab::Utils.append_path(Gitlab.config.gitlab.url, '/oauth/authorize')
]
-
p.frame_src(*frame_src_values)
+
+ default_connect_src = p.directives['connect-src'] || p.directives['default-src']
+ connect_src_values =
+ Array.wrap(default_connect_src) | [Gitlab::Observability.observability_url]
+ p.connect_src(*connect_src_values)
end
end
end
diff --git a/app/controllers/concerns/onboarding/status.rb b/app/controllers/concerns/onboarding/status.rb
new file mode 100644
index 00000000000..986f3f17847
--- /dev/null
+++ b/app/controllers/concerns/onboarding/status.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Onboarding
+ class Status
+ def initialize(user)
+ @user = user
+ end
+
+ def continue_full_onboarding?
+ false
+ end
+
+ def single_invite?
+ # If there are more than one member it will mean we have been invited to multiple projects/groups and
+ # are not able to distinguish which one we should putting the user in after registration
+ members.count == 1
+ end
+
+ def last_invited_member
+ members.last
+ end
+
+ def last_invited_member_source
+ last_invited_member&.source
+ end
+
+ def invite_with_tasks_to_be_done?
+ return false if members.empty?
+
+ MemberTask.for_members(members).exists?
+ end
+
+ private
+
+ attr_reader :user
+
+ def members
+ @members ||= user.members
+ end
+ end
+end
diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb
index a7655efe7a9..7f1b961e92a 100644
--- a/app/controllers/concerns/preview_markdown.rb
+++ b/app/controllers/concerns/preview_markdown.rb
@@ -48,9 +48,7 @@ module PreviewMarkdown
end.merge(
requested_path: params[:path],
ref: params[:ref],
- # Disable comments in markdown for IE browsers because comments in IE
- # could allow script execution.
- allow_comments: !browser.ie?
+ allow_comments: false
)
end
diff --git a/app/controllers/concerns/redirects_for_missing_path_on_tree.rb b/app/controllers/concerns/redirects_for_missing_path_on_tree.rb
index 92574dfade9..97c23a2cf3c 100644
--- a/app/controllers/concerns/redirects_for_missing_path_on_tree.rb
+++ b/app/controllers/concerns/redirects_for_missing_path_on_tree.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module RedirectsForMissingPathOnTree
- def redirect_to_tree_root_for_missing_path(project, ref, path)
- redirect_to project_tree_path(project, ref), notice: missing_path_on_ref(path, ref)
+ def redirect_to_tree_root_for_missing_path(project, ref, path, ref_type: nil)
+ redirect_to project_tree_path(project, ref, ref_type: ref_type), notice: missing_path_on_ref(path, ref)
end
private
diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_allowlisted_monitoring_client.rb
index ef3d281589a..ad6d4dc548c 100644
--- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
+++ b/app/controllers/concerns/requires_allowlisted_monitoring_client.rb
@@ -1,28 +1,28 @@
# frozen_string_literal: true
-module RequiresWhitelistedMonitoringClient
+module RequiresAllowlistedMonitoringClient
extend ActiveSupport::Concern
included do
- before_action :validate_ip_whitelisted_or_valid_token!
+ before_action :validate_ip_allowlisted_or_valid_token!
end
private
- def validate_ip_whitelisted_or_valid_token!
- render_404 unless client_ip_whitelisted? || valid_token?
+ def validate_ip_allowlisted_or_valid_token!
+ render_404 unless client_ip_allowlisted? || valid_token?
end
- def client_ip_whitelisted?
+ def client_ip_allowlisted?
# Always allow developers to access http://localhost:3000/-/metrics for
# debugging purposes
return true if Rails.env.development? && request.local?
- ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.instance.client_ip) }
+ ip_allowlist.any? { |e| e.include?(Gitlab::RequestContext.instance.client_ip) }
end
- def ip_whitelist
- @ip_whitelist ||= Settings.monitoring.ip_whitelist.map { |ip| IPAddr.new(ip) }
+ def ip_allowlist
+ @ip_allowlist ||= Settings.monitoring.ip_whitelist.map { |ip| IPAddr.new(ip) }
end
def valid_token?
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index 222fcc17222..29b61264322 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -110,7 +110,7 @@ module UploadsActions
if uploader_mounted?
model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
else
- build_uploader_from_upload || build_uploader_from_params
+ build_uploader_from_upload
end
end
strong_memoize_attr :uploader
@@ -125,21 +125,6 @@ module UploadsActions
end
# rubocop: enable CodeReuse/ActiveRecord
- def build_uploader_from_params
- return unless uploader = build_uploader
-
- uploader.retrieve_from_store!(params[:filename])
-
- Gitlab::AppJsonLogger.info(
- message: 'Deprecated usage of build_uploader_from_params',
- uploader_class: uploader.class.name,
- path: params[:filename],
- exists: uploader.exists?
- )
-
- uploader
- end
-
def build_uploader
return unless params[:secret] && params[:filename]
diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb
index 45869c05f41..13378800ea9 100644
--- a/app/controllers/concerns/verifies_with_email.rb
+++ b/app/controllers/concerns/verifies_with_email.rb
@@ -25,6 +25,7 @@ module VerifiesWithEmail
if user.valid_password?(user_params[:password])
# The user has logged in successfully.
+
if user.unlock_token
# Prompt for the token if it already has been set
prompt_for_email_verification(user)
@@ -32,7 +33,8 @@ module VerifiesWithEmail
# require email verification if:
# - their account has been locked because of too many failed login attempts, or
# - they have logged in before, but never from the current ip address
- send_verification_instructions(user)
+ reason = 'sign in from untrusted IP address' unless user.access_locked?
+ send_verification_instructions(user, reason: reason)
prompt_for_email_verification(user)
end
end
@@ -75,13 +77,13 @@ module VerifiesWithEmail
super
end
- def send_verification_instructions(user)
+ def send_verification_instructions(user, reason: nil)
return if send_rate_limited?(user)
service = Users::EmailVerification::GenerateTokenService.new(attr: :unlock_token, user: user)
raw_token, encrypted_token = service.execute
user.unlock_token = encrypted_token
- user.lock_access!({ send_instructions: false })
+ user.lock_access!({ send_instructions: false, reason: reason })
send_verification_instructions_email(user, raw_token)
end
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index 577bd04d656..b3a1b510db9 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -10,6 +10,7 @@ class Explore::ProjectsController < Explore::ApplicationController
MIN_SEARCH_LENGTH = 3
PAGE_LIMIT = 50
+ RSS_ENTRIES_LIMIT = 20
before_action :set_non_archived_param
before_action :set_sorting
@@ -83,6 +84,14 @@ class Explore::ProjectsController < Explore::ApplicationController
params[:topic] = @topic.name
@projects = load_projects
+
+ respond_to do |format|
+ format.html
+ format.atom do
+ @projects = @projects.projects_order_id_desc.limit(RSS_ENTRIES_LIMIT)
+ render layout: 'xml'
+ end
+ end
end
private
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 3d3b7f31dfd..5c0c2b4adf2 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -14,6 +14,7 @@ class GraphqlController < ApplicationController
# The query string of a standard IntrospectionQuery, used to compare incoming requests for caching
CACHED_INTROSPECTION_QUERY_STRING = CachedIntrospectionQuery.query_string
+ INTROSPECTION_QUERY_OPERATION_NAME = 'IntrospectionQuery'
# If a user is using their session to access GraphQL, we need to have session
# storage, since the admin-mode check is session wide.
@@ -58,7 +59,7 @@ class GraphqlController < ApplicationController
urgency :low, [:execute]
def execute
- result = if Feature.enabled?(:cache_introspection_query) && params[:operationName] == 'IntrospectionQuery'
+ result = if Feature.enabled?(:cache_introspection_query) && introspection_query?
execute_introspection_query
else
multiplex? ? execute_multiplex : execute_query
@@ -276,9 +277,6 @@ class GraphqlController < ApplicationController
def execute_introspection_query
if introspection_query_can_use_cache?
- Gitlab::AppLogger.info(message: "IntrospectionQueryCache hit")
- log_introspection_query_cache_details(true)
-
# Context for caching: https://gitlab.com/gitlab-org/gitlab/-/issues/409448
Rails.cache.fetch(
introspection_query_cache_key,
@@ -286,17 +284,12 @@ class GraphqlController < ApplicationController
execute_query.to_json
end
else
- Gitlab::AppLogger.info(message: "IntrospectionQueryCache miss")
- log_introspection_query_cache_details(false)
-
execute_query
end
end
def introspection_query_can_use_cache?
- graphql_query = GraphQL::Query.new(GitlabSchema, query: query, variables: build_variables(params[:variables]))
-
- CACHED_INTROSPECTION_QUERY_STRING == graphql_query.query_string.squish
+ CACHED_INTROSPECTION_QUERY_STRING == graphql_query_object.query_string.squish
end
def introspection_query_cache_key
@@ -306,13 +299,17 @@ class GraphqlController < ApplicationController
['introspection-query-cache', Gitlab.revision, context[:remove_deprecated]]
end
- def log_introspection_query_cache_details(can_use_introspection_query_cache)
- Gitlab::AppLogger.info(
- message: "IntrospectionQueryCache",
- can_use_introspection_query_cache: can_use_introspection_query_cache.to_s,
- query: query,
- variables: build_variables(params[:variables]).to_s,
- introspection_query_cache_key: introspection_query_cache_key.to_s
- )
+ def introspection_query?
+ if params.key?(:operationName)
+ params[:operationName] == INTROSPECTION_QUERY_OPERATION_NAME
+ else
+ # If we don't provide operationName param, we infer it from the query
+ graphql_query_object.selected_operation_name == INTROSPECTION_QUERY_OPERATION_NAME
+ end
+ end
+
+ def graphql_query_object
+ @graphql_query_object ||= GraphQL::Query.new(GitlabSchema, query: query,
+ variables: build_variables(params[:variables]))
end
end
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 5f6b55ea928..cbed75019f2 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -9,6 +9,10 @@ class Groups::MilestonesController < Groups::ApplicationController
feature_category :team_planning
urgency :low
+ before_action do
+ push_frontend_feature_flag(:content_editor_on_issues, group)
+ end
+
def index
respond_to do |format|
format.html do
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index 4b52617d287..2dd0e36b65f 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -6,10 +6,6 @@ class Groups::RunnersController < Groups::ApplicationController
before_action :authorize_update_runner!, only: [:edit, :update, :destroy, :pause, :resume]
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show, :register]
- before_action only: [:index] do
- push_frontend_feature_flag(:create_runner_workflow_for_namespace, group)
- end
-
feature_category :runner
urgency :low
@@ -20,11 +16,9 @@ class Groups::RunnersController < Groups::ApplicationController
Gitlab::Tracking.event(self.class.name, 'index', user: current_user, namespace: @group)
end
- def show
- end
+ def show; end
- def edit
- end
+ def edit; end
def update
if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
@@ -34,12 +28,10 @@ class Groups::RunnersController < Groups::ApplicationController
end
end
- def new
- render_404 unless create_runner_workflow_for_namespace_enabled?
- end
+ def new; end
def register
- render_404 unless create_runner_workflow_for_namespace_enabled? && runner.registration_available?
+ render_404 unless runner.registration_available?
end
private
@@ -67,10 +59,6 @@ class Groups::RunnersController < Groups::ApplicationController
render_404
end
-
- def create_runner_workflow_for_namespace_enabled?
- Feature.enabled?(:create_runner_workflow_for_namespace, group)
- end
end
Groups::RunnersController.prepend_mod
diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb
index 4bbaf92b126..169caabf9d8 100644
--- a/app/controllers/groups/settings/ci_cd_controller.rb
+++ b/app/controllers/groups/settings/ci_cd_controller.rb
@@ -14,6 +14,7 @@ module Groups
feature_category :continuous_integration
before_action do
+ push_frontend_feature_flag(:ci_group_env_scope_graphql, group)
push_frontend_feature_flag(:ci_variables_pages, current_user)
end
diff --git a/app/controllers/groups/uploads_controller.rb b/app/controllers/groups/uploads_controller.rb
index cd1ebc39411..d29532f9d6f 100644
--- a/app/controllers/groups/uploads_controller.rb
+++ b/app/controllers/groups/uploads_controller.rb
@@ -9,7 +9,7 @@ class Groups::UploadsController < Groups::ApplicationController
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
- feature_category :groups_and_projects
+ feature_category :portfolio_management
urgency :low, [:show]
private
diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb
index a2abed7ba4e..a85629985ba 100644
--- a/app/controllers/health_check_controller.rb
+++ b/app/controllers/health_check_controller.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class HealthCheckController < HealthCheck::HealthCheckController
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
end
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index 5fac7c0d663..1381999ab4c 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -3,7 +3,7 @@
# rubocop:disable Rails/ApplicationController
class HealthController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
CHECKS = [
Gitlab::HealthChecks::MasterCheck
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index bcb6aed9e38..f3a0ce64839 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -82,7 +82,7 @@ class Import::BaseController < ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def find_already_added_projects(import_type)
- current_user.created_projects.where(import_type: import_type).with_import_state
+ current_user.created_projects.inc_routes.where(import_type: import_type).with_import_state
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/import/bitbucket_server_controller.rb b/app/controllers/import/bitbucket_server_controller.rb
index 40664922d3d..e17cd00d053 100644
--- a/app/controllers/import/bitbucket_server_controller.rb
+++ b/app/controllers/import/bitbucket_server_controller.rb
@@ -103,8 +103,8 @@ class Import::BitbucketServerController < Import::BaseController
return render_validation_error('Missing project key') unless @project_key.present? && @repo_slug.present?
return render_validation_error('Missing repository slug') unless @repo_slug.present?
- return render_validation_error('Invalid project key') unless @project_key =~ VALID_BITBUCKET_PROJECT_CHARS
- return render_validation_error('Invalid repository slug') unless @repo_slug =~ VALID_BITBUCKET_CHARS
+ return render_validation_error('Invalid project key') unless VALID_BITBUCKET_PROJECT_CHARS.match?(@project_key)
+ return render_validation_error('Invalid repository slug') unless VALID_BITBUCKET_CHARS.match?(@repo_slug)
end
def render_validation_error(message)
diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb
index 3dfa8d7b11e..9f41c092fa0 100644
--- a/app/controllers/metrics_controller.rb
+++ b/app/controllers/metrics_controller.rb
@@ -2,7 +2,7 @@
# rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
protect_from_forgery with: :exception, prepend: true
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
index 96a3fab7e1a..a1d4df6ff48 100644
--- a/app/controllers/oauth/authorizations_controller.rb
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
+ include Gitlab::GonHelper
include InitializesCurrentUserMode
include Gitlab::Utils::StrongMemoize
+ before_action :add_gon_variables
before_action :verify_confirmed_email!, :verify_admin_allowed!
layout 'profile'
diff --git a/app/controllers/organizations/application_controller.rb b/app/controllers/organizations/application_controller.rb
index 5f5a57d176b..43cc7014f62 100644
--- a/app/controllers/organizations/application_controller.rb
+++ b/app/controllers/organizations/application_controller.rb
@@ -4,6 +4,8 @@ module Organizations
class ApplicationController < ::ApplicationController
before_action :organization
+ layout 'organization'
+
private
def organization
diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb
index 0eb5c3aa6fd..4781ef995b7 100644
--- a/app/controllers/organizations/organizations_controller.rb
+++ b/app/controllers/organizations/organizations_controller.rb
@@ -6,6 +6,8 @@ module Organizations
before_action { authorize_action!(:admin_organization) }
- def directory; end
+ def show; end
+
+ def groups_and_projects; end
end
end
diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb
index eb64016379d..f618eafea38 100644
--- a/app/controllers/profiles/accounts_controller.rb
+++ b/app/controllers/profiles/accounts_controller.rb
@@ -7,6 +7,7 @@ class Profiles::AccountsController < Profiles::ApplicationController
urgency :low, [:show]
def show
+ push_frontend_feature_flag(:delay_delete_own_user)
render(locals: show_view_variables)
end
diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb
index b663a75f04a..1477f8e0aac 100644
--- a/app/controllers/profiles/notifications_controller.rb
+++ b/app/controllers/profiles/notifications_controller.rb
@@ -45,7 +45,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
projects = project_notifications.map(&:source)
ActiveRecord::Associations::Preloader.new(
records: projects,
- associations: { namespace: [:route, :owner], group: [] }
+ associations: { namespace: [:route, :owner], group: [], creator: [] }
).call
Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute
diff --git a/app/controllers/projects/alerting/notifications_controller.rb b/app/controllers/projects/alerting/notifications_controller.rb
index 89e8a261288..281ac14d3ce 100644
--- a/app/controllers/projects/alerting/notifications_controller.rb
+++ b/app/controllers/projects/alerting/notifications_controller.rb
@@ -72,7 +72,7 @@ module Projects
end
def endpoint_identifier
- params[:endpoint_identifier] || AlertManagement::HttpIntegration::LEGACY_IDENTIFIER
+ params[:endpoint_identifier] || AlertManagement::HttpIntegration::LEGACY_IDENTIFIERS
end
def notification_payload
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 28393e1f365..b41e4d11d24 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -49,6 +49,7 @@ class Projects::BlobController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
@@ -160,6 +161,8 @@ class Projects::BlobController < Projects::ApplicationController
end
def check_for_ambiguous_ref
+ return if Feature.enabled?(:redirect_with_ref_type, @project)
+
@ref_type = ref_type
if @ref_type == ExtractsRef::BRANCH_REF_TYPE && ambiguous_ref?(@project, @ref)
@@ -169,7 +172,17 @@ class Projects::BlobController < Projects::ApplicationController
end
def commit
- @commit ||= @repository.commit(@ref)
+ if Feature.enabled?(:redirect_with_ref_type, @project)
+ response = ::ExtractsRef::RequestedRef.new(@repository, ref_type: ref_type, ref: @ref).find
+ @commit = response[:commit]
+ @ref_type = response[:ref_type]
+
+ if response[:ambiguous]
+ return redirect_to(project_blob_path(@project, File.join(@ref_type ? @ref : @commit.id, @path), ref_type: @ref_type))
+ end
+ else
+ @commit ||= @repository.commit(@ref)
+ end
return render_404 unless @commit
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 10d0d03e56d..4cc1ed092d2 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -12,12 +12,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
push_frontend_feature_flag(:environment_details_vue, @project)
end
- before_action only: [:index] do
- push_frontend_feature_flag(:kas_user_access_project, @project)
- end
-
- before_action only: [:edit, :new] do
- push_frontend_feature_flag(:environment_settings_to_graphql, @project)
+ before_action only: [:index, :edit, :new] do
+ push_frontend_feature_flag(:kubernetes_namespace_for_environment)
end
before_action :authorize_read_environment!
@@ -28,7 +24,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action :environment, only: [:show, :edit, :update, :stop, :terminal, :terminal_websocket_authorize, :cancel_auto_stop]
before_action :verify_api_request!, only: :terminal_websocket_authorize
before_action :expire_etag_cache, only: [:index], unless: -> { request.format.json? }
- before_action :set_kas_cookie, only: [:index], if: -> { current_user && request.format.html? }
+ before_action :set_kas_cookie, only: [:index, :edit, :new], if: -> { current_user && request.format.html? }
after_action :expire_etag_cache, only: [:cancel_auto_stop]
track_event :index, :folder, :show, :new, :edit, :create, :update, :stop, :cancel_auto_stop, :terminal,
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index ff3dc71b6cc..de2040afff3 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -65,9 +65,8 @@ class Projects::ForksController < Projects::ApplicationController
end
end
- # rubocop: disable CodeReuse/ActiveRecord
def create
- @forked_project = fork_namespace.projects.find_by(path: project.path)
+ @forked_project = fork_namespace.projects.find_by(path: project.path) # rubocop: disable CodeReuse/ActiveRecord
@forked_project = nil unless @forked_project && @forked_project.forked_from_project == project
@forked_project ||= fork_service.execute
@@ -96,7 +95,9 @@ class Projects::ForksController < Projects::ApplicationController
current_user: current_user
).execute
+ # rubocop: disable CodeReuse/ActiveRecord
forks.includes(:route, :creator, :group, :topics, namespace: [:route, :owner])
+ # rubocop: enable CodeReuse/ActiveRecord
end
def fork_service
@@ -130,15 +131,21 @@ class Projects::ForksController < Projects::ApplicationController
end
def load_namespaces_with_associations
+ # rubocop: disable CodeReuse/ActiveRecord
@load_namespaces_with_associations ||= fork_service.valid_fork_targets(only_groups: true).preload(:route)
+ # rubocop: enable CodeReuse/ActiveRecord
end
def memberships_hash
+ # rubocop: disable CodeReuse/ActiveRecord
current_user.members.where(source: load_namespaces_with_associations).index_by(&:source_id)
+ # rubocop: enable CodeReuse/ActiveRecord
end
def forked_projects_by_namespace(namespaces)
+ # rubocop: disable CodeReuse/ActiveRecord
project.forks.where(namespace: namespaces).includes(:namespace).index_by(&:namespace_id)
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/controllers/projects/grafana_api_controller.rb b/app/controllers/projects/grafana_api_controller.rb
deleted file mode 100644
index 2cc6c6c35ba..00000000000
--- a/app/controllers/projects/grafana_api_controller.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-class Projects::GrafanaApiController < Projects::ApplicationController
- include RenderServiceResults
- include MetricsDashboard
-
- before_action :authorize_read_grafana!, only: :proxy
-
- feature_category :metrics
- urgency :low
-
- def proxy
- return not_found if Feature.enabled?(:remove_monitor_metrics)
-
- result = ::Grafana::ProxyService.new(
- project,
- params[:datasource_id],
- params[:proxy_path],
- prometheus_params
- ).execute
-
- return continue_polling_response if result.nil?
- return error_response(result) if result[:status] == :error
-
- success_response(result)
- end
-
- private
-
- def metrics_dashboard_params
- params.permit(:embedded, :grafana_url)
- end
-
- def query_params
- params.permit(:query, :start_time, :end_time, :step)
- end
-
- def prometheus_params
- query_params.to_h
- .except(:start_time, :end_time)
- .merge(
- start: query_params[:start_time],
- end: query_params[:end_time]
- )
- end
-end
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 7121096bd77..6109e29b169 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -11,6 +11,7 @@ class Projects::IncidentsController < Projects::ApplicationController
push_force_frontend_feature_flag(:work_items_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(:moved_mr_sidebar, project)
+ push_frontend_feature_flag(:move_close_into_dropdown, project)
end
feature_category :incident_management
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 6311907a859..6a45595580f 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -51,13 +51,14 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:service_desk_new_note_email_native_attachments, project)
push_frontend_feature_flag(:saved_replies, current_user)
push_frontend_feature_flag(:issues_grid_view)
+ push_frontend_feature_flag(:service_desk_ticket)
end
before_action only: [:index, :show] do
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
end
- before_action only: :index do
+ before_action only: [:index, :service_desk] do
push_frontend_feature_flag(:or_issuable_queries, project)
push_frontend_feature_flag(:frontend_caching, project&.group)
end
@@ -69,6 +70,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(:moved_mr_sidebar, project)
+ push_frontend_feature_flag(:move_close_into_dropdown, project)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 79ddcbf732d..4e0b304a2ee 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -21,7 +21,7 @@ class Projects::JobsController < Projects::ApplicationController
before_action :verify_proxy_request!, only: :proxy_websocket_authorize
before_action :push_job_log_jump_to_failures, only: [:show]
before_action :reject_if_build_artifacts_size_refreshing!, only: [:erase]
-
+ before_action :push_ai_build_failure_cause, only: [:show]
layout 'project'
feature_category :continuous_integration
@@ -258,4 +258,8 @@ class Projects::JobsController < Projects::ApplicationController
def push_job_log_jump_to_failures
push_frontend_feature_flag(:job_log_jump_to_failures, @project)
end
+
+ def push_ai_build_failure_cause
+ push_frontend_feature_flag(:ai_build_failure_cause, @project)
+ end
end
diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb
index 76a233afa13..66a358963e2 100644
--- a/app/controllers/projects/merge_requests/conflicts_controller.rb
+++ b/app/controllers/projects/merge_requests/conflicts_controller.rb
@@ -15,7 +15,8 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
respond_to do |format|
format.html do
@issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
- Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_loading_conflict_ui_action(user: current_user)
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
+ .track_loading_conflict_ui_action(user: current_user)
end
format.json do
@@ -23,12 +24,14 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
render json: @conflicts_list
elsif @merge_request.can_be_merged?
render json: {
- message: _('The merge conflicts for this merge request have already been resolved. Please return to the merge request.'),
+ message: _('The merge conflicts for this merge request have already been resolved. ' \
+ 'Please return to the merge request.'),
type: 'error'
}
else
render json: {
- message: _('The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally.'),
+ message: _('The merge conflicts for this merge request cannot be resolved through GitLab. ' \
+ 'Please try to resolve them locally.'),
type: 'error'
}
end
@@ -52,7 +55,8 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_resolve_conflict_action(user: current_user)
if @merge_request.can_be_merged?
- render status: :bad_request, json: { message: _('The merge conflicts for this merge request have already been resolved.') }
+ render status: :bad_request,
+ json: { message: _('The merge conflicts for this merge request have already been resolved.') }
return
end
@@ -71,6 +75,8 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
private
+ alias_method :issuable, :merge_request
+
def authorize_can_resolve_conflicts!
@conflicts_list = ::MergeRequests::Conflicts::ListService.new(@merge_request)
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 06381315614..6a3523b82d9 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -11,6 +11,12 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
before_action :build_merge_request, except: [:create]
+ before_action only: [:new] do
+ if can?(current_user, :fill_in_merge_request_template, project)
+ push_frontend_feature_flag(:fill_in_mr_template, project)
+ end
+ end
+
urgency :low, [
:new,
:create,
@@ -25,7 +31,9 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
end
def create
- @merge_request = ::MergeRequests::CreateService.new(project: project, current_user: current_user, params: merge_request_params).execute
+ @merge_request = ::MergeRequests::CreateService
+ .new(project: project, current_user: current_user, params: merge_request_params)
+ .execute
if @merge_request.valid?
incr_count_webide_merge_request
@@ -82,7 +90,10 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
def branch_to
@target_project = selected_target_project
- if @target_project && params[:ref].present? && Ability.allowed?(current_user, :create_merge_request_in, @target_project)
+ if @target_project &&
+ params[:ref].present? &&
+ Ability.allowed?(current_user, :create_merge_request_in, @target_project)
+
@ref = params[:ref]
@commit = @target_project.commit(Gitlab::Git::BRANCH_REF_PREFIX + @ref)
end
@@ -104,10 +115,13 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
def build_merge_request
params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
+ new_params = merge_request_params.merge(diff_options: diff_options)
# Gitaly N+1 issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/58096
Gitlab::GitalyClient.allow_n_plus_1_calls do
- @merge_request = ::MergeRequests::BuildService.new(project: project, current_user: current_user, params: merge_request_params.merge(diff_options: diff_options)).execute
+ @merge_request = ::MergeRequests::BuildService
+ .new(project: project, current_user: current_user, params: new_params)
+ .execute
end
end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index f3a01fd3223..5bd0063ab95 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -49,7 +49,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
pagination_data: diffs.pagination_data
}
- # NOTE: Any variables that would affect the resulting json needs to be added to the cache_context to avoid stale cache issues.
+ # NOTE: Any variables that would affect the resulting json needs to be added to the cache_context
+ # to avoid stale cache issues.
cache_context = [
current_user&.cache_key,
unfoldable_positions.map(&:to_h),
@@ -130,7 +131,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
# rubocop: disable CodeReuse/ActiveRecord
def commit
return unless commit_id = params[:commit_id].presence
- return unless @merge_request.all_commits.exists?(sha: commit_id) || @merge_request.recent_context_commits.map(&:id).include?(commit_id)
+ return unless @merge_request.all_commits.exists?(sha: commit_id) ||
+ @merge_request.recent_context_commits.map(&:id).include?(commit_id)
@commit ||= @project.commit(commit_id)
end
@@ -160,7 +162,10 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
end
end
- return @merge_request.context_commits_diff if show_only_context_commits? && !@merge_request.context_commits_diff.empty?
+ if show_only_context_commits? && !@merge_request.context_commits_diff.empty?
+ return @merge_request.context_commits_diff
+ end
+
return @merge_request.merge_head_diff if render_merge_ref_head_diff?
if @start_sha
diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb
index ca6ab83b877..74c495261a3 100644
--- a/app/controllers/projects/merge_requests/drafts_controller.rb
+++ b/app/controllers/projects/merge_requests/drafts_controller.rb
@@ -27,17 +27,23 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
draft_note = create_service.execute
+ if draft_note.errors.present?
+ render json: { errors: draft_note.errors.full_messages.to_sentence }, status: :unprocessable_entity
+ return
+ end
+
prepare_notes_for_rendering(draft_note)
render json: DraftNoteSerializer.new(current_user: current_user).represent(draft_note)
end
def update
- draft_note.update!(draft_note_params)
-
- prepare_notes_for_rendering(draft_note)
-
- render json: DraftNoteSerializer.new(current_user: current_user).represent(draft_note)
+ if draft_note.update(draft_note_params)
+ prepare_notes_for_rendering(draft_note)
+ render json: DraftNoteSerializer.new(current_user: current_user).represent(draft_note)
+ else
+ render json: { errors: draft_note.errors.full_messages.to_sentence }, status: :unprocessable_entity
+ end
end
def destroy
@@ -57,10 +63,13 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
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)
+ 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
+ return render json: { message: _('An error occurred while approving, please try again.') },
+ status: :internal_server_error
end
end
@@ -101,7 +110,9 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli
# rubocop: disable CodeReuse/ActiveRecord
def merge_request
- @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).find_by!(iid: params[:merge_request_id])
+ @merge_request ||= MergeRequestsFinder
+ .new(current_user, project_id: @project.id)
+ .find_by!(iid: params[:merge_request_id])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 60f619a8d20..2172c91fc76 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -41,19 +41,23 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_force_frontend_feature_flag(:content_editor_on_issues, project&.content_editor_on_issues_feature_flag_enabled?)
push_frontend_feature_flag(:core_security_mr_widget_counts, project)
push_frontend_feature_flag(:issue_assignees_widget, @project)
- push_frontend_feature_flag(:deprecate_vulnerabilities_feedback, @project)
push_frontend_feature_flag(:moved_mr_sidebar, project)
+ push_frontend_feature_flag(:sast_reports_in_inline_diff, project)
push_frontend_feature_flag(:mr_experience_survey, project)
push_frontend_feature_flag(:saved_replies, current_user)
push_frontend_feature_flag(:code_quality_inline_drawer, project)
- push_frontend_feature_flag(:auto_merge_labels_mr_widget, project)
push_force_frontend_feature_flag(:summarize_my_code_review, summarize_my_code_review_enabled?)
push_frontend_feature_flag(:mr_activity_filters, current_user)
push_frontend_feature_flag(:review_apps_redeploy_mr_widget, project)
- push_frontend_feature_flag(:comment_on_files, current_user)
push_frontend_feature_flag(:ci_job_failures_in_mr, project)
end
+ before_action only: [:edit] do
+ if can?(current_user, :fill_in_merge_request_template, project)
+ push_frontend_feature_flag(:fill_in_mr_template, project)
+ end
+ end
+
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :diffs, :discussions]
after_action :log_merge_request_show, only: [:show, :diffs]
@@ -124,16 +128,31 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@merge_request.recent_context_commits
)
- per_page = [(params[:per_page] || MergeRequestDiff::COMMITS_SAFE_SIZE).to_i, MergeRequestDiff::COMMITS_SAFE_SIZE].min
- recent_commits = @merge_request.recent_commits(load_from_gitaly: true, limit: per_page, page: params[:page]).with_latest_pipeline(@merge_request.source_branch).with_markdown_cache
+ per_page = [
+ (params[:per_page] || MergeRequestDiff::COMMITS_SAFE_SIZE).to_i,
+ MergeRequestDiff::COMMITS_SAFE_SIZE
+ ].min
+ recent_commits = @merge_request
+ .recent_commits(load_from_gitaly: true, limit: per_page, page: params[:page])
+ .with_latest_pipeline(@merge_request.source_branch)
+ .with_markdown_cache
@next_page = recent_commits.next_page
@commits = set_commits_for_rendering(
recent_commits,
commits_count: @merge_request.commits_count
)
- commits_count = @merge_request.preparing? ? '-' : @merge_request.commits_count + @merge_request.context_commits_count
- render json: { html: view_to_html_string('projects/merge_requests/_commits'), next_page: @next_page, count: commits_count }
+ commits_count = if @merge_request.preparing?
+ '-'
+ else
+ @merge_request.commits_count + @merge_request.context_commits_count
+ end
+
+ render json: {
+ html: view_to_html_string('projects/merge_requests/_commits'),
+ next_page: @next_page,
+ count: commits_count
+ }
end
def pipelines
@@ -221,7 +240,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def update
- @merge_request = ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: merge_request_update_params).execute(@merge_request)
+ @merge_request = ::MergeRequests::UpdateService
+ .new(project: project, current_user: current_user, params: merge_request_update_params)
+ .execute(@merge_request)
respond_to do |format|
format.html do
@@ -287,7 +308,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def assign_related_issues
- result = ::MergeRequests::AssignIssuesService.new(project: project, current_user: current_user, params: { merge_request: @merge_request }).execute
+ result = ::MergeRequests::AssignIssuesService
+ .new(project: project, current_user: current_user, params: { merge_request: @merge_request })
+ .execute
case result[:count]
when 0
@@ -317,7 +340,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def rebase
- @merge_request.rebase_async(current_user.id, skip_ci: Gitlab::Utils.to_boolean(merge_params[:skip_ci], default: false))
+ @merge_request
+ .rebase_async(current_user.id, skip_ci: Gitlab::Utils.to_boolean(merge_params[:skip_ci], default: false))
head :ok
rescue MergeRequest::RebaseLockTimeout => e
@@ -334,7 +358,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
IssuableExportCsvWorker.perform_async(:merge_request, current_user.id, project.id, finder_options.to_h) # rubocop:disable CodeReuse/Worker
index_path = project_merge_requests_path(project)
- message = _('Your CSV export has started. It will be emailed to %{email} when complete.') % { email: current_user.notification_email_or_default }
+ message = _('Your CSV export has started. It will be emailed to %{email} when complete.') %
+ { email: current_user.notification_email_or_default }
redirect_to(index_path, notice: message)
end
@@ -432,10 +457,15 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@commits_count = @merge_request.commits_count + @merge_request.context_commits_count
@diffs_count = get_diffs_count
@issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
- @current_user_data = Gitlab::Json.dump(UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity))
+ @current_user_data = Gitlab::Json
+ .dump(UserSerializer.new(project: @project)
+ .represent(current_user, {}, MergeRequestCurrentUserEntity))
@show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
@file_by_file_default = current_user&.view_diffs_file_by_file
- @coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json) if @merge_request.has_coverage_reports?
+ if @merge_request.has_coverage_reports?
+ @coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json)
+ end
+
@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)
@@ -478,12 +508,18 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def merge!
# Disable the CI check if auto_merge_strategy is specified since we have
# to wait until CI completes to know
- unless @merge_request.mergeable?(skip_ci_check: auto_merge_requested?)
+ skipped_checks = @merge_request.skipped_mergeable_checks(
+ auto_merge_requested: auto_merge_requested?,
+ auto_merge_strategy: params[:auto_merge_strategy]
+ )
+
+ unless @merge_request.mergeable?(**skipped_checks)
return :failed
end
squashing = params.fetch(:squash, false)
- merge_service = ::MergeRequests::MergeService.new(project: @project, current_user: current_user, params: merge_params)
+ merge_service = ::MergeRequests::MergeService
+ .new(project: @project, current_user: current_user, params: merge_params)
unless merge_service.hooks_validation_pass?(@merge_request, validate_squash_message: squashing)
return :hook_validation_error
@@ -500,7 +536,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
AutoMergeService.new(project, current_user, merge_params).update(merge_request)
else
AutoMergeService.new(project, current_user, merge_params)
- .execute(merge_request, params[:auto_merge_strategy] || AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+ .execute(
+ merge_request,
+ params[:auto_merge_strategy] || AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS
+ )
end
else
@merge_request.merge_async(current_user.id, merge_params)
@@ -595,7 +634,9 @@ 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 = 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)
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 35b65dbce7e..1f4e5b54500 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -24,6 +24,10 @@ class Projects::MilestonesController < Projects::ApplicationController
feature_category :team_planning
urgency :low
+ before_action do
+ push_frontend_feature_flag(:content_editor_on_issues, @project)
+ end
+
def index
@sort = params[:sort] || 'due_date_asc'
@milestones = milestones.sort_by_attribute(@sort)
diff --git a/app/controllers/projects/ml/candidates_controller.rb b/app/controllers/projects/ml/candidates_controller.rb
index ed7155fc5f4..9905e454acb 100644
--- a/app/controllers/projects/ml/candidates_controller.rb
+++ b/app/controllers/projects/ml/candidates_controller.rb
@@ -3,7 +3,9 @@
module Projects
module Ml
class CandidatesController < ApplicationController
- before_action :check_feature_enabled, :set_candidate
+ before_action :set_candidate
+ before_action :check_read, only: [:show]
+ before_action :check_write, only: [:destroy]
feature_category :mlops
@@ -26,9 +28,13 @@ module Projects
render_404 unless @candidate.present?
end
- def check_feature_enabled
+ def check_read
render_404 unless can?(current_user, :read_model_experiments, @project)
end
+
+ def check_write
+ render_404 unless can?(current_user, :write_model_experiments, @project)
+ end
end
end
end
diff --git a/app/controllers/projects/ml/experiments_controller.rb b/app/controllers/projects/ml/experiments_controller.rb
index a620e9919e7..85e7f63779c 100644
--- a/app/controllers/projects/ml/experiments_controller.rb
+++ b/app/controllers/projects/ml/experiments_controller.rb
@@ -5,7 +5,8 @@ module Projects
class ExperimentsController < ::Projects::ApplicationController
include Projects::Ml::ExperimentsHelper
- before_action :check_feature_enabled
+ before_action :check_read, only: [:show, :index]
+ before_action :check_write, only: [:destroy]
before_action :set_experiment, only: [:show, :destroy]
feature_category :mlops
@@ -55,10 +56,14 @@ module Projects
private
- def check_feature_enabled
+ def check_read
render_404 unless can?(current_user, :read_model_experiments, @project)
end
+ def check_write
+ render_404 unless can?(current_user, :write_model_experiments, @project)
+ end
+
def set_experiment
@experiment = ::Ml::Experiment.by_project_id_and_iid(@project.id, params[:iid])
diff --git a/app/controllers/projects/ml/models_controller.rb b/app/controllers/projects/ml/models_controller.rb
new file mode 100644
index 00000000000..77855b73cbd
--- /dev/null
+++ b/app/controllers/projects/ml/models_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Projects
+ module Ml
+ class ModelsController < ::Projects::ApplicationController
+ before_action :check_feature_enabled
+ feature_category :mlops
+
+ def index
+ @models = ::Projects::Ml::ModelFinder.new(@project).execute
+ end
+
+ private
+
+ def check_feature_enabled
+ render_404 unless can?(current_user, :read_model_registry, @project)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 054e8c302c9..7fcdf220bd2 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class Projects::NotesController < Projects::ApplicationController
+ extend Gitlab::Utils::Override
include RendersNotes
include NotesActions
include NotesHelper
@@ -11,10 +12,30 @@ class Projects::NotesController < Projects::ApplicationController
before_action :authorize_create_note!, only: [:create]
before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
- feature_category :team_planning
+ feature_category :team_planning, [:index, :create, :update, :destroy, :delete_attachment, :toggle_award_emoji]
+ feature_category :code_review_workflow, [:resolve, :unresolve, :outdated_line_change]
urgency :medium, [:index]
urgency :low, [:create, :update, :destroy, :resolve, :unresolve, :toggle_award_emoji, :outdated_line_change]
+ override :feature_category
+ def feature_category
+ if %w[index create].include?(params[:action])
+ category = feature_category_override_for_target_type(params[:target_type])
+ return category if category
+ end
+
+ super
+ end
+
+ def feature_category_override_for_target_type(target_type)
+ case target_type
+ when 'merge_request'
+ 'code_review_workflow'
+ when 'commit', 'project_snippet'
+ 'source_code_management'
+ end
+ end
+
def delete_attachment
note.remove_attachment!
note.update_attribute(:attachment, nil)
diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb
index 332d33b8e52..6cfbb61fbb2 100644
--- a/app/controllers/projects/pages_controller.rb
+++ b/app/controllers/projects/pages_controller.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
class Projects::PagesController < Projects::ApplicationController
- layout :resolve_layout
-
before_action :require_pages_enabled!
before_action :authorize_read_pages!, only: [:show]
before_action :authorize_update_pages!, except: [:show, :destroy]
@@ -10,10 +8,6 @@ class Projects::PagesController < Projects::ApplicationController
feature_category :pages
- before_action do
- push_frontend_feature_flag(:show_pages_in_deployments_menu, current_user, type: :experiment)
- end
-
def new
@pipeline_wizard_data = {
project_path: @project.full_path,
@@ -66,10 +60,6 @@ class Projects::PagesController < Projects::ApplicationController
private
- def resolve_layout
- 'project_settings' unless Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
- end
-
def project_params
params.require(:project).permit(project_params_attributes)
end
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index fb332fec3b5..4fd307b5105 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -25,14 +25,25 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
end
def create
- @schedule = Ci::CreatePipelineScheduleService
- .new(@project, current_user, schedule_params)
- .execute
-
- if @schedule.persisted?
- redirect_to pipeline_schedules_path(@project)
+ if ::Feature.enabled?(:ci_refactoring_pipeline_schedule_create_service, @project)
+ response = Ci::PipelineSchedules::CreateService.new(@project, current_user, schedule_params).execute
+ @schedule = response.payload
+
+ if response.success?
+ redirect_to pipeline_schedules_path(@project)
+ else
+ render :new
+ end
else
- render :new
+ @schedule = Ci::CreatePipelineScheduleService
+ .new(@project, current_user, schedule_params)
+ .execute
+
+ if @schedule.persisted?
+ redirect_to pipeline_schedules_path(@project)
+ else
+ render :new
+ end
end
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 98e6459b543..a96ee2215c2 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -22,7 +22,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action :ensure_pipeline, only: [:show, :downloadable_artifacts]
before_action :reject_if_build_artifacts_size_refreshing!, only: [:destroy]
- before_action :push_frontend_feature_flags, only: [:show, :builds, :dag, :failures, :test_report]
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
@@ -350,10 +349,6 @@ class Projects::PipelinesController < Projects::ApplicationController
def tracking_project_source
project
end
-
- def push_frontend_feature_flags
- push_frontend_feature_flag(:pipeline_details_header_vue, @project)
- end
end
Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController')
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index 2b2c2cef8e2..db19ca23e9f 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -12,8 +12,7 @@ class Projects::RunnersController < Projects::ApplicationController
redirect_to project_settings_ci_cd_path(@project, anchor: 'js-runners-settings')
end
- def edit
- end
+ def edit; end
def update
if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success?
@@ -23,12 +22,10 @@ class Projects::RunnersController < Projects::ApplicationController
end
end
- def new
- render_404 unless create_runner_workflow_for_namespace_enabled?
- end
+ def new; end
def register
- render_404 unless create_runner_workflow_for_namespace_enabled? && runner.registration_available?
+ render_404 unless runner.registration_available?
end
def destroy
@@ -55,8 +52,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
end
- def show
- end
+ def show; end
def toggle_shared_runners
update_params = { shared_runners_enabled: !project.shared_runners_enabled }
@@ -84,8 +80,4 @@ class Projects::RunnersController < Projects::ApplicationController
def runner_params
params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
end
-
- def create_runner_workflow_for_namespace_enabled?
- Feature.enabled?(:create_runner_workflow_for_namespace, project.namespace)
- end
end
diff --git a/app/controllers/projects/service_desk/custom_email_controller.rb b/app/controllers/projects/service_desk/custom_email_controller.rb
new file mode 100644
index 00000000000..fb5e87f9a97
--- /dev/null
+++ b/app/controllers/projects/service_desk/custom_email_controller.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+module Projects
+ module ServiceDesk
+ class CustomEmailController < Projects::ApplicationController
+ before_action :check_feature_flag_enabled
+ before_action :authorize_admin_project!
+
+ feature_category :service_desk
+ urgency :low
+
+ def create
+ response = ::ServiceDesk::CustomEmails::CreateService.new(
+ project: project,
+ current_user: current_user,
+ params: params
+ ).execute
+
+ json_response(service_response: response)
+ end
+
+ def update
+ response = ServiceDeskSettings::UpdateService.new(project, current_user, update_setting_params).execute
+
+ if response.error?
+ json_response(
+ error_message: s_("ServiceDesk|Cannot update custom email"),
+ status: :unprocessable_entity
+ )
+ return
+ end
+
+ json_response
+ end
+
+ def destroy
+ response = ::ServiceDesk::CustomEmails::DestroyService.new(
+ project: project,
+ current_user: current_user
+ ).execute
+
+ json_response(service_response: response)
+ end
+
+ def show
+ json_response
+ end
+
+ private
+
+ def update_setting_params
+ params.permit(:custom_email_enabled)
+ end
+
+ def json_response(error_message: nil, status: :ok, service_response: nil)
+ if service_response.present?
+ status = service_response.success? ? :ok : :unprocessable_entity
+ error_message = service_response.message
+ end
+
+ respond_to do |format|
+ format.json { render json: custom_email_attributes(error_message: error_message), status: status }
+ end
+ end
+
+ def custom_email_attributes(error_message:)
+ setting = project.service_desk_setting
+
+ {
+ custom_email: setting&.custom_email,
+ custom_email_enabled: setting&.custom_email_enabled || false,
+ custom_email_verification_state: setting&.custom_email_verification&.state,
+ custom_email_verification_error: setting&.custom_email_verification&.error,
+ custom_email_smtp_address: setting&.custom_email_credential&.smtp_address,
+ error_message: error_message
+ }
+ end
+
+ def check_feature_flag_enabled
+ render_404 unless Feature.enabled?(:service_desk_custom_email, @project)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/service_desk_controller.rb b/app/controllers/projects/service_desk_controller.rb
index 8f576b8d72b..b1e30e7a45b 100644
--- a/app/controllers/projects/service_desk_controller.rb
+++ b/app/controllers/projects/service_desk_controller.rb
@@ -13,12 +13,12 @@ class Projects::ServiceDeskController < Projects::ApplicationController
def update
Projects::UpdateService.new(project, current_user, { service_desk_enabled: params[:service_desk_enabled] }).execute
- result = ServiceDeskSettings::UpdateService.new(project, current_user, setting_params).execute
+ response = ServiceDeskSettings::UpdateService.new(project, current_user, setting_params).execute
- if result[:status] == :success
+ if response.success?
json_response
else
- render json: { message: result[:message] }, status: :unprocessable_entity
+ render json: { message: response.message }, status: :unprocessable_entity
end
end
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index ce760051f79..0e892ef3faa 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -14,10 +14,6 @@ module Projects
before_action do
push_frontend_feature_flag(:ci_variables_pages, current_user)
- push_frontend_feature_flag(:ci_limit_environment_scope, @project)
- push_frontend_feature_flag(:create_runner_workflow_for_namespace, @project.namespace)
- push_frontend_feature_flag(:frozen_outbound_job_token_scopes, @project)
- push_frontend_feature_flag(:frozen_outbound_job_token_scopes_override, @project)
end
helper_method :highlight_badge
diff --git a/app/controllers/projects/tracing_controller.rb b/app/controllers/projects/tracing_controller.rb
new file mode 100644
index 00000000000..d1218ebf344
--- /dev/null
+++ b/app/controllers/projects/tracing_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Projects
+ class TracingController < Projects::ApplicationController
+ include ::Observability::ContentSecurityPolicy
+
+ feature_category :tracing
+
+ before_action :check_tracing_enabled
+
+ def index; end
+
+ private
+
+ def check_tracing_enabled
+ render_404 unless Gitlab::Observability.tracing_enabled?(project)
+ end
+ end
+end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index c8f698d6193..b961339111b 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -12,12 +12,14 @@ class Projects::TreeController < Projects::ApplicationController
before_action :require_non_empty_project, except: [:new, :create]
before_action :assign_ref_vars
+ before_action :find_requested_ref, only: [:show]
before_action :assign_dir_vars, only: [:create_dir]
before_action :authorize_read_code!
before_action :authorize_edit_tree!, only: [:create_dir]
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
@@ -28,18 +30,20 @@ class Projects::TreeController < Projects::ApplicationController
def show
return render_404 unless @commit
- @ref_type = ref_type
- if @ref_type == BRANCH_REF_TYPE && ambiguous_ref?(@project, @ref)
- branch = @project.repository.find_branch(@ref)
- if branch
- redirect_to project_tree_path(@project, branch.target)
- return
+ unless Feature.enabled?(:redirect_with_ref_type, @project)
+ @ref_type = ref_type
+ if @ref_type == BRANCH_REF_TYPE && ambiguous_ref?(@project, @ref)
+ branch = @project.repository.find_branch(@ref)
+ if branch
+ redirect_to project_tree_path(@project, branch.target)
+ return
+ end
end
end
if tree.entries.empty?
if @repository.blob_at(@commit.id, @path)
- redirect_to project_blob_path(@project, File.join(@ref, @path))
+ redirect_to project_blob_path(@project, File.join(@ref, @path), ref_type: @ref_type)
elsif @path.present?
redirect_to_tree_root_for_missing_path(@project, @ref, @path)
end
@@ -59,6 +63,23 @@ class Projects::TreeController < Projects::ApplicationController
private
+ def find_requested_ref
+ return unless Feature.enabled?(:redirect_with_ref_type, @project)
+
+ @ref_type = ref_type
+ if @ref_type.present?
+ @tree = @repo.tree(@ref, @path, ref_type: @ref_type)
+ else
+ response = ExtractsPath::RequestedRef.new(@repository, ref_type: nil, ref: @ref).find
+ @ref_type = response[:ref_type]
+ @commit = response[:commit]
+
+ if response[:ambiguous]
+ redirect_to(project_tree_path(@project, File.join(@ref_type ? @ref : @commit.id, @path), ref_type: @ref_type))
+ end
+ end
+ end
+
def redirect_renamed_default_branch?
action_name == 'show'
end
diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb
index 8f4987a07f6..48399e17b25 100644
--- a/app/controllers/projects/uploads_controller.rb
+++ b/app/controllers/projects/uploads_controller.rb
@@ -11,7 +11,7 @@ class Projects::UploadsController < Projects::ApplicationController
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
- feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
+ feature_category :team_planning
private
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 81f205a6457..51f6158d9c0 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -38,9 +38,11 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:remove_monitor_metrics, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_frontend_feature_flag(:ci_namespace_catalog_experimental, @project)
+ push_frontend_feature_flag(:service_desk_custom_email, @project)
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies)
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
@@ -172,7 +174,9 @@ class ProjectsController < Projects::ApplicationController
flash.now[:alert] = _("Project '%{project_name}' queued for deletion.") % { project_name: @project.name }
end
- if ambiguous_ref?(@project, @ref)
+ if Feature.enabled?(:redirect_with_ref_type, @project)
+ @ref_type = 'heads'
+ elsif ambiguous_ref?(@project, @ref)
branch = @project.repository.find_branch(@ref)
# The files view would render a ref other than the default branch
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index 76aa4afbe80..76f181e3ce8 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -7,10 +7,10 @@ module Registrations
include ::Gitlab::Utils::StrongMemoize
layout 'minimal'
- skip_before_action :authenticate_user!, :required_signup_info, :check_two_factor_requirement, only: [:show, :update]
- before_action :require_current_user
+ skip_before_action :required_signup_info, :check_two_factor_requirement
helper_method :welcome_update_params
+ helper_method :onboarding_status
feature_category :user_management
@@ -25,7 +25,7 @@ module Registrations
if result.success?
track_event('successfully_submitted_form')
- finish_onboarding_on_welcome_page unless complete_signup_onboarding?
+ successful_update_hooks
redirect_to update_success_path
else
@@ -35,14 +35,10 @@ module Registrations
private
- def registering_from_invite?(members)
- # If there are more than one member it will mean we have been invited to multiple projects/groups and
- # are not able to distinguish which one we should putting the user in after registration
- members.count == 1 && members.last.source.present?
- end
+ def authenticate_user!
+ return if current_user
- def require_current_user
- return redirect_to new_user_registration_path unless current_user
+ redirect_to new_user_registration_path
end
def completed_welcome_step?
@@ -54,33 +50,28 @@ module Registrations
end
def path_for_signed_in_user(user)
- stored_location_for(user) || members_activity_path(user.members)
- end
-
- def members_activity_path(members)
- return dashboard_projects_path unless members.any?
- return dashboard_projects_path unless members.last.source.present?
-
- members.last.source.activity_path
+ stored_location_for(user) || last_member_activity_path
end
# overridden in EE
def complete_signup_onboarding?
- false
+ onboarding_status.continue_full_onboarding?
end
- def invites_with_tasks_to_be_done?
- MemberTask.for_members(user_members).exists?
+ def last_member_activity_path
+ return dashboard_projects_path unless onboarding_status.last_invited_member_source.present?
+
+ onboarding_status.last_invited_member_source.activity_path
end
def update_success_path
- if invites_with_tasks_to_be_done?
+ if onboarding_status.invite_with_tasks_to_be_done?
issues_dashboard_path(assignee_username: current_user.username)
elsif complete_signup_onboarding? # trials/regular registration on .com
signup_onboarding_path
- elsif registering_from_invite?(user_members) # invites w/o tasks due to order
- flash[:notice] = helpers.invite_accepted_notice(user_members.last)
- members_activity_path(user_members)
+ elsif onboarding_status.single_invite? # invites w/o tasks due to order
+ flash[:notice] = helpers.invite_accepted_notice(onboarding_status.last_invited_member)
+ onboarding_status.last_invited_member_source.activity_path
else
# Subscription registrations goes through here as well.
# Invites will come here too if there is more than 1.
@@ -88,13 +79,8 @@ module Registrations
end
end
- def user_members
- current_user.members
- end
- strong_memoize_attr :user_members
-
# overridden in EE
- def finish_onboarding_on_welcome_page; end
+ def successful_update_hooks; end
# overridden in EE
def signup_onboarding_path; end
@@ -106,6 +92,11 @@ module Registrations
def welcome_update_params
{}
end
+
+ def onboarding_status
+ Onboarding::Status.new(current_user)
+ end
+ strong_memoize_attr :onboarding_status
end
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index f481681da02..76b7d30cd51 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -184,8 +184,6 @@ class RegistrationsController < Devise::RegistrationsController
end
def check_captcha
- ensure_correct_params!
-
return unless show_recaptcha_sign_up?
return unless Gitlab::Recaptcha.load_configurations!
@@ -224,6 +222,7 @@ class RegistrationsController < Devise::RegistrationsController
end
def sign_up_params
+ ensure_correct_params!
params.require(:user).permit(sign_up_params_attributes)
end
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index b797a204d7f..6d3811514d9 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -29,7 +29,7 @@ class UploadsController < ApplicationController
before_action :authorize_create_access!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
- feature_category :team_planning
+ feature_category :groups_and_projects
def self.model_classes
MODEL_CLASSES
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 4db5745c005..88a8851607b 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -97,11 +97,11 @@ class UsersController < ApplicationController
end
def groups
- load_groups
-
respond_to do |format|
format.html { render 'show' }
format.json do
+ load_groups
+
render json: {
html: view_to_html_string("shared/groups/_list", groups: @groups)
}
@@ -110,36 +110,36 @@ class UsersController < ApplicationController
end
def projects
- load_projects
-
- present_projects(@projects)
+ present_projects do
+ load_projects
+ end
end
def contributed
- load_contributed_projects
-
- present_projects(@contributed_projects)
+ present_projects do
+ load_contributed_projects
+ end
end
def starred
- load_starred_projects
-
- present_projects(@starred_projects)
+ present_projects do
+ load_starred_projects
+ end
end
def followers
- @user_followers = user.followers.page(params[:page])
-
- present_users(@user_followers)
+ present_users do
+ @user_followers = user.followers.page(params[:page])
+ end
end
def following
- @user_following = user.followees.page(params[:page])
-
- present_users(@user_following)
+ present_users do
+ @user_following = user.followees.page(params[:page])
+ end
end
- def present_projects(projects)
+ def present_projects
skip_pagination = Gitlab::Utils.to_boolean(params[:skip_pagination])
skip_namespace = Gitlab::Utils.to_boolean(params[:skip_namespace])
compact_mode = Gitlab::Utils.to_boolean(params[:compact_mode])
@@ -147,17 +147,19 @@ class UsersController < ApplicationController
respond_to do |format|
format.html { render 'show' }
format.json do
+ projects = yield
+
pager_json("shared/projects/_list", projects.count, projects: projects, skip_pagination: skip_pagination, skip_namespace: skip_namespace, compact_mode: compact_mode)
end
end
end
def snippets
- load_snippets
-
respond_to do |format|
format.html { render 'show' }
format.json do
+ load_snippets
+
render json: {
html: view_to_html_string("snippets/_snippets", collection: @snippets)
}
@@ -281,10 +283,11 @@ class UsersController < ApplicationController
access_denied! unless can?(current_user, :read_user_profile, user)
end
- def present_users(users)
+ def present_users
respond_to do |format|
format.html { render 'show' }
format.json do
+ users = yield
render json: {
html: view_to_html_string("shared/users/index", users: users)
}