summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /app/controllers
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
downloadgitlab-ce-b595cb0c1dec83de5bdee18284abe86614bed33b.tar.gz
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/application_settings_controller.rb11
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/admin/hooks_controller.rb51
-rw-r--r--app/controllers/admin/system_info_controller.rb3
-rw-r--r--app/controllers/admin/topics_controller.rb10
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/clusters/clusters_controller.rb1
-rw-r--r--app/controllers/concerns/google_analytics_csp.rb24
-rw-r--r--app/controllers/concerns/harbor/access.rb27
-rw-r--r--app/controllers/concerns/harbor/artifact.rb41
-rw-r--r--app/controllers/concerns/harbor/repository.rb51
-rw-r--r--app/controllers/concerns/harbor/tag.rb41
-rw-r--r--app/controllers/concerns/integrations/hooks_execution.rb60
-rw-r--r--app/controllers/concerns/integrations/params.rb1
-rw-r--r--app/controllers/concerns/issuable_actions.rb1
-rw-r--r--app/controllers/concerns/issuable_collections.rb11
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb5
-rw-r--r--app/controllers/concerns/verifies_with_email.rb194
-rw-r--r--app/controllers/confirmations_controller.rb1
-rw-r--r--app/controllers/graphql_controller.rb7
-rw-r--r--app/controllers/groups/harbor/application_controller.rb16
-rw-r--r--app/controllers/groups/harbor/artifacts_controller.rb15
-rw-r--r--app/controllers/groups/harbor/repositories_controller.rb17
-rw-r--r--app/controllers/groups/harbor/tags_controller.rb15
-rw-r--r--app/controllers/groups/registry/repositories_controller.rb4
-rw-r--r--app/controllers/import/bitbucket_controller.rb15
-rw-r--r--app/controllers/import/bitbucket_server_controller.rb7
-rw-r--r--app/controllers/import/bulk_imports_controller.rb8
-rw-r--r--app/controllers/import/fogbugz_controller.rb10
-rw-r--r--app/controllers/import/gitea_controller.rb2
-rw-r--r--app/controllers/import/github_controller.rb16
-rw-r--r--app/controllers/import/gitlab_controller.rb6
-rw-r--r--app/controllers/jira_connect/oauth_application_ids_controller.rb9
-rw-r--r--app/controllers/jira_connect/subscriptions_controller.rb8
-rw-r--r--app/controllers/ldap/omniauth_callbacks_controller.rb16
-rw-r--r--app/controllers/oauth/applications_controller.rb6
-rw-r--r--app/controllers/oauth/authorizations_controller.rb2
-rw-r--r--app/controllers/profiles/personal_access_tokens_controller.rb29
-rw-r--r--app/controllers/projects/blame_controller.rb2
-rw-r--r--app/controllers/projects/blob_controller.rb1
-rw-r--r--app/controllers/projects/environments_controller.rb3
-rw-r--r--app/controllers/projects/google_cloud/base_controller.rb18
-rw-r--r--app/controllers/projects/google_cloud/configuration_controller.rb38
-rw-r--r--app/controllers/projects/google_cloud/databases_controller.rb18
-rw-r--r--app/controllers/projects/google_cloud/deployments_controller.rb31
-rw-r--r--app/controllers/projects/google_cloud/gcp_regions_controller.rb12
-rw-r--r--app/controllers/projects/google_cloud/revoke_oauth_controller.rb7
-rw-r--r--app/controllers/projects/google_cloud/service_accounts_controller.rb25
-rw-r--r--app/controllers/projects/google_cloud_controller.rb34
-rw-r--r--app/controllers/projects/group_links_controller.rb2
-rw-r--r--app/controllers/projects/harbor/application_controller.rb12
-rw-r--r--app/controllers/projects/harbor/artifacts_controller.rb15
-rw-r--r--app/controllers/projects/harbor/repositories_controller.rb8
-rw-r--r--app/controllers/projects/harbor/tags_controller.rb15
-rw-r--r--app/controllers/projects/hooks_controller.rb51
-rw-r--r--app/controllers/projects/incidents_controller.rb3
-rw-r--r--app/controllers/projects/issues_controller.rb5
-rw-r--r--app/controllers/projects/jobs_controller.rb26
-rw-r--r--app/controllers/projects/logs_controller.rb103
-rw-r--r--app/controllers/projects/merge_requests_controller.rb5
-rw-r--r--app/controllers/projects/metrics_dashboard_controller.rb1
-rw-r--r--app/controllers/projects/pipelines/tests_controller.rb19
-rw-r--r--app/controllers/projects/pipelines_controller.rb12
-rw-r--r--app/controllers/projects/project_members_controller.rb4
-rw-r--r--app/controllers/projects/registry/repositories_controller.rb4
-rw-r--r--app/controllers/projects/service_ping_controller.rb3
-rw-r--r--app/controllers/projects/settings/integrations_controller.rb5
-rw-r--r--app/controllers/projects/settings/operations_controller.rb18
-rw-r--r--app/controllers/projects/tags/releases_controller.rb2
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/controllers/projects/tracings_controller.rb30
-rw-r--r--app/controllers/projects/tree_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/controllers/registrations/welcome_controller.rb1
-rw-r--r--app/controllers/registrations_controller.rb3
-rw-r--r--app/controllers/search_controller.rb34
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/controllers/users/terms_controller.rb5
-rw-r--r--app/controllers/users_controller.rb8
79 files changed, 887 insertions, 449 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 7f95b136e4e..e05e87ffd89 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -28,7 +28,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:create_self_monitoring_project,
:status_create_self_monitoring_project,
:delete_self_monitoring_project,
- :status_delete_self_monitoring_project
+ :status_delete_self_monitoring_project,
+ :reset_error_tracking_access_token
]
feature_category :source_code_management, [:repository, :clear_repository_check_states]
@@ -37,6 +38,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
feature_category :service_ping, [:usage_data, :service_usage_data]
feature_category :integrations, [:integrations]
feature_category :pages, [:lets_encrypt_terms_of_service]
+ feature_category :error_tracking, [:reset_error_tracking_access_token]
VALID_SETTING_PANELS = %w(general repository
ci_cd reporting metrics_and_profiling
@@ -96,6 +98,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_back_or_default
end
+ def reset_error_tracking_access_token
+ @application_setting.reset_error_tracking_access_token!
+
+ redirect_to general_admin_application_settings_path,
+ notice: _('New error tracking access token has been generated!')
+ end
+
def clear_repository_check_states
RepositoryCheck::ClearWorker.perform_async # rubocop:disable CodeReuse/Worker
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index 865af244773..bf573d45852 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -5,7 +5,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
before_action :finder, only: [:edit, :update, :destroy]
- feature_category :navigation
+ feature_category :onboarding
urgency :low
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index 6f5475a4a78..810801d4209 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -8,40 +8,6 @@ class Admin::HooksController < Admin::ApplicationController
feature_category :integrations
urgency :low, [:test]
- def index
- @hooks = SystemHook.all.load
- @hook = SystemHook.new
- end
-
- def create
- @hook = SystemHook.new(hook_params.to_h)
-
- if @hook.save
- redirect_to admin_hooks_path, notice: _('Hook was successfully created.')
- else
- @hooks = SystemHook.all
- render :index
- end
- end
-
- def edit
- end
-
- def update
- if hook.update(hook_params)
- flash[:notice] = _('System hook was successfully updated.')
- redirect_to admin_hooks_path
- else
- render 'edit'
- end
- end
-
- def destroy
- destroy_hook(hook)
-
- redirect_to admin_hooks_path, status: :found
- end
-
def test
result = TestHooks::SystemService.new(hook, current_user, params[:trigger]).execute
@@ -52,6 +18,10 @@ class Admin::HooksController < Admin::ApplicationController
private
+ def relation
+ SystemHook
+ end
+
def hook
@hook ||= SystemHook.find(params[:id])
end
@@ -60,12 +30,11 @@ class Admin::HooksController < Admin::ApplicationController
@hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
end
- def hook_params
- params.require(:hook).permit(
- :enable_ssl_verification,
- :token,
- :url,
- *SystemHook.triggers.values
- )
+ def hook_param_names
+ %i[enable_ssl_verification token url]
+ end
+
+ def trigger_values
+ SystemHook.triggers.values
end
end
diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb
index 7ae930abb84..f81b02ad31f 100644
--- a/app/controllers/admin/system_info_controller.rb
+++ b/app/controllers/admin/system_info_controller.rb
@@ -12,7 +12,10 @@ class Admin::SystemInfoController < Admin::ApplicationController
EXCLUDED_MOUNT_TYPES = [
'autofs',
'binfmt_misc',
+ 'bpf',
'cgroup',
+ 'cgroup2',
+ 'configfs',
'debugfs',
'devfs',
'devpts',
diff --git a/app/controllers/admin/topics_controller.rb b/app/controllers/admin/topics_controller.rb
index 908313bdb83..b451928e591 100644
--- a/app/controllers/admin/topics_controller.rb
+++ b/app/controllers/admin/topics_controller.rb
@@ -4,7 +4,7 @@ class Admin::TopicsController < Admin::ApplicationController
include SendFileUpload
include PreviewMarkdown
- before_action :topic, only: [:edit, :update]
+ before_action :topic, only: [:edit, :update, :destroy]
feature_category :projects
@@ -37,6 +37,14 @@ class Admin::TopicsController < Admin::ApplicationController
end
end
+ def destroy
+ @topic.destroy!
+
+ redirect_to admin_topics_path,
+ status: :found,
+ notice: _('Topic %{topic_name} was successfully removed.') % { topic_name: @topic.title_or_name }
+ end
+
private
def topic
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 30760d472a4..71d9910b4b8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -179,6 +179,10 @@ class ApplicationController < ActionController::Base
payload[:queue_duration_s] = request.env[::Gitlab::Middleware::RailsQueueDuration::GITLAB_RAILS_QUEUE_DURATION_KEY]
+ if Feature.enabled?(:log_response_length)
+ payload[:response_bytes] = response.body_parts.sum(&:bytesize)
+ end
+
store_cloudflare_headers!(payload, request)
end
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index a04fd09aa22..51150700860 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -50,7 +50,6 @@ class Clusters::ClustersController < Clusters::BaseController
def show
if params[:tab] == 'integrations'
@prometheus_integration = Clusters::IntegrationPresenter.new(@cluster.find_or_build_integration_prometheus)
- @elastic_stack_integration = Clusters::IntegrationPresenter.new(@cluster.find_or_build_integration_elastic_stack)
end
end
diff --git a/app/controllers/concerns/google_analytics_csp.rb b/app/controllers/concerns/google_analytics_csp.rb
new file mode 100644
index 00000000000..1a8e405928d
--- /dev/null
+++ b/app/controllers/concerns/google_analytics_csp.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module GoogleAnalyticsCSP
+ extend ActiveSupport::Concern
+
+ included do
+ content_security_policy do |policy|
+ next unless helpers.google_tag_manager_enabled? || policy.directives.present?
+
+ default_script_src = policy.directives['script-src'] || policy.directives['default-src']
+ script_src_values = Array.wrap(default_script_src) | ['*.googletagmanager.com']
+ policy.script_src(*script_src_values)
+
+ default_img_src = policy.directives['img-src'] || policy.directives['default-src']
+ img_src_values = Array.wrap(default_img_src) | ['*.google-analytics.com', '*.googletagmanager.com']
+ policy.img_src(*img_src_values)
+
+ default_connect_src = policy.directives['connect-src'] || policy.directives['default-src']
+ connect_src_values =
+ Array.wrap(default_connect_src) | ['*.google-analytics.com', '*.analytics.google.com', '*.googletagmanager.com']
+ policy.connect_src(*connect_src_values)
+ end
+ end
+end
diff --git a/app/controllers/concerns/harbor/access.rb b/app/controllers/concerns/harbor/access.rb
new file mode 100644
index 00000000000..70de72f15fc
--- /dev/null
+++ b/app/controllers/concerns/harbor/access.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Harbor
+ module Access
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :harbor_registry_enabled!
+ before_action :authorize_read_harbor_registry!
+ before_action do
+ push_frontend_feature_flag(:harbor_registry_integration)
+ end
+
+ feature_category :integrations
+ end
+
+ private
+
+ def harbor_registry_enabled!
+ render_404 unless Feature.enabled?(:harbor_registry_integration)
+ end
+
+ def authorize_read_harbor_registry!
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/app/controllers/concerns/harbor/artifact.rb b/app/controllers/concerns/harbor/artifact.rb
new file mode 100644
index 00000000000..c9d7d26fbb9
--- /dev/null
+++ b/app/controllers/concerns/harbor/artifact.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Harbor
+ module Artifact
+ def index
+ respond_to do |format|
+ format.json do
+ artifacts
+ end
+ end
+ end
+
+ private
+
+ def query_params
+ params.permit(:repository_id, :search, :sort, :page, :limit)
+ end
+
+ def query
+ Gitlab::Harbor::Query.new(container.harbor_integration, query_params)
+ end
+
+ def artifacts
+ unless query.valid?
+ return render(
+ json: { message: 'Invalid parameters', errors: query.errors },
+ status: :unprocessable_entity
+ )
+ end
+
+ artifacts_json = ::Integrations::HarborSerializers::ArtifactSerializer.new
+ .with_pagination(request, response)
+ .represent(query.artifacts)
+ render json: artifacts_json
+ end
+
+ def container
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/app/controllers/concerns/harbor/repository.rb b/app/controllers/concerns/harbor/repository.rb
new file mode 100644
index 00000000000..0e541e2172e
--- /dev/null
+++ b/app/controllers/concerns/harbor/repository.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Harbor
+ module Repository
+ def index
+ respond_to do |format|
+ format.html
+ format.json do
+ repositories
+ end
+ end
+ end
+
+ # The show action renders index to allow frontend routing to work on page refresh
+ def show
+ render :index
+ end
+
+ private
+
+ def query_params
+ params.permit(:search, :sort, :page, :limit)
+ end
+
+ def query
+ Gitlab::Harbor::Query.new(container.harbor_integration, query_params)
+ end
+
+ def repositories
+ unless query.valid?
+ return render(
+ json: { message: 'Invalid parameters', errors: query.errors },
+ status: :unprocessable_entity
+ )
+ end
+
+ repositories_json = ::Integrations::HarborSerializers::RepositorySerializer.new
+ .with_pagination(request, response)
+ .represent(
+ query.repositories,
+ url: container.harbor_integration.url,
+ project_name: container.harbor_integration.project_name
+ )
+ render json: repositories_json
+ end
+
+ def container
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/app/controllers/concerns/harbor/tag.rb b/app/controllers/concerns/harbor/tag.rb
new file mode 100644
index 00000000000..e0c00d1155a
--- /dev/null
+++ b/app/controllers/concerns/harbor/tag.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Harbor
+ module Tag
+ def index
+ respond_to do |format|
+ format.json do
+ tags
+ end
+ end
+ end
+
+ private
+
+ def query_params
+ params.permit(:repository_id, :artifact_id, :sort, :page, :limit)
+ end
+
+ def query
+ Gitlab::Harbor::Query.new(container.harbor_integration, query_params)
+ end
+
+ def tags
+ unless query.valid?
+ return render(
+ json: { message: 'Invalid parameters', errors: query.errors },
+ status: :unprocessable_entity
+ )
+ end
+
+ tags_json = ::Integrations::HarborSerializers::TagSerializer.new
+ .with_pagination(request, response)
+ .represent(query.tags)
+ render json: tags_json
+ end
+
+ def container
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/app/controllers/concerns/integrations/hooks_execution.rb b/app/controllers/concerns/integrations/hooks_execution.rb
index 6a9d3d51f9b..fb26840168f 100644
--- a/app/controllers/concerns/integrations/hooks_execution.rb
+++ b/app/controllers/concerns/integrations/hooks_execution.rb
@@ -3,8 +3,68 @@
module Integrations::HooksExecution
extend ActiveSupport::Concern
+ included do
+ attr_writer :hooks, :hook
+ end
+
+ def index
+ self.hooks = relation.select(&:persisted?)
+ self.hook = relation.new
+ end
+
+ def create
+ self.hook = relation.new(hook_params)
+ hook.save
+
+ unless hook.valid?
+ self.hooks = relation.select(&:persisted?)
+ flash[:alert] = hook.errors.full_messages.join.html_safe
+ end
+
+ redirect_to action: :index
+ end
+
+ def update
+ if hook.update(hook_params)
+ flash[:notice] = _('Hook was successfully updated.')
+ redirect_to action: :index
+ else
+ render 'edit'
+ end
+ end
+
+ def destroy
+ destroy_hook(hook)
+
+ redirect_to action: :index, status: :found
+ end
+
+ def edit
+ redirect_to(action: :index) unless hook
+ end
+
private
+ def hook_params
+ permitted = hook_param_names + trigger_values
+ permitted << { url_variables: [:key, :value] }
+
+ ps = params.require(:hook).permit(*permitted).to_h
+
+ ps[:url_variables] = ps[:url_variables].to_h { [_1[:key], _1[:value].presence] } if ps.key?(:url_variables)
+
+ if action_name == 'update' && ps.key?(:url_variables)
+ supplied = ps[:url_variables]
+ ps[:url_variables] = hook.url_variables.merge(supplied).compact
+ end
+
+ ps
+ end
+
+ def hook_param_names
+ %i[enable_ssl_verification token url push_events_branch_filter]
+ end
+
def destroy_hook(hook)
result = WebHooks::DestroyService.new(current_user).execute(hook)
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index d256b331174..c3ad9d3dff3 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -6,7 +6,6 @@ module Integrations
ALLOWED_PARAMS_CE = [
:active,
- :add_pusher,
:alert_events,
:api_key,
:api_token,
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 07850acd23d..a5e49b1b16a 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -184,7 +184,6 @@ module IssuableActions
def paginated_discussions
return if params[:per_page].blank?
- return if issuable.instance_of?(Issue) && Feature.disabled?(:paginated_issue_discussions, project)
return if issuable.instance_of?(MergeRequest) && Feature.disabled?(:paginated_mr_discussions, project)
strong_memoize(:paginated_discussions) do
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 4841225de08..de38d26e3fe 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -24,12 +24,9 @@ module IssuableCollections
show_alert_if_search_is_disabled
@issuables = issuables_collection
+ set_pagination
- unless pagination_disabled?
- set_pagination
-
- return if redirect_out_of_range(@issuables, @total_pages)
- end
+ return if redirect_out_of_range(@issuables, @total_pages)
if params[:label_name].present? && @project
labels_params = { project_id: @project.id, title: params[:label_name] }
@@ -59,10 +56,6 @@ module IssuableCollections
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
- def pagination_disabled?
- false
- end
-
# rubocop: disable CodeReuse/ActiveRecord
def issuables_collection
finder.execute.preload(preload_for_collection)
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
index 0b51b3dd380..dc7ba8295b9 100644
--- a/app/controllers/concerns/product_analytics_tracking.rb
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -28,7 +28,10 @@ module ProductAnalyticsTracking
def event_enabled?(event)
events_to_ff = {
g_analytics_valuestream: :route_hll_to_snowplow,
- i_search_paid: :route_hll_to_snowplow_phase2
+
+ i_search_paid: :route_hll_to_snowplow_phase2,
+ i_search_total: :route_hll_to_snowplow_phase2,
+ i_search_advanced: :route_hll_to_snowplow_phase2
}
Feature.enabled?(events_to_ff[event.to_sym], tracking_namespace_source)
diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb
new file mode 100644
index 00000000000..1a3e7136481
--- /dev/null
+++ b/app/controllers/concerns/verifies_with_email.rb
@@ -0,0 +1,194 @@
+# frozen_string_literal: true
+
+# == VerifiesWithEmail
+#
+# Controller concern to handle verification by email
+module VerifiesWithEmail
+ extend ActiveSupport::Concern
+ include ActionView::Helpers::DateHelper
+
+ TOKEN_LENGTH = 6
+ TOKEN_VALID_FOR_MINUTES = 60
+
+ included do
+ prepend_before_action :verify_with_email, only: :create, unless: -> { two_factor_enabled? }
+ end
+
+ def verify_with_email
+ return unless user = find_user || find_verification_user
+
+ if session[:verification_user_id] && token = verification_params[:verification_token].presence
+ # The verification token is submitted, verify it
+ verify_token(user, token)
+ elsif require_email_verification_enabled?(user)
+ # Limit the amount of password guesses, since we now display the email verification page
+ # when the password is correct, which could be a giveaway when brute-forced.
+ return render_sign_in_rate_limited if check_rate_limit!(:user_sign_in, scope: user) { true }
+
+ 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)
+ elsif user.access_locked? || !AuthenticationEvent.initial_login_or_known_ip_address?(user, request.ip)
+ # 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)
+ prompt_for_email_verification(user)
+ end
+ end
+ end
+ end
+
+ def resend_verification_code
+ return unless user = find_verification_user
+
+ send_verification_instructions(user)
+ prompt_for_email_verification(user)
+ end
+
+ def successful_verification
+ session.delete(:verification_user_id)
+ @redirect_url = after_sign_in_path_for(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+
+ render layout: 'minimal'
+ end
+
+ private
+
+ def find_verification_user
+ return unless session[:verification_user_id]
+
+ User.find_by_id(session[:verification_user_id])
+ end
+
+ # After successful verification and calling sign_in, devise redirects the
+ # user to this path. Override it to show the successful verified page.
+ def after_sign_in_path_for(resource)
+ if action_name == 'create' && session[:verification_user_id]
+ return users_successful_verification_path
+ end
+
+ super
+ end
+
+ def send_verification_instructions(user)
+ return if send_rate_limited?(user)
+
+ raw_token, encrypted_token = generate_token
+ user.unlock_token = encrypted_token
+ user.lock_access!({ send_instructions: false })
+ send_verification_instructions_email(user, raw_token)
+ end
+
+ def send_verification_instructions_email(user, token)
+ return unless user.can?(:receive_notifications)
+
+ Notify.verification_instructions_email(
+ user.id,
+ token: token,
+ expires_in: TOKEN_VALID_FOR_MINUTES).deliver_later
+
+ log_verification(user, :instructions_sent)
+ end
+
+ def verify_token(user, token)
+ return handle_verification_failure(user, :rate_limited) if verification_rate_limited?(user)
+ return handle_verification_failure(user, :invalid) unless valid_token?(user, token)
+ return handle_verification_failure(user, :expired) if expired_token?(user)
+
+ handle_verification_success(user)
+ end
+
+ def generate_token
+ raw_token = SecureRandom.random_number(10**TOKEN_LENGTH).to_s.rjust(TOKEN_LENGTH, '0')
+ encrypted_token = digest_token(raw_token)
+ [raw_token, encrypted_token]
+ end
+
+ def digest_token(token)
+ Devise.token_generator.digest(User, :unlock_token, token)
+ end
+
+ def render_sign_in_rate_limited
+ message = s_('IdentityVerification|Maximum login attempts exceeded. '\
+ 'Wait %{interval} and try again.') % { interval: user_sign_in_interval }
+ redirect_to new_user_session_path, alert: message
+ end
+
+ def user_sign_in_interval
+ interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:user_sign_in][:interval]
+ distance_of_time_in_words(interval_in_seconds)
+ end
+
+ def verification_rate_limited?(user)
+ Gitlab::ApplicationRateLimiter.throttled?(:email_verification, scope: user.unlock_token)
+ end
+
+ def send_rate_limited?(user)
+ Gitlab::ApplicationRateLimiter.throttled?(:email_verification_code_send, scope: user)
+ end
+
+ def expired_token?(user)
+ user.locked_at < (Time.current - TOKEN_VALID_FOR_MINUTES.minutes)
+ end
+
+ def valid_token?(user, token)
+ user.unlock_token == digest_token(token)
+ end
+
+ def handle_verification_failure(user, reason)
+ message = case reason
+ when :rate_limited
+ s_("IdentityVerification|You've reached the maximum amount of tries. "\
+ 'Wait %{interval} or resend a new code and try again.') % { interval: email_verification_interval }
+ when :expired
+ s_('IdentityVerification|The code has expired. Resend a new code and try again.')
+ when :invalid
+ s_('IdentityVerification|The code is incorrect. Enter it again, or resend a new code.')
+ end
+
+ user.errors.add(:base, message)
+ log_verification(user, :failed_attempt, reason)
+
+ prompt_for_email_verification(user)
+ end
+
+ def email_verification_interval
+ interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:email_verification][:interval]
+ distance_of_time_in_words(interval_in_seconds)
+ end
+
+ def handle_verification_success(user)
+ user.unlock_access!
+ log_verification(user, :successful)
+
+ sign_in(user)
+ end
+
+ def prompt_for_email_verification(user)
+ session[:verification_user_id] = user.id
+ self.resource = user
+
+ render 'devise/sessions/email_verification'
+ end
+
+ def verification_params
+ params.require(:user).permit(:verification_token)
+ end
+
+ def log_verification(user, event, reason = nil)
+ Gitlab::AppLogger.info(
+ message: 'Email Verification',
+ event: event.to_s.titlecase,
+ username: user.username,
+ ip: request.ip,
+ reason: reason.to_s
+ )
+ end
+
+ def require_email_verification_enabled?(user)
+ Feature.enabled?(:require_email_verification, user)
+ end
+end
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index 704453fbf44..713231cbc6f 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -4,6 +4,7 @@ class ConfirmationsController < Devise::ConfirmationsController
include AcceptsPendingInvitations
include GitlabRecaptcha
include OneTrustCSP
+ include GoogleAnalyticsCSP
prepend_before_action :check_recaptcha, only: :create
before_action :load_recaptcha, only: :new
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index c71c101b434..67eeb43d5a2 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -82,6 +82,13 @@ class GraphqlController < ApplicationController
render_error(exception.message, status: :unprocessable_entity)
end
+ rescue_from ActiveRecord::QueryAborted do |exception|
+ log_exception(exception)
+
+ error = "Request timed out. Please try a less complex query or a smaller set of records."
+ render_error(error, status: :service_unavailable)
+ end
+
override :feature_category
def feature_category
::Gitlab::FeatureCategories.default.from_request(request) || super
diff --git a/app/controllers/groups/harbor/application_controller.rb b/app/controllers/groups/harbor/application_controller.rb
new file mode 100644
index 00000000000..cff767c8efd
--- /dev/null
+++ b/app/controllers/groups/harbor/application_controller.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Groups
+ module Harbor
+ class ApplicationController < Groups::ApplicationController
+ layout 'group'
+ include ::Harbor::Access
+
+ private
+
+ def authorize_read_harbor_registry!
+ render_404 unless can?(current_user, :read_harbor_registry, @group)
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups/harbor/artifacts_controller.rb b/app/controllers/groups/harbor/artifacts_controller.rb
new file mode 100644
index 00000000000..b7570b44a2c
--- /dev/null
+++ b/app/controllers/groups/harbor/artifacts_controller.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Groups
+ module Harbor
+ class ArtifactsController < ::Groups::Harbor::ApplicationController
+ include ::Harbor::Artifact
+
+ private
+
+ def container
+ @group
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups/harbor/repositories_controller.rb b/app/controllers/groups/harbor/repositories_controller.rb
index 364607f9b20..1ad38bd7103 100644
--- a/app/controllers/groups/harbor/repositories_controller.rb
+++ b/app/controllers/groups/harbor/repositories_controller.rb
@@ -2,22 +2,13 @@
module Groups
module Harbor
- class RepositoriesController < Groups::ApplicationController
- feature_category :integrations
-
- before_action :harbor_registry_enabled!
- before_action do
- push_frontend_feature_flag(:harbor_registry_integration)
- end
-
- def show
- render :index
- end
+ class RepositoriesController < ::Groups::Harbor::ApplicationController
+ include ::Harbor::Repository
private
- def harbor_registry_enabled!
- render_404 unless Feature.enabled?(:harbor_registry_integration)
+ def container
+ @group
end
end
end
diff --git a/app/controllers/groups/harbor/tags_controller.rb b/app/controllers/groups/harbor/tags_controller.rb
new file mode 100644
index 00000000000..da43cb3f64c
--- /dev/null
+++ b/app/controllers/groups/harbor/tags_controller.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Groups
+ module Harbor
+ class TagsController < ::Groups::Harbor::ApplicationController
+ include ::Harbor::Tag
+
+ private
+
+ def container
+ @group
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups/registry/repositories_controller.rb b/app/controllers/groups/registry/repositories_controller.rb
index cb7bf001918..bb2d08e487a 100644
--- a/app/controllers/groups/registry/repositories_controller.rb
+++ b/app/controllers/groups/registry/repositories_controller.rb
@@ -8,6 +8,10 @@ module Groups
before_action :verify_container_registry_enabled!
before_action :authorize_read_container_image!
+ before_action do
+ push_frontend_feature_flag(:container_registry_show_shortened_path, group)
+ end
+
feature_category :container_registry
urgency :low
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index 55707000cf8..75193309a4e 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -18,14 +18,14 @@ class Import::BitbucketController < Import::BaseController
if auth_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(auth_state, params[:state])
go_to_bitbucket_for_permissions
else
- response = oauth_client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url)
+ response = oauth_client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url(namespace_id: params[:namespace_id]))
session[:bitbucket_token] = response.token
session[:bitbucket_expires_at] = response.expires_at
session[:bitbucket_expires_in] = response.expires_in
session[:bitbucket_refresh_token] = response.refresh_token
- redirect_to status_import_bitbucket_url
+ redirect_to status_import_bitbucket_url(namespace_id: params[:namespace_id])
end
end
@@ -78,16 +78,15 @@ class Import::BitbucketController < Import::BaseController
bitbucket_repos.reject { |repo| repo.valid? }
end
+ def provider_url
+ nil
+ end
+
override :provider_name
def provider_name
:bitbucket
end
- override :provider_url
- def provider_url
- provider.url
- end
-
private
def oauth_client
@@ -121,7 +120,7 @@ class Import::BitbucketController < Import::BaseController
def go_to_bitbucket_for_permissions
state = SecureRandom.base64(64)
session[:bitbucket_auth_state] = state
- redirect_to oauth_client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url, state: state)
+ redirect_to oauth_client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url(namespace_id: params[:namespace_id]), state: state)
end
def bitbucket_unauthorized(exception)
diff --git a/app/controllers/import/bitbucket_server_controller.rb b/app/controllers/import/bitbucket_server_controller.rb
index 00f3f0b08b2..12147196749 100644
--- a/app/controllers/import/bitbucket_server_controller.rb
+++ b/app/controllers/import/bitbucket_server_controller.rb
@@ -49,7 +49,7 @@ class Import::BitbucketServerController < Import::BaseController
session[bitbucket_server_username_key] = params[:bitbucket_server_username]
session[bitbucket_server_url_key] = params[:bitbucket_server_url]
- redirect_to status_import_bitbucket_server_path
+ redirect_to status_import_bitbucket_server_path(namespace_id: params[:namespace_id])
end
# We need to re-expose controller's internal method 'status' as action.
@@ -115,7 +115,7 @@ class Import::BitbucketServerController < Import::BaseController
unless session[bitbucket_server_url_key].present? &&
session[bitbucket_server_username_key].present? &&
session[personal_access_token_key].present?
- redirect_to new_import_bitbucket_server_path
+ redirect_to new_import_bitbucket_server_path(namespace_id: params[:namespace_id])
end
end
@@ -170,9 +170,6 @@ class Import::BitbucketServerController < Import::BaseController
}
}, status: :unprocessable_entity
end
- format.html do
- redirect_to new_import_bitbucket_server_path
- end
end
end
end
diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb
index 34f12aebb91..2d607fb7ff7 100644
--- a/app/controllers/import/bulk_imports_controller.rb
+++ b/app/controllers/import/bulk_imports_controller.rb
@@ -17,7 +17,7 @@ class Import::BulkImportsController < ApplicationController
session[access_token_key] = configure_params[access_token_key]&.strip
session[url_key] = configure_params[url_key]
- redirect_to status_import_bulk_imports_url
+ redirect_to status_import_bulk_imports_url(namespace_id: params[:namespace_id])
end
def status
@@ -35,6 +35,12 @@ class Import::BulkImportsController < ApplicationController
render json: json_response
end
format.html do
+ if params[:namespace_id]
+ @namespace = Namespace.find_by_id(params[:namespace_id])
+
+ render_404 unless current_user.can?(:create_subgroup, @namespace)
+ end
+
@source_url = session[url_key]
end
end
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index b949a99c250..7b580234227 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -17,12 +17,12 @@ class Import::FogbugzController < Import::BaseController
res = Gitlab::FogbugzImport::Client.new(import_params.to_h.symbolize_keys)
rescue StandardError
# If the URI is invalid various errors can occur
- return redirect_to new_import_fogbugz_path, alert: _('Could not connect to FogBugz, check your URL')
+ return redirect_to new_import_fogbugz_path(namespace_id: params[:namespace_id]), alert: _('Could not connect to FogBugz, check your URL')
end
session[:fogbugz_token] = res.get_token
session[:fogbugz_uri] = params[:uri]
- redirect_to new_user_map_import_fogbugz_path
+ redirect_to new_user_map_import_fogbugz_path(namespace_id: params[:namespace_id])
end
def new_user_map
@@ -41,12 +41,12 @@ class Import::FogbugzController < Import::BaseController
flash[:notice] = _('The user map has been saved. Continue by selecting the projects you want to import.')
- redirect_to status_import_fogbugz_path
+ redirect_to status_import_fogbugz_path(namespace_id: params[:namespace_id])
end
def status
unless client.valid?
- return redirect_to new_import_fogbugz_path
+ return redirect_to new_import_fogbugz_path(namespace_id: params[:namespace_id])
end
super
@@ -106,7 +106,7 @@ class Import::FogbugzController < Import::BaseController
end
def fogbugz_unauthorized(exception)
- redirect_to new_import_fogbugz_path, alert: exception.message
+ redirect_to new_import_fogbugz_path(namespace_id: params[:namespace_id]), alert: exception.message
end
def import_params
diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb
index 399a92c59e0..4b4ac07b389 100644
--- a/app/controllers/import/gitea_controller.rb
+++ b/app/controllers/import/gitea_controller.rb
@@ -7,7 +7,7 @@ class Import::GiteaController < Import::GithubController
def new
if session[access_token_key].present? && provider_url.present?
- redirect_to status_import_url(namespace_id: params[:namespace_id])
+ redirect_to status_import_url
end
end
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 8dd40b6254e..9cc58ce542c 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -23,25 +23,24 @@ class Import::GithubController < Import::BaseController
if !ci_cd_only? && github_import_configured? && logged_in_with_provider?
go_to_provider_for_permissions
elsif session[access_token_key]
- redirect_to status_import_url(namespace_id: params[:namespace_id])
+ redirect_to status_import_url
end
end
def callback
auth_state = session.delete(auth_state_key)
- namespace_id = session.delete(:namespace_id)
if auth_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(auth_state, params[:state])
provider_unauthorized
else
session[access_token_key] = get_token(params[:code])
- redirect_to status_import_url(namespace_id: namespace_id)
+ redirect_to status_import_url
end
end
def personal_access_token
session[access_token_key] = params[:personal_access_token]&.strip
- redirect_to status_import_url(namespace_id: params[:namespace_id].presence)
+ redirect_to status_import_url
end
def status
@@ -205,15 +204,15 @@ class Import::GithubController < Import::BaseController
end
def new_import_url
- public_send("new_import_#{provider_name}_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend
+ public_send("new_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend
end
- def status_import_url(namespace_id: nil)
- public_send("status_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: namespace_id })) # rubocop:disable GitlabSecurity/PublicSend
+ def status_import_url
+ public_send("status_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: params[:namespace_id].presence })) # rubocop:disable GitlabSecurity/PublicSend
end
def callback_import_url
- public_send("users_import_#{provider_name}_callback_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend
+ public_send("users_import_#{provider_name}_callback_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend
end
def provider_unauthorized
@@ -255,7 +254,6 @@ class Import::GithubController < Import::BaseController
def provider_auth
if !ci_cd_only? && session[access_token_key].blank?
- session[:namespace_id] = params[:namespace_id]
go_to_provider_for_permissions
end
end
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
index c846d9d225a..dd25698d0a9 100644
--- a/app/controllers/import/gitlab_controller.rb
+++ b/app/controllers/import/gitlab_controller.rb
@@ -12,8 +12,8 @@ class Import::GitlabController < Import::BaseController
rescue_from OAuth2::Error, with: :gitlab_unauthorized
def callback
- session[:gitlab_access_token] = client.get_token(params[:code], callback_import_gitlab_url)
- redirect_to status_import_gitlab_url
+ session[:gitlab_access_token] = client.get_token(params[:code], callback_import_gitlab_url(namespace_id: params[:namespace_id]))
+ redirect_to status_import_gitlab_url(namespace_id: params[:namespace_id])
end
# We need to re-expose controller's internal method 'status' as action.
@@ -79,7 +79,7 @@ class Import::GitlabController < Import::BaseController
end
def go_to_gitlab_for_permissions
- redirect_to client.authorize_url(callback_import_gitlab_url)
+ redirect_to client.authorize_url(callback_import_gitlab_url(namespace_id: params[:namespace_id]))
end
def gitlab_unauthorized
diff --git a/app/controllers/jira_connect/oauth_application_ids_controller.rb b/app/controllers/jira_connect/oauth_application_ids_controller.rb
index 05c23210da2..a84b47f4c8b 100644
--- a/app/controllers/jira_connect/oauth_application_ids_controller.rb
+++ b/app/controllers/jira_connect/oauth_application_ids_controller.rb
@@ -5,9 +5,10 @@ module JiraConnect
feature_category :integrations
skip_before_action :authenticate_user!
+ skip_before_action :verify_authenticity_token
def show
- if Feature.enabled?(:jira_connect_oauth_self_managed) && jira_connect_application_key.present?
+ if show_application_id?
render json: { application_id: jira_connect_application_key }
else
head :not_found
@@ -16,6 +17,12 @@ module JiraConnect
private
+ def show_application_id?
+ return if Gitlab.com?
+
+ Feature.enabled?(:jira_connect_oauth_self_managed) && jira_connect_application_key.present?
+ end
+
def jira_connect_application_key
Gitlab::CurrentSettings.jira_connect_application_key.presence
end
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index 2ba9f8264e1..623113f8413 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -25,6 +25,7 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
before_action :allow_rendering_in_iframe, only: :index
before_action :verify_qsh_claim!, only: :index
+ before_action :allow_self_managed_content_security_policy, only: :index
before_action :authenticate_user!, only: :create
def index
@@ -62,6 +63,13 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
private
+ def allow_self_managed_content_security_policy
+ return unless current_jira_installation.instance_url?
+
+ request.content_security_policy.directives['connect-src'] ||= []
+ request.content_security_policy.directives['connect-src'] << Gitlab::Utils.append_path(current_jira_installation.instance_url, '/-/jira_connect/oauth_application_ids')
+ end
+
def create_service
JiraConnectSubscriptions::CreateService.new(current_jira_installation, current_user, namespace_path: params['namespace_path'], jira_user: jira_user)
end
diff --git a/app/controllers/ldap/omniauth_callbacks_controller.rb b/app/controllers/ldap/omniauth_callbacks_controller.rb
index 6aa46b8e4c3..955dfe58449 100644
--- a/app/controllers/ldap/omniauth_callbacks_controller.rb
+++ b/app/controllers/ldap/omniauth_callbacks_controller.rb
@@ -3,10 +3,12 @@
class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
extend ::Gitlab::Utils::Override
+ before_action :check_action_name_in_available_providers
+
def self.define_providers!
return unless Gitlab::Auth::Ldap::Config.sign_in_enabled?
- Gitlab::Auth::Ldap::Config.available_servers.each do |server|
+ Gitlab::Auth::Ldap::Config.servers.each do |server|
alias_method server['provider_name'], :ldap
end
end
@@ -36,6 +38,18 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
redirect_to new_user_session_path
end
+
+ private
+
+ def check_action_name_in_available_providers
+ render_404 unless available_providers.include?(action_name)
+ end
+
+ def available_providers
+ Gitlab::Auth::Ldap::Config.available_servers.map do |server|
+ server['provider_name']
+ end
+ end
end
Ldap::OmniauthCallbacksController.prepend_mod_with('Ldap::OmniauthCallbacksController')
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index 3724bb0d925..a996bad3fac 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -52,10 +52,10 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
end
def set_index_vars
- @applications = current_user.oauth_applications
+ @applications = current_user.oauth_applications.load
@authorized_tokens = current_user.oauth_authorized_tokens
- @authorized_anonymous_tokens = @authorized_tokens.reject(&:application)
- @authorized_apps = @authorized_tokens.map(&:application).uniq.reject(&:nil?)
+ .latest_per_application
+ .preload_application
# Don't overwrite a value possibly set by `create`
@application ||= Doorkeeper::Application.new
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
index c9c51289d3a..2e9fbb1d0d9 100644
--- a/app/controllers/oauth/authorizations_controller.rb
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -54,8 +54,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
# limit scopes when signing in with GitLab
def downgrade_scopes!
- return unless Feature.enabled?(:omniauth_login_minimal_scopes, current_user)
-
auth_type = params.delete('gl_auth_type')
return unless auth_type == 'login'
diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb
index 265fa505b2a..1a8908e8571 100644
--- a/app/controllers/profiles/personal_access_tokens_controller.rb
+++ b/app/controllers/profiles/personal_access_tokens_controller.rb
@@ -14,6 +14,13 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
name: params[:name],
scopes: scopes
)
+
+ respond_to do |format|
+ format.html
+ format.json do
+ render json: @active_personal_access_tokens
+ end
+ end
end
def create
@@ -56,6 +63,28 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
def active_personal_access_tokens
tokens = finder(state: 'active', sort: 'expires_at_asc').execute
+
+ if Feature.enabled?('access_token_pagination')
+ tokens = tokens.page(page)
+ add_pagination_headers(tokens)
+ end
+
::API::Entities::PersonalAccessTokenWithDetails.represent(tokens)
end
+
+ def add_pagination_headers(relation)
+ Gitlab::Pagination::OffsetHeaderBuilder.new(
+ request_context: self,
+ per_page: relation.limit_value,
+ page: relation.current_page,
+ next_page: relation.next_page,
+ prev_page: relation.prev_page,
+ total: relation.total_count,
+ params: params.permit(:page)
+ ).execute
+ end
+
+ def page
+ (params[:page] || 1).to_i
+ end
end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index 64ced43311a..5bfda526fb0 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -25,7 +25,7 @@ class Projects::BlameController < Projects::ApplicationController
blame_service = Projects::BlameService.new(@blob, @commit, params.permit(:page))
- @blame = Gitlab::View::Presenter::Factory.new(blame_service.blame, project: @project, path: @path).fabricate!
+ @blame = Gitlab::View::Presenter::Factory.new(blame_service.blame, project: @project, path: @path, page: blame_service.page).fabricate!
render locals: { blame_pagination: blame_service.pagination }
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index a9561fb9312..97aae56c4ec 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -42,7 +42,6 @@ class Projects::BlobController < Projects::ApplicationController
urgency :low, [:create, :show, :edit, :update, :diff]
before_action do
- push_frontend_feature_flag(:refactor_blob_viewer, @project)
push_frontend_feature_flag(:highlight_js, @project)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index ac3c85f3b40..7ef9fd9daed 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -24,9 +24,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action :environment, only: [:show, :edit, :update, :stop, :terminal, :terminal_websocket_authorize, :metrics, :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 do
- push_frontend_feature_flag(:monitor_logging, project)
- end
after_action :expire_etag_cache, only: [:cancel_auto_stop]
feature_category :continuous_delivery
diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb
index 980e9bdcdad..050b26a40c7 100644
--- a/app/controllers/projects/google_cloud/base_controller.rb
+++ b/app/controllers/projects/google_cloud/base_controller.rb
@@ -12,7 +12,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
def admin_project_google_cloud!
unless can?(current_user, :admin_project_google_cloud, project)
- track_event('admin_project_google_cloud!', 'access_denied', 'invalid_user')
+ track_event('admin_project_google_cloud!', 'error_access_denied', 'invalid_user')
access_denied!
end
end
@@ -20,7 +20,11 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
def google_oauth2_enabled!
config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
if config.app_id.blank? || config.app_secret.blank?
- track_event('google_oauth2_enabled!', 'access_denied', { reason: 'google_oauth2_not_configured', config: config })
+ track_event(
+ 'google_oauth2_enabled!',
+ 'error_access_denied',
+ { reason: 'google_oauth2_not_configured', config: config }
+ )
access_denied! 'This GitLab instance not configured for Google Oauth2.'
end
end
@@ -31,7 +35,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
enabled_for_project = Feature.enabled?(:incubation_5mp_google_cloud, project)
feature_is_enabled = enabled_for_user || enabled_for_group || enabled_for_project
unless feature_is_enabled
- track_event('feature_flag_enabled!', 'access_denied', 'feature_flag_not_enabled')
+ track_event('feature_flag_enabled!', 'error_access_denied', 'feature_flag_not_enabled')
access_denied!
end
end
@@ -42,7 +46,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
return if is_token_valid
- return_url = project_google_cloud_index_path(project)
+ return_url = project_google_cloud_configuration_path(project)
state = generate_session_key_redirect(request.url, return_url)
@authorize_url = GoogleApi::CloudPlatform::Client.new(nil,
callback_google_api_auth_url,
@@ -65,12 +69,6 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
end
- def handle_gcp_error(action, error)
- track_event(action, 'gcp_error', error)
- @js_data = { screen: 'gcp_error', error: error.to_s }.to_json
- render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error'
- end
-
def track_event(action, label, property)
options = { label: label, project: project, user: current_user }
diff --git a/app/controllers/projects/google_cloud/configuration_controller.rb b/app/controllers/projects/google_cloud/configuration_controller.rb
new file mode 100644
index 00000000000..fa672058247
--- /dev/null
+++ b/app/controllers/projects/google_cloud/configuration_controller.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Projects
+ module GoogleCloud
+ class ConfigurationController < Projects::GoogleCloud::BaseController
+ def index
+ @google_cloud_path = project_google_cloud_configuration_path(project)
+ js_data = {
+ configurationUrl: project_google_cloud_configuration_path(project),
+ deploymentsUrl: project_google_cloud_deployments_path(project),
+ databasesUrl: project_google_cloud_databases_path(project),
+ serviceAccounts: ::GoogleCloud::ServiceAccountsService.new(project).find_for_project,
+ createServiceAccountUrl: project_google_cloud_service_accounts_path(project),
+ emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'),
+ configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project),
+ gcpRegions: gcp_regions,
+ revokeOauthUrl: revoke_oauth_url
+ }
+ @js_data = js_data.to_json
+ track_event('configuration#index', 'success', js_data)
+ end
+
+ private
+
+ def gcp_regions
+ params = { key: Projects::GoogleCloud::GcpRegionsController::GCP_REGION_CI_VAR_KEY }
+ list = ::Ci::VariablesFinder.new(project, params).execute
+ list.map { |variable| { gcp_region: variable.value, environment: variable.environment_scope } }
+ end
+
+ def revoke_oauth_url
+ google_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ .validate_token(expires_at_in_session)
+ google_token_valid ? project_google_cloud_revoke_oauth_index_path(project) : nil
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/google_cloud/databases_controller.rb b/app/controllers/projects/google_cloud/databases_controller.rb
new file mode 100644
index 00000000000..711409e7550
--- /dev/null
+++ b/app/controllers/projects/google_cloud/databases_controller.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Projects
+ module GoogleCloud
+ class DatabasesController < Projects::GoogleCloud::BaseController
+ def index
+ @google_cloud_path = project_google_cloud_configuration_path(project)
+ js_data = {
+ configurationUrl: project_google_cloud_configuration_path(project),
+ deploymentsUrl: project_google_cloud_deployments_path(project),
+ databasesUrl: project_google_cloud_databases_path(project)
+ }
+ @js_data = js_data.to_json
+ track_event('databases#index', 'success', js_data)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/google_cloud/deployments_controller.rb b/app/controllers/projects/google_cloud/deployments_controller.rb
index 4867d344c5a..4aa17b36fad 100644
--- a/app/controllers/projects/google_cloud/deployments_controller.rb
+++ b/app/controllers/projects/google_cloud/deployments_controller.rb
@@ -3,32 +3,47 @@
class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::BaseController
before_action :validate_gcp_token!
+ def index
+ @google_cloud_path = project_google_cloud_configuration_path(project)
+ js_data = {
+ configurationUrl: project_google_cloud_configuration_path(project),
+ deploymentsUrl: project_google_cloud_deployments_path(project),
+ databasesUrl: project_google_cloud_databases_path(project),
+ enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project),
+ enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project)
+ }
+ @js_data = js_data.to_json
+ track_event('deployments#index', 'success', js_data)
+ end
+
def cloud_run
- params = { token_in_session: token_in_session }
+ params = { google_oauth2_token: token_in_session }
enable_cloud_run_response = GoogleCloud::EnableCloudRunService
.new(project, current_user, params).execute
if enable_cloud_run_response[:status] == :error
- track_event('deployments#cloud_run', 'enable_cloud_run_error', enable_cloud_run_response)
+ track_event('deployments#cloud_run', 'error_enable_cloud_run', enable_cloud_run_response)
flash[:error] = enable_cloud_run_response[:message]
- redirect_to project_google_cloud_index_path(project)
+ redirect_to project_google_cloud_deployments_path(project)
else
params = { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN }
generate_pipeline_response = GoogleCloud::GeneratePipelineService
.new(project, current_user, params).execute
if generate_pipeline_response[:status] == :error
- track_event('deployments#cloud_run', 'generate_pipeline_error', generate_pipeline_response)
+ track_event('deployments#cloud_run', 'error_generate_pipeline', generate_pipeline_response)
flash[:error] = 'Failed to generate pipeline'
- redirect_to project_google_cloud_index_path(project)
+ redirect_to project_google_cloud_deployments_path(project)
else
cloud_run_mr_params = cloud_run_mr_params(generate_pipeline_response[:branch_name])
- track_event('deployments#cloud_run', 'cloud_run_success', cloud_run_mr_params)
+ track_event('deployments#cloud_run', 'success', cloud_run_mr_params)
redirect_to project_new_merge_request_path(project, merge_request: cloud_run_mr_params)
end
end
- rescue Google::Apis::ClientError => error
- handle_gcp_error('deployments#cloud_run', error)
+ rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error
+ track_event('deployments#cloud_run', 'error_gcp', error)
+ flash[:warning] = _('Google Cloud Error - %{error}') % { error: error }
+ redirect_to project_google_cloud_deployments_path(project)
end
def cloud_storage
diff --git a/app/controllers/projects/google_cloud/gcp_regions_controller.rb b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
index beeb91cfd80..3fbe9a96284 100644
--- a/app/controllers/projects/google_cloud/gcp_regions_controller.rb
+++ b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
@@ -6,8 +6,10 @@ class Projects::GoogleCloud::GcpRegionsController < Projects::GoogleCloud::BaseC
# Source https://cloud.google.com/run/docs/locations 2022-01-30
AVAILABLE_REGIONS = %w[asia-east1 asia-northeast1 asia-southeast1 europe-north1 europe-west1 europe-west4 us-central1 us-east1 us-east4 us-west1].freeze
+ GCP_REGION_CI_VAR_KEY = 'GCP_REGION'
+
def index
- @google_cloud_path = project_google_cloud_index_path(project)
+ @google_cloud_path = project_google_cloud_configuration_path(project)
params = { per_page: 50 }
branches = BranchesFinder.new(project.repository, params).execute(gitaly_pagination: true)
tags = TagsFinder.new(project.repository, params).execute(gitaly_pagination: true)
@@ -16,16 +18,16 @@ class Projects::GoogleCloud::GcpRegionsController < Projects::GoogleCloud::BaseC
screen: 'gcp_regions_form',
availableRegions: AVAILABLE_REGIONS,
refs: refs,
- cancelPath: project_google_cloud_index_path(project)
+ cancelPath: project_google_cloud_configuration_path(project)
}
@js_data = js_data.to_json
- track_event('gcp_regions#index', 'form_render', js_data)
+ track_event('gcp_regions#index', 'success', js_data)
end
def create
permitted_params = params.permit(:ref, :gcp_region)
response = GoogleCloud::GcpRegionAddOrReplaceService.new(project).execute(permitted_params[:ref], permitted_params[:gcp_region])
- track_event('gcp_regions#create', 'form_submit', response)
- redirect_to project_google_cloud_index_path(project), notice: _('GCP region configured')
+ track_event('gcp_regions#create', 'success', response)
+ redirect_to project_google_cloud_configuration_path(project), notice: _('GCP region configured')
end
end
diff --git a/app/controllers/projects/google_cloud/revoke_oauth_controller.rb b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
index 03d1474707b..1a9a2daf4f2 100644
--- a/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
+++ b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
@@ -8,16 +8,15 @@ class Projects::GoogleCloud::RevokeOauthController < Projects::GoogleCloud::Base
response = google_api_client.revoke_authorizations
if response.success?
- status = 'success'
redirect_message = { notice: s_('GoogleCloud|Google OAuth2 token revocation requested') }
+ track_event('revoke_oauth#create', 'success', response.to_json)
else
- status = 'failed'
redirect_message = { alert: s_('GoogleCloud|Google OAuth2 token revocation request failed') }
+ track_event('revoke_oauth#create', 'error', response.to_json)
end
session.delete(GoogleApi::CloudPlatform::Client.session_key_for_token)
- track_event('revoke_oauth#create', 'create', status)
- redirect_to project_google_cloud_index_path(project), redirect_message
+ redirect_to project_google_cloud_configuration_path(project), redirect_message
end
end
diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb
index 5d8b2030d5c..dbd83be19db 100644
--- a/app/controllers/projects/google_cloud/service_accounts_controller.rb
+++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb
@@ -4,14 +4,15 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
before_action :validate_gcp_token!
def index
- @google_cloud_path = project_google_cloud_index_path(project)
+ @google_cloud_path = project_google_cloud_configuration_path(project)
google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
gcp_projects = google_api_client.list_projects
if gcp_projects.empty?
@js_data = { screen: 'no_gcp_projects' }.to_json
- track_event('service_accounts#index', 'form_error', 'no_gcp_projects')
- render status: :unauthorized, template: 'projects/google_cloud/errors/no_gcp_projects'
+ track_event('service_accounts#index', 'error_form', 'no_gcp_projects')
+ flash[:warning] = _('No Google Cloud projects - You need at least one Google Cloud project')
+ redirect_to project_google_cloud_configuration_path(project)
else
params = { per_page: 50 }
branches = BranchesFinder.new(project.repository, params).execute(gitaly_pagination: true)
@@ -21,14 +22,16 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
screen: 'service_accounts_form',
gcpProjects: gcp_projects,
refs: refs,
- cancelPath: project_google_cloud_index_path(project)
+ cancelPath: project_google_cloud_configuration_path(project)
}
@js_data = js_data.to_json
- track_event('service_accounts#index', 'form_success', js_data)
+ track_event('service_accounts#index', 'success', js_data)
end
- rescue Google::Apis::ClientError => error
- handle_gcp_error('service_accounts#index', error)
+ rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error
+ track_event('service_accounts#index', 'error_gcp', error)
+ flash[:warning] = _('Google Cloud Error - %{error}') % { error: error }
+ redirect_to project_google_cloud_configuration_path(project)
end
def create
@@ -42,9 +45,11 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
environment_name: permitted_params[:ref]
).execute
- track_event('service_accounts#create', 'form_submit', response)
- redirect_to project_google_cloud_index_path(project), notice: response.message
+ track_event('service_accounts#create', 'success', response)
+ redirect_to project_google_cloud_configuration_path(project), notice: response.message
rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error
- handle_gcp_error('service_accounts#create', error)
+ track_event('service_accounts#create', 'error_gcp', error)
+ flash[:warning] = _('Google Cloud Error - %{error}') % { error: error }
+ redirect_to project_google_cloud_configuration_path(project)
end
end
diff --git a/app/controllers/projects/google_cloud_controller.rb b/app/controllers/projects/google_cloud_controller.rb
deleted file mode 100644
index 49bb4bec859..00000000000
--- a/app/controllers/projects/google_cloud_controller.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class Projects::GoogleCloudController < Projects::GoogleCloud::BaseController
- GCP_REGION_CI_VAR_KEY = 'GCP_REGION'
-
- def index
- js_data = {
- screen: 'home',
- serviceAccounts: GoogleCloud::ServiceAccountsService.new(project).find_for_project,
- createServiceAccountUrl: project_google_cloud_service_accounts_path(project),
- enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project),
- enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project),
- emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'),
- configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project),
- gcpRegions: gcp_regions,
- revokeOauthUrl: revoke_oauth_url
- }
- @js_data = js_data.to_json
- track_event('google_cloud#index', 'index', js_data)
- end
-
- private
-
- def gcp_regions
- list = ::Ci::VariablesFinder.new(project, { key: GCP_REGION_CI_VAR_KEY }).execute
- list.map { |variable| { gcp_region: variable.value, environment: variable.environment_scope } }
- end
-
- def revoke_oauth_url
- google_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
- .validate_token(expires_at_in_session)
- google_token_valid ? project_google_cloud_revoke_oauth_index_path(project) : nil
- end
-end
diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb
index 6007e09f109..08eebfa0e4b 100644
--- a/app/controllers/projects/group_links_controller.rb
+++ b/app/controllers/projects/group_links_controller.rb
@@ -9,7 +9,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
def update
group_link = @project.project_group_links.find(params[:id])
- Projects::GroupLinks::UpdateService.new(group_link).execute(group_link_params)
+ Projects::GroupLinks::UpdateService.new(group_link, current_user).execute(group_link_params)
if group_link.expires?
render json: {
diff --git a/app/controllers/projects/harbor/application_controller.rb b/app/controllers/projects/harbor/application_controller.rb
index e6e694783fa..9271ec560dc 100644
--- a/app/controllers/projects/harbor/application_controller.rb
+++ b/app/controllers/projects/harbor/application_controller.rb
@@ -4,18 +4,12 @@ module Projects
module Harbor
class ApplicationController < Projects::ApplicationController
layout 'project'
-
- before_action :harbor_registry_enabled!
- before_action do
- push_frontend_feature_flag(:harbor_registry_integration)
- end
-
- feature_category :integrations
+ include ::Harbor::Access
private
- def harbor_registry_enabled!
- render_404 unless Feature.enabled?(:harbor_registry_integration)
+ def authorize_read_harbor_registry!
+ render_404 unless can?(current_user, :read_harbor_registry, @project)
end
end
end
diff --git a/app/controllers/projects/harbor/artifacts_controller.rb b/app/controllers/projects/harbor/artifacts_controller.rb
new file mode 100644
index 00000000000..ce36f181b42
--- /dev/null
+++ b/app/controllers/projects/harbor/artifacts_controller.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ module Harbor
+ class ArtifactsController < ::Projects::Harbor::ApplicationController
+ include ::Harbor::Artifact
+
+ private
+
+ def container
+ @project
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/harbor/repositories_controller.rb b/app/controllers/projects/harbor/repositories_controller.rb
index dd3e3dc1978..4db13331bf0 100644
--- a/app/controllers/projects/harbor/repositories_controller.rb
+++ b/app/controllers/projects/harbor/repositories_controller.rb
@@ -3,8 +3,12 @@
module Projects
module Harbor
class RepositoriesController < ::Projects::Harbor::ApplicationController
- def show
- render :index
+ include ::Harbor::Repository
+
+ private
+
+ def container
+ @project
end
end
end
diff --git a/app/controllers/projects/harbor/tags_controller.rb b/app/controllers/projects/harbor/tags_controller.rb
new file mode 100644
index 00000000000..f49c5ac7768
--- /dev/null
+++ b/app/controllers/projects/harbor/tags_controller.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ module Harbor
+ class TagsController < ::Projects::Harbor::ApplicationController
+ include ::Harbor::Tag
+
+ private
+
+ def container
+ @project
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index 99eba32e00f..50f388324f1 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -15,52 +15,21 @@ class Projects::HooksController < Projects::ApplicationController
feature_category :integrations
urgency :low, [:test]
- def index
- @hooks = @project.hooks.load
- @hook = ProjectHook.new
- end
-
- def create
- @hook = @project.hooks.new(hook_params)
- @hook.save
-
- unless @hook.valid?
- @hooks = @project.hooks.select(&:persisted?)
- flash[:alert] = @hook.errors.full_messages.join.html_safe
- end
-
- redirect_to action: :index
- end
-
- def edit
- redirect_to(action: :index) unless hook
- end
-
- def update
- if hook.update(hook_params)
- flash[:notice] = _('Hook was successfully updated.')
- redirect_to action: :index
- else
- render 'edit'
- end
- end
-
def test
- result = TestHooks::ProjectService.new(hook, current_user, params[:trigger]).execute
+ trigger = params.fetch(:trigger, ::ProjectHook.triggers.each_value.first.to_s)
+ result = TestHooks::ProjectService.new(hook, current_user, trigger).execute
set_hook_execution_notice(result)
redirect_back_or_default(default: { action: :index })
end
- def destroy
- destroy_hook(hook)
+ private
- redirect_to action: :index, status: :found
+ def relation
+ @project.hooks
end
- private
-
def hook
@hook ||= @project.hooks.find(params[:id])
end
@@ -69,13 +38,7 @@ class Projects::HooksController < Projects::ApplicationController
@hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
end
- def hook_params
- params.require(:hook).permit(
- :enable_ssl_verification,
- :token,
- :url,
- :push_events_branch_filter,
- *ProjectHook.triggers.values
- )
+ def trigger_values
+ ProjectHook.triggers.values
end
end
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 70eab792b40..f9fa8046962 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -8,6 +8,9 @@ class Projects::IncidentsController < Projects::ApplicationController
before_action :load_incident, only: [:show]
before_action do
push_frontend_feature_flag(:incident_timeline, @project)
+ push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
+ push_frontend_feature_flag(:work_items_mvc_2)
+ push_frontend_feature_flag(:work_items_hierarchy, @project)
end
feature_category :incident_management
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index f974b16468c..f1c9e2b2653 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -22,7 +22,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
before_action :redirect_if_task, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
- after_action :log_issue_show, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
+ after_action :log_issue_show, only: :show
before_action :set_issuables_index, if: ->(c) {
SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !index_html_request?
@@ -41,14 +41,11 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :authorize_download_code!, only: [:related_branches]
before_action do
- push_frontend_feature_flag(:contacts_autocomplete, project&.group)
push_frontend_feature_flag(:incident_timeline, project)
end
before_action only: :show do
- push_frontend_feature_flag(:confidential_notes, project&.group)
push_frontend_feature_flag(:issue_assignees_widget, project)
- push_frontend_feature_flag(:paginated_issue_discussions, project)
push_frontend_feature_flag(:realtime_labels, project)
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
push_frontend_feature_flag(:work_items_mvc_2)
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 9574c5d5849..ad59f421c06 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -5,28 +5,22 @@ class Projects::JobsController < Projects::ApplicationController
include ContinueParams
include ProjectStatsRefreshConflictsGuard
- urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :status, :erase, :raw]
+ urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :erase, :raw]
before_action :find_job_as_build, except: [:index, :play, :show]
before_action :find_job_as_processable, only: [:play, :show]
before_action :authorize_read_build_trace!, only: [:trace, :raw]
before_action :authorize_read_build!
before_action :authorize_update_build!,
- except: [:index, :show, :status, :raw, :trace, :erase, :cancel, :unschedule]
+ except: [:index, :show, :raw, :trace, :erase, :cancel, :unschedule]
before_action :authorize_erase_build!, only: [:erase]
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_websocket_authorize]
before_action :verify_api_request!, only: :terminal_websocket_authorize
before_action :authorize_create_proxy_build!, only: :proxy_websocket_authorize
before_action :verify_proxy_request!, only: :proxy_websocket_authorize
- before_action :push_jobs_table_vue, only: [:index]
- before_action :push_jobs_table_vue_search, only: [:index]
+ before_action :push_job_log_search, only: [:show]
before_action :reject_if_build_artifacts_size_refreshing!, only: [:erase]
- before_action do
- push_frontend_feature_flag(:infinitely_collapsible_sections, @project)
- push_frontend_feature_flag(:trigger_job_retry_action, @project)
- end
-
layout 'project'
feature_category :continuous_integration
@@ -125,12 +119,6 @@ class Projects::JobsController < Projects::ApplicationController
end
end
- def status
- render json: Ci::JobSerializer
- .new(project: @project, current_user: @current_user)
- .represent_status(@build.present(current_user: current_user))
- end
-
def erase
if @build.erase(erased_by: current_user)
redirect_to project_job_path(project, @build),
@@ -261,11 +249,7 @@ class Projects::JobsController < Projects::ApplicationController
::Gitlab::Workhorse.channel_websocket(service)
end
- def push_jobs_table_vue
- push_frontend_feature_flag(:jobs_table_vue, @project)
- end
-
- def push_jobs_table_vue_search
- push_frontend_feature_flag(:jobs_table_vue_search, @project)
+ def push_job_log_search
+ push_frontend_feature_flag(:job_log_search, @project)
end
end
diff --git a/app/controllers/projects/logs_controller.rb b/app/controllers/projects/logs_controller.rb
deleted file mode 100644
index 0f751db2064..00000000000
--- a/app/controllers/projects/logs_controller.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-
-module Projects
- class LogsController < Projects::ApplicationController
- include ::Gitlab::Utils::StrongMemoize
-
- before_action :authorize_read_pod_logs!
- before_action :ensure_deployments, only: %i(k8s elasticsearch)
-
- feature_category :logging
- urgency :low
-
- def index
- return render_404 unless Feature.enabled?(:monitor_logging, project)
-
- if environment || cluster
- render :index
- else
- render :empty_logs
- end
- end
-
- def k8s
- render_logs(::PodLogs::KubernetesService, k8s_params)
- end
-
- def elasticsearch
- render_logs(::PodLogs::ElasticsearchService, elasticsearch_params)
- end
-
- private
-
- def render_logs(service, permitted_params)
- ::Gitlab::PollingInterval.set_header(response, interval: 3_000)
-
- result = service.new(cluster, namespace, params: permitted_params).execute
-
- if result.nil?
- head :accepted
- elsif result[:status] == :success
- render json: result
- else
- render status: :bad_request, json: result
- end
- end
-
- # cluster is selected either via environment or directly by id
- def cluster_params
- params.permit(:environment_name, :cluster_id)
- end
-
- def k8s_params
- params.permit(:container_name, :pod_name)
- end
-
- def elasticsearch_params
- params.permit(:container_name, :pod_name, :search, :start_time, :end_time, :cursor)
- end
-
- def environment
- strong_memoize(:environment) do
- if cluster_params.key?(:environment_name)
- ::Environments::EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first
- else
- project.default_environment
- end
- end
- end
-
- def cluster
- strong_memoize(:cluster) do
- if gitlab_managed_apps_logs?
- clusters = ClusterAncestorsFinder.new(project, current_user).execute
- clusters.find { |cluster| cluster.id == cluster_params[:cluster_id].to_i }
- else
- environment&.deployment_platform&.cluster
- end
- end
- end
-
- def namespace
- if gitlab_managed_apps_logs?
- Gitlab::Kubernetes::Helm::NAMESPACE
- else
- environment.deployment_namespace
- end
- end
-
- def ensure_deployments
- return if gitlab_managed_apps_logs?
- return if cluster && namespace.present?
-
- render status: :bad_request, json: {
- status: :error,
- message: _('Environment does not have deployments')
- }
- end
-
- def gitlab_managed_apps_logs?
- cluster_params.key?(:cluster_id)
- end
- end
-end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index d420e136316..a2f018c013b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -32,10 +32,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
before_action only: [:show] do
- push_frontend_feature_flag(:file_identifier_hash)
push_frontend_feature_flag(:merge_request_widget_graphql, project)
push_frontend_feature_flag(:core_security_mr_widget_counts, project)
- push_frontend_feature_flag(:confidential_notes, project)
push_frontend_feature_flag(:restructured_mr_widget, project)
push_frontend_feature_flag(:refactor_mr_widgets_extensions, project)
push_frontend_feature_flag(:refactor_code_quality_extension, project)
@@ -44,10 +42,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:issue_assignees_widget, @project)
push_frontend_feature_flag(:realtime_labels, project)
push_frontend_feature_flag(:refactor_security_extension, @project)
+ push_frontend_feature_flag(:refactor_code_quality_inline_findings, project)
push_frontend_feature_flag(:mr_attention_requests, current_user)
push_frontend_feature_flag(:moved_mr_sidebar, project)
push_frontend_feature_flag(:paginated_mr_discussions, project)
push_frontend_feature_flag(:mr_review_submit_comment, project)
+ push_frontend_feature_flag(:mr_experience_survey, project)
end
before_action do
@@ -86,6 +86,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:rebase,
:discussions,
:pipelines,
+ :coverage_reports,
:test_reports,
:codequality_mr_diff_reports,
:codequality_reports,
diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb
index f2f276071a0..b78ee6ca917 100644
--- a/app/controllers/projects/metrics_dashboard_controller.rb
+++ b/app/controllers/projects/metrics_dashboard_controller.rb
@@ -12,7 +12,6 @@ module Projects
before_action do
push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
- push_frontend_feature_flag(:monitor_logging, project)
end
feature_category :metrics
diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb
index e5b2dd14f69..8ac370b1bd4 100644
--- a/app/controllers/projects/pipelines/tests_controller.rb
+++ b/app/controllers/projects/pipelines/tests_controller.rb
@@ -7,6 +7,7 @@ module Projects
before_action :authorize_read_build!
before_action :builds, only: [:show]
+ before_action :validate_test_reports!, only: [:show]
feature_category :code_testing
@@ -23,19 +24,21 @@ module Projects
def show
respond_to do |format|
format.json do
- if pipeline.has_expired_test_reports?
- render json: { errors: 'Test report artifacts have expired' }, status: :not_found
- else
- render json: TestSuiteSerializer
- .new(project: project, current_user: @current_user)
- .represent(test_suite, details: true)
- end
+ render json: TestSuiteSerializer
+ .new(project: project, current_user: @current_user)
+ .represent(test_suite, details: true)
end
end
end
private
+ def validate_test_reports!
+ unless pipeline.has_test_reports?
+ render json: { errors: 'Test report artifacts not found' }, status: :not_found
+ end
+ end
+
def builds
@builds ||= pipeline.latest_builds.id_in(build_ids).presence || render_404
end
@@ -48,7 +51,7 @@ module Projects
def test_suite
suite = builds.sum do |build|
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
+ build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
end
Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, project).load!
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index adc3a912a91..b2aa1d9f4ca 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -38,6 +38,8 @@ class Projects::PipelinesController < Projects::ApplicationController
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_pipelines', if: -> { should_track_ci_cd_pipelines? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', if: -> { should_track_ci_cd_deployment_frequency? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_lead_time', if: -> { should_track_ci_cd_lead_time? }
+ track_redis_hll_event :charts, name: 'p_analytics_ci_cd_time_to_restore_service', if: -> { should_track_ci_cd_time_to_restore_service? }
+ track_redis_hll_event :charts, name: 'p_analytics_ci_cd_change_failure_rate', if: -> { should_track_ci_cd_change_failure_rate? }
wrap_parameters Ci::Pipeline
@@ -174,7 +176,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def stage
- @stage = pipeline.legacy_stage(params[:stage])
+ @stage = pipeline.stage(params[:stage])
return not_found unless @stage
render json: StageSerializer
@@ -361,6 +363,14 @@ class Projects::PipelinesController < Projects::ApplicationController
def should_track_ci_cd_lead_time?
params[:chart] == 'lead-time'
end
+
+ def should_track_ci_cd_time_to_restore_service?
+ params[:chart] == 'time-to-restore-service'
+ end
+
+ def should_track_ci_cd_change_failure_rate?
+ params[:chart] == 'change-failure-rate'
+ end
end
Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController')
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 168e703c87d..cd9c6efb106 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -13,9 +13,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def index
@sort = params[:sort].presence || sort_value_name
-
- @group_links = @project.project_group_links
- @group_links = @group_links.search(params[:search_groups]) if params[:search_groups].present?
+ @include_relations ||= requested_relations(:groups_with_inherited_permissions)
if can?(current_user, :admin_project_member, @project)
@invited_members = present_members(invited_members)
diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb
index ad3b2bc98e7..87cb8e4781f 100644
--- a/app/controllers/projects/registry/repositories_controller.rb
+++ b/app/controllers/projects/registry/repositories_controller.rb
@@ -8,6 +8,10 @@ module Projects
before_action :authorize_update_container_image!, only: [:destroy]
+ before_action do
+ push_frontend_feature_flag(:container_registry_show_shortened_path, project)
+ end
+
def index
respond_to do |format|
format.html { ensure_root_container_repository! }
diff --git a/app/controllers/projects/service_ping_controller.rb b/app/controllers/projects/service_ping_controller.rb
index d8f1785d95e..43c249afd8e 100644
--- a/app/controllers/projects/service_ping_controller.rb
+++ b/app/controllers/projects/service_ping_controller.rb
@@ -17,7 +17,8 @@ class Projects::ServicePingController < Projects::ApplicationController
return render_404 unless Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?
Gitlab::UsageDataCounters::WebIdeCounter.increment_previews_success_count
- Gitlab::UsageDataCounters::EditorUniqueCounter.track_live_preview_edit_action(author: current_user)
+ Gitlab::UsageDataCounters::EditorUniqueCounter.track_live_preview_edit_action(author: current_user,
+ project: project)
head(200)
end
diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb
index 3365da65de8..cee9e9feb7b 100644
--- a/app/controllers/projects/settings/integrations_controller.rb
+++ b/app/controllers/projects/settings/integrations_controller.rb
@@ -11,6 +11,7 @@ module Projects
before_action :integration, only: [:edit, :update, :test]
before_action :default_integration, only: [:edit, :update]
before_action :web_hook_logs, only: [:edit, :update]
+ before_action -> { check_rate_limit!(:project_testing_integration, scope: [@project, current_user]) }, only: :test
respond_to :html
@@ -88,7 +89,7 @@ module Projects
unless result[:success]
return {
error: true,
- message: s_('Integrations|Connection failed. Please check your settings.'),
+ message: s_('Integrations|Connection failed. Check your integration settings.'),
service_response: result[:message].to_s,
test_failed: true
}
@@ -98,7 +99,7 @@ module Projects
rescue *Gitlab::HTTP::HTTP_ERRORS => e
{
error: true,
- message: s_('Integrations|Connection failed. Please check your settings.'),
+ message: s_('Integrations|Connection failed. Check your integration settings.'),
service_response: e.message,
test_failed: true
}
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index 77d7f3570f3..478d9f0b38e 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -14,7 +14,6 @@ module Projects
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
helper_method :error_tracking_setting
- helper_method :tracing_setting
feature_category :incident_management
urgency :low
@@ -60,19 +59,9 @@ module Projects
::Gitlab::Tracking::IncidentManagement.track_from_params(
update_params[:incident_management_setting_attributes]
)
- track_tracing_external_url
end
end
- def track_tracing_external_url
- external_url_previous_change = project&.tracing_setting&.external_url_previous_change
-
- return unless external_url_previous_change
- return unless external_url_previous_change[0].blank? && external_url_previous_change[1].present?
-
- ::Gitlab::Tracking.event('project:operations:tracing', 'external_url_populated', user: current_user, project: project, namespace: project.namespace)
- end
-
def alerting_params
{ alerting_setting_attributes: { regenerate_token: true } }
end
@@ -124,10 +113,6 @@ module Projects
project.build_error_tracking_setting
end
- def tracing_setting
- @tracing_setting ||= project.tracing_setting || project.build_tracing_setting
- end
-
def update_params
params.require(:project).permit(permitted_project_params)
end
@@ -147,8 +132,7 @@ module Projects
project: [:slug, :name, :organization_slug, :organization_name, :sentry_project_id]
],
- grafana_integration_attributes: [:token, :grafana_url, :enabled],
- tracing_setting_attributes: [:external_url]
+ grafana_integration_attributes: [:token, :grafana_url, :enabled]
}
end
end
diff --git a/app/controllers/projects/tags/releases_controller.rb b/app/controllers/projects/tags/releases_controller.rb
index b852673d82a..adeadf2133e 100644
--- a/app/controllers/projects/tags/releases_controller.rb
+++ b/app/controllers/projects/tags/releases_controller.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+# TODO: remove this file together with FF https://gitlab.com/gitlab-org/gitlab/-/issues/366244
+# also delete view/routes
class Projects::Tags::ReleasesController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 432497850f2..847b1baca10 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -53,7 +53,7 @@ class Projects::TagsController < Projects::ApplicationController
return render_404 unless @tag
- @release = @project.releases.find_or_initialize_by(tag: @tag.name)
+ @release = @project.releases.find_by(tag: @tag.name)
@commit = @repository.commit(@tag.dereferenced_target)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/tracings_controller.rb b/app/controllers/projects/tracings_controller.rb
deleted file mode 100644
index b5c1354c4a9..00000000000
--- a/app/controllers/projects/tracings_controller.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module Projects
- class TracingsController < Projects::ApplicationController
- content_security_policy do |p|
- next if p.directives.blank?
-
- global_frame_src = p.frame_src
-
- p.frame_src -> { frame_src_csp_policy(global_frame_src) }
- end
-
- before_action :authorize_update_environment!
-
- feature_category :tracing
- urgency :low
-
- def show
- render_404 unless Feature.enabled?(:monitor_tracing, @project)
- end
-
- private
-
- def frame_src_csp_policy(global_frame_src)
- external_url = @project&.tracing_setting&.external_url
-
- external_url.presence || global_frame_src
- end
- end
-end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index ed14f66847c..ce51cbb6677 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -18,7 +18,6 @@ class Projects::TreeController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:lazy_load_commits, @project)
- push_frontend_feature_flag(:refactor_blob_viewer, @project)
push_frontend_feature_flag(:highlight_js, @project)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 1e0ef1ad337..37e472050a0 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -36,7 +36,6 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:lazy_load_commits, @project)
- push_frontend_feature_flag(:refactor_blob_viewer, @project)
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:increase_page_size_exponentially, @project)
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index a2b25acae64..4e18e6a3b20 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -3,6 +3,7 @@
module Registrations
class WelcomeController < ApplicationController
include OneTrustCSP
+ include GoogleAnalyticsCSP
layout 'minimal'
skip_before_action :authenticate_user!, :required_signup_info, :check_two_factor_requirement, only: [:show, :update]
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 206580d205a..bb16c2d2098 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -7,6 +7,7 @@ class RegistrationsController < Devise::RegistrationsController
include InvisibleCaptchaOnSignup
include OneTrustCSP
include BizibleCSP
+ include GoogleAnalyticsCSP
layout 'devise'
@@ -220,7 +221,7 @@ class RegistrationsController < Devise::RegistrationsController
return unless member
- Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s)
+ Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s, user: resource)
end
def context_user
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 7d251ba555c..7a7e63f5fc4 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -9,7 +9,7 @@ class SearchController < ApplicationController
RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete].freeze
- track_redis_hll_event :show, name: 'i_search_total'
+ track_event :show, name: 'i_search_total', destinations: [:redis_hll, :snowplow]
around_action :allow_gitaly_ref_name_caching
@@ -42,13 +42,19 @@ class SearchController < ApplicationController
@sort = params[:sort] || default_sort
@search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
- @scope = @search_service.scope
- @without_count = @search_service.without_count?
- @show_snippets = @search_service.show_snippets?
- @search_results = @search_service.search_results
- @search_objects = @search_service.search_objects
- @search_highlight = @search_service.search_highlight
- @aggregations = @search_service.search_aggregations
+
+ @search_level = @search_service.level
+ @search_type = search_type
+
+ @global_search_duration_s = Benchmark.realtime do
+ @scope = @search_service.scope
+ @without_count = @search_service.without_count?
+ @show_snippets = @search_service.show_snippets?
+ @search_results = @search_service.search_results
+ @search_objects = @search_service.search_objects
+ @search_highlight = @search_service.search_highlight
+ @aggregations = @search_service.search_aggregations
+ end
increment_search_counters
end
@@ -144,7 +150,9 @@ class SearchController < ApplicationController
payload[:metadata]['meta.search.filters.state'] = params[:state]
payload[:metadata]['meta.search.force_search_results'] = params[:force_search_results]
payload[:metadata]['meta.search.project_ids'] = params[:project_ids]
- payload[:metadata]['meta.search.search_level'] = params[:search_level]
+ payload[:metadata]['meta.search.type'] = @search_type if @search_type.present?
+ payload[:metadata]['meta.search.level'] = @search_level if @search_level.present?
+ payload[:metadata][:global_search_duration_s] = @global_search_duration_s if @global_search_duration_s.present?
if search_service.abuse_detected?
payload[:metadata]['abuse.confidence'] = Gitlab::Abuse.confidence(:certain)
@@ -203,6 +211,14 @@ class SearchController < ApplicationController
render status: :request_timeout
end
end
+
+ def tracking_namespace_source
+ search_service.project&.namespace || search_service.group
+ end
+
+ def search_type
+ 'basic'
+ end
end
SearchController.prepend_mod_with('SearchController')
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 9000e9c39de..6195d152f00 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -11,6 +11,8 @@ class SessionsController < Devise::SessionsController
include Gitlab::Utils::StrongMemoize
include OneTrustCSP
include BizibleCSP
+ include VerifiesWithEmail
+ include GoogleAnalyticsCSP
skip_before_action :check_two_factor_requirement, only: [:destroy]
skip_before_action :check_password_expiration, only: [:destroy]
diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb
index f7eb2aad9dc..f36b140f3a2 100644
--- a/app/controllers/users/terms_controller.rb
+++ b/app/controllers/users/terms_controller.rb
@@ -4,6 +4,7 @@ module Users
class TermsController < ApplicationController
include InternalRedirect
include OneTrustCSP
+ include GoogleAnalyticsCSP
skip_before_action :authenticate_user!, only: [:index]
skip_before_action :enforce_terms!
@@ -13,6 +14,10 @@ module Users
before_action :terms
+ before_action only: [:index] do
+ push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)
+ end
+
layout 'terms'
feature_category :user_management
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 2799479d922..eaf08cd421b 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -58,7 +58,9 @@ class UsersController < ApplicationController
# Get all keys of a user(params[:username]) in a text format
# Helpful for sysadmins to put in respective servers
def ssh_keys
- render plain: user.all_ssh_keys.join("\n")
+ keys = user.all_ssh_keys.join("\n")
+ keys << "\n" unless keys.empty?
+ render plain: keys
end
def activity
@@ -74,7 +76,9 @@ class UsersController < ApplicationController
# Get all gpg keys of a user(params[:username]) in a text format
def gpg_keys
- render plain: user.gpg_keys.select(&:verified?).map(&:key).join("\n")
+ keys = user.gpg_keys.filter_map { |gpg_key| gpg_key.key if gpg_key.verified? }.join("\n")
+ keys << "\n" unless keys.empty?
+ render plain: keys
end
def groups