From 698515313fe38fb3f85fdeec1efa15e2c8b54cfd Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Tue, 15 May 2018 12:25:51 +0200 Subject: Fixes rejected pushes from maintainers Before the push git would make a call to `/:namespace/:project/git-receive-pack`. This would perform an access check without a ref. So the `Project#branch_allows_maintainer_push?` would return false. This adjusts `Project#branch_allows_maintainer_push?` to return true when passing no branch name if there are merge requests open that would allow the user to push. The actual check then happens when a call to `/api/v4/internal/allowed` is made from a git hook. --- app/models/project.rb | 12 ++++++++---- .../unreleased/bvl-fix-maintainer-push-rejected.yml | 6 ++++++ spec/models/project_spec.rb | 5 +++++ spec/requests/git_http_spec.rb | 17 +++++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/bvl-fix-maintainer-push-rejected.yml diff --git a/app/models/project.rb b/app/models/project.rb index 9ca733ecd98..57da42adc28 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -2139,10 +2139,14 @@ class Project < ActiveRecord::Base check_access = -> do next false if empty_repo? - merge_request = source_of_merge_requests.opened - .where(allow_collaboration: true) - .find_by(source_branch: branch_name) - merge_request&.can_be_merged_by?(user) + merge_requests = source_of_merge_requests.opened + .where(allow_collaboration: true) + + if branch_name + merge_requests.find_by(source_branch: branch_name)&.can_be_merged_by?(user) + else + merge_requests.any? { |merge_request| merge_request.can_be_merged_by?(user) } + end end if RequestStore.active? diff --git a/changelogs/unreleased/bvl-fix-maintainer-push-rejected.yml b/changelogs/unreleased/bvl-fix-maintainer-push-rejected.yml new file mode 100644 index 00000000000..54154ad2449 --- /dev/null +++ b/changelogs/unreleased/bvl-fix-maintainer-push-rejected.yml @@ -0,0 +1,6 @@ +--- +title: Fix bug where maintainer would not be allowed to push to forks with merge requests + that have `Allow maintainer edits` enabled. +merge_request: 18968 +author: +type: fixed diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index b9a9c4ebf42..58928465f95 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -3658,6 +3658,11 @@ describe Project do .to be_truthy end + it 'allows access when there are merge requests open but no branch name is given' do + expect(project.branch_allows_collaboration?(user, nil)) + .to be_truthy + end + it 'does not allow guest users access' do guest = create(:user) target_project.add_guest(guest) diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index 2514dab1714..92fcfb65269 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -1,6 +1,7 @@ require "spec_helper" describe 'Git HTTP requests' do + include ProjectForksHelper include TermsHelper include GitHttpHelpers include WorkhorseHelpers @@ -305,6 +306,22 @@ describe 'Git HTTP requests' do expect(response.body).to eq(change_access_error(:push_code)) end end + + context 'when merge requests are open that allow maintainer access' do + let(:canonical_project) { create(:project, :public, :repository) } + let(:project) { fork_project(canonical_project, nil, repository: true) } + + before do + canonical_project.add_master(user) + create(:merge_request, + source_project: project, + target_project: canonical_project, + source_branch: 'fixes', + allow_collaboration: true) + end + + it_behaves_like 'pushes are allowed' + end end end -- cgit v1.2.3