Fix templates API endpoint when project name has dots

parent 13ee246a
---
title: Fix templates API endpoint when project name has dots
merge_request: 31758
author:
type: fixed
......@@ -5,6 +5,10 @@ module API
include PaginationParams
TEMPLATE_TYPES = %w[dockerfiles gitignores gitlab_ci_ymls licenses].freeze
# The regex is needed to ensure a period (e.g. agpl-3.0)
# isn't confused with a format type. We also need to allow encoded
# values (e.g. C%2B%2B for C++), so allow % and + as well.
TEMPLATE_NAMES_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(name: /[\w%.+-]+/)
before { authenticate_non_get! }
......@@ -36,10 +40,8 @@ module API
optional :project, type: String, desc: 'The project name to use when expanding placeholders in the template. Only affects licenses'
optional :fullname, type: String, desc: 'The full name of the copyright holder to use when expanding placeholders in the template. Only affects licenses'
end
# The regex is needed to ensure a period (e.g. agpl-3.0)
# isn't confused with a format type. We also need to allow encoded
# values (e.g. C%2B%2B for C++), so allow % and + as well.
get ':id/templates/:type/:name', requirements: { name: /[\w%.+-]+/ } do
get ':id/templates/:type/:name', requirements: TEMPLATE_NAMES_ENDPOINT_REQUIREMENTS do
template = TemplateFinder
.build(params[:type], user_project, name: params[:name])
.execute
......
......@@ -7,16 +7,24 @@ describe API::ProjectTemplates do
let_it_be(:private_project) { create(:project, :private) }
let_it_be(:developer) { create(:user) }
let(:url_encoded_path) { "#{public_project.namespace.path}%2F#{public_project.path}" }
before do
private_project.add_developer(developer)
end
describe 'GET /projects/:id/templates/:type' do
it 'accepts project paths with dots' do
get api("/projects/#{public_project.namespace.path}%2F#{public_project.path}/templates/dockerfiles")
shared_examples 'accepts project paths with dots' do
it do
subject
expect(response).to have_gitlab_http_status(:ok)
end
end
describe 'GET /projects/:id/templates/:type' do
it_behaves_like 'accepts project paths with dots' do
subject { get api("/projects/#{url_encoded_path}/templates/dockerfiles") }
end
it 'returns dockerfiles' do
get api("/projects/#{public_project.id}/templates/dockerfiles")
......@@ -81,6 +89,10 @@ describe API::ProjectTemplates do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template_list')
end
it_behaves_like 'accepts project paths with dots' do
subject { get api("/projects/#{url_encoded_path}/templates/licenses") }
end
end
describe 'GET /projects/:id/templates/:type/:key' do
......@@ -150,6 +162,10 @@ describe API::ProjectTemplates do
expect(response).to match_response_schema('public_api/v4/license')
end
it_behaves_like 'accepts project paths with dots' do
subject { get api("/projects/#{url_encoded_path}/templates/gitlab_ci_ymls/Android") }
end
shared_examples 'path traversal attempt' do |template_type|
it 'rejects invalid filenames' do
get api("/projects/#{public_project.id}/templates/#{template_type}/%2e%2e%2fPython%2ea")
......@@ -179,5 +195,9 @@ describe API::ProjectTemplates do
expect(content).to include('Project Placeholder')
expect(content).to include("Copyright (C) #{Time.now.year} Fullname Placeholder")
end
it_behaves_like 'accepts project paths with dots' do
subject { get api("/projects/#{url_encoded_path}/templates/licenses/mit") }
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