diff options
Diffstat (limited to 'app/controllers')
53 files changed, 549 insertions, 187 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 9d81d3fad07..3047ee02680 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -5,11 +5,28 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController before_action :set_application_setting before_action :whitelist_query_limiting, only: [:usage_data] + before_action :validate_self_monitoring_feature_flag_enabled, only: [ + :create_self_monitoring_project, + :status_create_self_monitoring_project, + :delete_self_monitoring_project, + :status_delete_self_monitoring_project + ] + + before_action do + push_frontend_feature_flag(:self_monitoring_project) + end VALID_SETTING_PANELS = %w(general integrations repository ci_cd reporting metrics_and_profiling network preferences).freeze + # The current size of a sidekiq job's jid is 24 characters. The size of the + # jid is an internal detail of Sidekiq, and they do not guarantee that it'll + # stay the same. We chose 50 to give us room in case the size of the jid + # increases. The jid is alphanumeric, so 50 is very generous. There is a spec + # that ensures that the constant value is more than the size of an actual jid. + PARAM_JOB_ID_MAX_SIZE = 50 + VALID_SETTING_PANELS.each do |action| define_method(action) { perform_update if submitted? } end @@ -62,8 +79,103 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url end + def create_self_monitoring_project + job_id = SelfMonitoringProjectCreateWorker.perform_async + + render status: :accepted, json: { + job_id: job_id, + monitor_status: status_create_self_monitoring_project_admin_application_settings_path + } + end + + def status_create_self_monitoring_project + job_id = params[:job_id].to_s + + unless job_id.length <= PARAM_JOB_ID_MAX_SIZE + return render status: :bad_request, json: { + message: _('Parameter "job_id" cannot exceed length of %{job_id_max_size}' % + { job_id_max_size: PARAM_JOB_ID_MAX_SIZE }) + } + end + + if Gitlab::CurrentSettings.instance_administration_project_id.present? + return render status: :ok, json: self_monitoring_data + + elsif SelfMonitoringProjectCreateWorker.in_progress?(job_id) + ::Gitlab::PollingInterval.set_header(response, interval: 3_000) + + return render status: :accepted, json: { + message: _('Job to create self-monitoring project is in progress') + } + end + + render status: :bad_request, json: { + message: _('Self-monitoring project does not exist. Please check logs ' \ + 'for any error messages') + } + end + + def delete_self_monitoring_project + job_id = SelfMonitoringProjectDeleteWorker.perform_async + + render status: :accepted, json: { + job_id: job_id, + monitor_status: status_delete_self_monitoring_project_admin_application_settings_path + } + end + + def status_delete_self_monitoring_project + job_id = params[:job_id].to_s + + unless job_id.length <= PARAM_JOB_ID_MAX_SIZE + return render status: :bad_request, json: { + message: _('Parameter "job_id" cannot exceed length of %{job_id_max_size}' % + { job_id_max_size: PARAM_JOB_ID_MAX_SIZE }) + } + end + + if Gitlab::CurrentSettings.instance_administration_project_id.nil? + return render status: :ok, json: { + message: _('Self-monitoring project has been successfully deleted') + } + + elsif SelfMonitoringProjectDeleteWorker.in_progress?(job_id) + ::Gitlab::PollingInterval.set_header(response, interval: 3_000) + + return render status: :accepted, json: { + message: _('Job to delete self-monitoring project is in progress') + } + end + + render status: :bad_request, json: { + message: _('Self-monitoring project was not deleted. Please check logs ' \ + 'for any error messages') + } + end + private + def validate_self_monitoring_feature_flag_enabled + self_monitoring_project_not_implemented unless Feature.enabled?(:self_monitoring_project) + end + + def self_monitoring_data + { + project_id: Gitlab::CurrentSettings.instance_administration_project_id, + project_full_path: Gitlab::CurrentSettings.instance_administration_project&.full_path + } + end + + def self_monitoring_project_not_implemented + render( + status: :not_implemented, + json: { + message: _('Self-monitoring is not enabled on this GitLab server, contact your administrator.'), + documentation_url: help_page_path('administration/monitoring/gitlab_instance_administration_project/index') + } + ) + end + def set_application_setting @application_setting = ApplicationSetting.current_without_cache end diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb index 244fc2b31bb..657aa177ecf 100644 --- a/app/controllers/admin/system_info_controller.rb +++ b/app/controllers/admin/system_info_controller.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true class Admin::SystemInfoController < Admin::ApplicationController - EXCLUDED_MOUNT_OPTIONS = [ - 'nobrowse', - 'read-only', - 'ro' + EXCLUDED_MOUNT_OPTIONS = %w[ + nobrowse + read-only + ro ].freeze EXCLUDED_MOUNT_TYPES = [ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f5306801c04..60b5d9b6da8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -33,6 +33,7 @@ class ApplicationController < ActionController::Base before_action :check_impersonation_availability before_action :required_signup_info + around_action :set_current_context around_action :set_locale around_action :set_session_storage @@ -448,6 +449,14 @@ class ApplicationController < ActionController::Base request.base_url end + def set_current_context(&block) + Gitlab::ApplicationContext.with_context( + user: -> { auth_user }, + project: -> { @project }, + namespace: -> { @group }, + &block) + end + def set_locale(&block) Gitlab::I18n.with_user_locale(current_user, &block) end diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 1298b33471b..1d6711e3c22 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -27,17 +27,7 @@ module Boards issues = list_service.execute issues = issues.page(params[:page]).per(params[:per] || 20).without_count Issue.move_nulls_to_end(issues) if Gitlab::Database.read_write? - issues = issues.preload(:milestone, - :assignees, - project: [ - :route, - { - namespace: [:route] - } - ], - labels: [:priorities], - notes: [:award_emoji, :author] - ) + issues = issues.preload(associations_to_preload) render_issues(issues, list_service.metadata) end @@ -74,6 +64,21 @@ module Boards private + def associations_to_preload + [ + :milestone, + :assignees, + project: [ + :route, + { + namespace: [:route] + } + ], + labels: [:priorities], + notes: [:award_emoji, :author] + ] + end + def can_move_issues? head(:forbidden) unless can?(current_user, :admin_issue, board) end @@ -90,7 +95,7 @@ module Boards end def filter_params - params.merge(board_id: params[:board_id], id: params[:list_id]) + params.permit(*Boards::Issues::ListService.valid_params).merge(board_id: params[:board_id], id: params[:list_id]) .reject { |_, value| value.nil? } end @@ -139,3 +144,5 @@ module Boards end end end + +Boards::IssuesController.prepend_if_ee('EE::Boards::IssuesController') diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb index be68d0d0a1d..51ddbe2beb4 100644 --- a/app/controllers/clusters/applications_controller.rb +++ b/app/controllers/clusters/applications_controller.rb @@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController end def cluster_application_params - params.permit(:application, :hostname, :kibana_hostname, :email, :stack) + params.permit(:application, :hostname, :email, :stack, :modsecurity_enabled) end def cluster_application_destroy_params diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index f4b74b14c0b..52a5f801bad 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -14,7 +14,6 @@ class Clusters::ClustersController < Clusters::BaseController before_action :update_applications_status, only: [:cluster_status] before_action only: [:show] do push_frontend_feature_flag(:enable_cluster_application_elastic_stack) - push_frontend_feature_flag(:enable_cluster_application_crossplane) end helper_method :token_in_session diff --git a/app/controllers/concerns/record_user_last_activity.rb b/app/controllers/concerns/record_user_last_activity.rb index a394ef9a2b8..4013596ba12 100644 --- a/app/controllers/concerns/record_user_last_activity.rb +++ b/app/controllers/concerns/record_user_last_activity.rb @@ -21,7 +21,7 @@ module RecordUserLastActivity return if Gitlab::Database.read_only? if current_user && current_user.last_activity_on != Date.today - Users::ActivityService.new(current_user, "visited #{request.path}").execute + Users::ActivityService.new(current_user).execute end end end diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb index 2e9905997db..c92b1cecaaa 100644 --- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -18,7 +18,7 @@ module RequiresWhitelistedMonitoringClient # debugging purposes return true if Rails.env.development? && request.local? - ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.client_ip) } + ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.instance.client_ip) } end def ip_whitelist diff --git a/app/controllers/concerns/sourcegraph_gon.rb b/app/controllers/concerns/sourcegraph_decorator.rb index 01925cf9d4d..5ef09b9221f 100644 --- a/app/controllers/concerns/sourcegraph_gon.rb +++ b/app/controllers/concerns/sourcegraph_decorator.rb @@ -1,10 +1,19 @@ # frozen_string_literal: true -module SourcegraphGon +module SourcegraphDecorator extend ActiveSupport::Concern included do before_action :push_sourcegraph_gon, if: :html_request? + + content_security_policy do |p| + next if p.directives.blank? + next unless Gitlab::CurrentSettings.sourcegraph_enabled + + default_connect_src = p.directives['connect-src'] || p.directives['default-src'] + connect_src_values = Array.wrap(default_connect_src) | [Gitlab::CurrentSettings.sourcegraph_url] + p.connect_src(*connect_src_values) + end end private diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index a8ffa33f1c7..9ec8f930a78 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -11,7 +11,7 @@ module SpammableActions end def mark_as_spam - if SpamService.new(spammable).mark_as_spam! + if Spam::MarkAsSpamService.new(spammable: spammable).execute redirect_to spammable_path, notice: _("%{spammable_titlecase} was submitted to Akismet successfully.") % { spammable_titlecase: spammable.spammable_entity_type.titlecase } else redirect_to spammable_path, alert: _('Error with Akismet. Please check the logs for more info.') diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 72d40f709e6..d7ff2ded5ae 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -3,6 +3,7 @@ class GraphqlController < ApplicationController # Unauthenticated users have access to the API for public data skip_before_action :authenticate_user! + skip_around_action :set_session_storage # Allow missing CSRF tokens, this would mean that if a CSRF is invalid or missing, # the user won't be authenticated but can proceed as an anonymous user. diff --git a/app/controllers/groups/group_links_controller.rb b/app/controllers/groups/group_links_controller.rb index 7965311c5f1..d3360acd245 100644 --- a/app/controllers/groups/group_links_controller.rb +++ b/app/controllers/groups/group_links_controller.rb @@ -3,6 +3,7 @@ class Groups::GroupLinksController < Groups::ApplicationController before_action :check_feature_flag! before_action :authorize_admin_group! + before_action :group_link, only: [:update, :destroy] def create shared_with_group = Group.find(params[:shared_with_group_id]) if params[:shared_with_group_id].present? @@ -22,13 +23,36 @@ class Groups::GroupLinksController < Groups::ApplicationController redirect_to group_group_members_path(group) end + def update + @group_link.update(group_link_params) + end + + def destroy + Groups::GroupLinks::DestroyService.new(nil, nil).execute(@group_link) + + respond_to do |format| + format.html do + redirect_to group_group_members_path(group), status: :found + end + format.js { head :ok } + end + end + private + def group_link + @group_link ||= group.shared_with_group_links.find(params[:id]) + end + def group_link_create_params params.permit(:shared_group_access, :expires_at) end + def group_link_params + params.require(:group_link).permit(:group_access, :expires_at) + end + def check_feature_flag! - render_404 unless Feature.enabled?(:share_group_with_group) + render_404 unless Feature.enabled?(:share_group_with_group, default_enabled: true) end end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index dcdf9aced1a..d1eed85fde6 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -20,28 +20,17 @@ class Groups::GroupMembersController < Groups::ApplicationController :override def index - can_manage_members = can?(current_user, :admin_group_member, @group) - @sort = params[:sort].presence || sort_value_name @project = @group.projects.find(params[:project_id]) if params[:project_id] @members = find_members if can_manage_members - @invited_members = @members.invite - @invited_members = @invited_members.search_invite_email(params[:search_invited]) if params[:search_invited].present? - @invited_members = present_members(@invited_members.page(params[:invited_members_page]).per(MEMBER_PER_PAGE_LIMIT)) + @skip_groups = @group.related_group_ids + @invited_members = present_invited_members(@members) end @members = @members.non_invite - @members = @members.search(params[:search]) if params[:search].present? - @members = @members.sort_by_attribute(@sort) - - if can_manage_members && params[:two_factor].present? - @members = @members.filter_by_2fa(params[:two_factor]) - end - - @members = @members.page(params[:page]).per(MEMBER_PER_PAGE_LIMIT) - @members = present_members(@members) + @members = present_group_members(@members) @requesters = present_members( AccessRequestsFinder.new(@group).execute(current_user)) @@ -54,8 +43,30 @@ class Groups::GroupMembersController < Groups::ApplicationController private + def present_invited_members(members) + invited_members = members.invite + + if params[:search_invited].present? + invited_members = invited_members.search_invite_email(params[:search_invited]) + end + + present_members(invited_members + .page(params[:invited_members_page]) + .per(MEMBER_PER_PAGE_LIMIT)) + end + def find_members - GroupMembersFinder.new(@group).execute(include_relations: requested_relations) + filter_params = params.slice(:two_factor, :search).merge(sort: @sort) + GroupMembersFinder.new(@group, current_user).execute(include_relations: requested_relations, params: filter_params) + end + + def can_manage_members + can?(current_user, :admin_group_member, @group) + end + + def present_group_members(original_members) + members = original_members.page(params[:page]).per(MEMBER_PER_PAGE_LIMIT) + present_members(members) end end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 1e9d51cf970..7eba73daa3c 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -119,7 +119,9 @@ class Groups::MilestonesController < Groups::ApplicationController end def search_params - params.permit(:state, :search_title).merge(group_ids: group.id) + groups = request.format.json? ? group.self_and_ancestors.select(:id) : group.id + + params.permit(:state, :search_title).merge(group_ids: groups) end end diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index 4c9aac9a327..ca35b07111c 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -3,6 +3,10 @@ class IdeController < ApplicationController layout 'fullscreen' + before_action do + push_frontend_feature_flag(:stage_all_by_default, default_enabled: true) + end + def index Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 92f36c031f1..bc3308fd6c6 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -31,7 +31,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Extend the standard message generation to accept our custom exception def failure_message exception = request.env["omniauth.error"] - error = exception.error_reason if exception.respond_to?(:error_reason) + error = exception.error_reason if exception.respond_to?(:error_reason) error ||= exception.error if exception.respond_to?(:error) error ||= exception.message if exception.respond_to?(:message) error ||= request.env["omniauth.error.type"].to_s @@ -177,7 +177,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController message << _("Create a GitLab account first, and then connect it to your %{label} account.") % { label: label } end - flash[:notice] = message.join(' ') + flash[:alert] = message.join(' ') redirect_to new_user_session_path end diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb index c473023cacb..f409193aefc 100644 --- a/app/controllers/profiles/active_sessions_controller.rb +++ b/app/controllers/profiles/active_sessions_controller.rb @@ -4,4 +4,13 @@ class Profiles::ActiveSessionsController < Profiles::ApplicationController def index @sessions = ActiveSession.list(current_user).reject(&:is_impersonated) end + + def destroy + ActiveSession.destroy_with_public_id(current_user, params[:id]) + + respond_to do |format| + format.html { redirect_to profile_active_sessions_url, status: :found } + format.js { head :ok } + end + end end diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index 214640a5295..2166dd7dad7 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -48,7 +48,8 @@ class Profiles::PreferencesController < Profiles::ApplicationController :time_display_relative, :time_format_in_24h, :show_whitespace_in_diffs, - :sourcegraph_enabled + :sourcegraph_enabled, + :render_whitespace_in_code ] end end diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb index 92655d593dd..b62ce940e9c 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -17,6 +17,7 @@ class Projects::BlameController < Projects::ApplicationController end environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit } + environment_params[:find_latest] = true @environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last @blame_groups = Gitlab::Blame.new(@blob, @commit).groups diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 7c97f771a70..3cd14cf845f 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -8,7 +8,7 @@ class Projects::BlobController < Projects::ApplicationController include NotesHelper include ActionView::Helpers::SanitizeHelper include RedirectsForMissingPathOnTree - include SourcegraphGon + include SourcegraphDecorator prepend_before_action :authenticate_user!, only: [:edit] @@ -205,6 +205,7 @@ class Projects::BlobController < Projects::ApplicationController def show_html environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit } + environment_params[:find_latest] = true @environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last @last_commit = @repository.last_commit_for_path(@commit.id, @blob.path) diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb index 812420e9708..b50afa12da0 100644 --- a/app/controllers/projects/ci/lints_controller.rb +++ b/app/controllers/projects/ci/lints_controller.rb @@ -10,8 +10,8 @@ class Projects::Ci::LintsController < Projects::ApplicationController @content = params[:content] result = Gitlab::Ci::YamlProcessor.new_with_validation_errors(@content, yaml_processor_options) - @error = result.errors.join(', ') - @status = result.valid? + @status = result.valid? + @errors = result.errors if result.valid? @config_processor = result.content diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index afb670b687b..3f2dc9b09fa 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -8,7 +8,7 @@ class Projects::CommitController < Projects::ApplicationController include CreatesCommit include DiffForPath include DiffHelper - include SourcegraphGon + include SourcegraphDecorator # Authorize before_action :require_non_empty_project @@ -151,7 +151,7 @@ class Projects::CommitController < Projects::ApplicationController @diffs = commit.diffs(opts) @notes_count = commit.notes.count - @environment = EnvironmentsFinder.new(@project, current_user, commit: @commit).execute.last + @environment = EnvironmentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 5586c2fc631..943277afe95 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -101,6 +101,7 @@ class Projects::CompareController < Projects::ApplicationController def define_environment if compare environment_params = @repository.branch_exists?(head_ref) ? { ref: head_ref } : { commit: compare.commit } + environment_params[:find_latest] = true @environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last end end diff --git a/app/controllers/projects/environments/sample_metrics_controller.rb b/app/controllers/projects/environments/sample_metrics_controller.rb index 79a7eab150b..9176c7cbd56 100644 --- a/app/controllers/projects/environments/sample_metrics_controller.rb +++ b/app/controllers/projects/environments/sample_metrics_controller.rb @@ -2,7 +2,7 @@ class Projects::Environments::SampleMetricsController < Projects::ApplicationController def query - result = Metrics::SampleMetricsService.new(params[:identifier]).query + result = Metrics::SampleMetricsService.new(params[:identifier], range_start: params[:start], range_end: params[:end]).query if result render json: { "status": "success", "data": { "resultType": "matrix", "result": result } } diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 1179782036d..70c4b536854 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -15,11 +15,15 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do push_frontend_feature_flag(:prometheus_computed_alerts) end + before_action do + push_frontend_feature_flag(:auto_stop_environments) + end after_action :expire_etag_cache, only: [:cancel_auto_stop] def index @environments = project.environments .with_state(params[:scope] || :available) + @project = ProjectPresenter.new(project, current_user: current_user) respond_to do |format| format.html @@ -28,6 +32,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController render json: { environments: serialize_environments(request, response, params[:nested]), + review_app: serialize_review_app, available_count: project.environments.available.count, stopped_count: project.environments.stopped.count } @@ -217,7 +222,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController def metrics_dashboard_params params - .permit(:embedded, :group, :title, :y_label, :dashboard_path, :environment) + .permit(:embedded, :group, :title, :y_label, :dashboard_path, :environment, :sample_metrics) .merge(dashboard_path: params[:dashboard], environment: environment) end @@ -239,6 +244,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController .represent(@environments) end + def serialize_review_app + ReviewAppSetupSerializer.new(current_user: @current_user).represent(@project) + end + def authorize_stop_environment! access_denied! unless can?(current_user, :stop_environment, environment) end diff --git a/app/controllers/projects/error_tracking/base_controller.rb b/app/controllers/projects/error_tracking/base_controller.rb new file mode 100644 index 00000000000..6efc6d00702 --- /dev/null +++ b/app/controllers/projects/error_tracking/base_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Projects::ErrorTracking::BaseController < Projects::ApplicationController + POLLING_INTERVAL = 1_000 + + def set_polling_interval + Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) + end +end diff --git a/app/controllers/projects/error_tracking/projects_controller.rb b/app/controllers/projects/error_tracking/projects_controller.rb new file mode 100644 index 00000000000..75a2c976d8b --- /dev/null +++ b/app/controllers/projects/error_tracking/projects_controller.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Projects + module ErrorTracking + class ProjectsController < Projects::ApplicationController + respond_to :json + + before_action :authorize_read_sentry_issue! + + def index + service = ::ErrorTracking::ListProjectsService.new( + project, + current_user, + list_projects_params + ) + result = service.execute + + if result[:status] == :success + render json: { projects: serialize_projects(result[:projects]) } + else + render( + status: result[:http_status] || :bad_request, + json: { message: result[:message] } + ) + end + end + + private + + def list_projects_params + { api_host: params[:api_host], token: params[:token] } + end + + def serialize_projects(projects) + ::ErrorTracking::ProjectSerializer + .new(project: project, user: current_user) + .represent(projects) + end + end + end +end diff --git a/app/controllers/projects/error_tracking/stack_traces_controller.rb b/app/controllers/projects/error_tracking/stack_traces_controller.rb new file mode 100644 index 00000000000..c5d5d6da6a6 --- /dev/null +++ b/app/controllers/projects/error_tracking/stack_traces_controller.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Projects + module ErrorTracking + class StackTracesController < Projects::ErrorTracking::BaseController + respond_to :json + + before_action :authorize_read_sentry_issue!, :set_polling_interval + + def index + result = fetch_latest_event_issue + + if result[:status] == :success + result_with_syntax_highlight = Gitlab::ErrorTracking::StackTraceHighlightDecorator.decorate(result[:latest_event]) + + render json: { error: serialize_error_event(result_with_syntax_highlight) } + else + render json: { message: result[:message] }, status: result.fetch(:http_status, :bad_request) + end + end + + private + + def fetch_latest_event_issue + ::ErrorTracking::IssueLatestEventService + .new(project, current_user, issue_id: params[:issue_id]) + .execute + end + + def serialize_error_event(event) + ::ErrorTracking::ErrorEventSerializer + .new(project: project, user: current_user) + .represent(event) + end + end + end +end diff --git a/app/controllers/projects/error_tracking_controller.rb b/app/controllers/projects/error_tracking_controller.rb index ba21ccfb169..88f739ce29e 100644 --- a/app/controllers/projects/error_tracking_controller.rb +++ b/app/controllers/projects/error_tracking_controller.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -class Projects::ErrorTrackingController < Projects::ApplicationController - before_action :authorize_read_sentry_issue! - before_action :set_issue_id, only: [:details, :stack_trace] +class Projects::ErrorTrackingController < Projects::ErrorTracking::BaseController + respond_to :json - POLLING_INTERVAL = 10_000 + before_action :authorize_read_sentry_issue! + before_action :set_issue_id, only: :details def index respond_to do |format| @@ -20,25 +20,21 @@ class Projects::ErrorTrackingController < Projects::ApplicationController respond_to do |format| format.html format.json do + set_polling_interval render_issue_detail_json end end end - def stack_trace - respond_to do |format| - format.json do - render_issue_stack_trace_json - end - end - end + def update + service = ErrorTracking::IssueUpdateService.new(project, current_user, issue_update_params) + result = service.execute - def list_projects - respond_to do |format| - format.json do - render_project_list_json - end - end + return if handle_errors(result) + + render json: { + result: result + } end private @@ -71,41 +67,6 @@ class Projects::ErrorTrackingController < Projects::ApplicationController } end - def render_issue_stack_trace_json - service = ErrorTracking::IssueLatestEventService.new(project, current_user, issue_details_params) - result = service.execute - - return if handle_errors(result) - - result_with_syntax_highlight = Gitlab::ErrorTracking::StackTraceHighlightDecorator.decorate(result[:latest_event]) - - render json: { - error: serialize_error_event(result_with_syntax_highlight) - } - end - - def render_project_list_json - service = ErrorTracking::ListProjectsService.new( - project, - current_user, - list_projects_params - ) - result = service.execute - - if result[:status] == :success - render json: { - projects: serialize_projects(result[:projects]) - } - else - return render( - status: result[:http_status] || :bad_request, - json: { - message: result[:message] - } - ) - end - end - def handle_errors(result) unless result[:status] == :success render json: { message: result[:message] }, @@ -117,8 +78,8 @@ class Projects::ErrorTrackingController < Projects::ApplicationController params.permit(:search_term, :sort, :cursor) end - def list_projects_params - params.require(:error_tracking_setting).permit([:api_host, :token]) + def issue_update_params + params.permit(:issue_id, :status) end def issue_details_params @@ -129,10 +90,6 @@ class Projects::ErrorTrackingController < Projects::ApplicationController @issue_id = issue_details_params[:issue_id] end - def set_polling_interval - Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) - end - def serialize_errors(errors) ErrorTracking::ErrorSerializer .new(project: project, user: current_user) @@ -144,16 +101,4 @@ class Projects::ErrorTrackingController < Projects::ApplicationController .new(project: project, user: current_user) .represent(error) end - - def serialize_error_event(event) - ErrorTracking::ErrorEventSerializer - .new(project: project, user: current_user) - .represent(event) - end - - def serialize_projects(projects) - ErrorTracking::ProjectSerializer - .new(project: project, user: current_user) - .represent(projects) - end end diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index cb6d9c2ba18..9806b91c7e8 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -9,6 +9,7 @@ class Projects::ForksController < Projects::ApplicationController before_action :require_non_empty_project before_action :authorize_download_code! before_action :authenticate_user!, only: [:new, :create] + before_action :authorize_fork_project!, only: [:new, :create] # rubocop: disable CodeReuse/ActiveRecord def index @@ -61,6 +62,8 @@ class Projects::ForksController < Projects::ApplicationController end # rubocop: enable CodeReuse/ActiveRecord + private + def whitelist_query_limiting Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42335') end diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb index ccfc38d97b2..3f6e116a62b 100644 --- a/app/controllers/projects/git_http_client_controller.rb +++ b/app/controllers/projects/git_http_client_controller.rb @@ -3,6 +3,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController include ActionController::HttpAuthentication::Basic include KerberosSpnegoHelper + include Gitlab::Utils::StrongMemoize attr_reader :authentication_result, :redirected_path @@ -47,7 +48,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController send_final_spnego_response return # Allow access end - elsif project && download_request? && http_allowed? && Guest.can?(:download_code, project) + elsif http_download_allowed? @authentication_result = Gitlab::Auth::Result.new(nil, project, :none, [:download_code]) @@ -89,11 +90,9 @@ class Projects::GitHttpClientController < Projects::ApplicationController end def repository - repo_type.repository_for(project) - end - - def wiki? - repo_type.wiki? + strong_memoize(:repository) do + repo_type.repository_for(project) + end end def repo_type @@ -113,8 +112,10 @@ class Projects::GitHttpClientController < Projects::ApplicationController authentication_result.ci?(project) end - def http_allowed? - Gitlab::ProtocolAccess.allowed?('http') + def http_download_allowed? + Gitlab::ProtocolAccess.allowed?('http') && + download_request? && + project && Guest.can?(:download_code, project) end end diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb index 93f7ce73a51..236f1b967de 100644 --- a/app/controllers/projects/git_http_controller.rb +++ b/app/controllers/projects/git_http_controller.rb @@ -75,17 +75,20 @@ class Projects::GitHttpController < Projects::GitHttpClientController end def enqueue_fetch_statistics_update - return if wiki? - return unless project.daily_statistics_enabled? + return if Gitlab::Database.read_only? + return if repo_type.wiki? + return unless project&.daily_statistics_enabled? ProjectDailyStatisticsWorker.perform_async(project.id) end def access - @access ||= access_klass.new(access_actor, project, - 'http', authentication_abilities: authentication_abilities, - namespace_path: params[:namespace_id], project_path: project_path, - redirected_path: redirected_path, auth_result_type: auth_result_type) + @access ||= access_klass.new(access_actor, project, 'http', + authentication_abilities: authentication_abilities, + namespace_path: params[:namespace_id], + project_path: project_path, + redirected_path: redirected_path, + auth_result_type: auth_result_type) end def access_actor @@ -107,7 +110,7 @@ class Projects::GitHttpController < Projects::GitHttpClientController end def log_user_activity - Users::ActivityService.new(user, 'pull').execute + Users::ActivityService.new(user).execute end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 229374c3929..0944d7b47bf 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -44,9 +44,11 @@ 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, default_enabled: true) + push_frontend_feature_flag(:issue_link_types, project) end + around_action :allow_gitaly_ref_name_caching, only: [:discussions] + respond_to :html alias_method :designs, :show diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 796f3ff603f..cb473d6ee96 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -51,6 +51,8 @@ class Projects::JobsController < Projects::ApplicationController build.trace.read do |stream| respond_to do |format| format.json do + build.trace.being_watched! + # TODO: when the feature flag is removed we should not pass # content_format to serialize method. content_format = Feature.enabled?(:job_log_json, @project, default_enabled: true) ? :json : :html diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index 78dc196b08e..23222cbd37c 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -12,10 +12,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap before_action :build_merge_request, except: [:create] def new - # n+1: https://gitlab.com/gitlab-org/gitlab-foss/issues/40934 - Gitlab::GitalyClient.allow_n_plus_1_calls do - define_new_vars - end + define_new_vars end def create @@ -52,7 +49,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap @diff_notes_disabled = true - @environment = @merge_request.environments_for(current_user).last + @environment = @merge_request.environments_for(current_user, latest: true).last render json: { html: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs, environment: @environment) } end diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 37d90ecdc00..c0c8474232a 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -51,7 +51,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic # 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 + @environment = @merge_request.environments_for(current_user, latest: true).last diffs.unfold_diff_files(note_positions.unfoldable) diffs.write_cache diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 69e3e7c7acb..17025670488 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -9,7 +9,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo include ToggleAwardEmoji include IssuableCollections include RecordUserLastActivity - include SourcegraphGon + include SourcegraphDecorator skip_before_action :merge_request, only: [:index, :bulk_update] before_action :whitelist_query_limiting, only: [:assign_related_issues, :update] @@ -25,7 +25,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo before_action do push_frontend_feature_flag(:vue_issuable_sidebar, @project.group) - push_frontend_feature_flag(:release_search_filter, @project, default_enabled: true) push_frontend_feature_flag(:async_mr_widget, @project) end @@ -222,11 +221,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo def ci_environments_status 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 + EnvironmentStatus.for_deployed_merge_request(@merge_request, current_user) else EnvironmentStatus.for_merge_request(@merge_request, current_user) end diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index f1e591ea1ec..18a171700e9 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -34,7 +34,7 @@ class Projects::PagesController < Projects::ApplicationController if result[:status] == :success flash[:notice] = 'Your changes have been saved' else - flash[:alert] = 'Something went wrong on our end' + flash[:alert] = result[:message] end redirect_to project_pages_path(@project) @@ -45,6 +45,12 @@ class Projects::PagesController < Projects::ApplicationController private def project_params - params.require(:project).permit(:pages_https_only) + params.require(:project).permit(project_params_attributes) + end + + def project_params_attributes + %i[pages_https_only] end end + +Projects::PagesController.prepend_if_ee('EE::Projects::PagesController') diff --git a/app/controllers/projects/performance_monitoring/dashboards_controller.rb b/app/controllers/projects/performance_monitoring/dashboards_controller.rb new file mode 100644 index 00000000000..2d872b78096 --- /dev/null +++ b/app/controllers/projects/performance_monitoring/dashboards_controller.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Projects + module PerformanceMonitoring + class DashboardsController < ::Projects::ApplicationController + include BlobHelper + + before_action :check_repository_available! + before_action :validate_required_params! + + rescue_from ActionController::ParameterMissing do |exception| + respond_error(http_status: :bad_request, message: _('Request parameter %{param} is missing.') % { param: exception.param }) + end + + def create + result = ::Metrics::Dashboard::CloneDashboardService.new(project, current_user, dashboard_params).execute + + if result[:status] == :success + respond_success(result) + else + respond_error(result) + end + end + + private + + def respond_success(result) + set_web_ide_link_notice(result.dig(:dashboard, :path)) + respond_to do |format| + format.json { render status: result.delete(:http_status), json: result } + end + end + + def respond_error(result) + respond_to do |format| + format.json { render json: { error: result[:message] }, status: result[:http_status] } + end + end + + def set_web_ide_link_notice(new_dashboard_path) + web_ide_link_start = "<a href=\"#{ide_edit_path(project, redirect_safe_branch_name, new_dashboard_path)}\">" + message = _("Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}.") % { web_ide_link_start: web_ide_link_start, web_ide_link_end: "</a>" } + flash[:notice] = message.html_safe + end + + def validate_required_params! + params.require(%i(branch file_name dashboard commit_message)) + end + + def redirect_safe_branch_name + repository.find_branch(params[:branch]).name + end + + def dashboard_params + params.permit(%i(branch file_name dashboard commit_message)).to_h + end + end + end +end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index e3ef8f3f2ff..a62eb94a3e4 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -80,6 +80,12 @@ class Projects::PipelinesController < Projects::ApplicationController end end + def destroy + ::Ci::DestroyPipelineService.new(project, current_user).execute(pipeline) + + redirect_to project_pipelines_path(project), status: :see_other + end + def builds render_show end diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index 267dca74f96..c9c7ba1253f 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -23,7 +23,7 @@ module Projects private def prometheus_adapter - @prometheus_adapter ||= ::Prometheus::AdapterService.new(project).prometheus_adapter + @prometheus_adapter ||= ::Gitlab::Prometheus::Adapter.new(project, project.deployment_platform&.cluster).prometheus_adapter end def require_prometheus_metrics! diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb index f39d98be516..f7bc6898112 100644 --- a/app/controllers/projects/raw_controller.rb +++ b/app/controllers/projects/raw_controller.rb @@ -9,9 +9,9 @@ class Projects::RawController < Projects::ApplicationController 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], unless: :external_storage_request? + before_action :assign_ref_vars before_action :redirect_to_external_storage, only: :show, if: :static_objects_external_storage_enabled? def show @@ -23,11 +23,15 @@ class Projects::RawController < Projects::ApplicationController private def show_rate_limit - if rate_limiter.throttled?(:show_raw_controller, scope: [@project, @commit, @path], threshold: raw_blob_request_limit) + # This bypasses assign_ref_vars to avoid a Gitaly FindCommit lookup. + # When rate limiting, we really don't care if a different commit is + # being requested. + _ref, path = extract_ref(get_id) + + if rate_limiter.throttled?(:show_raw_controller, scope: [@project, path], threshold: raw_blob_request_limit) rate_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 + render plain: _('You cannot access the raw file. Please wait a minute.'), status: :too_many_requests end end diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index d6030a9e455..08a57a9b146 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -7,7 +7,7 @@ class Projects::ReleasesController < Projects::ApplicationController before_action :authorize_read_release! before_action do push_frontend_feature_flag(:release_issue_summary, project) - push_frontend_feature_flag(:release_evidence_collection, project) + push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true) end before_action :authorize_update_release!, only: %i[edit update] before_action :authorize_read_release_evidence!, only: [:evidence] diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index dbd11c8ddc8..daddd9dd485 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -46,8 +46,8 @@ class Projects::SnippetsController < Projects::ApplicationController def create create_params = snippet_params.merge(spammable_params) - - @snippet = CreateSnippetService.new(@project, current_user, create_params).execute + service_response = Snippets::CreateService.new(project, current_user, create_params).execute + @snippet = service_response.payload[:snippet] recaptcha_check_with_fallback { render :new } end @@ -55,7 +55,8 @@ class Projects::SnippetsController < Projects::ApplicationController def update update_params = snippet_params.merge(spammable_params) - UpdateSnippetService.new(project, current_user, @snippet, update_params).execute + service_response = Snippets::UpdateService.new(project, current_user, update_params).execute(@snippet) + @snippet = service_response.payload[:snippet] recaptcha_check_with_fallback { render :edit } end @@ -89,11 +90,17 @@ class Projects::SnippetsController < Projects::ApplicationController end def destroy - return access_denied! unless can?(current_user, :admin_project_snippet, @snippet) - - @snippet.destroy - - redirect_to project_snippets_path(@project), status: :found + service_response = Snippets::DestroyService.new(current_user, @snippet).execute + + if service_response.success? + redirect_to project_snippets_path(project), status: :found + elsif service_response.http_status == 403 + access_denied! + else + redirect_to project_snippet_path(project, @snippet), + status: :found, + alert: service_response.message + end end protected diff --git a/app/controllers/projects/starrers_controller.rb b/app/controllers/projects/starrers_controller.rb index 4efe956e973..d9654f4f72a 100644 --- a/app/controllers/projects/starrers_controller.rb +++ b/app/controllers/projects/starrers_controller.rb @@ -7,8 +7,8 @@ class Projects::StarrersController < Projects::ApplicationController @starrers = UsersStarProjectsFinder.new(@project, params, current_user: @current_user).execute @sort = params[:sort].presence || sort_value_name @starrers = @starrers.preload_users.sort_by_attribute(@sort).page(params[:page]) - @public_count = @project.starrers.with_public_profile.size - @total_count = @project.starrers.size + @public_count = @project.starrers.with_public_profile.size + @total_count = @project.starrers.size @private_count = @total_count - @public_count end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index eec89afe354..aba28e5c835 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -15,6 +15,10 @@ class Projects::TreeController < Projects::ApplicationController before_action :authorize_download_code! before_action :authorize_edit_tree!, only: [:create_dir] + before_action only: [:show] do + push_frontend_feature_flag(:vue_file_list_lfs_badge) + end + def show return render_404 unless @repository.commit(@ref) @@ -28,7 +32,8 @@ class Projects::TreeController < Projects::ApplicationController respond_to do |format| format.html do - lfs_blob_ids + lfs_blob_ids if Feature.disabled?(:vue_file_list, @project) + @last_commit = @repository.last_commit_for_path(@commit.id, @tree.path) || @commit end end diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb index 3e5a1cfc74d..72251988b5e 100644 --- a/app/controllers/projects/uploads_controller.rb +++ b/app/controllers/projects/uploads_controller.rb @@ -29,4 +29,14 @@ class Projects::UploadsController < Projects::ApplicationController Project.find_by_full_path("#{namespace}/#{id}") end + + # Overrides ApplicationController#build_canonical_path since there are + # multiple routes that match project uploads: + # https://gitlab.com/gitlab-org/gitlab/issues/196396 + def build_canonical_path(project) + return super unless action_name == 'show' + return super unless params[:secret] && params[:filename] + + show_namespace_project_uploads_url(project.namespace.to_param, project.to_param, params[:secret], params[:filename]) + end end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index fb06299676c..cfc0925d9e1 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -39,6 +39,10 @@ class Projects::WikisController < Projects::ApplicationController if @page set_encoding_error unless valid_encoding? + # Assign vars expected by MarkupHelper + @ref = params[:version_id] + @path = @page.path + render 'show' elsif file_blob send_blob(@project_wiki.repository, file_blob) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 47d6fb67108..bf05defbc2e 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -21,8 +21,7 @@ class ProjectsController < Projects::ApplicationController before_action :assign_ref_vars, if: -> { action_name == 'show' && repo_exists? } before_action :tree, if: -> { action_name == 'show' && repo_exists? && project_view_files? } - before_action :lfs_blob_ids, - if: -> { action_name == 'show' && repo_exists? && project_view_files? } + before_action :lfs_blob_ids, if: :show_blob_ids?, only: :show before_action :project_export_enabled, only: [:export, :download_export, :remove_export, :generate_new_export] before_action :present_project, only: [:edit] before_action :authorize_download_code!, only: [:refs] @@ -52,7 +51,7 @@ class ProjectsController < Projects::ApplicationController def edit @badge_api_endpoint = expose_url(api_v4_projects_badges_path(id: @project.id)) - render 'edit' + render_edit end def create @@ -86,7 +85,7 @@ class ProjectsController < Projects::ApplicationController else flash.now[:alert] = result[:message] - format.html { render 'edit' } + format.html { render_edit } end format.js @@ -296,6 +295,10 @@ class ProjectsController < Projects::ApplicationController private + def show_blob_ids? + repo_exists? && project_view_files? && Feature.disabled?(:vue_file_list, @project) + end + # Render project landing depending of which features are available # So if page is not available in the list it renders the next page # @@ -383,10 +386,12 @@ class ProjectsController < Projects::ApplicationController :template_project_id, :merge_method, :initialize_with_readme, + :autoclose_referenced_issues, project_feature_attributes: %i[ builds_access_level issues_access_level + forking_access_level merge_requests_access_level repository_access_level snippets_access_level @@ -483,6 +488,10 @@ class ProjectsController < Projects::ApplicationController def rate_limiter ::Gitlab::ApplicationRateLimiter end + + def render_edit + render 'edit' + end end ProjectsController.prepend_if_ee('EE::ProjectsController') diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 5fc7f5c84f0..c0ba87bf3ed 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -60,7 +60,7 @@ class RegistrationsController < Devise::RegistrationsController end def update_registration - user_params = params.require(:user).permit(:name, :role, :setup_for_company) + user_params = params.require(:user).permit(:role, :setup_for_company) result = ::Users::SignupService.new(current_user, user_params).execute if result[:status] == :success @@ -152,13 +152,7 @@ class RegistrationsController < Devise::RegistrationsController end def sign_up_params - clean_params = params.require(:user).permit(:username, :email, :email_confirmation, :name, :password) - - if experiment_enabled?(:signup_flow) - clean_params[:name] = clean_params[:username] - end - - clean_params + params.require(:user).permit(:username, :email, :email_confirmation, :name, :first_name, :last_name, :password) end def resource_name diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index e30935be4b6..04d2b3068da 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -21,6 +21,8 @@ class SearchController < ApplicationController return if params[:search].blank? + return unless search_term_valid? + @search_term = params[:search] @scope = search_service.scope @@ -62,6 +64,20 @@ class SearchController < ApplicationController private + def search_term_valid? + unless search_service.valid_query_length? + flash[:alert] = t('errors.messages.search_chars_too_long', count: SearchService::SEARCH_CHAR_LIMIT) + return false + end + + unless search_service.valid_terms_count? + flash[:alert] = t('errors.messages.search_terms_too_long', count: SearchService::SEARCH_TERM_LIMIT) + return false + end + + true + end + def render_commits @search_objects = prepare_commits_for_rendering(@search_objects) end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 0007d5826ba..c29e9d3843b 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -262,7 +262,7 @@ class SessionsController < Devise::SessionsController def log_user_activity(user) login_counter.increment - Users::ActivityService.new(user, 'login').execute + Users::ActivityService.new(user).execute end def load_recaptcha diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 54774df5e76..fc073e47368 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -50,8 +50,8 @@ class SnippetsController < ApplicationController def create create_params = snippet_params.merge(spammable_params) - - @snippet = CreateSnippetService.new(nil, current_user, create_params).execute + service_response = Snippets::CreateService.new(nil, current_user, create_params).execute + @snippet = service_response.payload[:snippet] move_temporary_files if @snippet.valid? && params[:files] @@ -61,7 +61,8 @@ class SnippetsController < ApplicationController def update update_params = snippet_params.merge(spammable_params) - UpdateSnippetService.new(nil, current_user, @snippet, update_params).execute + service_response = Snippets::UpdateService.new(nil, current_user, update_params).execute(@snippet) + @snippet = service_response.payload[:snippet] recaptcha_check_with_fallback { render :edit } end @@ -96,11 +97,17 @@ class SnippetsController < ApplicationController end def destroy - return access_denied! unless can?(current_user, :admin_personal_snippet, @snippet) - - @snippet.destroy + service_response = Snippets::DestroyService.new(current_user, @snippet).execute - redirect_to snippets_path, status: :found + if service_response.success? + redirect_to dashboard_snippets_path, status: :found + elsif service_response.http_status == 403 + access_denied! + else + redirect_to snippet_path(@snippet), + status: :found, + alert: service_response.message + end end protected |