Open WebIDE in fork when user doesn't have access

When opening the IDE on a project where the user doesn't have push
access, we create a fork and then redirect back to the IDE. To make
sure the user can actually commit, we need to open the IDE in the forked
project rather than the upstream project.
This commit is contained in:
Markus Koller 2019-07-11 19:27:21 +02:00
parent 21c372827e
commit 60a6074dc9
No known key found for this signature in database
GPG key ID: EC9A8B44C0635CE2
4 changed files with 47 additions and 8 deletions

View file

@ -18,7 +18,16 @@ module BlobHelper
end
def ide_edit_path(project = @project, ref = @ref, path = @path, options = {})
segments = [ide_path, 'project', project.full_path, 'edit', ref]
project_path =
if !current_user || can?(current_user, :push_code, project)
project.full_path
else
# We currently always fork to the user's namespace
# in edit_fork_button_tag
"#{current_user.namespace.full_path}/#{project.path}"
end
segments = [ide_path, 'project', project_path, 'edit', ref]
segments.concat(['-', encode_ide_path(path)]) if path.present?
File.join(segments)
end

View file

@ -0,0 +1,5 @@
---
title: Open WebIDE in fork when user doesn't have access
merge_request: 30642
author:
type: changed

View file

@ -162,6 +162,7 @@ describe 'Projects > Files > User edits files', :js do
expect_fork_status
expect(page).to have_css('.ide-sidebar-project-title', text: "#{project2.name} #{user.namespace.full_path}/#{project2.path}")
expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
end

View file

@ -29,14 +29,15 @@ describe BlobHelper do
let(:project) { create(:project, :repository, namespace: namespace) }
before do
allow(self).to receive(:current_user).and_return(nil)
allow(self).to receive(:can_collaborate_with_project?).and_return(true)
allow(helper).to receive(:current_user).and_return(nil)
allow(helper).to receive(:can?).and_return(true)
allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
end
it 'verifies blob is text' do
expect(helper).not_to receive(:blob_text_viewable?)
button = edit_blob_button(project, 'refs/heads/master', 'README.md')
button = helper.edit_blob_button(project, 'refs/heads/master', 'README.md')
expect(button).to start_with('<button')
end
@ -46,25 +47,25 @@ describe BlobHelper do
expect(project.repository).not_to receive(:blob_at)
edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
helper.edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
end
it 'returns a link with the proper route' do
stub_feature_flags(web_ide_default: false)
link = edit_blob_button(project, 'master', 'README.md')
link = helper.edit_blob_button(project, 'master', 'README.md')
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
end
it 'returns a link with a Web IDE route' do
link = edit_blob_button(project, 'master', 'README.md')
link = helper.edit_blob_button(project, 'master', 'README.md')
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
end
it 'returns a link with the passed link_opts on the expected route' do
stub_feature_flags(web_ide_default: false)
link = edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
link = helper.edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
end
@ -203,6 +204,13 @@ describe BlobHelper do
describe '#ide_edit_path' do
let(:project) { create(:project) }
let(:current_user) { create(:user) }
let(:can_push_code) { true }
before do
allow(helper).to receive(:current_user).and_return(current_user)
allow(helper).to receive(:can?).and_return(can_push_code)
end
around do |example|
old_script_name = Rails.application.routes.default_url_options[:script_name]
@ -243,5 +251,21 @@ describe BlobHelper do
expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
end
context 'when user is not logged in' do
let(:current_user) { nil }
it 'returns IDE path inside the project' do
expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
end
end
context 'when user cannot push to the project' do
let(:can_push_code) { false }
it "returns IDE path with the user's fork" do
expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{current_user.namespace.full_path}/#{project.path}/edit/master")
end
end
end
end