diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
commit | 0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch) | |
tree | 7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /app/controllers | |
parent | 72123183a20411a36d607d70b12d57c484394c8e (diff) | |
download | gitlab-ce-0ea3fcec397b69815975647f5e2aa5fe944a8486.tar.gz |
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'app/controllers')
94 files changed, 537 insertions, 582 deletions
diff --git a/app/controllers/admin/application_settings/appearances_controller.rb b/app/controllers/admin/application_settings/appearances_controller.rb index 47b2356a60f..cf765c96a8f 100644 --- a/app/controllers/admin/application_settings/appearances_controller.rb +++ b/app/controllers/admin/application_settings/appearances_controller.rb @@ -4,6 +4,7 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont before_action :set_appearance, except: :create feature_category :navigation + urgency :low def show end diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 253fca0a253..7f95b136e4e 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -24,6 +24,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :delete_self_monitoring_project, :status_delete_self_monitoring_project ] + urgency :low, [ + :create_self_monitoring_project, + :status_create_self_monitoring_project, + :delete_self_monitoring_project, + :status_delete_self_monitoring_project + ] feature_category :source_code_management, [:repository, :clear_repository_check_states] feature_category :continuous_integration, [:ci_cd, :reset_registration_token] diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index 8b672929f88..865af244773 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -6,6 +6,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController before_action :finder, only: [:edit, :update, :destroy] feature_category :navigation + urgency :low # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 20e36e5fd84..8fe106249c3 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -7,7 +7,6 @@ class Admin::DashboardController < Admin::ApplicationController feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned - # rubocop: disable CodeReuse/ActiveRecord def index @counts = Gitlab::Database::Count.approximate_counts(COUNTED_ITEMS) @projects = Project.order_id_desc.without_deleted.with_route.limit(10) @@ -24,7 +23,6 @@ class Admin::DashboardController < Admin::ApplicationController Gitlab::Redis::Sessions ].map(&:version).uniq end - # rubocop: enable CodeReuse/ActiveRecord def stats @users_statistics = UsersStatistics.latest diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 4d163824ef6..2ae0442c005 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -108,6 +108,7 @@ class Admin::GroupsController < Admin::ApplicationController :visibility_level, :require_two_factor_authentication, :two_factor_grace_period, + :enabled_git_access_protocol, :project_creation_level, :subgroup_creation_level, admin_note_attributes: [ diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 02e33baaf07..24d7bd9ca7b 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -98,3 +98,5 @@ class Admin::RunnersController < Admin::ApplicationController end # rubocop: enable CodeReuse/ActiveRecord end + +Admin::RunnersController.prepend_mod diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 6b11b8eda5c..874eb8985fb 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -9,7 +9,7 @@ class Admin::UsersController < Admin::ApplicationController before_action :ensure_destroy_prerequisites_met, only: [:destroy] before_action :check_ban_user_feature_flag, only: [:ban] - feature_category :users + feature_category :user_management PAGINATION_WITH_COUNT_LIMIT = 1000 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4fc96752507..30760d472a4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base include FlocOptOut include CheckRateLimit + before_action :limit_session_time, if: -> { !current_user } before_action :authenticate_user!, except: [:route_not_found] before_action :enforce_terms!, if: :should_enforce_terms? before_action :validate_user_service_ticket! @@ -43,7 +44,6 @@ class ApplicationController < ActionController::Base # Make sure the `auth_user` is memoized so it can be logged, we do this after # all other before filters that could have set the user. before_action :auth_user - before_action :limit_session_time, if: -> { !current_user } prepend_around_action :set_current_context diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index f84d2ed320d..32d1ddf920e 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -62,7 +62,9 @@ class AutocompleteController < ApplicationController def deploy_keys_with_owners deploy_keys = DeployKey.with_write_access_for_project(project) - render json: DeployKeySerializer.new.represent(deploy_keys, { with_owner: true, user: current_user }) + render json: DeployKeys::BasicDeployKeySerializer.new.represent( + deploy_keys, { with_owner: true, user: current_user } + ) end private diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index ae3b6125bde..a04fd09aa22 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -8,7 +8,7 @@ class Clusters::ClustersController < Clusters::BaseController before_action :cluster, only: [:cluster_status, :show, :update, :destroy, :clear_cache] before_action :user_cluster, only: [:connect] before_action :authorize_read_cluster!, only: [:show, :index] - before_action :authorize_create_cluster!, only: [:connect, :authorize_aws_role] + before_action :authorize_create_cluster!, only: [:connect] before_action :authorize_update_cluster!, only: [:update] before_action :update_applications_status, only: [:cluster_status] before_action :ensure_feature_enabled!, except: [:index, :new_cluster_docs] @@ -16,15 +16,6 @@ class Clusters::ClustersController < Clusters::BaseController helper_method :token_in_session STATUS_POLLING_INTERVAL = 10_000 - AWS_CSP_DOMAINS = %w[https://ec2.ap-east-1.amazonaws.com https://ec2.ap-northeast-1.amazonaws.com https://ec2.ap-northeast-2.amazonaws.com https://ec2.ap-northeast-3.amazonaws.com https://ec2.ap-south-1.amazonaws.com https://ec2.ap-southeast-1.amazonaws.com https://ec2.ap-southeast-2.amazonaws.com https://ec2.ca-central-1.amazonaws.com https://ec2.eu-central-1.amazonaws.com https://ec2.eu-north-1.amazonaws.com https://ec2.eu-west-1.amazonaws.com https://ec2.eu-west-2.amazonaws.com https://ec2.eu-west-3.amazonaws.com https://ec2.me-south-1.amazonaws.com https://ec2.sa-east-1.amazonaws.com https://ec2.us-east-1.amazonaws.com https://ec2.us-east-2.amazonaws.com https://ec2.us-west-1.amazonaws.com https://ec2.us-west-2.amazonaws.com https://ec2.af-south-1.amazonaws.com https://iam.amazonaws.com].freeze - - content_security_policy do |p| - next if p.directives.blank? - - default_connect_src = p.directives['connect-src'] || p.directives['default-src'] - connect_src_values = Array.wrap(default_connect_src) | AWS_CSP_DOMAINS - p.connect_src(*connect_src_values) - end def index @clusters = cluster_list @@ -95,19 +86,6 @@ class Clusters::ClustersController < Clusters::BaseController redirect_to clusterable.index_path, status: :found end - def create_aws - @aws_cluster = ::Clusters::CreateService - .new(current_user, create_aws_cluster_params) - .execute - .present(current_user: current_user) - - if @aws_cluster.persisted? - head :created, location: @aws_cluster.show_path - else - render status: :unprocessable_entity, json: @aws_cluster.errors - end - end - def create_user @user_cluster = ::Clusters::CreateService .new(current_user, create_user_cluster_params) @@ -117,23 +95,10 @@ class Clusters::ClustersController < Clusters::BaseController if @user_cluster.persisted? redirect_to @user_cluster.show_path else - generate_gcp_authorize_url - validate_gcp_token - gcp_cluster - render :connect end end - def authorize_aws_role - response = Clusters::Aws::AuthorizeRoleService.new( - current_user, - params: aws_role_params - ).execute - - render json: response.body, status: response.status - end - def clear_cache cluster.delete_cached_resources! @@ -204,27 +169,6 @@ class Clusters::ClustersController < Clusters::BaseController end end - def create_aws_cluster_params - params.require(:cluster).permit( - *base_permitted_cluster_params, - :name, - provider_aws_attributes: [ - :kubernetes_version, - :key_name, - :role_arn, - :region, - :vpc_id, - :instance_type, - :num_nodes, - :security_group_id, - subnet_ids: [] - ]).merge( - provider_type: :aws, - platform_type: :kubernetes, - clusterable: clusterable.__subject__ - ) - end - def create_user_cluster_params params.require(:cluster).permit( *base_permitted_cluster_params, @@ -242,29 +186,6 @@ class Clusters::ClustersController < Clusters::BaseController ) end - def aws_role_params - params.require(:cluster).permit(:role_arn, :region) - end - - def generate_gcp_authorize_url - connect_path = clusterable.connect_path().to_s - error_path = @project ? project_clusters_path(@project) : connect_path - - state = generate_session_key_redirect(connect_path, error_path) - - @authorize_url = GoogleApi::CloudPlatform::Client.new( - nil, callback_google_api_auth_url, - state: state).authorize_url - rescue GoogleApi::Auth::ConfigMissingError - # no-op - end - - def gcp_cluster - cluster = Clusters::BuildService.new(clusterable.__subject__).execute - cluster.build_provider_gcp - @gcp_cluster = cluster.present(current_user: current_user) - end - def proxyable cluster.cluster end @@ -295,11 +216,6 @@ class Clusters::ClustersController < Clusters::BaseController @user_cluster = cluster.present(current_user: current_user) end - def validate_gcp_token - @valid_gcp_token = GoogleApi::CloudPlatform::Client.new(token_in_session, nil) - .validate_token(expires_at_in_session) - end - def token_in_session session[GoogleApi::CloudPlatform::Client.session_key_for_token] end @@ -309,26 +225,6 @@ class Clusters::ClustersController < Clusters::BaseController session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] end - def generate_session_key_redirect(uri, error_uri) - GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key| - session[key] = uri - session[:error_uri] = error_uri - end - end - - ## - # Unfortunately the EC2 API doesn't provide a list of - # possible instance types. There is a workaround, using - # the Pricing API, but instead of requiring the - # user to grant extra permissions for this we use the - # values that validate the CloudFormation template. - def load_instance_types - stack_template = File.read(Rails.root.join('vendor', 'aws', 'cloudformation', 'eks_cluster.yaml')) - instance_types = YAML.safe_load(stack_template).dig('Parameters', 'NodeInstanceType', 'AllowedValues') - - instance_types.map { |type| Hash(name: type, value: type) } - end - def update_applications_status @cluster.applications.each(&:schedule_status_update) end diff --git a/app/controllers/concerns/gitlab_recaptcha.rb b/app/controllers/concerns/gitlab_recaptcha.rb index 15e856463ea..cedadba5fc7 100644 --- a/app/controllers/concerns/gitlab_recaptcha.rb +++ b/app/controllers/concerns/gitlab_recaptcha.rb @@ -17,6 +17,9 @@ module GitlabRecaptcha flash.delete :recaptcha_error self.resource = resource_class.new + + add_gon_variables + render action: 'new' end end diff --git a/app/controllers/concerns/integrations/actions.rb b/app/controllers/concerns/integrations/actions.rb index 1f788860c8f..e0a12555e11 100644 --- a/app/controllers/concerns/integrations/actions.rb +++ b/app/controllers/concerns/integrations/actions.rb @@ -51,11 +51,9 @@ module Integrations::Actions private - # rubocop:disable Gitlab/ModuleWithInstanceVariables def integration @integration ||= find_or_initialize_non_project_specific_integration(params[:id]) end - # rubocop:enable Gitlab/ModuleWithInstanceVariables def success_message if integration.active? diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index 4d3eb9cd183..07850acd23d 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -184,7 +184,8 @@ module IssuableActions def paginated_discussions return if params[:per_page].blank? - return unless issuable.instance_of?(Issue) && Feature.enabled?(:paginated_issue_discussions, project) + return if issuable.instance_of?(Issue) && Feature.disabled?(:paginated_issue_discussions, project) + return if issuable.instance_of?(MergeRequest) && Feature.disabled?(:paginated_mr_discussions, project) strong_memoize(:paginated_discussions) do issuable diff --git a/app/controllers/concerns/issues_calendar.rb b/app/controllers/concerns/issues_calendar.rb index 1fdfde4c869..51d6d3cf05a 100644 --- a/app/controllers/concerns/issues_calendar.rb +++ b/app/controllers/concerns/issues_calendar.rb @@ -4,7 +4,6 @@ module IssuesCalendar extend ActiveSupport::Concern # rubocop:disable Gitlab/ModuleWithInstanceVariables - # rubocop: disable CodeReuse/ActiveRecord def render_issues_calendar(issuables) @issues = issuables .non_archived @@ -23,6 +22,5 @@ module IssuesCalendar end end end - # rubocop: enable CodeReuse/ActiveRecord # rubocop:enable Gitlab/ModuleWithInstanceVariables end diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 0b9024dc3db..fb11bece79c 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -143,8 +143,8 @@ module MembershipActions raise NotImplementedError end - def requested_relations - case params[:with_inherited_permissions].presence + def requested_relations(inherited_permissions = :with_inherited_permissions) + case params[inherited_permissions].presence when 'exclude' [:direct] when 'only' diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index 55b6747fcfb..928c617471b 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -6,8 +6,7 @@ module NotesActions extend ActiveSupport::Concern # last_fetched_at is an integer number of microseconds, which is the same - # precision as PostgreSQL "timestamp" fields. It's important for them to have - # identical precision for accurate pagination + # precision as PostgreSQL "timestamp" fields. MICROSECOND = 1_000_000 included do @@ -23,7 +22,7 @@ module NotesActions end def index - notes, meta = gather_notes + notes, meta = gather_all_notes notes = prepare_notes_for_rendering(notes) notes = notes.select { |n| n.readable_by?(current_user) } notes = @@ -33,11 +32,7 @@ module NotesActions notes.map { |note| note_json(note) } end - # We know there's more data, so tell the frontend to poll again after 1ms - set_polling_interval_header(interval: 1) if meta[:more] - - # Only present an ETag for the empty response to ensure pagination works - # as expected + # Only present an ETag for the empty response ::Gitlab::EtagCaching::Middleware.skip!(response) if notes.present? render json: meta.merge(notes: notes) @@ -105,17 +100,6 @@ module NotesActions private - # Lower bound (last_fetched_at as specified in the request) is already set in - # the finder. Here, we select between returning all notes since then, or a - # page's worth of notes. - def gather_notes - if Feature.enabled?(:paginated_notes, noteable.try(:resource_parent)) - gather_some_notes - else - gather_all_notes - end - end - def gather_all_notes now = Time.current notes = merge_resource_events(notes_finder.execute.inc_relations_for_view) @@ -123,27 +107,11 @@ module NotesActions [notes, { last_fetched_at: (now.to_i * MICROSECOND) + now.usec }] end - def gather_some_notes - paginator = ::Gitlab::UpdatedNotesPaginator.new( - notes_finder.execute.inc_relations_for_view, - last_fetched_at: last_fetched_at - ) - - notes = paginator.notes - - # Fetch all the synthetic notes in the same time range as the real notes. - # Although we don't limit the number, their text is under our control so - # should be fairly cheap to process. - notes = merge_resource_events(notes, fetch_until: paginator.next_fetched_at) - - [notes, paginator.metadata] - end - - def merge_resource_events(notes, fetch_until: nil) + def merge_resource_events(notes) return notes if notes_filter == UserPreference::NOTES_FILTERS[:only_comments] ResourceEvents::MergeIntoNotesService - .new(noteable, current_user, last_fetched_at: last_fetched_at, fetch_until: fetch_until) + .new(noteable, current_user, last_fetched_at: last_fetched_at) .execute(notes) end diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb index 4021ff83578..0b51b3dd380 100644 --- a/app/controllers/concerns/product_analytics_tracking.rb +++ b/app/controllers/concerns/product_analytics_tracking.rb @@ -20,8 +20,17 @@ module ProductAnalyticsTracking def route_events_to(destinations, name, &block) track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll) - if destinations.include?(:snowplow) && Feature.enabled?(:route_hll_to_snowplow, tracking_namespace_source) + if destinations.include?(:snowplow) && event_enabled?(name) Gitlab::Tracking.event(self.class.to_s, name, namespace: tracking_namespace_source, user: current_user) end end + + def event_enabled?(event) + events_to_ff = { + g_analytics_valuestream: :route_hll_to_snowplow, + i_search_paid: :route_hll_to_snowplow_phase2 + } + + Feature.enabled?(events_to_ff[event.to_sym], tracking_namespace_source) + end end diff --git a/app/controllers/concerns/project_stats_refresh_conflicts_guard.rb b/app/controllers/concerns/project_stats_refresh_conflicts_guard.rb new file mode 100644 index 00000000000..a3349997dbd --- /dev/null +++ b/app/controllers/concerns/project_stats_refresh_conflicts_guard.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ProjectStatsRefreshConflictsGuard + extend ActiveSupport::Concern + + def reject_if_build_artifacts_size_refreshing! + return unless project.refreshing_build_artifacts_size? + + Gitlab::ProjectStatsRefreshConflictsLogger.warn_request_rejected_during_stats_refresh(project.id) + + render_409('Action temporarily disabled. The project this pipeline belongs to is undergoing stats refresh.') + end +end diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb index 0ee8d0c9307..1bb81a46e50 100644 --- a/app/controllers/concerns/snippets_actions.rb +++ b/app/controllers/concerns/snippets_actions.rb @@ -75,7 +75,6 @@ module SnippetsActions private - # rubocop:disable Gitlab/ModuleWithInstanceVariables def blob @blob ||= blobs.first end @@ -87,7 +86,6 @@ module SnippetsActions snippet.blobs end end - # rubocop:enable Gitlab/ModuleWithInstanceVariables def convert_line_endings(content) params[:line_ending] == 'raw' ? content : content.gsub(/\r\n/, "\n") diff --git a/app/controllers/concerns/sorting_preference.rb b/app/controllers/concerns/sorting_preference.rb index 8d8845e2f41..6278b489028 100644 --- a/app/controllers/concerns/sorting_preference.rb +++ b/app/controllers/concerns/sorting_preference.rb @@ -5,10 +5,12 @@ module SortingPreference include CookiesHelper def set_sort_order(field = sorting_field, default_order = default_sort_order) - set_sort_order_from_user_preference(field) || - set_sort_order_from_cookie(field) || - params[:sort] || - default_order + sort_order = set_sort_order_from_user_preference(field) || set_sort_order_from_cookie(field) || params[:sort] + + # some types of sorting might not be available on the dashboard + return default_order unless valid_sort_order?(sort_order) + + sort_order end # Implement sorting_field method on controllers @@ -85,4 +87,11 @@ module SortingPreference else value end end + + def valid_sort_order?(sort_order) + return false unless sort_order + return can_sort_by_issue_weight?(action_name == 'issues') if sort_order.include?('weight') + + true + end end diff --git a/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb b/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb index b254916cdd6..707c1e6c84f 100644 --- a/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb +++ b/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb @@ -32,3 +32,5 @@ module SpammableActions::CaptchaCheck::HtmlFormatActionsSupport request.headers['X-GitLab-Spam-Log-Id'] = params[:spam_log_id] if params[:spam_log_id] end end + +SpammableActions::CaptchaCheck::HtmlFormatActionsSupport.prepend_mod diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index 9fc8886aaee..83447744013 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -167,7 +167,7 @@ module WikiActions render 'shared/wikis/diff' end - # rubocop:disable Gitlab/ModuleWithInstanceVariables + # rubocop:enable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables def destroy diff --git a/app/controllers/concerns/zuora_csp.rb b/app/controllers/concerns/zuora_csp.rb new file mode 100644 index 00000000000..5f9be11d7b9 --- /dev/null +++ b/app/controllers/concerns/zuora_csp.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module ZuoraCSP + extend ActiveSupport::Concern + + ZUORA_URL = 'https://*.zuora.com' + + included do + content_security_policy do |policy| + next if policy.directives.blank? + + default_script_src = policy.directives['script-src'] || policy.directives['default-src'] + script_src_values = Array.wrap(default_script_src) | ["'self'", "'unsafe-eval'", ZUORA_URL] + + default_frame_src = policy.directives['frame-src'] || policy.directives['default-src'] + frame_src_values = Array.wrap(default_frame_src) | ["'self'", ZUORA_URL] + + default_child_src = policy.directives['child-src'] || policy.directives['default-src'] + child_src_values = Array.wrap(default_child_src) | ["'self'", ZUORA_URL] + + policy.script_src(*script_src_values) + policy.frame_src(*frame_src_values) + policy.child_src(*child_src_values) + end + end +end diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index dd30d688fa8..704453fbf44 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -8,7 +8,7 @@ class ConfirmationsController < Devise::ConfirmationsController prepend_before_action :check_recaptcha, only: :create before_action :load_recaptcha, only: :new - feature_category :users + feature_category :authentication_and_authorization def almost_there flash[:notice] = nil diff --git a/app/controllers/groups/autocomplete_sources_controller.rb b/app/controllers/groups/autocomplete_sources_controller.rb index a2eb475d360..171494e66bd 100644 --- a/app/controllers/groups/autocomplete_sources_controller.rb +++ b/app/controllers/groups/autocomplete_sources_controller.rb @@ -5,8 +5,7 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController feature_category :team_planning, [:issues, :labels, :milestones, :commands] feature_category :code_review, [:merge_requests] - urgency :low, [:issues, :labels, :milestones, :commands] - urgency :low, [:merge_requests] + urgency :low, [:issues, :labels, :milestones, :commands, :merge_requests, :members] def members render json: ::Groups::ParticipantsService.new(@group, current_user).execute(target) diff --git a/app/controllers/groups/email_campaigns_controller.rb b/app/controllers/groups/email_campaigns_controller.rb index 70c8a23d918..38087e3fc11 100644 --- a/app/controllers/groups/email_campaigns_controller.rb +++ b/app/controllers/groups/email_campaigns_controller.rb @@ -4,6 +4,7 @@ class Groups::EmailCampaignsController < Groups::ApplicationController EMAIL_CAMPAIGNS_SCHEMA_URL = 'iglu:com.gitlab/email_campaigns/jsonschema/1-0-0' feature_category :navigation + urgency :low before_action :check_params diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index b95d8c87a4a..f0b857ca4c9 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -25,10 +25,8 @@ class Groups::GroupMembersController < Groups::ApplicationController urgency :low def index - push_frontend_feature_flag(:group_member_inherited_group, @group) - @sort = params[:sort].presence || sort_value_name - @include_relations ||= requested_relations + @include_relations ||= requested_relations(:groups_with_inherited_permissions) if can?(current_user, :admin_group_member, @group) @invited_members = invited_members diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index 8d687bf3c2c..aeb54527c69 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -41,3 +41,5 @@ class Groups::RunnersController < Groups::ApplicationController params.require(:runner).permit(Ci::Runner::FORM_EDITABLE) end end + +Groups::RunnersController.prepend_mod diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 4b75cec19f7..b1afac1f1c7 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -9,6 +9,7 @@ module Groups before_action :authorize_update_max_artifacts_size!, only: [:update] before_action :define_variables, only: [:show] before_action :push_licensed_features, only: [:show] + before_action :assign_variables_to_gon, only: [:show] feature_category :continuous_integration urgency :low @@ -81,6 +82,10 @@ module Groups # Overridden in EE def push_licensed_features end + + # Overridden in EE + def assign_variables_to_gon + end end end end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index d46cf899d8c..327b4832f31 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -30,10 +30,6 @@ class GroupsController < Groups::ApplicationController before_action :user_actions, only: [:show] - before_action do - push_frontend_feature_flag(:vue_issues_list, @group) - end - before_action :check_export_rate_limit!, only: [:export, :download_export] before_action :track_experiment_event, only: [:new] @@ -212,7 +208,7 @@ class GroupsController < Groups::ApplicationController end def issues - return super if !html_request? || Feature.disabled?(:vue_issues_list, group) + return super unless html_request? @has_issues = IssuesFinder.new(current_user, group_id: group.id, include_subgroups: true).execute .non_archived @@ -289,6 +285,7 @@ class GroupsController < Groups::ApplicationController :chat_team_name, :require_two_factor_authentication, :two_factor_grace_period, + :enabled_git_access_protocol, :project_creation_level, :subgroup_creation_level, :default_branch_protection, @@ -360,6 +357,7 @@ class GroupsController < Groups::ApplicationController flash[:alert] = _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.') flash.delete :recaptcha_error @group = Group.new(group_params) + add_gon_variables render action: 'new' end diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index 5be2d7527ff..1508531828d 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -13,7 +13,7 @@ class HelpController < ApplicationController def index # Remove YAML frontmatter so that it doesn't look weird - @help_index = File.read(Rails.root.join('doc', 'index.md')).sub(YAML_FRONT_MATTER_REGEXP, '') + @help_index = File.read(path_to_doc('index.md')).sub(YAML_FRONT_MATTER_REGEXP, '') # Prefix Markdown links with `help/` unless they are external links. # '//' not necessarily part of URL, e.g., mailto:mail@example.com @@ -24,7 +24,7 @@ class HelpController < ApplicationController end def show - @path = Rack::Utils.clean_path_info(path_params[:path]) + @path = Rack::Utils.clean_path_info(params[:path]) respond_to do |format| format.any(:markdown, :md, :html) do @@ -38,7 +38,7 @@ class HelpController < ApplicationController # Allow access to specific media files in the doc folder format.any(:png, :gif, :jpeg, :mp4, :mp3) do # Note: We are purposefully NOT using `Rails.root.join` because of https://gitlab.com/gitlab-org/gitlab/-/issues/216028. - path = File.join(Rails.root, 'doc', "#{@path}.#{params[:format]}") + path = path_to_doc("#{@path}.#{params[:format]}") if File.exist?(path) send_file(path, disposition: 'inline') @@ -61,16 +61,8 @@ class HelpController < ApplicationController private - def path_params - params.require(:path) - - params - end - def redirect_to_documentation_website? - return false unless Gitlab::UrlSanitizer.valid_web?(documentation_url) - - true + Gitlab::UrlSanitizer.valid_web?(documentation_url) end def documentation_url @@ -105,18 +97,22 @@ class HelpController < ApplicationController def render_documentation # Note: We are purposefully NOT using `Rails.root.join` because of https://gitlab.com/gitlab-org/gitlab/-/issues/216028. - path = File.join(Rails.root, 'doc', "#{@path}.md") + path = path_to_doc("#{@path}.md") if File.exist?(path) # Remove YAML frontmatter so that it doesn't look weird @markdown = File.read(path).gsub(YAML_FRONT_MATTER_REGEXP, '') - render 'show.html.haml' + render :show, formats: :html else # Force template to Haml - render 'errors/not_found.html.haml', layout: 'errors', status: :not_found + render 'errors/not_found', layout: 'errors', status: :not_found, formats: :html end end + + def path_to_doc(file_name) + File.join(Rails.root, 'doc', file_name) + end end ::HelpController.prepend_mod diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index 2bcbf88039b..9fcb8385312 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -22,6 +22,11 @@ class IdeController < ApplicationController def index Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count + + if project && Feature.enabled?(:route_hll_to_snowplow_phase2, project&.namespace) + Gitlab::Tracking.event(self.class.to_s, 'web_ide_views', + namespace: project&.namespace, user: current_user) + end end private diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index c223d9d211e..b949a99c250 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -44,7 +44,6 @@ class Import::FogbugzController < Import::BaseController redirect_to status_import_fogbugz_path end - # rubocop: disable CodeReuse/ActiveRecord def status unless client.valid? return redirect_to new_import_fogbugz_path @@ -52,19 +51,18 @@ class Import::FogbugzController < Import::BaseController super end - # rubocop: enable CodeReuse/ActiveRecord def create - repo = client.repo(params[:repo_id]) - fb_session = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] } + credentials = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] } + umap = session[:fogbugz_user_map] || client.user_map - project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, current_user.namespace, current_user, umap).execute + result = Import::FogbugzService.new(client, current_user, params.merge(umap: umap)).execute(credentials) - if project.persisted? - render json: ProjectSerializer.new.represent(project, serializer: :import) + if result[:status] == :success + render json: ProjectSerializer.new.represent(result[:project], serializer: :import) else - render json: { errors: project_save_error(project) }, status: :unprocessable_entity + render json: { errors: result[:message] }, status: result[:http_status] end end diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb index 4b4ac07b389..399a92c59e0 100644 --- a/app/controllers/import/gitea_controller.rb +++ b/app/controllers/import/gitea_controller.rb @@ -7,7 +7,7 @@ class Import::GiteaController < Import::GithubController def new if session[access_token_key].present? && provider_url.present? - redirect_to status_import_url + redirect_to status_import_url(namespace_id: params[:namespace_id]) end end diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 9bd8f893614..8dd40b6254e 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -76,12 +76,10 @@ class Import::GithubController < Import::BaseController protected - # rubocop: disable CodeReuse/ActiveRecord override :importable_repos def importable_repos client_repos.to_a end - # rubocop: enable CodeReuse/ActiveRecord override :incompatible_repos def incompatible_repos diff --git a/app/controllers/jira_connect/oauth_application_ids_controller.rb b/app/controllers/jira_connect/oauth_application_ids_controller.rb new file mode 100644 index 00000000000..05c23210da2 --- /dev/null +++ b/app/controllers/jira_connect/oauth_application_ids_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module JiraConnect + class OauthApplicationIdsController < ::ApplicationController + feature_category :integrations + + skip_before_action :authenticate_user! + + def show + if Feature.enabled?(:jira_connect_oauth_self_managed) && jira_connect_application_key.present? + render json: { application_id: jira_connect_application_key } + else + head :not_found + end + end + + private + + def jira_connect_application_key + Gitlab::CurrentSettings.jira_connect_application_key.presence + end + end +end diff --git a/app/controllers/jwks_controller.rb b/app/controllers/jwks_controller.rb index 3b0e6ca2eb1..d3a8d3dafea 100644 --- a/app/controllers/jwks_controller.rb +++ b/app/controllers/jwks_controller.rb @@ -13,10 +13,6 @@ class JwksController < Doorkeeper::OpenidConnect::DiscoveryController def payload [ - # We keep openid_connect_signing_key so that we can seamlessly - # replace it with ci_jwt_signing_key and remove it on the next release. - # TODO: Remove openid_connect_signing_key in 13.7 - # https://gitlab.com/gitlab-org/gitlab/-/issues/221031 Rails.application.secrets.openid_connect_signing_key, Gitlab::CurrentSettings.ci_jwt_signing_key ].compact.map do |key_data| diff --git a/app/controllers/mailgun/webhooks_controller.rb b/app/controllers/mailgun/webhooks_controller.rb new file mode 100644 index 00000000000..f7cb3eaa8ee --- /dev/null +++ b/app/controllers/mailgun/webhooks_controller.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Mailgun + class WebhooksController < ApplicationController + respond_to :json + + skip_before_action :authenticate_user! + skip_before_action :verify_authenticity_token + + before_action :ensure_feature_enabled! + before_action :authenticate_signature! + + feature_category :team_planning + + WEBHOOK_PROCESSORS = [ + Gitlab::Mailgun::WebhookProcessors::FailureLogger, + Gitlab::Mailgun::WebhookProcessors::MemberInvites + ].freeze + + def process_webhook + WEBHOOK_PROCESSORS.each do |processor_class| + processor_class.new(params['event-data']).execute + end + + head :ok + end + + private + + def ensure_feature_enabled! + render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled? + end + + def authenticate_signature! + access_denied! unless valid_signature? + end + + def valid_signature? + return false if Gitlab::CurrentSettings.mailgun_signing_key.blank? + + # per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks + digest = OpenSSL::Digest.new('SHA256') + data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join + + hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data) + + ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest) + end + + def render_406 + # failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks + head :not_acceptable + end + end +end diff --git a/app/controllers/members/mailgun/permanent_failures_controller.rb b/app/controllers/members/mailgun/permanent_failures_controller.rb deleted file mode 100644 index 685faa34694..00000000000 --- a/app/controllers/members/mailgun/permanent_failures_controller.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -module Members - module Mailgun - class PermanentFailuresController < ApplicationController - respond_to :json - - skip_before_action :authenticate_user! - skip_before_action :verify_authenticity_token - - before_action :ensure_feature_enabled! - before_action :authenticate_signature! - before_action :validate_invite_email! - - feature_category :authentication_and_authorization - - def create - webhook_processor.execute - - head :ok - end - - private - - def ensure_feature_enabled! - render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled? - end - - def authenticate_signature! - access_denied! unless valid_signature? - end - - def valid_signature? - return false if Gitlab::CurrentSettings.mailgun_signing_key.blank? - - # per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks - digest = OpenSSL::Digest.new('SHA256') - data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join - - hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data) - - ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest) - end - - def validate_invite_email! - # permanent_failures webhook does not provide a way to filter failures, so we'll get them all on this endpoint - # and we only care about our invite_emails - render_406 unless payload[:tags]&.include?(::Members::Mailgun::INVITE_EMAIL_TAG) - end - - def webhook_processor - ::Members::Mailgun::ProcessWebhookService.new(payload) - end - - def payload - @payload ||= params.permit!['event-data'] - end - - def render_406 - # failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks - head :not_acceptable - end - end - end -end diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index 0817813f967..c9c51289d3a 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -19,6 +19,9 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController session.delete(:user_return_to) render "doorkeeper/authorizations/redirect", locals: { redirect_uri: parsed_redirect_uri }, layout: false else + redirect_uri = URI(authorization.authorize.redirect_uri) + allow_redirect_uri_form_action(redirect_uri.scheme) + render "doorkeeper/authorizations/new" end else @@ -28,6 +31,20 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController private + # Chrome blocks redirections if the form-action CSP directive is present + # and the redirect location's scheme isn't allow-listed + # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/form-action + # https://github.com/w3c/webappsec-csp/issues/8 + def allow_redirect_uri_form_action(redirect_uri_scheme) + return unless content_security_policy? + + form_action = request.content_security_policy.form_action + return unless form_action + + form_action.push("#{redirect_uri_scheme}:") + request.content_security_policy.form_action(*form_action) + end + def pre_auth_params # Cannot be achieved with a before_action hook, due to the execution order. downgrade_scopes! if action_name == 'new' diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 927b50245a4..45decccfc36 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -178,6 +178,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController flash[:notice] = _('Welcome back! Your account had been deactivated due to inactivity but is now reactivated.') end + store_after_sign_up_path_for_user if intent_to_register? sign_in_and_redirect(user, event: :authentication) end else @@ -259,6 +260,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController (request_params['remember_me'] == '1') if request_params.present? end + def intent_to_register? + request_params = request.env['omniauth.params'] + (request_params['intent'] == 'register') if request_params.present? + end + def store_redirect_fragment(redirect_fragment) key = stored_location_key_for(:user) location = session[key] @@ -291,6 +297,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def fail_admin_mode_invalid_credentials redirect_to new_admin_session_path, alert: _('Invalid login or password') end + + def store_after_sign_up_path_for_user + store_location_for(:user, users_sign_up_welcome_path) + end end OmniauthCallbacksController.prepend_mod_with('OmniauthCallbacksController') diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb index 83eabbb736e..cb8b2783000 100644 --- a/app/controllers/profiles/accounts_controller.rb +++ b/app/controllers/profiles/accounts_controller.rb @@ -3,7 +3,7 @@ class Profiles::AccountsController < Profiles::ApplicationController include AuthHelper - feature_category :users + feature_category :authentication_and_authorization urgency :low, [:show] def show diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb index aafd7c2b65b..2607ba7d404 100644 --- a/app/controllers/profiles/active_sessions_controller.rb +++ b/app/controllers/profiles/active_sessions_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Profiles::ActiveSessionsController < Profiles::ApplicationController - feature_category :users + feature_category :authentication_and_authorization def index @sessions = ActiveSession.list(current_user).reject(&:is_impersonated) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index ad2e384077a..265fa505b2a 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -24,11 +24,10 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController @personal_access_token = result.payload[:personal_access_token] if result.success? - PersonalAccessToken.redis_store!(current_user.id, @personal_access_token.token) - redirect_to profile_personal_access_tokens_path, notice: _("Your new personal access token has been created.") + render json: { new_token: @personal_access_token.token, + active_access_tokens: active_personal_access_tokens }, status: :ok else - set_index_vars - render :index + render json: { errors: result.errors }, status: :unprocessable_entity end end @@ -52,14 +51,11 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def set_index_vars @scopes = Gitlab::Auth.available_scopes_for(current_user) - - @inactive_personal_access_tokens = finder(state: 'inactive').execute @active_personal_access_tokens = active_personal_access_tokens - - @new_personal_access_token = PersonalAccessToken.redis_getdel(current_user.id) end def active_personal_access_tokens - finder(state: 'active', sort: 'expires_at_asc').execute + tokens = finder(state: 'active', sort: 'expires_at_asc').execute + ::API::Entities::PersonalAccessTokenWithDetails.represent(tokens) end end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index d5e7195a157..dd1ac526b89 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -14,7 +14,10 @@ class ProfilesController < Profiles::ApplicationController push_frontend_feature_flag(:webauthn) end - feature_category :users + feature_category :users, [:show, :update, :reset_incoming_email_token, :reset_feed_token, + :reset_static_object_token, :update_username] + + feature_category :authentication_and_authorization, [:audit_log] urgency :low, [:show, :update] def show diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index dbf3b2051fb..85e258b62e8 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -4,7 +4,7 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController before_action :check_can_collaborate! before_action do push_frontend_feature_flag(:schema_linting, @project) - push_frontend_feature_flag(:pipeline_editor_file_tree, @project) + push_frontend_feature_flag(:simulate_pipeline, @project) end feature_category :pipeline_authoring diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 60b8e45f5be..f4125fd0a15 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -84,7 +84,7 @@ class Projects::CommitsController < Projects::ApplicationController @commits.each(&:lazy_author) # preload authors - @commits = @commits.with_latest_pipeline(@ref) + @commits = @commits.with_markdown_cache.with_latest_pipeline(@ref) @commits = set_commits_for_rendering(@commits) end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 3ced5f21b24..09a06aaed8c 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -102,7 +102,11 @@ class Projects::CompareController < Projects::ApplicationController # source == head_ref == to def source_project - project + strong_memoize(:source_project) do + # Eager load project's avatar url to prevent batch loading + # for all forked projects + project&.tap(&:avatar_url) + end end def compare @@ -112,17 +116,24 @@ class Projects::CompareController < Projects::ApplicationController end def start_ref - @start_ref ||= Addressable::URI.unescape(compare_params[:from]) + @start_ref ||= Addressable::URI.unescape(compare_params[:from]).presence end def head_ref return @ref if defined?(@ref) - @ref = @head_ref = Addressable::URI.unescape(compare_params[:to]) + @ref = @head_ref = Addressable::URI.unescape(compare_params[:to]).presence end def define_commits - @commits = compare.present? ? set_commits_for_rendering(@compare.commits) : [] + strong_memoize(:commits) do + if compare.present? + commits = compare.commits.with_markdown_cache.with_latest_pipeline(head_ref) + set_commits_for_rendering(commits) + else + [] + end + end end def define_diffs diff --git a/app/controllers/projects/environments/prometheus_api_controller.rb b/app/controllers/projects/environments/prometheus_api_controller.rb index 94fe67b5e85..cbb16d596a0 100644 --- a/app/controllers/projects/environments/prometheus_api_controller.rb +++ b/app/controllers/projects/environments/prometheus_api_controller.rb @@ -6,6 +6,7 @@ class Projects::Environments::PrometheusApiController < Projects::ApplicationCon before_action :proxyable feature_category :metrics + urgency :low private diff --git a/app/controllers/projects/environments/sample_metrics_controller.rb b/app/controllers/projects/environments/sample_metrics_controller.rb index 3df20810cb3..80344c83ab7 100644 --- a/app/controllers/projects/environments/sample_metrics_controller.rb +++ b/app/controllers/projects/environments/sample_metrics_controller.rb @@ -2,6 +2,7 @@ class Projects::Environments::SampleMetricsController < Projects::ApplicationController feature_category :metrics + urgency :low def query result = Metrics::SampleMetricsService.new(params[:identifier], range_start: params[:start], range_end: params[:end]).query diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 1a2c0d64d19..ac3c85f3b40 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -207,7 +207,11 @@ class Projects::EnvironmentsController < Projects::ApplicationController private def deployments - environment.deployments.ordered.page(params[:page]) + environment + .deployments + .with_environment_page_associations + .ordered + .page(params[:page]) end def verify_api_request! diff --git a/app/controllers/projects/error_tracking/base_controller.rb b/app/controllers/projects/error_tracking/base_controller.rb index ffbe487d8a1..62b8b9f3c1a 100644 --- a/app/controllers/projects/error_tracking/base_controller.rb +++ b/app/controllers/projects/error_tracking/base_controller.rb @@ -4,6 +4,7 @@ class Projects::ErrorTracking::BaseController < Projects::ApplicationController POLLING_INTERVAL = 1_000 feature_category :error_tracking + urgency :low def set_polling_interval Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) diff --git a/app/controllers/projects/error_tracking/projects_controller.rb b/app/controllers/projects/error_tracking/projects_controller.rb index d59cbc25d25..531bd327e43 100644 --- a/app/controllers/projects/error_tracking/projects_controller.rb +++ b/app/controllers/projects/error_tracking/projects_controller.rb @@ -8,6 +8,7 @@ module Projects before_action :authorize_read_sentry_issue! feature_category :error_tracking + urgency :low def index service = ::ErrorTracking::ListProjectsService.new( diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb index 0d65431d870..980e9bdcdad 100644 --- a/app/controllers/projects/google_cloud/base_controller.rb +++ b/app/controllers/projects/google_cloud/base_controller.rb @@ -2,6 +2,7 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController feature_category :five_minute_production_app + urgency :low before_action :admin_project_google_cloud! before_action :google_oauth2_enabled! diff --git a/app/controllers/projects/grafana_api_controller.rb b/app/controllers/projects/grafana_api_controller.rb index 9c5d6c8ebc3..d5099367873 100644 --- a/app/controllers/projects/grafana_api_controller.rb +++ b/app/controllers/projects/grafana_api_controller.rb @@ -5,6 +5,7 @@ class Projects::GrafanaApiController < Projects::ApplicationController include MetricsDashboard feature_category :metrics + urgency :low def proxy result = ::Grafana::ProxyService.new( diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb index fd7ba7b5460..70eab792b40 100644 --- a/app/controllers/projects/incidents_controller.rb +++ b/app/controllers/projects/incidents_controller.rb @@ -7,7 +7,6 @@ class Projects::IncidentsController < Projects::ApplicationController before_action :authorize_read_issue! before_action :load_incident, only: [:show] before_action do - push_frontend_feature_flag(:incident_escalations, @project) push_frontend_feature_flag(:incident_timeline, @project) end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index b65616fdb3c..f974b16468c 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -20,10 +20,12 @@ class Projects::IssuesController < Projects::ApplicationController before_action :disable_query_limiting, only: [:create_merge_request, :move, :bulk_update] before_action :check_issues_available! before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } + before_action :redirect_if_task, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } + after_action :log_issue_show, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } before_action :set_issuables_index, if: ->(c) { - SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !vue_issues_list? + SET_ISSUABLES_INDEX_ONLY_ACTIONS.include?(c.action_name.to_sym) && !index_html_request? } # Allow write(create) issue @@ -39,7 +41,6 @@ class Projects::IssuesController < Projects::ApplicationController before_action :authorize_download_code!, only: [:related_branches] before_action do - push_frontend_feature_flag(:vue_issues_list, project&.group) push_frontend_feature_flag(:contacts_autocomplete, project&.group) push_frontend_feature_flag(:incident_timeline, project) end @@ -50,6 +51,8 @@ class Projects::IssuesController < Projects::ApplicationController push_frontend_feature_flag(:paginated_issue_discussions, project) push_frontend_feature_flag(:realtime_labels, project) push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?) + push_frontend_feature_flag(:work_items_mvc_2) + push_frontend_feature_flag(:work_items_hierarchy, project) end around_action :allow_gitaly_ref_name_caching, only: [:discussions] @@ -81,7 +84,7 @@ class Projects::IssuesController < Projects::ApplicationController attr_accessor :vulnerability_id def index - if vue_issues_list? + if index_html_request? set_sort_order else @issues = @issuables @@ -251,16 +254,14 @@ class Projects::IssuesController < Projects::ApplicationController end def service_desk - @issues = @issuables # rubocop:disable Gitlab/ModuleWithInstanceVariables - @users.push(User.support_bot) # rubocop:disable Gitlab/ModuleWithInstanceVariables + @issues = @issuables + @users.push(User.support_bot) end protected - def vue_issues_list? - action_name.to_sym == :index && - html_request? && - Feature.enabled?(:vue_issues_list, project&.group) + def index_html_request? + action_name.to_sym == :index && html_request? end def sorting_field @@ -403,6 +404,13 @@ class Projects::IssuesController < Projects::ApplicationController # Overridden in EE def create_vulnerability_issue_feedback(issue); end + + def redirect_if_task + return render_404 if issue.task? && !project.work_items_feature_flag_enabled? + return unless issue.task? + + redirect_to project_work_items_path(project, issue.id, params: request.query_parameters) + end end Projects::IssuesController.prepend_mod_with('Projects::IssuesController') diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 8c9f82b9dc1..9574c5d5849 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -3,6 +3,7 @@ class Projects::JobsController < Projects::ApplicationController include SendFileUpload include ContinueParams + include ProjectStatsRefreshConflictsGuard urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :status, :erase, :raw] @@ -19,6 +20,7 @@ class Projects::JobsController < Projects::ApplicationController before_action :verify_proxy_request!, only: :proxy_websocket_authorize before_action :push_jobs_table_vue, only: [:index] before_action :push_jobs_table_vue_search, only: [:index] + before_action :reject_if_build_artifacts_size_refreshing!, only: [:erase] before_action do push_frontend_feature_flag(:infinitely_collapsible_sections, @project) @@ -40,7 +42,6 @@ class Projects::JobsController < Projects::ApplicationController @builds = @builds.page(params[:page]).per(30).without_count end - # rubocop: disable CodeReuse/ActiveRecord def show respond_to do |format| format.html @@ -53,7 +54,6 @@ class Projects::JobsController < Projects::ApplicationController end end end - # rubocop: enable CodeReuse/ActiveRecord def trace @build.trace.being_watched! if @build.running? diff --git a/app/controllers/projects/logs_controller.rb b/app/controllers/projects/logs_controller.rb index 63d8981ef38..0f751db2064 100644 --- a/app/controllers/projects/logs_controller.rb +++ b/app/controllers/projects/logs_controller.rb @@ -8,6 +8,7 @@ module Projects before_action :ensure_deployments, only: %i(k8s elasticsearch) feature_category :logging + urgency :low def index return render_404 unless Feature.enabled?(:monitor_logging, project) diff --git a/app/controllers/projects/mattermosts_controller.rb b/app/controllers/projects/mattermosts_controller.rb index c4f4913a620..a4091ebdf4b 100644 --- a/app/controllers/projects/mattermosts_controller.rb +++ b/app/controllers/projects/mattermosts_controller.rb @@ -20,7 +20,7 @@ class Projects::MattermostsController < Projects::ApplicationController if result flash[:notice] = 'This service is now configured' - redirect_to edit_project_integration_path(@project, integration) + redirect_to edit_project_settings_integration_path(@project, integration) else flash[:alert] = message || 'Failed to configure service' redirect_to new_project_mattermost_path(@project) diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb index 686d2c1dc1f..db7557674b2 100644 --- a/app/controllers/projects/merge_requests/drafts_controller.rb +++ b/app/controllers/projects/merge_requests/drafts_controller.rb @@ -49,6 +49,10 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli def publish result = DraftNotes::PublishService.new(merge_request, current_user).execute(draft_note(allow_nil: true)) + if Feature.enabled?(:mr_review_submit_comment, @project) && create_note_params[:note] + Notes::CreateService.new(@project, current_user, create_note_params).execute + end + if result[:status] == :success head :ok else @@ -102,6 +106,15 @@ class Projects::MergeRequests::DraftsController < Projects::MergeRequests::Appli end end + def create_note_params + params.permit( + :note + ).tap do |create_params| + create_params[:noteable_type] = merge_request.class.name + create_params[:noteable_id] = merge_request.id + end + end + def prepare_notes_for_rendering(notes) return [] unless notes diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 458df40ece1..d420e136316 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -35,19 +35,19 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:file_identifier_hash) push_frontend_feature_flag(:merge_request_widget_graphql, project) push_frontend_feature_flag(:core_security_mr_widget_counts, project) - push_frontend_feature_flag(:paginated_notes, project) push_frontend_feature_flag(:confidential_notes, project) push_frontend_feature_flag(:restructured_mr_widget, project) push_frontend_feature_flag(:refactor_mr_widgets_extensions, project) + push_frontend_feature_flag(:refactor_code_quality_extension, project) push_frontend_feature_flag(:refactor_mr_widget_test_summary, project) push_frontend_feature_flag(:rebase_without_ci_ui, project) push_frontend_feature_flag(:issue_assignees_widget, @project) push_frontend_feature_flag(:realtime_labels, project) - push_frontend_feature_flag(:updated_diff_expansion_buttons, project) + push_frontend_feature_flag(:refactor_security_extension, @project) push_frontend_feature_flag(:mr_attention_requests, current_user) - push_frontend_feature_flag(:updated_mr_header, project) - push_frontend_feature_flag(:remove_diff_header_icons, project) push_frontend_feature_flag(:moved_mr_sidebar, project) + push_frontend_feature_flag(:paginated_mr_discussions, project) + push_frontend_feature_flag(:mr_review_submit_comment, project) end before_action do @@ -299,7 +299,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo def remove_wip @merge_request = ::MergeRequests::UpdateService - .new(project: project, current_user: current_user, params: { wip_event: 'unwip' }) + .new(project: project, current_user: current_user, params: { wip_event: 'ready' }) .execute(@merge_request) render json: serialize_widget(@merge_request) diff --git a/app/controllers/projects/metrics/dashboards/builder_controller.rb b/app/controllers/projects/metrics/dashboards/builder_controller.rb index 96ca6d89111..a6b57798923 100644 --- a/app/controllers/projects/metrics/dashboards/builder_controller.rb +++ b/app/controllers/projects/metrics/dashboards/builder_controller.rb @@ -7,6 +7,7 @@ module Projects before_action :authorize_metrics_dashboard! feature_category :metrics + urgency :low def panel_preview respond_to do |format| diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb index e305b018293..f2f276071a0 100644 --- a/app/controllers/projects/metrics_dashboard_controller.rb +++ b/app/controllers/projects/metrics_dashboard_controller.rb @@ -16,6 +16,7 @@ module Projects end feature_category :metrics + urgency :low def show if environment diff --git a/app/controllers/projects/performance_monitoring/dashboards_controller.rb b/app/controllers/projects/performance_monitoring/dashboards_controller.rb index 51a07c1b7a5..8acbc17aef3 100644 --- a/app/controllers/projects/performance_monitoring/dashboards_controller.rb +++ b/app/controllers/projects/performance_monitoring/dashboards_controller.rb @@ -13,6 +13,7 @@ module Projects end feature_category :metrics + urgency :low def create result = ::Metrics::Dashboard::CloneDashboardService.new(project, current_user, dashboard_params).execute diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index fa38fb209f0..a23d7fb3e6b 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -14,13 +14,11 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController feature_category :continuous_integration urgency :low - # rubocop: disable CodeReuse/ActiveRecord def index @scope = params[:scope] @all_schedules = Ci::PipelineSchedulesFinder.new(@project).execute @schedules = Ci::PipelineSchedulesFinder.new(@project).execute(scope: params[:scope]) end - # rubocop: enable CodeReuse/ActiveRecord def new @schedule = project.pipeline_schedules.new diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb index 8f0e20290fe..e5b2dd14f69 100644 --- a/app/controllers/projects/pipelines/tests_controller.rb +++ b/app/controllers/projects/pipelines/tests_controller.rb @@ -23,7 +23,7 @@ module Projects def show respond_to do |format| format.json do - if Feature.enabled?(:ci_test_report_artifacts_expired, project) && pipeline.has_expired_test_reports? + if pipeline.has_expired_test_reports? render json: { errors: 'Test report artifacts have expired' }, status: :not_found else render json: TestSuiteSerializer @@ -36,7 +36,6 @@ module Projects private - # rubocop: disable CodeReuse/ActiveRecord def builds @builds ||= pipeline.latest_builds.id_in(build_ids).presence || render_404 end @@ -56,7 +55,6 @@ module Projects suite end - # rubocop: enable CodeReuse/ActiveRecord end end end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 94865024688..adc3a912a91 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -3,6 +3,8 @@ class Projects::PipelinesController < Projects::ApplicationController include ::Gitlab::Utils::StrongMemoize include RedisTracking + include ProjectStatsRefreshConflictsGuard + include ZuoraCSP urgency :low, [ :index, :new, :builds, :show, :failures, :create, @@ -19,11 +21,10 @@ class Projects::PipelinesController < Projects::ApplicationController before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables] before_action :authorize_update_pipeline!, only: [:retry, :cancel] before_action :ensure_pipeline, only: [:show, :downloadable_artifacts] + before_action :reject_if_build_artifacts_size_refreshing!, only: [:destroy] before_action do push_frontend_feature_flag(:pipeline_tabs_vue, @project) - push_frontend_feature_flag(:downstream_retry_action, @project) - push_frontend_feature_flag(:failed_jobs_tab_vue, @project) end # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596 @@ -42,23 +43,6 @@ class Projects::PipelinesController < Projects::ApplicationController POLLING_INTERVAL = 10_000 - content_security_policy do |policy| - next if policy.directives.blank? - - default_script_src = policy.directives['script-src'] || policy.directives['default-src'] - script_src_values = Array.wrap(default_script_src) | ["'self'", "'unsafe-eval'", 'https://*.zuora.com'] - - default_frame_src = policy.directives['frame-src'] || policy.directives['default-src'] - frame_src_values = Array.wrap(default_frame_src) | ["'self'", 'https://*.zuora.com'] - - default_child_src = policy.directives['child-src'] || policy.directives['default-src'] - child_src_values = Array.wrap(default_child_src) | ["'self'", 'https://*.zuora.com'] - - policy.script_src(*script_src_values) - policy.frame_src(*frame_src_values) - policy.child_src(*child_src_values) - end - feature_category :continuous_integration, [ :charts, :show, :config_variables, :stage, :cancel, :retry, :builds, :dag, :failures, :status, diff --git a/app/controllers/projects/prometheus/alerts_controller.rb b/app/controllers/projects/prometheus/alerts_controller.rb index 5e1b9570fa0..c3dc17694d9 100644 --- a/app/controllers/projects/prometheus/alerts_controller.rb +++ b/app/controllers/projects/prometheus/alerts_controller.rb @@ -14,19 +14,11 @@ module Projects prepend_before_action :repository, :project_without_auth, only: [:notify] before_action :authorize_read_prometheus_alerts!, except: [:notify] - before_action :alert, only: [:show, :metrics_dashboard] + before_action :alert, only: [:metrics_dashboard] feature_category :incident_management urgency :low - def index - render json: serialize_as_json(alerts) - end - - def show - render json: serialize_as_json(alert) - end - def notify token = extract_alert_manager_token(request) result = notify_service.execute(token) diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index c5778ba15f2..db5471ea322 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -7,6 +7,7 @@ module Projects before_action :require_prometheus_metrics! feature_category :metrics + urgency :low def active_common respond_to do |format| @@ -66,7 +67,7 @@ module Projects ) if @metric.persisted? - redirect_to edit_project_integration_path(project, ::Integrations::Prometheus), + redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), notice: _('Metric was successfully added.') else render 'new' @@ -77,7 +78,7 @@ module Projects @metric = prometheus_metric if @metric.update(metrics_params) - redirect_to edit_project_integration_path(project, ::Integrations::Prometheus), + redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), notice: _('Metric was successfully updated.') else render 'edit' @@ -93,7 +94,7 @@ module Projects respond_to do |format| format.html do - redirect_to edit_project_integration_path(project, ::Integrations::Prometheus), status: :see_other + redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), status: :see_other end format.json do head :ok diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 1dfb71842bd..da414d068a6 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -18,11 +18,7 @@ class Projects::ReleasesController < Projects::ApplicationController require_non_empty_project end format.json do - if Feature.enabled?(:remove_sha_from_releases_json, project) - render json: ReleaseSerializer.new.represent(releases) - else - render json: releases - end + render json: ReleaseSerializer.new.represent(releases) end end end @@ -56,19 +52,11 @@ class Projects::ReleasesController < Projects::ApplicationController end def release - @release ||= project.releases.find_by_tag!(sanitized_tag_name) + @release ||= project.releases.find_by_tag!(params[:tag]) end def link - release.links.find_by_filepath!(sanitized_filepath) - end - - def sanitized_filepath - "/#{CGI.unescape(params[:filepath])}" - end - - def sanitized_tag_name - CGI.unescape(params[:tag]) + release.links.find_by_filepath!("/#{params[:filepath]}") end # Default order_by is 'released_at', which is set in ReleasesFinder. diff --git a/app/controllers/projects/service_hook_logs_controller.rb b/app/controllers/projects/service_hook_logs_controller.rb deleted file mode 100644 index 7b037c60321..00000000000 --- a/app/controllers/projects/service_hook_logs_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -class Projects::ServiceHookLogsController < Projects::HookLogsController - extend Gitlab::Utils::Override - - before_action :integration, only: [:show, :retry] - - def retry - execute_hook - redirect_to edit_project_integration_path(@project, @integration) - end - - private - - def integration - @integration ||= @project.find_or_initialize_integration(params[:integration_id]) - end - - override :hook - def hook - @hook ||= integration.service_hook || not_found - end -end diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb deleted file mode 100644 index 8f83e34411b..00000000000 --- a/app/controllers/projects/services_controller.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true - -class Projects::ServicesController < Projects::ApplicationController - include Integrations::Params - include InternalRedirect - - # Authorize - before_action :authorize_admin_project! - before_action :ensure_service_enabled - before_action :integration - before_action :default_integration, only: [:edit, :update] - before_action :web_hook_logs, only: [:edit, :update] - - respond_to :html - - layout "project_settings" - - feature_category :integrations - urgency :low, [:test] - - def edit - end - - def update - attributes = integration_params[:integration] - - if use_inherited_settings?(attributes) - integration.inherit_from_id = default_integration.id - - if saved = integration.save(context: :manual_change) - BulkUpdateIntegrationService.new(default_integration, [integration]).execute - end - else - attributes[:inherit_from_id] = nil - integration.attributes = attributes - saved = integration.save(context: :manual_change) - end - - respond_to do |format| - format.html do - if saved - redirect_to redirect_path, notice: success_message - else - render 'edit' - end - end - - format.json do - status = saved ? :ok : :unprocessable_entity - - render json: serialize_as_json, status: status - end - end - end - - def test - if integration.testable? - render json: service_test_response, status: :ok - else - render json: {}, status: :not_found - end - end - - private - - def redirect_path - safe_redirect_path(params[:redirect_to]).presence || edit_project_integration_path(project, integration) - end - - def service_test_response - unless integration.update(integration_params[:integration]) - return { error: true, message: _('Validations failed.'), service_response: integration.errors.full_messages.join(','), test_failed: false } - end - - result = ::Integrations::Test::ProjectService.new(integration, current_user, params[:event]).execute - - unless result[:success] - return { error: true, message: s_('Integrations|Connection failed. Please check your settings.'), service_response: result[:message].to_s, test_failed: true } - end - - result[:data].presence || {} - rescue *Gitlab::HTTP::HTTP_ERRORS => e - { error: true, message: s_('Integrations|Connection failed. Please check your settings.'), service_response: e.message, test_failed: true } - end - - def success_message - if integration.active? - s_('Integrations|%{integration} settings saved and active.') % { integration: integration.title } - else - s_('Integrations|%{integration} settings saved, but not active.') % { integration: integration.title } - end - end - - def integration - @integration ||= project.find_or_initialize_integration(params[:id]) - end - alias_method :service, :integration - - def default_integration - @default_integration ||= Integration.default_integration(integration.type, project) - end - - def web_hook_logs - return unless integration.service_hook.present? - - @web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page]) - end - - def ensure_service_enabled - render_404 unless service - end - - def serialize_as_json - integration - .as_json(only: integration.json_fields) - .merge(errors: integration.errors.as_json) - end - - def use_inherited_settings?(attributes) - default_integration && attributes[:inherit_from_id] == default_integration.id.to_s - end -end diff --git a/app/controllers/projects/settings/branch_rules_controller.rb b/app/controllers/projects/settings/branch_rules_controller.rb new file mode 100644 index 00000000000..0a415b60124 --- /dev/null +++ b/app/controllers/projects/settings/branch_rules_controller.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Projects + module Settings + class BranchRulesController < Projects::ApplicationController + before_action :authorize_admin_project! + + feature_category :source_code_management + + def index + render_404 unless Feature.enabled?(:branch_rules, project) + end + end + end +end diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index ee50327be8f..cda6c8abea7 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -13,6 +13,7 @@ module Projects before_action :define_variables before_action do push_frontend_feature_flag(:ajax_new_deploy_token, @project) + push_frontend_feature_flag(:ci_variable_settings_graphql, @project) end helper_method :highlight_badge @@ -27,14 +28,7 @@ module Projects ).to_json end - if current_user.ci_owned_runners_cross_joins_fix_enabled? - render - else - # @assignable_runners is using ci_owned_runners - ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do - render - end - end + render end def update diff --git a/app/controllers/projects/settings/integration_hook_logs_controller.rb b/app/controllers/projects/settings/integration_hook_logs_controller.rb new file mode 100644 index 00000000000..b3b5a292d42 --- /dev/null +++ b/app/controllers/projects/settings/integration_hook_logs_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Projects + module Settings + class IntegrationHookLogsController < Projects::HookLogsController + extend Gitlab::Utils::Override + + before_action :integration, only: [:show, :retry] + + def retry + execute_hook + redirect_to edit_project_settings_integration_path(@project, @integration) + end + + private + + def integration + @integration ||= @project.find_or_initialize_integration(params[:integration_id]) + end + + override :hook + def hook + @hook ||= integration.service_hook || not_found + end + end + end +end diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb index c9d92d1aee9..3365da65de8 100644 --- a/app/controllers/projects/settings/integrations_controller.rb +++ b/app/controllers/projects/settings/integrations_controller.rb @@ -3,14 +3,142 @@ module Projects module Settings class IntegrationsController < Projects::ApplicationController + include ::Integrations::Params + include ::InternalRedirect + before_action :authorize_admin_project! + before_action :ensure_integration_enabled, only: [:edit, :update, :test] + before_action :integration, only: [:edit, :update, :test] + before_action :default_integration, only: [:edit, :update] + before_action :web_hook_logs, only: [:edit, :update] + + respond_to :html + layout "project_settings" feature_category :integrations + urgency :low, [:test] - def show + def index @integrations = @project.find_or_initialize_integrations end + + def edit + end + + def update + attributes = integration_params[:integration] + + if use_inherited_settings?(attributes) + integration.inherit_from_id = default_integration.id + + if saved = integration.save(context: :manual_change) + BulkUpdateIntegrationService.new(default_integration, [integration]).execute + end + else + attributes[:inherit_from_id] = nil + integration.attributes = attributes + saved = integration.save(context: :manual_change) + end + + respond_to do |format| + format.html do + if saved + redirect_to redirect_path, notice: success_message + else + render 'edit' + end + end + + format.json do + status = saved ? :ok : :unprocessable_entity + + render json: serialize_as_json, status: status + end + end + end + + def test + if integration.testable? + render json: integration_test_response, status: :ok + else + render json: {}, status: :not_found + end + end + + private + + def redirect_path + safe_redirect_path(params[:redirect_to]).presence || + edit_project_settings_integration_path(project, integration) + end + + def integration_test_response + unless integration.update(integration_params[:integration]) + return { + error: true, + message: _('Validations failed.'), + service_response: integration.errors.full_messages.join(','), + test_failed: false + } + end + + result = ::Integrations::Test::ProjectService.new(integration, current_user, params[:event]).execute + + unless result[:success] + return { + error: true, + message: s_('Integrations|Connection failed. Please check your settings.'), + service_response: result[:message].to_s, + test_failed: true + } + end + + result[:data].presence || {} + rescue *Gitlab::HTTP::HTTP_ERRORS => e + { + error: true, + message: s_('Integrations|Connection failed. Please check your settings.'), + service_response: e.message, + test_failed: true + } + end + + def success_message + if integration.active? + format(s_('Integrations|%{integration} settings saved and active.'), integration: integration.title) + else + format(s_('Integrations|%{integration} settings saved, but not active.'), integration: integration.title) + end + end + + def integration + @integration ||= project.find_or_initialize_integration(params[:id]) + end + + def default_integration + @default_integration ||= Integration.default_integration(integration.type, project) + end + + def web_hook_logs + return unless integration.service_hook.present? + + @web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page]) + end + + def ensure_integration_enabled + render_404 unless integration + end + + def serialize_as_json + integration + .as_json(only: integration.json_fields) + .merge(errors: integration.errors.as_json) + end + + def use_inherited_settings?(attributes) + default_integration && attributes[:inherit_from_id] == default_integration.id.to_s + end end end end diff --git a/app/controllers/projects/settings/packages_and_registries_controller.rb b/app/controllers/projects/settings/packages_and_registries_controller.rb index 0cd2bfa9695..d3c08bef808 100644 --- a/app/controllers/projects/settings/packages_and_registries_controller.rb +++ b/app/controllers/projects/settings/packages_and_registries_controller.rb @@ -17,12 +17,7 @@ module Projects private def packages_and_registries_settings_enabled! - render_404 unless can_destroy_container_registry_image?(project) - end - - def can_destroy_container_registry_image?(project) - Gitlab.config.registry.enabled && - can?(current_user, :destroy_container_image, project) + render_404 unless can?(current_user, :view_package_registry_project_settings, project) end end end diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index 0fd2d56229a..a178b8f7aa3 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -15,6 +15,7 @@ module Projects urgency :low, [:show, :create_deploy_token] def show + push_frontend_feature_flag(:branch_rules, @project) render_show end diff --git a/app/controllers/projects/static_site_editor_controller.rb b/app/controllers/projects/static_site_editor_controller.rb deleted file mode 100644 index fed6307514e..00000000000 --- a/app/controllers/projects/static_site_editor_controller.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -class Projects::StaticSiteEditorController < Projects::ApplicationController - include ExtractsPath - include CreatesCommit - include BlobHelper - - layout 'fullscreen' - - content_security_policy do |policy| - next if policy.directives.blank? - - frame_src_values = Array.wrap(policy.directives['frame-src']) | ['https://www.youtube.com'] - policy.frame_src(*frame_src_values) - end - - prepend_before_action :authenticate_user!, only: [:show] - before_action :assign_ref_and_path, only: [:show] - before_action :authorize_edit_tree!, only: [:show] - - feature_category :static_site_editor - - def index - render_404 - end - - def show - redirect_to ide_edit_path(project, @ref, @path) - end - - private - - def serialize_necessary_payload_values_to_json(payload) - # This will convert booleans, Array-like and Hash-like objects to JSON - payload.transform_values do |value| - if value.is_a?(String) || value.is_a?(Integer) - value - elsif value.nil? - '' - else - value.to_json - end - end - end - - def assign_ref_and_path - @ref, @path = extract_ref(params.fetch(:id)) - - render_404 if @ref.blank? || @path.blank? - end -end diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index eb3579551bd..432497850f2 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -94,11 +94,10 @@ class Projects::TagsController < Projects::ApplicationController def destroy result = ::Tags::DestroyService.new(project, current_user).execute(params[:id]) - if result[:status] == :success - render json: result - else - render json: { message: result[:message] }, status: result[:return_code] - end + flash_type = result[:status] == :error ? :alert : :notice + flash[flash_type] = result[:message] + + redirect_to project_tags_path(@project), status: :see_other end private diff --git a/app/controllers/projects/tracings_controller.rb b/app/controllers/projects/tracings_controller.rb index a4aac6aaa32..b5c1354c4a9 100644 --- a/app/controllers/projects/tracings_controller.rb +++ b/app/controllers/projects/tracings_controller.rb @@ -13,6 +13,7 @@ module Projects before_action :authorize_update_environment! feature_category :tracing + urgency :low def show render_404 unless Feature.enabled?(:monitor_tracing, @project) diff --git a/app/controllers/projects/usage_quotas_controller.rb b/app/controllers/projects/usage_quotas_controller.rb index f45ee265432..07a3c010f4f 100644 --- a/app/controllers/projects/usage_quotas_controller.rb +++ b/app/controllers/projects/usage_quotas_controller.rb @@ -6,6 +6,7 @@ class Projects::UsageQuotasController < Projects::ApplicationController layout "project_settings" feature_category :utilization + urgency :low def index @hide_search_settings = true diff --git a/app/controllers/projects/work_items_controller.rb b/app/controllers/projects/work_items_controller.rb index 27857dac2b7..ba23af41bb0 100644 --- a/app/controllers/projects/work_items_controller.rb +++ b/app/controllers/projects/work_items_controller.rb @@ -3,6 +3,8 @@ class Projects::WorkItemsController < Projects::ApplicationController before_action do push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?) + push_frontend_feature_flag(:work_items_mvc_2) + push_frontend_feature_flag(:work_items_hierarchy, project) end feature_category :team_planning diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 60d30352ff8..1e0ef1ad337 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -42,6 +42,13 @@ class ProjectsController < Projects::ApplicationController 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?) + push_frontend_feature_flag(:work_items_mvc_2) + push_frontend_feature_flag(:package_registry_access_level) + push_frontend_feature_flag(:work_items_hierarchy, @project) + end + + before_action only: :edit do + push_frontend_feature_flag(:enforce_auth_checks_on_uploads, @project) end layout :determine_layout @@ -410,6 +417,7 @@ class ProjectsController < Projects::ApplicationController repository_access_level snippets_access_level wiki_access_level + package_registry_access_level pages_access_level metrics_dashboard_access_level analytics_access_level diff --git a/app/controllers/pwa_controller.rb b/app/controllers/pwa_controller.rb index ea14dfb27b3..8de1b10e1f1 100644 --- a/app/controllers/pwa_controller.rb +++ b/app/controllers/pwa_controller.rb @@ -4,9 +4,13 @@ class PwaController < ApplicationController # rubocop:disable Gitlab/NamespacedC layout 'errors' feature_category :navigation + urgency :low skip_before_action :authenticate_user! + def manifest + end + def offline end end diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb index ea50099120b..a2b25acae64 100644 --- a/app/controllers/registrations/welcome_controller.rb +++ b/app/controllers/registrations/welcome_controller.rb @@ -45,7 +45,7 @@ module Registrations end def update_params - params.require(:user).permit(:role, :other_role, :setup_for_company) + params.require(:user).permit(:role, :setup_for_company) end def requires_confirmation?(user) diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 7011bf856e3..206580d205a 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -153,6 +153,7 @@ class RegistrationsController < Devise::RegistrationsController flash[:alert] = _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.') flash.delete :recaptcha_error + add_gon_variables render action: 'new' end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index aab901c1008..7d251ba555c 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -4,6 +4,7 @@ class SearchController < ApplicationController include ControllerWithCrossProjectAccessCheck include SearchHelper include RedisTracking + include ProductAnalyticsTracking include SearchRateLimitable RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete].freeze @@ -71,7 +72,6 @@ class SearchController < ApplicationController render json: { count: count } end - # rubocop: disable CodeReuse/ActiveRecord def autocomplete term = params[:term] @@ -80,7 +80,6 @@ class SearchController < ApplicationController render json: search_autocomplete_opts(term).to_json end - # rubocop: enable CodeReuse/ActiveRecord def opensearch end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 66a531b0b3b..9000e9c39de 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -127,7 +127,9 @@ class SessionsController < Devise::SessionsController flash[:alert] = _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.') flash.delete :recaptcha_error - redirect_to new_user_session_path + add_gon_variables + + respond_with_navigational(resource) { render :new } end end @@ -181,7 +183,6 @@ class SessionsController < Devise::SessionsController # Handle an "initial setup" state, where there's only one user, it's an admin, # and they require a password change. - # rubocop: disable CodeReuse/ActiveRecord def check_initial_setup return unless User.limit(2).count == 1 # Count as much 2 to know if we have exactly one @@ -196,7 +197,6 @@ class SessionsController < Devise::SessionsController redirect_to edit_user_password_path(reset_password_token: @token), notice: _("Please create a password for your new account.") end - # rubocop: enable CodeReuse/ActiveRecord def ensure_password_authentication_enabled! render_403 unless Gitlab::CurrentSettings.password_authentication_enabled_for_web? diff --git a/app/controllers/users/callouts_controller.rb b/app/controllers/users/callouts_controller.rb index fe308d9dd1e..f94ef9063c3 100644 --- a/app/controllers/users/callouts_controller.rb +++ b/app/controllers/users/callouts_controller.rb @@ -3,6 +3,7 @@ module Users class CalloutsController < ApplicationController feature_category :navigation + urgency :low def create if callout.persisted? diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb index f0d95b56d33..f7eb2aad9dc 100644 --- a/app/controllers/users/terms_controller.rb +++ b/app/controllers/users/terms_controller.rb @@ -15,7 +15,7 @@ module Users layout 'terms' - feature_category :users + feature_category :user_management def index @redirect = redirect_path diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 794d60e733d..2799479d922 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -29,13 +29,14 @@ class UsersController < ApplicationController feature_category :users, [:show, :activity, :groups, :projects, :contributed, :starred, :followers, :following, :calendar, :calendar_activities, - :exists, :activity, :follow, :unfollow, :ssh_keys, :gpg_keys] + :exists, :activity, :follow, :unfollow, :ssh_keys] feature_category :snippets, [:snippets] + feature_category :source_code_management, [:gpg_keys] # TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914 - urgency :low, [:show, :calendar_activities, :contributed, :activity, :projects, :groups] - urgency :default, [:calendar, :followers, :following, :starred] + urgency :low, [:show, :calendar_activities, :contributed, :activity, :projects, :groups, :calendar] + urgency :default, [:followers, :following, :starred] urgency :high, [:exists] def show diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb index 6f389aa4924..4decd7f1bee 100644 --- a/app/controllers/whats_new_controller.rb +++ b/app/controllers/whats_new_controller.rb @@ -9,6 +9,7 @@ class WhatsNewController < ApplicationController before_action :check_valid_page_param, :set_pagination_headers feature_category :navigation + urgency :low def index respond_to do |format| |