diff options
Diffstat (limited to 'app/controllers')
127 files changed, 734 insertions, 397 deletions
diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index 956e03cef07..bab2d5639a7 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -9,4 +9,4 @@ class Admin::ApplicationController < ApplicationController layout 'admin' end -Admin::ApplicationController.prepend_if_ee('EE::Admin::ApplicationController') +Admin::ApplicationController.prepend_mod_with('Admin::ApplicationController') diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 646a6dffd10..80cb04ac496 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -49,7 +49,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController def integrations return not_found unless instance_level_integrations? - @integrations = Service.find_or_initialize_all_non_project_specific(Service.for_instance).sort_by(&:title) + @integrations = Integration.find_or_initialize_all_non_project_specific(Integration.for_instance).sort_by(&:title) end def update @@ -292,4 +292,4 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end end -Admin::ApplicationSettingsController.prepend_if_ee('EE::Admin::ApplicationSettingsController') +Admin::ApplicationSettingsController.prepend_mod_with('Admin::ApplicationSettingsController') diff --git a/app/controllers/admin/cohorts_controller.rb b/app/controllers/admin/cohorts_controller.rb index 9bb73c822b0..c29b5224b09 100644 --- a/app/controllers/admin/cohorts_controller.rb +++ b/app/controllers/admin/cohorts_controller.rb @@ -6,6 +6,6 @@ class Admin::CohortsController < Admin::ApplicationController # Backwards compatibility. Remove it and routing in 14.0 # @see https://gitlab.com/gitlab-org/gitlab/-/issues/299303 def index - redirect_to admin_users_path(tab: 'cohorts') + redirect_to cohorts_admin_users_path end end diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index da89276f5eb..46e5a508a1b 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -24,4 +24,4 @@ class Admin::DashboardController < Admin::ApplicationController end end -Admin::DashboardController.prepend_if_ee('EE::Admin::DashboardController') +Admin::DashboardController.prepend_mod_with('Admin::DashboardController') diff --git a/app/controllers/admin/dev_ops_report_controller.rb b/app/controllers/admin/dev_ops_report_controller.rb index 4178e51fb13..a235af7c538 100644 --- a/app/controllers/admin/dev_ops_report_controller.rb +++ b/app/controllers/admin/dev_ops_report_controller.rb @@ -24,4 +24,4 @@ class Admin::DevOpsReportController < Admin::ApplicationController end end -Admin::DevOpsReportController.prepend_if_ee('EE::Admin::DevOpsReportController') +Admin::DevOpsReportController.prepend_mod_with('Admin::DevOpsReportController') diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index e14cfc236cf..5b33ee78e8c 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -117,4 +117,4 @@ class Admin::GroupsController < Admin::ApplicationController end end -Admin::GroupsController.prepend_if_ee('EE::Admin::GroupsController') +Admin::GroupsController.prepend_mod_with('Admin::GroupsController') diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb index e013b5fbd72..5733929c25e 100644 --- a/app/controllers/admin/health_check_controller.rb +++ b/app/controllers/admin/health_check_controller.rb @@ -14,4 +14,4 @@ class Admin::HealthCheckController < Admin::ApplicationController end end -Admin::HealthCheckController.prepend_if_ee('EE::Admin::HealthCheckController') +Admin::HealthCheckController.prepend_mod_with('Admin::HealthCheckController') diff --git a/app/controllers/admin/integrations_controller.rb b/app/controllers/admin/integrations_controller.rb index 4247446365c..316e6d9aa74 100644 --- a/app/controllers/admin/integrations_controller.rb +++ b/app/controllers/admin/integrations_controller.rb @@ -11,7 +11,7 @@ class Admin::IntegrationsController < Admin::ApplicationController private def find_or_initialize_non_project_specific_integration(name) - Service.find_or_initialize_non_project_specific_integration(name, instance: true) + Integration.find_or_initialize_non_project_specific_integration(name, instance: true) end def scoped_edit_integration_path(integration) diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb index be63bf4c7ce..6cc11b40de0 100644 --- a/app/controllers/admin/labels_controller.rb +++ b/app/controllers/admin/labels_controller.rb @@ -47,7 +47,7 @@ class Admin::LabelsController < Admin::ApplicationController format.html do redirect_to admin_labels_path, status: :found, notice: _('Label was removed') end - format.js + format.js { head :ok } end end diff --git a/app/controllers/admin/plan_limits_controller.rb b/app/controllers/admin/plan_limits_controller.rb index 0a5cdc06d61..88bc5ea0198 100644 --- a/app/controllers/admin/plan_limits_controller.rb +++ b/app/controllers/admin/plan_limits_controller.rb @@ -35,6 +35,7 @@ class Admin::PlanLimitsController < Admin::ApplicationController npm_max_file_size nuget_max_file_size pypi_max_file_size + terraform_module_max_file_size generic_packages_max_file_size ]) end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 39718793c1d..6fd1e9bb70e 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -89,4 +89,4 @@ class Admin::ProjectsController < Admin::ApplicationController end end -Admin::ProjectsController.prepend_if_ee('EE::Admin::ProjectsController') +Admin::ProjectsController.prepend_mod_with('Admin::ProjectsController') diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 576b148fbff..40ec68c1d46 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -7,9 +7,11 @@ class Admin::RunnersController < Admin::ApplicationController feature_category :continuous_integration + NUMBER_OF_RUNNERS_PER_PAGE = 30 + def index finder = Ci::RunnersFinder.new(current_user: current_user, params: params) - @runners = finder.execute + @runners = finder.execute.page(params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE) @active_runners_count = Ci::Runner.online.count @sort = finder.sort_key end diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb index 9f951e838c8..d34773ee4dc 100644 --- a/app/controllers/admin/services_controller.rb +++ b/app/controllers/admin/services_controller.rb @@ -1,28 +1,28 @@ # frozen_string_literal: true class Admin::ServicesController < Admin::ApplicationController - include ServiceParams + include Integrations::Params - before_action :service, only: [:edit, :update] + before_action :integration, only: [:edit, :update] before_action :disable_query_limiting, only: [:index] feature_category :integrations def index - @activated_services = Service.for_template.active.sort_by(&:title) - @existing_instance_types = Service.for_instance.pluck(:type) # rubocop: disable CodeReuse/ActiveRecord + @activated_services = Integration.for_template.active.sort_by(&:title) + @existing_instance_types = Integration.for_instance.pluck(:type) # rubocop: disable CodeReuse/ActiveRecord end def edit - if service.nil? || Service.instance_exists_for?(service.type) + if integration.nil? || Integration.instance_exists_for?(integration.type) redirect_to admin_application_settings_services_path, alert: "Service is unknown or it doesn't exist" end end def update - if service.update(service_params[:service]) - PropagateServiceTemplateWorker.perform_async(service.id) if service.active? # rubocop:disable CodeReuse/Worker + if integration.update(integration_params[:integration]) + PropagateServiceTemplateWorker.perform_async(integration.id) if integration.active? # rubocop:disable CodeReuse/Worker redirect_to admin_application_settings_services_path, notice: 'Application settings saved successfully' @@ -34,9 +34,11 @@ class Admin::ServicesController < Admin::ApplicationController private # rubocop: disable CodeReuse/ActiveRecord - def service - @service ||= Service.find_by(id: params[:id], template: true) + def integration + @integration ||= Integration.find_by(id: params[:id], template: true) + @service ||= @integration # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/329759 end + alias_method :service, :integration # rubocop: enable CodeReuse/ActiveRecord def disable_query_limiting diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 8a090c8ef10..2e9229db56c 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -4,22 +4,29 @@ class Admin::UsersController < Admin::ApplicationController include RoutableActions include Analytics::UniqueVisitsHelper - before_action :user, except: [:index, :new, :create] + before_action :user, except: [:index, :cohorts, :new, :create] before_action :check_impersonation_availability, only: :impersonate before_action :ensure_destroy_prerequisites_met, only: [:destroy] + before_action :check_ban_user_feature_flag, only: [:ban] feature_category :users + PAGINATION_WITH_COUNT_LIMIT = 1000 + def index + return redirect_to cohorts_admin_users_path if params[:tab] == 'cohorts' + @users = User.filter_items(params[:filter]).order_name_asc @users = @users.search_with_secondary_emails(params[:search_query]) if params[:search_query].present? @users = users_with_included_associations(@users) @users = @users.sort_by_attribute(@sort = params[:sort]) @users = @users.page(params[:page]) + @users = @users.without_count if paginate_without_count? + end + def cohorts @cohorts = load_cohorts - - track_cohorts_visit if params[:tab] == 'cohorts' + track_cohorts_visit end def show @@ -124,6 +131,24 @@ class Admin::UsersController < Admin::ApplicationController end end + def ban + result = Users::BanService.new(current_user).execute(user) + + if result[:status] == :success + redirect_back_or_admin_user(notice: _("Successfully banned")) + else + redirect_back_or_admin_user(alert: _("Error occurred. User was not banned")) + end + end + + def unban + if update_user { |user| user.activate } + redirect_back_or_admin_user(notice: _("Successfully unbanned")) + else + redirect_back_or_admin_user(alert: _("Error occurred. User was not unbanned")) + end + end + def unlock if update_user { |user| user.unlock_access! } redirect_back_or_admin_user(alert: _("Successfully unlocked")) @@ -228,6 +253,12 @@ class Admin::UsersController < Admin::ApplicationController protected + def paginate_without_count? + counts = Gitlab::Database::Count.approximate_counts([User]) + + counts[User] > PAGINATION_WITH_COUNT_LIMIT + end + def users_with_included_associations(users) users.includes(:authorized_projects) # rubocop: disable CodeReuse/ActiveRecord end @@ -313,18 +344,20 @@ class Admin::UsersController < Admin::ApplicationController access_denied! unless Gitlab.config.gitlab.impersonation_enabled end + def check_ban_user_feature_flag + access_denied! unless Feature.enabled?(:ban_user_feature_flag) + end + def log_impersonation_event Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username }) end def load_cohorts - if Gitlab::CurrentSettings.usage_ping_enabled - cohorts_results = Rails.cache.fetch('cohorts', expires_in: 1.day) do - CohortsService.new.execute - end - - CohortsSerializer.new.represent(cohorts_results) + cohorts_results = Rails.cache.fetch('cohorts', expires_in: 1.day) do + CohortsService.new.execute end + + CohortsSerializer.new.represent(cohorts_results) end def track_cohorts_visit @@ -334,4 +367,4 @@ class Admin::UsersController < Admin::ApplicationController end end -Admin::UsersController.prepend_if_ee('EE::Admin::UsersController') +Admin::UsersController.prepend_mod_with('Admin::UsersController') diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 607f3435394..00b9fb1060d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,6 +22,7 @@ class ApplicationController < ActionController::Base include Gitlab::Logging::CloudflareHelper include Gitlab::Utils::StrongMemoize include ::Gitlab::WithFeatureCategory + include FlocOptOut before_action :authenticate_user!, except: [:route_not_found] before_action :enforce_terms!, if: :should_enforce_terms? @@ -105,6 +106,10 @@ class ApplicationController < ActionController::Base redirect_back(fallback_location: default, **options) end + def check_if_gl_com_or_dev + render_404 unless ::Gitlab.dev_env_or_com? + end + def not_found render_404 end @@ -207,13 +212,13 @@ class ApplicationController < ActionController::Base end respond_to do |format| - format.any { head status } format.html do render template, layout: "errors", status: status, locals: { message: message } end + format.any { head status } end end @@ -223,8 +228,8 @@ class ApplicationController < ActionController::Base def render_403 respond_to do |format| - format.any { head :forbidden } format.html { render "errors/access_denied", layout: "errors", status: :forbidden } + format.any { head :forbidden } end end @@ -555,4 +560,4 @@ class ApplicationController < ActionController::Base end end -ApplicationController.prepend_ee_mod +ApplicationController.prepend_mod diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 79e45bcf929..1c07245da08 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -71,4 +71,4 @@ class AutocompleteController < ApplicationController end end -AutocompleteController.prepend_if_ee('EE::AutocompleteController') +AutocompleteController.prepend_mod_with('AutocompleteController') diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 347bf1f4fa8..003ed45adb5 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -27,7 +27,9 @@ module Boards list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params) issues = issues_from(list_service) - Issue.move_nulls_to_end(issues) if Gitlab::Database.read_write? + if Gitlab::Database.read_write? && !board.disabled_for?(current_user) + Issue.move_nulls_to_end(issues) + end render_issues(issues, list_service.metadata) end @@ -158,4 +160,4 @@ module Boards end end -Boards::IssuesController.prepend_if_ee('EE::Boards::IssuesController') +Boards::IssuesController.prepend_mod_with('Boards::IssuesController') diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb index 19a4508c061..8ab8337a3ad 100644 --- a/app/controllers/boards/lists_controller.rb +++ b/app/controllers/boards/lists_controller.rb @@ -33,10 +33,10 @@ module Boards service = Boards::Lists::UpdateService.new(board_parent, current_user, update_list_params) result = service.execute(list) - if result[:status] == :success + if result.success? head :ok else - head result[:http_status] + head result.http_status end end @@ -99,4 +99,4 @@ module Boards end end -Boards::ListsController.prepend_if_ee('EE::Boards::ListsController') +Boards::ListsController.prepend_mod_with('Boards::ListsController') diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index c64301f72ba..32de9e69c85 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -62,6 +62,7 @@ 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 @@ -362,4 +363,4 @@ class Clusters::ClustersController < Clusters::BaseController end end -Clusters::ClustersController.prepend_if_ee('EE::Clusters::ClustersController') +Clusters::ClustersController.prepend_mod_with('Clusters::ClustersController') diff --git a/app/controllers/clusters/integrations_controller.rb b/app/controllers/clusters/integrations_controller.rb index a8c7eb10136..17884a55242 100644 --- a/app/controllers/clusters/integrations_controller.rb +++ b/app/controllers/clusters/integrations_controller.rb @@ -24,7 +24,7 @@ module Clusters end def cluster_integration_params - params.require(:integration).permit(:application_type, :enabled) + params.permit(integration: [:enabled, :application_type]).require(:integration) end def cluster diff --git a/app/controllers/concerns/accepts_pending_invitations.rb b/app/controllers/concerns/accepts_pending_invitations.rb index cb66c1a055d..5601b7a7f79 100644 --- a/app/controllers/concerns/accepts_pending_invitations.rb +++ b/app/controllers/concerns/accepts_pending_invitations.rb @@ -6,7 +6,15 @@ module AcceptsPendingInvitations def accept_pending_invitations return unless resource.active_for_authentication? - clear_stored_location_for_resource if resource.accept_pending_invitations!.any? + if resource.pending_invitations.load.any? + resource.accept_pending_invitations! + clear_stored_location_for_resource + after_pending_invitations_hook + end + end + + def after_pending_invitations_hook + # no-op end def clear_stored_location_for_resource diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index 87555a28eb8..4f4b204def8 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -177,4 +177,4 @@ module AuthenticatesWithTwoFactor end end -AuthenticatesWithTwoFactor.prepend_if_ee('EE::AuthenticatesWithTwoFactor') +AuthenticatesWithTwoFactor.prepend_mod_with('AuthenticatesWithTwoFactor') diff --git a/app/controllers/concerns/boards_actions.rb b/app/controllers/concerns/boards_actions.rb index 79e6f027c2f..2f9edfad12d 100644 --- a/app/controllers/concerns/boards_actions.rb +++ b/app/controllers/concerns/boards_actions.rb @@ -7,12 +7,10 @@ module BoardsActions included do include BoardsResponses + before_action :authorize_read_board!, only: [:index, :show] before_action :boards, only: :index before_action :board, only: :show before_action :push_licensed_features, only: [:index, :show] - before_action do - push_frontend_feature_flag(:not_issuable_queries, parent, default_enabled: true) - end end def index @@ -21,7 +19,7 @@ module BoardsActions def show # Add / update the board in the recent visits table - Boards::Visits::CreateService.new(parent, current_user).execute(board) if request.format.html? + board_visit_service.new(parent, current_user).execute(board) if request.format.html? respond_with_board end @@ -54,6 +52,10 @@ module BoardsActions board_klass.to_type end + def board_visit_service + Boards::Visits::CreateService + end + def serializer BoardSerializer.new(current_user: current_user) end @@ -63,4 +65,4 @@ module BoardsActions end end -BoardsActions.prepend_if_ee('EE::BoardsActions') +BoardsActions.prepend_mod_with('BoardsActions') diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb index 7307b7b4f8f..eb7392648a1 100644 --- a/app/controllers/concerns/boards_responses.rb +++ b/app/controllers/concerns/boards_responses.rb @@ -91,4 +91,4 @@ module BoardsResponses end end -BoardsResponses.prepend_if_ee('EE::BoardsResponses') +BoardsResponses.prepend_mod_with('BoardsResponses') diff --git a/app/controllers/concerns/cycle_analytics_params.rb b/app/controllers/concerns/cycle_analytics_params.rb index 50e340dc9b1..b74e343f90b 100644 --- a/app/controllers/concerns/cycle_analytics_params.rb +++ b/app/controllers/concerns/cycle_analytics_params.rb @@ -43,4 +43,4 @@ module CycleAnalyticsParams end end -CycleAnalyticsParams.prepend_if_ee('EE::CycleAnalyticsParams') +CycleAnalyticsParams.prepend_mod_with('CycleAnalyticsParams') diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb index bf38e4ad117..c67e73d4e78 100644 --- a/app/controllers/concerns/enforces_two_factor_authentication.rb +++ b/app/controllers/concerns/enforces_two_factor_authentication.rb @@ -72,4 +72,4 @@ module EnforcesTwoFactorAuthentication end end -EnforcesTwoFactorAuthentication.prepend_if_ee('EE::EnforcesTwoFactorAuthentication') +EnforcesTwoFactorAuthentication.prepend_mod_with('EnforcesTwoFactorAuthentication') diff --git a/app/controllers/concerns/floc_opt_out.rb b/app/controllers/concerns/floc_opt_out.rb new file mode 100644 index 00000000000..3039af02bbb --- /dev/null +++ b/app/controllers/concerns/floc_opt_out.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module FlocOptOut + extend ActiveSupport::Concern + + included do + after_action :set_floc_opt_out_header, unless: :floc_enabled? + end + + def floc_enabled? + Gitlab::CurrentSettings.floc_enabled + end + + def set_floc_opt_out_header + response.headers['Permissions-Policy'] = 'interest-cohort=()' + end +end diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb new file mode 100644 index 00000000000..10122b4c77b --- /dev/null +++ b/app/controllers/concerns/integrations/params.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module Integrations + module Params + extend ActiveSupport::Concern + + ALLOWED_PARAMS_CE = [ + :active, + :add_pusher, + :alert_events, + :api_key, + :api_url, + :bamboo_url, + :branches_to_be_notified, + :labels_to_be_notified, + :labels_to_be_notified_behavior, + :build_key, + :build_type, + :ca_pem, + :channel, + :channels, + :color, + :colorize_messages, + :comment_on_event_enabled, + :comment_detail, + :confidential_issues_events, + :confluence_url, + :datadog_site, + :datadog_env, + :datadog_service, + :default_irc_uri, + :device, + :disable_diffs, + :drone_url, + :enable_ssl_verification, + :external_wiki_url, + :google_iap_service_account_json, + :google_iap_audience_client_id, + :inherit_from_id, + # We're using `issues_events` and `merge_requests_events` + # in the view so we still need to explicitly state them + # here. `Service#event_names` would only give + # `issue_events` and `merge_request_events` (singular!) + # See app/helpers/services_helper.rb for how we + # make those event names plural as special case. + :issues_events, + :issues_url, + :jenkins_url, + :jira_issue_transition_automatic, + :jira_issue_transition_id, + :manual_configuration, + :merge_requests_events, + :mock_service_url, + :namespace, + :new_issue_url, + :notify_only_broken_pipelines, + :password, + :priority, + :project_key, + :project_name, + :project_url, + :recipients, + :restrict_to_branch, + :room, + :send_from_committer_email, + :server, + :server_host, + :server_port, + :sound, + :subdomain, + :teamcity_url, + :token, + :type, + :url, + :user_key, + :username, + :webhook + ].freeze + + # Parameters to ignore if no value is specified + FILTER_BLANK_PARAMS = [:password].freeze + + def integration_params + dynamic_params = @integration.event_channel_names + @integration.event_names # rubocop:disable Gitlab/ModuleWithInstanceVariables + allowed = allowed_integration_params + dynamic_params + return_value = params.permit(:id, integration: allowed, service: allowed) + return_value[:integration] ||= return_value.delete(:service) + param_values = return_value[:integration] + + if param_values.is_a?(ActionController::Parameters) + FILTER_BLANK_PARAMS.each do |param| + param_values.delete(param) if param_values[param].blank? + end + end + + return_value + end + + def allowed_integration_params + ALLOWED_PARAMS_CE + end + end +end + +Integrations::Params.prepend_mod_with('Integrations::Params') diff --git a/app/controllers/concerns/integrations_actions.rb b/app/controllers/concerns/integrations_actions.rb index a3ea39d9c3d..f5a3ec913c2 100644 --- a/app/controllers/concerns/integrations_actions.rb +++ b/app/controllers/concerns/integrations_actions.rb @@ -4,7 +4,7 @@ module IntegrationsActions extend ActiveSupport::Concern included do - include ServiceParams + include Integrations::Params before_action :integration, only: [:edit, :update, :test] end @@ -14,7 +14,7 @@ module IntegrationsActions end def update - saved = integration.update(service_params[:service]) + saved = integration.update(integration_params[:integration]) respond_to do |format| format.html do @@ -49,9 +49,7 @@ module IntegrationsActions private def integration - # Using instance variable `@service` still required as it's used in ServiceParams. - # Should be removed once that is refactored to use `@integration`. - @integration = @service ||= find_or_initialize_non_project_specific_integration(params[:id]) # rubocop:disable Gitlab/ModuleWithInstanceVariables + @integration ||= find_or_initialize_non_project_specific_integration(params[:id]) end def success_message diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb index a35bc19aa37..b803be67d2e 100644 --- a/app/controllers/concerns/internal_redirect.rb +++ b/app/controllers/concerns/internal_redirect.rb @@ -46,4 +46,4 @@ module InternalRedirect end end -InternalRedirect.prepend_if_ee('EE::InternalRedirect') +InternalRedirect.prepend_mod_with('InternalRedirect') diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index 57d4203ad43..929e60a9e77 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -8,9 +8,6 @@ module IssuableActions before_action :authorize_destroy_issuable!, only: :destroy before_action :check_destroy_confirmation!, only: :destroy before_action :authorize_admin_issuable!, only: :bulk_update - before_action do - push_frontend_feature_flag(:not_issuable_queries, @project, default_enabled: true) - end end def show @@ -64,7 +61,7 @@ module IssuableActions end def destroy - Issuable::DestroyService.new(issuable.project, current_user).execute(issuable) + Issuable::DestroyService.new(project: issuable.project, current_user: current_user).execute(issuable) name = issuable.human_class_name flash[:notice] = "The #{name} was successfully deleted." @@ -262,4 +259,4 @@ module IssuableActions # rubocop:enable Gitlab/ModuleWithInstanceVariables end -IssuableActions.prepend_if_ee('EE::IssuableActions') +IssuableActions.prepend_mod_with('IssuableActions') diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index 3f5f3b6e9df..d2d2e656af8 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -158,4 +158,4 @@ module IssuableCollections # rubocop:enable Gitlab/ModuleWithInstanceVariables end -IssuableCollections.prepend_if_ee('EE::IssuableCollections') +IssuableCollections.prepend_mod_with('IssuableCollections') diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb index 7ed66027da3..ca2979a5a29 100644 --- a/app/controllers/concerns/issuable_collections_action.rb +++ b/app/controllers/concerns/issuable_collections_action.rb @@ -32,10 +32,6 @@ module IssuableCollectionsAction private - def set_not_query_feature_flag(object = nil) - push_frontend_feature_flag(:not_issuable_queries, object, default_enabled: true) - end - def sorting_field case action_name when 'issues' diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb index bc3fd32759f..55e0ed8cd42 100644 --- a/app/controllers/concerns/lfs_request.rb +++ b/app/controllers/concerns/lfs_request.rb @@ -136,4 +136,4 @@ module LfsRequest end end -LfsRequest.prepend_if_ee('EE::LfsRequest') +LfsRequest.prepend_mod_with('LfsRequest') diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 7bbee8ba79e..20861afbb88 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -186,3 +186,5 @@ module MembershipActions end end end + +MembershipActions.prepend_mod_with('MembershipActions') diff --git a/app/controllers/concerns/page_limiter.rb b/app/controllers/concerns/page_limiter.rb index 3c280fa4f12..362b02e5856 100644 --- a/app/controllers/concerns/page_limiter.rb +++ b/app/controllers/concerns/page_limiter.rb @@ -46,7 +46,7 @@ module PageLimiter if params[:page].present? && params[:page].to_i > max_page_number record_page_limit_interception - raise PageOutOfBoundsError.new(max_page_number) + raise PageOutOfBoundsError, max_page_number end end diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb index 4ea07c814ef..f1f5a1179c9 100644 --- a/app/controllers/concerns/renders_commits.rb +++ b/app/controllers/concerns/renders_commits.rb @@ -23,6 +23,7 @@ module RendersCommits def prepare_commits_for_rendering(commits) commits.each(&:lazy_author) # preload commits' authors + commits.each(&:lazy_latest_pipeline) Banzai::CommitRenderer.render(commits, @project, current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb index c92b1cecaaa..e98c1a30887 100644 --- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -35,6 +35,6 @@ module RequiresWhitelistedMonitoringClient end def render_404 - render file: Rails.root.join('public', '404'), layout: false, status: '404' + render "errors/not_found", layout: "errors", status: :not_found end end diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb index bc2e7fba288..7257378f465 100644 --- a/app/controllers/concerns/routable_actions.rb +++ b/app/controllers/concerns/routable_actions.rb @@ -56,4 +56,4 @@ module RoutableActions end end -RoutableActions.prepend_if_ee('EE::RoutableActions') +RoutableActions.prepend_mod_with('RoutableActions') diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb deleted file mode 100644 index 7c57d321c80..00000000000 --- a/app/controllers/concerns/service_params.rb +++ /dev/null @@ -1,101 +0,0 @@ -# frozen_string_literal: true - -module ServiceParams - extend ActiveSupport::Concern - - ALLOWED_PARAMS_CE = [ - :active, - :add_pusher, - :alert_events, - :api_key, - :api_url, - :api_version, - :bamboo_url, - :branches_to_be_notified, - :labels_to_be_notified, - :build_key, - :build_type, - :ca_pem, - :channel, - :channels, - :color, - :colorize_messages, - :comment_on_event_enabled, - :comment_detail, - :confidential_issues_events, - :confluence_url, - :datadog_site, - :datadog_env, - :datadog_service, - :default_irc_uri, - :device, - :disable_diffs, - :drone_url, - :enable_ssl_verification, - :external_wiki_url, - :google_iap_service_account_json, - :google_iap_audience_client_id, - :inherit_from_id, - # We're using `issues_events` and `merge_requests_events` - # in the view so we still need to explicitly state them - # here. `Service#event_names` would only give - # `issue_events` and `merge_request_events` (singular!) - # See app/helpers/services_helper.rb for how we - # make those event names plural as special case. - :issues_events, - :issues_url, - :jenkins_url, - :jira_issue_transition_automatic, - :jira_issue_transition_id, - :manual_configuration, - :merge_requests_events, - :mock_service_url, - :namespace, - :new_issue_url, - :notify, - :notify_only_broken_pipelines, - :password, - :priority, - :project_key, - :project_name, - :project_url, - :recipients, - :restrict_to_branch, - :room, - :send_from_committer_email, - :server, - :server_host, - :server_port, - :sound, - :subdomain, - :teamcity_url, - :token, - :type, - :url, - :user_key, - :username, - :webhook - ].freeze - - # Parameters to ignore if no value is specified - FILTER_BLANK_PARAMS = [:password].freeze - - def service_params - dynamic_params = @service.event_channel_names + @service.event_names # rubocop:disable Gitlab/ModuleWithInstanceVariables - service_params = params.permit(:id, service: allowed_service_params + dynamic_params) - - if service_params[:service].is_a?(ActionController::Parameters) - FILTER_BLANK_PARAMS.each do |param| - service_params[:service].delete(param) if service_params[:service][param].blank? - end - end - - service_params - end - - def allowed_service_params - ALLOWED_PARAMS_CE - end -end - -ServiceParams.prepend_if_ee('EE::ServiceParams') diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index 60ff0a12d0c..fc4f9aa3409 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -115,9 +115,6 @@ module WikiActions @error = response.message render 'shared/wikis/edit' end - rescue WikiPage::PageChangedError, WikiPage::PageRenameError => e - @error = e.message - render 'shared/wikis/edit' end # rubocop:enable Gitlab/ModuleWithInstanceVariables @@ -141,8 +138,8 @@ module WikiActions # rubocop:disable Gitlab/ModuleWithInstanceVariables def history if page - @page_versions = Kaminari.paginate_array(page.versions(page: params[:page].to_i), - total_count: page.count_versions) + @commits = Kaminari.paginate_array(page.versions(page: params[:page].to_i), + total_count: page.count_versions) .page(params[:page]) render 'shared/wikis/history' diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb index 93ded59900d..dc2265e063a 100644 --- a/app/controllers/concerns/with_performance_bar.rb +++ b/app/controllers/concerns/with_performance_bar.rb @@ -20,12 +20,12 @@ module WithPerformanceBar end def cookie_or_default_value - return false unless Gitlab::PerformanceBar.enabled_for_user?(current_user) + cookie_enabled = if cookies[:perf_bar_enabled].present? + cookies[:perf_bar_enabled] == 'true' + else + cookies[:perf_bar_enabled] = 'true' if Rails.env.development? + end - if cookies[:perf_bar_enabled].present? - cookies[:perf_bar_enabled] == 'true' - else - cookies[:perf_bar_enabled] = 'true' if Rails.env.development? - end + cookie_enabled && Gitlab::PerformanceBar.allowed_for_user?(current_user) end end diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index c42c9827eaf..e82500912fa 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -27,7 +27,7 @@ class ConfirmationsController < Devise::ConfirmationsController else Gitlab::AppLogger.info("Email Confirmed: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip}") flash[:notice] = flash[:notice] + _(" Please sign in.") - new_session_path(:user, anchor: 'login-pane') + new_session_path(:user, anchor: 'login-pane', invite_email: resource.email) end end @@ -36,4 +36,4 @@ class ConfirmationsController < Devise::ConfirmationsController end end -ConfirmationsController.prepend_if_ee('EE::ConfirmationsController') +ConfirmationsController.prepend_mod_with('ConfirmationsController') diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index aa3592ff209..7cb39625371 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -116,4 +116,4 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController end end -Dashboard::ProjectsController.prepend_if_ee('EE::Dashboard::ProjectsController') +Dashboard::ProjectsController.prepend_mod_with('Dashboard::ProjectsController') diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 29cb60ad3cc..227dd0591d4 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -11,11 +11,10 @@ class DashboardController < Dashboard::ApplicationController before_action :projects, only: [:issues, :merge_requests] before_action :set_show_full_reference, only: [:issues, :merge_requests] before_action :check_filters_presence!, only: [:issues, :merge_requests] - before_action :set_not_query_feature_flag respond_to :html - feature_category :audit_events, [:activity] + feature_category :users, [:activity] feature_category :issue_tracking, [:issues, :issues_calendar] feature_category :code_review, [:merge_requests] diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index f6671f7250f..5ef973e9bf3 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -122,4 +122,4 @@ class Explore::ProjectsController < Explore::ApplicationController end end -Explore::ProjectsController.prepend_if_ee('EE::Explore::ProjectsController') +Explore::ProjectsController.prepend_mod_with('Explore::ProjectsController') diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 38bfb5ef2f8..725d8b62c77 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -109,6 +109,8 @@ class GraphqlController < ApplicationController end end + # When modifying the context, also update GraphqlChannel#context if needed + # so that we have similar context when executing queries, mutations, and subscriptions def context api_user = !!sessionless_user? @context ||= { diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index a504d2ce991..a3bbfc8be0d 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -72,4 +72,4 @@ class Groups::ApplicationController < ApplicationController end end -Groups::ApplicationController.prepend_if_ee('EE::Groups::ApplicationController') +Groups::ApplicationController.prepend_mod_with('Groups::ApplicationController') diff --git a/app/controllers/groups/autocomplete_sources_controller.rb b/app/controllers/groups/autocomplete_sources_controller.rb new file mode 100644 index 00000000000..5270a718952 --- /dev/null +++ b/app/controllers/groups/autocomplete_sources_controller.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +class Groups::AutocompleteSourcesController < Groups::ApplicationController + feature_category :subgroups, [:members] + feature_category :issue_tracking, [:issues, :labels, :milestones, :commands] + feature_category :code_review, [:merge_requests] + + def members + render json: ::Groups::ParticipantsService.new(@group, current_user).execute(target) + end + + def issues + render json: issuable_serializer.represent( + autocomplete_service.issues(confidential_only: params[:confidential_only], issue_types: params[:issue_types]), + parent_group: @group + ) + end + + def merge_requests + render json: issuable_serializer.represent(autocomplete_service.merge_requests, parent_group: @group) + end + + def labels + render json: autocomplete_service.labels_as_hash(target) + end + + def commands + render json: autocomplete_service.commands(target) + end + + def milestones + render json: autocomplete_service.milestones + end + + private + + def autocomplete_service + @autocomplete_service ||= ::Groups::AutocompleteService.new(@group, current_user, params) + end + + def issuable_serializer + GroupIssuableAutocompleteSerializer.new + end + + # rubocop: disable CodeReuse/ActiveRecord + def target + QuickActions::TargetService + .new(nil, current_user, group: @group) + .execute(params[:type], params[:type_id]) + end + # rubocop: enable CodeReuse/ActiveRecord +end + +Groups::AutocompleteSourcesController.prepend_mod diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index be38fe25842..e1f09d73739 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -5,7 +5,6 @@ class Groups::BoardsController < Groups::ApplicationController include RecordUserLastActivity include Gitlab::Utils::StrongMemoize - before_action :authorize_read_board!, only: [:index, :show] before_action :assign_endpoint_vars before_action do push_frontend_feature_flag(:graphql_board_lists, group, default_enabled: false) diff --git a/app/controllers/groups/email_campaigns_controller.rb b/app/controllers/groups/email_campaigns_controller.rb index 4ce7d86be3c..c1e3ce519cc 100644 --- a/app/controllers/groups/email_campaigns_controller.rb +++ b/app/controllers/groups/email_campaigns_controller.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class Groups::EmailCampaignsController < Groups::ApplicationController - include InProductMarketingHelper - EMAIL_CAMPAIGNS_SCHEMA_URL = 'iglu:com.gitlab/email_campaigns/jsonschema/1-0-0' feature_category :navigation @@ -18,11 +16,13 @@ class Groups::EmailCampaignsController < Groups::ApplicationController def track_click if Gitlab.com? + message = Gitlab::Email::Message::InProductMarketing.for(@track).new(group: group, series: @series) + data = { namespace_id: group.id, track: @track.to_s, series: @series, - subject_line: subject_line(@track, @series) + subject_line: message.subject_line } context = SnowplowTracker::SelfDescribingJson.new(EMAIL_CAMPAIGNS_SCHEMA_URL, data) diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 5df7ff0632a..c2ac56ccc63 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -4,6 +4,7 @@ class Groups::GroupMembersController < Groups::ApplicationController include MembershipActions include MembersPresentation include SortingHelper + include Gitlab::Utils::StrongMemoize MEMBER_PER_PAGE_LIMIT = 50 @@ -21,16 +22,17 @@ class Groups::GroupMembersController < Groups::ApplicationController feature_category :authentication_and_authorization + helper_method :can_manage_members? + def index + preload_max_access @sort = params[:sort].presence || sort_value_name - @project = @group.projects.find(params[:project_id]) if params[:project_id] - @members = GroupMembersFinder .new(@group, current_user, params: filter_params) .execute(include_relations: requested_relations) - if can_manage_members + if can_manage_members? @skip_groups = @group.related_group_ids @invited_members = @members.invite @@ -52,8 +54,18 @@ class Groups::GroupMembersController < Groups::ApplicationController private - def can_manage_members - can?(current_user, :admin_group_member, @group) + def preload_max_access + return unless current_user + + # this allows the can? against admin type queries in this action to + # only perform the query once, even if it is cached + current_user.max_access_for_group[@group.id] = @group.max_member_access(current_user) + end + + def can_manage_members? + strong_memoize(:can_manage_members) do + can?(current_user, :admin_group_member, @group) + end end def present_invited_members(invited_members) @@ -77,4 +89,4 @@ class Groups::GroupMembersController < Groups::ApplicationController end end -Groups::GroupMembersController.prepend_if_ee('EE::Groups::GroupMembersController') +Groups::GroupMembersController.prepend_mod_with('Groups::GroupMembersController') diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 84dc570a1e9..e9dce3947dd 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -21,7 +21,7 @@ class Groups::MilestonesController < Groups::ApplicationController end def new - @milestone = Milestone.new + @noteable = @milestone = Milestone.new end def create @@ -70,7 +70,7 @@ class Groups::MilestonesController < Groups::ApplicationController end def milestone - @milestone = group.milestones.find_by_iid(params[:id]) + @noteable = @milestone ||= group.milestones.find_by_iid(params[:id]) render_404 unless @milestone end @@ -95,4 +95,4 @@ class Groups::MilestonesController < Groups::ApplicationController end end -Groups::MilestonesController.prepend_if_ee('EE::Groups::MilestonesController') +Groups::MilestonesController.prepend_mod_with('Groups::MilestonesController') diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index dbfd31ebcad..b02b0e85d38 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -10,7 +10,6 @@ class Groups::RunnersController < Groups::ApplicationController feature_category :continuous_integration def show - render 'shared/runners/show' end def edit diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index f1a6bcbe825..88c709e3f53 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -100,4 +100,4 @@ module Groups end end -Groups::Settings::CiCdController.prepend_if_ee('EE::Groups::Settings::CiCdController') +Groups::Settings::CiCdController.prepend_mod_with('Groups::Settings::CiCdController') diff --git a/app/controllers/groups/settings/integrations_controller.rb b/app/controllers/groups/settings/integrations_controller.rb index c3c93fe238a..8e3b2cb5d1b 100644 --- a/app/controllers/groups/settings/integrations_controller.rb +++ b/app/controllers/groups/settings/integrations_controller.rb @@ -12,11 +12,11 @@ module Groups layout 'group_settings' def index - @integrations = Service.find_or_initialize_all_non_project_specific(Service.for_group(group)).sort_by(&:title) + @integrations = Integration.find_or_initialize_all_non_project_specific(Integration.for_group(group)).sort_by(&:title) end def edit - @default_integration = Service.default_integration(integration.type, group) + @default_integration = Integration.default_integration(integration.type, group) super end @@ -24,7 +24,7 @@ module Groups private def find_or_initialize_non_project_specific_integration(name) - Service.find_or_initialize_non_project_specific_integration(name, group_id: group.id) + Integration.find_or_initialize_non_project_specific_integration(name, group_id: group.id) end def scoped_edit_integration_path(integration) diff --git a/app/controllers/groups/settings/packages_and_registries_controller.rb b/app/controllers/groups/settings/packages_and_registries_controller.rb index 90fb6497e20..c44e0727ff9 100644 --- a/app/controllers/groups/settings/packages_and_registries_controller.rb +++ b/app/controllers/groups/settings/packages_and_registries_controller.rb @@ -9,7 +9,7 @@ module Groups feature_category :package_registry - def index + def show end private diff --git a/app/controllers/groups/variables_controller.rb b/app/controllers/groups/variables_controller.rb index 75bb6975c6e..00ddb8d736c 100644 --- a/app/controllers/groups/variables_controller.rb +++ b/app/controllers/groups/variables_controller.rb @@ -57,4 +57,4 @@ module Groups end end -Groups::VariablesController.prepend_if_ee('EE::Groups::VariablesController') +Groups::VariablesController.prepend_mod_with('Groups::VariablesController') diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 63f138aa462..a755d242d4a 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -35,10 +35,6 @@ class GroupsController < Groups::ApplicationController push_frontend_feature_flag(:vue_issuables_list, @group) end - before_action do - set_not_query_feature_flag(@group) - end - before_action :export_rate_limit, only: [:export, :download_export] helper_method :captcha_required? @@ -53,10 +49,9 @@ class GroupsController < Groups::ApplicationController feature_category :subgroups, [ :index, :new, :create, :show, :edit, :update, - :destroy, :details, :transfer + :destroy, :details, :transfer, :activity ] - feature_category :audit_events, [:activity] feature_category :issue_tracking, [:issues, :issues_calendar, :preview_markdown] feature_category :code_review, [:merge_requests, :unfoldered_environment_names] feature_category :projects, [:projects] @@ -197,7 +192,7 @@ class GroupsController < Groups::ApplicationController def unfoldered_environment_names respond_to do |format| format.json do - render json: EnvironmentNamesFinder.new(@group, current_user).execute + render json: Environments::EnvironmentNamesFinder.new(@group, current_user).execute end end end @@ -369,4 +364,4 @@ class GroupsController < Groups::ApplicationController end end -GroupsController.prepend_if_ee('EE::GroupsController') +GroupsController.prepend_mod_with('GroupsController') diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb index 87cda723895..1121ecfb65c 100644 --- a/app/controllers/import/base_controller.rb +++ b/app/controllers/import/base_controller.rb @@ -97,7 +97,7 @@ class Import::BaseController < ApplicationController group = Groups::NestedCreateService.new(current_user, group_path: names).execute group.errors.any? ? current_user.namespace : group - rescue => e + rescue StandardError => e Gitlab::AppLogger.error(e) current_user.namespace diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index 17f937a3dfd..9f91f3a1e1c 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -15,7 +15,7 @@ class Import::FogbugzController < Import::BaseController def callback begin res = Gitlab::FogbugzImport::Client.new(import_params.to_h.symbolize_keys) - rescue + 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') end diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index beb3e92b5ea..22bcd14d664 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -265,4 +265,4 @@ class Import::GithubController < Import::BaseController end end -Import::GithubController.prepend_if_ee('EE::Import::GithubController') +Import::GithubController.prepend_mod_with('Import::GithubController') diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 0eb08d2d0ad..0a9a9e03e94 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -3,10 +3,10 @@ class InvitesController < ApplicationController include Gitlab::Utils::StrongMemoize + prepend_before_action :authenticate_user!, :track_invite_join_click, only: :show before_action :member before_action :ensure_member_exists before_action :invite_details - before_action :set_invite_type, only: :show skip_before_action :authenticate_user!, only: :decline helper_method :member?, :current_user_matches_invite? @@ -16,18 +16,12 @@ class InvitesController < ApplicationController feature_category :authentication_and_authorization def show - experiment('members/invite_email', actor: member).track(:opened) if initial_invite_email? - accept if skip_invitation_prompt? end def accept if member.accept_invite!(current_user) - experiment('members/invite_email', actor: member).track(:accepted) if initial_invite_email? - session.delete(:invite_type) - - redirect_to invite_details[:path], notice: _("You have been granted %{member_human_access} access to %{title} %{name}.") % - { member_human_access: member.human_access, title: invite_details[:title], name: invite_details[:name] } + redirect_to invite_details[:path], notice: helpers.invite_accepted_notice(member) else redirect_back_or_default(options: { alert: _("The invitation could not be accepted.") }) end @@ -53,14 +47,6 @@ class InvitesController < ApplicationController private - def set_invite_type - session[:invite_type] = params[:invite_type] if params[:invite_type].in?([Members::InviteEmailExperiment::INVITE_TYPE]) - end - - def initial_invite_email? - session[:invite_type] == Members::InviteEmailExperiment::INVITE_TYPE - end - def skip_invitation_prompt? !member? && current_user_matches_invite? end @@ -85,21 +71,48 @@ class InvitesController < ApplicationController def ensure_member_exists return if member - render_404 + redirect_back_or_default(options: { alert: _("The invitation can not be found with the provided invite token.") }) + end + + def track_invite_join_click + experiment('members/invite_email', actor: member).track(:join_clicked) if member && Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type]) end def authenticate_user! return if current_user - store_location_for :user, request.fullpath + store_location_for(:user, invite_landing_url) if member if user_sign_up? - redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.") + set_session_invite_params + + experiment(:invite_signup_page_interaction, actor: member) do |experiment_instance| + set_originating_member_id if experiment_instance.enabled? + + experiment_instance.use do + redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.") + end + experiment_instance.try do + redirect_to new_users_sign_up_invite_path(invite_email: member.invite_email) + end + + experiment_instance.track(:view) + end else redirect_to new_user_session_path(sign_in_redirect_params), notice: sign_in_notice end end + def set_session_invite_params + session[:invite_email] = member.invite_email + + set_originating_member_id if Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type]) + end + + def set_originating_member_id + session[:originating_member_id] = member.id + end + def sign_in_redirect_params member ? { invite_email: member.invite_email } : {} end @@ -116,6 +129,10 @@ class InvitesController < ApplicationController end end + def invite_landing_url + root_url + invite_details[:path] + end + def invite_details @invite_details ||= case member.source when Project @@ -123,14 +140,14 @@ class InvitesController < ApplicationController name: member.source.full_name, url: project_url(member.source), title: _("project"), - path: project_path(member.source) + path: member.source.activity_path } when Group { name: member.source.name, url: group_url(member.source), title: _("group"), - path: group_path(member.source) + path: member.source.activity_path } end end diff --git a/app/controllers/jira_connect/application_controller.rb b/app/controllers/jira_connect/application_controller.rb index 9c311f92b69..a6529ecb4ce 100644 --- a/app/controllers/jira_connect/application_controller.rb +++ b/app/controllers/jira_connect/application_controller.rb @@ -24,7 +24,7 @@ class JiraConnect::ApplicationController < ApplicationController # Make sure `qsh` claim matches the current request render_403 unless payload['qsh'] == Atlassian::Jwt.create_query_string_hash(request.url, request.method, jira_connect_base_url) - rescue + rescue StandardError render_403 end diff --git a/app/controllers/ldap/omniauth_callbacks_controller.rb b/app/controllers/ldap/omniauth_callbacks_controller.rb index ebc35448964..6aa46b8e4c3 100644 --- a/app/controllers/ldap/omniauth_callbacks_controller.rb +++ b/app/controllers/ldap/omniauth_callbacks_controller.rb @@ -38,4 +38,4 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController end end -Ldap::OmniauthCallbacksController.prepend_if_ee('EE::Ldap::OmniauthCallbacksController') +Ldap::OmniauthCallbacksController.prepend_mod_with('Ldap::OmniauthCallbacksController') diff --git a/app/controllers/oauth/jira/authorizations_controller.rb b/app/controllers/oauth/jira/authorizations_controller.rb index f23149c8544..8169b5fcbb0 100644 --- a/app/controllers/oauth/jira/authorizations_controller.rb +++ b/app/controllers/oauth/jira/authorizations_controller.rb @@ -16,7 +16,7 @@ class Oauth::Jira::AuthorizationsController < ApplicationController redirect_to oauth_authorization_path(client_id: params['client_id'], response_type: 'code', - scope: params['scope'], + scope: normalize_scope(params['scope']), redirect_uri: oauth_jira_callback_url) end @@ -48,4 +48,12 @@ class Oauth::Jira::AuthorizationsController < ApplicationController rescue Doorkeeper::Errors::DoorkeeperError => e render status: :unauthorized, body: e.type end + + private + + # When using the GitHub Enterprise connector in Jira we receive the "repo" scope, + # this doesn't exist in GitLab but we can map it to our "api" scope. + def normalize_scope(scope) + scope == 'repo' ? 'api' : scope + end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index af502c083d7..31f404a9974 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -289,4 +289,4 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end end -OmniauthCallbacksController.prepend_if_ee('EE::OmniauthCallbacksController') +OmniauthCallbacksController.prepend_mod_with('OmniauthCallbacksController') diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index bc6975f8953..2c0ed825daa 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -69,4 +69,4 @@ class PasswordsController < Devise::PasswordsController end end -PasswordsController.prepend_if_ee('EE::PasswordsController') +PasswordsController.prepend_mod_with('PasswordsController') diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb index d8419be9f23..bd52ef0b0d4 100644 --- a/app/controllers/profiles/accounts_controller.rb +++ b/app/controllers/profiles/accounts_controller.rb @@ -37,4 +37,4 @@ class Profiles::AccountsController < Profiles::ApplicationController end end -Profiles::AccountsController.prepend_if_ee('EE::Profiles::AccountsController') +Profiles::AccountsController.prepend_mod_with('Profiles::AccountsController') diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 251967a7dff..ba539ef808d 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -60,4 +60,4 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController end end -Profiles::PersonalAccessTokensController.prepend_if_ee('EE::Profiles::PersonalAccessTokensController') +Profiles::PersonalAccessTokensController.prepend_mod_with('Profiles::PersonalAccessTokensController') diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index 45bab5f6cd1..adecb56ea38 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -55,4 +55,4 @@ class Profiles::PreferencesController < Profiles::ApplicationController end end -Profiles::PreferencesController.prepend_if_ee('::EE::Profiles::PreferencesController') +Profiles::PreferencesController.prepend_mod_with('Profiles::PreferencesController') diff --git a/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb new file mode 100644 index 00000000000..7b4f6739a9b --- /dev/null +++ b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class Projects::Analytics::CycleAnalytics::StagesController < Projects::ApplicationController + respond_to :json + + feature_category :planning_analytics + + before_action :authorize_read_cycle_analytics! + before_action :only_default_value_stream_is_allowed! + + def index + result = list_service.execute + + if result.success? + render json: cycle_analytics_configuration(result.payload[:stages]) + else + render json: { message: result.message }, status: result.http_status + end + end + + private + + def only_default_value_stream_is_allowed! + render_404 if params[:value_stream_id] != Analytics::CycleAnalytics::Stages::BaseService::DEFAULT_VALUE_STREAM_NAME + end + + def value_stream + Analytics::CycleAnalytics::ProjectValueStream.build_default_value_stream(@project) + end + + def list_params + { value_stream: value_stream } + end + + def list_service + Analytics::CycleAnalytics::Stages::ListService.new(parent: @project, current_user: current_user, params: list_params) + end + + def cycle_analytics_configuration(stages) + stage_presenters = stages.map { |s| ::Analytics::CycleAnalytics::StagePresenter.new(s) } + + Analytics::CycleAnalytics::ConfigurationEntity.new(stages: stage_presenters) + end +end diff --git a/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb b/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb new file mode 100644 index 00000000000..03dcb164d94 --- /dev/null +++ b/app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class Projects::Analytics::CycleAnalytics::ValueStreamsController < Projects::ApplicationController + respond_to :json + + feature_category :planning_analytics + + before_action :authorize_read_cycle_analytics! + + def index + # FOSS users can only see the default value stream + value_streams = [Analytics::CycleAnalytics::ProjectValueStream.build_default_value_stream(@project)] + + render json: Analytics::CycleAnalytics::ValueStreamSerializer.new.represent(value_streams) + end +end diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index 001967b8bb4..7c419cac1cc 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -49,4 +49,4 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController end end -Projects::AutocompleteSourcesController.prepend_if_ee('EE::Projects::AutocompleteSourcesController') +Projects::AutocompleteSourcesController.prepend_mod_with('Projects::AutocompleteSourcesController') diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb index 2c7c49b4250..1df7b9ed165 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -20,7 +20,7 @@ class Projects::BlameController < Projects::ApplicationController environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit } environment_params[:find_latest] = true - @environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last + @environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last @blame = Gitlab::Blame.new(@blob, @commit) @blame = Gitlab::View::Presenter::Factory.new(@blame, project: @project, path: @path).fabricate! diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index a398fc56a35..dbe628cb43a 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -31,19 +31,23 @@ class Projects::BlobController < Projects::ApplicationController before_action :editor_variables, except: [:show, :preview, :diff] before_action :validate_diff_params, only: :diff before_action :set_last_commit_sha, only: [:edit, :update] - before_action :record_experiment, only: :new + before_action :track_experiment, only: :create track_redis_hll_event :create, :update, name: 'g_edit_by_sfe' feature_category :source_code_management + before_action do + push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml) + end + def new commit unless @repository.empty? end def create create_commit(Files::CreateService, success_notice: _("The file has been successfully created."), - success_path: -> { project_blob_path(@project, File.join(@branch_name, @file_path)) }, + success_path: -> { create_success_path }, failure_view: :new, failure_path: project_new_blob_path(@project, @ref)) end @@ -214,7 +218,7 @@ class Projects::BlobController < Projects::ApplicationController def show_html environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit } environment_params[:find_latest] = true - @environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last + @environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last @last_commit = @repository.last_commit_for_path(@commit.id, @blob.path, literal_pathspec: true) @code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path) @@ -262,9 +266,17 @@ class Projects::BlobController < Projects::ApplicationController current_user&.id end - def record_experiment - return unless params[:file_name] == @project.ci_config_path_or_default && @project.namespace.recent? + def create_success_path + if params[:code_quality_walkthrough] + project_pipelines_path(@project, code_quality_walkthrough: true) + else + project_blob_path(@project, File.join(@branch_name, @file_path)) + end + end + + def track_experiment + return unless params[:code_quality_walkthrough] - record_experiment_user(:ci_syntax_templates_b, namespace_id: @project.namespace_id) + experiment(:code_quality_walkthrough, namespace: @project.root_ancestor).track(:commit_created) end end diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 349649c7b35..9a3e9437426 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -5,7 +5,6 @@ class Projects::BoardsController < Projects::ApplicationController include IssuableCollections before_action :check_issues_available! - before_action :authorize_read_board!, only: [:index, :show] before_action :assign_endpoint_vars before_action do push_frontend_feature_flag(:swimlanes_buffered_rendering, project, default_enabled: :yaml) diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index 754e2ccf4f9..6e31816bc99 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -3,11 +3,9 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController before_action :check_can_collaborate! before_action do - push_frontend_feature_flag(:ci_config_visualization_tab, @project, default_enabled: :yaml) - push_frontend_feature_flag(:ci_config_merged_tab, @project, default_enabled: :yaml) - push_frontend_feature_flag(:pipeline_status_for_pipeline_editor, @project, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_editor_empty_state_action, @project, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_editor_branch_switcher, @project, default_enabled: :yaml) + push_frontend_feature_flag(:pipeline_editor_drawer, @project, default_enabled: :yaml) end feature_category :pipeline_authoring diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 0c3ff07bc76..863715429ff 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -24,7 +24,7 @@ class Projects::CommitController < Projects::ApplicationController end BRANCH_SEARCH_LIMIT = 1000 - COMMIT_DIFFS_PER_PAGE = 75 + COMMIT_DIFFS_PER_PAGE = 20 feature_category :source_code_management @@ -49,7 +49,7 @@ class Projects::CommitController < Projects::ApplicationController end def diff_files - render json: { html: view_to_html_string('projects/commit/diff_files', diffs: @diffs, environment: @environment) } + render template: 'projects/commit/diff_files', layout: false, locals: { diffs: @diffs, environment: @environment } end # rubocop: disable CodeReuse/ActiveRecord @@ -167,7 +167,7 @@ class Projects::CommitController < Projects::ApplicationController @diffs = commit.diffs(opts) @notes_count = commit.notes.count - @environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last + @environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 221bc16e256..28a87f83451 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -26,6 +26,10 @@ class Projects::CompareController < Projects::ApplicationController feature_category :source_code_management + # Diffs may be pretty chunky, the less is better in this endpoint. + # Pagination design guides: https://design.gitlab.com/components/pagination/#behavior + COMMIT_DIFFS_PER_PAGE = 20 + def index end @@ -132,7 +136,7 @@ class Projects::CompareController < Projects::ApplicationController if compare environment_params = source_project.repository.branch_exists?(head_ref) ? { ref: head_ref } : { commit: compare.commit } environment_params[:find_latest] = true - @environment = EnvironmentsByDeploymentsFinder.new(source_project, current_user, environment_params).execute.last + @environment = ::Environments::EnvironmentsByDeploymentsFinder.new(source_project, current_user, environment_params).execute.last end end diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 92483607e65..76de9a83c87 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -264,4 +264,4 @@ class Projects::EnvironmentsController < Projects::ApplicationController end end -Projects::EnvironmentsController.prepend_if_ee('EE::Projects::EnvironmentsController') +Projects::EnvironmentsController.prepend_mod_with('Projects::EnvironmentsController') diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 9fc8e8c063b..8fa3635a737 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -131,4 +131,4 @@ class Projects::ForksController < Projects::ApplicationController end end -Projects::ForksController.prepend_if_ee('EE::Projects::ForksController') +Projects::ForksController.prepend_mod_with('Projects::ForksController') diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb index c6c90ffaba2..27893fe510d 100644 --- a/app/controllers/projects/group_links_controller.rb +++ b/app/controllers/projects/group_links_controller.rb @@ -60,4 +60,4 @@ class Projects::GroupLinksController < Projects::ApplicationController end end -Projects::GroupLinksController.prepend_if_ee('EE::Projects::GroupLinksController') +Projects::GroupLinksController.prepend_mod_with('Projects::GroupLinksController') diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index 8dabf3e640b..b87bfc58f8b 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -32,6 +32,7 @@ class Projects::HooksController < Projects::ApplicationController end def edit + redirect_to(action: :index) unless hook end def update diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index c8528ad6d28..3b3f9bdcf6b 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -81,4 +81,4 @@ class Projects::ImportsController < Projects::ApplicationController end end -Projects::ImportsController.prepend_if_ee('EE::Projects::ImportsController') +Projects::ImportsController.prepend_mod_with('Projects::ImportsController') diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index cae5cc411bc..01a6de76ba5 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -56,8 +56,6 @@ class Projects::IssuesController < Projects::ApplicationController push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml) push_frontend_feature_flag(:issue_assignees_widget, @project, default_enabled: :yaml) - record_experiment_user(:invite_members_version_b) - experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance| experiment_instance.exclude! unless helpers.can_import_members? @@ -110,12 +108,12 @@ class Projects::IssuesController < Projects::ApplicationController params[:issue] ||= ActionController::Parameters.new( assignee_ids: "" ) - build_params = issue_create_params.merge( + build_params = issue_params.merge( merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of], discussion_to_resolve: params[:discussion_to_resolve], - confidential: !!Gitlab::Utils.to_boolean(issue_create_params[:confidential]) + confidential: !!Gitlab::Utils.to_boolean(issue_params[:confidential]) ) - service = ::Issues::BuildService.new(project, current_user, build_params) + service = ::Issues::BuildService.new(project: project, current_user: current_user, params: build_params) @issue = @noteable = service.execute @@ -130,12 +128,12 @@ class Projects::IssuesController < Projects::ApplicationController end def create - create_params = issue_create_params.merge(spammable_params).merge( + create_params = issue_params.merge(spammable_params).merge( merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of], discussion_to_resolve: params[:discussion_to_resolve] ) - service = ::Issues::CreateService.new(project, current_user, create_params) + service = ::Issues::CreateService.new(project: project, current_user: current_user, params: create_params) @issue = service.execute create_vulnerability_issue_feedback(issue) @@ -162,7 +160,7 @@ class Projects::IssuesController < Projects::ApplicationController new_project = Project.find(params[:move_to_project_id]) return render_404 unless issue.can_move?(current_user, new_project) - @issue = ::Issues::UpdateService.new(project, current_user, target_project: new_project).execute(issue) + @issue = ::Issues::UpdateService.new(project: project, current_user: current_user, params: { target_project: new_project }).execute(issue) end respond_to do |format| @@ -176,7 +174,7 @@ class Projects::IssuesController < Projects::ApplicationController end def reorder - service = ::Issues::ReorderService.new(project, current_user, reorder_params) + service = ::Issues::ReorderService.new(project: project, current_user: current_user, params: reorder_params) if service.execute(issue) head :ok @@ -187,7 +185,7 @@ class Projects::IssuesController < Projects::ApplicationController def related_branches @related_branches = ::Issues::RelatedBranchesService - .new(project, current_user) + .new(project: project, current_user: current_user) .execute(issue) .map { |branch| branch.merge(link: branch_link(branch)) } @@ -215,7 +213,7 @@ class Projects::IssuesController < Projects::ApplicationController def create_merge_request create_params = params.slice(:branch_name, :ref).merge(issue_iid: issue.iid) create_params[:target_project_id] = params[:target_project_id] - result = ::MergeRequests::CreateFromIssueService.new(project, current_user, create_params).execute + result = ::MergeRequests::CreateFromIssueService.new(project: project, current_user: current_user, mr_params: create_params).execute if result[:status] == :success render json: MergeRequestCreateSerializer.new.represent(result[:merge_request]) @@ -316,17 +314,8 @@ class Projects::IssuesController < Projects::ApplicationController task_num lock_version discussion_locked - ] + [{ label_ids: [], assignee_ids: [], update_task: [:index, :checked, :line_number, :line_source] }] - end - - def issue_create_params - create_params = %i[ issue_type - ] - - params.require(:issue).permit( - *create_params - ).merge(issue_params) + ] + [{ label_ids: [], assignee_ids: [], update_task: [:index, :checked, :line_number, :line_source] }] end def reorder_params @@ -345,7 +334,7 @@ class Projects::IssuesController < Projects::ApplicationController def update_service update_params = issue_params.merge(spammable_params) - ::Issues::UpdateService.new(project, current_user, update_params) + ::Issues::UpdateService.new(project: project, current_user: current_user, params: update_params) end def finder_type @@ -402,4 +391,4 @@ class Projects::IssuesController < Projects::ApplicationController def create_vulnerability_issue_feedback(issue); end end -Projects::IssuesController.prepend_if_ee('EE::Projects::IssuesController') +Projects::IssuesController.prepend_mod_with('Projects::IssuesController') diff --git a/app/controllers/projects/logs_controller.rb b/app/controllers/projects/logs_controller.rb index f9b8091a419..a4bdbc827e0 100644 --- a/app/controllers/projects/logs_controller.rb +++ b/app/controllers/projects/logs_controller.rb @@ -58,7 +58,7 @@ module Projects def environment strong_memoize(:environment) do if cluster_params.key?(:environment_name) - EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first + ::Environments::EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first else project.default_environment end diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb index e74717a44ab..78170fab7a7 100644 --- a/app/controllers/projects/merge_requests/application_controller.rb +++ b/app/controllers/projects/merge_requests/application_controller.rb @@ -65,4 +65,4 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont end end -Projects::MergeRequests::ApplicationController.prepend_if_ee('EE::Projects::MergeRequests::ApplicationController') +Projects::MergeRequests::ApplicationController.prepend_mod_with('Projects::MergeRequests::ApplicationController') diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index dc77b5e09c8..9f1e2d8236a 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -19,7 +19,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap end def create - @merge_request = ::MergeRequests::CreateService.new(project, current_user, merge_request_params).execute + @merge_request = ::MergeRequests::CreateService.new(project: project, current_user: current_user, params: merge_request_params).execute if @merge_request.valid? incr_count_webide_merge_request @@ -93,7 +93,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap # Gitaly N+1 issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/58096 Gitlab::GitalyClient.allow_n_plus_1_calls do - @merge_request = ::MergeRequests::BuildService.new(project, current_user, merge_request_params.merge(diff_options: diff_options)).execute + @merge_request = ::MergeRequests::BuildService.new(project: project, current_user: current_user, params: merge_request_params.merge(diff_options: diff_options)).execute end end @@ -141,4 +141,4 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap end end -Projects::MergeRequests::CreationsController.prepend_ee_mod +Projects::MergeRequests::CreationsController.prepend_mod diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 98ef9d918ae..3eaabfbf33e 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -47,7 +47,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic diffs = @compare.diffs(diff_options) render json: DiffsMetadataSerializer.new(project: @merge_request.project, current_user: current_user) - .represent(diffs, additional_attributes) + .represent(diffs, additional_attributes.merge(only_context_commits: show_only_context_commits?)) end private @@ -92,7 +92,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic # rubocop: disable CodeReuse/ActiveRecord def commit return unless commit_id = params[:commit_id].presence - return unless @merge_request.all_commits.exists?(sha: commit_id) + return unless @merge_request.all_commits.exists?(sha: commit_id) || @merge_request.recent_context_commits.map(&:id).include?(commit_id) @commit ||= @project.commit(commit_id) end @@ -122,6 +122,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic end end + return @merge_request.context_commits_diff if show_only_context_commits? && !@merge_request.context_commits_diff.empty? return @merge_request.merge_head_diff if render_merge_ref_head_diff? if @start_sha diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 4e409b5f28f..613faa200d1 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -42,11 +42,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml) push_frontend_feature_flag(:usage_data_i_testing_summary_widget_total, @project, default_enabled: :yaml) push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml) + push_frontend_feature_flag(:diffs_virtual_scrolling, project, default_enabled: :yaml) # Usage data feature flags push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml) - - record_experiment_user(:invite_members_version_b) + push_frontend_feature_flag(:diff_settings_usage_data, default_enabled: :yaml) experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance| experiment_instance.exclude! unless helpers.can_import_members? @@ -60,6 +60,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo before_action do push_frontend_feature_flag(:mr_collapsed_approval_rules, @project) + push_frontend_feature_flag(:show_relevant_approval_rule_approvers, @project, default_enabled: :yaml) end around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions] @@ -114,6 +115,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo @noteable = @merge_request @commits_count = @merge_request.commits_count + @merge_request.context_commits_count + @diffs_count = get_diffs_count @issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar') @current_user_data = UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity).to_json @show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs @@ -244,7 +246,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end def update - @merge_request = ::MergeRequests::UpdateService.new(project, current_user, merge_request_update_params).execute(@merge_request) + @merge_request = ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: merge_request_update_params).execute(@merge_request) respond_to do |format| format.html do @@ -273,7 +275,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo def remove_wip @merge_request = ::MergeRequests::UpdateService - .new(project, current_user, wip_event: 'unwip') + .new(project: project, current_user: current_user, params: { wip_event: 'unwip' }) .execute(@merge_request) render json: serialize_widget(@merge_request) @@ -308,7 +310,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end def assign_related_issues - result = ::MergeRequests::AssignIssuesService.new(project, current_user, merge_request: @merge_request).execute + result = ::MergeRequests::AssignIssuesService.new(project: project, current_user: current_user, params: { merge_request: @merge_request }).execute case result[:count] when 0 @@ -386,6 +388,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo private + def get_diffs_count + if show_only_context_commits? + @merge_request.context_commits_diff.raw_diffs.size + else + @merge_request.diff_size + end + end + def merge_request_update_params merge_request_params.merge!(params.permit(:merge_request_diff_head_sha)) end @@ -412,7 +422,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo return :failed end - merge_service = ::MergeRequests::MergeService.new(@project, current_user, merge_params) + merge_service = ::MergeRequests::MergeService.new(project: @project, current_user: current_user, params: merge_params) unless merge_service.hooks_validation_pass?(@merge_request) return :hook_validation_error @@ -525,4 +535,4 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end end -Projects::MergeRequestsController.prepend_if_ee('EE::Projects::MergeRequestsController') +Projects::MergeRequestsController.prepend_mod_with('Projects::MergeRequestsController') diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index dcd3c49441e..dcdda18784d 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -39,7 +39,7 @@ class Projects::MilestonesController < Projects::ApplicationController end def new - @milestone = @project.milestones.new + @noteable = @milestone = @project.milestones.new respond_with(@milestone) end @@ -125,7 +125,7 @@ class Projects::MilestonesController < Projects::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def milestone - @milestone ||= @project.milestones.find_by!(iid: params[:id]) + @noteable = @milestone ||= @project.milestones.find_by!(iid: params[:id]) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/controllers/projects/mirrors_controller.rb b/app/controllers/projects/mirrors_controller.rb index 01abb72fc86..bcb6b574d5a 100644 --- a/app/controllers/projects/mirrors_controller.rb +++ b/app/controllers/projects/mirrors_controller.rb @@ -94,4 +94,4 @@ class Projects::MirrorsController < Projects::ApplicationController end end -Projects::MirrorsController.prepend_if_ee('EE::Projects::MirrorsController') +Projects::MirrorsController.prepend_mod_with('Projects::MirrorsController') diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index 0aac517e3e3..4bd33882eee 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -55,4 +55,4 @@ class Projects::PagesController < Projects::ApplicationController end end -Projects::PagesController.prepend_if_ee('EE::Projects::PagesController') +Projects::PagesController.prepend_mod_with('Projects::PagesController') diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 9f326ef59f5..0de8dc597ae 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -13,14 +13,12 @@ class Projects::PipelinesController < Projects::ApplicationController before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables] before_action :authorize_update_pipeline!, only: [:retry, :cancel] before_action do - push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_graph_layers_view, project, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_filter_jobs, project, default_enabled: :yaml) push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml) - push_frontend_feature_flag(:jira_for_vulnerabilities, project, type: :development, default_enabled: :yaml) end - before_action :ensure_pipeline, only: [:show] + before_action :ensure_pipeline, only: [:show, :downloadable_artifacts] # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596 before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? } @@ -33,7 +31,12 @@ class Projects::PipelinesController < Projects::ApplicationController POLLING_INTERVAL = 10_000 - feature_category :continuous_integration + feature_category :continuous_integration, [ + :charts, :show, :config_variables, :stage, :cancel, :retry, + :builds, :dag, :failures, :status, :downloadable_artifacts, + :index, :create, :new, :destroy + ] + feature_category :code_testing, [:test_report] def index @pipelines = Ci::PipelinesFinder @@ -55,6 +58,17 @@ class Projects::PipelinesController < Projects::ApplicationController e.try {} e.track(:view, value: project.namespace_id) end + experiment(:code_quality_walkthrough, namespace: project.root_ancestor) do |e| + e.exclude! unless current_user + e.exclude! unless can?(current_user, :create_pipeline, project) + e.exclude! unless project.root_ancestor.recent? + e.exclude! if @pipelines_count.to_i > 0 + e.exclude! if helpers.has_gitlab_ci?(project) + + e.use {} + e.try {} + e.track(:view, property: project.root_ancestor.id.to_s) + end end format.json do Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) @@ -162,7 +176,11 @@ class Projects::PipelinesController < Projects::ApplicationController end def retry - pipeline.retry_failed(current_user) + if Gitlab::Ci::Features.background_pipeline_retry_endpoint?(@project) + ::Ci::RetryPipelineWorker.perform_async(pipeline.id, current_user.id) # rubocop:disable CodeReuse/Worker + else + pipeline.retry_failed(current_user) + end respond_to do |format| format.html do @@ -206,13 +224,20 @@ class Projects::PipelinesController < Projects::ApplicationController end end + def downloadable_artifacts + render json: Ci::DownloadableArtifactSerializer.new( + project: project, + current_user: current_user + ).represent(@pipeline) + end + private def serialize_pipelines PipelineSerializer .new(project: @project, current_user: @current_user) .with_pagination(request, response) - .represent(@pipelines, disable_coverage: true, preload: true) + .represent(@pipelines, disable_coverage: true, preload: true, code_quality_walkthrough: params[:code_quality_walkthrough].present?) end def render_show @@ -298,4 +323,4 @@ class Projects::PipelinesController < Projects::ApplicationController end end -Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController') +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 5972b29a298..cc2157a7d51 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -64,4 +64,4 @@ class Projects::ProjectMembersController < Projects::ApplicationController end end -Projects::ProjectMembersController.prepend_if_ee('EE::Projects::ProjectMembersController') +Projects::ProjectMembersController.prepend_mod_with('Projects::ProjectMembersController') diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb index 84b155c8002..8c70ef446a2 100644 --- a/app/controllers/projects/protected_branches_controller.rb +++ b/app/controllers/projects/protected_branches_controller.rb @@ -29,4 +29,4 @@ class Projects::ProtectedBranchesController < Projects::ProtectedRefsController end end -Projects::ProtectedBranchesController.prepend_if_ee('EE::Projects::ProtectedBranchesController') +Projects::ProtectedBranchesController.prepend_mod_with('Projects::ProtectedBranchesController') diff --git a/app/controllers/projects/protected_refs_controller.rb b/app/controllers/projects/protected_refs_controller.rb index 4cba1a75330..abbfe9ce22a 100644 --- a/app/controllers/projects/protected_refs_controller.rb +++ b/app/controllers/projects/protected_refs_controller.rb @@ -68,4 +68,4 @@ class Projects::ProtectedRefsController < Projects::ApplicationController end end -Projects::ProtectedRefsController.prepend_if_ee('EE::Projects::ProtectedRefsController') +Projects::ProtectedRefsController.prepend_mod_with('Projects::ProtectedRefsController') diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 26382856761..1bb50eabd1d 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -8,11 +8,6 @@ class Projects::ReleasesController < Projects::ApplicationController # We have to check `download_code` permission because detail URL path # contains git-tag name. before_action :authorize_download_code!, except: [:index] - before_action do - push_frontend_feature_flag(:graphql_release_data, project, default_enabled: true) - push_frontend_feature_flag(:graphql_milestone_stats, project, default_enabled: true) - push_frontend_feature_flag(:graphql_releases_page, project, default_enabled: true) - end before_action :authorize_update_release!, only: %i[edit update] before_action :authorize_create_release!, only: :new diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index da018b24836..8f64a8aa1d3 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -35,7 +35,7 @@ class Projects::RepositoriesController < Projects::ApplicationController return if archive_not_modified? send_git_archive @repository, **repo_params - rescue => ex + rescue StandardError => ex logger.error("#{self.class.name}: #{ex}") git_not_found! end @@ -127,4 +127,4 @@ class Projects::RepositoriesController < Projects::ApplicationController end end -Projects::RepositoriesController.prepend_if_ee('EE::Projects::RepositoriesController') +Projects::RepositoriesController.prepend_mod_with('Projects::RepositoriesController') diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb index d225d5e104c..fa6adc9431d 100644 --- a/app/controllers/projects/runner_projects_controller.rb +++ b/app/controllers/projects/runner_projects_controller.rb @@ -17,7 +17,10 @@ class Projects::RunnerProjectsController < Projects::ApplicationController if @runner.assign_to(project, current_user) redirect_to path else - redirect_to path, alert: 'Failed adding runner to project' + assign_to_messages = @runner.errors.messages[:assign_to] + alert = assign_to_messages&.join(',') || 'Failed adding runner to project' + + redirect_to path, alert: alert end end diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index b7a5a63e642..ec1f57f090a 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -48,28 +48,17 @@ class Projects::RunnersController < Projects::ApplicationController end def show - render 'shared/runners/show' end def toggle_shared_runners if !project.shared_runners_enabled && project.group && project.group.shared_runners_setting == 'disabled_and_unoverridable' - - if Feature.enabled?(:vueify_shared_runners_toggle, @project) - render json: { error: _('Cannot enable shared runners because parent group does not allow it') }, status: :unauthorized - else - redirect_to project_runners_path(@project), alert: _('Cannot enable shared runners because parent group does not allow it') - end - + render json: { error: _('Cannot enable shared runners because parent group does not allow it') }, status: :unauthorized return end project.toggle!(:shared_runners_enabled) - if Feature.enabled?(:vueify_shared_runners_toggle, @project) - render json: {}, status: :ok - else - redirect_to project_settings_ci_cd_path(@project, anchor: 'js-runners-settings') - end + render json: {}, status: :ok end def toggle_group_runners diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb index bc4e58e54a9..19de157357a 100644 --- a/app/controllers/projects/security/configuration_controller.rb +++ b/app/controllers/projects/security/configuration_controller.rb @@ -14,4 +14,4 @@ module Projects end end -Projects::Security::ConfigurationController.prepend_if_ee('EE::Projects::Security::ConfigurationController') +Projects::Security::ConfigurationController.prepend_mod_with('Projects::Security::ConfigurationController') diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index ccb8b393bfe..74145a70b95 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -1,19 +1,16 @@ # frozen_string_literal: true class Projects::ServicesController < Projects::ApplicationController - include ServiceParams + include Integrations::Params include InternalRedirect # Authorize before_action :authorize_admin_project! before_action :ensure_service_enabled - before_action :service + before_action :integration before_action :web_hook_logs, only: [:edit, :update] before_action :set_deprecation_notice_for_prometheus_service, only: [:edit, :update] before_action :redirect_deprecated_prometheus_service, only: [:update] - before_action only: :edit do - push_frontend_feature_flag(:jira_for_vulnerabilities, @project, type: :development, default_enabled: :yaml) - end respond_to :html @@ -22,20 +19,19 @@ class Projects::ServicesController < Projects::ApplicationController feature_category :integrations def edit - @default_integration = Service.default_integration(service.type, project) + @default_integration = Integration.default_integration(service.type, project) end def update - @service.attributes = service_params[:service] - @service.inherit_from_id = nil if service_params[:service][:inherit_from_id].blank? + @integration.attributes = integration_params[:integration] + @integration.inherit_from_id = nil if integration_params[:integration][:inherit_from_id].blank? - saved = @service.save(context: :manual_change) + saved = @integration.save(context: :manual_change) respond_to do |format| format.html do if saved - target_url = safe_redirect_path(params[:redirect_to]).presence || edit_project_service_path(@project, @service) - redirect_to target_url, notice: success_message + redirect_to redirect_path, notice: success_message else render 'edit' end @@ -50,7 +46,7 @@ class Projects::ServicesController < Projects::ApplicationController end def test - if @service.can_test? + if integration.can_test? render json: service_test_response, status: :ok else render json: {}, status: :not_found @@ -59,12 +55,16 @@ class Projects::ServicesController < Projects::ApplicationController private + def redirect_path + safe_redirect_path(params[:redirect_to]).presence || edit_project_service_path(@project, @integration) + end + def service_test_response - unless @service.update(service_params[:service]) - return { error: true, message: _('Validations failed.'), service_response: @service.errors.full_messages.join(','), test_failed: false } + unless @integration.update(integration_params[:integration]) + return { error: true, message: _('Validations failed.'), service_response: @integration.errors.full_messages.join(','), test_failed: false } end - result = ::Integrations::Test::ProjectService.new(@service, current_user, params[:event]).execute + result = ::Integrations::Test::ProjectService.new(@integration, current_user, params[:event]).execute unless result[:success] return { error: true, message: s_('Integrations|Connection failed. Please check your settings.'), service_response: result[:message].to_s, test_failed: true } @@ -76,16 +76,18 @@ class Projects::ServicesController < Projects::ApplicationController end def success_message - if @service.active? - s_('Integrations|%{integration} settings saved and active.') % { integration: @service.title } + if integration.active? + s_('Integrations|%{integration} settings saved and active.') % { integration: integration.title } else - s_('Integrations|%{integration} settings saved, but not active.') % { integration: @service.title } + s_('Integrations|%{integration} settings saved, but not active.') % { integration: integration.title } end end - def service - @service ||= @project.find_or_initialize_service(params[:id]) + def integration + @integration ||= @project.find_or_initialize_service(params[:id]) + @service ||= @integration # TODO: remove references to @service end + alias_method :service, :integration def web_hook_logs return unless @service.service_hook.present? @@ -98,17 +100,17 @@ class Projects::ServicesController < Projects::ApplicationController end def serialize_as_json - @service + integration .as_json(only: @service.json_fields) .merge(errors: @service.errors.as_json) end def redirect_deprecated_prometheus_service - redirect_to edit_project_service_path(project, @service) if @service.is_a?(::PrometheusService) && Feature.enabled?(:settings_operations_prometheus_service, project) + redirect_to edit_project_service_path(project, integration) if integration.is_a?(::PrometheusService) && Feature.enabled?(:settings_operations_prometheus_service, project) end def set_deprecation_notice_for_prometheus_service - return if !@service.is_a?(::PrometheusService) || !Feature.enabled?(:settings_operations_prometheus_service, project) + return if !integration.is_a?(::PrometheusService) || !Feature.enabled?(:settings_operations_prometheus_service, project) operations_link_start = "<a href=\"#{project_settings_operations_path(project)}\">" message = s_('PrometheusService|You can now manage your Prometheus settings on the %{operations_link_start}Operations%{operations_link_end} page. Fields on this page has been deprecated.') % { operations_link_start: operations_link_start, operations_link_end: "</a>" } diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 1a465406660..3254d4129d3 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -12,7 +12,6 @@ module Projects before_action :define_variables before_action do push_frontend_feature_flag(:ajax_new_deploy_token, @project) - push_frontend_feature_flag(:vueify_shared_runners_toggle, @project) end helper_method :highlight_badge @@ -119,12 +118,13 @@ module Projects .assignable_for(project) .ordered .page(params[:specific_page]).per(NUMBER_OF_RUNNERS_PER_PAGE) + .with_tags - @shared_runners = ::Ci::Runner.instance_type.active + @shared_runners = ::Ci::Runner.instance_type.active.with_tags @shared_runners_count = @shared_runners.count(:all) - @group_runners = ::Ci::Runner.belonging_to_parent_group_of_project(@project.id) + @group_runners = ::Ci::Runner.belonging_to_parent_group_of_project(@project.id).with_tags end def define_ci_variables @@ -143,7 +143,7 @@ module Projects end def define_badges_variables - @ref = params[:ref] || @project.default_branch || 'master' + @ref = params[:ref] || @project.default_branch_or_main @badges = [Gitlab::Ci::Badge::Pipeline::Status, Gitlab::Ci::Badge::Coverage::Report] @@ -160,4 +160,4 @@ module Projects end end -Projects::Settings::CiCdController.prepend_if_ee('EE::Projects::Settings::CiCdController') +Projects::Settings::CiCdController.prepend_mod_with('Projects::Settings::CiCdController') diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb index a05793a0283..a357227c870 100644 --- a/app/controllers/projects/settings/operations_controller.rb +++ b/app/controllers/projects/settings/operations_controller.rb @@ -155,4 +155,4 @@ module Projects end end -Projects::Settings::OperationsController.prepend_if_ee('::EE::Projects::Settings::OperationsController') +Projects::Settings::OperationsController.prepend_mod_with('Projects::Settings::OperationsController') diff --git a/app/controllers/projects/settings/packages_and_registries_controller.rb b/app/controllers/projects/settings/packages_and_registries_controller.rb new file mode 100644 index 00000000000..fee51dc1311 --- /dev/null +++ b/app/controllers/projects/settings/packages_and_registries_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Projects + module Settings + class PackagesAndRegistriesController < Projects::ApplicationController + layout 'project_settings' + + before_action :authorize_admin_project! + before_action :packages_and_registries_settings_enabled! + + feature_category :package_registry + + def show + end + + private + + def packages_and_registries_settings_enabled! + render_404 unless settings_packages_and_registries_enabled?(project) + end + end + end +end diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index bb5ad8e9aea..728231dbdbd 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -134,4 +134,4 @@ module Projects end end -Projects::Settings::RepositoryController.prepend_if_ee('EE::Projects::Settings::RepositoryController') +Projects::Settings::RepositoryController.prepend_mod_with('Projects::Settings::RepositoryController') diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index ff28c3be298..de2ab16b5b1 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -13,6 +13,10 @@ class Projects::SnippetsController < Projects::Snippets::ApplicationController before_action :authorize_read_snippet!, except: [:new, :index] before_action :authorize_update_snippet!, only: :edit + before_action only: [:show] do + push_frontend_feature_flag(:improved_emoji_picker, @project, default_enabled: :yaml) + end + def index @snippet_counts = ::Snippets::CountService .new(current_user, project: @project) diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index 3bf9988ca22..94b0473e1f3 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -9,9 +9,6 @@ class Projects::TagsController < Projects::ApplicationController before_action :require_non_empty_project before_action :authorize_download_code! before_action :authorize_admin_tag!, only: [:new, :create, :destroy] - before_action do - push_frontend_feature_flag(:gldropdown_tags, default_enabled: :yaml) - end feature_category :source_code_management, [:index, :show, :new, :destroy] feature_category :release_evidence, [:create] diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index d1486f765e4..a1493a25a1a 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -6,4 +6,8 @@ class Projects::WikisController < Projects::ApplicationController alias_method :container, :project feature_category :wiki + + before_action do + push_frontend_feature_flag(:wiki_content_editor, project, default_enabled: :yaml) + end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 7c9d6daad02..e66893ac269 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -43,13 +43,12 @@ class ProjectsController < Projects::ApplicationController feature_category :projects, [ :index, :show, :new, :create, :edit, :update, :transfer, - :destroy, :resolve, :archive, :unarchive, :toggle_star + :destroy, :resolve, :archive, :unarchive, :toggle_star, :activity ] feature_category :source_code_management, [:remove_fork, :housekeeping, :refs] feature_category :issue_tracking, [:preview_markdown, :new_issuable_address] feature_category :importers, [:export, :remove_export, :generate_new_export, :download_export] - feature_category :audit_events, [:activity] feature_category :code_review, [:unfoldered_environment_names] def index @@ -85,7 +84,7 @@ class ProjectsController < Projects::ApplicationController notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name } ) else - render 'new', locals: { active_tab: active_new_project_tab } + render 'new' end end @@ -311,7 +310,7 @@ class ProjectsController < Projects::ApplicationController def unfoldered_environment_names respond_to do |format| format.json do - render json: EnvironmentNamesFinder.new(@project, current_user).execute + render json: Environments::EnvironmentNamesFinder.new(@project, current_user).execute end end end @@ -545,4 +544,4 @@ class ProjectsController < Projects::ApplicationController end end -ProjectsController.prepend_if_ee('EE::ProjectsController') +ProjectsController.prepend_mod_with('ProjectsController') diff --git a/app/controllers/registrations/experience_levels_controller.rb b/app/controllers/registrations/experience_levels_controller.rb index 3a721823d89..d04e8d296ed 100644 --- a/app/controllers/registrations/experience_levels_controller.rb +++ b/app/controllers/registrations/experience_levels_controller.rb @@ -38,7 +38,7 @@ module Registrations end def learn_gitlab - @learn_gitlab ||= LearnGitlab.new(current_user) + @learn_gitlab ||= LearnGitlab::Project.new(current_user) end end end diff --git a/app/controllers/registrations/invites_controller.rb b/app/controllers/registrations/invites_controller.rb new file mode 100644 index 00000000000..548714e80e9 --- /dev/null +++ b/app/controllers/registrations/invites_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Registrations + class InvitesController < RegistrationsController + layout 'simple_registration' + + before_action :check_if_gl_com_or_dev + end +end diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb index 62ec03206c4..87465f8714d 100644 --- a/app/controllers/registrations/welcome_controller.rb +++ b/app/controllers/registrations/welcome_controller.rb @@ -18,7 +18,13 @@ module Registrations if result[:status] == :success return redirect_to new_users_sign_up_group_path if show_signup_onboarding? - redirect_to path_for_signed_in_user(current_user) + members = current_user.members + + if members.count == 1 && members.last.source.present? + redirect_to members_activity_path(members), notice: helpers.invite_accepted_notice(members.last) + else + redirect_to path_for_signed_in_user(current_user) + end else render :show end @@ -48,7 +54,14 @@ module Registrations def path_for_signed_in_user(user) return users_almost_there_path if requires_confirmation?(user) - stored_location_for(user) || dashboard_projects_path + stored_location_for(user) || members_activity_path(user.members) + end + + def members_activity_path(members) + return dashboard_projects_path unless members.any? + return dashboard_projects_path unless members.last.source.present? + + members.last.source.activity_path end def show_signup_onboarding? @@ -57,4 +70,4 @@ module Registrations end end -Registrations::WelcomeController.prepend_if_ee('EE::Registrations::WelcomeController') +Registrations::WelcomeController.prepend_mod_with('Registrations::WelcomeController') diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 61218a95add..0f29f6f608f 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -155,13 +155,21 @@ class RegistrationsController < Devise::RegistrationsController end def resource - @resource ||= Users::BuildService.new(current_user, sign_up_params).execute + @resource ||= Users::RegistrationsBuildService + .new(current_user, sign_up_params.merge({ skip_confirmation: skip_email_confirmation? })) + .execute end def devise_mapping @devise_mapping ||= Devise.mappings[:user] end + def skip_email_confirmation? + invite_email = session.delete(:invite_email) + + sign_up_params[:email] == invite_email + end + def load_recaptcha Gitlab::Recaptcha.load_configurations! end @@ -179,6 +187,21 @@ class RegistrationsController < Devise::RegistrationsController def set_invite_params @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email]) end + + def after_pending_invitations_hook + member_id = session.delete(:originating_member_id) + + return unless member_id + + # if invited multiple times to different projects, only the email clicked will be counted as accepted + # for the specific member on a project or group + member = resource.members.find_by(id: member_id) # rubocop: disable CodeReuse/ActiveRecord + + return unless member + + experiment(:invite_signup_page_interaction, actor: member).track(:form_submission) + experiment('members/invite_email', actor: member).track(:accepted) + end end -RegistrationsController.prepend_if_ee('EE::RegistrationsController') +RegistrationsController.prepend_mod_with('RegistrationsController') diff --git a/app/controllers/repositories/git_http_client_controller.rb b/app/controllers/repositories/git_http_client_controller.rb index a5b81054ee4..76d9983d341 100644 --- a/app/controllers/repositories/git_http_client_controller.rb +++ b/app/controllers/repositories/git_http_client_controller.rb @@ -134,4 +134,4 @@ module Repositories end end -Repositories::GitHttpClientController.prepend_if_ee('EE::Repositories::GitHttpClientController') +Repositories::GitHttpClientController.prepend_mod_with('Repositories::GitHttpClientController') diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb index d68ba80ab5d..11a219b4ff0 100644 --- a/app/controllers/repositories/git_http_controller.rb +++ b/app/controllers/repositories/git_http_controller.rb @@ -122,4 +122,4 @@ module Repositories end end -Repositories::GitHttpController.prepend_if_ee('EE::Repositories::GitHttpController') +Repositories::GitHttpController.prepend_mod_with('Repositories::GitHttpController') diff --git a/app/controllers/repositories/lfs_api_controller.rb b/app/controllers/repositories/lfs_api_controller.rb index 2de29da4b45..4f2e02c78c3 100644 --- a/app/controllers/repositories/lfs_api_controller.rb +++ b/app/controllers/repositories/lfs_api_controller.rb @@ -148,4 +148,4 @@ module Repositories end end -Repositories::LfsApiController.prepend_if_ee('EE::Repositories::LfsApiController') +Repositories::LfsApiController.prepend_mod_with('Repositories::LfsApiController') diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index 672a03ad11d..97b6671a82a 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -70,4 +70,4 @@ class RootController < Dashboard::ProjectsController end end -RootController.prepend_if_ee('EE::RootController') +RootController.prepend_mod_with('RootController') diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 3b218822395..ac6239615b4 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -152,4 +152,4 @@ class SearchController < ApplicationController end end -SearchController.prepend_if_ee('EE::SearchController') +SearchController.prepend_mod_with('SearchController') diff --git a/app/controllers/sent_notifications_controller.rb b/app/controllers/sent_notifications_controller.rb index db07b212d00..64d66ee86f1 100644 --- a/app/controllers/sent_notifications_controller.rb +++ b/app/controllers/sent_notifications_controller.rb @@ -53,4 +53,4 @@ class SentNotificationsController < ApplicationController end end -SentNotificationsController.prepend_if_ee('EE::SentNotificationsController') +SentNotificationsController.prepend_mod_with('SentNotificationsController') diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b8842b2efdb..4fcf82c605b 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -22,6 +22,7 @@ class SessionsController < Devise::SessionsController prepend_before_action :check_captcha, only: [:create] prepend_before_action :store_redirect_uri, only: [:new] prepend_before_action :require_no_authentication_without_flash, only: [:new, :create] + prepend_before_action :check_forbidden_password_based_login, if: -> { action_name == 'create' && password_based_login? } prepend_before_action :ensure_password_authentication_enabled!, if: -> { action_name == 'create' && password_based_login? } before_action :auto_sign_in_with_provider, only: [:new] @@ -313,6 +314,13 @@ class SessionsController < Devise::SessionsController def set_invite_params @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email]) end + + def check_forbidden_password_based_login + if find_user&.password_based_login_forbidden? + flash[:alert] = _('You are not allowed to log in using password') + redirect_to new_user_session_path + end + end end -SessionsController.prepend_if_ee('EE::SessionsController') +SessionsController.prepend_mod_with('SessionsController') diff --git a/app/controllers/terraform/services_controller.rb b/app/controllers/terraform/services_controller.rb new file mode 100644 index 00000000000..e7b9a94fd8e --- /dev/null +++ b/app/controllers/terraform/services_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Terraform::ServicesController < ApplicationController + skip_before_action :authenticate_user! + + feature_category :infrastructure_as_code + + def index + render json: { 'modules.v1' => "/api/#{::API::API.version}/packages/terraform/modules/v1/" } + end +end diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 2c827292928..4077a3d3dac 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -117,4 +117,4 @@ class UploadsController < ApplicationController end end -UploadsController.prepend_if_ee('EE::UploadsController') +UploadsController.prepend_mod_with('UploadsController') diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 54d97f588fc..287ee2d5ab8 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -260,4 +260,4 @@ class UsersController < ApplicationController end end -UsersController.prepend_if_ee('EE::UsersController') +UsersController.prepend_mod_with('UsersController') diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb index e24b0bbc7bb..6f389aa4924 100644 --- a/app/controllers/whats_new_controller.rb +++ b/app/controllers/whats_new_controller.rb @@ -5,6 +5,7 @@ class WhatsNewController < ApplicationController skip_before_action :authenticate_user! + before_action :check_whats_new_enabled before_action :check_valid_page_param, :set_pagination_headers feature_category :navigation @@ -19,6 +20,10 @@ class WhatsNewController < ApplicationController private + def check_whats_new_enabled + render_404 if Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled? + end + def check_valid_page_param render_404 if current_page < 1 end |