diff options
Diffstat (limited to 'app/controllers')
34 files changed, 265 insertions, 89 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 42634bf611e..a570da61d54 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -64,7 +64,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController private def set_application_setting - @application_setting = Gitlab::CurrentSettings.current_application_settings + @application_setting = ApplicationSetting.current_without_cache end def whitelist_query_limiting diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7321f719deb..75108bf2646 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -516,4 +516,10 @@ class ApplicationController < ActionController::Base def sentry_context Gitlab::Sentry.context(current_user) end + + def allow_gitaly_ref_name_caching + ::Gitlab::GitalyClient.allow_ref_name_caching do + yield + end + end end diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb index 7625600e452..9da2f888ead 100644 --- a/app/controllers/concerns/boards_responses.rb +++ b/app/controllers/concerns/boards_responses.rb @@ -3,8 +3,9 @@ module BoardsResponses include Gitlab::Utils::StrongMemoize + # Overridden on EE module def board_params - params.require(:board).permit(:name, :weight, :milestone_id, :assignee_id, label_ids: []) + params.require(:board).permit(:name) end def parent diff --git a/app/controllers/concerns/continue_params.rb b/app/controllers/concerns/continue_params.rb index 54c0510497f..d5830f6648c 100644 --- a/app/controllers/concerns/continue_params.rb +++ b/app/controllers/concerns/continue_params.rb @@ -6,7 +6,7 @@ module ContinueParams def continue_params continue_params = params[:continue] - return unless continue_params + return {} unless continue_params continue_params = continue_params.permit(:to, :notice, :notice_now) continue_params[:to] = safe_redirect_path(continue_params[:to]) diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb index 6785e6972d0..fa3716502a0 100644 --- a/app/controllers/concerns/internal_redirect.rb +++ b/app/controllers/concerns/internal_redirect.rb @@ -5,8 +5,8 @@ module InternalRedirect def safe_redirect_path(path) return unless path - # Verify that the string starts with a `/` but not a double `/`. - return unless path =~ %r{^/\w.*$} + # Verify that the string starts with a `/` and a known route character. + return unless path =~ %r{^/[-\w].*$} uri = URI(path) # Ignore anything path of the redirect except for the path, querystring and, diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index 88a0690938a..21b3949e361 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -42,7 +42,7 @@ module IssuableCollections @issuables = @issuables.page(params[:page]) @issuables = per_page_for_relative_position if params[:sort] == 'relative_position' - @issuable_meta_data = issuable_meta_data(@issuables, collection_type) + @issuable_meta_data = issuable_meta_data(@issuables, collection_type, current_user) @total_pages = issuable_page_count end # rubocop:enable Gitlab/ModuleWithInstanceVariables diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb index 18ed4027eac..4ad287c4a13 100644 --- a/app/controllers/concerns/issuable_collections_action.rb +++ b/app/controllers/concerns/issuable_collections_action.rb @@ -11,7 +11,7 @@ module IssuableCollectionsAction .non_archived .page(params[:page]) - @issuable_meta_data = issuable_meta_data(@issues, collection_type) + @issuable_meta_data = issuable_meta_data(@issues, collection_type, current_user) respond_to do |format| format.html @@ -22,7 +22,7 @@ module IssuableCollectionsAction def merge_requests @merge_requests = issuables_collection.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@merge_requests, collection_type) + @issuable_meta_data = issuable_meta_data(@merge_requests, collection_type, current_user) end # rubocop:enable Gitlab/ModuleWithInstanceVariables diff --git a/app/controllers/concerns/multiple_boards_actions.rb b/app/controllers/concerns/multiple_boards_actions.rb new file mode 100644 index 00000000000..95a6800f55c --- /dev/null +++ b/app/controllers/concerns/multiple_boards_actions.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module MultipleBoardsActions + include Gitlab::Utils::StrongMemoize + extend ActiveSupport::Concern + + included do + include BoardsActions + + before_action :redirect_to_recent_board, only: [:index] + before_action :authenticate_user!, only: [:recent] + before_action :authorize_create_board!, only: [:create] + before_action :authorize_admin_board!, only: [:create, :update, :destroy] + end + + def recent + recent_visits = ::Boards::VisitsFinder.new(parent, current_user).latest(4) + recent_boards = recent_visits.map(&:board) + + render json: serialize_as_json(recent_boards) + end + + def create + board = Boards::CreateService.new(parent, current_user, board_params).execute + + respond_to do |format| + format.json do + if board.persisted? + extra_json = { board_path: board_path(board) } + render json: serialize_as_json(board).merge(extra_json) + else + render json: board.errors, status: :unprocessable_entity + end + end + end + end + + def update + service = Boards::UpdateService.new(parent, current_user, board_params) + + respond_to do |format| + format.json do + if service.execute(board) + extra_json = { board_path: board_path(board) } + render json: serialize_as_json(board).merge(extra_json) + else + render json: board.errors, status: :unprocessable_entity + end + end + end + end + + def destroy + service = Boards::DestroyService.new(parent, current_user) + service.execute(board) + + respond_to do |format| + format.json { head :ok } + format.html { redirect_to boards_path, status: :found } + end + end + + private + + def redirect_to_recent_board + return if request.format.json? || !parent.multiple_issue_boards_available? || !latest_visited_board + + redirect_to board_path(latest_visited_board.board) + end + + def latest_visited_board + @latest_visited_board ||= Boards::VisitsFinder.new(parent, current_user).latest + end + + def authorize_create_board! + check_multiple_group_issue_boards_available! if group? + end + + def authorize_admin_board! + return render_404 unless can?(current_user, :admin_board, parent) + end + + def serializer + BoardSerializer.new(current_user: current_user) + end + + def serialize_as_json(resource) + serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?) + end +end diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index f96d1821095..0098c4cdf4c 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -203,17 +203,17 @@ module NotesActions # These params are also sent by the client but we need to set these based on # target_type and target_id because we're checking permissions based on that - create_params[:noteable_type] = params[:target_type].classify + create_params[:noteable_type] = noteable.class.name - case params[:target_type] - when 'commit' - create_params[:commit_id] = params[:target_id] - when 'merge_request' - create_params[:noteable_id] = params[:target_id] + case noteable + when Commit + create_params[:commit_id] = noteable.id + when MergeRequest + create_params[:noteable_id] = noteable.id # Notes on MergeRequest can have an extra `commit_id` context create_params[:commit_id] = params.dig(:note, :commit_id) else - create_params[:noteable_id] = params[:target_id] + create_params[:noteable_id] = noteable.id end end end diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb index 426f224d26b..f47ead2f0da 100644 --- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -14,6 +14,10 @@ module RequiresWhitelistedMonitoringClient end def client_ip_whitelisted? + # Always allow developers to access http://localhost:3000/-/metrics for + # debugging purposes + return true if Rails.env.development? && request.local? + ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.client_ip) } end diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index 65d14781d92..d43f5393ecc 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -3,6 +3,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController include ParamsBackwardCompatibility include RendersMemberAccess + include OnboardingExperimentHelper prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) } before_action :set_non_archived_param diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 09cbc052c76..8f6fcb362d2 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -10,6 +10,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController def index @sort = params[:sort] @todos = @todos.page(params[:page]) + @todos = @todos.with_entity_associations return if redirect_out_of_range(@todos) end diff --git a/app/controllers/groups/clusters_controller.rb b/app/controllers/groups/clusters_controller.rb index b846fb21266..92602fd8096 100644 --- a/app/controllers/groups/clusters_controller.rb +++ b/app/controllers/groups/clusters_controller.rb @@ -4,7 +4,6 @@ class Groups::ClustersController < Clusters::ClustersController include ControllerWithCrossProjectAccessCheck prepend_before_action :group - prepend_before_action :check_group_clusters_feature_flag! requires_cross_project_access layout 'group' @@ -18,12 +17,4 @@ class Groups::ClustersController < Clusters::ClustersController def group @group ||= find_routable!(Group, params[:group_id] || params[:id]) end - - def check_group_clusters_feature_flag! - render_404 unless group_clusters_enabled? - end - - def group_clusters_enabled? - group.group_clusters_enabled? - end end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index e936d771502..797833e3f91 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -7,6 +7,10 @@ class GroupsController < Groups::ApplicationController include PreviewMarkdown include RecordUserLastActivity + before_action do + push_frontend_feature_flag(:manual_sorting) + end + respond_to :html prepend_before_action(only: [:show, :issues]) { authenticate_sessionless_user!(:rss) } @@ -197,8 +201,7 @@ class GroupsController < Groups::ApplicationController params[:sort] ||= 'latest_activity_desc' options = {} - options[:only_owned] = true if params[:shared] == '0' - options[:only_shared] = true if params[:shared] == '1' + options[:include_subgroups] = true @projects = GroupProjectsFinder.new(params: params, group: group, options: options, current_user: current_user) .execute diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 80e4f54bbf4..b1f285f76d7 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -12,6 +12,11 @@ class Projects::ApplicationController < ApplicationController helper_method :repository, :can_collaborate_with_project?, :user_access + rescue_from Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError do |exception| + log_exception(exception) + render_404 + end + private def project @@ -87,10 +92,4 @@ class Projects::ApplicationController < ApplicationController def check_issues_available! return render_404 unless @project.feature_available?(:issues, current_user) end - - def allow_gitaly_ref_name_caching - ::Gitlab::GitalyClient.allow_ref_name_caching do - yield - end - end end diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 95897aaf980..14b02993e6e 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Projects::BoardsController < Projects::ApplicationController - include BoardsActions + include MultipleBoardsActions include IssuableCollections before_action :check_issues_available! diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index fc708400657..d77f64a84f5 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -25,15 +25,6 @@ class Projects::BranchesController < Projects::ApplicationController @refs_pipelines = @project.ci_pipelines.latest_successful_for_refs(@branches.map(&:name)) @merged_branch_names = repository.merged_branch_names(@branches.map(&:name)) - # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/48097 - Gitlab::GitalyClient.allow_n_plus_1_calls do - @max_commits = @branches.reduce(0) do |memo, branch| - diverging_commit_counts = repository.diverging_commit_counts(branch) - [memo, diverging_commit_counts.values_at(:behind, :ahead, :distance)] - .flatten.compact.max - end - end - # https://gitlab.com/gitlab-org/gitlab-ce/issues/48097 Gitlab::GitalyClient.allow_n_plus_1_calls do render @@ -51,6 +42,19 @@ class Projects::BranchesController < Projects::ApplicationController @branches = @repository.recent_branches end + def diverging_commit_counts + respond_to do |format| + format.json do + service = Branches::DivergingCommitCountsService.new(repository) + branches = BranchesFinder.new(repository, params.permit(names: [])).execute + + Gitlab::GitalyClient.allow_n_plus_1_calls do + render json: branches.to_h { |branch| [branch.name, service.call(branch)] } + end + end + end + end + # rubocop: disable CodeReuse/ActiveRecord def create branch_name = strip_tags(sanitize(params[:branch_name])) @@ -64,8 +68,9 @@ class Projects::BranchesController < Projects::ApplicationController success = (result[:status] == :success) if params[:issue_iid] && success - issue = IssuesFinder.new(current_user, project_id: @project.id).find_by(iid: params[:issue_iid]) - SystemNoteService.new_issue_branch(issue, @project, current_user, branch_name) if issue + target_project = confidential_issue_project || @project + issue = IssuesFinder.new(current_user, project_id: target_project.id).find_by(iid: params[:issue_iid]) + SystemNoteService.new_issue_branch(issue, target_project, current_user, branch_name, branch_project: @project) if issue end respond_to do |format| @@ -162,4 +167,15 @@ class Projects::BranchesController < Projects::ApplicationController @branches = Kaminari.paginate_array(@branches).page(params[:page]) end end + + def confidential_issue_project + return unless Feature.enabled?(:create_confidential_merge_request, @project) + return if params[:confidential_issue_project_id].blank? + + confidential_issue_project = Project.find(params[:confidential_issue_project_id]) + + return unless can?(current_user, :update_issue, confidential_issue_project) + + confidential_issue_project + end end diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 7a1700a206a..ac1c4bc7fd3 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -46,18 +46,14 @@ class Projects::ForksController < Projects::ApplicationController @forked_project ||= ::Projects::ForkService.new(project, current_user, namespace: namespace).execute - if @forked_project.saved? && @forked_project.forked? - if @forked_project.import_in_progress? - redirect_to project_import_path(@forked_project, continue: continue_params) - else - if continue_params - redirect_to continue_params[:to], notice: continue_params[:notice] - else - redirect_to project_path(@forked_project), notice: "The project '#{@forked_project.name}' was successfully forked." - end - end - else + if !@forked_project.saved? || !@forked_project.forked? render :error + elsif @forked_project.import_in_progress? + redirect_to project_import_path(@forked_project, continue: continue_params) + elsif continue_params[:to] + redirect_to continue_params[:to], notice: continue_params[:notice] + else + redirect_to project_path(@forked_project), notice: "The project '#{@forked_project.name}' was successfully forked." end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index afbf9fd7720..da32ab9e2e0 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -23,7 +23,7 @@ class Projects::ImportsController < Projects::ApplicationController def show if @project.import_finished? - if continue_params&.key?(:to) + if continue_params[:to] redirect_to continue_params[:to], notice: continue_params[:notice] else redirect_to project_path(@project), notice: finished_notice @@ -31,11 +31,7 @@ class Projects::ImportsController < Projects::ApplicationController elsif @project.import_failed? redirect_to new_project_import_path(@project) else - if continue_params && continue_params[:notice_now] - flash.now[:notice] = continue_params[:notice_now] - end - - # Render + flash.now[:notice] = continue_params[:notice_now] end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index b16f3dd9d82..e275b417784 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -10,6 +10,10 @@ class Projects::IssuesController < Projects::ApplicationController include SpammableActions include RecordUserLastActivity + before_action do + push_frontend_feature_flag(:manual_sorting) + end + def issue_except_actions %i[index calendar new create bulk_update import_csv] end @@ -168,6 +172,7 @@ class Projects::IssuesController < Projects::ApplicationController def create_merge_request create_params = params.slice(:branch_name, :ref).merge(issue_iid: issue.iid) + create_params[:target_project_id] = params[:target_project_id] if Feature.enabled?(:create_confidential_merge_request, @project) result = ::MergeRequests::CreateFromIssueService.new(project, current_user, create_params).execute if result[:status] == :success diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index d7c0039b234..02ff6e872c9 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -103,7 +103,7 @@ class Projects::JobsController < Projects::ApplicationController @build.cancel - if continue_params + if continue_params[:to] redirect_to continue_params[:to] else redirect_to builds_project_pipeline_path(@project, @build.pipeline.id) diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb index f2a6268b3e9..dcc272aecff 100644 --- a/app/controllers/projects/merge_requests/application_controller.rb +++ b/app/controllers/projects/merge_requests/application_controller.rb @@ -51,4 +51,11 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont Ci::Pipeline.none end end + + def close_merge_request_if_no_source_project + return if @merge_request.source_project + return unless @merge_request.open? + + @merge_request.close + end end diff --git a/app/controllers/projects/merge_requests/content_controller.rb b/app/controllers/projects/merge_requests/content_controller.rb new file mode 100644 index 00000000000..6e026b83ee3 --- /dev/null +++ b/app/controllers/projects/merge_requests/content_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Projects::MergeRequests::ContentController < Projects::MergeRequests::ApplicationController + # @merge_request.check_mergeability is not executed here since + # widget serializer calls it via mergeable? method + # but we might want to call @merge_request.check_mergeability + # for other types of serialization + + before_action :close_merge_request_if_no_source_project + around_action :allow_gitaly_ref_name_caching + + def widget + respond_to do |format| + format.json do + Gitlab::PollingInterval.set_header(response, interval: 10_000) + + serializer = MergeRequestSerializer.new(current_user: current_user, project: merge_request.project) + render json: serializer.represent(merge_request, serializer: 'widget') + end + end + end +end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index fc37ce1dbc4..7ee8e0ea8f8 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -235,12 +235,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo params[:auto_merge_strategy].present? || params[:merge_when_pipeline_succeeds].present? end - def close_merge_request_if_no_source_project - if !@merge_request.source_project && @merge_request.open? - @merge_request.close - end - end - private def ci_environments_status_on_merge_result? diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index b3447812ef2..b4ca9074ca9 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -55,6 +55,7 @@ class Projects::RefsController < Projects::ApplicationController format.html { render_404 } format.json do response.headers["More-Logs-Url"] = @more_log_url if summary.more? + response.headers["More-Logs-Offset"] = summary.next_offset if summary.more? render json: @logs end diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index 6d60117c37d..e205e2fd4f8 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -46,6 +46,8 @@ module Projects repository.save! if repository.has_tags? end end + rescue ContainerRegistry::Path::InvalidRegistryPathError + @character_error = true end end end diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index ac3004d069f..bc2ce15286f 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -99,7 +99,7 @@ module Projects end def deploy_token_params - params.require(:deploy_token).permit(:name, :expires_at, :read_repository, :read_registry) + params.require(:deploy_token).permit(:name, :expires_at, :read_repository, :read_registry, :username) end end end diff --git a/app/controllers/projects/templates_controller.rb b/app/controllers/projects/templates_controller.rb index 7ceea4e5b96..f987033a26c 100644 --- a/app/controllers/projects/templates_controller.rb +++ b/app/controllers/projects/templates_controller.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true class Projects::TemplatesController < Projects::ApplicationController - before_action :authenticate_user!, :get_template_class + before_action :authenticate_user! + before_action :authorize_can_read_issuable! + before_action :get_template_class def show template = @template_type.find(params[:key], project) @@ -13,9 +15,20 @@ class Projects::TemplatesController < Projects::ApplicationController private + # User must have: + # - `read_merge_request` to see merge request templates, or + # - `read_issue` to see issue templates + # + # Note params[:template_type] has a route constraint to limit it to + # `merge_request` or `issue` + def authorize_can_read_issuable! + action = [:read_, params[:template_type]].join + + authorize_action!(action) + end + def get_template_class template_types = { issue: Gitlab::Template::IssueTemplate, merge_request: Gitlab::Template::MergeRequestTemplate }.with_indifferent_access @template_type = template_types[params[:template_type]] - render json: [], status: :not_found unless @template_type end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 12db493978b..330e2d0f8a5 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -298,7 +298,7 @@ class ProjectsController < Projects::ApplicationController elsif @project.feature_available?(:issues, current_user) @issues = issuables_collection.page(params[:page]) @collection_type = 'Issue' - @issuable_meta_data = issuable_meta_data(@issues, @collection_type) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type, current_user) end render :show diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 07b38371ab9..b2b151bbcf0 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -3,6 +3,7 @@ class RegistrationsController < Devise::RegistrationsController include Recaptcha::Verify include AcceptsPendingInvitations + include RecaptchaExperimentHelper prepend_before_action :check_captcha, only: :create before_action :whitelist_query_limiting, only: [:destroy] @@ -15,13 +16,6 @@ class RegistrationsController < Devise::RegistrationsController end def create - # To avoid duplicate form fields on the login page, the registration form - # names fields using `new_user`, but Devise still wants the params in - # `user`. - if params["new_#{resource_name}"].present? && params[resource_name].blank? - params[resource_name] = params.delete(:"new_#{resource_name}") - end - accept_pending_invitations super do |new_user| @@ -74,19 +68,35 @@ class RegistrationsController < Devise::RegistrationsController end def after_sign_up_path_for(user) - Gitlab::AppLogger.info("User Created: username=#{user.username} email=#{user.email} ip=#{request.remote_ip} confirmed:#{user.confirmed?}") + Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?)) user.confirmed? ? stored_location_for(user) || dashboard_projects_path : users_almost_there_path end def after_inactive_sign_up_path_for(resource) - Gitlab::AppLogger.info("User Created: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip} confirmed:false") + Gitlab::AppLogger.info(user_created_message) users_almost_there_path end private + def user_created_message(confirmed: false) + "User Created: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip} confirmed:#{confirmed}" + end + + def ensure_correct_params! + # To avoid duplicate form fields on the login page, the registration form + # names fields using `new_user`, but Devise still wants the params in + # `user`. + if params["new_#{resource_name}"].present? && params[resource_name].blank? + params[resource_name] = params.delete(:"new_#{resource_name}") + end + end + def check_captcha - return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true) + ensure_correct_params! + + return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true) # reCAPTCHA on the UI will still display however + return unless show_recaptcha_sign_up? return unless Gitlab::Recaptcha.load_configurations! return if verify_recaptcha diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index a80ab3bcd28..8c674be58c5 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -5,6 +5,8 @@ class SearchController < ApplicationController include SearchHelper include RendersCommits + around_action :allow_gitaly_ref_name_caching + skip_before_action :authenticate_user! requires_cross_project_access if: -> do search_term_present = params[:search].present? || params[:term].present? diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb index eee14b0faf4..612897f27e6 100644 --- a/app/controllers/snippets/notes_controller.rb +++ b/app/controllers/snippets/notes_controller.rb @@ -5,8 +5,8 @@ class Snippets::NotesController < ApplicationController include ToggleAwardEmoji skip_before_action :authenticate_user!, only: [:index] - before_action :snippet - before_action :authorize_read_snippet!, only: [:show, :index, :create] + before_action :authorize_read_snippet!, only: [:show, :index] + before_action :authorize_create_note!, only: [:create] private @@ -33,4 +33,8 @@ class Snippets::NotesController < ApplicationController def authorize_read_snippet! return render_404 unless can?(current_user, :read_personal_snippet, snippet) end + + def authorize_create_note! + access_denied! unless can?(current_user, :create_note, noteable) + end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 8ea5450b4e8..fad036b8df8 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -137,7 +137,7 @@ class SnippetsController < ApplicationController def move_temporary_files params[:files].each do |file| - FileMover.new(file, @snippet).execute + FileMover.new(file, from_model: current_user, to_model: @snippet).execute end end end diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 5d28635232b..94bd18f70d4 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -41,7 +41,11 @@ class UploadsController < ApplicationController when Note can?(current_user, :read_project, model.project) when User - true + # We validate the current user has enough (writing) + # access to itself when a secret is given. + # For instance, user avatars are readable by anyone, + # while temporary, user snippet uploads are not. + !secret? || can?(current_user, :update_user, model) when Appearance true else @@ -56,9 +60,13 @@ class UploadsController < ApplicationController def authorize_create_access! return unless model - # for now we support only personal snippets comments. Only personal_snippet - # is allowed as a model to #create through routing. - authorized = can?(current_user, :create_note, model) + authorized = + case model + when User + can?(current_user, :update_user, model) + else + can?(current_user, :create_note, model) + end render_unauthorized unless authorized end @@ -75,6 +83,10 @@ class UploadsController < ApplicationController User === model || Appearance === model end + def secret? + params[:secret].present? + end + def upload_model_class MODEL_CLASSES[params[:model]] || raise(UnknownUploadModelError) end |