Commit 38ff8cd1 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'sha-handling' into 'master'

Adds requirements that supports anything in sha params

Closes #26561 and #2709

See merge request gitlab-org/gitlab-ce!14462
parents 07e33089 771b777a
---
title: Fix 404 errors in API caused when the branch name had a dot
merge_request: 14462
author: gvieira37
type: fixed
...@@ -85,7 +85,7 @@ GET /projects/:id/repository/blobs/:sha ...@@ -85,7 +85,7 @@ GET /projects/:id/repository/blobs/:sha
Parameters: Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `sha` (required) - The commit or branch name - `sha` (required) - The blob SHA
## Raw blob content ## Raw blob content
......
...@@ -4,6 +4,10 @@ module API ...@@ -4,6 +4,10 @@ module API
LOG_FILENAME = Rails.root.join("log", "api_json.log") LOG_FILENAME = Rails.root.join("log", "api_json.log")
NO_SLASH_URL_PART_REGEX = %r{[^/]+}
PROJECT_ENDPOINT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze
COMMIT_ENDPOINT_REQUIREMENTS = PROJECT_ENDPOINT_REQUIREMENTS.merge(sha: NO_SLASH_URL_PART_REGEX).freeze
use GrapeLogging::Middleware::RequestLogger, use GrapeLogging::Middleware::RequestLogger,
logger: Logger.new(LOG_FILENAME), logger: Logger.new(LOG_FILENAME),
formatter: Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp.new, formatter: Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp.new,
...@@ -96,9 +100,6 @@ module API ...@@ -96,9 +100,6 @@ module API
helpers ::API::Helpers helpers ::API::Helpers
helpers ::API::Helpers::CommonHelpers helpers ::API::Helpers::CommonHelpers
NO_SLASH_URL_PART_REGEX = %r{[^/]+}
PROJECT_ENDPOINT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze
# Keep in alphabetical order # Keep in alphabetical order
mount ::API::AccessRequests mount ::API::AccessRequests
mount ::API::AwardEmoji mount ::API::AwardEmoji
......
...@@ -4,8 +4,6 @@ module API ...@@ -4,8 +4,6 @@ module API
class Commits < Grape::API class Commits < Grape::API
include PaginationParams include PaginationParams
COMMIT_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(sha: API::NO_SLASH_URL_PART_REGEX)
before { authorize! :download_code, user_project } before { authorize! :download_code, user_project }
params do params do
...@@ -85,7 +83,7 @@ module API ...@@ -85,7 +83,7 @@ module API
params do params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ':id/repository/commits/:sha', requirements: COMMIT_ENDPOINT_REQUIREMENTS do get ':id/repository/commits/:sha', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
...@@ -99,7 +97,7 @@ module API ...@@ -99,7 +97,7 @@ module API
params do params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ':id/repository/commits/:sha/diff', requirements: COMMIT_ENDPOINT_REQUIREMENTS do get ':id/repository/commits/:sha/diff', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
...@@ -115,7 +113,7 @@ module API ...@@ -115,7 +113,7 @@ module API
use :pagination use :pagination
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ':id/repository/commits/:sha/comments', requirements: COMMIT_ENDPOINT_REQUIREMENTS do get ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
...@@ -132,7 +130,7 @@ module API ...@@ -132,7 +130,7 @@ module API
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag to be cherry picked' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag to be cherry picked'
requires :branch, type: String, desc: 'The name of the branch' requires :branch, type: String, desc: 'The name of the branch'
end end
post ':id/repository/commits/:sha/cherry_pick', requirements: COMMIT_ENDPOINT_REQUIREMENTS do post ':id/repository/commits/:sha/cherry_pick', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
authorize! :push_code, user_project authorize! :push_code, user_project
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
...@@ -169,7 +167,7 @@ module API ...@@ -169,7 +167,7 @@ module API
requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line' requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line'
end end
end end
post ':id/repository/commits/:sha/comments', requirements: COMMIT_ENDPOINT_REQUIREMENTS do post ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
......
...@@ -57,7 +57,7 @@ module API ...@@ -57,7 +57,7 @@ module API
desc 'Get raw blob contents from the repository' desc 'Get raw blob contents from the repository'
params do params do
requires :sha, type: String, desc: 'The commit, branch name, or tag name' requires :sha, type: String, desc: 'The commit hash'
end end
get ':id/repository/blobs/:sha/raw' do get ':id/repository/blobs/:sha/raw' do
assign_blob_vars! assign_blob_vars!
...@@ -67,7 +67,7 @@ module API ...@@ -67,7 +67,7 @@ module API
desc 'Get a blob from the repository' desc 'Get a blob from the repository'
params do params do
requires :sha, type: String, desc: 'The commit, branch name, or tag name' requires :sha, type: String, desc: 'The commit hash'
end end
get ':id/repository/blobs/:sha' do get ':id/repository/blobs/:sha' do
assign_blob_vars! assign_blob_vars!
......
...@@ -8,7 +8,7 @@ module API ...@@ -8,7 +8,7 @@ module API
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects do resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
helpers do helpers do
params :optional_scope do params :optional_scope do
optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show',
......
...@@ -11,7 +11,7 @@ module API ...@@ -11,7 +11,7 @@ module API
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: { id: %r{[^/]+} } do resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
desc 'Get a project repository commits' do desc 'Get a project repository commits' do
success ::API::Entities::Commit success ::API::Entities::Commit
end end
...@@ -72,7 +72,7 @@ module API ...@@ -72,7 +72,7 @@ module API
params do params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ":id/repository/commits/:sha" do get ":id/repository/commits/:sha", requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit not_found! "Commit" unless commit
...@@ -86,7 +86,7 @@ module API ...@@ -86,7 +86,7 @@ module API
params do params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ":id/repository/commits/:sha/diff" do get ":id/repository/commits/:sha/diff", requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit not_found! "Commit" unless commit
...@@ -102,7 +102,7 @@ module API ...@@ -102,7 +102,7 @@ module API
use :pagination use :pagination
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end end
get ':id/repository/commits/:sha/comments' do get ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
...@@ -119,7 +119,7 @@ module API ...@@ -119,7 +119,7 @@ module API
requires :sha, type: String, desc: 'A commit sha to be cherry picked' requires :sha, type: String, desc: 'A commit sha to be cherry picked'
requires :branch, type: String, desc: 'The name of the branch' requires :branch, type: String, desc: 'The name of the branch'
end end
post ':id/repository/commits/:sha/cherry_pick' do post ':id/repository/commits/:sha/cherry_pick', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
authorize! :push_code, user_project authorize! :push_code, user_project
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
...@@ -156,7 +156,7 @@ module API ...@@ -156,7 +156,7 @@ module API
requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line' requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line'
end end
end end
post ':id/repository/commits/:sha/comments' do post ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha]) commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit not_found! 'Commit' unless commit
......
...@@ -8,7 +8,7 @@ module API ...@@ -8,7 +8,7 @@ module API
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: { id: %r{[^/]+} } do resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
helpers do helpers do
def handle_project_member_errors(errors) def handle_project_member_errors(errors)
if errors[:project_access].any? if errors[:project_access].any?
...@@ -43,7 +43,7 @@ module API ...@@ -43,7 +43,7 @@ module API
requires :sha, type: String, desc: 'The commit, branch name, or tag name' requires :sha, type: String, desc: 'The commit, branch name, or tag name'
requires :filepath, type: String, desc: 'The path to the file to display' requires :filepath, type: String, desc: 'The path to the file to display'
end end
get [":id/repository/blobs/:sha", ":id/repository/commits/:sha/blob"] do get [":id/repository/blobs/:sha", ":id/repository/commits/:sha/blob"], requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
repo = user_project.repository repo = user_project.repository
commit = repo.commit(params[:sha]) commit = repo.commit(params[:sha])
not_found! "Commit" unless commit not_found! "Commit" unless commit
...@@ -56,7 +56,7 @@ module API ...@@ -56,7 +56,7 @@ module API
params do params do
requires :sha, type: String, desc: 'The commit, branch name, or tag name' requires :sha, type: String, desc: 'The commit, branch name, or tag name'
end end
get ':id/repository/raw_blobs/:sha' do get ':id/repository/raw_blobs/:sha', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
repo = user_project.repository repo = user_project.repository
begin begin
blob = Gitlab::Git::Blob.raw(repo, params[:sha]) blob = Gitlab::Git::Blob.raw(repo, params[:sha])
......
...@@ -97,10 +97,11 @@ describe API::V3::Repositories do ...@@ -97,10 +97,11 @@ describe API::V3::Repositories do
end end
end end
{ [
'blobs/:sha' => 'blobs/master', ['blobs/:sha', 'blobs/master'],
'commits/:sha/blob' => 'commits/master/blob' ['blobs/:sha', 'blobs/v1.1.0'],
}.each do |desc_path, example_path| ['commits/:sha/blob', 'commits/master/blob']
].each do |desc_path, example_path|
describe "GET /projects/:id/repository/#{desc_path}" do describe "GET /projects/:id/repository/#{desc_path}" do
let(:route) { "/projects/#{project.id}/repository/#{example_path}?filepath=README.md" } let(:route) { "/projects/#{project.id}/repository/#{example_path}?filepath=README.md" }
shared_examples_for 'repository blob' do shared_examples_for 'repository blob' do
...@@ -110,7 +111,7 @@ describe API::V3::Repositories do ...@@ -110,7 +111,7 @@ describe API::V3::Repositories do
end end
context 'when sha does not exist' do context 'when sha does not exist' do
it_behaves_like '404 response' do it_behaves_like '404 response' do
let(:request) { get v3_api(route.sub('master', 'invalid_branch_name'), current_user) } let(:request) { get v3_api("/projects/#{project.id}/repository/#{desc_path.sub(':sha', 'invalid_branch_name')}?filepath=README.md", current_user) }
let(:message) { '404 Commit Not Found' } let(:message) { '404 Commit Not Found' }
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