Commit de0602ad authored by Mathieu Parent's avatar Mathieu Parent

Allow dots in Helm channel, but forbid repeated dots

Changelog: changed
parent fe980078
...@@ -11,7 +11,8 @@ module API ...@@ -11,7 +11,8 @@ module API
feature_category :package_registry feature_category :package_registry
PACKAGE_FILENAME = 'package.tgz' PACKAGE_FILENAME = 'package.tgz'
FILE_NAME_REQUIREMENTS = { HELM_REQUIREMENTS = {
channel: API::NO_SLASH_URL_PART_REGEX,
file_name: API::NO_SLASH_URL_PART_REGEX file_name: API::NO_SLASH_URL_PART_REGEX
}.freeze }.freeze
...@@ -33,7 +34,7 @@ module API ...@@ -33,7 +34,7 @@ module API
requires :id, type: String, desc: 'The ID or full path of a project' requires :id, type: String, desc: 'The ID or full path of a project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
namespace ':id/packages/helm' do namespace ':id/packages/helm', requirements: HELM_REQUIREMENTS do
desc 'Download a chart index' do desc 'Download a chart index' do
detail 'This feature was introduced in GitLab 14.0' detail 'This feature was introduced in GitLab 14.0'
end end
...@@ -58,7 +59,7 @@ module API ...@@ -58,7 +59,7 @@ module API
requires :channel, type: String, desc: 'Helm channel', regexp: Gitlab::Regex.helm_channel_regex requires :channel, type: String, desc: 'Helm channel', regexp: Gitlab::Regex.helm_channel_regex
requires :file_name, type: String, desc: 'Helm package file name' requires :file_name, type: String, desc: 'Helm package file name'
end end
get ":channel/charts/:file_name.tgz", requirements: FILE_NAME_REQUIREMENTS do get ":channel/charts/:file_name.tgz" do
authorize_read_package!(authorized_user_project) authorize_read_package!(authorized_user_project)
package_file = Packages::Helm::PackageFilesFinder.new(authorized_user_project, params[:channel], file_name: "#{params[:file_name]}.tgz").most_recent! package_file = Packages::Helm::PackageFilesFinder.new(authorized_user_project, params[:channel], file_name: "#{params[:file_name]}.tgz").most_recent!
......
...@@ -131,7 +131,7 @@ module Gitlab ...@@ -131,7 +131,7 @@ module Gitlab
end end
def helm_channel_regex def helm_channel_regex
@helm_channel_regex ||= %r{\A[-\.\_a-zA-Z0-9]+\z}.freeze @helm_channel_regex ||= %r{\A([a-zA-Z0-9](\.|-|_)?){1,63}(?<!\.|-|_)\z}.freeze
end end
def helm_package_regex def helm_package_regex
......
...@@ -653,13 +653,23 @@ RSpec.describe Gitlab::Regex do ...@@ -653,13 +653,23 @@ RSpec.describe Gitlab::Regex do
it { is_expected.to match('release') } it { is_expected.to match('release') }
it { is_expected.to match('my-repo') } it { is_expected.to match('my-repo') }
it { is_expected.to match('my-repo42') } it { is_expected.to match('My-Re_po') }
it { is_expected.to match('my_repo42') }
it { is_expected.to match('1.2.3') }
it { is_expected.to match('v1.2.3-beta-12') }
# Do not allow empty # Do not allow empty
it { is_expected.not_to match('') } it { is_expected.not_to match('') }
# Do not allow Unicode # Do not allow Unicode
it { is_expected.not_to match('hé') } it { is_expected.not_to match('hé') }
it { is_expected.not_to match('.1.23') }
it { is_expected.not_to match('1..23') }
it { is_expected.not_to match('1.2.3.') }
it { is_expected.not_to match('1..2.3.') }
it { is_expected.not_to match('1/../2.3.') }
it { is_expected.not_to match('1/..%2F2.3.') }
end end
describe '.helm_package_regex' do describe '.helm_package_regex' do
......
...@@ -18,11 +18,11 @@ RSpec.describe API::HelmPackages do ...@@ -18,11 +18,11 @@ RSpec.describe API::HelmPackages do
let_it_be(:other_package) { create(:npm_package, project: project) } let_it_be(:other_package) { create(:npm_package, project: project) }
describe 'GET /api/v4/projects/:id/packages/helm/:channel/index.yaml' do describe 'GET /api/v4/projects/:id/packages/helm/:channel/index.yaml' do
let(:url) { "/projects/#{project_id}/packages/helm/stable/index.yaml" } let(:project_id) { project.id }
let(:channel) { 'stable' }
let(:url) { "/projects/#{project_id}/packages/helm/#{channel}/index.yaml" }
context 'with a project id' do context 'with a project id' do
let(:project_id) { project.id }
it_behaves_like 'handling helm chart index requests' it_behaves_like 'handling helm chart index requests'
end end
...@@ -31,6 +31,18 @@ RSpec.describe API::HelmPackages do ...@@ -31,6 +31,18 @@ RSpec.describe API::HelmPackages do
it_behaves_like 'handling helm chart index requests' it_behaves_like 'handling helm chart index requests'
end end
context 'with dot in channel' do
let(:channel) { 'with.dot' }
subject { get api(url) }
before do
project.update!(visibility: 'public')
end
it_behaves_like 'returning response status', :success
end
end end
describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do
......
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