diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-19 15:57:54 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-19 15:57:54 +0300 |
commit | 419c53ec62de6e97a517abd5fdd4cbde3a942a34 (patch) | |
tree | 1f43a548b46bca8a5fb8fe0c31cef1883d49c5b6 /app/controllers | |
parent | 1da20d9135b3ad9e75e65b028bffc921aaf8deb7 (diff) |
Add latest changes from gitlab-org/gitlab@16-5-stable-eev16.5.0-rc42
Diffstat (limited to 'app/controllers')
63 files changed, 299 insertions, 498 deletions
diff --git a/app/controllers/acme_challenges_controller.rb b/app/controllers/acme_challenges_controller.rb index 4a7706db94e..a187e43b3df 100644 --- a/app/controllers/acme_challenges_controller.rb +++ b/app/controllers/acme_challenges_controller.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -# rubocop:disable Rails/ApplicationController -class AcmeChallengesController < ActionController::Base +class AcmeChallengesController < BaseActionController def show if acme_order render plain: acme_order.challenge_file_content, content_type: 'text/plain' @@ -16,4 +15,3 @@ class AcmeChallengesController < ActionController::Base @acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token]) end end -# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/admin/identities_controller.rb b/app/controllers/admin/identities_controller.rb index 15c4103a781..17b0adb868e 100644 --- a/app/controllers/admin/identities_controller.rb +++ b/app/controllers/admin/identities_controller.rb @@ -63,6 +63,6 @@ class Admin::IdentitiesController < Admin::ApplicationController end def identity_params - params.require(:identity).permit(:provider, :extern_uid) + params.require(:identity).permit(:provider, :extern_uid, :saml_provider_id) end end diff --git a/app/controllers/admin/topics_controller.rb b/app/controllers/admin/topics_controller.rb index c4de600dd1d..40cad2d26f4 100644 --- a/app/controllers/admin/topics_controller.rb +++ b/app/controllers/admin/topics_controller.rb @@ -8,10 +8,6 @@ class Admin::TopicsController < Admin::ApplicationController feature_category :groups_and_projects - before_action do - push_frontend_feature_flag(:content_editor_on_issues, current_user) - end - def index @topics = Projects::TopicsFinder.new(params: params.permit(:search)).execute.page(params[:page]).without_count end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7c69f43fa3d..f60da46826a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,7 @@ require 'gon' require 'fogbugz' -class ApplicationController < ActionController::Base +class ApplicationController < BaseActionController include Gitlab::GonHelper include Gitlab::NoCacheHeaders include GitlabRoutingHelper @@ -24,6 +24,7 @@ class ApplicationController < ActionController::Base include ::Gitlab::EndpointAttributes include FlocOptOut include CheckRateLimit + include RequestPayloadLogger extend ContentSecurityPolicyPatch before_action :limit_session_time, if: -> { !current_user } @@ -180,29 +181,6 @@ class ApplicationController < ActionController::Base @workhorse_excluded_content_types ||= %w[text/html application/json] end - def append_info_to_payload(payload) - super - - payload[:ua] = request.env["HTTP_USER_AGENT"] - payload[:remote_ip] = request.remote_ip - - payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id - payload[:metadata] = @current_context - payload[:request_urgency] = urgency&.name - payload[:target_duration_s] = urgency&.duration - logged_user = auth_user - if logged_user.present? - payload[:user_id] = logged_user.try(:id) - payload[:username] = logged_user.try(:username) - end - - payload[:queue_duration_s] = request.env[::Gitlab::Middleware::RailsQueueDuration::GITLAB_RAILS_QUEUE_DURATION_KEY] - - payload[:response_bytes] = response.body_parts.sum(&:bytesize) if Feature.enabled?(:log_response_length) - - store_cloudflare_headers!(payload, request) - end - ## # Controllers such as GitHttpController may use alternative methods # (e.g. tokens) to authenticate the user, whereas Devise sets current_user. diff --git a/app/controllers/base_action_controller.rb b/app/controllers/base_action_controller.rb new file mode 100644 index 00000000000..af2c9e98778 --- /dev/null +++ b/app/controllers/base_action_controller.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# GitLab lightweight base action controller +# +# This class should be limited to content that +# is desired/required for *all* controllers in +# GitLab. +# +# Most controllers inherit from `ApplicationController`. +# Some controllers don't want or need all of that +# logic and instead inherit from `ActionController::Base`. +# This makes it difficult to set security headers and +# handle other critical logic across *all* controllers. +# +# Between this controller and `ApplicationController` +# no controller should ever inherit directly from +# `ActionController::Base` +# +# rubocop:disable Rails/ApplicationController +# rubocop:disable Gitlab/NamespacedClass +class BaseActionController < ActionController::Base + before_action :security_headers + + private + + def security_headers + headers['Cross-Origin-Opener-Policy'] = 'same-origin' if ::Feature.enabled?(:coop_header) + end +end +# rubocop:enable Gitlab/NamespacedClass +# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb index 7328b793b09..b61a8c5ff12 100644 --- a/app/controllers/chaos_controller.rb +++ b/app/controllers/chaos_controller.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -# rubocop:disable Rails/ApplicationController -class ChaosController < ActionController::Base +class ChaosController < BaseActionController before_action :validate_chaos_secret, unless: :development_or_test? def leakmem @@ -95,4 +94,3 @@ class ChaosController < ActionController::Base Rails.env.development? || Rails.env.test? end end -# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/concerns/access_tokens_actions.rb b/app/controllers/concerns/access_tokens_actions.rb index de53fd4d835..84cbdda1581 100644 --- a/app/controllers/concerns/access_tokens_actions.rb +++ b/app/controllers/concerns/access_tokens_actions.rb @@ -69,7 +69,6 @@ module AccessTokensActions resource.members.load @scopes = Gitlab::Auth.available_scopes_for(resource) - @scopes.delete(Gitlab::Auth::K8S_PROXY_SCOPE) unless Feature.enabled?(:k8s_proxy_pat, current_user) @active_access_tokens = active_access_tokens end # rubocop:enable Gitlab/ModuleWithInstanceVariables diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 896004045f4..27f1d1f5528 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -10,18 +10,18 @@ module CreatesCommit if user_access(target_project).can_push_to_branch?(branch_name_or_ref) @project_to_commit_into = target_project + @different_project = false @branch_name ||= @ref else @project_to_commit_into = current_user.fork_of(target_project) + @different_project = true @branch_name ||= @project_to_commit_into.repository.next_branch('patch') end @start_branch ||= @ref || @branch_name - start_project = @project_to_commit_into - commit_params = @commit_params.merge( - start_project: start_project, + start_project: @project_to_commit_into, start_branch: @start_branch, source_project: @project, target_project: target_project, @@ -74,7 +74,7 @@ module CreatesCommit nil else mr_message = - if different_project? + if @different_project # rubocop:disable Gitlab/ModuleWithInstanceVariables _("You can now submit a merge request to get this change into the original project.") else _("You can now submit a merge request to get this change into the original branch.") @@ -128,16 +128,12 @@ module CreatesCommit # rubocop: enable CodeReuse/ActiveRecord # rubocop:enable Gitlab/ModuleWithInstanceVariables - def different_project? - @project_to_commit_into != @project # rubocop:disable Gitlab/ModuleWithInstanceVariables - end - def create_merge_request? # Even if the field is set, if we're checking the same branch # as the target branch in the same project, # we don't want to create a merge request. params[:create_merge_request].present? && - (different_project? || @start_branch != @branch_name) # rubocop:disable Gitlab/ModuleWithInstanceVariables + (@different_project || @start_branch != @branch_name) # rubocop:disable Gitlab/ModuleWithInstanceVariables end def branch_name_or_ref diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb index 539feb3cf1c..24475909b62 100644 --- a/app/controllers/concerns/enforces_two_factor_authentication.rb +++ b/app/controllers/concerns/enforces_two_factor_authentication.rb @@ -73,7 +73,7 @@ module EnforcesTwoFactorAuthentication end def skip_two_factor? - session[:skip_two_factor] && session[:skip_two_factor] > Time.current + session[:skip_two_factor] && session[:skip_two_factor].future? end def two_factor_verifier diff --git a/app/controllers/concerns/google_analytics_csp.rb b/app/controllers/concerns/google_analytics_csp.rb deleted file mode 100644 index 1a8e405928d..00000000000 --- a/app/controllers/concerns/google_analytics_csp.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module GoogleAnalyticsCSP - extend ActiveSupport::Concern - - included do - content_security_policy do |policy| - next unless helpers.google_tag_manager_enabled? || policy.directives.present? - - default_script_src = policy.directives['script-src'] || policy.directives['default-src'] - script_src_values = Array.wrap(default_script_src) | ['*.googletagmanager.com'] - policy.script_src(*script_src_values) - - default_img_src = policy.directives['img-src'] || policy.directives['default-src'] - img_src_values = Array.wrap(default_img_src) | ['*.google-analytics.com', '*.googletagmanager.com'] - policy.img_src(*img_src_values) - - default_connect_src = policy.directives['connect-src'] || policy.directives['default-src'] - connect_src_values = - Array.wrap(default_connect_src) | ['*.google-analytics.com', '*.analytics.google.com', '*.googletagmanager.com'] - policy.connect_src(*connect_src_values) - end - end -end diff --git a/app/controllers/concerns/google_syndication_csp.rb b/app/controllers/concerns/google_syndication_csp.rb deleted file mode 100644 index c55debe448b..00000000000 --- a/app/controllers/concerns/google_syndication_csp.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module GoogleSyndicationCSP - extend ActiveSupport::Concern - - ALLOWED_SRC = ['*.google.com/pagead/landing', 'pagead2.googlesyndication.com/pagead/landing'].freeze - - included do - content_security_policy do |policy| - next unless helpers.google_tag_manager_enabled? || policy.directives.present? - - connect_src_values = Array.wrap( - policy.directives['connect-src'] || policy.directives['default-src'] - ) - - connect_src_values.concat(ALLOWED_SRC) if helpers.google_tag_manager_enabled? - - policy.connect_src(*connect_src_values.uniq) - end - end -end diff --git a/app/controllers/concerns/import/github_oauth.rb b/app/controllers/concerns/import/github_oauth.rb index dc03a132768..ae5a0401155 100644 --- a/app/controllers/concerns/import/github_oauth.rb +++ b/app/controllers/concerns/import/github_oauth.rb @@ -54,23 +54,15 @@ module Import state = SecureRandom.base64(64) session[auth_state_key] = state session[:auth_on_failure_path] = "#{new_project_path}#import_project" - if Feature.enabled?(:remove_legacy_github_client) - oauth_client.auth_code.authorize_url( - redirect_uri: callback_import_url, - scope: 'repo, user, user:email', - state: state - ) - else - client.authorize_url(callback_import_url, state) - end + oauth_client.auth_code.authorize_url( + redirect_uri: callback_import_url, + scope: 'repo, user, user:email', + state: state + ) end def get_token(code) - if Feature.enabled?(:remove_legacy_github_client) - oauth_client.auth_code.get_token(code).token - else - client.get_token(code) - end + oauth_client.auth_code.get_token(code).token end def missing_oauth_config diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 0c15c4d0d3f..b4f5589a059 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -5,7 +5,6 @@ module MembershipActions extend ActiveSupport::Concern def update - update_params = params.require(root_params_key).permit(:access_level, :expires_at) member = members_and_requesters.find(params[:id]) result = Members::UpdateService .new(current_user, update_params) @@ -148,6 +147,10 @@ module MembershipActions membershipable.requesters end + def update_params + params.require(root_params_key).permit(:access_level, :expires_at) + end + def requested_relations(inherited_permissions = :with_inherited_permissions) case params[inherited_permissions].presence when 'exclude' @@ -156,7 +159,8 @@ module MembershipActions [:inherited] else if Feature.enabled?(:webui_members_inherited_users, current_user) - [:inherited, :direct, :shared_from_groups, (:invited_groups if params[:project_id])].compact + project_relations = [:invited_groups, :shared_into_ancestors] + [:inherited, :direct, :shared_from_groups, *(project_relations if params[:project_id])] else [:inherited, :direct] end diff --git a/app/controllers/concerns/onboarding/redirectable.rb b/app/controllers/concerns/onboarding/redirectable.rb new file mode 100644 index 00000000000..7e669db9199 --- /dev/null +++ b/app/controllers/concerns/onboarding/redirectable.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Onboarding + module Redirectable + extend ActiveSupport::Concern + + private + + def after_sign_up_path + if onboarding_status.single_invite? + flash[:notice] = helpers.invite_accepted_notice(onboarding_status.last_invited_member) + onboarding_status.last_invited_member_source.activity_path + else + # Invites will come here if there is more than 1. + path_for_signed_in_user + end + end + + def path_for_signed_in_user + stored_location_for(:user) || last_member_activity_path + end + + def last_member_activity_path + return dashboard_projects_path unless onboarding_status.last_invited_member_source.present? + + onboarding_status.last_invited_member_source.activity_path + end + end +end + +Onboarding::Redirectable.prepend_mod diff --git a/app/controllers/concerns/onboarding/status.rb b/app/controllers/concerns/onboarding/status.rb index 8a99f5a6c12..ea4dc550149 100644 --- a/app/controllers/concerns/onboarding/status.rb +++ b/app/controllers/concerns/onboarding/status.rb @@ -2,21 +2,12 @@ module Onboarding class Status - def self.tracking_label - { free: 'free_registration' } - end - def initialize(params, session, user) @params = params @session = session @user = user end - # overridden in EE - def continue_full_onboarding? - false - end - def single_invite? # If there are more than one member it will mean we have been invited to multiple projects/groups and # are not able to distinguish which one we should putting the user in after registration diff --git a/app/controllers/concerns/planning_hierarchy.rb b/app/controllers/concerns/planning_hierarchy.rb index 5df838bc183..51999a87e26 100644 --- a/app/controllers/concerns/planning_hierarchy.rb +++ b/app/controllers/concerns/planning_hierarchy.rb @@ -7,7 +7,7 @@ module PlanningHierarchy def planning_hierarchy return access_denied! unless can?(current_user, :read_planning_hierarchy, @project) - render 'shared/planning_hierarchy' + route_not_found end # rubocop:enable Gitlab/ModuleWithInstanceVariables end diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb index e148f5d063a..d4610267897 100644 --- a/app/controllers/concerns/product_analytics_tracking.rb +++ b/app/controllers/concerns/product_analytics_tracking.rb @@ -14,7 +14,7 @@ module ProductAnalyticsTracking end def track_internal_event(*controller_actions, name:, conditions: nil) - custom_conditions = [:trackable_html_request?, *conditions] + custom_conditions = [:trackable_html_request?, :authenticated?, *conditions] after_action only: controller_actions, if: custom_conditions do Gitlab::InternalEvents.track_event( @@ -70,4 +70,8 @@ module ProductAnalyticsTracking cookies[:visitor_id] = { value: uuid, expires: 24.months } uuid end + + def authenticated? + current_user.present? + end end diff --git a/app/controllers/concerns/renders_projects_list.rb b/app/controllers/concerns/renders_projects_list.rb index 2d37bc3f9a5..56383658696 100644 --- a/app/controllers/concerns/renders_projects_list.rb +++ b/app/controllers/concerns/renders_projects_list.rb @@ -5,7 +5,7 @@ module RendersProjectsList def prepare_projects_for_rendering(projects) preload_max_member_access_for_collection(Project, projects) - current_user.preloaded_member_roles_for_projects(projects) if current_user + preload_member_roles(projects) if current_user # Call the count methods on every project, so the BatchLoader would load them all at # once when the entities are rendered @@ -15,4 +15,10 @@ module RendersProjectsList projects end + + def preload_member_roles(projects) + # overridden in EE + end end + +RendersProjectsList.prepend_mod diff --git a/app/controllers/concerns/request_payload_logger.rb b/app/controllers/concerns/request_payload_logger.rb new file mode 100644 index 00000000000..b13164e5c57 --- /dev/null +++ b/app/controllers/concerns/request_payload_logger.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module RequestPayloadLogger + extend ActiveSupport::Concern + include Gitlab::Logging::CloudflareHelper + + def append_info_to_payload(payload) + super + + payload[:ua] = request.env["HTTP_USER_AGENT"] + payload[:remote_ip] = request.remote_ip + payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id + + payload[:metadata] = Gitlab::ApplicationContext.current + + if defined?(urgency) + payload[:request_urgency] = urgency&.name + payload[:target_duration_s] = urgency&.duration + end + + logged_user = auth_user + if logged_user.present? + payload[:user_id] = logged_user.try(:id) + payload[:username] = logged_user.try(:username) + end + + payload[:queue_duration_s] = request.env[::Gitlab::Middleware::RailsQueueDuration::GITLAB_RAILS_QUEUE_DURATION_KEY] + payload[:response_bytes] = response.body_parts.sum(&:bytesize) if Feature.enabled?(:log_response_length) + + store_cloudflare_headers!(payload, request) + end +end diff --git a/app/controllers/concerns/snippets/blobs_actions.rb b/app/controllers/concerns/snippets/blobs_actions.rb index 2a0491b4df8..955debfc209 100644 --- a/app/controllers/concerns/snippets/blobs_actions.rb +++ b/app/controllers/concerns/snippets/blobs_actions.rb @@ -4,7 +4,6 @@ module Snippets::BlobsActions extend ActiveSupport::Concern include Gitlab::Utils::StrongMemoize - include ExtractsRef include Snippets::SendBlob included do @@ -19,20 +18,14 @@ module Snippets::BlobsActions private - def repository_container - snippet - end - - # rubocop:disable Gitlab/ModuleWithInstanceVariables def blob - assign_ref_vars - - return unless @commit + ref_extractor = ExtractsRef::RefExtractor.new(snippet, params.permit(:id, :ref, :path, :ref_type)) + ref_extractor.extract! + return unless ref_extractor.commit - @repo.blob_at(@commit.id, @path) + snippet.repository.blob_at(ref_extractor.commit.id, ref_extractor.path) end strong_memoize_attr :blob - # rubocop:enable Gitlab/ModuleWithInstanceVariables def ensure_blob render_404 unless blob diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index 5ceabaa734a..db1cf31d349 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -4,8 +4,6 @@ class ConfirmationsController < Devise::ConfirmationsController include AcceptsPendingInvitations include GitlabRecaptcha include OneTrustCSP - include GoogleAnalyticsCSP - include GoogleSyndicationCSP prepend_before_action :check_recaptcha, only: :create before_action :load_recaptcha, only: :new diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 29bc48f93e9..1941920325f 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -255,6 +255,12 @@ class GraphqlController < ApplicationController end def authorize_access_api! + if current_user.nil? && + request_authenticator.authentication_token_present? && + Feature.enabled?(:invalid_graphql_auth_401) + render_error('Invalid token', status: :unauthorized) + end + return if can?(current_user, :access_api) render_error('API not accessible for user', status: :forbidden) @@ -301,6 +307,8 @@ class GraphqlController < ApplicationController end def introspection_query_can_use_cache? + return false if Gitlab.dev_or_test_env? + CACHED_INTROSPECTION_QUERY_STRING == graphql_query_object.query_string.squish end diff --git a/app/controllers/groups/autocomplete_sources_controller.rb b/app/controllers/groups/autocomplete_sources_controller.rb index 414461d9e93..86bf65f4723 100644 --- a/app/controllers/groups/autocomplete_sources_controller.rb +++ b/app/controllers/groups/autocomplete_sources_controller.rb @@ -8,6 +8,11 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController urgency :low, [:issues, :labels, :milestones, :commands, :merge_requests, :members] def members + if Feature.enabled?(:cache_autocomplete_sources_members, current_user) + # Cache the response on the frontend + expires_in 3.minutes + end + render json: ::Groups::ParticipantsService.new(@group, current_user).execute(target) end diff --git a/app/controllers/groups/custom_emoji_controller.rb b/app/controllers/groups/custom_emoji_controller.rb new file mode 100644 index 00000000000..f202c9febba --- /dev/null +++ b/app/controllers/groups/custom_emoji_controller.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Groups + class CustomEmojiController < Groups::ApplicationController + feature_category :code_review_workflow + urgency :low + + before_action do + render_404 unless Feature.enabled?(:custom_emoji) + end + end +end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index cbed75019f2..5f6b55ea928 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -9,10 +9,6 @@ class Groups::MilestonesController < Groups::ApplicationController feature_category :team_planning urgency :low - before_action do - push_frontend_feature_flag(:content_editor_on_issues, group) - end - def index respond_to do |format| format.html do diff --git a/app/controllers/groups/observability_controller.rb b/app/controllers/groups/observability_controller.rb deleted file mode 100644 index 525407f5849..00000000000 --- a/app/controllers/groups/observability_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -module Groups - class ObservabilityController < Groups::ApplicationController - include ::Observability::ContentSecurityPolicy - - feature_category :tracing - - before_action :check_observability_allowed - - def dashboards - render_observability - end - - def manage - render_observability - end - - def explore - render_observability - end - - def datasources - render_observability - end - - private - - def render_observability - render 'observability', layout: 'group', locals: { base_layout: 'layouts/fullscreen' } - end - - def check_observability_allowed - render_404 unless Gitlab::Observability.allowed_for_action?(current_user, group, params[:action]) - end - end -end diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 1381999ab4c..2b2db2f950c 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -# rubocop:disable Rails/ApplicationController -class HealthController < ActionController::Base +class HealthController < BaseActionController protect_from_forgery with: :exception, prepend: true include RequiresAllowlistedMonitoringClient @@ -40,4 +39,3 @@ class HealthController < ActionController::Base render json: result.json, status: result.http_status end end -# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb index d7d7ad84bc8..a8ec738caf4 100644 --- a/app/controllers/import/bulk_imports_controller.rb +++ b/app/controllers/import/bulk_imports_controller.rb @@ -152,7 +152,7 @@ class Import::BulkImportsController < ApplicationController allow_local_network: allow_local_requests?, schemes: %w[http https] ) - rescue Gitlab::UrlBlocker::BlockedUrlError => e + rescue Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError => e clear_session_data redirect_to new_group_path(anchor: 'import-group-pane'), alert: _('Specified URL cannot be used: "%{reason}"') % { reason: e.message } diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index 9ee8e59053f..34fdf513313 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -128,7 +128,7 @@ class Import::FogbugzController < Import::BaseController allow_local_network: allow_local_requests?, schemes: %w[http https] ) - rescue Gitlab::UrlBlocker::BlockedUrlError => e + rescue Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError => e redirect_to new_import_fogbugz_url, alert: _('Specified URL cannot be used: "%{reason}"') % { reason: e.message } end diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb index 2778b97419a..4e95c6527c3 100644 --- a/app/controllers/import/gitea_controller.rb +++ b/app/controllers/import/gitea_controller.rb @@ -85,7 +85,6 @@ class Import::GiteaController < Import::GithubController @client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], **client_options) end - override :client_options def client_options verified_url, provider_hostname = verify_blocked_uri @@ -99,7 +98,7 @@ class Import::GiteaController < Import::GithubController allow_local_network: allow_local_requests?, schemes: %w[http https] ) - rescue Gitlab::UrlBlocker::BlockedUrlError => e + rescue Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError => e session[access_token_key] = nil redirect_to new_import_url, alert: _('Specified URL cannot be used: "%{reason}"') % { reason: e.message } diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 28732d58484..2b72ceceb5a 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -192,7 +192,7 @@ class Import::GithubController < Import::BaseController def client_proxy @client_proxy ||= Gitlab::GithubImport::Clients::Proxy.new( - session[access_token_key], client_options + session[access_token_key] ) end @@ -265,10 +265,6 @@ class Import::GithubController < Import::BaseController end # rubocop: enable CodeReuse/ActiveRecord - def client_options - { wait_for_rate_limit_reset: false } - end - def rate_limit_threshold_exceeded head :too_many_requests end diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index d299613f498..84ccfbc603a 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -87,13 +87,22 @@ class JwtController < ApplicationController # We have to parse scope here, because Docker Client does not send an array of scopes, # but rather a flat list and we loose second scope when being processed by Rails: - # scope=scopeA&scope=scopeB + # scope=scopeA&scope=scopeB. + # + # Additionally, according to RFC6749 (https://datatracker.ietf.org/doc/html/rfc6749#section-3.3), some clients may use + # a scope parameter expressed as a list of space-delimited elements. Therefore, we must account for this and split the + # scope parameter value(s) appropriately. # # This method makes to always return an array of scopes def scopes_param return unless params[:scope].present? - Array(Rack::Utils.parse_query(request.query_string)['scope']) + scopes = Array(Rack::Utils.parse_query(request.query_string)['scope']) + if Feature.enabled?(:jwt_auth_space_delimited_scopes, Feature.current_request) + scopes.flat_map(&:split) + else + scopes + end end def auth_user diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb index 9f41c092fa0..61851fd1c60 100644 --- a/app/controllers/metrics_controller.rb +++ b/app/controllers/metrics_controller.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -# rubocop:disable Rails/ApplicationController -class MetricsController < ActionController::Base +class MetricsController < BaseActionController include RequiresAllowlistedMonitoringClient protect_from_forgery with: :exception, prepend: true @@ -36,4 +35,3 @@ class MetricsController < ActionController::Base ) end end -# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/oauth/tokens_controller.rb b/app/controllers/oauth/tokens_controller.rb index 012fa318eea..7889e89fc5c 100644 --- a/app/controllers/oauth/tokens_controller.rb +++ b/app/controllers/oauth/tokens_controller.rb @@ -2,4 +2,7 @@ class Oauth::TokensController < Doorkeeper::TokensController include EnforcesTwoFactorAuthentication + include RequestPayloadLogger + + alias_method :auth_user, :current_user end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 72b3516ae3f..a97516fddff 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -7,6 +7,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController include InitializesCurrentUserMode include KnownSignIn include AcceptsPendingInvitations + include Onboarding::Redirectable after_action :verify_known_sign_in @@ -169,38 +170,38 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def sign_in_user_flow(auth_user_class) auth_user = build_auth_user(auth_user_class) new_user = auth_user.new? - user = auth_user.find_and_update! + @user = auth_user.find_and_update! if auth_user.valid_sign_in? # In this case the `#current_user` would not be set. So we can't fetch it # from that in `#context_user`. Pushing it manually here makes the information # available in the logs for this request. - Gitlab::ApplicationContext.push(user: user) - track_event(user, oauth['provider'], 'succeeded') - Gitlab::Tracking.event(self.class.name, "#{oauth['provider']}_sso", user: user) if new_user + Gitlab::ApplicationContext.push(user: @user) + track_event(@user, oauth['provider'], 'succeeded') + Gitlab::Tracking.event(self.class.name, "#{oauth['provider']}_sso", user: @user) if new_user - set_remember_me(user) + set_remember_me(@user) - if user.two_factor_enabled? && !auth_user.bypass_two_factor? - prompt_for_two_factor(user) + if @user.two_factor_enabled? && !auth_user.bypass_two_factor? + prompt_for_two_factor(@user) store_idp_two_factor_status(false) else - if user.deactivated? - user.activate + if @user.deactivated? + @user.activate flash[:notice] = _('Welcome back! Your account had been deactivated due to inactivity but is now reactivated.') end # session variable for storing bypass two-factor request from IDP store_idp_two_factor_status(true) - accept_pending_invitations(user: user) if new_user - persist_accepted_terms_if_required(user) if new_user + accept_pending_invitations(user: @user) if new_user + persist_accepted_terms_if_required(@user) if new_user - perform_registration_tasks(user, oauth['provider']) if new_user - sign_in_and_redirect_or_verify_identity(user, auth_user, new_user) + perform_registration_tasks(@user, oauth['provider']) if new_user + sign_in_and_redirect_or_verify_identity(@user, auth_user, new_user) end else - fail_login(user) + fail_login(@user) end rescue Gitlab::Auth::OAuth::User::SigninDisabledForProviderError handle_disabled_provider @@ -323,9 +324,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController store_location_for(:user, after_sign_up_path) end - def after_sign_up_path - users_sign_up_welcome_path + def onboarding_status + Onboarding::Status.new(params.to_unsafe_h.deep_symbolize_keys, session, @user) end + strong_memoize_attr :onboarding_status # overridden in EE def sign_in_and_redirect_or_verify_identity(user, _, _) diff --git a/app/controllers/organizations/application_controller.rb b/app/controllers/organizations/application_controller.rb index d3c3e878bdf..8a99b6804ae 100644 --- a/app/controllers/organizations/application_controller.rb +++ b/app/controllers/organizations/application_controller.rb @@ -27,5 +27,9 @@ module Organizations def authorize_read_organization! access_denied! unless can?(current_user, :read_organization, organization) end + + def authorize_admin_organization! + access_denied! unless can?(current_user, :admin_organization, organization) + end end end diff --git a/app/controllers/organizations/settings_controller.rb b/app/controllers/organizations/settings_controller.rb new file mode 100644 index 00000000000..a81cbf57a42 --- /dev/null +++ b/app/controllers/organizations/settings_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Organizations + class SettingsController < ApplicationController + feature_category :cell + + before_action :authorize_admin_organization! + + def general; end + end +end diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 57e5ca4d55a..abb6e46394e 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -45,11 +45,17 @@ class Profiles::NotificationsController < Profiles::ApplicationController projects = project_notifications.map(&:source) ActiveRecord::Associations::Preloader.new( records: projects, - associations: { namespace: [:route, :owner], group: [], creator: [], project_setting: [] } + associations: project_associations ).call Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute project_notifications.select { |notification| current_user.can?(:read_project, notification.source) } end # rubocop: enable CodeReuse/ActiveRecord + + def project_associations + { namespace: [:route, :owner], group: [], creator: [], project_setting: [] } + end end + +Profiles::NotificationsController.prepend_mod diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 0e4d9f3c154..4b6e2f768fa 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -61,7 +61,6 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def set_index_vars @scopes = Gitlab::Auth.available_scopes_for(current_user) - @scopes.delete(Gitlab::Auth::K8S_PROXY_SCOPE) unless Feature.enabled?(:k8s_proxy_pat, current_user) @active_access_tokens = active_access_tokens end diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index e83b72b71a8..f1646027e8e 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -140,7 +140,10 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController def build_qr_code uri = current_user.otp_provisioning_uri(account_string, issuer: issuer_host) - RQRCode.render_qrcode(uri, :svg, level: :m, unit: 3) + RQRCode::QRCode.new(uri, level: :m).as_svg( + shape_rendering: "crispEdges", + module_size: 3 + ) end def account_string diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 62233c8c3c9..30c6f4d865a 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -85,7 +85,7 @@ class Projects::ApplicationController < ApplicationController end def require_pages_enabled! - not_found unless @project.pages_available? + not_found unless ::Gitlab::Pages.enabled? end def check_issues_available! diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index 480e3408023..60c8fe97e81 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -13,6 +13,11 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController urgency :low, [:issues, :labels, :milestones, :commands, :contacts] def members + if Feature.enabled?(:cache_autocomplete_sources_members, current_user) + # Cache the response on the frontend + expires_in 3.minutes + end + 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 f621adbebc7..b37962b850f 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -15,6 +15,7 @@ class Projects::BlameController < Projects::ApplicationController urgency :low, [:show] def show + @ref_type = ref_type load_environment load_blame end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 56e4b22ded2..015e56db012 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -101,8 +101,9 @@ class Projects::BlobController < Projects::ApplicationController ) rescue Files::UpdateService::FileChangedError @conflict = true - @different_project = different_project? - render :edit + render "edit", locals: { + commit_to_fork: @different_project + } end def preview @@ -164,7 +165,7 @@ class Projects::BlobController < Projects::ApplicationController @ref_type = ref_type - if @ref_type == ExtractsRef::BRANCH_REF_TYPE && ambiguous_ref?(@project, @ref) + if @ref_type == ExtractsRef::RefExtractor::BRANCH_REF_TYPE && ambiguous_ref?(@project, @ref) branch = @project.repository.find_branch(@ref) redirect_to project_blob_path(@project, File.join(branch.target, @path)) end diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb index 9d7569047f6..6e4d456ecc1 100644 --- a/app/controllers/projects/cycle_analytics_controller.rb +++ b/app/controllers/projects/cycle_analytics_controller.rb @@ -23,6 +23,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController before_action do push_licensed_feature(:cycle_analytics_for_groups) if project.licensed_feature_available?(:cycle_analytics_for_groups) push_licensed_feature(:group_level_analytics_dashboard) if project.licensed_feature_available?(:group_level_analytics_dashboard) + push_frontend_feature_flag(:vsa_predefined_date_ranges, project) if project.licensed_feature_available?(:cycle_analytics_for_projects) push_licensed_feature(:cycle_analytics_for_projects) diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb index b5099d555ae..1777497ee52 100644 --- a/app/controllers/projects/find_file_controller.rb +++ b/app/controllers/projects/find_file_controller.rb @@ -14,7 +14,9 @@ class Projects::FindFileController < Projects::ApplicationController urgency :low, [:show, :list] def show - return render_404 unless @repository.commit(@ref) + return render_404 unless @commit + + @ref_type = ref_type respond_to do |format| format.html @@ -22,7 +24,7 @@ class Projects::FindFileController < Projects::ApplicationController end def list - file_paths = @repo.ls_files(@ref) + file_paths = @repo.ls_files(@commit.id) respond_to do |format| format.json { render json: file_paths } diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb index 69d349b1f1d..bacf3192ee6 100644 --- a/app/controllers/projects/incidents_controller.rb +++ b/app/controllers/projects/incidents_controller.rb @@ -11,8 +11,8 @@ class Projects::IncidentsController < Projects::ApplicationController push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?) push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?) push_frontend_feature_flag(:moved_mr_sidebar, project) - push_frontend_feature_flag(:move_close_into_dropdown, project) push_force_frontend_feature_flag(:linked_work_items, @project&.linked_work_items_feature_flag_enabled?) + push_frontend_feature_flag(:notifications_todos_buttons, project) end feature_category :incident_management diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 9abcc108ace..4849cccac52 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -7,7 +7,6 @@ class Projects::IssuesController < Projects::ApplicationController include IssuableCollections include IssuesCalendar include RecordUserLastActivity - include ::Observability::ContentSecurityPolicy ISSUES_EXCEPT_ACTIONS = %i[index calendar new create bulk_update import_csv export_csv service_desk].freeze SET_ISSUABLES_INDEX_ONLY_ACTIONS = %i[index calendar service_desk].freeze @@ -46,13 +45,12 @@ class Projects::IssuesController < Projects::ApplicationController before_action do push_frontend_feature_flag(:preserve_unchanged_markdown, project) - push_frontend_feature_flag(:content_editor_on_issues, project&.group) - push_force_frontend_feature_flag(:content_editor_on_issues, project&.content_editor_on_issues_feature_flag_enabled?) push_frontend_feature_flag(:service_desk_new_note_email_native_attachments, project) push_frontend_feature_flag(:saved_replies, current_user) push_frontend_feature_flag(:issues_grid_view) push_frontend_feature_flag(:service_desk_ticket) push_frontend_feature_flag(:issues_list_drawer, project) + push_frontend_feature_flag(:linked_work_items, project) end before_action only: [:index, :show] do @@ -71,8 +69,8 @@ class Projects::IssuesController < Projects::ApplicationController push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?) push_frontend_feature_flag(:epic_widget_edit_confirmation, project) push_frontend_feature_flag(:moved_mr_sidebar, project) - push_frontend_feature_flag(:move_close_into_dropdown, project) push_force_frontend_feature_flag(:linked_work_items, project.linked_work_items_feature_flag_enabled?) + push_frontend_feature_flag(:notifications_todos_buttons, project) end around_action :allow_gitaly_ref_name_caching, only: [:discussions] @@ -277,6 +275,12 @@ class Projects::IssuesController < Projects::ApplicationController @issues = @issuables end + def discussions + Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/425834') + + super + end + protected def index_html_request? @@ -450,7 +454,7 @@ class Projects::IssuesController < Projects::ApplicationController def redirect_if_work_item return unless use_work_items_path?(issue) - redirect_to project_work_items_path(project, issue.iid, params: request.query_parameters) + redirect_to project_work_item_path(project, issue.iid, params: request.query_parameters) end def require_incident_for_incident_routes diff --git a/app/controllers/projects/mattermosts_controller.rb b/app/controllers/projects/mattermosts_controller.rb index a4091ebdf4b..9a3e7e31d68 100644 --- a/app/controllers/projects/mattermosts_controller.rb +++ b/app/controllers/projects/mattermosts_controller.rb @@ -19,10 +19,10 @@ class Projects::MattermostsController < Projects::ApplicationController result, message = integration.configure(current_user, configure_params) if result - flash[:notice] = 'This service is now configured' + flash[:notice] = 'This integration is now configured' redirect_to edit_project_settings_integration_path(@project, integration) else - flash[:alert] = message || 'Failed to configure service' + flash[:alert] = message || 'Failed to configure integration' redirect_to new_project_mattermost_path(@project) end end @@ -31,7 +31,7 @@ class Projects::MattermostsController < Projects::ApplicationController def configure_params params.require(:mattermost).permit(:trigger, :team_id).merge( - url: service_trigger_url(integration), + url: integration_trigger_url(integration), icon_url: asset_url('slash-command-logo.png', skip_pipeline: true)) end diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb index 81ff6c215f9..1af0ce3c35e 100644 --- a/app/controllers/projects/merge_requests/application_controller.rb +++ b/app/controllers/projects/merge_requests/application_controller.rb @@ -7,11 +7,6 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont feature_category :code_review_workflow - before_action do - push_frontend_feature_flag(:content_editor_on_issues, project&.group) - push_force_frontend_feature_flag(:content_editor_on_issues, project&.content_editor_on_issues_feature_flag_enabled?) - end - private # Normally the methods with `check_(\w+)_available!` pattern are diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index 6a3523b82d9..33a93ed99fb 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -4,7 +4,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap include DiffForPath include DiffHelper include RendersCommits - include ::Observability::ContentSecurityPolicy skip_before_action :merge_request before_action :authorize_create_merge_request_from! diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 53fd7256b19..ad7b7221e44 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -11,7 +11,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo include SourcegraphDecorator include DiffHelper include Gitlab::Cache::Helpers - include ::Observability::ContentSecurityPolicy prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) } skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv] @@ -37,8 +36,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end before_action only: [:show, :diffs] do - push_frontend_feature_flag(:content_editor_on_issues, project&.group) - push_force_frontend_feature_flag(:content_editor_on_issues, project&.content_editor_on_issues_feature_flag_enabled?) push_frontend_feature_flag(:core_security_mr_widget_counts, project) push_frontend_feature_flag(:issue_assignees_widget, @project) push_frontend_feature_flag(:moved_mr_sidebar, project) @@ -46,9 +43,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:mr_experience_survey, project) push_frontend_feature_flag(:saved_replies, current_user) push_force_frontend_feature_flag(:summarize_my_code_review, summarize_my_code_review_enabled?) - push_frontend_feature_flag(:mr_activity_filters, current_user) push_frontend_feature_flag(:ci_job_failures_in_mr, project) push_frontend_feature_flag(:mr_pipelines_graphql, project) + push_frontend_feature_flag(:notifications_todos_buttons, project) end before_action only: [:edit] do @@ -159,7 +156,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo pipelines: PipelineSerializer .new(project: @project, current_user: @current_user) .with_pagination(request, response) - .represent(@pipelines, preload: true), + .represent( + @pipelines, + preload: true, + disable_failed_builds: ::Feature.enabled?(:ci_fix_performance_pipelines_json_endpoint, @project) + ), count: { all: @pipelines.count } diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 1f4e5b54500..35b65dbce7e 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -24,10 +24,6 @@ class Projects::MilestonesController < Projects::ApplicationController feature_category :team_planning urgency :low - before_action do - push_frontend_feature_flag(:content_editor_on_issues, @project) - end - def index @sort = params[:sort] || 'due_date_asc' @milestones = milestones.sort_by_attribute(@sort) diff --git a/app/controllers/projects/ml/models_controller.rb b/app/controllers/projects/ml/models_controller.rb index 77855b73cbd..4ff7d014723 100644 --- a/app/controllers/projects/ml/models_controller.rb +++ b/app/controllers/projects/ml/models_controller.rb @@ -4,17 +4,30 @@ module Projects module Ml class ModelsController < ::Projects::ApplicationController before_action :check_feature_enabled + before_action :set_model, only: [:show] feature_category :mlops + MAX_MODELS_PER_PAGE = 20 + def index - @models = ::Projects::Ml::ModelFinder.new(@project).execute + @paginator = ::Projects::Ml::ModelFinder.new(@project) + .execute + .keyset_paginate(cursor: params[:cursor], per_page: MAX_MODELS_PER_PAGE) end + def show; end + private def check_feature_enabled render_404 unless can?(current_user, :read_model_registry, @project) end + + def set_model + @model = ::Ml::Model.by_project_id_and_id(@project, params[:model_id]) + + render_404 unless @model + end end end end diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb deleted file mode 100644 index 396841e667d..00000000000 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ /dev/null @@ -1,137 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Prometheus - class MetricsController < Projects::ApplicationController - before_action :check_feature_availability! - before_action :authorize_admin_project! - before_action :require_prometheus_metrics! - - feature_category :metrics - urgency :low - - def active_common - respond_to do |format| - format.json do - matched_metrics = prometheus_adapter.query(:matched_metrics) || {} - - if matched_metrics.any? - render json: matched_metrics - else - head :no_content - end - end - end - end - - def validate_query - respond_to do |format| - format.json do - result = prometheus_adapter.query(:validate, params[:query]) - - if result - render json: result - else - head :accepted - end - end - end - end - - def new - @metric = project.prometheus_metrics.new - end - - def index - respond_to do |format| - format.json do - metrics = ::PrometheusMetricsFinder.new( - project: project, - ordered: true - ).execute.to_a - - response = {} - if metrics.any? - response[:metrics] = ::PrometheusMetricSerializer - .new(project: project) - .represent(metrics) - end - - render json: response - end - end - end - - def create - @metric = project.prometheus_metrics.create( - metrics_params.to_h.symbolize_keys - ) - - if @metric.persisted? - redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), - notice: _('Metric was successfully added.') - else - render 'new' - end - end - - def update - @metric = prometheus_metric - - if @metric.update(metrics_params) - redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), - notice: _('Metric was successfully updated.') - else - render 'edit' - end - end - - def edit - @metric = prometheus_metric - end - - def destroy - destroy_metrics_service(prometheus_metric).execute - - respond_to do |format| - format.html do - redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), status: :see_other - end - format.json do - head :ok - end - end - end - - private - - def prometheus_adapter - @prometheus_adapter ||= ::Gitlab::Prometheus::Adapter.new(project, project.deployment_platform&.cluster).prometheus_adapter - end - - def require_prometheus_metrics! - render_404 unless prometheus_adapter&.can_query? - end - - def prometheus_metric - @prometheus_metric ||= ::PrometheusMetricsFinder.new(id: params[:id]).execute.first - end - - def update_metrics_service(metric) - ::Projects::Prometheus::Metrics::UpdateService.new(metric, metrics_params) - end - - def destroy_metrics_service(metric) - ::Projects::Prometheus::Metrics::DestroyService.new(metric) - end - - def metrics_params - params.require(:prometheus_metric).permit(:title, :query, :y_label, :unit, :legend, :group) - end - - def check_feature_availability! - render_404 if Feature.enabled?(:remove_monitor_metrics) - end - end - end -end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 6a246219f7d..fa26601204a 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -41,6 +41,7 @@ class ProjectsController < Projects::ApplicationController push_frontend_feature_flag(:remove_monitor_metrics, @project) push_frontend_feature_flag(:explain_code_chat, current_user) push_frontend_feature_flag(:service_desk_custom_email, @project) + push_frontend_feature_flag(:issue_email_participants, @project) push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks) push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies) push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?) diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb deleted file mode 100644 index f7a601ec0bd..00000000000 --- a/app/controllers/registrations/welcome_controller.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -module Registrations - class WelcomeController < ApplicationController - include OneTrustCSP - include GoogleAnalyticsCSP - include GoogleSyndicationCSP - include ::Gitlab::Utils::StrongMemoize - - layout 'minimal' - # TODO: Once this is an ee + SaaS only feature, we can remove this. - # To be completed in https://gitlab.com/gitlab-org/gitlab/-/issues/411858 - skip_before_action :check_two_factor_requirement - - helper_method :welcome_update_params - helper_method :onboarding_status - - feature_category :user_management - - def show - return redirect_to path_for_signed_in_user(current_user) if completed_welcome_step? - - track_event('render') - end - - def update - result = ::Users::SignupService.new(current_user, update_params).execute - - if result.success? - track_event('successfully_submitted_form') - successful_update_hooks - - redirect_to update_success_path - else - render :show - end - end - - private - - def authenticate_user! - return if current_user - - redirect_to new_user_registration_path - end - - def completed_welcome_step? - !current_user.setup_for_company.nil? - end - - def update_params - params.require(:user).permit(:role, :setup_for_company) - end - - def path_for_signed_in_user(user) - stored_location_for(user) || last_member_activity_path - end - - def last_member_activity_path - return dashboard_projects_path unless onboarding_status.last_invited_member_source.present? - - onboarding_status.last_invited_member_source.activity_path - end - - def update_success_path - if onboarding_status.continue_full_onboarding? # trials/regular registration on .com - signup_onboarding_path - elsif onboarding_status.single_invite? # invites w/o tasks due to order - flash[:notice] = helpers.invite_accepted_notice(onboarding_status.last_invited_member) - onboarding_status.last_invited_member_source.activity_path - else - # Subscription registrations goes through here as well. - # Invites will come here too if there is more than 1. - path_for_signed_in_user(current_user) - end - end - - # overridden in EE - def successful_update_hooks; end - - # overridden in EE - def signup_onboarding_path; end - - # overridden in EE - def track_event(action); end - - # overridden in EE - def welcome_update_params - {} - end - - def onboarding_status - Onboarding::Status.new(params.to_unsafe_h.deep_symbolize_keys, session, current_user) - end - strong_memoize_attr :onboarding_status - end -end - -Registrations::WelcomeController.prepend_mod_with('Registrations::WelcomeController') diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index a8b5ca81f49..72636a89433 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -7,13 +7,12 @@ class RegistrationsController < Devise::RegistrationsController include InvisibleCaptchaOnSignup include OneTrustCSP include BizibleCSP - include GoogleAnalyticsCSP - include GoogleSyndicationCSP include PreferredLanguageSwitcher include Gitlab::Tracking::Helpers::WeakPasswordErrorEvent include SkipsAlreadySignedInMessage include Gitlab::RackLoadBalancingHelpers include ::Gitlab::Utils::StrongMemoize + include Onboarding::Redirectable layout 'devise' @@ -26,11 +25,7 @@ class RegistrationsController < Devise::RegistrationsController check_rate_limit!(:user_sign_up, scope: request.ip) end - before_action only: [:new] do - push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) - end - - feature_category :user_management + feature_category :instance_resiliency helper_method :arkose_labs_enabled? helper_method :registration_path_params @@ -60,7 +55,7 @@ class RegistrationsController < Devise::RegistrationsController # Devise sets a flash message on both successful & failed signups, # but we only want to show a message if the resource is blocked by a pending approval. - flash[:notice] = nil unless resource.blocked_pending_approval? + flash[:notice] = nil unless allow_flash_content?(resource) rescue Gitlab::Access::AccessDeniedError redirect_to(new_user_session_path) end @@ -121,6 +116,9 @@ class RegistrationsController < Devise::RegistrationsController def after_sign_up_path_for(user) Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?)) + # Member#accept_invite! operates on the member record to change the association, so the user needs reloaded + # to update the collection. + user.reset after_sign_up_path end @@ -146,8 +144,13 @@ class RegistrationsController < Devise::RegistrationsController private - def after_sign_up_path - users_sign_up_welcome_path + def onboarding_status + Onboarding::Status.new(params.to_unsafe_h.deep_symbolize_keys, session, resource) + end + strong_memoize_attr :onboarding_status + + def allow_flash_content?(user) + user.blocked_pending_approval? || onboarding_status.single_invite? end # overridden in EE diff --git a/app/controllers/repositories/lfs_api_controller.rb b/app/controllers/repositories/lfs_api_controller.rb index da243a0301e..d9ca216b168 100644 --- a/app/controllers/repositories/lfs_api_controller.rb +++ b/app/controllers/repositories/lfs_api_controller.rb @@ -26,11 +26,7 @@ module Repositories end if download_request? - if Feature.enabled?(:lfs_batch_direct_downloads, project) - render json: { objects: download_objects! }, content_type: LfsRequest::CONTENT_TYPE - else - render json: { objects: legacy_download_objects! }, content_type: LfsRequest::CONTENT_TYPE - end + render json: { objects: download_objects! }, content_type: LfsRequest::CONTENT_TYPE elsif upload_request? render json: { objects: upload_objects! }, content_type: LfsRequest::CONTENT_TYPE else diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index d247490402f..7fff31c767f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -35,6 +35,18 @@ class SearchController < ApplicationController update_scope_for_code_search end + before_action only: :show do + push_frontend_feature_flag(:search_notes_hide_archived_projects, current_user) + end + + before_action only: :show do + push_frontend_feature_flag(:search_issues_hide_archived_projects, current_user) + end + + before_action only: :show do + push_frontend_feature_flag(:search_merge_requests_hide_archived_projects, current_user) + end + rescue_from ActiveRecord::QueryCanceled, with: :render_timeout layout 'search' diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index afbadc7f4ac..595d79abcf2 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -12,8 +12,6 @@ class SessionsController < Devise::SessionsController include OneTrustCSP include BizibleCSP include VerifiesWithEmail - include GoogleAnalyticsCSP - include GoogleSyndicationCSP include PreferredLanguageSwitcher include SkipsAlreadySignedInMessage include AcceptsPendingInvitations diff --git a/app/controllers/users/namespace_visits_controller.rb b/app/controllers/users/namespace_visits_controller.rb index 7c96d78e26e..d4f536654ca 100644 --- a/app/controllers/users/namespace_visits_controller.rb +++ b/app/controllers/users/namespace_visits_controller.rb @@ -5,7 +5,6 @@ module Users feature_category :navigation def create - return head :not_found unless Feature.enabled?(:server_side_frecent_namespaces, current_user) return head :bad_request unless params[:type].present? && params[:id].present? Users::TrackNamespaceVisitsWorker.perform_async(params[:type], params[:id], current_user.id, DateTime.now) # rubocop:disable CodeReuse/Worker diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb index f36b140f3a2..f7eb2aad9dc 100644 --- a/app/controllers/users/terms_controller.rb +++ b/app/controllers/users/terms_controller.rb @@ -4,7 +4,6 @@ module Users class TermsController < ApplicationController include InternalRedirect include OneTrustCSP - include GoogleAnalyticsCSP skip_before_action :authenticate_user!, only: [:index] skip_before_action :enforce_terms! @@ -14,10 +13,6 @@ module Users before_action :terms - before_action only: [:index] do - push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) - end - layout 'terms' feature_category :user_management |