Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-20 12:07:57 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-20 12:07:57 +0300
commit7881eb30eaa8b01dbcfe87faa09927c75c7d6e45 (patch)
tree298bc8d2c62b2f2c29cb8ecbcf3de3eaaa6466d9 /app/controllers
parent64b66e0cb6d1bfd27abf24e06653f00bddb60597 (diff)
Add latest changes from gitlab-org/gitlab@12-6-stable-ee
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/admin/identities_controller.rb6
-rw-r--r--app/controllers/admin/jobs_controller.rb20
-rw-r--r--app/controllers/admin/sessions_controller.rb29
-rw-r--r--app/controllers/application_controller.rb40
-rw-r--r--app/controllers/autocomplete_controller.rb16
-rw-r--r--app/controllers/boards/lists_controller.rb2
-rw-r--r--app/controllers/clusters/clusters_controller.rb59
-rw-r--r--app/controllers/concerns/boards_actions.rb5
-rw-r--r--app/controllers/concerns/confirm_email_warning.rb7
-rw-r--r--app/controllers/concerns/cycle_analytics_params.rb3
-rw-r--r--app/controllers/concerns/enforces_admin_authentication.rb1
-rw-r--r--app/controllers/concerns/initializes_current_user_mode.rb13
-rw-r--r--app/controllers/concerns/issuable_actions.rb12
-rw-r--r--app/controllers/concerns/membership_actions.rb11
-rw-r--r--app/controllers/concerns/notes_actions.rb6
-rw-r--r--app/controllers/concerns/service_params.rb1
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb4
-rw-r--r--app/controllers/concerns/sourcegraph_gon.rb2
-rw-r--r--app/controllers/concerns/uploads_actions.rb38
-rw-r--r--app/controllers/groups/group_members_controller.rb9
-rw-r--r--app/controllers/groups_controller.rb1
-rw-r--r--app/controllers/instance_statistics/conversational_development_index_controller.rb9
-rw-r--r--app/controllers/instance_statistics/dev_ops_score_controller.rb9
-rw-r--r--app/controllers/oauth/applications_controller.rb1
-rw-r--r--app/controllers/oauth/authorizations_controller.rb2
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb25
-rw-r--r--app/controllers/projects/branches_controller.rb10
-rw-r--r--app/controllers/projects/ci/lints_controller.rb10
-rw-r--r--app/controllers/projects/environments/prometheus_api_controller.rb36
-rw-r--r--app/controllers/projects/environments/sample_metrics_controller.rb13
-rw-r--r--app/controllers/projects/environments_controller.rb34
-rw-r--r--app/controllers/projects/error_tracking_controller.rb15
-rw-r--r--app/controllers/projects/hook_logs_controller.rb10
-rw-r--r--app/controllers/projects/issues_controller.rb7
-rw-r--r--app/controllers/projects/jobs_controller.rb33
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb29
-rw-r--r--app/controllers/projects/merge_requests_controller.rb19
-rw-r--r--app/controllers/projects/pages_controller.rb3
-rw-r--r--app/controllers/projects/pages_domains_controller.rb10
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb12
-rw-r--r--app/controllers/projects/pipelines_controller.rb1
-rw-r--r--app/controllers/projects/project_members_controller.rb2
-rw-r--r--app/controllers/projects/raw_controller.rb20
-rw-r--r--app/controllers/projects/releases_controller.rb12
-rw-r--r--app/controllers/projects/service_hook_logs_controller.rb20
-rw-r--r--app/controllers/projects/services_controller.rb7
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb10
-rw-r--r--app/controllers/projects_controller.rb18
-rw-r--r--app/controllers/snippets_controller.rb10
-rw-r--r--app/controllers/uploads_controller.rb1
51 files changed, 452 insertions, 223 deletions
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index 6e5dd1a1f55..06ba916fc55 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -60,6 +60,8 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
font
message
starts_at
+ target_path
+ broadcast_type
))
end
end
diff --git a/app/controllers/admin/identities_controller.rb b/app/controllers/admin/identities_controller.rb
index 8f2e34a6294..327538f1e93 100644
--- a/app/controllers/admin/identities_controller.rb
+++ b/app/controllers/admin/identities_controller.rb
@@ -28,7 +28,8 @@ class Admin::IdentitiesController < Admin::ApplicationController
def update
if @identity.update(identity_params)
- RepairLdapBlockedUserService.new(@user).execute
+ ::Users::RepairLdapBlockedService.new(@user).execute
+
redirect_to admin_user_identities_path(@user), notice: _('User identity was successfully updated.')
else
render :edit
@@ -37,7 +38,8 @@ class Admin::IdentitiesController < Admin::ApplicationController
def destroy
if @identity.destroy
- RepairLdapBlockedUserService.new(@user).execute
+ ::Users::RepairLdapBlockedService.new(@user).execute
+
redirect_to admin_user_identities_path(@user), status: :found, notice: _('User identity was successfully removed.')
else
redirect_to admin_user_identities_path(@user), status: :found, alert: _('Failed to remove user identity.')
diff --git a/app/controllers/admin/jobs_controller.rb b/app/controllers/admin/jobs_controller.rb
index 0c1afdc3d3b..892f6dc657c 100644
--- a/app/controllers/admin/jobs_controller.rb
+++ b/app/controllers/admin/jobs_controller.rb
@@ -1,25 +1,15 @@
# frozen_string_literal: true
class Admin::JobsController < Admin::ApplicationController
- # rubocop: disable CodeReuse/ActiveRecord
def index
+ # We need all builds for tabs counters
+ @all_builds = JobsFinder.new(current_user: current_user).execute
+
@scope = params[:scope]
- @all_builds = Ci::Build
- @builds = @all_builds.order('id DESC')
- @builds =
- case @scope
- when 'pending'
- @builds.pending.reverse_order
- when 'running'
- @builds.running.reverse_order
- when 'finished'
- @builds.finished
- else
- @builds
- end
+ @builds = JobsFinder.new(current_user: current_user, params: params).execute
+ @builds = @builds.eager_load_everything
@builds = @builds.page(params[:page]).per(30)
end
- # rubocop: enable CodeReuse/ActiveRecord
def cancel_all
Ci::Build.running_or_pending.each(&:cancel)
diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb
index 1f946e41995..f9587655a8d 100644
--- a/app/controllers/admin/sessions_controller.rb
+++ b/app/controllers/admin/sessions_controller.rb
@@ -6,17 +6,23 @@ class Admin::SessionsController < ApplicationController
before_action :user_is_admin!
def new
- # Renders a form in which the admin can enter their password
+ if current_user_mode.admin_mode?
+ redirect_to redirect_path, notice: _('Admin mode already enabled')
+ else
+ current_user_mode.request_admin_mode! unless current_user_mode.admin_mode_requested?
+ store_location_for(:redirect, redirect_path)
+ end
end
def create
if current_user_mode.enable_admin_mode!(password: params[:password])
- redirect_location = stored_location_for(:redirect) || admin_root_path
- redirect_to safe_redirect_path(redirect_location)
+ redirect_to redirect_path, notice: _('Admin mode enabled')
else
- flash.now[:alert] = _('Invalid Login or password')
+ flash.now[:alert] = _('Invalid login or password')
render :new
end
+ rescue Gitlab::Auth::CurrentUserMode::NotRequestedError
+ redirect_to new_admin_session_path, alert: _('Re-authentication period expired or never requested. Please try again')
end
def destroy
@@ -30,4 +36,19 @@ class Admin::SessionsController < ApplicationController
def user_is_admin!
render_404 unless current_user&.admin?
end
+
+ def redirect_path
+ redirect_to_path = safe_redirect_path(stored_location_for(:redirect)) || safe_redirect_path_for_url(request.referer)
+
+ if redirect_to_path &&
+ excluded_redirect_paths.none? { |excluded| redirect_to_path.include?(excluded) }
+ redirect_to_path
+ else
+ admin_root_path
+ end
+ end
+
+ def excluded_redirect_paths
+ [new_admin_session_path, admin_session_path]
+ end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 25c1d80b117..f5306801c04 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -16,15 +16,16 @@ class ApplicationController < ActionController::Base
include ConfirmEmailWarning
include Gitlab::Tracking::ControllerConcern
include Gitlab::Experimentation::ControllerConcern
+ include InitializesCurrentUserMode
before_action :authenticate_user!, except: [:route_not_found]
before_action :enforce_terms!, if: :should_enforce_terms?
before_action :validate_user_service_ticket!
- before_action :check_password_expiration
+ before_action :check_password_expiration, if: :html_request?
before_action :ldap_security_check
- before_action :sentry_context
+ around_action :sentry_context
before_action :default_headers
- before_action :add_gon_variables, unless: [:peek_request?, :json_request?]
+ before_action :add_gon_variables, if: :html_request?
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :require_email, unless: :devise_controller?
before_action :active_user_check, unless: :devise_controller?
@@ -41,7 +42,6 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
helper_method :can?
- helper_method :current_user_mode
helper_method :import_sources_enabled?, :github_import_enabled?,
:gitea_import_enabled?, :github_import_configured?,
:gitlab_import_enabled?, :gitlab_import_configured?,
@@ -74,6 +74,18 @@ class ApplicationController < ActionController::Base
render_403
end
+ rescue_from Gitlab::Auth::IpBlacklisted do
+ Gitlab::AuthLogger.error(
+ message: 'Rack_Attack',
+ env: :blocklist,
+ remote_ip: request.ip,
+ request_method: request.request_method,
+ path: request.fullpath
+ )
+
+ head :forbidden
+ end
+
rescue_from Gitlab::Auth::TooManyIps do |e|
head :forbidden, retry_after: Gitlab::Auth::UniqueIpsLimiter.config.unique_ips_limit_time_window
end
@@ -153,7 +165,7 @@ class ApplicationController < ActionController::Base
end
def log_exception(exception)
- Gitlab::Sentry.track_acceptable_exception(exception)
+ Gitlab::ErrorTracking.track_exception(exception)
backtrace_cleaner = request.env["action_dispatch.backtrace_cleaner"]
application_trace = ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception).application_trace
@@ -216,10 +228,6 @@ class ApplicationController < ActionController::Base
end
end
- def respond_201
- head :created
- end
-
def respond_422
head :unprocessable_entity
end
@@ -455,8 +463,8 @@ class ApplicationController < ActionController::Base
response.headers['Page-Title'] = URI.escape(page_title('GitLab'))
end
- def peek_request?
- request.path.start_with?('/-/peek')
+ def html_request?
+ request.format.html?
end
def json_request?
@@ -466,7 +474,7 @@ class ApplicationController < ActionController::Base
def should_enforce_terms?
return false unless Gitlab::CurrentSettings.current_application_settings.enforce_terms
- !(peek_request? || devise_controller?)
+ html_request? && !devise_controller?
end
def set_usage_stats_consent_flag
@@ -524,8 +532,8 @@ class ApplicationController < ActionController::Base
@impersonator ||= User.find(session[:impersonator_id]) if session[:impersonator_id]
end
- def sentry_context
- Gitlab::Sentry.context(current_user)
+ def sentry_context(&block)
+ Gitlab::ErrorTracking.with_context(current_user, &block)
end
def allow_gitaly_ref_name_caching
@@ -534,10 +542,6 @@ class ApplicationController < ActionController::Base
end
end
- def current_user_mode
- @current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user)
- end
-
# A user requires a role and have the setup_for_company attribute set when they are part of the experimental signup
# flow (executed by the Growth team). Users are redirected to the welcome page when their role is required and the
# experiment is enabled for the current user.
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index 06531932b31..0df201ab506 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -40,10 +40,20 @@ class AutocompleteController < ApplicationController
end
def merge_request_target_branches
- merge_requests = MergeRequestsFinder.new(current_user, params).execute
- target_branches = merge_requests.recent_target_branches
+ if target_branch_params.present?
+ merge_requests = MergeRequestsFinder.new(current_user, target_branch_params).execute
+ target_branches = merge_requests.recent_target_branches
+
+ render json: target_branches.map { |target_branch| { title: target_branch } }
+ else
+ render json: { error: _('At least one of group_id or project_id must be specified') }, status: :bad_request
+ end
+ end
+
+ private
- render json: target_branches.map { |target_branch| { title: target_branch } }
+ def target_branch_params
+ params.permit(:group_id, :project_id).select { |_, v| v.present? }
end
end
diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb
index 880f7500708..0b8469e8290 100644
--- a/app/controllers/boards/lists_controller.rb
+++ b/app/controllers/boards/lists_controller.rb
@@ -53,7 +53,7 @@ module Boards
service = Boards::Lists::GenerateService.new(board_parent, current_user)
if service.execute(board)
- lists = board.lists.movable.preload_associations
+ lists = board.lists.movable.preload_associated_models
List.preload_preferences_for_user(lists, current_user)
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index 9a539cf7c24..f4b74b14c0b 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -3,18 +3,15 @@
class Clusters::ClustersController < Clusters::BaseController
include RoutableActions
- before_action :cluster, only: [:cluster_status, :show, :update, :destroy]
+ before_action :cluster, only: [:cluster_status, :show, :update, :destroy, :clear_cache]
before_action :generate_gcp_authorize_url, only: [:new]
before_action :validate_gcp_token, only: [:new]
before_action :gcp_cluster, only: [:new]
before_action :user_cluster, only: [:new]
- before_action :authorize_create_cluster!, only: [:new, :authorize_aws_role, :revoke_aws_role, :aws_proxy]
+ before_action :authorize_create_cluster!, only: [:new, :authorize_aws_role]
before_action :authorize_update_cluster!, only: [:update]
- before_action :authorize_admin_cluster!, only: [:destroy]
+ before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache]
before_action :update_applications_status, only: [:cluster_status]
- before_action only: [:new, :create_gcp] do
- push_frontend_feature_flag(:create_eks_clusters)
- end
before_action only: [:show] do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
push_frontend_feature_flag(:enable_cluster_application_crossplane)
@@ -42,11 +39,10 @@ class Clusters::ClustersController < Clusters::BaseController
end
def new
- return unless Feature.enabled?(:create_eks_clusters)
-
if params[:provider] == 'aws'
@aws_role = current_user.aws_role || Aws::Role.new
@aws_role.ensure_role_external_id!
+ @instance_types = load_instance_types.to_json
elsif params[:provider] == 'gcp'
redirect_to @authorize_url if @authorize_url && !@valid_gcp_token
@@ -113,6 +109,7 @@ class Clusters::ClustersController < Clusters::BaseController
generate_gcp_authorize_url
validate_gcp_token
user_cluster
+ params[:provider] = 'gcp'
render :new, locals: { active_tab: 'create' }
end
@@ -149,34 +146,24 @@ class Clusters::ClustersController < Clusters::BaseController
end
def authorize_aws_role
- role = current_user.build_aws_role(create_role_params)
-
- role.save ? respond_201 : respond_422
- end
-
- def revoke_aws_role
- current_user.aws_role&.destroy
+ response = Clusters::Aws::AuthorizeRoleService.new(
+ current_user,
+ params: aws_role_params
+ ).execute
- head :no_content
+ render json: response.body, status: response.status
end
- def aws_proxy
- response = Clusters::Aws::ProxyService.new(
- current_user.aws_role,
- params: params
- ).execute
+ def clear_cache
+ cluster.delete_cached_resources!
- render json: response.body, status: response.status
+ redirect_to cluster.show_path, notice: _('Cluster cache cleared.')
end
private
def destroy_params
- # To be uncomented on https://gitlab.com/gitlab-org/gitlab/merge_requests/16954
- # This MR got split into other since it was too big.
- #
- # params.permit(:cleanup)
- {}
+ params.permit(:cleanup)
end
def update_params
@@ -270,13 +257,12 @@ class Clusters::ClustersController < Clusters::BaseController
)
end
- def create_role_params
+ def aws_role_params
params.require(:cluster).permit(:role_arn, :role_external_id)
end
def generate_gcp_authorize_url
- params = Feature.enabled?(:create_eks_clusters) ? { provider: :gke } : {}
- state = generate_session_key_redirect(clusterable.new_path(params).to_s)
+ state = generate_session_key_redirect(clusterable.new_path(provider: :gcp).to_s)
@authorize_url = GoogleApi::CloudPlatform::Client.new(
nil, callback_google_api_auth_url,
@@ -317,6 +303,19 @@ class Clusters::ClustersController < Clusters::BaseController
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/boards_actions.rb b/app/controllers/concerns/boards_actions.rb
index a093d0d6e7f..eb1080cb3d2 100644
--- a/app/controllers/concerns/boards_actions.rb
+++ b/app/controllers/concerns/boards_actions.rb
@@ -9,6 +9,7 @@ module BoardsActions
before_action :boards, only: :index
before_action :board, only: :show
+ before_action :push_wip_limits, only: [:index, :show]
end
def index
@@ -24,6 +25,10 @@ module BoardsActions
private
+ # Noop on FOSS
+ def push_wip_limits
+ end
+
def boards
strong_memoize(:boards) do
Boards::ListService.new(parent, current_user).execute
diff --git a/app/controllers/concerns/confirm_email_warning.rb b/app/controllers/concerns/confirm_email_warning.rb
index 86df0010665..32e1a46e580 100644
--- a/app/controllers/concerns/confirm_email_warning.rb
+++ b/app/controllers/concerns/confirm_email_warning.rb
@@ -4,15 +4,18 @@ module ConfirmEmailWarning
extend ActiveSupport::Concern
included do
- before_action :set_confirm_warning, if: -> { Feature.enabled?(:soft_email_confirmation) }
+ before_action :set_confirm_warning, if: :show_confirm_warning?
end
protected
+ def show_confirm_warning?
+ html_request? && request.get? && Feature.enabled?(:soft_email_confirmation)
+ end
+
def set_confirm_warning
return unless current_user
return if current_user.confirmed?
- return if peek_request? || json_request? || !request.get?
email = current_user.unconfirmed_email || current_user.email
diff --git a/app/controllers/concerns/cycle_analytics_params.rb b/app/controllers/concerns/cycle_analytics_params.rb
index 1645af695be..a78d803927c 100644
--- a/app/controllers/concerns/cycle_analytics_params.rb
+++ b/app/controllers/concerns/cycle_analytics_params.rb
@@ -38,7 +38,8 @@ module CycleAnalyticsParams
end
def to_utc_time(field)
- Date.parse(field).to_time.utc
+ date = field.is_a?(Date) ? field : Date.parse(field)
+ date.to_time.utc
end
end
diff --git a/app/controllers/concerns/enforces_admin_authentication.rb b/app/controllers/concerns/enforces_admin_authentication.rb
index e731211f423..527759de0bb 100644
--- a/app/controllers/concerns/enforces_admin_authentication.rb
+++ b/app/controllers/concerns/enforces_admin_authentication.rb
@@ -18,6 +18,7 @@ module EnforcesAdminAuthentication
return unless Feature.enabled?(:user_mode_in_session)
unless current_user_mode.admin_mode?
+ current_user_mode.request_admin_mode!
store_location_for(:redirect, request.fullpath) if storable_location?
redirect_to(new_admin_session_path, notice: _('Re-authentication required'))
end
diff --git a/app/controllers/concerns/initializes_current_user_mode.rb b/app/controllers/concerns/initializes_current_user_mode.rb
new file mode 100644
index 00000000000..df7cea5c754
--- /dev/null
+++ b/app/controllers/concerns/initializes_current_user_mode.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module InitializesCurrentUserMode
+ extend ActiveSupport::Concern
+
+ included do
+ helper_method :current_user_mode
+ end
+
+ def current_user_mode
+ @current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user)
+ end
+end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 6162d006cc7..c4abaacd573 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -98,13 +98,11 @@ module IssuableActions
error_message = "Destroy confirmation not provided for #{issuable.human_class_name}"
exception = RuntimeError.new(error_message)
- Gitlab::Sentry.track_acceptable_exception(
+ Gitlab::ErrorTracking.track_exception(
exception,
- extra: {
- project_path: issuable.project.full_path,
- issuable_type: issuable.class.name,
- issuable_id: issuable.id
- }
+ project_path: issuable.project.full_path,
+ issuable_type: issuable.class.name,
+ issuable_id: issuable.id
)
index_path = polymorphic_path([parent, issuable.class])
@@ -121,7 +119,7 @@ module IssuableActions
end
def bulk_update
- result = Issuable::BulkUpdateService.new(current_user, bulk_update_params).execute(resource_name)
+ result = Issuable::BulkUpdateService.new(parent, current_user, bulk_update_params).execute(resource_name)
quantity = result[:count]
render json: { notice: "#{quantity} #{resource_name.pluralize(quantity)} updated" }
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 0b2756c0c6a..993f091b0e6 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -144,4 +144,15 @@ module MembershipActions
end
end
end
+
+ def requested_relations
+ case params[:with_inherited_permissions].presence
+ when 'exclude'
+ [:direct]
+ when 'only'
+ [:inherited]
+ else
+ [:inherited, :direct]
+ end
+ end
end
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index fbae4c53c31..3d599d9e7f9 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -63,7 +63,11 @@ module NotesActions
json.merge!(note_json(@note))
end
- render json: json
+ if @note.errors.present? && @note.errors.keys != [:commands_only]
+ render json: json, status: :unprocessable_entity
+ else
+ render json: json
+ end
end
format.html { redirect_back_or_default }
end
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index fd9d5fad38e..3ccf227c431 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -18,6 +18,7 @@ module ServiceParams
:channels,
:color,
:colorize_messages,
+ :comment_on_event_enabled,
:confidential_issues_events,
:default_irc_uri,
:description,
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index f644923443b..d5c26fca957 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -33,6 +33,8 @@ module SessionlessAuthentication
end
def enable_admin_mode!
- current_user_mode.enable_admin_mode!(skip_password_validation: true) if Feature.enabled?(:user_mode_in_session)
+ return unless Feature.enabled?(:user_mode_in_session)
+
+ current_user_mode.enable_sessionless_admin_mode!
end
end
diff --git a/app/controllers/concerns/sourcegraph_gon.rb b/app/controllers/concerns/sourcegraph_gon.rb
index ab4abd734fb..01925cf9d4d 100644
--- a/app/controllers/concerns/sourcegraph_gon.rb
+++ b/app/controllers/concerns/sourcegraph_gon.rb
@@ -4,7 +4,7 @@ module SourcegraphGon
extend ActiveSupport::Concern
included do
- before_action :push_sourcegraph_gon, unless: :json_request?
+ before_action :push_sourcegraph_gon, if: :html_request?
end
private
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index b87779c22d3..655575e0944 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -1,11 +1,16 @@
# frozen_string_literal: true
module UploadsActions
+ extend ActiveSupport::Concern
include Gitlab::Utils::StrongMemoize
include SendFileUpload
UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze
+ included do
+ prepend_before_action :set_request_format_from_path_extension
+ end
+
def create
uploader = UploadService.new(model, params[:file], uploader_class).execute
@@ -39,15 +44,14 @@ module UploadsActions
expires_in ttl, directives
- disposition = uploader.embeddable? ? 'inline' : 'attachment'
-
- uploaders = [uploader, *uploader.versions.values]
- uploader = uploaders.find { |version| version.filename == params[:filename] }
+ file_uploader = [uploader, *uploader.versions.values].find do |version|
+ version.filename == params[:filename]
+ end
- return render_404 unless uploader
+ return render_404 unless file_uploader
workhorse_set_content_type!
- send_upload(uploader, attachment: uploader.filename, disposition: disposition)
+ send_upload(file_uploader, attachment: file_uploader.filename, disposition: content_disposition)
end
def authorize
@@ -64,6 +68,28 @@ module UploadsActions
private
+ # Based on ActionDispatch::Http::MimeNegotiation. We have an
+ # initializer that monkey-patches this method out (so that repository
+ # paths don't guess a format based on extension), but we do want this
+ # behavior when serving uploads.
+ def set_request_format_from_path_extension
+ path = request.headers['action_dispatch.original_path'] || request.headers['PATH_INFO']
+
+ if match = path&.match(/\.(\w+)\z/)
+ format = Mime[match.captures.first]
+
+ request.format = format.symbol if format
+ end
+ end
+
+ def content_disposition
+ if uploader.embeddable? || uploader.pdf?
+ 'inline'
+ else
+ 'attachment'
+ end
+ end
+
def uploader_class
raise NotImplementedError
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index 1b1416a72d7..dcdf9aced1a 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -24,8 +24,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
@sort = params[:sort].presence || sort_value_name
@project = @group.projects.find(params[:project_id]) if params[:project_id]
-
- @members = GroupMembersFinder.new(@group).execute
+ @members = find_members
if can_manage_members
@invited_members = @members.invite
@@ -52,6 +51,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
# MembershipActions concern
alias_method :membershipable, :group
+
+ private
+
+ def find_members
+ GroupMembersFinder.new(@group).execute(include_relations: requested_relations)
+ end
end
Groups::GroupMembersController.prepend_if_ee('EE::Groups::GroupMembersController')
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 755d97b091c..0953ca96317 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -181,6 +181,7 @@ class GroupsController < Groups::ApplicationController
:avatar,
:description,
:emails_disabled,
+ :mentions_disabled,
:lfs_enabled,
:name,
:path,
diff --git a/app/controllers/instance_statistics/conversational_development_index_controller.rb b/app/controllers/instance_statistics/conversational_development_index_controller.rb
deleted file mode 100644
index 306c16d559c..00000000000
--- a/app/controllers/instance_statistics/conversational_development_index_controller.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class InstanceStatistics::ConversationalDevelopmentIndexController < InstanceStatistics::ApplicationController
- # rubocop: disable CodeReuse/ActiveRecord
- def index
- @metric = ConversationalDevelopmentIndex::Metric.order(:created_at).last&.present
- end
- # rubocop: enable CodeReuse/ActiveRecord
-end
diff --git a/app/controllers/instance_statistics/dev_ops_score_controller.rb b/app/controllers/instance_statistics/dev_ops_score_controller.rb
new file mode 100644
index 00000000000..238f7fa7707
--- /dev/null
+++ b/app/controllers/instance_statistics/dev_ops_score_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class InstanceStatistics::DevOpsScoreController < InstanceStatistics::ApplicationController
+ # rubocop: disable CodeReuse/ActiveRecord
+ def index
+ @metric = DevOpsScore::Metric.order(:created_at).last&.present
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+end
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index 8dd51ce1d64..bbf0bdd3662 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -6,6 +6,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
include PageLayoutHelper
include OauthApplications
include Gitlab::Experimentation::ControllerConcern
+ include InitializesCurrentUserMode
before_action :verify_user_oauth_applications_enabled, except: :index
before_action :authenticate_user!
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
index e65726dffbf..2a4e659c5b9 100644
--- a/app/controllers/oauth/authorizations_controller.rb
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -2,6 +2,8 @@
class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
include Gitlab::Experimentation::ControllerConcern
+ include InitializesCurrentUserMode
+
layout 'profile'
# Overridden from Doorkeeper::AuthorizationsController to
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index eca58748cc5..92f36c031f1 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -4,6 +4,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include AuthenticatesWithTwoFactor
include Devise::Controllers::Rememberable
include AuthHelper
+ include InitializesCurrentUserMode
protect_from_forgery except: [:kerberos, :saml, :cas3, :failure], with: :exception, prepend: true
@@ -94,8 +95,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
return render_403 unless link_provider_allowed?(oauth['provider'])
log_audit_event(current_user, with: oauth['provider'])
- identity_linker ||= auth_module::IdentityLinker.new(current_user, oauth, session)
+ if Feature.enabled?(:user_mode_in_session)
+ return admin_mode_flow if current_user_mode.admin_mode_requested?
+ end
+
+ identity_linker ||= auth_module::IdentityLinker.new(current_user, oauth, session)
link_identity(identity_linker)
if identity_linker.changed?
@@ -239,6 +244,24 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
store_location_for(:user, uri.to_s)
end
end
+
+ def admin_mode_flow
+ if omniauth_identity_matches_current_user?
+ current_user_mode.enable_admin_mode!(skip_password_validation: true)
+
+ redirect_to stored_location_for(:redirect) || admin_root_path, notice: _('Admin mode enabled')
+ else
+ fail_admin_mode_invalid_credentials
+ end
+ end
+
+ def omniauth_identity_matches_current_user?
+ current_user.matches_identity?(oauth['provider'], oauth['uid'])
+ end
+
+ def fail_admin_mode_invalid_credentials
+ redirect_to new_admin_session_path, alert: _('Invalid login or password')
+ end
end
OmniauthCallbacksController.prepend_if_ee('EE::OmniauthCallbacksController')
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 578a3d451a7..09754409104 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -46,7 +46,7 @@ class Projects::BranchesController < Projects::ApplicationController
def diverging_commit_counts
respond_to do |format|
format.json do
- service = Branches::DivergingCommitCountsService.new(repository)
+ service = ::Branches::DivergingCommitCountsService.new(repository)
branches = BranchesFinder.new(repository, params.permit(names: [])).execute
Gitlab::GitalyClient.allow_n_plus_1_calls do
@@ -63,7 +63,7 @@ class Projects::BranchesController < Projects::ApplicationController
redirect_to_autodeploy = project.empty_repo? && project.deployment_platform.present?
- result = CreateBranchService.new(project, current_user)
+ result = ::Branches::CreateService.new(project, current_user)
.execute(branch_name, ref)
success = (result[:status] == :success)
@@ -102,7 +102,7 @@ class Projects::BranchesController < Projects::ApplicationController
def destroy
@branch_name = Addressable::URI.unescape(params[:id])
- result = DeleteBranchService.new(project, current_user).execute(@branch_name)
+ result = ::Branches::DeleteService.new(project, current_user).execute(@branch_name)
respond_to do |format|
format.html do
@@ -118,7 +118,7 @@ class Projects::BranchesController < Projects::ApplicationController
end
def destroy_all_merged
- DeleteMergedBranchesService.new(@project, current_user).async_execute
+ ::Branches::DeleteMergedService.new(@project, current_user).async_execute
redirect_to project_branches_path(@project),
notice: _('Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes.')
@@ -133,8 +133,6 @@ class Projects::BranchesController < Projects::ApplicationController
# frontend could omit this set. To prevent excessive I/O, we require
# that a list of names be specified.
def limit_diverging_commit_counts!
- return unless Feature.enabled?(:limit_diverging_commit_counts, default_enabled: true)
-
limit = Kaminari.config.default_per_page
# If we don't have many branches in the repository, then go ahead.
diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb
index d7a0b7ece14..812420e9708 100644
--- a/app/controllers/projects/ci/lints_controller.rb
+++ b/app/controllers/projects/ci/lints_controller.rb
@@ -8,11 +8,13 @@ class Projects::Ci::LintsController < Projects::ApplicationController
def create
@content = params[:content]
- @error = Gitlab::Ci::YamlProcessor.validation_message(@content, yaml_processor_options)
- @status = @error.blank?
+ result = Gitlab::Ci::YamlProcessor.new_with_validation_errors(@content, yaml_processor_options)
- if @error.blank?
- @config_processor = Gitlab::Ci::YamlProcessor.new(@content, yaml_processor_options)
+ @error = result.errors.join(', ')
+ @status = result.valid?
+
+ if result.valid?
+ @config_processor = result.content
@stages = @config_processor.stages
@builds = @config_processor.builds
@jobs = @config_processor.jobs
diff --git a/app/controllers/projects/environments/prometheus_api_controller.rb b/app/controllers/projects/environments/prometheus_api_controller.rb
index e902d218c75..98fcc594d6e 100644
--- a/app/controllers/projects/environments/prometheus_api_controller.rb
+++ b/app/controllers/projects/environments/prometheus_api_controller.rb
@@ -7,23 +7,34 @@ class Projects::Environments::PrometheusApiController < Projects::ApplicationCon
before_action :environment
def proxy
- result = Prometheus::ProxyService.new(
+ variable_substitution_result =
+ variable_substitution_service.new(environment, permit_params).execute
+
+ if variable_substitution_result[:status] == :error
+ return error_response(variable_substitution_result)
+ end
+
+ prometheus_result = Prometheus::ProxyService.new(
environment,
proxy_method,
proxy_path,
- proxy_params
+ variable_substitution_result[:params]
).execute
- return continue_polling_response if result.nil?
- return error_response(result) if result[:status] == :error
+ return continue_polling_response if prometheus_result.nil?
+ return error_response(prometheus_result) if prometheus_result[:status] == :error
- success_response(result)
+ success_response(prometheus_result)
end
private
- def query_context
- Gitlab::Prometheus::QueryVariables.call(environment)
+ def variable_substitution_service
+ Prometheus::ProxyVariableSubstitutionService
+ end
+
+ def permit_params
+ params.permit!
end
def environment
@@ -37,15 +48,4 @@ class Projects::Environments::PrometheusApiController < Projects::ApplicationCon
def proxy_path
params[:proxy_path]
end
-
- def proxy_params
- substitute_query_variables(params).permit!
- end
-
- def substitute_query_variables(params)
- query = params[:query]
- return params unless query
-
- params.merge(query: query % query_context)
- end
end
diff --git a/app/controllers/projects/environments/sample_metrics_controller.rb b/app/controllers/projects/environments/sample_metrics_controller.rb
new file mode 100644
index 00000000000..79a7eab150b
--- /dev/null
+++ b/app/controllers/projects/environments/sample_metrics_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class Projects::Environments::SampleMetricsController < Projects::ApplicationController
+ def query
+ result = Metrics::SampleMetricsService.new(params[:identifier]).query
+
+ if result
+ render json: { "status": "success", "data": { "resultType": "matrix", "result": result } }
+ else
+ render_404
+ end
+ end
+end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 4562296cea0..1179782036d 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -7,14 +7,15 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action :authorize_read_environment!
before_action :authorize_create_environment!, only: [:new, :create]
before_action :authorize_stop_environment!, only: [:stop]
- before_action :authorize_update_environment!, only: [:edit, :update]
+ before_action :authorize_update_environment!, only: [:edit, :update, :cancel_auto_stop]
before_action :authorize_admin_environment!, only: [:terminal, :terminal_websocket_authorize]
- before_action :environment, only: [:show, :edit, :update, :stop, :terminal, :terminal_websocket_authorize, :metrics]
+ before_action :environment, only: [:show, :edit, :update, :stop, :terminal, :terminal_websocket_authorize, :metrics, :cancel_auto_stop]
before_action :verify_api_request!, only: :terminal_websocket_authorize
- before_action :expire_etag_cache, only: [:index]
+ before_action :expire_etag_cache, only: [:index], unless: -> { request.format.json? }
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
push_frontend_feature_flag(:prometheus_computed_alerts)
end
+ after_action :expire_etag_cache, only: [:cancel_auto_stop]
def index
@environments = project.environments
@@ -104,6 +105,27 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
end
+ def cancel_auto_stop
+ result = Environments::ResetAutoStopService.new(project, current_user)
+ .execute(environment)
+
+ if result[:status] == :success
+ respond_to do |format|
+ message = _('Auto stop successfully canceled.')
+
+ format.html { redirect_back_or_default(default: { action: 'show' }, options: { notice: message }) }
+ format.json { render json: { message: message }, status: :ok }
+ end
+ else
+ respond_to do |format|
+ message = result[:message]
+
+ format.html { redirect_back_or_default(default: { action: 'show' }, options: { alert: message }) }
+ format.json { render json: { message: message }, status: :unprocessable_entity }
+ end
+ end
+ end
+
def terminal
# Currently, this acts as a hint to load the terminal details into the cache
# if they aren't there already. In the future, users will need these details
@@ -175,8 +197,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
def expire_etag_cache
- return if request.format.json?
-
# this forces to reload json content
Gitlab::EtagCaching::Store.new.tap do |store|
store.touch(project_environments_path(project, format: :json))
@@ -222,6 +242,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController
def authorize_stop_environment!
access_denied! unless can?(current_user, :stop_environment, environment)
end
+
+ def authorize_update_environment!
+ access_denied! unless can?(current_user, :update_environment, environment)
+ end
end
Projects::EnvironmentsController.prepend_if_ee('EE::Projects::EnvironmentsController')
diff --git a/app/controllers/projects/error_tracking_controller.rb b/app/controllers/projects/error_tracking_controller.rb
index 7143424473e..ba21ccfb169 100644
--- a/app/controllers/projects/error_tracking_controller.rb
+++ b/app/controllers/projects/error_tracking_controller.rb
@@ -44,13 +44,18 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
private
def render_index_json
- service = ErrorTracking::ListIssuesService.new(project, current_user)
+ service = ErrorTracking::ListIssuesService.new(
+ project,
+ current_user,
+ list_issues_params
+ )
result = service.execute
return if handle_errors(result)
render json: {
errors: serialize_errors(result[:issues]),
+ pagination: result[:pagination],
external_url: service.external_url
}
end
@@ -72,8 +77,10 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
return if handle_errors(result)
+ result_with_syntax_highlight = Gitlab::ErrorTracking::StackTraceHighlightDecorator.decorate(result[:latest_event])
+
render json: {
- error: serialize_error_event(result[:latest_event])
+ error: serialize_error_event(result_with_syntax_highlight)
}
end
@@ -106,6 +113,10 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
end
end
+ def list_issues_params
+ params.permit(:search_term, :sort, :cursor)
+ end
+
def list_projects_params
params.require(:error_tracking_setting).permit([:api_host, :token])
end
diff --git a/app/controllers/projects/hook_logs_controller.rb b/app/controllers/projects/hook_logs_controller.rb
index a7afc3d77a5..ed7e7b68acb 100644
--- a/app/controllers/projects/hook_logs_controller.rb
+++ b/app/controllers/projects/hook_logs_controller.rb
@@ -16,15 +16,17 @@ class Projects::HookLogsController < Projects::ApplicationController
end
def retry
- result = hook.execute(hook_log.request_data, hook_log.trigger)
-
- set_hook_execution_notice(result)
-
+ execute_hook
redirect_to edit_project_hook_path(@project, @hook)
end
private
+ def execute_hook
+ result = hook.execute(hook_log.request_data, hook_log.trigger)
+ set_hook_execution_notice(result)
+ end
+
def hook
@hook ||= @project.hooks.find(params[:hook_id])
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 009765702ab..229374c3929 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -44,7 +44,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, project.group)
- push_frontend_feature_flag(:release_search_filter, project)
+ push_frontend_feature_flag(:release_search_filter, project, default_enabled: true)
end
respond_to :html
@@ -237,7 +237,10 @@ class Projects::IssuesController < Projects::ApplicationController
end
def issue_params
- params.require(:issue).permit(*issue_params_attributes)
+ params.require(:issue).permit(
+ *issue_params_attributes,
+ sentry_issue_attributes: [:sentry_issue_identifier]
+ )
end
def issue_params_attributes
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 1d914ab6011..796f3ff603f 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -12,39 +12,20 @@ class Projects::JobsController < Projects::ApplicationController
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_websocket_authorize]
before_action :verify_api_request!, only: :terminal_websocket_authorize
before_action only: [:show] do
- push_frontend_feature_flag(:job_log_json, project)
+ push_frontend_feature_flag(:job_log_json, project, default_enabled: true)
end
layout 'project'
- # rubocop: disable CodeReuse/ActiveRecord
def index
+ # We need all builds for tabs counters
+ @all_builds = JobsFinder.new(current_user: current_user, project: @project).execute
+
@scope = params[:scope]
- @all_builds = project.builds.relevant
- @builds = @all_builds.order('ci_builds.id DESC')
- @builds =
- case @scope
- when 'pending'
- @builds.pending.reverse_order
- when 'running'
- @builds.running.reverse_order
- when 'finished'
- @builds.finished
- else
- @builds
- end
- @builds = @builds.includes([
- { pipeline: [:project, :user] },
- :job_artifacts_archive,
- :metadata,
- :trigger_request,
- :project,
- :user,
- :tags
- ])
+ @builds = JobsFinder.new(current_user: current_user, project: @project, params: params).execute
+ @builds = @builds.eager_load_everything
@builds = @builds.page(params[:page]).per(30).without_count
end
- # rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def show
@@ -72,7 +53,7 @@ class Projects::JobsController < Projects::ApplicationController
format.json do
# TODO: when the feature flag is removed we should not pass
# content_format to serialize method.
- content_format = Feature.enabled?(:job_log_json, @project) ? :json : :html
+ content_format = Feature.enabled?(:job_log_json, @project, default_enabled: true) ? :json : :html
build_trace = Ci::BuildTrace.new(
build: @build,
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 42f9c0522a3..37d90ecdc00 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -5,8 +5,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
include RendersNotes
before_action :apply_diff_view_cookie!
- before_action :commit, except: :diffs_batch
- before_action :define_diff_vars, except: :diffs_batch
+ before_action :commit
+ before_action :define_diff_vars
before_action :define_diff_comment_vars, except: [:diffs_batch, :diffs_metadata]
def show
@@ -20,14 +20,11 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def diffs_batch
return render_404 unless Feature.enabled?(:diffs_batch_load, @merge_request.project)
- diffable = @merge_request.merge_request_diff
-
- return render_404 unless diffable
-
- diffs = diffable.diffs_in_batch(params[:page], params[:per_page], diff_options: diff_options)
+ diffs = @compare.diffs_in_batch(params[:page], params[:per_page], diff_options: diff_options)
positions = @merge_request.note_positions_for_paths(diffs.diff_file_paths, current_user)
diffs.unfold_diff_files(positions.unfoldable)
+ diffs.write_cache
options = {
merge_request: @merge_request,
@@ -39,8 +36,10 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
end
def diffs_metadata
+ diffs = @compare.diffs(diff_options)
+
render json: DiffsMetadataSerializer.new(project: @merge_request.project)
- .represent(@diffs, additional_attributes)
+ .represent(diffs, additional_attributes)
end
private
@@ -49,11 +48,13 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
[{ source_project: :namespace }, { target_project: :namespace }]
end
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/issues/37735
def render_diffs
+ diffs = @compare.diffs(diff_options)
@environment = @merge_request.environments_for(current_user).last
- @diffs.unfold_diff_files(note_positions.unfoldable)
- @diffs.write_cache
+ diffs.unfold_diff_files(note_positions.unfoldable)
+ diffs.write_cache
request = {
current_user: current_user,
@@ -63,15 +64,14 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
options = additional_attributes.merge(diff_view: diff_view)
- render json: DiffsSerializer.new(request).represent(@diffs, options)
+ render json: DiffsSerializer.new(request).represent(diffs, options)
end
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/issues/37735
def define_diff_vars
@merge_request_diffs = @merge_request.merge_request_diffs.viewable.order_id_desc
@compare = commit || find_merge_request_diff_compare
return render_404 unless @compare
-
- @diffs = @compare.diffs(diff_options)
end
# rubocop: disable CodeReuse/ActiveRecord
@@ -84,6 +84,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
+ #
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/issues/37735
def find_merge_request_diff_compare
@merge_request_diff =
if diff_id = params[:diff_id].presence
@@ -126,6 +128,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
}
end
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/issues/37735
def define_diff_comment_vars
@new_diff_note_attrs = {
noteable_type: 'MergeRequest',
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 766ec1e33f3..69e3e7c7acb 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -20,11 +20,13 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
before_action only: [:show] do
push_frontend_feature_flag(:diffs_batch_load, @project)
+ push_frontend_feature_flag(:single_mr_diff_view, @project)
end
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
- push_frontend_feature_flag(:release_search_filter, @project)
+ push_frontend_feature_flag(:release_search_filter, @project, default_enabled: true)
+ push_frontend_feature_flag(:async_mr_widget, @project)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
@@ -218,11 +220,16 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def ci_environments_status
- environments = if ci_environments_status_on_merge_result?
- EnvironmentStatus.after_merge_request(@merge_request, current_user)
- else
- EnvironmentStatus.for_merge_request(@merge_request, current_user)
- end
+ environments =
+ if ci_environments_status_on_merge_result?
+ if Feature.enabled?(:deployment_merge_requests_widget, @project)
+ EnvironmentStatus.for_deployed_merge_request(@merge_request, current_user)
+ else
+ EnvironmentStatus.after_merge_request(@merge_request, current_user)
+ end
+ else
+ EnvironmentStatus.for_merge_request(@merge_request, current_user)
+ end
render json: EnvironmentStatusSerializer.new(current_user: current_user).represent(environments)
end
diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb
index 722fc30b3ff..f1e591ea1ec 100644
--- a/app/controllers/projects/pages_controller.rb
+++ b/app/controllers/projects/pages_controller.rb
@@ -15,8 +15,7 @@ class Projects::PagesController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def destroy
- project.remove_pages
- project.pages_domains.destroy_all # rubocop: disable DestroyAll
+ ::Pages::DeleteService.new(@project, current_user).execute
respond_to do |format|
format.html do
diff --git a/app/controllers/projects/pages_domains_controller.rb b/app/controllers/projects/pages_domains_controller.rb
index b693642981e..5a81a064048 100644
--- a/app/controllers/projects/pages_domains_controller.rb
+++ b/app/controllers/projects/pages_domains_controller.rb
@@ -8,7 +8,6 @@ class Projects::PagesDomainsController < Projects::ApplicationController
before_action :domain, except: [:new, :create]
def show
- redirect_to edit_project_pages_domain_path(@project, @domain)
end
def new
@@ -24,17 +23,18 @@ class Projects::PagesDomainsController < Projects::ApplicationController
flash[:alert] = 'Failed to verify domain ownership'
end
- redirect_to edit_project_pages_domain_path(@project, @domain)
+ redirect_to project_pages_domain_path(@project, @domain)
end
def edit
+ redirect_to project_pages_domain_path(@project, @domain)
end
def create
@domain = @project.pages_domains.create(create_params)
if @domain.valid?
- redirect_to edit_project_pages_domain_path(@project, @domain)
+ redirect_to project_pages_domain_path(@project, @domain)
else
render 'new'
end
@@ -46,7 +46,7 @@ class Projects::PagesDomainsController < Projects::ApplicationController
status: :found,
notice: 'Domain was updated'
else
- render 'edit'
+ render 'show'
end
end
@@ -68,7 +68,7 @@ class Projects::PagesDomainsController < Projects::ApplicationController
flash[:alert] = @domain.errors.full_messages.join(', ')
end
- redirect_to edit_project_pages_domain_path(@project, @domain)
+ redirect_to project_pages_domain_path(@project, @domain)
end
private
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index 72e939a3310..6a7e2b69652 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -83,12 +83,14 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
def play_rate_limit
return unless current_user
- limiter = ::Gitlab::ActionRateLimiter.new(action: :play_pipeline_schedule)
-
- return unless limiter.throttled?([current_user, schedule], 1)
+ if rate_limiter.throttled?(:play_pipeline_schedule, scope: [current_user, schedule])
+ flash[:alert] = _('You cannot play this scheduled pipeline at the moment. Please wait a minute.')
+ redirect_to pipeline_schedules_path(@project)
+ end
+ end
- flash[:alert] = _('You cannot play this scheduled pipeline at the moment. Please wait a minute.')
- redirect_to pipeline_schedules_path(@project)
+ def rate_limiter
+ ::Gitlab::ApplicationRateLimiter
end
def schedule
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 4d35353d5f5..e3ef8f3f2ff 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -11,7 +11,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
- push_frontend_feature_flag(:hide_dismissed_vulnerabilities)
push_frontend_feature_flag(:junit_pipeline_view)
end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index b01d48ca3d3..7bd084458d1 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -17,7 +17,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@skip_groups << @project.namespace_id unless @project.personal?
@skip_groups += @project.group.ancestors.pluck(:id) if @project.group
- @project_members = MembersFinder.new(@project, current_user).execute
+ @project_members = MembersFinder.new(@project, current_user).execute(include_relations: requested_relations)
if params[:search].present?
@project_members = @project_members.joins(:user).merge(User.search(params[:search]))
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index c94fdd9483d..f39d98be516 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -4,11 +4,15 @@
class Projects::RawController < Projects::ApplicationController
include ExtractsPath
include SendsBlob
+ include StaticObjectExternalStorage
+
+ prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:blob) }
before_action :require_non_empty_project
before_action :assign_ref_vars
before_action :authorize_download_code!
- before_action :show_rate_limit, only: [:show]
+ before_action :show_rate_limit, only: [:show], unless: :external_storage_request?
+ before_action :redirect_to_external_storage, only: :show, if: :static_objects_external_storage_enabled?
def show
@blob = @repository.blob_at(@commit.id, @path)
@@ -19,14 +23,16 @@ class Projects::RawController < Projects::ApplicationController
private
def show_rate_limit
- limiter = ::Gitlab::ActionRateLimiter.new(action: :show_raw_controller)
-
- return unless limiter.throttled?([@project, @commit, @path], raw_blob_request_limit)
+ if rate_limiter.throttled?(:show_raw_controller, scope: [@project, @commit, @path], threshold: raw_blob_request_limit)
+ rate_limiter.log_request(request, :raw_blob_request_limit, current_user)
- limiter.log_request(request, :raw_blob_request_limit, current_user)
+ flash[:alert] = _('You cannot access the raw file. Please wait a minute.')
+ redirect_to project_blob_path(@project, File.join(@ref, @path)), status: :too_many_requests
+ end
+ end
- flash[:alert] = _('You cannot access the raw file. Please wait a minute.')
- redirect_to project_blob_path(@project, File.join(@ref, @path)), status: :too_many_requests
+ def rate_limiter
+ ::Gitlab::ApplicationRateLimiter
end
def raw_blob_request_limit
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index 72c82aec31d..ffe69fe97e4 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -6,10 +6,11 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :release, only: %i[edit update]
before_action :authorize_read_release!
before_action do
- push_frontend_feature_flag(:release_edit_page, project, default_enabled: true)
push_frontend_feature_flag(:release_issue_summary, project)
+ push_frontend_feature_flag(:release_evidence_collection, project)
end
before_action :authorize_update_release!, only: %i[edit update]
+ before_action :authorize_download_code!, only: [:evidence]
def index
respond_to do |format|
@@ -20,6 +21,14 @@ class Projects::ReleasesController < Projects::ApplicationController
end
end
+ def evidence
+ respond_to do |format|
+ format.json do
+ render json: release.evidence_summary
+ end
+ end
+ end
+
protected
def releases
@@ -35,7 +44,6 @@ class Projects::ReleasesController < Projects::ApplicationController
private
def authorize_update_release!
- access_denied! unless Feature.enabled?(:release_edit_page, project, default_enabled: true)
access_denied! unless can?(current_user, :update_release, release)
end
diff --git a/app/controllers/projects/service_hook_logs_controller.rb b/app/controllers/projects/service_hook_logs_controller.rb
new file mode 100644
index 00000000000..5c814ea139f
--- /dev/null
+++ b/app/controllers/projects/service_hook_logs_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class Projects::ServiceHookLogsController < Projects::HookLogsController
+ before_action :service, only: [:show, :retry]
+
+ def retry
+ execute_hook
+ redirect_to edit_project_service_path(@project, @service)
+ end
+
+ private
+
+ def hook
+ @hook ||= service.service_hook
+ end
+
+ def service
+ @service ||= @project.find_or_initialize_service(params[:service_id])
+ end
+end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index c9f680a4696..daaca9e1268 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -7,6 +7,7 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :authorize_admin_project!
before_action :ensure_service_enabled
before_action :service
+ before_action :web_hook_logs, only: [:edit, :update]
respond_to :html
@@ -77,6 +78,12 @@ class Projects::ServicesController < Projects::ApplicationController
@service ||= @project.find_or_initialize_service(params[:id])
end
+ def web_hook_logs
+ return unless @service.service_hook.present?
+
+ @web_hook_logs ||= @service.service_hook.web_hook_logs.recent.page(params[:page])
+ end
+
def ensure_service_enabled
render_404 unless service
end
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index cfed8727450..6af815b8daa 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -13,7 +13,7 @@ module Projects
Projects::UpdateService.new(project, current_user, update_params).tap do |service|
result = service.execute
if result[:status] == :success
- flash[:notice] = _("Pipelines settings for '%{project_name}' were successfully updated.") % { project_name: @project.name }
+ flash[:toast] = _("Pipelines settings for '%{project_name}' were successfully updated.") % { project_name: @project.name }
run_autodevops_pipeline(service)
@@ -39,7 +39,7 @@ module Projects
def reset_registration_token
@project.reset_runners_token!
- flash[:notice] = _('New runners registration token has been generated!')
+ flash[:toast] = _("New runners registration token has been generated!")
redirect_to namespace_project_settings_ci_cd_path
end
@@ -65,12 +65,14 @@ module Projects
return unless service.run_auto_devops_pipeline?
if @project.empty_repo?
- flash[:warning] = _("This repository is currently empty. A new Auto DevOps pipeline will be created after a new file has been pushed to a branch.")
+ flash[:notice] = _("This repository is currently empty. A new Auto DevOps pipeline will be created after a new file has been pushed to a branch.")
return
end
CreatePipelineWorker.perform_async(project.id, current_user.id, project.default_branch, :web, ignore_skip_ci: true, save_on_errors: false)
- flash[:success] = "A new Auto DevOps pipeline has been created, go to <a href=\"#{project_pipelines_path(@project)}\">Pipelines page</a> for details".html_safe
+
+ pipelines_link_start = '<a href="%{url}">'.html_safe % { url: project_pipelines_path(@project) }
+ flash[:toast] = _("A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details") % { pipelines_link_start: pipelines_link_start, pipelines_link_end: "</a>".html_safe }
end
def define_variables
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index e5dea031bb5..47d6fb67108 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -32,6 +32,9 @@ class ProjectsController < Projects::ApplicationController
before_action :authorize_archive_project!, only: [:archive, :unarchive]
before_action :event_filter, only: [:show, :activity]
+ # Project Export Rate Limit
+ before_action :export_rate_limit, only: [:export, :download_export, :generate_new_export]
+
layout :determine_layout
def index
@@ -465,6 +468,21 @@ class ProjectsController < Projects::ApplicationController
def present_project
@project = @project.present(current_user: current_user)
end
+
+ def export_rate_limit
+ prefixed_action = "project_#{params[:action]}".to_sym
+
+ if rate_limiter.throttled?(prefixed_action, scope: [current_user, prefixed_action, @project])
+ rate_limiter.log_request(request, "#{prefixed_action}_request_limit".to_sym, current_user)
+
+ flash[:alert] = _('This endpoint has been requested too many times. Try again later.')
+ redirect_to edit_project_path(@project)
+ end
+ end
+
+ def rate_limiter
+ ::Gitlab::ApplicationRateLimiter
+ end
end
ProjectsController.prepend_if_ee('EE::ProjectsController')
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 5805d068e21..54774df5e76 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -15,13 +15,9 @@ class SnippetsController < ApplicationController
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw]
- # Allow read snippet
+ before_action :authorize_create_snippet!, only: [:new, :create]
before_action :authorize_read_snippet!, only: [:show, :raw]
-
- # Allow modify snippet
before_action :authorize_update_snippet!, only: [:edit, :update]
-
- # Allow destroy snippet
before_action :authorize_admin_snippet!, only: [:destroy]
skip_before_action :authenticate_user!, only: [:index, :show, :raw]
@@ -140,6 +136,10 @@ class SnippetsController < ApplicationController
return render_404 unless can?(current_user, :admin_personal_snippet, @snippet)
end
+ def authorize_create_snippet!
+ return render_404 unless can?(current_user, :create_personal_snippet)
+ end
+
def snippet_params
params.require(:personal_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description)
end
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 635db386792..67d33648470 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -20,7 +20,6 @@ class UploadsController < ApplicationController
skip_before_action :authenticate_user!
before_action :upload_mount_satisfied?
- before_action :find_model
before_action :authorize_access!, only: [:show]
before_action :authorize_create_access!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]