diff options
author | Sean McGivern <sean@mcgivern.me.uk> | 2017-05-05 22:08:29 +0000 |
---|---|---|
committer | Sean McGivern <sean@mcgivern.me.uk> | 2017-05-05 22:08:29 +0000 |
commit | 9e041f2185ecb957e1f3d1205ea3bac54a5eb803 (patch) | |
tree | 4dfdfc2ae250c90138c272429341af53f53eb7af /lib | |
parent | cc9edff6dcc4b73aa20683dee6021d6693533743 (diff) | |
parent | 8bc381db90c92bca6ba868d1588af1ad1a41073b (diff) | |
download | gitlab-ce-9e041f2185ecb957e1f3d1205ea3bac54a5eb803.tar.gz |
Merge branch '29925-gitlab-shell-hooks-can-no-longer-send-absolute-paths-to-gitlab-ce' into 'master'
Generate and handle a gl_repository param to pass around components
Closes #29925
See merge request !10992
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/helpers/internal_helpers.rb | 52 | ||||
-rw-r--r-- | lib/api/internal.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/git_post_receive.rb | 29 | ||||
-rw-r--r-- | lib/gitlab/gl_repository.rb | 20 | ||||
-rw-r--r-- | lib/gitlab/repo_path.rb | 29 | ||||
-rw-r--r-- | lib/gitlab/workhorse.rb | 6 |
6 files changed, 67 insertions, 79 deletions
diff --git a/lib/api/helpers/internal_helpers.rb b/lib/api/helpers/internal_helpers.rb index 718f936a1fc..264df7271a3 100644 --- a/lib/api/helpers/internal_helpers.rb +++ b/lib/api/helpers/internal_helpers.rb @@ -1,48 +1,14 @@ module API module Helpers module InternalHelpers - # Project paths may be any of the following: - # * /repository/storage/path/namespace/project - # * /namespace/project - # * namespace/project - # - # In addition, they may have a '.git' extension and multiple namespaces - # - # Transform all these cases to 'namespace/project' - def clean_project_path(project_path, storages = Gitlab.config.repositories.storages.values) - project_path = project_path.sub(/\.git\z/, '') - - storages.each do |storage| - storage_path = File.expand_path(storage['path']) - - if project_path.start_with?(storage_path) - project_path = project_path.sub(storage_path, '') - break - end - end - - project_path.sub(/\A\//, '') - end - - def project_path - @project_path ||= clean_project_path(params[:project]) - end - def wiki? - @wiki ||= project_path.end_with?('.wiki') && - !Project.find_by_full_path(project_path) + set_project unless defined?(@wiki) + @wiki end def project - @project ||= begin - # Check for *.wiki repositories. - # Strip out the .wiki from the pathname before finding the - # project. This applies the correct project permissions to - # the wiki repository as well. - project_path.chomp!('.wiki') if wiki? - - Project.find_by_full_path(project_path) - end + set_project unless defined?(@project) + @project end def ssh_authentication_abilities @@ -66,6 +32,16 @@ module API ::Users::ActivityService.new(actor, 'Git SSH').execute if commands.include?(params[:action]) end + + private + + def set_project + if params[:gl_repository] + @project, @wiki = Gitlab::GlRepository.parse(params[:gl_repository]) + else + @project, @wiki = Gitlab::RepoPath.parse(params[:project]) + end + end end end end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index ebed26dd178..2a11790b215 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -42,6 +42,10 @@ module API if access_status.status log_user_activity(actor) + # Project id to pass between components that don't share/don't have + # access to the same filesystem mounts + response[:gl_repository] = Gitlab::GlRepository.gl_repository(project, wiki?) + # Return the repository full path so that gitlab-shell has it when # handling ssh commands response[:repository_path] = @@ -134,11 +138,9 @@ module API return unless Gitlab::GitalyClient.enabled? - relative_path = Gitlab::RepoPath.strip_storage_path(params[:repo_path]) - project = Project.find_by_full_path(relative_path.sub(/\.(git|wiki)\z/, '')) - begin - Gitlab::GitalyClient::Notifications.new(project.repository).post_receive + repository = wiki? ? project.wiki.repository : project.repository + Gitlab::GitalyClient::Notifications.new(repository.raw_repository).post_receive rescue GRPC::Unavailable => e render_api_error!(e, 500) end diff --git a/lib/gitlab/git_post_receive.rb b/lib/gitlab/git_post_receive.rb index 6babea144c7..0e14253ab4e 100644 --- a/lib/gitlab/git_post_receive.rb +++ b/lib/gitlab/git_post_receive.rb @@ -1,25 +1,12 @@ module Gitlab class GitPostReceive include Gitlab::Identifier - attr_reader :repo_path, :identifier, :changes, :project + attr_reader :project, :identifier, :changes - def initialize(repo_path, identifier, changes) - repo_path.gsub!(/\.git\z/, '') - repo_path.gsub!(/\A\//, '') - - @repo_path = repo_path + def initialize(project, identifier, changes) + @project = project @identifier = identifier @changes = deserialize_changes(changes) - - retrieve_project_and_type - end - - def wiki? - @type == :wiki - end - - def regular_project? - @type == :project end def identify(revision) @@ -28,16 +15,6 @@ module Gitlab private - def retrieve_project_and_type - @type = :project - @project = Project.find_by_full_path(@repo_path) - - if @repo_path.end_with?('.wiki') && !@project - @type = :wiki - @project = Project.find_by_full_path(@repo_path.gsub(/\.wiki\z/, '')) - end - end - def deserialize_changes(changes) changes = utf8_encode_changes(changes) changes.lines diff --git a/lib/gitlab/gl_repository.rb b/lib/gitlab/gl_repository.rb new file mode 100644 index 00000000000..07c0abcce23 --- /dev/null +++ b/lib/gitlab/gl_repository.rb @@ -0,0 +1,20 @@ +module Gitlab + module GlRepository + def self.gl_repository(project, is_wiki) + "#{is_wiki ? 'wiki' : 'project'}-#{project.id}" + end + + def self.parse(gl_repository) + match_data = /\A(project|wiki)-([1-9][0-9]*)\z/.match(gl_repository) + unless match_data + raise ArgumentError, "Invalid GL Repository \"#{gl_repository}\"" + end + + type, id = match_data.captures + project = Project.find_by(id: id) + wiki = type == 'wiki' + + [project, wiki] + end + end +end diff --git a/lib/gitlab/repo_path.rb b/lib/gitlab/repo_path.rb index 4b1d828c45c..878e03f61d7 100644 --- a/lib/gitlab/repo_path.rb +++ b/lib/gitlab/repo_path.rb @@ -2,18 +2,29 @@ module Gitlab module RepoPath NotFoundError = Class.new(StandardError) - def self.strip_storage_path(repo_path) - result = nil + def self.parse(repo_path) + project_path = strip_storage_path(repo_path.sub(/\.git\z/, ''), fail_on_not_found: false) + project = Project.find_by_full_path(project_path) + if project_path.end_with?('.wiki') && !project + project = Project.find_by_full_path(project_path.chomp('.wiki')) + wiki = true + else + wiki = false + end + + [project, wiki] + end + + def self.strip_storage_path(repo_path, fail_on_not_found: true) + result = repo_path - Gitlab.config.repositories.storages.values.each do |params| - storage_path = params['path'] - if repo_path.start_with?(storage_path) - result = repo_path.sub(storage_path, '') - break - end + storage = Gitlab.config.repositories.storages.values.find do |params| + repo_path.start_with?(params['path']) end - if result.nil? + if storage + result = result.sub(storage['path'], '') + elsif fail_on_not_found raise NotFoundError.new("No known storage path matches #{repo_path.inspect}") end diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb index c551f939df1..8c5ad01e8c2 100644 --- a/lib/gitlab/workhorse.rb +++ b/lib/gitlab/workhorse.rb @@ -16,15 +16,17 @@ module Gitlab SECRET_LENGTH = 32 class << self - def git_http_ok(repository, user, action) + def git_http_ok(repository, is_wiki, user, action) + project = repository.project repo_path = repository.path_to_repo params = { GL_ID: Gitlab::GlId.gl_id(user), + GL_REPOSITORY: Gitlab::GlRepository.gl_repository(project, is_wiki), RepoPath: repo_path, } if Gitlab.config.gitaly.enabled - address = Gitlab::GitalyClient.get_address(repository.project.repository_storage) + address = Gitlab::GitalyClient.get_address(project.repository_storage) params[:Repository] = repository.gitaly_repository.to_h feature_enabled = case action.to_s |