Commit 7465e2d1 authored by Ash McKenzie's avatar Ash McKenzie

Merge branch 'sh-disable-formats-in-uploads-routes' into 'master'

Fix upload redirections when project has moved

Closes #196232

See merge request gitlab-org/gitlab!22822
parents 206d1980 8a8dccc8
...@@ -29,4 +29,14 @@ class Projects::UploadsController < Projects::ApplicationController ...@@ -29,4 +29,14 @@ class Projects::UploadsController < Projects::ApplicationController
Project.find_by_full_path("#{namespace}/#{id}") Project.find_by_full_path("#{namespace}/#{id}")
end end
# Overrides ApplicationController#build_canonical_path since there are
# multiple routes that match project uploads:
# https://gitlab.com/gitlab-org/gitlab/issues/196396
def build_canonical_path(project)
return super unless action_name == 'show'
return super unless params[:secret] && params[:filename]
show_namespace_project_uploads_url(project.namespace.to_param, project.to_param, params[:secret], params[:filename])
end
end end
---
title: Fix upload redirections when project has moved
merge_request: 22822
author:
type: fixed
...@@ -68,7 +68,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do ...@@ -68,7 +68,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
resources :uploads, only: [:create] do resources :uploads, only: [:create] do
collection do collection do
get ":secret/:filename", action: :show, as: :show, constraints: { filename: %r{[^/]+} } get ":secret/:filename", action: :show, as: :show, constraints: { filename: %r{[^/]+} }, format: false, defaults: { format: nil }
post :authorize post :authorize
end end
end end
......
...@@ -452,7 +452,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -452,7 +452,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :uploads, only: [:create] do resources :uploads, only: [:create] do
collection do collection do
get ":secret/:filename", action: :show, as: :show, constraints: { filename: %r{[^/]+} } get ":secret/:filename", action: :show, as: :show, constraints: { filename: %r{[^/]+} }, format: false, defaults: { format: nil }
post :authorize post :authorize
end end
end end
......
...@@ -21,9 +21,11 @@ scope path: :uploads do ...@@ -21,9 +21,11 @@ scope path: :uploads do
as: 'appearance_upload' as: 'appearance_upload'
# Project markdown uploads # Project markdown uploads
# DEPRECATED: Remove this in GitLab 13.0 because this is redundant to show_namespace_project_uploads
# https://gitlab.com/gitlab-org/gitlab/issues/196396
get ":namespace_id/:project_id/:secret/:filename", get ":namespace_id/:project_id/:secret/:filename",
to: "projects/uploads#show", to: redirect("%{namespace_id}/%{project_id}/uploads/%{secret}/%{filename}"),
constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, project_id: /[a-zA-Z.0-9_\-]+/, filename: %r{[^/]+} } constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, project_id: /[a-zA-Z.0-9_\-]+/, filename: %r{[^/]+} }, format: false, defaults: { format: nil }
# create uploads for models, snippets (notes) available for now # create uploads for models, snippets (notes) available for now
post ':model', post ':model',
......
...@@ -19,6 +19,22 @@ describe Groups::UploadsController do ...@@ -19,6 +19,22 @@ describe Groups::UploadsController do
let(:uploader_class) { NamespaceFileUploader } let(:uploader_class) { NamespaceFileUploader }
end end
context 'with a moved group' do
let!(:upload) { create(:upload, :issuable_upload, :with_file, model: model) }
let(:group) { model }
let(:old_path) { group.to_param + 'old' }
let!(:redirect_route) { model.redirect_routes.create(path: old_path) }
let(:upload_path) { File.basename(upload.path) }
it 'redirects to a file with the proper extension' do
get :show, params: { group_id: old_path, filename: upload_path, secret: upload.secret }
expect(response.location).to eq(show_group_uploads_url(group, upload.secret, upload_path))
expect(response.location).to end_with(upload.path)
expect(response).to have_gitlab_http_status(:redirect)
end
end
def post_authorize(verified: true) def post_authorize(verified: true)
request.headers.merge!(workhorse_internal_api_request_header) if verified request.headers.merge!(workhorse_internal_api_request_header) if verified
......
...@@ -25,6 +25,21 @@ describe Projects::UploadsController do ...@@ -25,6 +25,21 @@ describe Projects::UploadsController do
end end
end end
context 'with a moved project' do
let!(:upload) { create(:upload, :issuable_upload, :with_file, model: model) }
let(:project) { model }
let(:upload_path) { File.basename(upload.path) }
let!(:redirect_route) { project.redirect_routes.create(path: project.full_path + 'old') }
it 'redirects to a file with the proper extension' do
get :show, params: { namespace_id: project.namespace, project_id: project.to_param + 'old', filename: File.basename(upload.path), secret: upload.secret }
expect(response.location).to eq(show_project_uploads_url(project, upload.secret, upload_path))
expect(response.location).to end_with(upload.path)
expect(response).to have_gitlab_http_status(:redirect)
end
end
context "when exception occurs" do context "when exception occurs" do
before do before do
allow(FileUploader).to receive(:workhorse_authorize).and_raise(SocketError.new) allow(FileUploader).to receive(:workhorse_authorize).and_raise(SocketError.new)
......
...@@ -28,4 +28,12 @@ describe 'Uploads', 'routing' do ...@@ -28,4 +28,12 @@ describe 'Uploads', 'routing' do
expect(post("/uploads/#{model}?id=1")).not_to be_routable expect(post("/uploads/#{model}?id=1")).not_to be_routable
end end
end end
describe 'legacy paths' do
include RSpec::Rails::RequestExampleGroup
it 'redirects project uploads to canonical path under project namespace' do
expect(get('/uploads/namespace/project/12345/test.png')).to redirect_to('/namespace/project/uploads/12345/test.png')
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