diff options
Diffstat (limited to 'app/controllers')
44 files changed, 269 insertions, 99 deletions
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 2ce26de1768..a94726887d9 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -1,4 +1,6 @@ class Admin::GroupsController < Admin::ApplicationController + include MembersPresentation + before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update] def index @@ -10,8 +12,10 @@ class Admin::GroupsController < Admin::ApplicationController def show @group = Group.with_statistics.joins(:route).group('routes.path').find_by_full_path(params[:id]) - @members = @group.members.order("access_level DESC").page(params[:members_page]) - @requesters = AccessRequestsFinder.new(@group).execute(current_user) + @members = present_members( + @group.members.order("access_level DESC").page(params[:members_page])) + @requesters = present_members( + AccessRequestsFinder.new(@group).execute(current_user)) @projects = @group.projects.with_statistics.page(params[:projects_page]) end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 50cf2643390..3afe66c3566 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -1,4 +1,6 @@ class Admin::ProjectsController < Admin::ApplicationController + include MembersPresentation + before_action :project, only: [:show, :transfer, :repository_check] before_action :group, only: [:show, :transfer] @@ -19,11 +21,14 @@ class Admin::ProjectsController < Admin::ApplicationController def show if @group - @group_members = @group.members.order("access_level DESC").page(params[:group_members_page]) + @group_members = present_members( + @group.members.order("access_level DESC").page(params[:group_members_page])) end - @project_members = @project.members.page(params[:project_members_page]) - @requesters = AccessRequestsFinder.new(@project).execute(current_user) + @project_members = present_members( + @project.members.page(params[:project_members_page])) + @requesters = present_members( + AccessRequestsFinder.new(@project).execute(current_user)) end def transfer diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index cde1e284d2d..86bade49ec9 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -8,12 +8,12 @@ class AutocompleteController < ApplicationController def users @users = AutocompleteUsersFinder.new(params: params, current_user: current_user, project: @project, group: @group).execute - render json: @users, only: [:name, :username, :id], methods: [:avatar_url] + render json: UserSerializer.new.represent(@users) end def user @user = User.find(params[:id]) - render json: @user, only: [:name, :username, :id], methods: [:avatar_url] + render json: UserSerializer.new.represent(@user) end def projects diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb index 2c9c095a5d7..a145049dc7d 100644 --- a/app/controllers/concerns/boards_responses.rb +++ b/app/controllers/concerns/boards_responses.rb @@ -24,11 +24,11 @@ module BoardsResponses end def respond_with_boards - respond_with(@boards) + respond_with(@boards) # rubocop:disable Gitlab/ModuleWithInstanceVariables end def respond_with_board - respond_with(@board) + respond_with(@board) # rubocop:disable Gitlab/ModuleWithInstanceVariables end def respond_with(resource) diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 782f0be9c4a..6f4fdcdaa4f 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -1,6 +1,8 @@ module CreatesCommit extend ActiveSupport::Concern + include Gitlab::Utils::StrongMemoize + # rubocop:disable Gitlab/ModuleWithInstanceVariables def create_commit(service, success_path:, failure_path:, failure_view: nil, success_notice: nil) if can?(current_user, :push_code, @project) @project_to_commit_into = @project @@ -45,6 +47,7 @@ module CreatesCommit end end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def authorize_edit_tree! return if can_collaborate_with_project? @@ -77,6 +80,7 @@ module CreatesCommit end end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def new_merge_request_path project_new_merge_request_path( @project_to_commit_into, @@ -88,20 +92,28 @@ module CreatesCommit } ) end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def existing_merge_request_path - project_merge_request_path(@project, @merge_request) + project_merge_request_path(@project, @merge_request) # rubocop:disable Gitlab/ModuleWithInstanceVariables end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def merge_request_exists? - return @merge_request if defined?(@merge_request) - - @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened - .find_by(source_project_id: @project_to_commit_into, source_branch: @branch_name, target_branch: @start_branch) + strong_memoize(:merge_request) do + MergeRequestsFinder.new(current_user, project_id: @project.id) + .execute + .opened + .find_by( + source_project_id: @project_to_commit_into, + source_branch: @branch_name, + target_branch: @start_branch) + end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def different_project? - @project_to_commit_into != @project + @project_to_commit_into != @project # rubocop:disable Gitlab/ModuleWithInstanceVariables end def create_merge_request? @@ -109,6 +121,6 @@ module CreatesCommit # as the target branch in the same project, # we don't want to create a merge request. params[:create_merge_request].present? && - (different_project? || @start_branch != @branch_name) + (different_project? || @start_branch != @branch_name) # rubocop:disable Gitlab/ModuleWithInstanceVariables end end diff --git a/app/controllers/concerns/group_tree.rb b/app/controllers/concerns/group_tree.rb index 9d4f97aa443..b10147835f3 100644 --- a/app/controllers/concerns/group_tree.rb +++ b/app/controllers/concerns/group_tree.rb @@ -1,4 +1,5 @@ module GroupTree + # rubocop:disable Gitlab/ModuleWithInstanceVariables def render_group_tree(groups) @groups = if params[:filter].present? Gitlab::GroupHierarchy.new(groups.search(params[:filter])) @@ -20,5 +21,6 @@ module GroupTree render json: serializer.represent(@groups) end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables end end diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index 744e448e8df..74a4f437dc8 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -17,15 +17,15 @@ module IssuableActions end def update - @issuable = update_service.execute(issuable) + @issuable = update_service.execute(issuable) # rubocop:disable Gitlab/ModuleWithInstanceVariables respond_to do |format| format.html do - recaptcha_check_with_fallback { render :edit } + recaptcha_check_if_spammable { render :edit } end format.json do - render_entity_json + recaptcha_check_if_spammable(false) { render_entity_json } end end @@ -55,7 +55,6 @@ module IssuableActions def destroy Issuable::DestroyService.new(issuable.project, current_user).execute(issuable) - TodoService.new.destroy_issuable(issuable, current_user) name = issuable.human_class_name flash[:notice] = "The #{name} was successfully deleted." @@ -80,10 +79,16 @@ module IssuableActions private + def recaptcha_check_if_spammable(should_redirect = true, &block) + return yield unless issuable.is_a? Spammable + + recaptcha_check_with_fallback(should_redirect, &block) + end + def render_conflict_response respond_to do |format| format.html do - @conflict = true + @conflict = true # rubocop:disable Gitlab/ModuleWithInstanceVariables render :edit end @@ -98,7 +103,7 @@ module IssuableActions end def labels - @labels ||= LabelsFinder.new(current_user, project_id: @project.id).execute + @labels ||= LabelsFinder.new(current_user, project_id: @project.id).execute # rubocop:disable Gitlab/ModuleWithInstanceVariables end def authorize_destroy_issuable! @@ -108,7 +113,7 @@ module IssuableActions end def authorize_admin_issuable! - unless can?(current_user, :"admin_#{resource_name}", @project) + unless can?(current_user, :"admin_#{resource_name}", @project) # rubocop:disable Gitlab/ModuleWithInstanceVariables return access_denied! end end @@ -142,6 +147,7 @@ module IssuableActions @resource_name ||= controller_name.singularize end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def render_entity_json if @issuable.valid? render json: serializer.represent(@issuable) @@ -149,6 +155,7 @@ module IssuableActions render json: { errors: @issuable.errors.full_messages }, status: :unprocessable_entity end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def serializer raise NotImplementedError @@ -159,6 +166,6 @@ module IssuableActions end def parent - @project || @group + @project || @group # rubocop:disable Gitlab/ModuleWithInstanceVariables end end diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index f3c9251225f..b25e753a5ad 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -2,6 +2,7 @@ module IssuableCollections extend ActiveSupport::Concern include SortingHelper include Gitlab::IssuableMetadata + include Gitlab::Utils::StrongMemoize included do helper_method :finder @@ -9,6 +10,7 @@ module IssuableCollections private + # rubocop:disable Gitlab/ModuleWithInstanceVariables def set_issuables_index @issuables = issuables_collection @issuables = @issuables.page(params[:page]) @@ -33,6 +35,7 @@ module IssuableCollections @users.push(author) if author end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def issuables_collection finder.execute.preload(preload_for_collection) @@ -41,7 +44,7 @@ module IssuableCollections def redirect_out_of_range(total_pages) return false if total_pages.zero? - out_of_range = @issuables.current_page > total_pages + out_of_range = @issuables.current_page > total_pages # rubocop:disable Gitlab/ModuleWithInstanceVariables if out_of_range redirect_to(url_for(params.merge(page: total_pages, only_path: true))) @@ -51,7 +54,7 @@ module IssuableCollections end def issuable_page_count - page_count_for_relation(@issuables, finder.row_count) + page_count_for_relation(@issuables, finder.row_count) # rubocop:disable Gitlab/ModuleWithInstanceVariables end def page_count_for_relation(relation, row_count) @@ -66,6 +69,7 @@ module IssuableCollections finder_class.new(current_user, filter_params) end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def filter_params set_sort_order_from_cookie set_default_state @@ -90,6 +94,7 @@ module IssuableCollections @filter_params.permit(IssuableFinder::VALID_PARAMS) end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def set_default_state params[:state] = 'opened' if params[:state].blank? @@ -129,9 +134,9 @@ module IssuableCollections end def finder - return @finder if defined?(@finder) - - @finder = issuable_finder_for(@finder_type) + strong_memoize(:finder) do + issuable_finder_for(@finder_type) # rubocop:disable Gitlab/ModuleWithInstanceVariables + end end def collection_type diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index ad594903331..3ba1235cee0 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -2,10 +2,9 @@ module IssuesAction extend ActiveSupport::Concern include IssuableCollections + # rubocop:disable Gitlab/ModuleWithInstanceVariables def issues @finder_type = IssuesFinder - @label = finder.labels.first - @issues = issuables_collection .non_archived .page(params[:page]) @@ -17,4 +16,5 @@ module IssuesAction format.atom { render layout: 'xml.atom' } end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables end diff --git a/app/controllers/concerns/members_presentation.rb b/app/controllers/concerns/members_presentation.rb new file mode 100644 index 00000000000..c0622516fd3 --- /dev/null +++ b/app/controllers/concerns/members_presentation.rb @@ -0,0 +1,11 @@ +module MembersPresentation + extend ActiveSupport::Concern + + def present_members(members) + Gitlab::View::Presenter::Factory.new( + members, + current_user: current_user, + presenter_class: MembersPresenter + ).fabricate! + end +end diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index 8b569a01afd..a9cc13038bf 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -2,14 +2,15 @@ module MergeRequestsAction extend ActiveSupport::Concern include IssuableCollections + # rubocop:disable Gitlab/ModuleWithInstanceVariables def merge_requests @finder_type = MergeRequestsFinder - @label = finder.labels.first @merge_requests = issuables_collection.page(params[:page]) @issuable_meta_data = issuable_meta_data(@merge_requests, collection_type) end + # rubocop:enable Gitlab/ModuleWithInstanceVariables private diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb index 081f3336780..d92cf8b4894 100644 --- a/app/controllers/concerns/milestone_actions.rb +++ b/app/controllers/concerns/milestone_actions.rb @@ -6,7 +6,7 @@ module MilestoneActions format.html { redirect_to milestone_redirect_path } format.json do render json: tabs_json("shared/milestones/_merge_requests_tab", { - merge_requests: @milestone.sorted_merge_requests, + merge_requests: @milestone.sorted_merge_requests, # rubocop:disable Gitlab/ModuleWithInstanceVariables show_project_name: true }) end @@ -18,7 +18,7 @@ module MilestoneActions format.html { redirect_to milestone_redirect_path } format.json do render json: tabs_json("shared/milestones/_participants_tab", { - users: @milestone.participants + users: @milestone.participants # rubocop:disable Gitlab/ModuleWithInstanceVariables }) end end @@ -29,7 +29,7 @@ module MilestoneActions format.html { redirect_to milestone_redirect_path } format.json do render json: tabs_json("shared/milestones/_labels_tab", { - labels: @milestone.labels + labels: @milestone.labels # rubocop:disable Gitlab/ModuleWithInstanceVariables }) end end @@ -43,6 +43,7 @@ module MilestoneActions } end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def milestone_redirect_path if @project project_milestone_path(@project, @milestone) @@ -52,4 +53,5 @@ module MilestoneActions dashboard_milestone_path(@milestone.safe_title, title: @milestone.title) end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables end diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index be2e1b47feb..e82a5650935 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -1,5 +1,6 @@ module NotesActions include RendersNotes + include Gitlab::Utils::StrongMemoize extend ActiveSupport::Concern included do @@ -30,6 +31,7 @@ module NotesActions render json: notes_json end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def create create_params = note_params.merge( merge_request_diff_head_sha: params[:merge_request_diff_head_sha], @@ -47,7 +49,9 @@ module NotesActions format.html { redirect_back_or_default } end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables + # rubocop:disable Gitlab/ModuleWithInstanceVariables def update @note = Notes::UpdateService.new(project, current_user, note_params).execute(note) @@ -60,6 +64,7 @@ module NotesActions format.html { redirect_back_or_default } end end + # rubocop:enable Gitlab/ModuleWithInstanceVariables def destroy if note.editable? @@ -138,7 +143,7 @@ module NotesActions end else template = "discussions/_diff_discussion" - @fresh_discussion = true + @fresh_discussion = true # rubocop:disable Gitlab/ModuleWithInstanceVariables locals = { discussions: [discussion], on_image: on_image } end @@ -191,7 +196,7 @@ module NotesActions end def noteable - @noteable ||= notes_finder.target || @note&.noteable + @noteable ||= notes_finder.target || @note&.noteable # rubocop:disable Gitlab/ModuleWithInstanceVariables end def require_noteable! @@ -211,20 +216,21 @@ module NotesActions end def note_project - return @note_project if defined?(@note_project) - return nil unless project + strong_memoize(:note_project) do + return nil unless project - note_project_id = params[:note_project_id] + note_project_id = params[:note_project_id] - @note_project = - if note_project_id.present? - Project.find(note_project_id) - else - project - end + the_project = + if note_project_id.present? + Project.find(note_project_id) + else + project + end - return access_denied! unless can?(current_user, :create_note, @note_project) + return access_denied! unless can?(current_user, :create_note, the_project) - @note_project + the_project + end end end diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb index 9849aa93fa6..f0a68f23566 100644 --- a/app/controllers/concerns/oauth_applications.rb +++ b/app/controllers/concerns/oauth_applications.rb @@ -14,6 +14,6 @@ module OauthApplications end def load_scopes - @scopes = Doorkeeper.configuration.scopes + @scopes ||= Doorkeeper.configuration.scopes end end diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb index e9b9e9b38bc..90bb7a87b45 100644 --- a/app/controllers/concerns/preview_markdown.rb +++ b/app/controllers/concerns/preview_markdown.rb @@ -1,6 +1,7 @@ module PreviewMarkdown extend ActiveSupport::Concern + # rubocop:disable Gitlab/ModuleWithInstanceVariables def preview_markdown result = PreviewMarkdownService.new(@project, current_user, params).execute @@ -20,4 +21,5 @@ module PreviewMarkdown } } end + # rubocop:enable Gitlab/ModuleWithInstanceVariables end diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb index bb2c1dfa00a..fb41dc1e8a8 100644 --- a/app/controllers/concerns/renders_commits.rb +++ b/app/controllers/concerns/renders_commits.rb @@ -1,6 +1,6 @@ module RendersCommits def prepare_commits_for_rendering(commits) - Banzai::CommitRenderer.render(commits, @project, current_user) + Banzai::CommitRenderer.render(commits, @project, current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables commits end diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb index 824ad06465c..e7ef297879f 100644 --- a/app/controllers/concerns/renders_notes.rb +++ b/app/controllers/concerns/renders_notes.rb @@ -1,4 +1,5 @@ module RendersNotes + # rubocop:disable Gitlab/ModuleWithInstanceVariables def prepare_notes_for_rendering(notes, noteable = nil) preload_noteable_for_regular_notes(notes) preload_max_access_for_authors(notes, @project) @@ -7,6 +8,7 @@ module RendersNotes notes end + # rubocop:enable Gitlab/ModuleWithInstanceVariables private diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb index be2e6c7f193..3d61458c064 100644 --- a/app/controllers/concerns/service_params.rb +++ b/app/controllers/concerns/service_params.rb @@ -66,7 +66,7 @@ module ServiceParams FILTER_BLANK_PARAMS = [:password].freeze def service_params - dynamic_params = @service.event_channel_names + @service.event_names + dynamic_params = @service.event_channel_names + @service.event_names # rubocop:disable Gitlab/ModuleWithInstanceVariables service_params = params.permit(:id, service: ALLOWED_PARAMS_CE + dynamic_params) if service_params[:service].is_a?(Hash) diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb index ffea712a833..9095cc7f783 100644 --- a/app/controllers/concerns/snippets_actions.rb +++ b/app/controllers/concerns/snippets_actions.rb @@ -4,6 +4,7 @@ module SnippetsActions def edit end + # rubocop:disable Gitlab/ModuleWithInstanceVariables def raw disposition = params[:inline] == 'false' ? 'attachment' : 'inline' @@ -14,6 +15,7 @@ module SnippetsActions filename: @snippet.sanitized_file_name ) end + # rubocop:enable Gitlab/ModuleWithInstanceVariables private diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index ada0dde87fb..922aa58a00f 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -2,6 +2,7 @@ module SpammableActions extend ActiveSupport::Concern include Recaptcha::Verify + include Gitlab::Utils::StrongMemoize included do before_action :authorize_submit_spammable!, only: :mark_as_spam @@ -18,13 +19,13 @@ module SpammableActions private def ensure_spam_config_loaded! - return @spam_config_loaded if defined?(@spam_config_loaded) - - @spam_config_loaded = Gitlab::Recaptcha.load_configurations! + strong_memoize(:spam_config_loaded) do + Gitlab::Recaptcha.load_configurations! + end end - def recaptcha_check_with_fallback(&fallback) - if spammable.valid? + def recaptcha_check_with_fallback(should_redirect = true, &fallback) + if should_redirect && spammable.valid? redirect_to spammable_path elsif render_recaptcha? ensure_spam_config_loaded! @@ -33,7 +34,18 @@ module SpammableActions flash[:alert] = 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.' end - render :verify + respond_to do |format| + format.html do + render :verify + end + + format.json do + locals = { spammable: spammable, script: false, has_submit: false } + recaptcha_html = render_to_string(partial: 'shared/recaptcha_form', formats: :html, locals: locals) + + render json: { recaptcha_html: recaptcha_html } + end + end else yield end diff --git a/app/controllers/concerns/toggle_subscription_action.rb b/app/controllers/concerns/toggle_subscription_action.rb index 92cb534343e..776583579e8 100644 --- a/app/controllers/concerns/toggle_subscription_action.rb +++ b/app/controllers/concerns/toggle_subscription_action.rb @@ -12,7 +12,7 @@ module ToggleSubscriptionAction private def subscribable_project - @project || raise(NotImplementedError) + @project ||= raise(NotImplementedError) end def subscribable_resource diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb index ed253042701..230bbe4b1aa 100644 --- a/app/controllers/concerns/with_performance_bar.rb +++ b/app/controllers/concerns/with_performance_bar.rb @@ -6,6 +6,7 @@ module WithPerformanceBar end def peek_enabled? + return true if Rails.env.development? return false unless Gitlab::PerformanceBar.enabled?(current_user) if RequestStore.active? diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 8fc234a62b1..21e77431176 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -1,5 +1,6 @@ class Groups::GroupMembersController < Groups::ApplicationController include MembershipActions + include MembersPresentation include SortingHelper # Authorize @@ -14,15 +15,17 @@ class Groups::GroupMembersController < Groups::ApplicationController @members = @members.search(params[:search]) if params[:search].present? @members = @members.sort(@sort) @members = @members.page(params[:page]).per(50) - @members.includes(:user) + @members = present_members(@members.includes(:user)) - @requesters = AccessRequestsFinder.new(@group).execute(current_user) + @requesters = present_members( + AccessRequestsFinder.new(@group).execute(current_user)) @group_member = @group.group_members.new end def update - @group_member = @group.group_members.find(params[:id]) + @group_member = @group.members_and_requesters.find(params[:id]) + .present(current_user: current_user) return render_403 unless can?(current_user, :update_group_member, @group_member) diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb new file mode 100644 index 00000000000..1ff25a45398 --- /dev/null +++ b/app/controllers/ide_controller.rb @@ -0,0 +1,6 @@ +class IdeController < ApplicationController + layout 'nav_only' + + def index + end +end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 68a52f40342..57761bfbe26 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -1,6 +1,8 @@ class PasswordsController < Devise::PasswordsController include Gitlab::CurrentSettings + skip_before_action :require_no_authentication, only: [:edit, :update] + before_action :resource_from_email, only: [:create] before_action :check_password_authentication_available, only: [:create] before_action :throttle_reset, only: [:create] diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 9e79852e378..6025a40348b 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -86,4 +86,8 @@ class Projects::ApplicationController < ApplicationController def require_pages_enabled! not_found unless @project.pages_available? end + + def check_issues_available! + return render_404 unless @project.feature_available?(:issues, current_user) + end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 770381472c5..d838b8dc29e 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -5,9 +5,6 @@ class Projects::BlobController < Projects::ApplicationController include RendersBlob include ActionView::Helpers::SanitizeHelper - # Raised when given an invalid file path - InvalidPathError = Class.new(StandardError) - prepend_before_action :authenticate_user!, only: [:edit] before_action :require_non_empty_project, except: [:new, :create] @@ -61,7 +58,6 @@ class Projects::BlobController < Projects::ApplicationController create_commit(Files::UpdateService, success_path: -> { after_edit_path }, failure_view: :edit, failure_path: project_blob_path(@project, @id)) - rescue Files::UpdateService::FileChangedError @conflict = true render :edit @@ -132,7 +128,6 @@ class Projects::BlobController < Projects::ApplicationController def assign_blob_vars @id = params[:id] @ref, @path = extract_ref(@id) - rescue InvalidPathError render_404 end diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index e36105ddc11..949e54ff819 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -2,6 +2,7 @@ class Projects::BoardsController < Projects::ApplicationController include BoardsResponses include IssuableCollections + before_action :check_issues_available! before_action :authorize_read_board!, only: [:index, :show] before_action :assign_endpoint_vars diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 56df9991fda..cabafe26357 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -46,14 +46,16 @@ class Projects::BranchesController < Projects::ApplicationController result = CreateBranchService.new(project, current_user) .execute(branch_name, ref) - if params[:issue_iid] + 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 end respond_to do |format| format.html do - if result[:status] == :success + if success if redirect_to_autodeploy redirect_to url_to_autodeploy_setup(project, branch_name), notice: view_context.autodeploy_flash_notice(branch_name) @@ -67,7 +69,7 @@ class Projects::BranchesController < Projects::ApplicationController end format.json do - if result[:status] == :success + if success render json: { name: branch_name, url: project_tree_url(@project, branch_name) } else render json: result[:messsage], status: :unprocessable_entity diff --git a/app/controllers/projects/clusters/gcp_controller.rb b/app/controllers/projects/clusters/gcp_controller.rb index b64f7a2a6bd..25608df0b9c 100644 --- a/app/controllers/projects/clusters/gcp_controller.rb +++ b/app/controllers/projects/clusters/gcp_controller.rb @@ -1,6 +1,7 @@ class Projects::Clusters::GcpController < Projects::ApplicationController before_action :authorize_read_cluster! before_action :authorize_google_api, except: [:login] + before_action :authorize_google_project_billing, only: [:new] before_action :authorize_create_cluster!, only: [:new, :create] def login @@ -22,15 +23,20 @@ class Projects::Clusters::GcpController < Projects::ApplicationController end def create - @cluster = ::Clusters::CreateService - .new(project, current_user, create_params) - .execute(token_in_session) + case google_project_billing_status + when 'true' + @cluster = ::Clusters::CreateService + .new(project, current_user, create_params) + .execute(token_in_session) - if @cluster.persisted? - redirect_to project_cluster_path(project, @cluster) + return redirect_to project_cluster_path(project, @cluster) if @cluster.persisted? + when 'false' + flash[:error] = _('Please enable billing for one of your projects to be able to create a cluster.') else - render :new + flash[:error] = _('We could not verify that one of your projects on GCP has billing enabled. Please try again.') end + + render :new end private @@ -39,6 +45,7 @@ class Projects::Clusters::GcpController < Projects::ApplicationController params.require(:cluster).permit( :enabled, :name, + :environment_scope, provider_gcp_attributes: [ :gcp_project_id, :zone, @@ -57,6 +64,17 @@ class Projects::Clusters::GcpController < Projects::ApplicationController end end + def authorize_google_project_billing + redis_token_key = CheckGcpProjectBillingWorker.store_session_token(token_in_session) + CheckGcpProjectBillingWorker.perform_async(redis_token_key) + end + + def google_project_billing_status + Gitlab::Redis::SharedState.with do |redis| + redis.get(CheckGcpProjectBillingWorker.redis_shared_state_key_for(token_in_session)) + end + end + def token_in_session @token_in_session ||= session[GoogleApi::CloudPlatform::Client.session_key_for_token] diff --git a/app/controllers/projects/clusters/user_controller.rb b/app/controllers/projects/clusters/user_controller.rb index d7678512073..d0db64b2fa9 100644 --- a/app/controllers/projects/clusters/user_controller.rb +++ b/app/controllers/projects/clusters/user_controller.rb @@ -26,6 +26,7 @@ class Projects::Clusters::UserController < Projects::ApplicationController params.require(:cluster).permit( :enabled, :name, + :environment_scope, platform_kubernetes_attributes: [ :namespace, :api_url, diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index 0907daacbc3..1dc7f1b3a7f 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -8,11 +8,8 @@ class Projects::ClustersController < Projects::ApplicationController STATUS_POLLING_INTERVAL = 10_000 def index - @scope = params[:scope] || 'all' - @clusters = ClustersFinder.new(project, current_user, @scope).execute.page(params[:page]) - @active_count = ClustersFinder.new(project, current_user, :active).execute.count - @inactive_count = ClustersFinder.new(project, current_user, :inactive).execute.count - @all_count = @active_count + @inactive_count + clusters = ClustersFinder.new(project, current_user, :all).execute + @clusters = clusters.page(params[:page]).per(20) end def new @@ -90,6 +87,7 @@ class Projects::ClustersController < Projects::ApplicationController if cluster.managed? params.require(:cluster).permit( :enabled, + :environment_scope, platform_kubernetes_attributes: [ :namespace ] @@ -98,6 +96,7 @@ class Projects::ClustersController < Projects::ApplicationController params.require(:cluster).permit( :enabled, :name, + :environment_scope, platform_kubernetes_attributes: [ :api_url, :token, diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index d7a3441a245..384f18b316c 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -194,10 +194,6 @@ class Projects::IssuesController < Projects::ApplicationController render_404 unless can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user) end - def check_issues_available! - return render_404 unless @project.feature_available?(:issues, current_user) - end - def render_issue_json if @issue.valid? render json: serializer.represent(@issue) diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 1c4c09c772f..4865ec3dfe5 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -110,7 +110,7 @@ class Projects::JobsController < Projects::ApplicationController def erase if @build.erase(erased_by: current_user) redirect_to project_job_path(project, @build), - notice: "Build has been successfully erased!" + notice: "Job has been successfully erased!" else respond_422 end diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index 1511fc08c89..dc524b790a0 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -9,7 +9,10 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap before_action :build_merge_request, except: [:create] def new - define_new_vars + # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/40934 + Gitlab::GitalyClient.allow_n_plus_1_calls do + define_new_vars + end end def create diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index e7b3b73024b..2e8a738b6d9 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -10,6 +10,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort] before_action :set_issuables_index, only: [:index] before_action :authenticate_user!, only: [:assign_related_issues] + before_action :check_user_can_push_to_source_branch!, only: [:rebase] def index @merge_requests = @issuables @@ -131,7 +132,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo .new(project, current_user, wip_event: 'unwip') .execute(@merge_request) - render json: serializer.represent(@merge_request) + render json: serialize_widget(@merge_request) end def commit_change_content @@ -147,7 +148,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo .new(@project, current_user) .cancel(@merge_request) - render json: serializer.represent(@merge_request) + render json: serialize_widget(@merge_request) end def merge @@ -223,6 +224,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo render json: environments end + def rebase + RebaseWorker.perform_async(@merge_request.id, current_user.id) + + render nothing: true, status: 200 + end + protected alias_method :subscribable_resource, :merge_request @@ -304,6 +311,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end end + def serialize_widget(merge_request) + serializer.represent(merge_request, serializer: 'widget') + end + def serializer MergeRequestSerializer.new(current_user: current_user, project: merge_request.project) end @@ -318,4 +329,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo @finder_type = MergeRequestsFinder super end + + def check_user_can_push_to_source_branch! + return access_denied! unless @merge_request.source_branch_exists? + + access_check = ::Gitlab::UserAccess + .new(current_user, project: @merge_request.source_project) + .can_push_to_branch?(@merge_request.source_branch) + + access_denied! unless access_check + end end diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 627cb2bd93c..5940fae8dd0 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -11,7 +11,7 @@ class Projects::NotesController < Projects::ApplicationController # Controller actions are returned from AbstractController::Base and methods of parent classes are # excluded in order to return only specific controller related methods. # That is ok for the app (no :create method in ancestors) - # but fails for tests because there is a :create method on FactoryGirl (one of the ancestors) + # but fails for tests because there is a :create method on FactoryBot (one of the ancestors) # # see https://github.com/rails/rails/blob/v4.2.7/actionpack/lib/abstract_controller/base.rb#L78 # diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index ec7c645df5a..b478e7b5e05 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -1,9 +1,11 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :schedule, except: [:index, :new, :create] + before_action :play_rate_limit, only: [:play] + before_action :authorize_play_pipeline_schedule!, only: [:play] before_action :authorize_read_pipeline_schedule! before_action :authorize_create_pipeline_schedule!, only: [:new, :create] - before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create] + before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play] before_action :authorize_admin_pipeline_schedule!, only: [:destroy] def index @@ -40,6 +42,18 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController end end + def play + job_id = RunPipelineScheduleWorker.perform_async(schedule.id, current_user.id) + + if job_id + flash[:notice] = "Successfully scheduled a pipeline to run. Go to the <a href=\"#{project_pipelines_path(@project)}\">Pipelines page</a> for details.".html_safe + else + flash[:alert] = 'Unable to schedule a pipeline to run immediately' + end + + redirect_to pipeline_schedules_path(@project) + end + def take_ownership if schedule.update(owner: current_user) redirect_to pipeline_schedules_path(@project) @@ -60,6 +74,17 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController private + def play_rate_limit + return unless current_user + + limiter = ::Gitlab::ActionRateLimiter.new(action: :play_pipeline_schedule) + + return unless limiter.throttled?([current_user, schedule], 1) + + flash[:alert] = 'You cannot play this scheduled pipeline at the moment. Please wait a minute.' + redirect_to pipeline_schedules_path(@project) + end + def schedule @schedule ||= project.pipeline_schedules.find(params[:id]) end @@ -70,6 +95,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController variables_attributes: [:id, :key, :value, :_destroy] ) end + def authorize_play_pipeline_schedule! + return access_denied! unless can?(current_user, :play_pipeline_schedule, schedule) + end + def authorize_update_pipeline_schedule! return access_denied! unless can?(current_user, :update_pipeline_schedule, schedule) end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 7ad7b3003af..e146d0d3cd5 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -29,6 +29,8 @@ class Projects::PipelinesController < Projects::ApplicationController @pipelines_count = PipelinesFinder .new(project).execute.count + @pipelines.map(&:commit) # List commits for batch loading + respond_to do |format| format.html format.json do diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index d925dcd21ff..d7372beb9d3 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -1,5 +1,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController include MembershipActions + include MembersPresentation include SortingHelper # Authorize @@ -20,13 +21,14 @@ class Projects::ProjectMembersController < Projects::ApplicationController @group_links = @group_links.where(group_id: @project.invited_groups.search(params[:search]).select(:id)) end - @project_members = @project_members.sort(@sort).page(params[:page]) - @requesters = AccessRequestsFinder.new(@project).execute(current_user) + @project_members = present_members(@project_members.sort(@sort).page(params[:page])) + @requesters = present_members(AccessRequestsFinder.new(@project).execute(current_user)) @project_member = @project.project_members.new end def update - @project_member = @project.project_members.find(params[:id]) + @project_member = @project.members_and_requesters.find(params[:id]) + .present(current_user: current_user) return render_403 unless can?(current_user, :update_project_member, @project_member) diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 9f9773575a5..c950d0f7001 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -29,17 +29,17 @@ class Projects::RunnersController < Projects::ApplicationController def resume if Ci::UpdateRunnerService.new(@runner).update(active: true) - redirect_to runner_path(@runner), notice: 'Runner was successfully updated.' + redirect_to runners_path(@project), notice: 'Runner was successfully updated.' else - redirect_to runner_path(@runner), alert: 'Runner was not updated.' + redirect_to runners_path(@project), alert: 'Runner was not updated.' end end def pause if Ci::UpdateRunnerService.new(@runner).update(active: false) - redirect_to runner_path(@runner), notice: 'Runner was successfully updated.' + redirect_to runners_path(@project), notice: 'Runner was successfully updated.' else - redirect_to runner_path(@runner), alert: 'Runner was not updated.' + redirect_to runners_path(@project), alert: 'Runner was not updated.' end end diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index b029b31f9af..86717bb7242 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -11,6 +11,16 @@ module Projects define_auto_devops_variables end + def reset_cache + if ResetProjectCacheService.new(@project, current_user).execute + flash[:notice] = _("Project cache successfully reset.") + else + flash[:error] = _("Unable to reset project cache.") + end + + redirect_to project_pipelines_path(@project) + end + private def define_runners_variables diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index f3719059f88..f752a46f828 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -26,6 +26,7 @@ class Projects::TreeController < Projects::ApplicationController respond_to do |format| format.html do + lfs_blob_ids @last_commit = @repository.last_commit_for_path(@commit.id, @tree.path) || @commit end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3882fa4791d..6f229b08c0c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -9,6 +9,7 @@ class ProjectsController < Projects::ApplicationController before_action :repository, except: [:index, :new, :create] before_action :assign_ref_vars, only: [:show], if: :repo_exists? before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?] + before_action :lfs_blob_ids, only: [:show], if: [:repo_exists?, :project_view_files?] before_action :project_export_enabled, only: [:export, :download_export, :remove_export, :generate_new_export] # Authorize @@ -272,7 +273,7 @@ class ProjectsController < Projects::ApplicationController render 'projects/empty' if @project.empty_repo? else - if @project.wiki_enabled? + if can?(current_user, :read_wiki, @project) @project_wiki = @project.wiki @wiki_home = @project_wiki.find_page('home', params[:version_id]) elsif @project.feature_available?(:issues, current_user) @@ -352,7 +353,7 @@ class ProjectsController < Projects::ApplicationController end def repo_exists? - project.repository_exists? && !project.empty_repo? && project.repo + project.repository_exists? && !project.empty_repo? rescue Gitlab::Git::Repository::NoRepository project.repository.expire_exists_cache |