diff --git a/debian/patches/0250-gitlab-shell-4.0-compat.patch b/debian/patches/0250-gitlab-shell-4.0-compat.patch new file mode 100644 index 0000000000..51e2db20c3 --- /dev/null +++ b/debian/patches/0250-gitlab-shell-4.0-compat.patch @@ -0,0 +1,227 @@ +--- a/lib/api/internal.rb ++++ b/lib/api/internal.rb +@@ -3,6 +3,8 @@ + class Internal < Grape::API + before { authenticate_by_gitlab_shell_token! } + ++ helpers ::API::Helpers::InternalHelpers ++ + namespace 'internal' do + # Check if git command is allowed to project + # +@@ -14,36 +16,6 @@ + # ref - branch name + # forced_push - forced_push + # protocol - Git access protocol being used, e.g. HTTP or SSH +- # +- +- helpers do +- def wiki? +- @wiki ||= params[:project].end_with?('.wiki') && +- !Project.find_with_namespace(params[:project]) +- end +- +- def project +- @project ||= begin +- project_path = params[:project] +- +- # 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_with_namespace(project_path) +- end +- end +- +- def ssh_authentication_abilities +- [ +- :read_project, +- :download_code, +- :push_code +- ] +- end +- end + + post "/allowed" do + status 200 +--- /dev/null ++++ b/lib/api/helpers/internal_helpers.rb +@@ -0,0 +1,57 @@ ++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, storage_paths = Repository.storages.values) ++ project_path = project_path.sub(/\.git\z/, '') ++ ++ storage_paths.each do |storage_path| ++ 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_with_namespace(project_path) ++ 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_with_namespace(project_path) ++ end ++ end ++ ++ def ssh_authentication_abilities ++ [ ++ :read_project, ++ :download_code, ++ :push_code ++ ] ++ end ++ end ++ end ++end +--- /dev/null ++++ b/spec/requests/api/api_internal_helpers_spec.rb +@@ -0,0 +1,32 @@ ++require 'spec_helper' ++ ++describe ::API::Helpers::InternalHelpers do ++ include ::API::Helpers::InternalHelpers ++ ++ describe '.clean_project_path' do ++ project = 'namespace/project' ++ namespaced = File.join('namespace2', project) ++ ++ { ++ File.join(Dir.pwd, project) => project, ++ File.join(Dir.pwd, namespaced) => namespaced, ++ project => project, ++ namespaced => namespaced, ++ project + '.git' => project, ++ namespaced + '.git' => namespaced, ++ "/" + project => project, ++ "/" + namespaced => namespaced, ++ }.each do |project_path, expected| ++ context project_path do ++ # Relative and absolute storage paths, with and without trailing / ++ ['.', './', Dir.pwd, Dir.pwd + '/'].each do |storage_path| ++ context "storage path is #{storage_path}" do ++ subject { clean_project_path(project_path, [storage_path]) } ++ ++ it { is_expected.to eq(expected) } ++ end ++ end ++ end ++ end ++ end ++end +--- a/spec/requests/api/internal_spec.rb ++++ b/spec/requests/api/internal_spec.rb +@@ -191,6 +191,26 @@ + expect(json_response["status"]).to be_truthy + expect(json_response["repository_path"]).to eq(project.repository.path_to_repo) + end ++ ++ context 'project as /namespace/project' do ++ it do ++ pull(key, project_with_repo_path('/' + project.path_with_namespace)) ++ ++ expect(response).to have_http_status(200) ++ expect(json_response["status"]).to be_truthy ++ expect(json_response["repository_path"]).to eq(project.repository.path_to_repo) ++ end ++ end ++ ++ context 'project as namespace/project' do ++ it do ++ pull(key, project_with_repo_path(project.path_with_namespace)) ++ ++ expect(response).to have_http_status(200) ++ expect(json_response["status"]).to be_truthy ++ expect(json_response["repository_path"]).to eq(project.repository.path_to_repo) ++ end ++ end + end + end + +@@ -299,7 +319,7 @@ + + context 'project does not exist' do + it do +- pull(key, OpenStruct.new(path_with_namespace: 'gitlab/notexists')) ++ pull(key, project_with_repo_path('gitlab/notexist')) + + expect(response).to have_http_status(200) + expect(json_response["status"]).to be_falsey +@@ -392,11 +412,17 @@ + end + end + ++ def project_with_repo_path(path) ++ double().tap do |fake_project| ++ allow(fake_project).to receive_message_chain('repository.path_to_repo' => path) ++ end ++ end ++ + def pull(key, project, protocol = 'ssh') + post( + api("/internal/allowed"), + key_id: key.id, +- project: project.path_with_namespace, ++ project: project.repository.path_to_repo, + action: 'git-upload-pack', + secret_token: secret_token, + protocol: protocol +@@ -408,7 +434,7 @@ + api("/internal/allowed"), + changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master', + key_id: key.id, +- project: project.path_with_namespace, ++ project: project.repository.path_to_repo, + action: 'git-receive-pack', + secret_token: secret_token, + protocol: protocol +@@ -420,7 +446,7 @@ + api("/internal/allowed"), + ref: 'master', + key_id: key.id, +- project: project.path_with_namespace, ++ project: project.repository.path_to_repo, + action: 'git-upload-archive', + secret_token: secret_token, + protocol: 'ssh' +@@ -432,7 +458,7 @@ + api("/internal/lfs_authenticate"), + key_id: key_id, + secret_token: secret_token, +- project: project.path_with_namespace ++ project: project.repository.path_to_repo + ) + end + end diff --git a/debian/patches/0300-git-2-11-support.patch b/debian/patches/0300-git-2-11-support.patch index 4874c75d1b..9c1cca01b2 100644 --- a/debian/patches/0300-git-2-11-support.patch +++ b/debian/patches/0300-git-2-11-support.patch @@ -21,7 +21,7 @@ Subject: [PATCH] Merge branch '25301-git-2.11-force-push-bug' into 'master' Acce --- a/lib/api/internal.rb +++ b/lib/api/internal.rb -@@ -61,7 +61,11 @@ +@@ -33,7 +33,11 @@ if wiki? Gitlab::GitAccessWiki.new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities) else @@ -252,3 +252,20 @@ Subject: [PATCH] Merge branch '25301-git-2.11-force-push-bug' into 'master' Acce + end + end +end +--- a/lib/api/helpers/internal_helpers.rb ++++ b/lib/api/helpers/internal_helpers.rb +@@ -52,6 +52,14 @@ + :push_code + ] + end ++ ++ def parse_allowed_environment_variables ++ return if params[:env].blank? ++ ++ JSON.parse(params[:env]) ++ ++ rescue JSON::ParserError ++ end + end + end + end diff --git a/debian/patches/series b/debian/patches/series index 070c46fd79..63f87266db 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -8,4 +8,5 @@ pid-log-paths.patch 052-relax-grape.patch 0200-remove-order-dependency-in-label-finder-spec.patch 0210-use-jquery-ui-rails6.patch +0250-gitlab-shell-4.0-compat.patch 0300-git-2-11-support.patch