Commit 60a6074d authored by Markus Koller's avatar Markus Koller

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.
parent 21c37282
...@@ -18,7 +18,16 @@ module BlobHelper ...@@ -18,7 +18,16 @@ module BlobHelper
end end
def ide_edit_path(project = @project, ref = @ref, path = @path, options = {}) 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? segments.concat(['-', encode_ide_path(path)]) if path.present?
File.join(segments) File.join(segments)
end end
......
---
title: Open WebIDE in fork when user doesn't have access
merge_request: 30642
author:
type: changed
...@@ -162,6 +162,7 @@ describe 'Projects > Files > User edits files', :js do ...@@ -162,6 +162,7 @@ describe 'Projects > Files > User edits files', :js do
expect_fork_status 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') expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
end end
......
...@@ -29,14 +29,15 @@ describe BlobHelper do ...@@ -29,14 +29,15 @@ describe BlobHelper do
let(:project) { create(:project, :repository, namespace: namespace) } let(:project) { create(:project, :repository, namespace: namespace) }
before do before do
allow(self).to receive(:current_user).and_return(nil) allow(helper).to receive(:current_user).and_return(nil)
allow(self).to receive(:can_collaborate_with_project?).and_return(true) allow(helper).to receive(:can?).and_return(true)
allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
end end
it 'verifies blob is text' do it 'verifies blob is text' do
expect(helper).not_to receive(:blob_text_viewable?) 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') expect(button).to start_with('<button')
end end
...@@ -46,25 +47,25 @@ describe BlobHelper do ...@@ -46,25 +47,25 @@ describe BlobHelper do
expect(project.repository).not_to receive(:blob_at) 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 end
it 'returns a link with the proper route' do it 'returns a link with the proper route' do
stub_feature_flags(web_ide_default: false) 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") expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
end end
it 'returns a link with a Web IDE route' do 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") expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
end end
it 'returns a link with the passed link_opts on the expected route' do it 'returns a link with the passed link_opts on the expected route' do
stub_feature_flags(web_ide_default: false) 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") expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
end end
...@@ -203,6 +204,13 @@ describe BlobHelper do ...@@ -203,6 +204,13 @@ describe BlobHelper do
describe '#ide_edit_path' do describe '#ide_edit_path' do
let(:project) { create(:project) } 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| around do |example|
old_script_name = Rails.application.routes.default_url_options[:script_name] old_script_name = Rails.application.routes.default_url_options[:script_name]
...@@ -243,5 +251,21 @@ describe BlobHelper do ...@@ -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/") 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 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
end end
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