summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Koller <mkoller@gitlab.com>2019-06-20 19:45:01 +0200
committerMarkus Koller <mkoller@gitlab.com>2019-06-25 13:19:30 +0200
commitdb132bae1d0098dce835844bfa667c5377510d3c (patch)
tree0b690d78e0251ab6010e76aea7960a2f815b8935
parent8fd2c08472afc3846ba28f97994a57143bc76eaf (diff)
downloadgitlab-ce-51952-forking-via-webide.tar.gz
Support redirect paths starting with a dash51952-forking-via-webide
We use a leading dash for certain things like the WebIDE, which had the side effect of losing the `params[:continue][:to]` param when opening the WebIDE on a project where the user doesn't have push access and therefore needs to fork the project first.
-rw-r--r--app/controllers/concerns/internal_redirect.rb4
-rw-r--r--changelogs/unreleased/51952-forking-via-webide.yml5
-rw-r--r--spec/controllers/concerns/internal_redirect_spec.rb77
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb16
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb40
5 files changed, 106 insertions, 36 deletions
diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb
index 6785e6972d0..fa3716502a0 100644
--- a/app/controllers/concerns/internal_redirect.rb
+++ b/app/controllers/concerns/internal_redirect.rb
@@ -5,8 +5,8 @@ module InternalRedirect
def safe_redirect_path(path)
return unless path
- # Verify that the string starts with a `/` but not a double `/`.
- return unless path =~ %r{^/\w.*$}
+ # Verify that the string starts with a `/` and a known route character.
+ return unless path =~ %r{^/[-\w].*$}
uri = URI(path)
# Ignore anything path of the redirect except for the path, querystring and,
diff --git a/changelogs/unreleased/51952-forking-via-webide.yml b/changelogs/unreleased/51952-forking-via-webide.yml
new file mode 100644
index 00000000000..4497c6b6ca4
--- /dev/null
+++ b/changelogs/unreleased/51952-forking-via-webide.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve "500 error when forking via the web IDE button"
+merge_request: 29909
+author:
+type: fixed
diff --git a/spec/controllers/concerns/internal_redirect_spec.rb b/spec/controllers/concerns/internal_redirect_spec.rb
index 97119438ca1..da68c8c8697 100644
--- a/spec/controllers/concerns/internal_redirect_spec.rb
+++ b/spec/controllers/concerns/internal_redirect_spec.rb
@@ -15,44 +15,71 @@ describe InternalRedirect do
subject(:controller) { controller_class.new }
describe '#safe_redirect_path' do
- it 'is `nil` for invalid uris' do
- expect(controller.safe_redirect_path('Hello world')).to be_nil
+ where(:input) do
+ [
+ 'Hello world',
+ '//example.com/hello/world',
+ 'https://example.com/hello/world'
+ ]
end
- it 'is `nil` for paths trying to include a host' do
- expect(controller.safe_redirect_path('//example.com/hello/world')).to be_nil
+ with_them 'being invalid' do
+ it 'returns nil' do
+ expect(controller.safe_redirect_path(input)).to be_nil
+ end
end
- it 'returns the path if it is valid' do
- expect(controller.safe_redirect_path('/hello/world')).to eq('/hello/world')
+ where(:input) do
+ [
+ '/hello/world',
+ '/-/ide/project/path'
+ ]
end
- it 'returns the path with querystring if it is valid' do
- expect(controller.safe_redirect_path('/hello/world?hello=world#L123'))
- .to eq('/hello/world?hello=world#L123')
+ with_them 'being valid' do
+ it 'returns the path' do
+ expect(controller.safe_redirect_path(input)).to eq(input)
+ end
+
+ it 'returns the path with querystring and fragment' do
+ expect(controller.safe_redirect_path("#{input}?hello=world#L123"))
+ .to eq("#{input}?hello=world#L123")
+ end
end
end
describe '#safe_redirect_path_for_url' do
- it 'is `nil` for invalid urls' do
- expect(controller.safe_redirect_path_for_url('Hello world')).to be_nil
+ where(:input) do
+ [
+ 'Hello world',
+ 'http://example.com/hello/world',
+ 'http://test.host:3000/hello/world'
+ ]
end
- it 'is `nil` for urls from a with a different host' do
- expect(controller.safe_redirect_path_for_url('http://example.com/hello/world')).to be_nil
+ with_them 'being invalid' do
+ it 'returns nil' do
+ expect(controller.safe_redirect_path_for_url(input)).to be_nil
+ end
end
- it 'is `nil` for urls from a with a different port' do
- expect(controller.safe_redirect_path_for_url('http://test.host:3000/hello/world')).to be_nil
+ where(:input) do
+ [
+ 'http://test.host/hello/world'
+ ]
end
- it 'returns the path if the url is on the same host' do
- expect(controller.safe_redirect_path_for_url('http://test.host/hello/world')).to eq('/hello/world')
- end
+ with_them 'being on the same host' do
+ let(:path) { URI(input).path }
- it 'returns the path including querystring if the url is on the same host' do
- expect(controller.safe_redirect_path_for_url('http://test.host/hello/world?hello=world#L123'))
- .to eq('/hello/world?hello=world#L123')
+ it 'returns the path' do
+ expect(controller.safe_redirect_path_for_url(input)).to eq(path)
+ end
+
+ it 'returns the path with querystring and fragment' do
+ expect(controller.safe_redirect_path_for_url("#{input}?hello=world#L123"))
+ .to eq("#{path}?hello=world#L123")
+ end
end
end
@@ -82,12 +109,16 @@ describe InternalRedirect do
end
describe '#host_allowed?' do
- it 'allows uris with the same host and port' do
+ it 'allows URI with the same host and port' do
expect(controller.host_allowed?(URI('http://test.host/test'))).to be(true)
end
- it 'rejects uris with other host and port' do
+ it 'rejects URI with other host' do
expect(controller.host_allowed?(URI('http://example.com/test'))).to be(false)
end
+
+ it 'rejects URI with other port' do
+ expect(controller.host_allowed?(URI('http://test.host:3000/test'))).to be(false)
+ end
end
end
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index 3423fdf4c41..5ac5279e997 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -115,24 +115,34 @@ describe Projects::ForksController do
end
describe 'POST create' do
- def post_create
+ def post_create(params = {})
post :create,
params: {
namespace_id: project.namespace,
project_id: project,
namespace_key: user.namespace.id
- }
+ }.merge(params)
end
context 'when user is signed in' do
- it 'responds with status 302' do
+ before do
sign_in(user)
+ end
+ it 'responds with status 302' do
post_create
expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(namespace_project_import_path(user.namespace, project))
end
+
+ it 'passes continue params to the redirect' do
+ continue_params = { to: '/-/ide/project/path', notice: 'message' }
+ post_create continue: continue_params
+
+ expect(response).to have_gitlab_http_status(302)
+ expect(response).to redirect_to(namespace_project_import_path(user.namespace, project, continue: continue_params))
+ end
end
context 'when user is not signed in' do
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index 683268d064a..e0fa9dbb5fa 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -118,19 +118,31 @@ describe 'Projects > Files > User edits files', :js do
wait_for_requests
end
- it 'inserts a content of a file in a forked project' do
- click_link('.gitignore')
- find('.js-edit-blob').click
-
+ def expect_fork_prompt
expect(page).to have_link('Fork')
expect(page).to have_button('Cancel')
+ expect(page).to have_content(
+ "You're not allowed to edit files in this project directly. "\
+ "Please fork this project, make your changes there, and submit a merge request."
+ )
+ end
- click_link('Fork')
-
+ def expect_fork_status
expect(page).to have_content(
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
)
+ end
+
+ it 'inserts a content of a file in a forked project' do
+ click_link('.gitignore')
+ click_button('Edit')
+
+ expect_fork_prompt
+
+ click_link('Fork')
+
+ expect_fork_status
find('.file-editor', match: :first)
@@ -140,12 +152,24 @@ describe 'Projects > Files > User edits files', :js do
expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca')
end
+ it 'opens the Web IDE in a forked project' do
+ click_link('.gitignore')
+ click_button('Web IDE')
+
+ expect_fork_prompt
+
+ click_link('Fork')
+
+ expect_fork_status
+
+ expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
+ end
+
it 'commits an edited file in a forked project' do
click_link('.gitignore')
find('.js-edit-blob').click
- expect(page).to have_link('Fork')
- expect(page).to have_button('Cancel')
+ expect_fork_prompt
click_link('Fork')