Commit fc3ebbc0 authored by Luke Duncalfe's avatar Luke Duncalfe

Use owner for git actions during designs copy

When moving an issue we copy the design collection. Copying the design
collection involves adding commits to the design repository. Some users
have permission to move the issue (`:admin_issue` on the target
project), but not permission to push to the design repository of that
project and are being denied by
`GitAccessDesign#check_can_create_design!`.

Instead we now use the `Project#default_owner` to perform all of the git
actions instead of the `current_user`.

We still record the correct `Version#author` of the design in PostgreSQL
and still check the user can `:admin_issue` the target issue before
performing the copy.

https://gitlab.com/gitlab-org/gitlab/-/issues/263102
parent 3340a4e0
...@@ -14,6 +14,9 @@ module DesignManagement ...@@ -14,6 +14,9 @@ module DesignManagement
@target_repository = @target_project.design_repository @target_repository = @target_project.design_repository
@target_design_collection = @target_issue.design_collection @target_design_collection = @target_issue.design_collection
@temporary_branch = "CopyDesignCollectionService_#{SecureRandom.hex}" @temporary_branch = "CopyDesignCollectionService_#{SecureRandom.hex}"
# The user who triggered the copy may not have permissions to push
# to the design repository.
@git_user = @target_project.default_owner
@designs = DesignManagement::Design.unscoped.where(issue: issue).order(:id).load @designs = DesignManagement::Design.unscoped.where(issue: issue).order(:id).load
@versions = DesignManagement::Version.unscoped.where(issue: issue).order(:id).includes(:designs).load @versions = DesignManagement::Version.unscoped.where(issue: issue).order(:id).includes(:designs).load
...@@ -54,9 +57,9 @@ module DesignManagement ...@@ -54,9 +57,9 @@ module DesignManagement
private private
attr_reader :designs, :event_enum_map, :sha_attribute, :shas, :temporary_branch, attr_reader :designs, :event_enum_map, :git_user, :sha_attribute, :shas,
:target_design_collection, :target_issue, :target_repository, :temporary_branch, :target_design_collection, :target_issue,
:target_project, :versions :target_repository, :target_project, :versions
alias_method :merge_branch, :target_branch alias_method :merge_branch, :target_branch
...@@ -96,7 +99,7 @@ module DesignManagement ...@@ -96,7 +99,7 @@ module DesignManagement
# create `master` first by adding a file to it. # create `master` first by adding a file to it.
def create_master_branch! def create_master_branch!
target_repository.create_file( target_repository.create_file(
current_user, git_user,
".CopyDesignCollectionService_#{Time.now.to_i}", ".CopyDesignCollectionService_#{Time.now.to_i}",
'.gitlab', '.gitlab',
message: "Commit to create #{merge_branch} branch in CopyDesignCollectionService", message: "Commit to create #{merge_branch} branch in CopyDesignCollectionService",
...@@ -106,7 +109,7 @@ module DesignManagement ...@@ -106,7 +109,7 @@ module DesignManagement
def create_temporary_branch! def create_temporary_branch!
target_repository.add_branch( target_repository.add_branch(
current_user, git_user,
temporary_branch, temporary_branch,
target_repository.root_ref target_repository.root_ref
) )
...@@ -115,7 +118,7 @@ module DesignManagement ...@@ -115,7 +118,7 @@ module DesignManagement
def remove_temporary_branch! def remove_temporary_branch!
return unless target_repository.branch_exists?(temporary_branch) return unless target_repository.branch_exists?(temporary_branch)
target_repository.rm_branch(current_user, temporary_branch) target_repository.rm_branch(git_user, temporary_branch)
end end
# Merge the temporary branch containing the commits to `master` # Merge the temporary branch containing the commits to `master`
...@@ -124,7 +127,7 @@ module DesignManagement ...@@ -124,7 +127,7 @@ module DesignManagement
source_sha = shas.last source_sha = shas.last
target_repository.raw.merge( target_repository.raw.merge(
current_user, git_user,
source_sha, source_sha,
merge_branch, merge_branch,
'CopyDesignCollectionService finalize merge' 'CopyDesignCollectionService finalize merge'
...@@ -155,7 +158,7 @@ module DesignManagement ...@@ -155,7 +158,7 @@ module DesignManagement
end end
sha = target_repository.multi_action( sha = target_repository.multi_action(
current_user, git_user,
branch_name: temporary_branch, branch_name: temporary_branch,
message: commit_message(version), message: commit_message(version),
actions: gitaly_actions actions: gitaly_actions
......
---
title: Perform git actions with a user with elevated git permissions during a design
copy
merge_request: 44662
author:
type: fixed
...@@ -205,6 +205,7 @@ RSpec.describe Issues::MoveService do ...@@ -205,6 +205,7 @@ RSpec.describe Issues::MoveService do
end end
context 'issue with a design', :clean_gitlab_redis_shared_state do context 'issue with a design', :clean_gitlab_redis_shared_state do
let_it_be(:new_project) { create(:project) }
let!(:design) { create(:design, :with_lfs_file, issue: old_issue) } let!(:design) { create(:design, :with_lfs_file, issue: old_issue) }
let!(:note) { create(:diff_note_on_design, noteable: design, issue: old_issue, project: old_issue.project) } let!(:note) { create(:diff_note_on_design, noteable: design, issue: old_issue, project: old_issue.project) }
let(:subject) { move_service.execute(old_issue, new_project) } let(:subject) { move_service.execute(old_issue, new_project) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment