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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/application_settings_controller.rb10
-rw-r--r--app/controllers/admin/integrations_controller.rb2
-rw-r--r--app/controllers/admin/services_controller.rb3
-rw-r--r--app/controllers/clusters/base_controller.rb4
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb12
-rw-r--r--app/controllers/concerns/checks_collaboration.rb2
-rw-r--r--app/controllers/concerns/graceful_timeout_handling.rb15
-rw-r--r--app/controllers/concerns/integrations_actions.rb3
-rw-r--r--app/controllers/concerns/issuable_collections.rb2
-rw-r--r--app/controllers/concerns/packages_access.rb20
-rw-r--r--app/controllers/concerns/paginated_collection.rb2
-rw-r--r--app/controllers/concerns/renders_blob.rb8
-rw-r--r--app/controllers/concerns/send_file_upload.rb21
-rw-r--r--app/controllers/concerns/snippets_actions.rb22
-rw-r--r--app/controllers/concerns/wiki_actions.rb10
-rw-r--r--app/controllers/dashboard/projects_controller.rb2
-rw-r--r--app/controllers/dashboard/todos_controller.rb2
-rw-r--r--app/controllers/explore/projects_controller.rb2
-rw-r--r--app/controllers/groups/packages_controller.rb13
-rw-r--r--app/controllers/groups/releases_controller.rb23
-rw-r--r--app/controllers/groups/variables_controller.rb7
-rw-r--r--app/controllers/import/available_namespaces_controller.rb7
-rw-r--r--app/controllers/import/base_controller.rb8
-rw-r--r--app/controllers/import/gitea_controller.rb10
-rw-r--r--app/controllers/import/github_controller.rb76
-rw-r--r--app/controllers/import/manifest_controller.rb57
-rw-r--r--app/controllers/invites_controller.rb46
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb7
-rw-r--r--app/controllers/profiles/passwords_controller.rb2
-rw-r--r--app/controllers/profiles/personal_access_tokens_controller.rb8
-rw-r--r--app/controllers/projects/artifacts_controller.rb2
-rw-r--r--app/controllers/projects/blob_controller.rb2
-rw-r--r--app/controllers/projects/ci/lints_controller.rb34
-rw-r--r--app/controllers/projects/commit_controller.rb8
-rw-r--r--app/controllers/projects/cycle_analytics/events_controller.rb1
-rw-r--r--app/controllers/projects/cycle_analytics_controller.rb1
-rw-r--r--app/controllers/projects/environments_controller.rb15
-rw-r--r--app/controllers/projects/forks_controller.rb14
-rw-r--r--app/controllers/projects/incidents_controller.rb8
-rw-r--r--app/controllers/projects/issues_controller.rb20
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb19
-rw-r--r--app/controllers/projects/metrics/dashboards/builder_controller.rb42
-rw-r--r--app/controllers/projects/metrics_dashboard_controller.rb3
-rw-r--r--app/controllers/projects/packages/package_files_controller.rb16
-rw-r--r--app/controllers/projects/packages/packages_controller.rb24
-rw-r--r--app/controllers/projects/pipelines/tests_controller.rb19
-rw-r--r--app/controllers/projects/pipelines_controller.rb11
-rw-r--r--app/controllers/projects/product_analytics_controller.rb53
-rw-r--r--app/controllers/projects/prometheus/alerts_controller.rb8
-rw-r--r--app/controllers/projects/protected_refs_controller.rb2
-rw-r--r--app/controllers/projects/releases_controller.rb2
-rw-r--r--app/controllers/projects/services_controller.rb1
-rw-r--r--app/controllers/projects/settings/operations_controller.rb6
-rw-r--r--app/controllers/projects/snippets/blobs_controller.rb2
-rw-r--r--app/controllers/projects/snippets_controller.rb4
-rw-r--r--app/controllers/projects/variables_controller.rb7
-rw-r--r--app/controllers/projects_controller.rb8
-rw-r--r--app/controllers/registrations/experience_levels_controller.rb4
-rw-r--r--app/controllers/registrations_controller.rb14
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/controllers/repositories/lfs_storage_controller.rb5
-rw-r--r--app/controllers/root_controller.rb5
-rw-r--r--app/controllers/search_controller.rb14
-rw-r--r--app/controllers/sessions_controller.rb7
-rw-r--r--app/controllers/snippets_controller.rb4
66 files changed, 602 insertions, 193 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 41a6616d10c..3a5b8b2862e 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -16,7 +16,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
push_frontend_feature_flag(:ci_instance_variables_ui, default_enabled: true)
end
- VALID_SETTING_PANELS = %w(general integrations repository
+ VALID_SETTING_PANELS = %w(general repository
ci_cd reporting metrics_and_profiling
network preferences).freeze
@@ -32,12 +32,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end
def integrations
- if Feature.enabled?(:instance_level_integrations)
- @integrations = Service.find_or_initialize_instances.sort_by(&:title)
- else
- set_application_setting
- perform_update if submitted?
- end
+ @integrations = Service.find_or_initialize_instances.sort_by(&:title)
end
def update
@@ -225,7 +220,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:lets_encrypt_terms_of_service_accepted,
:domain_blacklist_file,
:raw_blob_request_limit,
- :namespace_storage_size_limit,
:issues_create_limit,
:default_branch_name,
disabled_oauth_sign_in_sources: [],
diff --git a/app/controllers/admin/integrations_controller.rb b/app/controllers/admin/integrations_controller.rb
index 4f3be43d14d..b2d5a2d130c 100644
--- a/app/controllers/admin/integrations_controller.rb
+++ b/app/controllers/admin/integrations_controller.rb
@@ -12,7 +12,7 @@ class Admin::IntegrationsController < Admin::ApplicationController
end
def integrations_enabled?
- Feature.enabled?(:instance_level_integrations)
+ true
end
def scoped_edit_integration_path(integration)
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb
index e0137accd2d..1bc82e98ab8 100644
--- a/app/controllers/admin/services_controller.rb
+++ b/app/controllers/admin/services_controller.rb
@@ -5,9 +5,6 @@ class Admin::ServicesController < Admin::ApplicationController
before_action :service, only: [:edit, :update]
before_action :whitelist_query_limiting, only: [:index]
- before_action only: :edit do
- push_frontend_feature_flag(:integration_form_refactor, default_enabled: true)
- end
def index
@services = Service.find_or_create_templates.sort_by(&:title)
diff --git a/app/controllers/clusters/base_controller.rb b/app/controllers/clusters/base_controller.rb
index c79a0bb01bc..188805c6106 100644
--- a/app/controllers/clusters/base_controller.rb
+++ b/app/controllers/clusters/base_controller.rb
@@ -6,10 +6,6 @@ class Clusters::BaseController < ApplicationController
skip_before_action :authenticate_user!
before_action :authorize_read_cluster!
- before_action do
- push_frontend_feature_flag(:managed_apps_local_tiller, clusterable, default_enabled: true)
- end
-
helper_method :clusterable
private
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index b885e55f902..4b4bcc8d37e 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -33,9 +33,7 @@ module AuthenticatesWithTwoFactor
end
def locked_user_redirect(user)
- flash.now[:alert] = locked_user_redirect_alert(user)
-
- render 'devise/sessions/new'
+ redirect_to new_user_session_path, alert: locked_user_redirect_alert(user)
end
def authenticate_with_two_factor
@@ -54,7 +52,13 @@ module AuthenticatesWithTwoFactor
private
def locked_user_redirect_alert(user)
- user.access_locked? ? _('Your account is locked.') : _('Invalid Login or password')
+ if user.access_locked?
+ _('Your account is locked.')
+ elsif !user.confirmed?
+ I18n.t('devise.failure.unconfirmed')
+ else
+ _('Invalid Login or password')
+ end
end
def clear_two_factor_attempt!
diff --git a/app/controllers/concerns/checks_collaboration.rb b/app/controllers/concerns/checks_collaboration.rb
index 1fa82f7dcd4..87239facdeb 100644
--- a/app/controllers/concerns/checks_collaboration.rb
+++ b/app/controllers/concerns/checks_collaboration.rb
@@ -17,7 +17,7 @@ module ChecksCollaboration
# used across multiple calls in the view
def user_access(project)
@user_access ||= {}
- @user_access[project] ||= Gitlab::UserAccess.new(current_user, project: project)
+ @user_access[project] ||= Gitlab::UserAccess.new(current_user, container: project)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end
diff --git a/app/controllers/concerns/graceful_timeout_handling.rb b/app/controllers/concerns/graceful_timeout_handling.rb
new file mode 100644
index 00000000000..490c0ec3b1d
--- /dev/null
+++ b/app/controllers/concerns/graceful_timeout_handling.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module GracefulTimeoutHandling
+ extend ActiveSupport::Concern
+
+ included do
+ rescue_from ActiveRecord::QueryCanceled do |exception|
+ raise exception unless request.format.json?
+
+ log_exception(exception)
+
+ render json: { error: _('There is too much data to calculate. Please change your selection.') }
+ end
+ end
+end
diff --git a/app/controllers/concerns/integrations_actions.rb b/app/controllers/concerns/integrations_actions.rb
index 46febc44807..9a8e5d14123 100644
--- a/app/controllers/concerns/integrations_actions.rb
+++ b/app/controllers/concerns/integrations_actions.rb
@@ -8,9 +8,6 @@ module IntegrationsActions
before_action :not_found, unless: :integrations_enabled?
before_action :integration, only: [:edit, :update, :test]
- before_action only: :edit do
- push_frontend_feature_flag(:integration_form_refactor, default_enabled: true)
- end
end
def edit
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 4f61e5ed711..89ba2175b60 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -65,7 +65,7 @@ module IssuableCollections
def page_count_for_relation(relation, row_count)
limit = relation.limit_value.to_f
- return 1 if limit.zero?
+ return 1 if limit == 0
(row_count.to_f / limit).ceil
end
diff --git a/app/controllers/concerns/packages_access.rb b/app/controllers/concerns/packages_access.rb
new file mode 100644
index 00000000000..6df2e064bb2
--- /dev/null
+++ b/app/controllers/concerns/packages_access.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module PackagesAccess
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :verify_packages_enabled!
+ before_action :verify_read_package!
+ end
+
+ private
+
+ def verify_packages_enabled!
+ render_404 unless Gitlab.config.packages.enabled
+ end
+
+ def verify_read_package!
+ authorize_read_package!(project)
+ end
+end
diff --git a/app/controllers/concerns/paginated_collection.rb b/app/controllers/concerns/paginated_collection.rb
index be84215a9e2..fcee4493314 100644
--- a/app/controllers/concerns/paginated_collection.rb
+++ b/app/controllers/concerns/paginated_collection.rb
@@ -6,7 +6,7 @@ module PaginatedCollection
private
def redirect_out_of_range(collection, total_pages = collection.total_pages)
- return false if total_pages.zero?
+ return false if total_pages == 0
out_of_range = collection.current_page > total_pages
diff --git a/app/controllers/concerns/renders_blob.rb b/app/controllers/concerns/renders_blob.rb
index b8026c7a01d..a15bf27a22f 100644
--- a/app/controllers/concerns/renders_blob.rb
+++ b/app/controllers/concerns/renders_blob.rb
@@ -29,6 +29,12 @@ module RendersBlob
end
def conditionally_expand_blob(blob)
- blob.expand! if params[:expanded] == 'true'
+ conditionally_expand_blobs([blob])
+ end
+
+ def conditionally_expand_blobs(blobs)
+ return unless params[:expanded] == 'true'
+
+ blobs.each { |blob| blob.expand! }
end
end
diff --git a/app/controllers/concerns/send_file_upload.rb b/app/controllers/concerns/send_file_upload.rb
index 2f5dc09be4a..7cb19fc7e58 100644
--- a/app/controllers/concerns/send_file_upload.rb
+++ b/app/controllers/concerns/send_file_upload.rb
@@ -18,7 +18,11 @@ module SendFileUpload
send_params.merge!(filename: attachment, disposition: disposition)
end
- if file_upload.file_storage?
+ if image_scaling_request?(file_upload)
+ location = file_upload.file_storage? ? file_upload.path : file_upload.url
+ headers.store(*Gitlab::Workhorse.send_scaled_image(location, params[:width].to_i))
+ head :ok
+ elsif file_upload.file_storage?
send_file file_upload.path, send_params
elsif file_upload.class.proxy_download_enabled? || proxy
headers.store(*Gitlab::Workhorse.send_url(file_upload.url(**redirect_params)))
@@ -37,4 +41,19 @@ module SendFileUpload
"application/octet-stream"
end
end
+
+ private
+
+ def image_scaling_request?(file_upload)
+ avatar_image_upload?(file_upload) && valid_image_scaling_width? && current_user &&
+ Feature.enabled?(:dynamic_image_resizing, current_user)
+ end
+
+ def avatar_image_upload?(file_upload)
+ file_upload.try(:image?) && file_upload.try(:mounted_as)&.to_sym == :avatar
+ end
+
+ def valid_image_scaling_width?
+ Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS.include?(params[:width]&.to_i)
+ end
end
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index 048b18c5c61..5552fd663f7 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -55,10 +55,9 @@ module SnippetsActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def show
- conditionally_expand_blob(blob)
-
respond_to do |format|
format.html do
+ conditionally_expand_blob(blob)
@note = Note.new(noteable: @snippet, project: @snippet.project)
@noteable = @snippet
@@ -68,11 +67,14 @@ module SnippetsActions
end
format.json do
+ conditionally_expand_blob(blob)
render_blob_json(blob)
end
format.js do
if @snippet.embeddable?
+ conditionally_expand_blobs(blobs)
+
render 'shared/snippets/show'
else
head :not_found
@@ -109,13 +111,15 @@ module SnippetsActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def blob
- return unless snippet
+ @blob ||= blobs.first
+ end
- @blob ||= if snippet.empty_repo?
- snippet.blob
- else
- snippet.blobs.first
- end
+ def blobs
+ @blobs ||= if snippet.empty_repo?
+ [snippet.blob]
+ else
+ snippet.blobs
+ end
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
@@ -132,6 +136,8 @@ module SnippetsActions
end
def redirect_if_binary
+ return if Feature.enabled?(:snippets_binary_blob)
+
redirect_to gitlab_snippet_path(snippet) if blob&.binary?
end
end
diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb
index a5182000f5b..5b953fe37d6 100644
--- a/app/controllers/concerns/wiki_actions.rb
+++ b/app/controllers/concerns/wiki_actions.rb
@@ -8,6 +8,8 @@ module WikiActions
extend ActiveSupport::Concern
included do
+ before_action { respond_to :html }
+
before_action :authorize_read_wiki!
before_action :authorize_create_wiki!, only: [:edit, :create]
before_action :authorize_admin_wiki!, only: :destroy
@@ -65,6 +67,8 @@ module WikiActions
@ref = params[:version_id]
@path = page.path
+ Gitlab::UsageDataCounters::WikiPageCounter.count(:view)
+
render 'shared/wikis/show'
elsif file_blob
send_blob(wiki.repository, file_blob)
@@ -107,14 +111,16 @@ module WikiActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def create
- @page = WikiPages::CreateService.new(container: container, current_user: current_user, params: wiki_params).execute
+ response = WikiPages::CreateService.new(container: container, current_user: current_user, params: wiki_params).execute
+ @page = response.payload[:page]
- if page.persisted?
+ if response.success?
redirect_to(
wiki_page_path(wiki, page),
notice: _('Wiki was successfully updated.')
)
else
+ flash[:alert] = response.message
render 'shared/wikis/edit'
end
rescue Gitlab::Git::Wiki::OperationError => e
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index ad64b6c4f94..91704f030cd 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -9,7 +9,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
include FiltersEvents
prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) }
- before_action :set_non_archived_param
+ before_action :set_non_archived_param, only: [:index, :starred]
before_action :set_sorting
before_action :projects, only: [:index]
skip_cross_project_access_check :index, :starred
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index db40b0bed77..4fc2f7b0571 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -9,8 +9,6 @@ class Dashboard::TodosController < Dashboard::ApplicationController
before_action :authorize_read_group!, only: :index
before_action :find_todos, only: [:index, :destroy_all]
- track_unique_visits :index, target_id: 'u_analytics_todos'
-
def index
@sort = params[:sort]
@todos = @todos.page(params[:page])
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index f1f41e67a4c..b3fa089a712 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -80,7 +80,7 @@ class Explore::ProjectsController < Explore::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def preload_associations(projects)
- projects.includes(:route, :creator, :group, namespace: [:route, :owner])
+ projects.includes(:route, :creator, :group, :project_feature, namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/groups/packages_controller.rb b/app/controllers/groups/packages_controller.rb
new file mode 100644
index 00000000000..600acc72e67
--- /dev/null
+++ b/app/controllers/groups/packages_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Groups
+ class PackagesController < Groups::ApplicationController
+ before_action :verify_packages_enabled!
+
+ private
+
+ def verify_packages_enabled!
+ render_404 unless group.packages_feature_enabled?
+ end
+ end
+end
diff --git a/app/controllers/groups/releases_controller.rb b/app/controllers/groups/releases_controller.rb
new file mode 100644
index 00000000000..500c57a6f3e
--- /dev/null
+++ b/app/controllers/groups/releases_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Groups
+ class ReleasesController < Groups::ApplicationController
+ def index
+ respond_to do |format|
+ format.json do
+ render json: ReleaseSerializer.new.represent(releases)
+ end
+ end
+ end
+
+ private
+
+ def releases
+ ReleasesFinder
+ .new(@group, current_user, { include_subgroups: true })
+ .execute(preload: false)
+ .page(params[:page])
+ .per(30)
+ end
+ end
+end
diff --git a/app/controllers/groups/variables_controller.rb b/app/controllers/groups/variables_controller.rb
index 02b015e8e53..fb639f6e472 100644
--- a/app/controllers/groups/variables_controller.rb
+++ b/app/controllers/groups/variables_controller.rb
@@ -15,7 +15,12 @@ module Groups
end
def update
- if @group.update(group_variables_params)
+ update_result = Ci::ChangeVariablesService.new(
+ container: @group, current_user: current_user,
+ params: group_variables_params
+ ).execute
+
+ if update_result
respond_to do |format|
format.json { render_group_variables }
end
diff --git a/app/controllers/import/available_namespaces_controller.rb b/app/controllers/import/available_namespaces_controller.rb
new file mode 100644
index 00000000000..7983b4f20b5
--- /dev/null
+++ b/app/controllers/import/available_namespaces_controller.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class Import::AvailableNamespacesController < ApplicationController
+ def index
+ render json: NamespaceSerializer.new.represent(current_user.manageable_groups_with_routes)
+ end
+end
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index bc05030f8af..8a7a4c92b37 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -41,6 +41,10 @@ class Import::BaseController < ApplicationController
raise NotImplementedError
end
+ def extra_representation_opts
+ {}
+ end
+
private
def filter_attribute
@@ -58,11 +62,11 @@ class Import::BaseController < ApplicationController
end
def serialized_provider_repos
- Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url)
+ Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts)
end
def serialized_incompatible_repos
- Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url)
+ Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts)
end
def serialized_imported_projects
diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb
index efeff8439e4..4785a71b8a1 100644
--- a/app/controllers/import/gitea_controller.rb
+++ b/app/controllers/import/gitea_controller.rb
@@ -54,6 +54,16 @@ class Import::GiteaController < Import::GithubController
end
end
+ override :client_repos
+ def client_repos
+ @client_repos ||= filtered(client.repos)
+ end
+
+ override :client
+ def client
+ @client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options)
+ end
+
override :client_options
def client_options
{ host: provider_url, api_version: 'v1' }
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index ac6b8c06d66..29fe34f0734 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -10,6 +10,9 @@ class Import::GithubController < Import::BaseController
before_action :provider_auth, only: [:status, :realtime_changes, :create]
before_action :expire_etag_cache, only: [:status, :create]
+ OAuthConfigMissingError = Class.new(StandardError)
+
+ rescue_from OAuthConfigMissingError, with: :missing_oauth_config
rescue_from Octokit::Unauthorized, with: :provider_unauthorized
rescue_from Octokit::TooManyRequests, with: :provider_rate_limit
@@ -22,7 +25,7 @@ class Import::GithubController < Import::BaseController
end
def callback
- session[access_token_key] = client.get_token(params[:code])
+ session[access_token_key] = get_token(params[:code])
redirect_to status_import_url
end
@@ -77,9 +80,7 @@ class Import::GithubController < Import::BaseController
override :provider_url
def provider_url
strong_memoize(:provider_url) do
- provider = Gitlab::Auth::OAuth::Provider.config_for('github')
-
- provider&.dig('url').presence || 'https://github.com'
+ oauth_config&.dig('url').presence || 'https://github.com'
end
end
@@ -104,11 +105,66 @@ class Import::GithubController < Import::BaseController
end
def client
- @client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options)
+ @client ||= if Feature.enabled?(:remove_legacy_github_client)
+ Gitlab::GithubImport::Client.new(session[access_token_key])
+ else
+ Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options)
+ end
end
def client_repos
- @client_repos ||= filtered(client.repos)
+ @client_repos ||= if Feature.enabled?(:remove_legacy_github_client)
+ filtered(concatenated_repos)
+ else
+ filtered(client.repos)
+ end
+ end
+
+ def concatenated_repos
+ return [] unless client.respond_to?(:each_page)
+
+ client.each_page(:repos).flat_map(&:objects)
+ end
+
+ def oauth_client
+ raise OAuthConfigMissingError unless oauth_config
+
+ @oauth_client ||= ::OAuth2::Client.new(
+ oauth_config.app_id,
+ oauth_config.app_secret,
+ oauth_options.merge(ssl: { verify: oauth_config['verify_ssl'] })
+ )
+ end
+
+ def oauth_config
+ @oauth_config ||= Gitlab::Auth::OAuth::Provider.config_for('github')
+ end
+
+ def oauth_options
+ if oauth_config
+ oauth_config.dig('args', 'client_options').deep_symbolize_keys
+ else
+ OmniAuth::Strategies::GitHub.default_options[:client_options].symbolize_keys
+ end
+ end
+
+ def authorize_url
+ if Feature.enabled?(:remove_legacy_github_client)
+ oauth_client.auth_code.authorize_url(
+ redirect_uri: callback_import_url,
+ scope: 'repo, user, user:email'
+ )
+ else
+ client.authorize_url(callback_import_url)
+ end
+ end
+
+ def get_token(code)
+ if Feature.enabled?(:remove_legacy_github_client)
+ oauth_client.auth_code.get_token(code).token
+ else
+ client.get_token(code)
+ end
end
def verify_import_enabled
@@ -116,7 +172,7 @@ class Import::GithubController < Import::BaseController
end
def go_to_provider_for_permissions
- redirect_to client.authorize_url(callback_import_url)
+ redirect_to authorize_url
end
def import_enabled?
@@ -152,6 +208,12 @@ class Import::GithubController < Import::BaseController
alert: _("GitHub API rate limit exceeded. Try again after %{reset_time}") % { reset_time: reset_time }
end
+ def missing_oauth_config
+ session[access_token_key] = nil
+ redirect_to new_import_url,
+ alert: _('Missing OAuth configuration for GitHub.')
+ end
+
def access_token_key
:"#{provider_name}_access_token"
end
diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb
index 9aec870c6ea..9c47e6d4b0b 100644
--- a/app/controllers/import/manifest_controller.rb
+++ b/app/controllers/import/manifest_controller.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class Import::ManifestController < Import::BaseController
+ extend ::Gitlab::Utils::Override
+
before_action :whitelist_query_limiting, only: [:create]
before_action :verify_import_enabled
before_action :ensure_import_vars, only: [:create, :status]
@@ -8,16 +10,9 @@ class Import::ManifestController < Import::BaseController
def new
end
- # rubocop: disable CodeReuse/ActiveRecord
def status
- @already_added_projects = find_already_added_projects
- already_added_import_urls = @already_added_projects.pluck(:import_url)
-
- @pending_repositories = repositories.to_a.reject do |repository|
- already_added_import_urls.include?(repository[:url])
- end
+ super
end
- # rubocop: enable CodeReuse/ActiveRecord
def upload
group = Group.find(params[:group_id])
@@ -42,8 +37,8 @@ class Import::ManifestController < Import::BaseController
end
end
- def jobs
- render json: find_jobs
+ def realtime_changes
+ super
end
def create
@@ -54,12 +49,43 @@ class Import::ManifestController < Import::BaseController
project = Gitlab::ManifestImport::ProjectCreator.new(repository, group, current_user).execute
if project.persisted?
- render json: ProjectSerializer.new.represent(project)
+ render json: ProjectSerializer.new.represent(project, serializer: :import)
else
render json: { errors: project_save_error(project) }, status: :unprocessable_entity
end
end
+ protected
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ override :importable_repos
+ def importable_repos
+ already_added_projects_names = already_added_projects.pluck(:import_url)
+
+ repositories.reject { |repo| already_added_projects_names.include?(repo[:url]) }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ override :incompatible_repos
+ def incompatible_repos
+ []
+ end
+
+ override :provider_name
+ def provider_name
+ :manifest
+ end
+
+ override :provider_url
+ def provider_url
+ nil
+ end
+
+ override :extra_representation_opts
+ def extra_representation_opts
+ { group_full_path: group.full_path }
+ end
+
private
def ensure_import_vars
@@ -82,15 +108,6 @@ class Import::ManifestController < Import::BaseController
find_already_added_projects.to_json(only: [:id], methods: [:import_status])
end
- # rubocop: disable CodeReuse/ActiveRecord
- def find_already_added_projects
- group.all_projects
- .where(import_type: 'manifest')
- .where(creator_id: current_user)
- .with_import_state
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def verify_import_enabled
render_404 unless manifest_import_enabled?
end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 5bd9ac7f275..29cafbbbdb6 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -4,6 +4,7 @@ class InvitesController < ApplicationController
include Gitlab::Utils::StrongMemoize
before_action :member
+ before_action :invite_details
skip_before_action :authenticate_user!, only: :decline
helper_method :member?, :current_user_matches_invite?
@@ -16,9 +17,8 @@ class InvitesController < ApplicationController
def accept
if member.accept_invite!(current_user)
- label, path = source_info(member.source)
-
- redirect_to path, notice: _("You have been granted %{member_human_access} access to %{label}.") % { member_human_access: member.human_access, label: label }
+ redirect_to invite_details[:path], notice: _("You have been granted %{member_human_access} access to %{title} %{name}.") %
+ { member_human_access: member.human_access, title: invite_details[:title], name: invite_details[:name] }
else
redirect_back_or_default(options: { alert: _("The invitation could not be accepted.") })
end
@@ -26,8 +26,6 @@ class InvitesController < ApplicationController
def decline
if member.decline_invite!
- label, _ = source_info(member.source)
-
path =
if current_user
dashboard_projects_path
@@ -35,7 +33,8 @@ class InvitesController < ApplicationController
new_user_session_path
end
- redirect_to path, notice: _("You have declined the invitation to join %{label}.") % { label: label }
+ redirect_to path, notice: _("You have declined the invitation to join %{title} %{name}.") %
+ { title: invite_details[:title], name: invite_details[:name] }
else
redirect_back_or_default(options: { alert: _("The invitation could not be declined.") })
end
@@ -76,24 +75,25 @@ class InvitesController < ApplicationController
notice = notice.join(' ') + "."
store_location_for :user, request.fullpath
- redirect_to new_user_session_path, notice: notice
+ redirect_to new_user_session_path(invite_email: member.invite_email), notice: notice
end
- def source_info(source)
- case source
- when Project
- project = member.source
- label = "project #{project.full_name}"
- path = project_path(project)
- when Group
- group = member.source
- label = "group #{group.name}"
- path = group_path(group)
- else
- label = "who knows what"
- path = dashboard_projects_path
- end
-
- [label, path]
+ def invite_details
+ @invite_details ||= case @member.source
+ when Project
+ {
+ name: @member.source.full_name,
+ url: project_url(@member.source),
+ title: _("project"),
+ path: project_path(@member.source)
+ }
+ when Group
+ {
+ name: @member.source.name,
+ url: group_url(@member.source),
+ title: _("group"),
+ path: group_path(@member.source)
+ }
+ end
end
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 706a4843117..6a393405e4d 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -27,6 +27,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
user = User.by_login(params[:username])
user&.increment_failed_attempts!
+ log_failed_login(params[:username], failed_strategy.name)
end
super
@@ -90,6 +91,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
private
+ def log_failed_login(user, provider)
+ # overridden in EE
+ end
+
def after_omniauth_failure_path_for(scope)
if Feature.enabled?(:user_mode_in_session)
return new_admin_session_path if current_user_mode.admin_mode_requested?
@@ -198,6 +203,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def fail_login(user)
+ log_failed_login(user.username, oauth['provider'])
+
error_message = user.errors.full_messages.to_sentence
redirect_to omniauth_error_path(oauth['provider'], error: error_message)
diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb
index d2787c2e450..fccbc29f598 100644
--- a/app/controllers/profiles/passwords_controller.rb
+++ b/app/controllers/profiles/passwords_controller.rb
@@ -52,7 +52,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
result = Users::UpdateService.new(current_user, password_attributes.merge(user: @user)).execute
if result[:status] == :success
- flash[:notice] = _('Password was successfully updated. Please login with it')
+ flash[:notice] = _('Password was successfully updated. Please sign in again.')
redirect_to new_user_session_path
else
@user.reset
diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb
index 30f25e8fdaa..21adc032940 100644
--- a/app/controllers/profiles/personal_access_tokens_controller.rb
+++ b/app/controllers/profiles/personal_access_tokens_controller.rb
@@ -20,12 +20,8 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
def revoke
@personal_access_token = finder.find(params[:id])
-
- if @personal_access_token.revoke!
- flash[:notice] = _("Revoked personal access token %{personal_access_token_name}!") % { personal_access_token_name: @personal_access_token.name }
- else
- flash[:alert] = _("Could not revoke personal access token %{personal_access_token_name}.") % { personal_access_token_name: @personal_access_token.name }
- end
+ service = PersonalAccessTokens::RevokeService.new(current_user, token: @personal_access_token).execute
+ service.success? ? flash[:notice] = service.message : flash[:alert] = service.message
redirect_to profile_personal_access_tokens_path
end
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index fef3c6cf424..652687932fd 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -108,7 +108,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
end
def validate_artifacts!
- render_404 unless build&.artifacts?
+ render_404 unless build&.available_artifacts?
end
def build
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 7f14522e61b..d969e7bf771 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -257,5 +257,3 @@ class Projects::BlobController < Projects::ApplicationController
params.permit(:full, :since, :to, :bottom, :unfold, :offset, :indent)
end
end
-
-Projects::BlobController.prepend_if_ee('EE::Projects::BlobController')
diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb
index 73b3eb9c205..c13baaea8c6 100644
--- a/app/controllers/projects/ci/lints_controller.rb
+++ b/app/controllers/projects/ci/lints_controller.rb
@@ -8,16 +8,30 @@ class Projects::Ci::LintsController < Projects::ApplicationController
def create
@content = params[:content]
- result = Gitlab::Ci::YamlProcessor.new_with_validation_errors(@content, yaml_processor_options)
-
- @status = result.valid?
- @errors = result.errors
-
- if result.valid?
- @config_processor = result.config
- @stages = @config_processor.stages
- @builds = @config_processor.builds
- @jobs = @config_processor.jobs
+ @dry_run = params[:dry_run]
+
+ if @dry_run && Gitlab::Ci::Features.lint_creates_pipeline_with_dry_run?(@project)
+ pipeline = Ci::CreatePipelineService
+ .new(@project, current_user, ref: @project.default_branch)
+ .execute(:push, dry_run: true, content: @content)
+
+ @status = pipeline.error_messages.empty?
+ @stages = pipeline.stages
+ @errors = pipeline.error_messages.map(&:content)
+ @warnings = pipeline.warning_messages.map(&:content)
+ else
+ result = Gitlab::Ci::YamlProcessor.new_with_validation_errors(@content, yaml_processor_options)
+
+ @status = result.valid?
+ @errors = result.errors
+ @warnings = result.warnings
+
+ if result.valid?
+ @config_processor = result.config
+ @stages = @config_processor.stages
+ @builds = @config_processor.builds
+ @jobs = @config_processor.jobs
+ end
end
render :show
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 3f2dc9b09fa..b0c6f3cc6a1 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -15,8 +15,8 @@ class Projects::CommitController < Projects::ApplicationController
before_action :authorize_download_code!
before_action :authorize_read_pipeline!, only: [:pipelines]
before_action :commit
- before_action :define_commit_vars, only: [:show, :diff_for_path, :pipelines, :merge_requests]
- before_action :define_note_vars, only: [:show, :diff_for_path]
+ before_action :define_commit_vars, only: [:show, :diff_for_path, :diff_files, :pipelines, :merge_requests]
+ before_action :define_note_vars, only: [:show, :diff_for_path, :diff_files]
before_action :authorize_edit_tree!, only: [:revert, :cherry_pick]
BRANCH_SEARCH_LIMIT = 1000
@@ -41,6 +41,10 @@ class Projects::CommitController < Projects::ApplicationController
render_diff_for_path(@commit.diffs(diff_options))
end
+ def diff_files
+ render json: { html: view_to_html_string('projects/commit/diff_files', diffs: @diffs, environment: @environment) }
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def pipelines
@pipelines = @commit.pipelines.order(id: :desc)
diff --git a/app/controllers/projects/cycle_analytics/events_controller.rb b/app/controllers/projects/cycle_analytics/events_controller.rb
index 673f53c221b..c69bf029c73 100644
--- a/app/controllers/projects/cycle_analytics/events_controller.rb
+++ b/app/controllers/projects/cycle_analytics/events_controller.rb
@@ -4,6 +4,7 @@ module Projects
module CycleAnalytics
class EventsController < Projects::ApplicationController
include CycleAnalyticsParams
+ include GracefulTimeoutHandling
before_action :authorize_read_cycle_analytics!
before_action :authorize_read_build!, only: [:test, :staging]
diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb
index 898d888c978..ef97bc795f9 100644
--- a/app/controllers/projects/cycle_analytics_controller.rb
+++ b/app/controllers/projects/cycle_analytics_controller.rb
@@ -5,6 +5,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
include ActionView::Helpers::TextHelper
include CycleAnalyticsParams
include Analytics::UniqueVisitsHelper
+ include GracefulTimeoutHandling
before_action :whitelist_query_limiting, only: [:show]
before_action :authorize_read_cycle_analytics!
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index d5da24a76de..71195fdb892 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -13,6 +13,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
authorize_metrics_dashboard!
push_frontend_feature_flag(:prometheus_computed_alerts)
+ push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
end
before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
@@ -104,7 +105,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
action_or_env_url =
if stop_action
- polymorphic_url([project.namespace.becomes(Namespace), project, stop_action])
+ polymorphic_url([project, stop_action])
else
project_environment_url(project, @environment)
end
@@ -158,18 +159,14 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
def metrics_redirect
- environment = project.default_environment
-
- if environment
- redirect_to environment_metrics_path(environment)
- else
- render :empty_metrics
- end
+ redirect_to project_metrics_dashboard_path(project)
end
def metrics
respond_to do |format|
- format.html
+ format.html do
+ redirect_to project_metrics_dashboard_path(project, environment: environment )
+ end
format.json do
# Currently, this acts as a hint to load the metrics details into the cache
# if they aren't there already
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index b93f6384e0c..41631aea620 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -36,7 +36,19 @@ class Projects::ForksController < Projects::ApplicationController
end
def new
- @namespaces = fork_service.valid_fork_targets - [project.namespace]
+ respond_to do |format|
+ format.html do
+ @own_namespace = current_user.namespace if fork_service.valid_fork_targets.include?(current_user.namespace)
+ @project = project
+ end
+
+ format.json do
+ namespaces = fork_service.valid_fork_targets - [current_user.namespace, project.namespace]
+ render json: {
+ namespaces: ForkNamespaceSerializer.new.represent(namespaces, project: project, current_user: current_user)
+ }
+ end
+ end
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
new file mode 100644
index 00000000000..12cc4dde1f4
--- /dev/null
+++ b/app/controllers/projects/incidents_controller.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class Projects::IncidentsController < Projects::ApplicationController
+ before_action :authorize_read_incidents!
+
+ def index
+ end
+end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 12b5a538bc9..2200860a184 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -51,8 +51,10 @@ class Projects::IssuesController < Projects::ApplicationController
end
before_action only: :show do
- push_frontend_feature_flag(:real_time_issue_sidebar, @project)
- push_frontend_feature_flag(:confidential_apollo_sidebar, @project)
+ real_time_feature_flag = :real_time_issue_sidebar
+ real_time_enabled = Gitlab::ActionCable::Config.in_app? || Feature.enabled?(real_time_feature_flag, @project)
+
+ gon.push({ features: { real_time_feature_flag.to_s.camelize(:lower) => real_time_enabled } }, true)
end
before_action only: :index do
@@ -88,7 +90,7 @@ class Projects::IssuesController < Projects::ApplicationController
params[:issue] ||= ActionController::Parameters.new(
assignee_ids: ""
)
- build_params = issue_params.merge(
+ build_params = issue_create_params.merge(
merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of],
discussion_to_resolve: params[:discussion_to_resolve],
confidential: !!Gitlab::Utils.to_boolean(params[:issue][:confidential])
@@ -108,7 +110,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
def create
- create_params = issue_params.merge(spammable_params).merge(
+ create_params = issue_create_params.merge(spammable_params).merge(
merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of],
discussion_to_resolve: params[:discussion_to_resolve]
)
@@ -291,6 +293,16 @@ class Projects::IssuesController < Projects::ApplicationController
] + [{ label_ids: [], assignee_ids: [], update_task: [:index, :checked, :line_number, :line_source] }]
end
+ def issue_create_params
+ create_params = %i[
+ issue_type
+ ]
+
+ params.require(:issue).permit(
+ *create_params
+ ).merge(issue_params)
+ end
+
def reorder_params
params.permit(:move_before_id, :move_after_id, :group_full_path)
end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 98b0abc89e9..bceccc7063b 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -41,7 +41,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def diffs_metadata
diffs = @compare.diffs(diff_options)
- render json: DiffsMetadataSerializer.new(project: @merge_request.project)
+ render json: DiffsMetadataSerializer.new(project: @merge_request.project, current_user: current_user)
.represent(diffs, additional_attributes)
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 5d4514be838..e77d2f0f5ee 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -31,16 +31,19 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:suggest_pipeline) if experiment_enabled?(:suggest_pipeline)
push_frontend_feature_flag(:code_navigation, @project, default_enabled: true)
push_frontend_feature_flag(:widget_visibility_polling, @project, default_enabled: true)
- push_frontend_feature_flag(:merge_ref_head_comments, @project)
+ push_frontend_feature_flag(:merge_ref_head_comments, @project, default_enabled: true)
push_frontend_feature_flag(:mr_commit_neighbor_nav, @project, default_enabled: true)
- push_frontend_feature_flag(:multiline_comments, @project)
+ push_frontend_feature_flag(:multiline_comments, @project, default_enabled: true)
push_frontend_feature_flag(:file_identifier_hash)
push_frontend_feature_flag(:batch_suggestions, @project, default_enabled: true)
+ push_frontend_feature_flag(:auto_expand_collapsed_diffs, @project, default_enabled: true)
+ push_frontend_feature_flag(:approvals_commented_by, @project, default_enabled: true)
+ push_frontend_feature_flag(:hide_jump_to_next_unresolved_in_threads, default_enabled: true)
+ push_frontend_feature_flag(:merge_request_widget_graphql, @project)
end
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
- push_frontend_feature_flag(:junit_pipeline_view, @project.group)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
@@ -80,7 +83,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@note = @project.notes.new(noteable: @merge_request)
@noteable = @merge_request
- @commits_count = @merge_request.commits_count
+ @commits_count = @merge_request.commits_count + @merge_request.context_commits_count
@issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
@current_user_data = UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestUserEntity).to_json
@show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
@@ -114,6 +117,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def commits
+ # Get context commits from repository
+ @context_commits =
+ set_commits_for_rendering(
+ @merge_request.recent_context_commits
+ )
+
# Get commits from repository
# or from cache if already merged
@commits =
@@ -403,7 +412,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
return access_denied! unless @merge_request.source_branch_exists?
access_check = ::Gitlab::UserAccess
- .new(current_user, project: @merge_request.source_project)
+ .new(current_user, container: @merge_request.source_project)
.can_push_to_branch?(@merge_request.source_branch)
access_denied! unless access_check
diff --git a/app/controllers/projects/metrics/dashboards/builder_controller.rb b/app/controllers/projects/metrics/dashboards/builder_controller.rb
new file mode 100644
index 00000000000..2ab574d7d10
--- /dev/null
+++ b/app/controllers/projects/metrics/dashboards/builder_controller.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Projects
+ module Metrics
+ module Dashboards
+ class BuilderController < Projects::ApplicationController
+ before_action :authorize_metrics_dashboard!
+
+ def panel_preview
+ respond_to do |format|
+ format.json do
+ if rendered_panel.success?
+ render json: rendered_panel.payload
+ else
+ render json: { message: rendered_panel.message }, status: :unprocessable_entity
+ end
+ end
+ end
+ end
+
+ private
+
+ def rendered_panel
+ @panel_preview ||= ::Metrics::Dashboard::PanelPreviewService.new(project, panel_yaml, environment).execute
+ end
+
+ def panel_yaml
+ params.require(:panel_yaml)
+ end
+
+ def environment
+ @environment ||=
+ if params[:environment]
+ project.environments.find(params[:environment])
+ else
+ project.default_environment
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb
index 235ee1dfbf2..51307c3665c 100644
--- a/app/controllers/projects/metrics_dashboard_controller.rb
+++ b/app/controllers/projects/metrics_dashboard_controller.rb
@@ -9,13 +9,14 @@ module Projects
before_action :authorize_metrics_dashboard!
before_action do
push_frontend_feature_flag(:prometheus_computed_alerts)
+ push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
end
def show
if environment
render 'projects/environments/metrics'
else
- render_404
+ render 'projects/environments/empty_metrics'
end
end
diff --git a/app/controllers/projects/packages/package_files_controller.rb b/app/controllers/projects/packages/package_files_controller.rb
new file mode 100644
index 00000000000..dd6d875cd1e
--- /dev/null
+++ b/app/controllers/projects/packages/package_files_controller.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Projects
+ module Packages
+ class PackageFilesController < ApplicationController
+ include PackagesAccess
+ include SendFileUpload
+
+ def download
+ package_file = project.package_files.find(params[:id])
+
+ send_upload(package_file.file, attachment: package_file.file_name)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/packages/packages_controller.rb b/app/controllers/projects/packages/packages_controller.rb
new file mode 100644
index 00000000000..fc4ef7a01dc
--- /dev/null
+++ b/app/controllers/projects/packages/packages_controller.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Projects
+ module Packages
+ class PackagesController < Projects::ApplicationController
+ include PackagesAccess
+
+ before_action :authorize_destroy_package!, only: [:destroy]
+
+ def show
+ @package = project.packages.find(params[:id])
+ @package_files = @package.package_files.recent
+ @maven_metadatum = @package.maven_metadatum
+ end
+
+ def destroy
+ @package = project.packages.find(params[:id])
+ @package.destroy
+
+ redirect_to project_packages_path(@project), status: :found, notice: _('Package was removed')
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb
index f03274bf32e..1c212964df5 100644
--- a/app/controllers/projects/pipelines/tests_controller.rb
+++ b/app/controllers/projects/pipelines/tests_controller.rb
@@ -3,7 +3,6 @@
module Projects
module Pipelines
class TestsController < Projects::Pipelines::ApplicationController
- before_action :validate_feature_flag!
before_action :authorize_read_build!
before_action :builds, only: [:show]
@@ -29,29 +28,21 @@ module Projects
private
- def validate_feature_flag!
- render_404 unless Feature.enabled?(:build_report_summary, project)
- end
-
# rubocop: disable CodeReuse/ActiveRecord
def builds
- pipeline.latest_builds.where(id: build_params)
+ @builds ||= pipeline.latest_builds.for_ids(build_ids).presence || render_404
end
- def build_params
+ def build_ids
return [] unless params[:build_ids]
params[:build_ids].split(",")
end
def test_suite
- if builds.present?
- builds.map do |build|
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
- end.sum
- else
- render_404
- end
+ builds.map do |build|
+ build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
+ end.sum
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index d8e11ddd423..bfe23eb1035 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -12,11 +12,10 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
- push_frontend_feature_flag(:junit_pipeline_view, project)
- push_frontend_feature_flag(:build_report_summary, project)
push_frontend_feature_flag(:filter_pipelines_search, project, default_enabled: true)
push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: true)
push_frontend_feature_flag(:pipelines_security_report_summary, project)
+ push_frontend_feature_flag(:new_pipeline_form)
end
before_action :ensure_pipeline, only: [:show]
@@ -177,8 +176,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def test_report
- return unless Feature.enabled?(:junit_pipeline_view, project)
-
respond_to do |format|
format.html do
render 'show'
@@ -192,12 +189,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
end
- def test_reports_count
- return unless Feature.enabled?(:junit_pipeline_view, project)
-
- render json: { total_count: pipeline.test_reports_count }.to_json
- end
-
private
def serialize_pipelines
diff --git a/app/controllers/projects/product_analytics_controller.rb b/app/controllers/projects/product_analytics_controller.rb
new file mode 100644
index 00000000000..badd7671dcf
--- /dev/null
+++ b/app/controllers/projects/product_analytics_controller.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+class Projects::ProductAnalyticsController < Projects::ApplicationController
+ before_action :feature_enabled!
+ before_action :authorize_read_product_analytics!
+ before_action :tracker_variables, only: [:setup, :test]
+
+ def index
+ @events = product_analytics_events.order_by_time.page(params[:page])
+ end
+
+ def setup
+ end
+
+ def test
+ @event = product_analytics_events.try(:first)
+ end
+
+ def graphs
+ @graphs = []
+ @timerange = 30
+
+ requested_graphs = %w(platform os_timezone br_lang doc_charset)
+
+ requested_graphs.each do |graph|
+ @graphs << ProductAnalytics::BuildGraphService
+ .new(project, { graph: graph, timerange: @timerange })
+ .execute
+ end
+ end
+
+ private
+
+ def product_analytics_events
+ @project.product_analytics_events
+ end
+
+ def tracker_variables
+ # We use project id as Snowplow appId
+ @project_id = @project.id.to_s
+
+ # Snowplow remembers values like appId and platform between reloads.
+ # That is why we have to rename the tracker with a random integer.
+ @random = rand(999999)
+
+ # Generate random platform every time a tracker is rendered.
+ @platform = %w(web mob app)[(@random % 3)]
+ end
+
+ def feature_enabled!
+ render_404 unless Feature.enabled?(:product_analytics, @project, default_enabled: false)
+ end
+end
diff --git a/app/controllers/projects/prometheus/alerts_controller.rb b/app/controllers/projects/prometheus/alerts_controller.rb
index 2c0521edece..c6ae65f7832 100644
--- a/app/controllers/projects/prometheus/alerts_controller.rb
+++ b/app/controllers/projects/prometheus/alerts_controller.rb
@@ -39,7 +39,7 @@ module Projects
render json: serialize_as_json(@alert)
else
- head :no_content
+ head :bad_request
end
end
@@ -49,7 +49,7 @@ module Projects
render json: serialize_as_json(alert)
else
- head :no_content
+ head :bad_request
end
end
@@ -59,14 +59,14 @@ module Projects
head :ok
else
- head :no_content
+ head :bad_request
end
end
private
def alerts_params
- params.permit(:operator, :threshold, :environment_id, :prometheus_metric_id)
+ params.permit(:operator, :threshold, :environment_id, :prometheus_metric_id, :runbook_url)
end
def notify_service
diff --git a/app/controllers/projects/protected_refs_controller.rb b/app/controllers/projects/protected_refs_controller.rb
index d9921757502..060403a9cd9 100644
--- a/app/controllers/projects/protected_refs_controller.rb
+++ b/app/controllers/projects/protected_refs_controller.rb
@@ -62,7 +62,7 @@ class Projects::ProtectedRefsController < Projects::ApplicationController
end
def access_level_attributes
- %i[access_level id]
+ %i[access_level id _destroy]
end
end
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index d58755c2655..c48d573edbf 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -29,7 +29,7 @@ class Projects::ReleasesController < Projects::ApplicationController
end
def new
- unless Feature.enabled?(:new_release_page, project)
+ unless Feature.enabled?(:new_release_page, project, default_enabled: true)
redirect_to(new_project_tag_path(@project))
end
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 6b7e253595c..ca2a19e67b0 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -12,7 +12,6 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :set_deprecation_notice_for_prometheus_service, only: [:edit, :update]
before_action :redirect_deprecated_prometheus_service, only: [:update]
before_action only: :edit do
- push_frontend_feature_flag(:integration_form_refactor, default_enabled: true)
push_frontend_feature_flag(:jira_issues_integration, @project, { default_enabled: true })
end
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index d7a6f1b0139..781b850ddfe 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -6,10 +6,6 @@ module Projects
before_action :authorize_admin_operations!
before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token]
- before_action do
- push_frontend_feature_flag(:pagerduty_webhook, project)
- end
-
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
helper_method :error_tracking_setting
@@ -49,7 +45,7 @@ module Projects
if result[:status] == :success
pagerduty_token = project.incident_management_setting&.pagerduty_token
- webhook_url = project_incidents_pagerduty_url(project, token: pagerduty_token)
+ webhook_url = project_incidents_integrations_pagerduty_url(project, token: pagerduty_token)
render json: { pagerduty_webhook_url: webhook_url, pagerduty_token: pagerduty_token }
else
diff --git a/app/controllers/projects/snippets/blobs_controller.rb b/app/controllers/projects/snippets/blobs_controller.rb
index 148fc7c96f8..eaec8600d77 100644
--- a/app/controllers/projects/snippets/blobs_controller.rb
+++ b/app/controllers/projects/snippets/blobs_controller.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class Projects::Snippets::BlobsController < Projects::Snippets::ApplicationController
- include Snippets::BlobsActions
+ include ::Snippets::BlobsActions
end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 49840e847f2..632e8db9796 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -14,6 +14,10 @@ class Projects::SnippetsController < Projects::Snippets::ApplicationController
before_action :authorize_update_snippet!, only: [:edit, :update]
before_action :authorize_admin_snippet!, only: [:destroy]
+ before_action do
+ push_frontend_feature_flag(:snippet_multiple_files, current_user)
+ end
+
def index
@snippet_counts = ::Snippets::CountService
.new(current_user, project: @project)
diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb
index 2cc030d18fc..0fd047f90cf 100644
--- a/app/controllers/projects/variables_controller.rb
+++ b/app/controllers/projects/variables_controller.rb
@@ -12,7 +12,12 @@ class Projects::VariablesController < Projects::ApplicationController
end
def update
- if @project.update(variables_params)
+ update_result = Ci::ChangeVariablesService.new(
+ container: @project, current_user: current_user,
+ params: variables_params
+ ).execute
+
+ if update_result
respond_to do |format|
format.json { render_variables }
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a5666cb70ac..ba21fbddde1 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -38,9 +38,16 @@ class ProjectsController < Projects::ApplicationController
before_action only: [:new, :create] do
frontend_experimentation_tracking_data(:new_create_project_ui, 'click_tab')
push_frontend_feature_flag(:new_create_project_ui) if experiment_enabled?(:new_create_project_ui)
+ end
+
+ before_action only: [:edit] do
push_frontend_feature_flag(:service_desk_custom_address, @project)
end
+ before_action only: [:edit] do
+ push_frontend_feature_flag(:approval_suggestions, @project)
+ end
+
layout :determine_layout
def index
@@ -392,6 +399,7 @@ class ProjectsController < Projects::ApplicationController
:initialize_with_readme,
:autoclose_referenced_issues,
:suggestion_commit_message,
+ :packages_enabled,
:service_desk_enabled,
project_feature_attributes: %i[
diff --git a/app/controllers/registrations/experience_levels_controller.rb b/app/controllers/registrations/experience_levels_controller.rb
index 97239b1bbac..5bb039bd9ba 100644
--- a/app/controllers/registrations/experience_levels_controller.rb
+++ b/app/controllers/registrations/experience_levels_controller.rb
@@ -2,9 +2,7 @@
module Registrations
class ExperienceLevelsController < ApplicationController
- # This will need to be changed to simply 'devise' as part of
- # https://gitlab.com/gitlab-org/growth/engineering/issues/64
- layout 'devise_experimental_separate_sign_up_flow'
+ layout 'devise_experimental_onboarding_issues'
before_action :check_experiment_enabled
before_action :ensure_namespace_path_param
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index b1c1fe3ba74..2a865aac767 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -17,7 +17,8 @@ class RegistrationsController < Devise::RegistrationsController
def new
if experiment_enabled?(:signup_flow)
- track_experiment_event(:signup_flow, 'start') # We want this event to be tracked when the user is _in_ the experimental group
+ track_experiment_event(:terms_opt_in, 'start')
+
@resource = build_resource
else
redirect_to new_user_session_path(anchor: 'register-pane')
@@ -25,8 +26,7 @@ class RegistrationsController < Devise::RegistrationsController
end
def create
- track_experiment_event(:signup_flow, 'end') unless experiment_enabled?(:signup_flow) # We want this event to be tracked when the user is _in_ the control group
-
+ track_experiment_event(:terms_opt_in, 'end')
accept_pending_invitations
super do |new_user|
@@ -62,9 +62,11 @@ class RegistrationsController < Devise::RegistrationsController
result = ::Users::SignupService.new(current_user, user_params).execute
if result[:status] == :success
- track_experiment_event(:signup_flow, 'end') # We want this event to be tracked when the user is _in_ the experimental group
+ if ::Gitlab.com? && show_onboarding_issues_experiment?
+ track_experiment_event(:onboarding_issues, 'signed_up')
+ record_experiment_user(:onboarding_issues)
+ end
- track_experiment_event(:onboarding_issues, 'signed_up') if ::Gitlab.com? && show_onboarding_issues_experiment?
return redirect_to new_users_sign_up_group_path if experiment_enabled?(:onboarding_issues) && show_onboarding_issues_experiment?
set_flash_message! :notice, :signed_up
@@ -178,6 +180,8 @@ class RegistrationsController < Devise::RegistrationsController
end
def terms_accepted?
+ return true if experiment_enabled?(:terms_opt_in)
+
Gitlab::Utils.to_boolean(params[:terms_opt_in])
end
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index 6a27d63625e..aa6609bef2a 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -105,7 +105,7 @@ module Repositories
access.check(git_command, Gitlab::GitAccess::ANY)
if repo_type.project? && !container
- @project = @container = access.project
+ @project = @container = access.container
end
end
diff --git a/app/controllers/repositories/lfs_storage_controller.rb b/app/controllers/repositories/lfs_storage_controller.rb
index ec5ca5bbeec..0436b740979 100644
--- a/app/controllers/repositories/lfs_storage_controller.rb
+++ b/app/controllers/repositories/lfs_storage_controller.rb
@@ -73,9 +73,8 @@ module Repositories
# rubocop: enable CodeReuse/ActiveRecord
def create_file!(oid, size)
- uploaded_file = UploadedFile.from_params(
- params, :file, LfsObjectUploader.workhorse_local_upload_path)
- return unless uploaded_file
+ uploaded_file = params[:file]
+ return unless uploaded_file.is_a?(UploadedFile)
LfsObject.create!(oid: oid, size: size, file: uploaded_file)
end
diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb
index 14469877e14..191134472c2 100644
--- a/app/controllers/root_controller.rb
+++ b/app/controllers/root_controller.rb
@@ -13,6 +13,7 @@ class RootController < Dashboard::ProjectsController
before_action :redirect_unlogged_user, if: -> { current_user.nil? }
before_action :redirect_logged_user, if: -> { current_user.present? }
+ before_action :customize_homepage, only: :index, if: -> { current_user.present? }
# We only need to load the projects when the user is logged in but did not
# configure a dashboard. In which case we render projects. We can do that straight
# from the #index action.
@@ -66,6 +67,10 @@ class RootController < Dashboard::ProjectsController
root_urls.exclude?(home_page_url)
end
+
+ def customize_homepage
+ @customize_homepage = experiment_enabled?(:customize_homepage)
+ end
end
RootController.prepend_if_ee('EE::RootController')
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index ff6d9350a5c..56b6a5201e7 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -6,7 +6,8 @@ class SearchController < ApplicationController
include RendersCommits
SCOPE_PRELOAD_METHOD = {
- projects: :with_web_entity_associations
+ projects: :with_web_entity_associations,
+ issues: :with_web_entity_associations
}.freeze
around_action :allow_gitaly_ref_name_caching
@@ -113,4 +114,15 @@ class SearchController < ApplicationController
Gitlab::UsageDataCounters::SearchCounter.count(:navbar_searches)
end
+
+ def append_info_to_payload(payload)
+ super
+
+ # Merging to :metadata will ensure these are logged as top level keys
+ payload[:metadata] || {}
+ payload[:metadata]['meta.search.group_id'] = params[:group_id]
+ payload[:metadata]['meta.search.project_id'] = params[:project_id]
+ payload[:metadata]['meta.search.search'] = params[:search]
+ payload[:metadata]['meta.search.scope'] = params[:scope]
+ end
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 9e8075d4bcc..f82212591b6 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -25,7 +25,7 @@ class SessionsController < Devise::SessionsController
before_action :store_unauthenticated_sessions, only: [:new]
before_action :save_failed_login, if: :action_new_and_failed_login?
before_action :load_recaptcha
- before_action :frontend_tracking_data, only: [:new]
+ before_action :set_invite_params, only: [:new]
after_action :log_failed_login, if: :action_new_and_failed_login?
after_action :verify_known_sign_in, only: [:create]
@@ -293,9 +293,8 @@ class SessionsController < Devise::SessionsController
end
end
- def frontend_tracking_data
- # We want tracking data pushed to the frontend when the user is _in_ the control group
- frontend_experimentation_tracking_data(:signup_flow, 'start') unless experiment_enabled?(:signup_flow)
+ def set_invite_params
+ @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
end
end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index e68b821459d..486c7f1d028 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -17,6 +17,10 @@ class SnippetsController < Snippets::ApplicationController
layout 'snippets'
+ before_action do
+ push_frontend_feature_flag(:snippet_multiple_files, current_user)
+ end
+
def index
if params[:username].present?
@user = UserFinder.new(params[:username]).find_by_username!