Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-17 12:10:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-17 12:10:45 +0300
commitd0ed973bd7c3a5c79c2bf9673d9d7260f91dd961 (patch)
treed207a547e2a91e94027fa2f4118ae54342c624cf /lib/api/helpers.rb
parent2511fbfa2c2903d7168ff63527b79cb301c14ac0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/api/helpers.rb')
-rw-r--r--lib/api/helpers.rb46
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index b616f1b35b3..e1207e7e222 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -147,7 +147,7 @@ module API
if id.is_a?(Integer) || id =~ INTEGER_ID_REGEX
projects.find_by(id: id)
elsif id.include?("/")
- projects.find_by_full_path(id)
+ projects.find_by_full_path(id, follow_redirects: Feature.enabled?(:api_redirect_moved_projects))
end
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -157,10 +157,23 @@ module API
return forbidden! unless authorized_project_scope?(project)
- return project if can?(current_user, :read_project, project)
- return unauthorized! if authenticate_non_public?
+ unless can?(current_user, read_project_ability, project)
+ return unauthorized! if authenticate_non_public?
+
+ return not_found!('Project')
+ end
+
+ if project_moved?(id, project)
+ return not_allowed!('Non GET methods are not allowed for moved projects') unless request.get?
+
+ return redirect!(url_with_project_id(project))
+ end
+
+ project
+ end
- not_found!('Project')
+ def read_project_ability
+ :read_project
end
def authorized_project_scope?(project)
@@ -438,6 +451,13 @@ module API
order_options
end
+ # An error is raised to interrupt user's request and redirect them to the right route.
+ # The error! helper behaves similarly, but it cannot be used because it formats the
+ # response message.
+ def redirect!(location_url)
+ raise ::API::API::MovedPermanentlyError, location_url
+ end
+
# error helpers
def forbidden!(reason = nil)
@@ -837,6 +857,24 @@ module API
def sanitize_id_param(id)
id.present? ? id.to_i : nil
end
+
+ def project_moved?(id, project)
+ return false unless Feature.enabled?(:api_redirect_moved_projects)
+ return false unless id.is_a?(String) && id.include?('/')
+ return false if project.blank? || id == project.full_path
+ return false unless params[:id] == id
+
+ true
+ end
+
+ def url_with_project_id(project)
+ new_params = params.merge(id: project.id.to_s).transform_values { |v| v.is_a?(String) ? CGI.escape(v) : v }
+ new_path = GrapePathHelpers::DecoratedRoute.new(route).path_segments_with_values(new_params).join('/')
+
+ Rack::Request.new(env).tap do |r|
+ r.path_info = "/#{new_path}"
+ end.url
+ end
end
end