diff options
Diffstat (limited to 'app/controllers/projects')
32 files changed, 271 insertions, 127 deletions
diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index 0d5f64c739c..cf432cfb429 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -8,6 +8,8 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController feature_category :users, [:members] feature_category :snippets, [:snippets] + urgency :low, [:merge_requests] + def members render json: ::Projects::ParticipantsService.new(@project, current_user).execute(target) end diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb index 0f87690bba5..57a06f26f8c 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -27,3 +27,5 @@ class Projects::BlameController < Projects::ApplicationController @blame = Gitlab::View::Presenter::Factory.new(@blame, project: @project, path: @path).fabricate! end end + +Projects::BlameController.prepend_mod diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index cd50c8cf5b1..b30ef7506aa 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -44,7 +44,7 @@ class Projects::BlobController < Projects::ApplicationController before_action do push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml) - push_frontend_feature_flag(:refactor_text_viewer, @project, default_enabled: :yaml) + push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml) push_frontend_feature_flag(:consolidated_edit_button, @project, default_enabled: :yaml) push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks) end @@ -99,7 +99,7 @@ class Projects::BlobController < Projects::ApplicationController @content = params[:content] @blob.load_all_data! diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true) - diff_lines = diffy.diff.scan(/.*\n/)[2..-1] + diff_lines = diffy.diff.scan(/.*\n/)[2..] diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines).to_a @diff_lines = Gitlab::Diff::Highlight.new(diff_lines, repository: @repository).highlight @@ -298,3 +298,5 @@ class Projects::BlobController < Projects::ApplicationController experiment(:code_quality_walkthrough, namespace: @project.root_ancestor).track(:commit_created) end end + +Projects::BlobController.prepend_mod diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 7354c2c71ac..81ad6243efe 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -11,7 +11,6 @@ class Projects::BoardsController < Projects::ApplicationController push_frontend_feature_flag(:issue_boards_filtered_search, project, default_enabled: :yaml) push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml) push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml) - push_frontend_feature_flag(:labels_widget, project, default_enabled: :yaml) experiment(:prominent_create_board_btn, subject: current_user) do |e| e.use { } e.try { } diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb index 9dc3194df85..7ef5016ac00 100644 --- a/app/controllers/projects/ci/lints_controller.rb +++ b/app/controllers/projects/ci/lints_controller.rb @@ -6,6 +6,7 @@ class Projects::Ci::LintsController < Projects::ApplicationController feature_category :pipeline_authoring respond_to :json, only: [:create] + urgency :low, [:create] def show end diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index 600516f95a2..6f12e3940dd 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -9,6 +9,8 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController feature_category :pipeline_authoring + urgency :low, [:show] + def show end @@ -21,7 +23,7 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController def setup_walkthrough_experiment experiment(:pipeline_editor_walkthrough, namespace: @project.namespace, sticky_to: current_user) do |e| e.candidate {} - e.record! + e.publish_to_database end end end diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 5154f145b46..ba83f8dad35 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -22,6 +22,8 @@ class Projects::ForksController < Projects::ApplicationController end def index + @sort = params[:sort] + @total_forks_count = project.forks.size @public_forks_count = project.forks.public_only.size @private_forks_count = @total_forks_count - project.forks.public_and_internal_only.size diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb new file mode 100644 index 00000000000..aff305ab7d6 --- /dev/null +++ b/app/controllers/projects/google_cloud/base_controller.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class Projects::GoogleCloud::BaseController < Projects::ApplicationController + feature_category :five_minute_production_app + + before_action :admin_project_google_cloud! + before_action :google_oauth2_enabled! + before_action :feature_flag_enabled! + + private + + def admin_project_google_cloud! + access_denied! unless can?(current_user, :admin_project_google_cloud, project) + end + + def google_oauth2_enabled! + config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2') + if config.app_id.blank? || config.app_secret.blank? + access_denied! 'This GitLab instance not configured for Google Oauth2.' + end + end + + def feature_flag_enabled! + access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud, project) + end +end diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb new file mode 100644 index 00000000000..a69a744154c --- /dev/null +++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::BaseController + before_action :validate_gcp_token! + + def index + @google_cloud_path = project_google_cloud_index_path(project) + google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil) + gcp_projects = google_api_client.list_projects + + if gcp_projects.empty? + @js_data = { screen: 'no_gcp_projects' }.to_json + render status: :unauthorized, template: 'projects/google_cloud/errors/no_gcp_projects' + else + @js_data = { + screen: 'service_accounts_form', + gcpProjects: gcp_projects, + environments: project.environments, + cancelPath: project_google_cloud_index_path(project) + }.to_json + end + rescue Google::Apis::ClientError => error + handle_gcp_error(error, project) + end + + def create + google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil) + service_accounts_service = GoogleCloud::ServiceAccountsService.new(project) + gcp_project = params[:gcp_project] + environment = params[:environment] + generated_name = "GitLab :: #{@project.name} :: #{environment}" + generated_desc = "GitLab generated service account for project '#{@project.name}' and environment '#{environment}'" + + service_account = google_api_client.create_service_account(gcp_project, generated_name, generated_desc) + service_account_key = google_api_client.create_service_account_key(gcp_project, service_account.unique_id) + + service_accounts_service.add_for_project( + environment, + service_account.project_id, + service_account.to_json, + service_account_key.to_json + ) + + redirect_to project_google_cloud_index_path(project), notice: _('Service account generated successfully') + rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error + handle_gcp_error(error, project) + end + + private + + def validate_gcp_token! + is_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil) + .validate_token(expires_at_in_session) + + return if is_token_valid + + return_url = project_google_cloud_index_path(project) + state = generate_session_key_redirect(request.url, return_url) + @authorize_url = GoogleApi::CloudPlatform::Client.new(nil, + callback_google_api_auth_url, + state: state).authorize_url + redirect_to @authorize_url + end + + def generate_session_key_redirect(uri, error_uri) + GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key| + session[key] = uri + session[:error_uri] = error_uri + end + end + + def token_in_session + session[GoogleApi::CloudPlatform::Client.session_key_for_token] + end + + def expires_at_in_session + session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] + end + + def handle_gcp_error(error, project) + Gitlab::ErrorTracking.track_exception(error, project_id: project.id) + @js_data = { screen: 'gcp_error', error: error.to_s }.to_json + render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error' + end +end diff --git a/app/controllers/projects/google_cloud_controller.rb b/app/controllers/projects/google_cloud_controller.rb index 7257ed1ef6f..1fa8ae60376 100644 --- a/app/controllers/projects/google_cloud_controller.rb +++ b/app/controllers/projects/google_cloud_controller.rb @@ -1,34 +1,12 @@ # frozen_string_literal: true -class Projects::GoogleCloudController < Projects::ApplicationController - feature_category :google_cloud - - before_action :admin_project_google_cloud? - before_action :google_oauth2_enabled? - before_action :feature_flag_enabled? - +class Projects::GoogleCloudController < Projects::GoogleCloud::BaseController def index @js_data = { + screen: 'home', serviceAccounts: GoogleCloud::ServiceAccountsService.new(project).find_for_project, - createServiceAccountUrl: '#mocked-url-create-service', + createServiceAccountUrl: project_google_cloud_service_accounts_path(project), emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg') }.to_json end - - private - - def admin_project_google_cloud? - access_denied! unless can?(current_user, :admin_project_google_cloud, project) - end - - def google_oauth2_enabled? - config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2') - if config.app_id.blank? || config.app_secret.blank? - access_denied! 'This GitLab instance not configured for Google Oauth2.' - end - end - - def feature_flag_enabled? - access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud) - end end diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index c79e5a8cc85..99eba32e00f 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -6,7 +6,7 @@ class Projects::HooksController < Projects::ApplicationController # Authorize before_action :authorize_admin_project! before_action :hook_logs, only: :edit - before_action -> { create_rate_limit(:project_testing_hook, @project) }, only: :test + before_action -> { check_rate_limit!(:project_testing_hook, scope: [@project, current_user]) }, only: :test respond_to :html diff --git a/app/controllers/projects/integrations/shimos_controller.rb b/app/controllers/projects/integrations/shimos_controller.rb new file mode 100644 index 00000000000..827dbb8f3f9 --- /dev/null +++ b/app/controllers/projects/integrations/shimos_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Projects + module Integrations + class ShimosController < Projects::ApplicationController + feature_category :integrations + + before_action :ensure_renderable + + def show; end + + private + + def ensure_renderable + render_404 unless Feature.enabled?(:shimo_integration, project) && project.has_shimo? && project.shimo_integration&.render? + end + end + end +end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 853e9c7ccdd..fc67cd98d15 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -10,7 +10,7 @@ class Projects::IssuesController < Projects::ApplicationController include RecordUserLastActivity ISSUES_EXCEPT_ACTIONS = %i[index calendar new create bulk_update import_csv export_csv service_desk].freeze - SET_ISSUEABLES_INDEX_ONLY_ACTIONS = %i[index calendar service_desk].freeze + SET_ISSUABLES_INDEX_ONLY_ACTIONS = %i[index calendar service_desk].freeze prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) } prepend_before_action(only: [:calendar]) { authenticate_sessionless_user!(:ics) } @@ -22,7 +22,7 @@ class Projects::IssuesController < Projects::ApplicationController before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } after_action :log_issue_show, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } - before_action :set_issuables_index, if: ->(c) { SET_ISSUEABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) } + before_action :set_issuables_index, if: ->(c) { SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) } # Allow write(create) issue before_action :authorize_create_issue!, only: [:new, :create] @@ -37,7 +37,9 @@ class Projects::IssuesController < Projects::ApplicationController before_action :authorize_download_code!, only: [:related_branches] # Limit the amount of issues created per minute - before_action :create_rate_limit, only: [:create], if: -> { Feature.disabled?('rate_limited_service_issues_create', project, default_enabled: :yaml) } + before_action -> { check_rate_limit!(:issues_create, scope: [@project, @current_user])}, + only: [:create], + if: -> { Feature.disabled?('rate_limited_service_issues_create', project, default_enabled: :yaml) } before_action do push_frontend_feature_flag(:tribute_autocomplete, @project) @@ -49,19 +51,9 @@ class Projects::IssuesController < Projects::ApplicationController before_action only: :show do push_frontend_feature_flag(:real_time_issue_sidebar, @project, default_enabled: :yaml) - push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml) + push_frontend_feature_flag(:confidential_notes, project&.group, default_enabled: :yaml) push_frontend_feature_flag(:issue_assignees_widget, @project, default_enabled: :yaml) - push_frontend_feature_flag(:labels_widget, @project, default_enabled: :yaml) push_frontend_feature_flag(:paginated_issue_discussions, @project, default_enabled: :yaml) - - experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance| - experiment_instance.exclude! unless helpers.can_admin_project_member?(@project) - - experiment_instance.use {} - experiment_instance.try(:invite_member_link) {} - - experiment_instance.track(:view, property: @project.root_ancestor.id.to_s) - end end around_action :allow_gitaly_ref_name_caching, only: [:discussions] @@ -373,20 +365,6 @@ class Projects::IssuesController < Projects::ApplicationController project_compare_path(project, from: project.default_branch, to: branch[:name]) end - def create_rate_limit - key = :issues_create - - if rate_limiter.throttled?(key, scope: [@project, @current_user]) - rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user) - - render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests - end - end - - def rate_limiter - ::Gitlab::ApplicationRateLimiter - end - def service_desk? action_name == 'service_desk' end diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 81b8da9cba3..fa7c62c34dd 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -4,8 +4,8 @@ class Projects::JobsController < Projects::ApplicationController include SendFileUpload include ContinueParams - before_action :find_job_as_build, except: [:index, :play] - before_action :find_job_as_processable, only: [:play] + before_action :find_job_as_build, except: [:index, :play, :show] + before_action :find_job_as_processable, only: [:play, :show] before_action :authorize_read_build_trace!, only: [:trace, :raw] before_action :authorize_read_build! before_action :authorize_update_build!, @@ -42,7 +42,7 @@ class Projects::JobsController < Projects::ApplicationController format.json do Gitlab::PollingInterval.set_header(response, interval: 10_000) - render json: BuildSerializer + render json: Ci::JobSerializer .new(project: @project, current_user: @current_user) .represent(@build.present(current_user: current_user), {}, BuildDetailsEntity) end @@ -118,7 +118,7 @@ class Projects::JobsController < Projects::ApplicationController end def status - render json: BuildSerializer + render json: Ci::JobSerializer .new(project: @project, current_user: @current_user) .represent_status(@build.present(current_user: current_user)) end diff --git a/app/controllers/projects/learn_gitlab_controller.rb b/app/controllers/projects/learn_gitlab_controller.rb index 91a43c5f03f..177533b89c8 100644 --- a/app/controllers/projects/learn_gitlab_controller.rb +++ b/app/controllers/projects/learn_gitlab_controller.rb @@ -3,6 +3,7 @@ class Projects::LearnGitlabController < Projects::ApplicationController before_action :authenticate_user! before_action :check_experiment_enabled? + before_action :enable_invite_for_help_continuous_onboarding_experiment feature_category :users @@ -14,4 +15,13 @@ class Projects::LearnGitlabController < Projects::ApplicationController def check_experiment_enabled? return access_denied! unless helpers.learn_gitlab_enabled?(project) end + + def enable_invite_for_help_continuous_onboarding_experiment + return unless current_user.can?(:admin_group_member, project.namespace) + + experiment(:invite_for_help_continuous_onboarding, namespace: project.namespace) do |e| + e.candidate {} + e.publish_to_database + end + end end diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb index a8038878504..76a233afa13 100644 --- a/app/controllers/projects/merge_requests/conflicts_controller.rb +++ b/app/controllers/projects/merge_requests/conflicts_controller.rb @@ -5,6 +5,12 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap before_action :authorize_can_resolve_conflicts! + urgency :low, [ + :show, + :conflict_for_path, + :resolve_conflicts + ] + def show respond_to do |format| format.html do diff --git a/app/controllers/projects/merge_requests/content_controller.rb b/app/controllers/projects/merge_requests/content_controller.rb index 399745151b1..588fc85ff77 100644 --- a/app/controllers/projects/merge_requests/content_controller.rb +++ b/app/controllers/projects/merge_requests/content_controller.rb @@ -13,6 +13,11 @@ class Projects::MergeRequests::ContentController < Projects::MergeRequests::Appl FAST_POLLING_INTERVAL = 10.seconds.in_milliseconds SLOW_POLLING_INTERVAL = 5.minutes.in_milliseconds + urgency :low, [ + :widget, + :cached_widget + ] + def widget respond_to do |format| format.json do diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index ecc5ad1f84e..beb179f584b 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -10,6 +10,15 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path] before_action :build_merge_request, except: [:create] + urgency :low, [ + :new, + :create, + :pipelines, + :diffs, + :branch_from, + :branch_to + ] + def new define_new_vars end diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 1188aec24a8..32ca7d779d2 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -14,6 +14,13 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic after_action :track_viewed_diffs_events, only: [:diffs_batch] + urgency :low, [ + :show, + :diff_for_path, + :diffs_batch, + :diffs_metadata + ] + def show render_diffs end @@ -36,6 +43,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic options = { environment: environment, merge_request: @merge_request, + commit: commit, diff_view: diff_view, merge_ref_head_diff: render_merge_ref_head_diff?, pagination_data: diffs.pagination_data, diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb index ca3f36cafe1..645720a0889 100644 --- a/app/controllers/projects/merge_requests/drafts_controller.rb +++ b/app/controllers/projects/merge_requests/drafts_controller.rb @@ -9,6 +9,13 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli before_action :authorize_admin_draft!, only: [:update, :destroy] before_action :authorize_admin_draft!, if: -> { action_name == 'publish' && params[:id].present? } + urgency :low, [ + :create, + :update, + :destroy, + :publish + ] + def index drafts = prepare_notes_for_rendering(draft_notes) render json: DraftNoteSerializer.new(current_user: current_user).represent(drafts) @@ -110,7 +117,7 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli def render_draft_note(note) params = { target_id: merge_request.id, target_type: 'MergeRequest', text: note.note } result = PreviewMarkdownService.new(@project, current_user, params).execute - markdown_params = { markdown_engine: result[:markdown_engine], issuable_state_filter_enabled: true } + markdown_params = { markdown_engine: result[:markdown_engine], issuable_reference_expansion_enabled: true } note.rendered_note = view_context.markdown(result[:text], markdown_params) note.users_referenced = result[:users] diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 6c5a8aa0610..7133233f083 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -42,21 +42,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml) push_frontend_feature_flag(:mr_changes_fluid_layout, project, default_enabled: :yaml) push_frontend_feature_flag(:mr_attention_requests, project, default_enabled: :yaml) - push_frontend_feature_flag(:labels_widget, project, default_enabled: :yaml) # Usage data feature flags push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml) push_frontend_feature_flag(:diff_settings_usage_data, default_enabled: :yaml) push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml) - - experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance| - experiment_instance.exclude! unless helpers.can_admin_project_member?(@project) - - experiment_instance.use {} - experiment_instance.try(:invite_member_link) {} - - experiment_instance.track(:view, property: @project.root_ancestor.id.to_s) - end end before_action do @@ -74,15 +64,28 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo :show, :toggle_award_emoji, :toggle_subscription, :update ] - feature_category :code_testing, [ - :test_reports, :coverage_reports, :codequality_reports, - :codequality_mr_diff_reports - ] - + feature_category :code_testing, [:test_reports, :coverage_reports] + feature_category :code_quality, [:codequality_reports, :codequality_mr_diff_reports] feature_category :accessibility_testing, [:accessibility_reports] feature_category :infrastructure_as_code, [:terraform_reports] feature_category :continuous_integration, [:pipeline_status, :pipelines, :exposed_artifacts] + urgency :high, [:export_csv] + urgency :low, [ + :index, + :show, + :commits, + :bulk_update, + :edit, + :update, + :cancel_auto_merge, + :merge, + :ci_environments_status, + :destroy, + :rebase, + :discussions + ] + def index @merge_requests = @issuables @@ -286,7 +289,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo if merge_request.errors.present? render json: @merge_request.errors, status: :bad_request else - render json: serializer.represent(@merge_request, serializer: 'basic') + render json: serializer.represent(@merge_request, serializer: params[:serializer] || 'basic') end end end diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index e8057308386..7322e08e62e 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -57,7 +57,7 @@ class Projects::NotesController < Projects::ApplicationController def outdated_line_change diff_lines = Rails.cache.fetch(['note', note.id, 'oudated_line_change'], expires_in: 7.days) do - ::MergeRequests::OutdatedDiscussionDiffLinesService.new(project: @project, note: note).execute.to_json + ::MergeRequests::OutdatedDiscussionDiffLinesService.new(project: note.noteable.source_project, note: note).execute.to_json end render json: diff_lines diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index 4af7508b935..ac94cc001dd 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -3,7 +3,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :schedule, except: [:index, :new, :create] - before_action :play_rate_limit, only: [:play] + before_action :check_play_rate_limit!, only: [:play] before_action :authorize_play_pipeline_schedule!, only: [:play] before_action :authorize_read_pipeline_schedule! before_action :authorize_create_pipeline_schedule!, only: [:new, :create] @@ -81,19 +81,15 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController private - def play_rate_limit + def check_play_rate_limit! return unless current_user - if rate_limiter.throttled?(:play_pipeline_schedule, scope: [current_user, schedule]) + check_rate_limit!(:play_pipeline_schedule, scope: [current_user, schedule]) do flash[:alert] = _('You cannot play this scheduled pipeline at the moment. Please wait a minute.') redirect_to pipeline_schedules_path(@project) end end - def rate_limiter - ::Gitlab::ApplicationRateLimiter - end - def schedule @schedule ||= project.pipeline_schedules.find(params[:id]) end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index a2312484a9b..71dc67bb6dc 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -14,13 +14,22 @@ class Projects::PipelinesController < Projects::ApplicationController before_action :authorize_update_pipeline!, only: [:retry, :cancel] before_action :ensure_pipeline, only: [:show, :downloadable_artifacts] + before_action do + push_frontend_feature_flag(:jobs_tab_vue, @project, default_enabled: :yaml) + end + # 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? } around_action :allow_gitaly_ref_name_caching, only: [:index, :show] + # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/345074 track_redis_hll_event :charts, name: 'p_analytics_pipelines' + track_redis_hll_event :charts, name: 'p_analytics_ci_cd_pipelines', if: -> { should_track_ci_cd_pipelines? } + track_redis_hll_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', if: -> { should_track_ci_cd_deployment_frequency? } + track_redis_hll_event :charts, name: 'p_analytics_ci_cd_lead_time', if: -> { should_track_ci_cd_lead_time? } + wrap_parameters Ci::Pipeline POLLING_INTERVAL = 10_000 @@ -307,7 +316,7 @@ class Projects::PipelinesController < Projects::ApplicationController e.control {} e.candidate {} - e.record! + e.publish_to_database end end @@ -320,9 +329,21 @@ class Projects::PipelinesController < Projects::ApplicationController e.control {} e.candidate {} - e.record! + e.publish_to_database end end + + def should_track_ci_cd_pipelines? + params[:chart].blank? || params[:chart] == 'pipelines' + end + + def should_track_ci_cd_deployment_frequency? + params[:chart] == 'deployment-frequency' + end + + def should_track_ci_cd_lead_time? + params[:chart] == 'lead-time' + end end Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController') diff --git a/app/controllers/projects/prometheus/alerts_controller.rb b/app/controllers/projects/prometheus/alerts_controller.rb index 312919831d4..7aebff13278 100644 --- a/app/controllers/projects/prometheus/alerts_controller.rb +++ b/app/controllers/projects/prometheus/alerts_controller.rb @@ -82,17 +82,17 @@ module Projects def create_service Projects::Prometheus::Alerts::CreateService - .new(project, current_user, alerts_params) + .new(project: project, current_user: current_user, params: alerts_params) end def update_service Projects::Prometheus::Alerts::UpdateService - .new(project, current_user, alerts_params) + .new(project: project, current_user: current_user, params: alerts_params) end def destroy_service Projects::Prometheus::Alerts::DestroyService - .new(project, current_user, nil) + .new(project: project, current_user: current_user, params: nil) end def schedule_prometheus_update! diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb index e86d2490282..9707b70f26f 100644 --- a/app/controllers/projects/raw_controller.rb +++ b/app/controllers/projects/raw_controller.rb @@ -13,7 +13,7 @@ class Projects::RawController < Projects::ApplicationController before_action :set_ref_and_path before_action :require_non_empty_project before_action :authorize_download_code! - before_action :show_rate_limit, only: [:show], unless: :external_storage_request? + before_action :check_show_rate_limit!, only: [:show], unless: :external_storage_request? before_action :redirect_to_external_storage, only: :show, if: :static_objects_external_storage_enabled? feature_category :source_code_management @@ -33,21 +33,11 @@ class Projects::RawController < Projects::ApplicationController @ref, @path = extract_ref(get_id) end - def show_rate_limit - if rate_limiter.throttled?(:show_raw_controller, scope: [@project, @path], threshold: raw_blob_request_limit) - rate_limiter.log_request(request, :raw_blob_request_limit, current_user) - + def check_show_rate_limit! + check_rate_limit!(:raw_blob, scope: [@project, @path]) do render plain: _('You cannot access the raw file. Please wait a minute.'), status: :too_many_requests end end - - def rate_limiter - ::Gitlab::ApplicationRateLimiter - end - - def raw_blob_request_limit - Gitlab::CurrentSettings - .current_application_settings - .raw_blob_request_limit - end end + +Projects::RawController.prepend_mod diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index 8beebb52980..77826a2f789 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -3,16 +3,16 @@ class Projects::RepositoriesController < Projects::ApplicationController include ExtractsPath include StaticObjectExternalStorage - include Gitlab::RateLimitHelpers include HotlinkInterceptor + include Gitlab::RepositoryArchiveRateLimiter prepend_before_action(only: [:archive]) { authenticate_sessionless_user!(:archive) } skip_before_action :default_cache_headers, only: :archive # Authorize + before_action :check_archive_rate_limiting!, only: :archive before_action :require_non_empty_project, except: :create - before_action :archive_rate_limit!, only: :archive before_action :intercept_hotlinking!, only: :archive before_action :assign_archive_vars, only: :archive before_action :assign_append_sha, only: :archive @@ -42,12 +42,6 @@ class Projects::RepositoriesController < Projects::ApplicationController private - def archive_rate_limit! - if archive_rate_limit_reached?(current_user, @project) - render plain: ::Gitlab::RateLimitHelpers::ARCHIVE_RATE_LIMIT_REACHED_MESSAGE, status: :too_many_requests - end - end - def repo_params @repo_params ||= { ref: @ref, path: params[:path], format: params[:format], append_sha: @append_sha } end @@ -125,6 +119,12 @@ class Projects::RepositoriesController < Projects::ApplicationController [path, nil] end end + + def check_archive_rate_limiting! + check_archive_rate_limit!(current_user, @project) do + render(plain: _('This archive has been requested too many times. Try again later.'), status: :too_many_requests) + end + end end Projects::RepositoriesController.prepend_mod_with('Projects::RepositoriesController') diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index e841c3e3d49..62a9f8a4625 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -4,8 +4,6 @@ class Projects::RunnersController < Projects::ApplicationController before_action :authorize_admin_build! before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show] - layout 'project_settings' - feature_category :runner def index diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 4fe37352995..ef6c10d43cd 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -9,10 +9,10 @@ module Projects layout 'project_settings' before_action :authorize_admin_pipeline! + before_action :check_builds_available! before_action :define_variables before_action do push_frontend_feature_flag(:ajax_new_deploy_token, @project) - push_frontend_feature_flag(:ci_scoped_job_token, @project, default_enabled: :yaml) end helper_method :highlight_badge diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index f8f2c1f0836..660ebcc30d3 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -60,3 +60,5 @@ class Projects::TreeController < Projects::ApplicationController } end end + +Projects::TreeController.prepend_mod diff --git a/app/controllers/projects/usage_quotas_controller.rb b/app/controllers/projects/usage_quotas_controller.rb index b319e427eaa..680874ffee4 100644 --- a/app/controllers/projects/usage_quotas_controller.rb +++ b/app/controllers/projects/usage_quotas_controller.rb @@ -9,14 +9,5 @@ class Projects::UsageQuotasController < Projects::ApplicationController def index @hide_search_settings = true - @storage_app_data = { - project_path: @project.full_path, - usage_quotas_help_page_path: help_page_path('user/usage_quotas'), - build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'), - packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'), - repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'), - snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'), - wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size') - } end end diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb index f93c75a203e..e7bccf5a243 100644 --- a/app/controllers/projects/variables_controller.rb +++ b/app/controllers/projects/variables_controller.rb @@ -5,6 +5,8 @@ class Projects::VariablesController < Projects::ApplicationController feature_category :pipeline_authoring + urgency :low, [:show, :update] + def show respond_to do |format| format.json do |