From db384e6b19af03b4c3c82a5760d83a3fd79f7982 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 18 Aug 2023 10:50:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@16-3-stable-ee --- app/controllers/admin/abuse_reports_controller.rb | 18 +++- .../admin/application_settings_controller.rb | 1 + .../admin/broadcast_messages_controller.rb | 12 +-- app/controllers/admin/identities_controller.rb | 2 + .../admin/impersonation_tokens_controller.rb | 2 + app/controllers/admin/labels_controller.rb | 18 ++-- app/controllers/admin/users_controller.rb | 35 ++----- .../concerns/authenticates_with_two_factor.rb | 8 ++ .../concerns/enforces_two_factor_authentication.rb | 2 +- app/controllers/concerns/google_syndication_csp.rb | 21 ++++ app/controllers/concerns/integrations/params.rb | 11 +- app/controllers/concerns/issuable_actions.rb | 1 + app/controllers/concerns/kas_cookie.rb | 15 ++- app/controllers/concerns/notes_actions.rb | 7 ++ app/controllers/concerns/onboarding/status.rb | 11 +- .../concerns/product_analytics_tracking.rb | 13 +++ app/controllers/concerns/verifies_with_email.rb | 67 ++++++++---- app/controllers/confirmations_controller.rb | 1 + app/controllers/graphql_controller.rb | 14 ++- app/controllers/groups/application_controller.rb | 12 --- .../dependency_proxy/application_controller.rb | 2 +- app/controllers/groups/labels_controller.rb | 9 +- app/controllers/groups/runners_controller.rb | 2 +- .../groups/settings/ci_cd_controller.rb | 7 +- app/controllers/groups/work_items_controller.rb | 11 ++ app/controllers/groups_controller.rb | 16 +-- app/controllers/import/github_controller.rb | 8 +- .../jira_connect/app_descriptor_controller.rb | 7 +- app/controllers/omniauth_callbacks_controller.rb | 18 +++- .../organizations/application_controller.rb | 7 +- .../organizations/organizations_controller.rb | 2 +- .../profiles/notifications_controller.rb | 2 +- app/controllers/profiles/preferences_controller.rb | 7 +- app/controllers/projects/blob_controller.rb | 27 ----- .../daily_build_group_report_results_controller.rb | 2 +- .../projects/ci/pipeline_editor_controller.rb | 2 + app/controllers/projects/discussions_controller.rb | 23 ++++- .../projects/environments_controller.rb | 9 +- app/controllers/projects/issues_controller.rb | 3 + app/controllers/projects/labels_controller.rb | 11 +- .../projects/merge_requests_controller.rb | 3 +- .../metrics/dashboards/builder_controller.rb | 47 --------- app/controllers/projects/pages_controller.rb | 10 +- .../dashboards_controller.rb | 114 --------------------- .../projects/pipeline_schedules_controller.rb | 24 ++--- .../projects/settings/ci_cd_controller.rb | 3 +- app/controllers/projects/tracing_controller.rb | 4 + app/controllers/projects/tree_controller.rb | 1 - app/controllers/projects_controller.rb | 4 +- .../registrations/welcome_controller.rb | 10 +- app/controllers/registrations_controller.rb | 1 + app/controllers/repositories/lfs_api_controller.rb | 4 +- .../repositories/lfs_storage_controller.rb | 5 +- app/controllers/search_controller.rb | 8 +- app/controllers/sessions_controller.rb | 1 + 55 files changed, 318 insertions(+), 367 deletions(-) create mode 100644 app/controllers/concerns/google_syndication_csp.rb create mode 100644 app/controllers/groups/work_items_controller.rb delete mode 100644 app/controllers/projects/metrics/dashboards/builder_controller.rb delete mode 100644 app/controllers/projects/performance_monitoring/dashboards_controller.rb (limited to 'app/controllers') diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb index 6b998c3d494..329c4e4921a 100644 --- a/app/controllers/admin/abuse_reports_controller.rb +++ b/app/controllers/admin/abuse_reports_controller.rb @@ -4,7 +4,7 @@ class Admin::AbuseReportsController < Admin::ApplicationController feature_category :insider_threat before_action :set_status_param, only: :index, if: -> { Feature.enabled?(:abuse_reports_list) } - before_action :find_abuse_report, only: [:show, :update, :destroy] + before_action :find_abuse_report, only: [:show, :moderate_user, :update, :destroy] def index @abuse_reports = AbuseReportsFinder.new(params).execute @@ -12,8 +12,22 @@ class Admin::AbuseReportsController < Admin::ApplicationController def show; end + # Kept for backwards compatibility. + # TODO: See https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/issues/167?work_item_iid=443 + # In 16.4 remove or re-use this endpoint after frontend has migrated to using moderate_user endpoint def update - response = Admin::AbuseReportUpdateService.new(@abuse_report, current_user, permitted_params).execute + response = Admin::AbuseReports::ModerateUserService.new(@abuse_report, current_user, permitted_params).execute + + if response.success? + render json: { message: response.message } + else + render json: { message: response.message }, status: :unprocessable_entity + end + end + + def moderate_user + response = Admin::AbuseReports::ModerateUserService.new(@abuse_report, current_user, permitted_params).execute + if response.success? render json: { message: response.message } else diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index f0b6d86d48d..be1edeb0d37 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -15,6 +15,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController before_action do push_frontend_feature_flag(:ci_variables_pages, current_user) + push_frontend_feature_flag(:ci_variable_drawer, current_user) end feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index 7f85103816e..06ee178599d 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -2,7 +2,7 @@ module Admin class BroadcastMessagesController < ApplicationController - include BroadcastMessagesHelper + include Admin::BroadcastMessagesHelper before_action :find_broadcast_message, only: [:edit, :update, :destroy] before_action :find_broadcast_messages, only: [:index, :create] @@ -11,13 +11,13 @@ module Admin urgency :low def index - @broadcast_message = BroadcastMessage.new + @broadcast_message = System::BroadcastMessage.new end def edit; end def create - @broadcast_message = BroadcastMessage.new(broadcast_message_params) + @broadcast_message = System::BroadcastMessage.new(broadcast_message_params) success = @broadcast_message.save respond_to do |format| @@ -69,18 +69,18 @@ module Admin end def preview - @broadcast_message = BroadcastMessage.new(broadcast_message_params) + @broadcast_message = System::BroadcastMessage.new(broadcast_message_params) render plain: render_broadcast_message(@broadcast_message), status: :ok end protected def find_broadcast_message - @broadcast_message = BroadcastMessage.find(params[:id]) + @broadcast_message = System::BroadcastMessage.find(params[:id]) end def find_broadcast_messages - @broadcast_messages = BroadcastMessage.order(ends_at: :desc).page(params[:page]) # rubocop: disable CodeReuse/ActiveRecord + @broadcast_messages = System::BroadcastMessage.order(ends_at: :desc).page(params[:page]) # rubocop: disable CodeReuse/ActiveRecord end def broadcast_message_params diff --git a/app/controllers/admin/identities_controller.rb b/app/controllers/admin/identities_controller.rb index 0745ba328c6..15c4103a781 100644 --- a/app/controllers/admin/identities_controller.rb +++ b/app/controllers/admin/identities_controller.rb @@ -23,6 +23,8 @@ class Admin::IdentitiesController < Admin::ApplicationController def index @identities = @user.identities + @can_impersonate = helpers.can_impersonate_user(user, impersonation_in_progress?) + @impersonation_error_text = @can_impersonate ? nil : helpers.impersonation_error_text(user, impersonation_in_progress?) end def edit diff --git a/app/controllers/admin/impersonation_tokens_controller.rb b/app/controllers/admin/impersonation_tokens_controller.rb index dae3337d19b..1f25dad3428 100644 --- a/app/controllers/admin/impersonation_tokens_controller.rb +++ b/app/controllers/admin/impersonation_tokens_controller.rb @@ -8,6 +8,8 @@ class Admin::ImpersonationTokensController < Admin::ApplicationController def index set_index_vars + @can_impersonate = helpers.can_impersonate_user(user, impersonation_in_progress?) + @impersonation_error_text = @can_impersonate ? nil : helpers.impersonation_error_text(user, impersonation_in_progress?) end def create diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb index 4747f3c5dea..10d060b8161 100644 --- a/app/controllers/admin/labels_controller.rb +++ b/app/controllers/admin/labels_controller.rb @@ -41,14 +41,20 @@ class Admin::LabelsController < Admin::ApplicationController end def destroy - @label.destroy - @labels = Label.templates - respond_to do |format| - format.html do - redirect_to admin_labels_path, status: :found, notice: _('Label was removed') + if @label.destroy + format.html do + redirect_to admin_labels_path, status: :found, + notice: format(_('%{label_name} was removed'), label_name: @label.name) + end + format.js { head :ok } + else + format.html do + redirect_to admin_labels_path, status: :found, + alert: @label.errors.full_messages.to_sentence + end + format.js { head :unprocessable_entity } end - format.js { head :ok } end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b75ca2649c3..f05b03c2787 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -7,6 +7,7 @@ class Admin::UsersController < Admin::ApplicationController before_action :user, except: [:index, :new, :create] before_action :check_impersonation_availability, only: :impersonate before_action :ensure_destroy_prerequisites_met, only: [:destroy] + before_action :set_shared_view_parameters, only: [:show, :projects, :keys] feature_category :user_management @@ -24,10 +25,7 @@ class Admin::UsersController < Admin::ApplicationController @users = @users.without_count if paginate_without_count? end - def show - @can_impersonate = can_impersonate_user - @impersonation_error_text = @can_impersonate ? nil : impersonation_error_text - end + def show; end # rubocop: disable CodeReuse/ActiveRecord def projects @@ -48,7 +46,7 @@ class Admin::UsersController < Admin::ApplicationController end def impersonate - if can_impersonate_user + if helpers.can_impersonate_user(user, impersonation_in_progress?) session[:impersonator_id] = current_user.id warden.set_user(user, scope: :user) @@ -60,7 +58,7 @@ class Admin::UsersController < Admin::ApplicationController redirect_to root_path else - flash[:alert] = impersonation_error_text + flash[:alert] = helpers.impersonation_error_text(user, impersonation_in_progress?) redirect_to admin_user_path(user) end @@ -384,28 +382,17 @@ class Admin::UsersController < Admin::ApplicationController Gitlab::AppLogger.info(format(_("User %{current_user_username} has started impersonating %{username}"), current_user_username: current_user.username, username: user.username)) end - def can_impersonate_user - can?(user, :log_in) && !user.password_expired? && !impersonation_in_progress? - end - - def impersonation_error_text - if impersonation_in_progress? - _("You are already impersonating another user") - elsif user.blocked? - _("You cannot impersonate a blocked user") - elsif user.password_expired? - _("You cannot impersonate a user with an expired password") - elsif user.internal? - _("You cannot impersonate an internal user") - else - _("You cannot impersonate a user who cannot log in") - end - end - # method overriden in EE def unlock_user update_user(&:unlock_access!) end + + private + + def set_shared_view_parameters + @can_impersonate = helpers.can_impersonate_user(user, impersonation_in_progress?) + @impersonation_error_text = @can_impersonate ? nil : helpers.impersonation_error_text(user, impersonation_in_progress?) + end end Admin::UsersController.prepend_mod_with('Admin::UsersController') diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index 9fd86e6a7e0..41a3ee3e1c8 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -52,6 +52,14 @@ module AuthenticatesWithTwoFactor elsif user && user.valid_password?(user_params[:password]) prompt_for_two_factor(user) end + rescue ActiveRecord::RecordInvalid => e + # We expect User to always be valid. + # Otherwise, raise internal server error instead of unprocessable entity to improve observability/alerting + if e.record.is_a?(User) + raise e.message + else + raise e + end end private diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb index 8068913eea2..539feb3cf1c 100644 --- a/app/controllers/concerns/enforces_two_factor_authentication.rb +++ b/app/controllers/concerns/enforces_two_factor_authentication.rb @@ -77,7 +77,7 @@ module EnforcesTwoFactorAuthentication end def two_factor_verifier - @two_factor_verifier ||= Gitlab::Auth::TwoFactorAuthVerifier.new(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables + @two_factor_verifier ||= Gitlab::Auth::TwoFactorAuthVerifier.new(current_user, request) # rubocop:disable Gitlab/ModuleWithInstanceVariables end def mfa_help_page_url diff --git a/app/controllers/concerns/google_syndication_csp.rb b/app/controllers/concerns/google_syndication_csp.rb new file mode 100644 index 00000000000..c55debe448b --- /dev/null +++ b/app/controllers/concerns/google_syndication_csp.rb @@ -0,0 +1,21 @@ +# 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/integrations/params.rb b/app/controllers/concerns/integrations/params.rb index 53dd06ce638..e344e0dcd8c 100644 --- a/app/controllers/concerns/integrations/params.rb +++ b/app/controllers/concerns/integrations/params.rb @@ -43,6 +43,7 @@ module Integrations :external_wiki_url, :google_iap_service_account_json, :google_iap_audience_client_id, + :google_play_protected_refs, :group_confidential_mention_events, :group_mention_events, :incident_events, @@ -102,10 +103,14 @@ module Integrations param_values = return_value[:integration] if param_values.is_a?(ActionController::Parameters) - if %w[update test].include?(action_name) && integration.chat? && - param_values['webhook'] == BaseChatNotification::SECRET_MASK + if %w[update test].include?(action_name) && integration.chat? + param_values.delete('webhook') if param_values['webhook'] == BaseChatNotification::SECRET_MASK - param_values.delete('webhook') + if integration.try(:mask_configurable_channels?) + integration.event_channel_names.each do |channel| + param_values.delete(channel) if param_values[channel] == BaseChatNotification::SECRET_MASK + end + end end integration.secret_fields.each do |param| diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index a326fa308ad..1b49cffd408 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -256,6 +256,7 @@ module IssuableActions :milestone_id, :state_event, :subscription_event, + :confidential, assignee_ids: [], add_label_ids: [], remove_label_ids: [] diff --git a/app/controllers/concerns/kas_cookie.rb b/app/controllers/concerns/kas_cookie.rb index 06a4ee873f8..fafd426da7a 100644 --- a/app/controllers/concerns/kas_cookie.rb +++ b/app/controllers/concerns/kas_cookie.rb @@ -8,11 +8,10 @@ module KasCookie next unless ::Gitlab::Kas::UserAccess.enabled? next unless Settings.gitlab.content_security_policy['enabled'] - kas_url = ::Gitlab::Kas.tunnel_url next if URI(kas_url).host == ::Gitlab.config.gitlab.host # already allowed, no need for exception - kas_url += '/' unless kas_url.end_with?('/') - p.connect_src(*Array.wrap(p.directives['connect-src']), kas_url) + p.connect_src(*Array.wrap(p.directives['connect-src']), kas_ws_url.sub(%r{/?$}, '/')) + p.connect_src(*Array.wrap(p.directives['connect-src']), kas_url.sub(%r{/?$}, '/')) end end @@ -26,4 +25,14 @@ module KasCookie cookies[::Gitlab::Kas::COOKIE_KEY] = cookie_data end + + private + + def kas_url + ::Gitlab::Kas.tunnel_url + end + + def kas_ws_url + ::Gitlab::Kas.tunnel_ws_url + end end diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index 7b2cf131fce..93cf1d15086 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -11,6 +11,7 @@ module NotesActions included do before_action :set_polling_interval_header, only: [:index] + before_action :require_last_fetched_at_header!, only: [:index] before_action :require_noteable!, only: [:index, :create] before_action :authorize_admin_note!, only: [:update, :destroy] before_action :note_project, only: [:create] @@ -262,6 +263,12 @@ module NotesActions render_404 unless noteable end + def require_last_fetched_at_header! + return if request.headers['X-Last-Fetched-At'].present? + + render json: { message: 'X-Last-Fetched-At header is required' }, status: :bad_request + end + def last_fetched_at microseconds = request.headers['X-Last-Fetched-At'].to_i diff --git a/app/controllers/concerns/onboarding/status.rb b/app/controllers/concerns/onboarding/status.rb index 986f3f17847..5112ebb3b5d 100644 --- a/app/controllers/concerns/onboarding/status.rb +++ b/app/controllers/concerns/onboarding/status.rb @@ -2,10 +2,17 @@ module Onboarding class Status - def initialize(user) + 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 @@ -39,3 +46,5 @@ module Onboarding end end end + +Onboarding::Status.prepend_mod_with('Onboarding::Status') diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb index 5424354b92c..e148f5d063a 100644 --- a/app/controllers/concerns/product_analytics_tracking.rb +++ b/app/controllers/concerns/product_analytics_tracking.rb @@ -12,6 +12,19 @@ module ProductAnalyticsTracking route_events_to(destinations, name, action, label, &block) end end + + def track_internal_event(*controller_actions, name:, conditions: nil) + custom_conditions = [:trackable_html_request?, *conditions] + + after_action only: controller_actions, if: custom_conditions do + Gitlab::InternalEvents.track_event( + name, + user: current_user, + project: tracking_project_source, + namespace: tracking_namespace_source + ) + end + end end private diff --git a/app/controllers/concerns/verifies_with_email.rb b/app/controllers/concerns/verifies_with_email.rb index 13378800ea9..6affd7bb4cc 100644 --- a/app/controllers/concerns/verifies_with_email.rb +++ b/app/controllers/concerns/verifies_with_email.rb @@ -12,6 +12,7 @@ module VerifiesWithEmail skip_before_action :required_signup_info, only: :successful_verification end + # rubocop:disable Metrics/PerceivedComplexity def verify_with_email return unless user = find_user || find_verification_user @@ -34,18 +35,42 @@ module VerifiesWithEmail # - their account has been locked because of too many failed login attempts, or # - they have logged in before, but never from the current ip address reason = 'sign in from untrusted IP address' unless user.access_locked? - send_verification_instructions(user, reason: reason) + send_verification_instructions(user, reason: reason) unless send_rate_limited?(user) prompt_for_email_verification(user) end end end end + # rubocop:enable Metrics/PerceivedComplexity def resend_verification_code return unless user = find_verification_user - send_verification_instructions(user) - prompt_for_email_verification(user) + if send_rate_limited?(user) + message = format( + s_("IdentityVerification|You've reached the maximum amount of resends. Wait %{interval} and try again."), + interval: rate_limit_interval(:email_verification_code_send) + ) + render json: { status: :failure, message: message } + else + send_verification_instructions(user) + render json: { status: :success } + end + end + + def update_email + return unless user = find_verification_user + + log_verification(user, :email_update_requested) + result = Users::EmailVerification::UpdateEmailService.new(user: user).execute(email: email_params[:email]) + + if result[:status] == :success + send_verification_instructions(user) + else + handle_verification_failure(user, result[:reason], result[:message]) + end + + render json: result end def successful_verification @@ -67,19 +92,7 @@ module VerifiesWithEmail User.find_by_id(session[:verification_user_id]) end - # After successful verification and calling sign_in, devise redirects the - # user to this path. Override it to show the successful verified page. - def after_sign_in_path_for(resource) - if action_name == 'create' && session[:verification_user_id] == resource.id - return users_successful_verification_path - end - - super - end - def send_verification_instructions(user, reason: nil) - return if send_rate_limited?(user) - service = Users::EmailVerification::GenerateTokenService.new(attr: :unlock_token, user: user) raw_token, encrypted_token = service.execute user.unlock_token = encrypted_token @@ -90,7 +103,8 @@ module VerifiesWithEmail def send_verification_instructions_email(user, token) return unless user.can?(:receive_notifications) - Notify.verification_instructions_email(user.email, token: token).deliver_later + email = verification_email(user) + Notify.verification_instructions_email(email, token: token).deliver_later log_verification(user, :instructions_sent) end @@ -101,21 +115,23 @@ module VerifiesWithEmail if result[:status] == :success handle_verification_success(user) + render json: { status: :success, redirect_path: users_successful_verification_path } else handle_verification_failure(user, result[:reason], result[:message]) + render json: result end end def render_sign_in_rate_limited message = format( s_('IdentityVerification|Maximum login attempts exceeded. Wait %{interval} and try again.'), - interval: user_sign_in_interval + interval: rate_limit_interval(:user_sign_in) ) redirect_to new_user_session_path, alert: message end - def user_sign_in_interval - interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:user_sign_in][:interval] + def rate_limit_interval(rate_limit) + interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[rate_limit][:interval] distance_of_time_in_words(interval_in_seconds) end @@ -126,15 +142,19 @@ module VerifiesWithEmail def handle_verification_failure(user, reason, message) user.errors.add(:base, message) log_verification(user, :failed_attempt, reason) - - prompt_for_email_verification(user) end def handle_verification_success(user) + user.confirm if unconfirmed_verification_email?(user) + user.email_reset_offered_at = Time.current if user.email_reset_offered_at.nil? user.unlock_access! log_verification(user, :successful) sign_in(user) + + log_audit_event(current_user, user, with: authentication_method) + log_user_activity(user) + verify_known_sign_in end def trusted_ip_address?(user) @@ -146,6 +166,7 @@ module VerifiesWithEmail def prompt_for_email_verification(user) session[:verification_user_id] = user.id self.resource = user + add_gon_variables # Necessary to set the sprite_icons path, since we skip the ApplicationController before_filters render 'devise/sessions/email_verification' end @@ -154,6 +175,10 @@ module VerifiesWithEmail params.require(:user).permit(:verification_token) end + def email_params + params.require(:user).permit(:email) + end + def log_verification(user, event, reason = nil) Gitlab::AppLogger.info( message: 'Email Verification', diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index e94138c4d9b..f7c7ee62c1a 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -5,6 +5,7 @@ class ConfirmationsController < Devise::ConfirmationsController include GitlabRecaptcha include OneTrustCSP include GoogleAnalyticsCSP + include GoogleSyndicationCSP skip_before_action :required_signup_info prepend_before_action :check_recaptcha, only: :create diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 5c0c2b4adf2..29bc48f93e9 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -38,6 +38,8 @@ class GraphqlController < ApplicationController before_action :track_jetbrains_usage before_action :track_jetbrains_bundled_usage before_action :track_gitlab_cli_usage + before_action :track_visual_studio_usage + before_action :track_neovim_plugin_usage before_action :disable_query_limiting before_action :limit_query_size @@ -59,7 +61,7 @@ class GraphqlController < ApplicationController urgency :low, [:execute] def execute - result = if Feature.enabled?(:cache_introspection_query) && introspection_query? + result = if introspection_query? execute_introspection_query else multiplex? ? execute_multiplex : execute_query @@ -184,6 +186,16 @@ class GraphqlController < ApplicationController .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) end + def track_visual_studio_usage + Gitlab::UsageDataCounters::VisualStudioExtensionActivityUniqueCounter + .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) + end + + def track_neovim_plugin_usage + Gitlab::UsageDataCounters::NeovimPluginActivityUniqueCounter + .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) diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 5440908aee7..59343ec8b08 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -37,18 +37,6 @@ class Groups::ApplicationController < ApplicationController end end - def authorize_admin_group_runners! - unless can?(current_user, :admin_group_runners, group) - render_404 - end - end - - def authorize_read_group_runners! - unless can?(current_user, :read_group_runners, group) - render_404 - end - end - def authorize_create_deploy_token! unless can?(current_user, :create_deploy_token, group) render_404 diff --git a/app/controllers/groups/dependency_proxy/application_controller.rb b/app/controllers/groups/dependency_proxy/application_controller.rb index 300a82eed78..12c3679cf2a 100644 --- a/app/controllers/groups/dependency_proxy/application_controller.rb +++ b/app/controllers/groups/dependency_proxy/application_controller.rb @@ -24,7 +24,7 @@ module Groups case user_or_deploy_token when User @authentication_result = Gitlab::Auth::Result.new(user_or_deploy_token, nil, :user, []) - sign_in(user_or_deploy_token) + sign_in(user_or_deploy_token) unless user_or_deploy_token.project_bot? when DeployToken @authentication_result = Gitlab::Auth::Result.new(user_or_deploy_token, nil, :deploy_token, []) end diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index 2d821676677..57bca5ebc52 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -64,8 +64,13 @@ class Groups::LabelsController < Groups::ApplicationController end def destroy - @label.destroy - redirect_to group_labels_path(@group), status: :found, notice: "#{@label.name} deleted permanently" + if @label.destroy + redirect_to group_labels_path(@group), status: :found, + notice: format(_('%{label_name} was removed'), label_name: @label.name) + else + redirect_to group_labels_path(@group), status: :found, + alert: @label.errors.full_messages.to_sentence + end end protected diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index 2dd0e36b65f..b3539da8429 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -49,7 +49,7 @@ class Groups::RunnersController < Groups::ApplicationController end def authorize_update_runner! - return if can?(current_user, :admin_group_runners, group) && can?(current_user, :update_runner, runner) + return if can?(current_user, :update_runner, runner) render_404 end diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 169caabf9d8..f50cdd2b1de 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -14,8 +14,8 @@ module Groups feature_category :continuous_integration before_action do - push_frontend_feature_flag(:ci_group_env_scope_graphql, group) push_frontend_feature_flag(:ci_variables_pages, current_user) + push_frontend_feature_flag(:ci_variable_drawer, current_user) end urgency :low @@ -49,7 +49,6 @@ module Groups def define_variables define_ci_variables - define_view_variables end def define_ci_variables @@ -59,10 +58,6 @@ module Groups .map { |variable| variable.present(current_user: current_user) } end - def define_view_variables - @content_class = 'limit-container-width' unless fluid_layout - end - def authorize_admin_group! return render_404 unless can?(current_user, :admin_group, group) end diff --git a/app/controllers/groups/work_items_controller.rb b/app/controllers/groups/work_items_controller.rb new file mode 100644 index 00000000000..d1e15c81471 --- /dev/null +++ b/app/controllers/groups/work_items_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Groups + class WorkItemsController < Groups::ApplicationController + feature_category :team_planning + + def index + not_found unless Feature.enabled?(:namespace_level_work_items, group) + end + end +end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index ec16be8f85e..344de886a93 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -37,6 +37,7 @@ class GroupsController < Groups::ApplicationController push_frontend_feature_flag(:frontend_caching, group) push_force_frontend_feature_flag(:work_items, group.work_items_feature_flag_enabled?) push_frontend_feature_flag(:issues_grid_view) + push_frontend_feature_flag(:new_graphql_users_autocomplete, group) end before_action only: :merge_requests do @@ -218,8 +219,8 @@ class GroupsController < Groups::ApplicationController return super unless html_request? @has_issues = IssuesFinder.new(current_user, group_id: group.id, include_subgroups: true).execute - .non_archived - .exists? + .non_archived + .exists? @has_projects = group_projects.exists? @@ -293,6 +294,7 @@ class GroupsController < Groups::ApplicationController :project_creation_level, :subgroup_creation_level, :default_branch_protection, + { default_branch_protection_defaults: [:allow_force_push, { allowed_to_merge: [:access_level], allowed_to_push: [:access_level] }] }, :default_branch_name, :allow_mfa_for_subgroups, :resource_access_token_creation_allowed, @@ -309,13 +311,13 @@ class GroupsController < Groups::ApplicationController options = { include_subgroups: true } projects = GroupProjectsFinder.new(params: params, group: group, options: options, current_user: current_user) - .execute - .includes(:namespace) + .execute + .includes(:namespace) @events = EventCollection - .new(projects, offset: params[:offset].to_i, filter: event_filter, groups: groups) - .to_a - .map(&:present) + .new(projects, offset: params[:offset].to_i, filter: event_filter, groups: groups) + .to_a + .map(&:present) Events::RenderService .new(current_user) diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 12210afd44a..28732d58484 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -13,10 +13,6 @@ class Import::GithubController < Import::BaseController before_action :provider_auth, only: [:status, :realtime_changes, :create] before_action :expire_etag_cache, only: [:status, :create] - before_action only: [:status] do - push_frontend_feature_flag(:import_details_page) - end - rescue_from Octokit::Unauthorized, with: :provider_unauthorized rescue_from Octokit::TooManyRequests, with: :provider_rate_limit rescue_from Gitlab::GithubImport::RateLimitError, with: :rate_limit_threshold_exceeded @@ -73,9 +69,7 @@ class Import::GithubController < Import::BaseController end end - def details - render_404 unless Feature.enabled?(:import_details_page) - end + def details; end def create result = Import::GithubService.new(client, current_user, import_params).execute(access_params, provider_name) diff --git a/app/controllers/jira_connect/app_descriptor_controller.rb b/app/controllers/jira_connect/app_descriptor_controller.rb index 2c498820a1e..3c50d54fa10 100644 --- a/app/controllers/jira_connect/app_descriptor_controller.rb +++ b/app/controllers/jira_connect/app_descriptor_controller.rb @@ -8,7 +8,7 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController skip_before_action :verify_atlassian_jwt! def show - result = { + render json: { name: Atlassian::JiraConnect.app_name, description: 'Integrate commits, branches and merge requests from GitLab into Jira', key: Atlassian::JiraConnect.app_key, @@ -36,15 +36,10 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController gdpr: true } } - - result[:links][:feedback] = URI.join(HOME_URL, FEEDBACK_URL) if Feature.enabled?(:jira_for_cloud_app_feedback_link) - - render json: result end private - FEEDBACK_URL = '/gitlab-org/gitlab/-/issues/413652' HOME_URL = 'https://gitlab.com' DOC_URL = 'https://docs.gitlab.com/ee/integration/jira/' diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index eda72400f17..72b3516ae3f 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -130,6 +130,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController link_identity(identity_linker) set_remember_me(current_user) + store_idp_two_factor_status(build_auth_user(auth_module::User).bypass_two_factor?) + if identity_linker.changed? redirect_identity_linked elsif identity_linker.failed? @@ -159,7 +161,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end def build_auth_user(auth_user_class) - auth_user_class.new(oauth) + strong_memoize_with(:build_auth_user, auth_user_class) do + auth_user_class.new(oauth) + end end def sign_in_user_flow(auth_user_class) @@ -179,12 +183,16 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController 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 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 @@ -323,6 +331,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def sign_in_and_redirect_or_verify_identity(user, _, _) sign_in_and_redirect(user, event: :authentication) end + + def store_idp_two_factor_status(bypass_2fa) + if Feature.enabled?(:by_pass_two_factor_for_current_session) + session[:provider_2FA] = true if bypass_2fa + else + session.delete(:provider_2FA) + end + end end OmniauthCallbacksController.prepend_mod_with('OmniauthCallbacksController') diff --git a/app/controllers/organizations/application_controller.rb b/app/controllers/organizations/application_controller.rb index 43cc7014f62..568cfe6399d 100644 --- a/app/controllers/organizations/application_controller.rb +++ b/app/controllers/organizations/application_controller.rb @@ -2,6 +2,7 @@ module Organizations class ApplicationController < ::ApplicationController + skip_before_action :authenticate_user! before_action :organization layout 'organization' @@ -16,8 +17,10 @@ module Organizations strong_memoize_attr :organization def authorize_action!(action) - access_denied! if Feature.disabled?(:ui_for_organizations) - access_denied! unless can?(current_user, action, organization) + return if Feature.enabled?(:ui_for_organizations, current_user) && + can?(current_user, action, organization) + + access_denied! end end end diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 4781ef995b7..650ec97c264 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -4,7 +4,7 @@ module Organizations class OrganizationsController < ApplicationController feature_category :cell - before_action { authorize_action!(:admin_organization) } + before_action { authorize_action!(:read_organization) } def show; end diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 1477f8e0aac..02f7dbf8e6f 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -45,7 +45,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController projects = project_notifications.map(&:source) ActiveRecord::Associations::Preloader.new( records: projects, - associations: { namespace: [:route, :owner], group: [], creator: [] } + associations: { namespace: [:route, :owner], group: [], creator: [], project_setting: [] } ).call Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index f19113276c2..3e8555a4ed1 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -37,7 +37,7 @@ class Profiles::PreferencesController < Profiles::ApplicationController end def preferences_param_names - preferences_param_names = [ + [ :color_scheme_id, :diffs_deletion_color, :diffs_addition_color, @@ -57,10 +57,9 @@ class Profiles::PreferencesController < Profiles::ApplicationController :project_shortcut_buttons, :markdown_surround_selection, :markdown_automatic_lists, - :use_new_navigation + :use_new_navigation, + :enabled_following ] - preferences_param_names << :enabled_following if ::Feature.enabled?(:disable_follow_users, user) - preferences_param_names end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index b41e4d11d24..56e4b22ded2 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -48,7 +48,6 @@ class Projects::BlobController < Projects::ApplicationController urgency :low, [:create, :show, :edit, :update, :diff] before_action do - push_frontend_feature_flag(:highlight_js, @project) push_frontend_feature_flag(:highlight_js_worker, @project) push_frontend_feature_flag(:explain_code_chat, current_user) push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks) @@ -275,8 +274,6 @@ class Projects::BlobController < Projects::ApplicationController @last_commit = @repository.last_commit_for_path(@commit.id, @blob.path, literal_pathspec: true) @code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path) - allow_lfs_direct_download - render 'show' end @@ -321,30 +318,6 @@ class Projects::BlobController < Projects::ApplicationController current_user&.id end - def allow_lfs_direct_download - return unless directly_downloading_lfs_object? && content_security_policy_enabled? - return unless (lfs_object = @project.lfs_objects.find_by_oid(@blob.lfs_oid)) - - request.content_security_policy.directives['connect-src'] ||= [] - request.content_security_policy.directives['connect-src'] << lfs_src(lfs_object) - end - - def directly_downloading_lfs_object? - Gitlab.config.lfs.enabled && - !Gitlab.config.lfs.object_store.proxy_download && - @blob&.stored_externally? - end - - def content_security_policy_enabled? - Gitlab.config.gitlab.content_security_policy.enabled - end - - def lfs_src(lfs_object) - file = lfs_object.file - file = file.cdn_enabled_url(request.remote_ip) if file.respond_to?(:cdn_enabled_url) - file.url - end - alias_method :tracking_project_source, :project def tracking_namespace_source diff --git a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb index 37138afc719..c1d325d8998 100644 --- a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb +++ b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb @@ -20,7 +20,7 @@ class Projects::Ci::DailyBuildGroupReportResultsController < Projects::Applicati end def render_csv(collection) - CsvBuilders::SingleBatch.new( + CsvBuilder::SingleBatch.new( collection, { date: 'date', diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index 8499bf0ced7..6e7f764c5c1 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -21,3 +21,5 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController render_404 unless can_collaborate_with_project?(@project) end end + +Projects::Ci::PipelineEditorController.prepend_mod diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb index 59de4fbb698..34b283b87f5 100644 --- a/app/controllers/projects/discussions_controller.rb +++ b/app/controllers/projects/discussions_controller.rb @@ -4,8 +4,8 @@ class Projects::DiscussionsController < Projects::ApplicationController include NotesHelper include RendersNotes - before_action :check_merge_requests_available! - before_action :merge_request + before_action :check_noteable_supports_resolvable_notes! + before_action :noteable before_action :discussion, only: [:resolve, :unresolve] before_action :authorize_resolve_discussion!, only: [:resolve, :unresolve] @@ -56,13 +56,26 @@ class Projects::DiscussionsController < Projects::ApplicationController end # rubocop: disable CodeReuse/ActiveRecord - def merge_request - @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).find_by!(iid: params[:merge_request_id]) + def noteable + @noteable ||= noteable_finder_class.new(current_user, project_id: @project.id).find_by!(iid: params[:noteable_id]) end # rubocop: enable CodeReuse/ActiveRecord + def noteable_finder_class + case params[:noteable_type] + when 'issues' + IssuesFinder + when 'merge_requests' + MergeRequestsFinder + end + end + + def check_noteable_supports_resolvable_notes! + render_404 unless noteable_finder_class && noteable&.supports_resolvable_notes? + end + def discussion - @discussion ||= @merge_request.find_discussion(params[:id]) || render_404 + @discussion ||= @noteable.find_discussion(params[:id]) || render_404 end def authorize_resolve_discussion! diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 4cc1ed092d2..127fe40b0e3 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -13,7 +13,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController end before_action only: [:index, :edit, :new] do - push_frontend_feature_flag(:kubernetes_namespace_for_environment) + push_frontend_feature_flag(:flux_resource_for_environment) end before_action :authorize_read_environment! @@ -110,10 +110,13 @@ class Projects::EnvironmentsController < Projects::ApplicationController return render_404 unless @environment.available? stop_actions = @environment.stop_with_actions!(current_user) + job = stop_actions.first if stop_actions&.count == 1 action_or_env_url = - if stop_actions&.count == 1 - polymorphic_url([project, stop_actions.first]) + if job.instance_of?(::Ci::Build) + polymorphic_url([project, job]) + elsif job.instance_of?(::Ci::Bridge) + project_pipeline_url(project, job.pipeline_id) else project_environment_url(project, @environment) end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 05be34d63e0..83947c443f4 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -52,6 +52,7 @@ class Projects::IssuesController < Projects::ApplicationController 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) end before_action only: [:index, :show] do @@ -61,6 +62,7 @@ class Projects::IssuesController < Projects::ApplicationController before_action only: [:index, :service_desk] do push_frontend_feature_flag(:or_issuable_queries, project) push_frontend_feature_flag(:frontend_caching, project&.group) + push_frontend_feature_flag(:new_graphql_users_autocomplete, project) end before_action only: :show do @@ -71,6 +73,7 @@ class Projects::IssuesController < Projects::ApplicationController 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_frontend_feature_flag(:action_cable_notes, project) end around_action :allow_gitaly_ref_name_caching, only: [:discussions] diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 649bead0b6d..67cff16a76b 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -79,10 +79,13 @@ class Projects::LabelsController < Projects::ApplicationController end def destroy - @label.destroy - @labels = find_labels - - redirect_to project_labels_path(@project), status: :found, notice: 'Label was removed' + if @label.destroy + redirect_to project_labels_path(@project), status: :found, + notice: format(_('%{label_name} was removed'), label_name: @label.name) + else + redirect_to project_labels_path(@project), status: :found, + alert: @label.errors.full_messages.to_sentence + end end def remove_priority diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2172c91fc76..30168558eff 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -50,6 +50,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:mr_activity_filters, current_user) push_frontend_feature_flag(:review_apps_redeploy_mr_widget, project) push_frontend_feature_flag(:ci_job_failures_in_mr, project) + push_frontend_feature_flag(:action_cable_notes, project) end before_action only: [:edit] do @@ -165,7 +166,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo pipelines: PipelineSerializer .new(project: @project, current_user: @current_user) .with_pagination(request, response) - .represent(@pipelines), + .represent(@pipelines, preload: true), count: { all: @pipelines.count } diff --git a/app/controllers/projects/metrics/dashboards/builder_controller.rb b/app/controllers/projects/metrics/dashboards/builder_controller.rb deleted file mode 100644 index 02e3afcdc80..00000000000 --- a/app/controllers/projects/metrics/dashboards/builder_controller.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Metrics - module Dashboards - class BuilderController < Projects::ApplicationController - before_action :authorize_metrics_dashboard! - - feature_category :metrics - urgency :low - - def panel_preview - return not_found if Feature.enabled?(:remove_monitor_metrics) - - respond_to do |format| - format.json do - if rendered_panel.success? - render json: rendered_panel.payload - else - render json: { message: rendered_panel.message }, status: :unprocessable_entity - end - end - end - end - - private - - def rendered_panel - @panel_preview ||= ::Metrics::Dashboard::PanelPreviewService.new(project, panel_yaml, environment).execute - end - - def panel_yaml - params.require(:panel_yaml) - end - - def environment - @environment ||= - if params[:environment] - project.environments.find(params[:environment]) - else - project.default_environment - end - end - end - end - end -end diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index 6cfbb61fbb2..02579cd4283 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -65,15 +65,7 @@ class Projects::PagesController < Projects::ApplicationController end def project_params_attributes - attributes = %i[pages_https_only] - - return attributes unless Feature.enabled?(:pages_unique_domain, @project) - - attributes + [ - project_setting_attributes: [ - :pages_unique_domain_enabled - ] - ] + [:pages_https_only, { project_setting_attributes: [:pages_unique_domain_enabled] }] end end diff --git a/app/controllers/projects/performance_monitoring/dashboards_controller.rb b/app/controllers/projects/performance_monitoring/dashboards_controller.rb deleted file mode 100644 index 1255ec1dde2..00000000000 --- a/app/controllers/projects/performance_monitoring/dashboards_controller.rb +++ /dev/null @@ -1,114 +0,0 @@ -# frozen_string_literal: true - -module Projects - module PerformanceMonitoring - class DashboardsController < ::Projects::ApplicationController - include BlobHelper - - before_action :check_repository_available! - before_action :validate_required_params! - - rescue_from ActionController::ParameterMissing do |exception| - respond_error(http_status: :bad_request, message: _('Request parameter %{param} is missing.') % { param: exception.param }) - end - - feature_category :metrics - urgency :low - - def create - return not_found if Feature.enabled?(:remove_monitor_metrics) - - result = ::Metrics::Dashboard::CloneDashboardService.new(project, current_user, dashboard_params).execute - - if result[:status] == :success - respond_success(result) - else - respond_error(result) - end - end - - def update - return not_found if Feature.enabled?(:remove_monitor_metrics) - - result = ::Metrics::Dashboard::UpdateDashboardService.new(project, current_user, dashboard_params.merge(file_content_params)).execute - - if result[:status] == :success - respond_update_success(result) - else - respond_error(result) - end - end - - private - - def respond_success(result) - set_web_ide_link_notice(result.dig(:dashboard, :path)) - respond_to do |format| - format.json { render status: result.delete(:http_status), json: result } - end - end - - def respond_error(result) - respond_to do |format| - format.json { render json: { error: result[:message] }, status: result[:http_status] } - end - end - - def set_web_ide_link_notice(new_dashboard_path) - web_ide_link_start = "" - message = _("Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}.") % { web_ide_link_start: web_ide_link_start, web_ide_link_end: "" } - flash[:notice] = message.html_safe - end - - def respond_update_success(result) - set_web_ide_link_update_notice(result.dig(:dashboard, :path)) - respond_to do |format| - format.json { render status: result.delete(:http_status), json: result } - end - end - - def set_web_ide_link_update_notice(new_dashboard_path) - web_ide_link_start = "" - message = _("Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}.") % { web_ide_link_start: web_ide_link_start, web_ide_link_end: "" } - flash[:notice] = message.html_safe - end - - def validate_required_params! - params.require(%i[branch file_name dashboard commit_message]) - end - - def redirect_safe_branch_name - repository.find_branch(params[:branch]).name - end - - def dashboard_params - params.permit(%i[branch file_name dashboard commit_message]).to_h - end - - def file_content_params - params.permit( - file_content: [ - :dashboard, - panel_groups: [ - :group, - :priority, - panels: [ - :type, - :title, - :y_label, - :weight, - metrics: [ - :id, - :unit, - :label, - :query, - :query_range - ] - ] - ] - ] - ) - end - end - end -end diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index 96c9aa89953..42b6d83ee85 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -24,25 +24,13 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController end def create - if ::Feature.enabled?(:ci_refactoring_pipeline_schedule_create_service, @project) - response = Ci::PipelineSchedules::CreateService.new(@project, current_user, schedule_params).execute - @schedule = response.payload - - if response.success? - redirect_to pipeline_schedules_path(@project) - else - render :new - end + response = Ci::PipelineSchedules::CreateService.new(@project, current_user, schedule_params).execute + @schedule = response.payload + + if response.success? + redirect_to pipeline_schedules_path(@project) else - @schedule = Ci::CreatePipelineScheduleService - .new(@project, current_user, schedule_params) - .execute - - if @schedule.persisted? - redirect_to pipeline_schedules_path(@project) - else - render :new - end + render :new end end diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 0e892ef3faa..0845fbc9713 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -14,6 +14,7 @@ module Projects before_action do push_frontend_feature_flag(:ci_variables_pages, current_user) + push_frontend_feature_flag(:ci_variable_drawer, current_user) end helper_method :highlight_badge @@ -88,7 +89,7 @@ module Projects :build_timeout_human_readable, :public_builds, :ci_separated_caches, :auto_cancel_pending_pipelines, :ci_config_path, :auto_rollback_enabled, auto_devops_attributes: [:id, :domain, :enabled, :deploy_strategy], - ci_cd_settings_attributes: [:default_git_depth, :forward_deployment_enabled] + ci_cd_settings_attributes: [:default_git_depth, :forward_deployment_enabled, :forward_deployment_rollback_allowed] ].tap do |list| list << :max_artifacts_size if can?(current_user, :update_max_artifacts_size, project) end diff --git a/app/controllers/projects/tracing_controller.rb b/app/controllers/projects/tracing_controller.rb index d1218ebf344..45e773bf62b 100644 --- a/app/controllers/projects/tracing_controller.rb +++ b/app/controllers/projects/tracing_controller.rb @@ -10,6 +10,10 @@ module Projects def index; end + def show + @trace_id = params[:id] + end + private def check_tracing_enabled diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index b961339111b..0371fb21ac8 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 :authorize_edit_tree!, only: [:create_dir] before_action do - push_frontend_feature_flag(:highlight_js, @project) push_frontend_feature_flag(:highlight_js_worker, @project) push_frontend_feature_flag(:explain_code_chat, current_user) push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 51f6158d9c0..2ad0f11dc91 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -37,11 +37,9 @@ class ProjectsController < Projects::ApplicationController before_action :check_export_rate_limit!, only: [:export, :download_export, :generate_new_export] before_action do - push_frontend_feature_flag(:highlight_js, @project) push_frontend_feature_flag(:highlight_js_worker, @project) push_frontend_feature_flag(:remove_monitor_metrics, @project) push_frontend_feature_flag(:explain_code_chat, current_user) - push_frontend_feature_flag(:ci_namespace_catalog_experimental, @project) push_frontend_feature_flag(:service_desk_custom_email, @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) @@ -471,6 +469,7 @@ class ProjectsController < Projects::ApplicationController mr_default_target_self warn_about_potentially_unwanted_characters enforce_auth_checks_on_uploads + emails_enabled ] end @@ -483,7 +482,6 @@ class ProjectsController < Projects::ApplicationController :resolve_outdated_diff_discussions, :container_registry_enabled, :description, - :emails_disabled, :external_authorization_classification_label, :import_url, :issues_tracker, diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb index 76f181e3ce8..68f8248d114 100644 --- a/app/controllers/registrations/welcome_controller.rb +++ b/app/controllers/registrations/welcome_controller.rb @@ -4,6 +4,7 @@ module Registrations class WelcomeController < ApplicationController include OneTrustCSP include GoogleAnalyticsCSP + include GoogleSyndicationCSP include ::Gitlab::Utils::StrongMemoize layout 'minimal' @@ -53,11 +54,6 @@ module Registrations stored_location_for(user) || last_member_activity_path end - # overridden in EE - def complete_signup_onboarding? - onboarding_status.continue_full_onboarding? - end - def last_member_activity_path return dashboard_projects_path unless onboarding_status.last_invited_member_source.present? @@ -67,7 +63,7 @@ module Registrations def update_success_path if onboarding_status.invite_with_tasks_to_be_done? issues_dashboard_path(assignee_username: current_user.username) - elsif complete_signup_onboarding? # trials/regular registration on .com + elsif 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) @@ -94,7 +90,7 @@ module Registrations end def onboarding_status - Onboarding::Status.new(current_user) + Onboarding::Status.new(params.to_unsafe_h.deep_symbolize_keys, session, current_user) end strong_memoize_attr :onboarding_status end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 76b7d30cd51..d8064bbbe82 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -8,6 +8,7 @@ class RegistrationsController < Devise::RegistrationsController include OneTrustCSP include BizibleCSP include GoogleAnalyticsCSP + include GoogleSyndicationCSP include PreferredLanguageSwitcher include Gitlab::Tracking::Helpers::WeakPasswordErrorEvent include SkipsAlreadySignedInMessage diff --git a/app/controllers/repositories/lfs_api_controller.rb b/app/controllers/repositories/lfs_api_controller.rb index 32119ddf89e..da243a0301e 100644 --- a/app/controllers/repositories/lfs_api_controller.rb +++ b/app/controllers/repositories/lfs_api_controller.rb @@ -64,11 +64,13 @@ module Repositories .for_oids(objects_oids) .index_by(&:oid) + guest_can_download = Guest.can?(:download_code, project) + objects.each do |object| if lfs_object = existing_oids[object[:oid]] object[:actions] = download_actions(object, lfs_object) - if Guest.can?(:download_code, project) + if guest_can_download object[:authenticated] = true end else diff --git a/app/controllers/repositories/lfs_storage_controller.rb b/app/controllers/repositories/lfs_storage_controller.rb index 22f1a81b95b..80f7153cd7a 100644 --- a/app/controllers/repositories/lfs_storage_controller.rb +++ b/app/controllers/repositories/lfs_storage_controller.rb @@ -18,10 +18,7 @@ module Repositories def download lfs_object = LfsObject.find_by_oid(oid) - unless lfs_object && lfs_object.file.exists? - render_lfs_not_found - return - end + return render_lfs_not_found unless lfs_object&.file&.exists? send_upload(lfs_object.file, send_params: { content_type: "application/octet-stream" }) end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 45aefe48538..6c1d9a20570 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -35,6 +35,10 @@ class SearchController < ApplicationController update_scope_for_code_search end + before_action only: :show do + push_frontend_feature_flag(:search_projects_hide_archived, current_user) + end + rescue_from ActiveRecord::QueryCanceled, with: :render_timeout layout 'search' @@ -107,7 +111,7 @@ class SearchController < ApplicationController end def autocomplete - term = params[:term] + term = params.require(:term) @project = search_service.project @ref = params[:project_ref] if params[:project_ref].present? @@ -248,7 +252,7 @@ class SearchController < ApplicationController end def search_type - 'basic' + search_service.search_type end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index a9972cbd885..66ace16400a 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -13,6 +13,7 @@ class SessionsController < Devise::SessionsController include BizibleCSP include VerifiesWithEmail include GoogleAnalyticsCSP + include GoogleSyndicationCSP include PreferredLanguageSwitcher include SkipsAlreadySignedInMessage -- cgit v1.2.3