diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-20 13:00:54 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-20 13:00:54 +0300 |
commit | 3cccd102ba543e02725d247893729e5c73b38295 (patch) | |
tree | f36a04ec38517f5deaaacb5acc7d949688d1e187 /app/controllers | |
parent | 205943281328046ef7b4528031b90fbda70c75ac (diff) |
Add latest changes from gitlab-org/gitlab@14-10-stable-eev14.10.0-rc42
Diffstat (limited to 'app/controllers')
90 files changed, 367 insertions, 292 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index a680c1f4517..75d1e4bf6a0 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -13,7 +13,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController before_action :disable_query_limiting, only: [:usage_data] - feature_category :not_owned, [ + feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned :general, :reporting, :metrics_and_profiling, :network, :preferences, :update, :reset_health_check_token ] @@ -53,6 +53,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def service_usage_data + @service_ping_data_present = Rails.cache.exist?('usage_data') end def update diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb index d4b906d5e33..4eda35d66f6 100644 --- a/app/controllers/admin/background_jobs_controller.rb +++ b/app/controllers/admin/background_jobs_controller.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Admin::BackgroundJobsController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned end diff --git a/app/controllers/admin/background_migrations_controller.rb b/app/controllers/admin/background_migrations_controller.rb index e21e6fd2dcb..42b89a3317e 100644 --- a/app/controllers/admin/background_migrations_controller.rb +++ b/app/controllers/admin/background_migrations_controller.rb @@ -6,8 +6,8 @@ class Admin::BackgroundMigrationsController < Admin::ApplicationController def index @relations_by_tab = { 'queued' => batched_migration_class.queued.queue_order, - 'failed' => batched_migration_class.failed.queue_order, - 'finished' => batched_migration_class.finished.queue_order.reverse_order + 'failed' => batched_migration_class.with_status(:failed).queue_order, + 'finished' => batched_migration_class.with_status(:finished).queue_order.reverse_order } @current_tab = @relations_by_tab.key?(params[:tab]) ? params[:tab] : 'queued' @@ -17,14 +17,14 @@ class Admin::BackgroundMigrationsController < Admin::ApplicationController def pause migration = batched_migration_class.find(params[:id]) - migration.paused! + migration.pause! redirect_back fallback_location: { action: 'index' } end def resume migration = batched_migration_class.find(params[:id]) - migration.active! + migration.execute! redirect_back fallback_location: { action: 'index' } end diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index ef843a84e6c..8b672929f88 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -45,8 +45,8 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController end def preview - broadcast_message = BroadcastMessage.new(broadcast_message_params) - render json: { message: render_broadcast_message(broadcast_message) } + @broadcast_message = BroadcastMessage.new(broadcast_message_params) + render partial: 'admin/broadcast_messages/preview' end protected @@ -58,8 +58,8 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController def broadcast_message_params params.require(:broadcast_message).permit(%i( color + theme ends_at - font message starts_at target_path diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index d12ccfc7423..20e36e5fd84 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -5,7 +5,7 @@ class Admin::DashboardController < Admin::ApplicationController COUNTED_ITEMS = [Project, User, Group].freeze - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb index 5733929c25e..3614f83723d 100644 --- a/app/controllers/admin/health_check_controller.rb +++ b/app/controllers/admin/health_check_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::HealthCheckController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def show @errors = HealthCheck::Utils.process_checks(checks) diff --git a/app/controllers/admin/integrations_controller.rb b/app/controllers/admin/integrations_controller.rb index db9835e65ec..ad0ee0b2cef 100644 --- a/app/controllers/admin/integrations_controller.rb +++ b/app/controllers/admin/integrations_controller.rb @@ -5,10 +5,6 @@ class Admin::IntegrationsController < Admin::ApplicationController before_action :not_found, unless: -> { instance_level_integrations? } - before_action do - push_frontend_feature_flag(:integration_form_sections, default_enabled: :yaml) - end - feature_category :integrations def overrides diff --git a/app/controllers/admin/plan_limits_controller.rb b/app/controllers/admin/plan_limits_controller.rb index 420fd93fad5..7bfbabe8dfc 100644 --- a/app/controllers/admin/plan_limits_controller.rb +++ b/app/controllers/admin/plan_limits_controller.rb @@ -5,7 +5,7 @@ class Admin::PlanLimitsController < Admin::ApplicationController before_action :set_plan_limits - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def create redirect_path = referer_path(request) || general_admin_application_settings_path @@ -38,6 +38,14 @@ class Admin::PlanLimitsController < Admin::ApplicationController pypi_max_file_size terraform_module_max_file_size generic_packages_max_file_size + ci_pipeline_size + ci_active_jobs + ci_active_pipelines + ci_project_subscriptions + ci_pipeline_schedules + ci_needs_size_limit + ci_registered_group_runners + ci_registered_project_runners ]) end end diff --git a/app/controllers/admin/requests_profiles_controller.rb b/app/controllers/admin/requests_profiles_controller.rb index fbbe8c24637..b60cb7ff9c2 100644 --- a/app/controllers/admin/requests_profiles_controller.rb +++ b/app/controllers/admin/requests_profiles_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::RequestsProfilesController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def index @profile_token = Gitlab::RequestProfiler.profile_token diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 2744be0150c..06880ace899 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -4,6 +4,9 @@ class Admin::RunnersController < Admin::ApplicationController include RunnerSetupScripts before_action :runner, except: [:index, :tag_list, :runner_setup_scripts] + before_action only: [:index] do + push_frontend_feature_flag(:admin_runners_bulk_delete, default_enabled: :yaml) + end feature_category :runner diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb index 67d991c8b03..e4e866a8b60 100644 --- a/app/controllers/admin/spam_logs_controller.rb +++ b/app/controllers/admin/spam_logs_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::SpamLogsController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb index f14305528a3..7ae930abb84 100644 --- a/app/controllers/admin/system_info_controller.rb +++ b/app/controllers/admin/system_info_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::SystemInfoController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned EXCLUDED_MOUNT_OPTIONS = %w[ nobrowse diff --git a/app/controllers/admin/version_check_controller.rb b/app/controllers/admin/version_check_controller.rb index dde1a7abafa..f5c70dc9e1b 100644 --- a/app/controllers/admin/version_check_controller.rb +++ b/app/controllers/admin/version_check_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::VersionCheckController < Admin::ApplicationController - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def version_check response = VersionCheck.new.response diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1d17e8aa085..572ec40ef16 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -196,6 +196,27 @@ class ApplicationController < ActionController::Base end end + # Devise defines current_user to be: + # + # def current_user + # @current_user ||= warden.authenticate(scope: mapping) + # end + # + # That means whenever current_user is called and `@current_user` is + # nil, Warden will attempt to authenticate a user. To avoid + # reauthenticating anonymous users, we may need to invalidate + # the user. + def reset_auth_user! + return if strong_memoized?(:auth_user) && auth_user + + # Controllers usually call auth_user first, but for some controllers + # authenticate_sessionless_user! is called after that. If we relied + # on the memoized auth_user, the value would always be nil for + # sessionless users. + clear_memoization(:auth_user) + auth_user + end + def log_exception(exception) # At this point, the controller already exits set_current_context around # block. To maintain the context while handling error exception, we need to diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 4bcd1be9f53..663e3cf8648 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -13,6 +13,7 @@ class AutocompleteController < ApplicationController feature_category :continuous_delivery, [:deploy_keys_with_owners] urgency :low, [:merge_request_target_branches] + urgency :default, [:users] def users group = Autocomplete::GroupFinder diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index d9179129983..939c0ef220c 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -14,7 +14,7 @@ class Clusters::ClustersController < Clusters::BaseController before_action :authorize_create_cluster!, only: [:new, :connect, :authorize_aws_role] before_action :authorize_update_cluster!, only: [:update] before_action :update_applications_status, only: [:cluster_status] - before_action :ensure_feature_enabled!, except: :index + before_action :ensure_feature_enabled!, except: [:index, :new_cluster_docs] helper_method :token_in_session @@ -184,7 +184,7 @@ class Clusters::ClustersController < Clusters::BaseController def cluster_list return [] unless certificate_based_clusters_enabled? - finder = ClusterAncestorsFinder.new(clusterable.subject, current_user) + finder = ClusterAncestorsFinder.new(clusterable.__subject__, current_user) clusters = finder.execute @has_ancestor_clusters = finder.has_ancestor_clusters? @@ -253,7 +253,7 @@ class Clusters::ClustersController < Clusters::BaseController ]).merge( provider_type: :gcp, platform_type: :kubernetes, - clusterable: clusterable.subject + clusterable: clusterable.__subject__ ) end @@ -274,7 +274,7 @@ class Clusters::ClustersController < Clusters::BaseController ]).merge( provider_type: :aws, platform_type: :kubernetes, - clusterable: clusterable.subject + clusterable: clusterable.__subject__ ) end @@ -291,7 +291,7 @@ class Clusters::ClustersController < Clusters::BaseController ]).merge( provider_type: :user, platform_type: :kubernetes, - clusterable: clusterable.subject + clusterable: clusterable.__subject__ ) end @@ -313,7 +313,7 @@ class Clusters::ClustersController < Clusters::BaseController end def gcp_cluster - cluster = Clusters::BuildService.new(clusterable.subject).execute + cluster = Clusters::BuildService.new(clusterable.__subject__).execute cluster.build_provider_gcp @gcp_cluster = cluster.present(current_user: current_user) end @@ -343,7 +343,7 @@ class Clusters::ClustersController < Clusters::BaseController end def user_cluster - cluster = Clusters::BuildService.new(clusterable.subject).execute + cluster = Clusters::BuildService.new(clusterable.__subject__).execute cluster.build_platform_kubernetes @user_cluster = cluster.present(current_user: current_user) end diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb index c67e73d4e78..b1b6e21644e 100644 --- a/app/controllers/concerns/enforces_two_factor_authentication.rb +++ b/app/controllers/concerns/enforces_two_factor_authentication.rb @@ -10,6 +10,11 @@ module EnforcesTwoFactorAuthentication extend ActiveSupport::Concern + MFA_HELP_PAGE = Rails.application.routes.url_helpers.help_page_url( + 'user/profile/account/two_factor_authentication.html', + anchor: 'enable-two-factor-authentication' + ) + included do before_action :check_two_factor_requirement, except: [:route_not_found] @@ -24,7 +29,16 @@ module EnforcesTwoFactorAuthentication return unless respond_to?(:current_user) if two_factor_authentication_required? && current_user_requires_two_factor? - redirect_to profile_two_factor_auth_path + case self + when GraphqlController + render_error( + _("Authentication error: enable 2FA in your profile settings to continue using GitLab: %{mfa_help_page}") % + { mfa_help_page: MFA_HELP_PAGE }, + status: :unauthorized + ) + else + redirect_to profile_two_factor_auth_path + end end end diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb index 80acb369cb2..d256b331174 100644 --- a/app/controllers/concerns/integrations/params.rb +++ b/app/controllers/concerns/integrations/params.rb @@ -89,7 +89,7 @@ module Integrations param_values = return_value[:integration] if param_values.is_a?(ActionController::Parameters) - integration.password_fields.each do |param| + integration.secret_fields.each do |param| param_values.delete(param) if param_values[param].blank? end end diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb index 48daacc09c2..7ec9be6baaf 100644 --- a/app/controllers/concerns/sessionless_authentication.rb +++ b/app/controllers/concerns/sessionless_authentication.rb @@ -20,16 +20,21 @@ module SessionlessAuthentication end def sessionless_sign_in(user) - if user.can_log_in_with_non_expired_password? - # Notice we are passing store false, so the user is not - # actually stored in the session and a token is needed - # for every request. If you want the token to work as a - # sign in token, you can simply remove store: false. - sign_in(user, store: false, message: :sessionless_sign_in) - elsif request_authenticator.can_sign_in_bot?(user) - # we suppress callbacks to avoid redirecting the bot - sign_in(user, store: false, message: :sessionless_sign_in, run_callbacks: false) - end + signed_in_user = + if user.can_log_in_with_non_expired_password? + # Notice we are passing store false, so the user is not + # actually stored in the session and a token is needed + # for every request. If you want the token to work as a + # sign in token, you can simply remove store: false. + sign_in(user, store: false, message: :sessionless_sign_in) + elsif request_authenticator.can_sign_in_bot?(user) + # we suppress callbacks to avoid redirecting the bot + sign_in(user, store: false, message: :sessionless_sign_in, run_callbacks: false) + end + + reset_auth_user! if respond_to?(:reset_auth_user!, true) + + signed_in_user end def sessionless_bypass_admin_mode!(&block) diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index 714a6f280f3..91de1d8aeae 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -21,10 +21,6 @@ module WikiActions before_action :load_sidebar, except: [:pages] before_action :set_content_class - before_action do - push_frontend_feature_flag(:wiki_switch_between_content_editor_raw_markdown, @group, default_enabled: :yaml) - end - before_action only: [:show, :edit, :update] do @valid_encoding = valid_encoding? end @@ -223,7 +219,7 @@ module WikiActions def page strong_memoize(:page) do - wiki.find_page(*page_params) + wiki.find_page(*page_params, load_content: load_content?) end end @@ -310,6 +306,12 @@ module WikiActions def send_wiki_file_blob(wiki, file_blob) send_blob(wiki.repository, file_blob) end + + def load_content? + return false if %w[history destroy diff show].include?(params[:action]) + + true + end end WikiActions.prepend_mod diff --git a/app/controllers/dashboard/application_controller.rb b/app/controllers/dashboard/application_controller.rb index 0e9fdc60363..95deacdc5b9 100644 --- a/app/controllers/dashboard/application_controller.rb +++ b/app/controllers/dashboard/application_controller.rb @@ -11,6 +11,6 @@ class Dashboard::ApplicationController < ApplicationController private def projects - @projects ||= current_user.authorized_projects.sorted_by_activity.non_archived + @projects ||= current_user.authorized_projects.sorted_by_updated_desc.non_archived end end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index f8a6d9f808e..23e0143506e 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -25,6 +25,9 @@ class Explore::ProjectsController < Explore::ApplicationController feature_category :projects + # TODO: Set higher urgency after addressing https://gitlab.com/gitlab-org/gitlab/-/issues/357913 + urgency :low, [:index] + def index show_alert_if_search_is_disabled @projects = load_projects @@ -110,7 +113,7 @@ class Explore::ProjectsController < Explore::ApplicationController end def load_topic - @topic = Projects::Topic.find_by_name(params[:topic_name]) + @topic = Projects::Topic.find_by_name_case_insensitive(params[:topic_name]) end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index ef229a2abec..b00d85b6b0f 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -32,6 +32,7 @@ class GraphqlController < ApplicationController before_action :set_user_last_activity before_action :track_vs_code_usage before_action :track_jetbrains_usage + before_action :track_gitlab_cli_usage before_action :disable_query_limiting before_action :limit_query_size @@ -43,7 +44,7 @@ class GraphqlController < ApplicationController around_action :sessionless_bypass_admin_mode!, if: :sessionless_user? # The default feature category is overridden to read from request - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned # We don't know what the query is going to be, so we can't set a high urgency # See https://gitlab.com/groups/gitlab-org/-/epics/5841 for the work that will @@ -143,6 +144,11 @@ class GraphqlController < ApplicationController .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) end + def track_gitlab_cli_usage + Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter + .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) + end + def execute_multiplex GitlabSchema.multiplex(multiplex_queries, context: context) end diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index 641b3adb12b..c65232c0fea 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -8,7 +8,7 @@ class Groups::BoardsController < Groups::ApplicationController before_action :assign_endpoint_vars before_action do push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml) - push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml) + push_frontend_feature_flag(:realtime_labels, group, default_enabled: :yaml) experiment(:prominent_create_board_btn, subject: current_user) do |e| e.control { } e.candidate { } @@ -43,11 +43,11 @@ class Groups::BoardsController < Groups::ApplicationController def assign_endpoint_vars @boards_endpoint = group_boards_path(group) - @namespace_path = group.to_param - @labels_endpoint = group_labels_path(group) end def authorize_read_board! access_denied! unless can?(current_user, :read_issue_board, group) end end + +Groups::BoardsController.prepend_mod diff --git a/app/controllers/groups/children_controller.rb b/app/controllers/groups/children_controller.rb index 10a6ad06ae5..d10c52f0301 100644 --- a/app/controllers/groups/children_controller.rb +++ b/app/controllers/groups/children_controller.rb @@ -9,6 +9,9 @@ module Groups feature_category :subgroups + # TODO: Set to higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/331494 + urgency :low, [:index] + def index params[:sort] ||= @group_projects_sort parent = if params[:parent_id].present? diff --git a/app/controllers/groups/crm/organizations_controller.rb b/app/controllers/groups/crm/organizations_controller.rb index f8536b4f538..846995ecba5 100644 --- a/app/controllers/groups/crm/organizations_controller.rb +++ b/app/controllers/groups/crm/organizations_controller.rb @@ -10,6 +10,10 @@ class Groups::Crm::OrganizationsController < Groups::ApplicationController render action: "index" end + def edit + render action: "index" + end + private def authorize_read_crm_organization! diff --git a/app/controllers/groups/email_campaigns_controller.rb b/app/controllers/groups/email_campaigns_controller.rb index 520ad768939..70c8a23d918 100644 --- a/app/controllers/groups/email_campaigns_controller.rb +++ b/app/controllers/groups/email_campaigns_controller.rb @@ -40,7 +40,7 @@ class Groups::EmailCampaignsController < Groups::ApplicationController project_pipelines_url(group.projects.first) when :trial, :trial_short 'https://about.gitlab.com/free-trial/' - when :team, :team_short, :invite_team + when :team, :team_short group_group_members_url(group) when :admin_verify project_settings_ci_cd_path(group.projects.first, ci_runner_templates: true, anchor: 'js-runners-settings') @@ -59,11 +59,6 @@ class Groups::EmailCampaignsController < Groups::ApplicationController @track = params[:track]&.to_sym @series = params[:series]&.to_i - # There is only one email that will be sent for invite team track so series - # should only have the value 0. Return early if track is invite team and - # condition for series value is met - return if @track == Namespaces::InviteTeamEmailService::TRACK && @series == 0 - track_valid = @track.in?(Namespaces::InProductMarketingEmailsService::TRACKS.keys) return render_404 unless track_valid diff --git a/app/controllers/groups/group_links_controller.rb b/app/controllers/groups/group_links_controller.rb index 0655d779a4e..cc2ca728592 100644 --- a/app/controllers/groups/group_links_controller.rb +++ b/app/controllers/groups/group_links_controller.rb @@ -6,30 +6,12 @@ class Groups::GroupLinksController < Groups::ApplicationController feature_category :subgroups - def create - shared_with_group = Group.find(params[:shared_with_group_id]) if params[:shared_with_group_id].present? - - if shared_with_group - result = Groups::GroupLinks::CreateService - .new(group, shared_with_group, current_user, group_link_create_params) - .execute - - return render_404 if result[:http_status] == 404 - - flash[:alert] = result[:message] if result[:status] == :error - else - flash[:alert] = _('Please select a group.') - end - - redirect_to group_group_members_path(group) - end - def update Groups::GroupLinks::UpdateService.new(@group_link).execute(group_link_params) if @group_link.expires? render json: { - expires_in: helpers.distance_of_time_in_words_to_now(@group_link.expires_at), + expires_in: helpers.time_ago_with_tooltip(@group_link.expires_at), expires_soon: @group_link.expires_soon? } else @@ -54,10 +36,6 @@ class Groups::GroupLinksController < Groups::ApplicationController @group_link ||= group.shared_with_group_links.find(params[:id]) end - def group_link_create_params - params.permit(:shared_group_access, :expires_at) - end - def group_link_params params.require(:group_link).permit(:group_access, :expires_at) end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index ece1083d4d1..51778f31f65 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -20,10 +20,13 @@ class Groups::GroupMembersController < Groups::ApplicationController :approve_access_request, :leave, :resend_invite, :override - feature_category :authentication_and_authorization + feature_category :subgroups def index + push_frontend_feature_flag(:group_member_inherited_group, @group) + @sort = params[:sort].presence || sort_value_name + @include_relations ||= requested_relations if can?(current_user, :admin_group_member, @group) @invited_members = invited_members diff --git a/app/controllers/groups/releases_controller.rb b/app/controllers/groups/releases_controller.rb index db5385ecc71..e87135cc104 100644 --- a/app/controllers/groups/releases_controller.rb +++ b/app/controllers/groups/releases_controller.rb @@ -17,8 +17,10 @@ module Groups def releases if Feature.enabled?(:group_releases_finder_inoperator) Releases::GroupReleasesFinder - .new(@group, current_user, { include_subgroups: true, page: params[:page], per: 30 }) + .new(@group, current_user) .execute(preload: false) + .page(params[:page]) + .per(30) else ReleasesFinder .new(@group, current_user, { include_subgroups: true }) diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index dabef978ee1..a2be4d9d7e1 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -11,6 +11,8 @@ class Groups::RunnersController < Groups::ApplicationController def index finder = Ci::RunnersFinder.new(current_user: current_user, params: { group: @group }) @group_runners_limited_count = finder.execute.except(:limit, :offset).page.total_count_with_limit(:all, limit: 1000) + + Gitlab::Tracking.event(self.class.name, 'index', user: current_user, namespace: @group) end def runner_list_group_view_vue_ui_enabled diff --git a/app/controllers/groups/settings/integrations_controller.rb b/app/controllers/groups/settings/integrations_controller.rb index ec64e75a68e..0a63c3d304b 100644 --- a/app/controllers/groups/settings/integrations_controller.rb +++ b/app/controllers/groups/settings/integrations_controller.rb @@ -7,10 +7,6 @@ module Groups before_action :authorize_admin_group! - before_action do - push_frontend_feature_flag(:integration_form_sections, group, default_enabled: :yaml) - end - feature_category :integrations layout 'group_settings' diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index b53d9b1be04..995d5abf045 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -15,7 +15,6 @@ class GroupsController < Groups::ApplicationController prepend_before_action(only: [:show, :issues]) { authenticate_sessionless_user!(:rss) } prepend_before_action(only: [:issues_calendar]) { authenticate_sessionless_user!(:ics) } - prepend_before_action :ensure_export_enabled, only: [:export, :download_export] prepend_before_action :check_captcha, only: :create, if: -> { captcha_enabled? } before_action :authenticate_user!, only: [:new, :create] @@ -33,7 +32,6 @@ class GroupsController < Groups::ApplicationController before_action do push_frontend_feature_flag(:vue_issues_list, @group, default_enabled: :yaml) - push_frontend_feature_flag(:iteration_cadences, @group, default_enabled: :yaml) end before_action :check_export_rate_limit!, only: [:export, :download_export] @@ -61,7 +59,8 @@ class GroupsController < Groups::ApplicationController feature_category :importers, [:export, :download_export] urgency :high, [:unfoldered_environment_names] - urgency :low, [:merge_requests] + # TODO: Set #show to higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/334795 + urgency :low, [:merge_requests, :show] def index redirect_to(current_user ? dashboard_groups_path : explore_groups_path) @@ -218,6 +217,8 @@ class GroupsController < Groups::ApplicationController @has_projects = group_projects.exists? + set_sort_order + respond_to do |format| format.html end @@ -293,7 +294,7 @@ class GroupsController < Groups::ApplicationController :setup_for_company, :jobs_to_be_done, :crm_enabled - ] + ] + [group_feature_attributes: group_feature_attributes] end # rubocop: disable CodeReuse/ActiveRecord @@ -338,10 +339,6 @@ class GroupsController < Groups::ApplicationController check_rate_limit!(prefixed_action, scope: [current_user, scope].compact) end - def ensure_export_enabled - render_404 unless Feature.enabled?(:group_import_export, @group, default_enabled: true) - end - private def load_recaptcha @@ -400,6 +397,10 @@ class GroupsController < Groups::ApplicationController experiment(:require_verification_for_namespace_creation, user: current_user).track(:start_create_group) end + + def group_feature_attributes + [] + end end GroupsController.prepend_mod_with('GroupsController') diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index f267d383804..5be2d7527ff 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -3,7 +3,7 @@ class HelpController < ApplicationController skip_before_action :authenticate_user!, unless: :public_visibility_restricted? skip_before_action :check_two_factor_requirement - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned layout 'help' diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index 44beceb4f48..9494a686467 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -18,6 +18,8 @@ class IdeController < ApplicationController feature_category :web_ide + urgency :low + def index Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count end diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb index 7ad3a2ee358..51ca12370e6 100644 --- a/app/controllers/import/base_controller.rb +++ b/app/controllers/import/base_controller.rb @@ -13,7 +13,13 @@ class Import::BaseController < ApplicationController provider_repos: serialized_provider_repos, incompatible_repos: serialized_incompatible_repos } end - format.html + format.html do + if params[:namespace_id]&.present? + @namespace = Namespace.find_by_id(params[:namespace_id]) + + render_404 unless current_user.can?(:create_projects, @namespace) + end + end end end @@ -70,7 +76,7 @@ class Import::BaseController < ApplicationController end def already_added_projects - @already_added_projects ||= filtered(find_already_added_projects(provider_name)) + @already_added_projects ||= find_already_added_projects(provider_name) end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index cfd86429df0..7c9525d1744 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -12,14 +12,21 @@ class Import::BitbucketController < Import::BaseController rescue_from Bitbucket::Error::Unauthorized, with: :bitbucket_unauthorized def callback - response = oauth_client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url) + auth_state = session[:bitbucket_auth_state] + session[:bitbucket_auth_state] = nil - session[:bitbucket_token] = response.token - session[:bitbucket_expires_at] = response.expires_at - session[:bitbucket_expires_in] = response.expires_in - session[:bitbucket_refresh_token] = response.refresh_token + if auth_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(auth_state, params[:state]) + go_to_bitbucket_for_permissions + else + response = oauth_client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url) + + session[:bitbucket_token] = response.token + session[:bitbucket_expires_at] = response.expires_at + session[:bitbucket_expires_in] = response.expires_in + session[:bitbucket_refresh_token] = response.refresh_token - redirect_to status_import_bitbucket_url + redirect_to status_import_bitbucket_url + end end def status @@ -113,7 +120,9 @@ class Import::BitbucketController < Import::BaseController end def go_to_bitbucket_for_permissions - redirect_to oauth_client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url) + state = SecureRandom.base64(64) + session[:bitbucket_auth_state] = state + redirect_to oauth_client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url, state: state) end def bitbucket_unauthorized(exception) diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 55f4563285d..9bd8f893614 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -23,24 +23,25 @@ class Import::GithubController < Import::BaseController if !ci_cd_only? && github_import_configured? && logged_in_with_provider? go_to_provider_for_permissions elsif session[access_token_key] - redirect_to status_import_url + redirect_to status_import_url(namespace_id: params[:namespace_id]) end end def callback - auth_state = session[auth_state_key] - session[auth_state_key] = nil + auth_state = session.delete(auth_state_key) + namespace_id = session.delete(:namespace_id) + if auth_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(auth_state, params[:state]) provider_unauthorized else session[access_token_key] = get_token(params[:code]) - redirect_to status_import_url + redirect_to status_import_url(namespace_id: namespace_id) end end def personal_access_token session[access_token_key] = params[:personal_access_token]&.strip - redirect_to status_import_url + redirect_to status_import_url(namespace_id: params[:namespace_id].presence) end def status @@ -62,7 +63,15 @@ class Import::GithubController < Import::BaseController end def realtime_changes - super + Gitlab::PollingInterval.set_header(response, interval: 3_000) + + render json: already_added_projects.map { |project| + { + id: project.id, + import_status: project.import_status, + stats: ::Gitlab::GithubImport::ObjectCounter.summary(project) + } + } end protected @@ -201,8 +210,8 @@ class Import::GithubController < Import::BaseController public_send("new_import_#{provider_name}_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend end - def status_import_url - public_send("status_import_#{provider_name}_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend + def status_import_url(namespace_id: nil) + public_send("status_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: namespace_id })) # rubocop:disable GitlabSecurity/PublicSend end def callback_import_url @@ -248,6 +257,7 @@ class Import::GithubController < Import::BaseController def provider_auth if !ci_cd_only? && session[access_token_key].blank? + session[:namespace_id] = params[:namespace_id] go_to_provider_for_permissions end end diff --git a/app/controllers/import/gitlab_groups_controller.rb b/app/controllers/import/gitlab_groups_controller.rb index aca71f6d57a..c9d5e9986dc 100644 --- a/app/controllers/import/gitlab_groups_controller.rb +++ b/app/controllers/import/gitlab_groups_controller.rb @@ -3,7 +3,6 @@ class Import::GitlabGroupsController < ApplicationController include WorkhorseAuthorization - before_action :ensure_group_import_enabled before_action :check_import_rate_limit!, only: %i[create] feature_category :importers @@ -51,10 +50,6 @@ class Import::GitlabGroupsController < ApplicationController end end - def ensure_group_import_enabled - render_404 unless Feature.enabled?(:group_import_export, @group, default_enabled: true) - end - def check_import_rate_limit! check_rate_limit!(:group_import, scope: current_user) do redirect_to new_group_path, alert: _('This endpoint has been requested too many times. Try again later.') diff --git a/app/controllers/import/history_controller.rb b/app/controllers/import/history_controller.rb new file mode 100644 index 00000000000..69e31392f21 --- /dev/null +++ b/app/controllers/import/history_controller.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Import::HistoryController < ApplicationController + feature_category :importers +end diff --git a/app/controllers/jira_connect/application_controller.rb b/app/controllers/jira_connect/application_controller.rb index 352e78d6255..9b3bff062dd 100644 --- a/app/controllers/jira_connect/application_controller.rb +++ b/app/controllers/jira_connect/application_controller.rb @@ -22,6 +22,8 @@ class JiraConnect::ApplicationController < ApplicationController def verify_qsh_claim! payload, _ = decode_auth_token! + return if request.format.json? && payload['qsh'] == 'context-qsh' + # 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 StandardError diff --git a/app/controllers/jira_connect/events_controller.rb b/app/controllers/jira_connect/events_controller.rb index 327192857f6..3c78f63e069 100644 --- a/app/controllers/jira_connect/events_controller.rb +++ b/app/controllers/jira_connect/events_controller.rb @@ -7,10 +7,6 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController before_action :verify_asymmetric_atlassian_jwt! def installed - unless Feature.enabled?(:jira_connect_installation_update, default_enabled: :yaml) - return head :ok if current_jira_installation - end - success = current_jira_installation ? update_installation : create_installation if success diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb index ec6ba07a125..d8ce67d6267 100644 --- a/app/controllers/jira_connect/subscriptions_controller.rb +++ b/app/controllers/jira_connect/subscriptions_controller.rb @@ -11,7 +11,9 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController style_src_values = Array.wrap(p.directives['style-src']) | %w('self' 'unsafe-inline') # rubocop: enable Lint/PercentStringArray - p.frame_ancestors :self, 'https://*.atlassian.net' + # *.jira.com is needed for some legacy Jira Cloud instances, new ones will use *.atlassian.net + # https://support.atlassian.com/organization-administration/docs/ip-addresses-and-domains-for-atlassian-cloud-products/ + p.frame_ancestors :self, 'https://*.atlassian.net', 'https://*.jira.com' p.script_src(*script_src_values) p.style_src(*style_src_values) end diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 010b85e81bf..8eebf9fbf6b 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -9,6 +9,8 @@ class JwtController < ApplicationController prepend_before_action :auth_user, :authenticate_project_or_user feature_category :authentication_and_authorization + # https://gitlab.com/gitlab-org/gitlab/-/issues/357037 + urgency :low SERVICES = { ::Auth::ContainerRegistryAuthenticationService::AUDIENCE => ::Auth::ContainerRegistryAuthenticationService, diff --git a/app/controllers/oauth/jira/authorizations_controller.rb b/app/controllers/oauth/jira_dvcs/authorizations_controller.rb index 8169b5fcbb0..613999f4ca7 100644 --- a/app/controllers/oauth/jira/authorizations_controller.rb +++ b/app/controllers/oauth/jira_dvcs/authorizations_controller.rb @@ -4,7 +4,7 @@ # flow routes for Jira DVCS integration. # See https://gitlab.com/gitlab-org/gitlab/issues/2381 # -class Oauth::Jira::AuthorizationsController < ApplicationController +class Oauth::JiraDvcs::AuthorizationsController < ApplicationController skip_before_action :authenticate_user! skip_before_action :verify_authenticity_token @@ -17,7 +17,7 @@ class Oauth::Jira::AuthorizationsController < ApplicationController redirect_to oauth_authorization_path(client_id: params['client_id'], response_type: 'code', scope: normalize_scope(params['scope']), - redirect_uri: oauth_jira_callback_url) + redirect_uri: oauth_jira_dvcs_callback_url) end # 2. Handle the callback call as we were a Github Enterprise instance client. @@ -33,7 +33,7 @@ class Oauth::Jira::AuthorizationsController < ApplicationController # 3. Rewire and adjust access_token request accordingly. def access_token # We have to modify request.parameters because Doorkeeper::Server reads params from there - request.parameters[:redirect_uri] = oauth_jira_callback_url + request.parameters[:redirect_uri] = oauth_jira_dvcs_callback_url strategy = Doorkeeper::Server.new(self).token_request('authorization_code') response = strategy.authorize diff --git a/app/controllers/profiles/chat_names_controller.rb b/app/controllers/profiles/chat_names_controller.rb index 8cfec247b7a..ae757c30d1c 100644 --- a/app/controllers/profiles/chat_names_controller.rb +++ b/app/controllers/profiles/chat_names_controller.rb @@ -4,7 +4,7 @@ class Profiles::ChatNamesController < Profiles::ApplicationController before_action :chat_name_token, only: [:new] before_action :chat_name_params, only: [:new, :create, :deny] - feature_category :users + feature_category :integrations def index @chat_names = current_user.chat_names diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 6ef0ed6d365..ccfd360a781 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Profiles::NotificationsController < Profiles::ApplicationController - feature_category :users + feature_category :team_planning def show @user = current_user diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index adecb56ea38..820b6520f6c 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -36,6 +36,8 @@ class Profiles::PreferencesController < Profiles::ApplicationController def preferences_param_names [ :color_scheme_id, + :diffs_deletion_color, + :diffs_addition_color, :layout, :dashboard, :project_view, diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 77fae34e2d2..48b0d313d3c 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -4,6 +4,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController skip_before_action :check_two_factor_requirement before_action :ensure_verified_primary_email, only: [:show, :create] before_action :validate_current_password, only: [:create, :codes, :destroy], if: :current_password_required? + before_action :update_current_user_otp!, only: [:show] helper_method :current_password_required? @@ -14,16 +15,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController feature_category :authentication_and_authorization def show - unless current_user.two_factor_enabled? - current_user.otp_secret = User.generate_otp_secret(32) - end - - unless current_user.otp_grace_period_started_at && two_factor_grace_period - current_user.otp_grace_period_started_at = Time.current - end - - Users::UpdateService.new(current_user, user: current_user).execute! - if two_factor_authentication_required? && !current_user.two_factor_enabled? two_factor_authentication_reason( global: lambda do @@ -68,6 +59,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController else @error = { message: _('Invalid pin code.') } @qr_code = build_qr_code + @account_string = account_string if Feature.enabled?(:webauthn, default_enabled: :yaml) setup_webauthn_registration @@ -138,6 +130,18 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController private + def update_current_user_otp! + if current_user.needs_new_otp_secret? + current_user.update_otp_secret! + end + + unless current_user.otp_grace_period_started_at && two_factor_grace_period + current_user.otp_grace_period_started_at = Time.current + end + + Users::UpdateService.new(current_user, user: current_user).execute! + end + def validate_current_password return if current_user.valid_password?(params[:current_password]) diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb index 7bb3ed1d109..feed94708f6 100644 --- a/app/controllers/projects/artifacts_controller.rb +++ b/app/controllers/projects/artifacts_controller.rb @@ -5,6 +5,8 @@ class Projects::ArtifactsController < Projects::ApplicationController include RendersBlob include SendFileUpload + urgency :low, [:browse, :file, :latest_succeeded] + layout 'project' before_action :authorize_read_build! before_action :authorize_update_build!, only: [:keep] diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index c44a0830e2e..7a30e68d9a2 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -8,7 +8,7 @@ class Projects::BoardsController < Projects::ApplicationController before_action :assign_endpoint_vars before_action do 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(:realtime_labels, project&.group, default_enabled: :yaml) experiment(:prominent_create_board_btn, subject: current_user) do |e| e.control { } e.candidate { } @@ -44,11 +44,11 @@ class Projects::BoardsController < Projects::ApplicationController def assign_endpoint_vars @boards_endpoint = project_boards_path(project) @bulk_issues_path = bulk_update_project_issues_path(project) - @namespace_path = project.namespace.full_path - @labels_endpoint = project_labels_path(project) end def authorize_read_board! access_denied! unless can?(current_user, :read_issue_board, project) end end + +Projects::BoardsController.prepend_mod diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index dad73c37fea..6264f10ce2d 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -34,11 +34,9 @@ class Projects::BranchesController < Projects::ApplicationController Gitlab::GitalyClient.allow_n_plus_1_calls do render end - rescue Gitlab::Git::CommandError => e - Gitlab::ErrorTracking.track_exception(e) - + rescue Gitlab::Git::CommandError @gitaly_unavailable = true - render + render status: :service_unavailable end format.json do branches = BranchesFinder.new(@repository, params).execute diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 0c26b402876..2b2764d2e34 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -31,7 +31,7 @@ class Projects::CommitController < Projects::ApplicationController respond_to do |format| format.html do - render + render locals: { pagination_params: params.permit(:page) } end format.diff do send_git_diff(@project.repository, @commit.diff_refs) @@ -106,6 +106,8 @@ class Projects::CommitController < Projects::ApplicationController end def revert + return render_404 unless @commit + assign_change_commit_vars return render_404 if @start_branch.blank? @@ -117,6 +119,8 @@ class Projects::CommitController < Projects::ApplicationController end def cherry_pick + return render_404 unless @commit + assign_change_commit_vars return render_404 if @start_branch.blank? diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 243cc7a346c..3ced5f21b24 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -34,7 +34,7 @@ class Projects::CompareController < Projects::ApplicationController def show apply_diff_view_cookie! - render + render locals: { pagination_params: params.permit(:page) } end def diff_for_path diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index eabc048e341..8e81e75ad13 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -104,11 +104,11 @@ class Projects::EnvironmentsController < Projects::ApplicationController def stop return render_404 unless @environment.available? - stop_action = @environment.stop_with_action!(current_user) + stop_actions = @environment.stop_with_actions!(current_user) action_or_env_url = - if stop_action - polymorphic_url([project, stop_action]) + if stop_actions&.count == 1 + polymorphic_url([project, stop_actions.first]) else project_environment_url(project, @environment) end diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb index f293ec752ab..0d65431d870 100644 --- a/app/controllers/projects/google_cloud/base_controller.rb +++ b/app/controllers/projects/google_cloud/base_controller.rb @@ -25,7 +25,11 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController end def feature_flag_enabled! - unless Feature.enabled?(:incubation_5mp_google_cloud) + enabled_for_user = Feature.enabled?(:incubation_5mp_google_cloud, current_user) + enabled_for_group = Feature.enabled?(:incubation_5mp_google_cloud, project.group) + enabled_for_project = Feature.enabled?(:incubation_5mp_google_cloud, project) + feature_is_enabled = enabled_for_user || enabled_for_group || enabled_for_project + unless feature_is_enabled track_event('feature_flag_enabled!', 'access_denied', 'feature_flag_not_enabled') access_denied! end diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index d3a05736a47..606f6ac7941 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -102,3 +102,5 @@ class Projects::GraphsController < Projects::ApplicationController render json: @log.to_json end end + +Projects::GraphsController.prepend_mod diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb index 6bc81381d92..6007e09f109 100644 --- a/app/controllers/projects/group_links_controller.rb +++ b/app/controllers/projects/group_links_controller.rb @@ -7,21 +7,6 @@ class Projects::GroupLinksController < Projects::ApplicationController feature_category :subgroups - def create - group = Group.find(params[:link_group_id]) if params[:link_group_id].present? - - if group - result = Projects::GroupLinks::CreateService.new(project, current_user, group_link_create_params).execute(group) - return render_404 if result[:http_status] == 404 - - flash[:alert] = result[:message] if result[:http_status] == 409 - else - flash[:alert] = _('Please select a group.') - end - - redirect_to project_project_members_path(project) - end - def update group_link = @project.project_group_links.find(params[:id]) Projects::GroupLinks::UpdateService.new(group_link).execute(group_link_params) @@ -54,10 +39,4 @@ class Projects::GroupLinksController < Projects::ApplicationController def group_link_params params.require(:group_link).permit(:group_access, :expires_at) end - - def group_link_create_params - params.permit(:link_group_access, :expires_at) - end end - -Projects::GroupLinksController.prepend_mod_with('Projects::GroupLinksController') diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb index 293581a6744..dd1e51bb9bd 100644 --- a/app/controllers/projects/incidents_controller.rb +++ b/app/controllers/projects/incidents_controller.rb @@ -7,9 +7,8 @@ class Projects::IncidentsController < Projects::ApplicationController before_action :authorize_read_issue! before_action :load_incident, only: [:show] before_action do - push_frontend_feature_flag(:incident_escalations, @project) - push_frontend_feature_flag(:incident_timeline_event_tab, @project, default_enabled: :yaml) - push_licensed_feature(:incident_timeline_events) if @project.licensed_feature_available?(:incident_timeline_events) + push_frontend_feature_flag(:incident_escalations, @project, default_enabled: :yaml) + push_frontend_feature_flag(:incident_timeline, @project, default_enabled: :yaml) end feature_category :incident_management diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index d4474b9d5a3..46943e7214a 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_ISSUABLES_INDEX_ONLY_ACTIONS = %i[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,9 @@ 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_ISSUABLES_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) && !vue_issues_list? + } # Allow write(create) issue before_action :authorize_create_issue!, only: [:new, :create] @@ -37,18 +39,17 @@ class Projects::IssuesController < Projects::ApplicationController before_action :authorize_download_code!, only: [:related_branches] before_action do - push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml) push_frontend_feature_flag(:vue_issues_list, project&.group, default_enabled: :yaml) - push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml) push_frontend_feature_flag(:contacts_autocomplete, project&.group, default_enabled: :yaml) - push_frontend_feature_flag(:markdown_continue_lists, project, default_enabled: :yaml) + push_frontend_feature_flag(:incident_timeline, project, default_enabled: :yaml) end before_action only: :show do 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(:paginated_issue_discussions, project, default_enabled: :yaml) - push_frontend_feature_flag(:work_items, project&.group, default_enabled: :yaml) + push_frontend_feature_flag(:realtime_labels, project, default_enabled: :yaml) + push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?) end around_action :allow_gitaly_ref_name_caching, only: [:discussions] @@ -72,10 +73,9 @@ class Projects::IssuesController < Projects::ApplicationController attr_accessor :vulnerability_id def index - if html_request? && Feature.enabled?(:vue_issues_list, project&.group, default_enabled: :yaml) + if vue_issues_list? set_sort_order else - set_issuables_index @issues = @issuables end @@ -249,6 +249,12 @@ class Projects::IssuesController < Projects::ApplicationController protected + def vue_issues_list? + action_name.to_sym == :index && + html_request? && + Feature.enabled?(:vue_issues_list, project&.group, default_enabled: :yaml) + end + def sorting_field Issue::SORTING_PREFERENCE_FIELD end diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index b0f032a01e5..4189419c3ba 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -18,6 +18,7 @@ class Projects::JobsController < Projects::ApplicationController before_action :authorize_create_proxy_build!, only: :proxy_websocket_authorize before_action :verify_proxy_request!, only: :proxy_websocket_authorize before_action :push_jobs_table_vue, only: [:index] + before_action :push_jobs_table_vue_search, only: [:index] before_action do push_frontend_feature_flag(:infinitely_collapsible_sections, @project, default_enabled: :yaml) @@ -77,10 +78,13 @@ class Projects::JobsController < Projects::ApplicationController end def retry - return respond_422 unless @build.retryable? + response = Ci::RetryJobService.new(project, current_user).execute(@build) - build = Ci::Build.retry(@build, current_user) - redirect_to build_path(build) + if response.success? + redirect_to build_path(response[:job]) + else + respond_422 + end end def play @@ -269,4 +273,8 @@ class Projects::JobsController < Projects::ApplicationController def push_jobs_table_vue push_frontend_feature_flag(:jobs_table_vue, @project, default_enabled: :yaml) end + + def push_jobs_table_vue_search + push_frontend_feature_flag(:jobs_table_vue_search, @project, default_enabled: :yaml) + end end diff --git a/app/controllers/projects/learn_gitlab_controller.rb b/app/controllers/projects/learn_gitlab_controller.rb index 177533b89c8..b9f9a1810b7 100644 --- a/app/controllers/projects/learn_gitlab_controller.rb +++ b/app/controllers/projects/learn_gitlab_controller.rb @@ -4,6 +4,7 @@ class Projects::LearnGitlabController < Projects::ApplicationController before_action :authenticate_user! before_action :check_experiment_enabled? before_action :enable_invite_for_help_continuous_onboarding_experiment + before_action :enable_video_tutorials_continuous_onboarding_experiment feature_category :users @@ -24,4 +25,8 @@ class Projects::LearnGitlabController < Projects::ApplicationController e.publish_to_database end end + + def enable_video_tutorials_continuous_onboarding_experiment + experiment(:video_tutorials_continuous_onboarding, namespace: project&.namespace).publish + end end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 60d7920f83e..03bb132fe47 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -37,17 +37,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:core_security_mr_widget_counts, project) push_frontend_feature_flag(:paginated_notes, project, default_enabled: :yaml) push_frontend_feature_flag(:confidential_notes, project, default_enabled: :yaml) - push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml) push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml) push_frontend_feature_flag(:refactor_mr_widgets_extensions, project, default_enabled: :yaml) push_frontend_feature_flag(:rebase_without_ci_ui, project, default_enabled: :yaml) - push_frontend_feature_flag(:markdown_continue_lists, project, default_enabled: :yaml) push_frontend_feature_flag(:secure_vulnerability_training, project, default_enabled: :yaml) push_frontend_feature_flag(:issue_assignees_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(:usage_data_diff_searches, project, default_enabled: :yaml) + push_frontend_feature_flag(:realtime_labels, project, default_enabled: :yaml) end before_action do @@ -85,7 +80,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo :destroy, :rebase, :discussions, - :pipelines + :pipelines, + :test_reports + ] + urgency :low, [ + :codequality_mr_diff_reports, + :codequality_reports ] def index @@ -130,9 +130,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo set_pipeline_variables - ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do - @number_of_pipelines = @pipelines.size - end + @number_of_pipelines = @pipelines.size render end @@ -196,17 +194,15 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo Gitlab::PollingInterval.set_header(response, interval: 10_000) - ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do - render json: { - pipelines: PipelineSerializer - .new(project: @project, current_user: @current_user) - .with_pagination(request, response) - .represent(@pipelines), - count: { - all: @pipelines.count - } + render json: { + pipelines: PipelineSerializer + .new(project: @project, current_user: @current_user) + .with_pagination(request, response) + .represent(@pipelines), + count: { + all: @pipelines.count } - end + } end def sast_reports diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 5dc9718d7a4..b896e2543ff 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -26,6 +26,7 @@ class Projects::MilestonesController < Projects::ApplicationController respond_to do |format| format.html do + @milestone_states = Milestone.states_count(@project) # We need to show group milestones in the JSON response # so that people can filter by and assign group milestones, # but we don't need to show them on the project milestones page itself. diff --git a/app/controllers/projects/packages/infrastructure_registry_controller.rb b/app/controllers/projects/packages/infrastructure_registry_controller.rb index 2fe353b7acb..99d75afc63a 100644 --- a/app/controllers/projects/packages/infrastructure_registry_controller.rb +++ b/app/controllers/projects/packages/infrastructure_registry_controller.rb @@ -9,7 +9,6 @@ module Projects def show @package = project.packages.find(params[:id]) - @package_files = @package.installable_package_files.recent end end end diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index 271c31b6429..ac94cc001dd 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -10,10 +10,6 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play] before_action :authorize_admin_pipeline_schedule!, only: [:destroy] - before_action do - push_frontend_feature_flag(:pipeline_schedules_with_tags, @project, default_enabled: :yaml) - end - feature_category :continuous_integration # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb index 602fc02686a..4daf700a8bd 100644 --- a/app/controllers/projects/pipelines/tests_controller.rb +++ b/app/controllers/projects/pipelines/tests_controller.rb @@ -3,6 +3,8 @@ module Projects module Pipelines class TestsController < Projects::Pipelines::ApplicationController + urgency :low, [:show, :summary] + before_action :authorize_read_build! before_action :builds, only: [:show] @@ -21,9 +23,13 @@ module Projects def show respond_to do |format| format.json do - render json: TestSuiteSerializer - .new(project: project, current_user: @current_user) - .represent(test_suite, details: true) + if Feature.enabled?(:ci_test_report_artifacts_expired, project, default_enabled: :yaml) && pipeline.has_expired_test_reports? + render json: { errors: 'Test report artifacts have expired' }, status: :not_found + else + render json: TestSuiteSerializer + .new(project: project, current_user: @current_user) + .represent(test_suite, details: true) + end end end end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 8279bb20769..02f041637ba 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -5,7 +5,7 @@ class Projects::PipelinesController < Projects::ApplicationController include RedisTracking urgency :default, [:status] - urgency :low, [:index, :new, :builds, :show, :failures, :create, :stage, :retry, :dag, :cancel] + urgency :low, [:index, :new, :builds, :show, :failures, :create, :stage, :retry, :dag, :cancel, :test_report] before_action :disable_query_limiting, only: [:create, :retry] before_action :pipeline, except: [:index, :new, :create, :charts, :config_variables] @@ -17,6 +17,10 @@ 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(:pipeline_tabs_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? } @@ -264,7 +268,7 @@ class Projects::PipelinesController < Projects::ApplicationController project .all_pipelines .includes(builds: :tags, user: :status) - .find_by!(id: params[:id]) + .find(params[:id]) .present(current_user: current_user) end end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 0279a65f262..49618c89672 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -8,7 +8,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController # Authorize before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access] - feature_category :authentication_and_authorization + feature_category :projects def index @sort = params[:sort].presence || sort_value_name diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index b070f9419fc..72af3280a39 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -43,12 +43,7 @@ class Projects::RefsController < Projects::ApplicationController end def logs_tree - tree_summary = ::Gitlab::TreeSummary.new( - @commit, @project, current_user, - path: @path, offset: permitted_params[:offset], limit: 25) - respond_to do |format| - format.html { render_404 } format.json do logs, next_offset = tree_summary.fetch_logs @@ -61,6 +56,13 @@ class Projects::RefsController < Projects::ApplicationController private + def tree_summary + ::Gitlab::TreeSummary.new( + @commit, @project, current_user, + path: @path, offset: permitted_params[:offset], limit: 25 + ) + end + def validate_ref_id return not_found if permitted_params[:id].present? && permitted_params[:id] !~ Gitlab::PathRegex.git_reference_regex end diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 1a2baf96020..19413d97d9d 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -8,9 +8,6 @@ class Projects::ReleasesController < Projects::ApplicationController before_action :authorize_update_release!, only: %i[edit update] before_action :authorize_create_release!, only: :new before_action :validate_suffix_path, :fetch_latest_tag, only: :latest_permalink - before_action only: :index do - push_frontend_feature_flag(:releases_index_apollo_client, project, default_enabled: :yaml) - end feature_category :release_orchestration diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb index 7b799cc0aa6..cdb02047215 100644 --- a/app/controllers/projects/security/configuration_controller.rb +++ b/app/controllers/projects/security/configuration_controller.rb @@ -6,6 +6,7 @@ module Projects include SecurityAndCompliancePermissions feature_category :static_application_security_testing, [:show] + urgency :low, [:show] def show render_403 unless can?(current_user, :read_security_configuration, project) diff --git a/app/controllers/projects/serverless/functions_controller.rb b/app/controllers/projects/serverless/functions_controller.rb index b6f77a6d515..7352edaaab2 100644 --- a/app/controllers/projects/serverless/functions_controller.rb +++ b/app/controllers/projects/serverless/functions_controller.rb @@ -6,7 +6,7 @@ module Projects before_action :ensure_feature_enabled! before_action :authorize_read_cluster! - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def index respond_to do |format| diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 105f8efde7b..1321111faaf 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -13,10 +13,6 @@ class Projects::ServicesController < Projects::ApplicationController before_action :set_deprecation_notice_for_prometheus_integration, only: [:edit, :update] before_action :redirect_deprecated_prometheus_integration, only: [:update] - before_action do - push_frontend_feature_flag(:integration_form_sections, project, default_enabled: :yaml) - end - respond_to :html layout "project_settings" diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 97f9c5814e2..c861b24d9ec 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -14,9 +14,7 @@ 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 + urgency :low, [:index] def index @snippet_counts = ::Snippets::CountService diff --git a/app/controllers/projects/static_site_editor_controller.rb b/app/controllers/projects/static_site_editor_controller.rb index 0d9a6f568a1..fed6307514e 100644 --- a/app/controllers/projects/static_site_editor_controller.rb +++ b/app/controllers/projects/static_site_editor_controller.rb @@ -3,6 +3,7 @@ class Projects::StaticSiteEditorController < Projects::ApplicationController include ExtractsPath include CreatesCommit + include BlobHelper layout 'fullscreen' @@ -24,28 +25,7 @@ class Projects::StaticSiteEditorController < Projects::ApplicationController end def show - service_response = ::StaticSiteEditor::ConfigService.new( - container: project, - current_user: current_user, - params: { - ref: @ref, - path: @path, - return_url: params[:return_url] - } - ).execute - - if service_response.success? - Gitlab::UsageDataCounters::StaticSiteEditorCounter.increment_views_count - - @data = serialize_necessary_payload_values_to_json(service_response.payload) - else - # TODO: For now, if the service returns any error, the user is redirected - # to the root project page with the error message displayed as an alert. - # See https://gitlab.com/gitlab-org/gitlab/-/issues/213285#note_414808004 - # for discussion of plans to handle this via a page owned by the Static Site Editor. - flash[:alert] = service_response.message - redirect_to project_path(project) - end + redirect_to ide_edit_path(project, @ref, @path) end private diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index e447fc3f3fe..a70795f2065 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -18,7 +18,6 @@ class Projects::TreeController < Projects::ApplicationController before_action do push_frontend_feature_flag(:lazy_load_commits, @project, default_enabled: :yaml) - push_frontend_feature_flag(:new_dir_modal, @project, default_enabled: :yaml) push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml) push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml) push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks) diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb index ed5bd73d6d1..e6e91231ba2 100644 --- a/app/controllers/projects/uploads_controller.rb +++ b/app/controllers/projects/uploads_controller.rb @@ -11,7 +11,7 @@ class Projects::UploadsController < Projects::ApplicationController before_action :authorize_upload_file!, only: [:create, :authorize] before_action :verify_workhorse_api!, only: [:authorize] - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned private diff --git a/app/controllers/projects/usage_quotas_controller.rb b/app/controllers/projects/usage_quotas_controller.rb index 680874ffee4..f45ee265432 100644 --- a/app/controllers/projects/usage_quotas_controller.rb +++ b/app/controllers/projects/usage_quotas_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Projects::UsageQuotasController < Projects::ApplicationController - before_action :authorize_admin_project! + before_action :authorize_read_usage_quotas! layout "project_settings" diff --git a/app/controllers/projects/web_ide_schemas_controller.rb b/app/controllers/projects/web_ide_schemas_controller.rb index 84a191815f4..cdc416de6c9 100644 --- a/app/controllers/projects/web_ide_schemas_controller.rb +++ b/app/controllers/projects/web_ide_schemas_controller.rb @@ -5,6 +5,8 @@ class Projects::WebIdeSchemasController < Projects::ApplicationController feature_category :web_ide + urgency :low + def show return respond_422 unless branch_sha diff --git a/app/controllers/projects/web_ide_terminals_controller.rb b/app/controllers/projects/web_ide_terminals_controller.rb index 1d179765ad9..350b091edfa 100644 --- a/app/controllers/projects/web_ide_terminals_controller.rb +++ b/app/controllers/projects/web_ide_terminals_controller.rb @@ -57,11 +57,13 @@ class Projects::WebIdeTerminalsController < Projects::ApplicationController end def retry - return respond_422 unless build.retryable? + response = Ci::RetryJobService.new(build.project, current_user).execute(build) - new_build = Ci::Build.retry(build, current_user) - - render_terminal(new_build) + if response.success? + render_terminal(response[:job]) + else + respond_422 + end end private diff --git a/app/controllers/projects/work_items_controller.rb b/app/controllers/projects/work_items_controller.rb index 1bd2762f277..d39664e1deb 100644 --- a/app/controllers/projects/work_items_controller.rb +++ b/app/controllers/projects/work_items_controller.rb @@ -2,12 +2,12 @@ class Projects::WorkItemsController < Projects::ApplicationController before_action do - push_frontend_feature_flag(:work_items, project, default_enabled: :yaml) + push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?) end - feature_category :not_owned + feature_category :team_planning def index - render_404 unless Feature.enabled?(:work_items, project, default_enabled: :yaml) + render_404 unless project&.work_items_feature_flag_enabled? end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 507a8b66942..6cdfdfa9e2f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -39,9 +39,8 @@ class ProjectsController < Projects::ApplicationController push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml) push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml) push_frontend_feature_flag(:increase_page_size_exponentially, @project, default_enabled: :yaml) - push_frontend_feature_flag(:new_dir_modal, @project, default_enabled: :yaml) push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks) - push_frontend_feature_flag(:work_items, @project, default_enabled: :yaml) + push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?) end layout :determine_layout @@ -57,7 +56,8 @@ class ProjectsController < Projects::ApplicationController feature_category :code_review, [:unfoldered_environment_names] feature_category :portfolio_management, [:planning_hierarchy] - urgency :low, [:refs] + # TODO: Set high urgency for #show https://gitlab.com/gitlab-org/gitlab/-/issues/334444 + urgency :low, [:refs, :show] urgency :high, [:unfoldered_environment_names] def index @@ -69,6 +69,13 @@ class ProjectsController < Projects::ApplicationController @namespace = Namespace.find_by(id: params[:namespace_id]) if params[:namespace_id] return access_denied! if @namespace && !can?(current_user, :create_projects, @namespace) + @current_user_group = + if current_user.manageable_groups(include_groups_with_developer_maintainer_access: true).count == 1 + current_user.manageable_groups(include_groups_with_developer_maintainer_access: true).first + else + nil + end + @project = Project.new(namespace_id: @namespace&.id) end # rubocop: enable CodeReuse/ActiveRecord @@ -82,13 +89,6 @@ class ProjectsController < Projects::ApplicationController @project = ::Projects::CreateService.new(current_user, project_params(attributes: project_params_create_attributes)).execute if @project.saved? - experiment(:new_project_sast_enabled, user: current_user).track(:created, - property: active_new_project_tab, - checked: Gitlab::Utils.to_boolean(project_params[:initialize_with_sast]), - project: @project, - namespace: @project.namespace - ) - redirect_to( project_path(@project, custom_import_params), notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name } @@ -305,12 +305,7 @@ class ProjectsController < Projects::ApplicationController end if find_tags && @repository.tag_count.nonzero? - tags = begin - TagsFinder.new(@repository, refs_params).execute - rescue Gitlab::Git::CommandError - [] - end - + tags = TagsFinder.new(@repository, refs_params).execute options['Tags'] = tags.take(100).map(&:name) end @@ -321,6 +316,8 @@ class ProjectsController < Projects::ApplicationController end render json: options.to_json + rescue Gitlab::Git::CommandError + render json: { error: _('Unable to load refs') }, status: :service_unavailable end # rubocop: enable CodeReuse/ActiveRecord @@ -545,9 +542,9 @@ class ProjectsController < Projects::ApplicationController def check_export_rate_limit! prefixed_action = "project_#{params[:action]}".to_sym - project_scope = params[:action] == 'download_export' ? @project : nil + group_scope = params[:action] == 'download_export' ? @project.namespace : nil - check_rate_limit!(prefixed_action, scope: [current_user, project_scope].compact) + check_rate_limit!(prefixed_action, scope: [current_user, group_scope].compact) end def render_edit diff --git a/app/controllers/sandbox_controller.rb b/app/controllers/sandbox_controller.rb index a87c2b38e60..a48b2b8a314 100644 --- a/app/controllers/sandbox_controller.rb +++ b/app/controllers/sandbox_controller.rb @@ -3,7 +3,7 @@ class SandboxController < ApplicationController # rubocop:disable Gitlab/NamespacedClass skip_before_action :authenticate_user! - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def mermaid render layout: false diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 817da658f14..b4e2da0c7b3 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -169,15 +169,17 @@ class SearchController < ApplicationController search_allowed = case params[:scope] when 'blobs' - Feature.enabled?(:global_search_code_tab, current_user, type: :ops, default_enabled: true) + Feature.enabled?(:global_search_code_tab, current_user, type: :ops, default_enabled: :yaml) when 'commits' - Feature.enabled?(:global_search_commits_tab, current_user, type: :ops, default_enabled: true) + Feature.enabled?(:global_search_commits_tab, current_user, type: :ops, default_enabled: :yaml) when 'issues' - Feature.enabled?(:global_search_issues_tab, current_user, type: :ops, default_enabled: true) + Feature.enabled?(:global_search_issues_tab, current_user, type: :ops, default_enabled: :yaml) when 'merge_requests' - Feature.enabled?(:global_search_merge_requests_tab, current_user, type: :ops, default_enabled: true) + Feature.enabled?(:global_search_merge_requests_tab, current_user, type: :ops, default_enabled: :yaml) when 'wiki_blobs' - Feature.enabled?(:global_search_wiki_tab, current_user, type: :ops, default_enabled: true) + Feature.enabled?(:global_search_wiki_tab, current_user, type: :ops, default_enabled: :yaml) + when 'users' + Feature.enabled?(:global_search_users_tab, current_user, type: :ops, default_enabled: :yaml) else true end diff --git a/app/controllers/sent_notifications_controller.rb b/app/controllers/sent_notifications_controller.rb index 64d66ee86f1..ebadfd1cdfb 100644 --- a/app/controllers/sent_notifications_controller.rb +++ b/app/controllers/sent_notifications_controller.rb @@ -3,7 +3,7 @@ class SentNotificationsController < ApplicationController skip_before_action :authenticate_user! - feature_category :users + feature_category :team_planning def unsubscribe @sent_notification = SentNotification.for(params[:id]) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index e907e291eeb..3e11e0940bf 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -126,7 +126,7 @@ class SessionsController < Devise::SessionsController flash[:alert] = _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.') flash.delete :recaptcha_error - respond_with_navigational(resource) { render :new } + redirect_to new_user_session_path end end diff --git a/app/controllers/snippets/blobs_controller.rb b/app/controllers/snippets/blobs_controller.rb index d7c4bbcf8f2..c9a78f39c89 100644 --- a/app/controllers/snippets/blobs_controller.rb +++ b/app/controllers/snippets/blobs_controller.rb @@ -2,6 +2,7 @@ class Snippets::BlobsController < Snippets::ApplicationController include Snippets::BlobsActions + urgency :low skip_before_action :authenticate_user!, only: [:raw] end diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 4df0ef78907..97bbb96eae6 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -14,7 +14,8 @@ class UploadsController < ApplicationController "appearance" => Appearance, "personal_snippet" => PersonalSnippet, "projects/topic" => Projects::Topic, - nil => PersonalSnippet + 'alert_management_metric_image' => ::AlertManagement::MetricImage, + nil => PersonalSnippet }.freeze rescue_from UnknownUploadModelError, with: :render_404 @@ -26,7 +27,7 @@ class UploadsController < ApplicationController before_action :authorize_create_access!, only: [:create, :authorize] before_action :verify_workhorse_api!, only: [:authorize] - feature_category :not_owned + feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned def self.model_classes MODEL_CLASSES @@ -56,6 +57,8 @@ class UploadsController < ApplicationController true when Projects::Topic true + when ::AlertManagement::MetricImage + can?(current_user, :read_alert_management_metric_image, model.alert) else can?(current_user, "read_#{model.class.underscore}".to_sym, model) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index dc02e4a3e87..228ef710749 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -27,7 +27,14 @@ class UsersController < ApplicationController check_rate_limit!(:username_exists, scope: request.ip) end - feature_category :users + feature_category :users, [:show, :activity, :groups, :projects, :contributed, :starred, + :followers, :following, :calendar, :calendar_activities, + :exists, :activity, :follow, :unfollow, :ssh_keys, :gpg_keys] + + feature_category :snippets, [:snippets] + + # TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914 + urgency :low, [:show] def show respond_to do |format| |