summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Speicher <robert@gitlab.com>2018-08-14 18:49:15 +0000
committerRobert Speicher <robert@gitlab.com>2018-08-14 18:49:15 +0000
commit02457041814fe4497b3df00e0e45edbee107c823 (patch)
tree6b07ce701bf00608cb21a3c1322a15c71a48d137
parent2dcf8b77a61c4c7cfebe8ae13f8112a0471056b0 (diff)
parentc36e35c4510cf78ba3e642346bf7aa7cbc0efab3 (diff)
downloadgitlab-shell-02457041814fe4497b3df00e0e45edbee107c823.tar.gz
Merge branch 'revert-refactor' into 'master'
Revert refactor Closes #147 See merge request gitlab-org/gitlab-shell!228
-rw-r--r--Gemfile9
-rw-r--r--Gemfile.lock68
-rw-r--r--Guardfile20
-rwxr-xr-xbin/authorized_keys10
-rwxr-xr-xbin/gitlab-keys2
-rwxr-xr-xbin/gitlab-shell-authorized-keys-check10
-rwxr-xr-xbin/gitlab-shell-authorized-principals-check8
-rwxr-xr-xhooks/post-receive6
-rwxr-xr-xhooks/pre-receive6
-rwxr-xr-xhooks/update4
-rw-r--r--lib/action.rb7
-rw-r--r--lib/action/api_2fa_recovery.rb54
-rw-r--r--lib/action/base.rb27
-rw-r--r--lib/action/git_lfs_authenticate.rb26
-rw-r--r--lib/action/gitaly.rb129
-rw-r--r--lib/actor.rb21
-rw-r--r--lib/actor/base.rb56
-rw-r--r--lib/actor/key.rb29
-rw-r--r--lib/actor/user.rb19
-rw-r--r--lib/actor/username.rb25
-rw-r--r--lib/errors.rb4
-rw-r--r--lib/gitlab_access.rb36
-rw-r--r--lib/gitlab_access_status.rb34
-rw-r--r--lib/gitlab_custom_hook.rb4
-rw-r--r--lib/gitlab_keys.rb2
-rw-r--r--lib/gitlab_net.rb150
-rw-r--r--lib/gitlab_post_receive.rb18
-rw-r--r--lib/gitlab_shell.rb309
-rw-r--r--lib/http_helper.rb19
-rw-r--r--spec/action/api_2fa_recovery.rb_spec.rb73
-rw-r--r--spec/action/base_spec.rb12
-rw-r--r--spec/action/git_lfs_authenticate_spec.rb48
-rw-r--r--spec/action/gitaly_spec.rb139
-rw-r--r--spec/actor/base_spec.rb28
-rw-r--r--spec/actor/key_spec.rb80
-rw-r--r--spec/actor/user_spec.rb62
-rw-r--r--spec/actor/username_spec.rb79
-rw-r--r--spec/actor_spec.rb34
-rw-r--r--spec/gitlab_access_spec.rb46
-rw-r--r--spec/gitlab_config_spec.rb36
-rw-r--r--spec/gitlab_keys_spec.rb75
-rw-r--r--spec/gitlab_lfs_authentication_spec.rb12
-rw-r--r--spec/gitlab_logger_spec.rb2
-rw-r--r--spec/gitlab_net_spec.rb293
-rw-r--r--spec/gitlab_post_receive_spec.rb18
-rw-r--r--spec/gitlab_shell_spec.rb614
-rw-r--r--spec/names_helper_spec.rb6
-rw-r--r--spec/vcr_cassettes/allowed-pull.yml2
-rw-r--r--spec/vcr_cassettes/allowed-push.yml2
-rw-r--r--spec/vcr_cassettes/discover-not-found.yml46
-rw-r--r--spec/vcr_cassettes/failed-push-unparsable.yml46
-rw-r--r--spec/vcr_cassettes/failed-push.yml46
-rw-r--r--spec/vcr_cassettes/http-pull-disabled-old.yml46
-rw-r--r--spec/vcr_cassettes/http-pull-disabled.yml4
-rw-r--r--spec/vcr_cassettes/http-push-disabled-old.yml46
-rw-r--r--spec/vcr_cassettes/http-push-disabled.yml4
-rw-r--r--spec/vcr_cassettes/ssh-pull-disabled-old.yml46
-rw-r--r--spec/vcr_cassettes/ssh-pull-disabled.yml4
-rw-r--r--spec/vcr_cassettes/ssh-pull-project-denied-old.yml46
-rw-r--r--spec/vcr_cassettes/ssh-pull-project-denied.yml4
-rw-r--r--spec/vcr_cassettes/ssh-push-disabled-old.yml46
-rw-r--r--spec/vcr_cassettes/ssh-push-disabled.yml4
-rw-r--r--spec/vcr_cassettes/ssh-push-project-denied-old.yml46
-rw-r--r--spec/vcr_cassettes/ssh-push-project-denied-with-user-old.yml46
-rw-r--r--spec/vcr_cassettes/ssh-push-project-denied-with-user.yml4
-rw-r--r--spec/vcr_cassettes/ssh-push-project-denied.yml4
66 files changed, 1177 insertions, 2084 deletions
diff --git a/Gemfile b/Gemfile
index 41e19eb..1e5de7a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,12 +1,13 @@
source "http://rubygems.org"
group :development, :test do
- gem 'guard-rspec', '~> 4.0'
- gem 'listen', '~> 3.0.0'
- gem 'rspec', '~> 3.0'
+ gem 'guard', '~> 1.5.0'
+ gem 'guard-rspec', '~> 2.1.0'
+ gem 'listen', '~> 0.5.0'
+ gem 'rspec', '~> 2.0'
gem 'rspec-its', '~> 1.0.0'
gem 'rubocop', '0.49.1', require: false
gem 'simplecov', '~> 0.9.0', require: false
- gem 'vcr', '~> 4.0'
+ gem 'vcr', '~> 2.4.0'
gem 'webmock', '~> 1.9.0'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 4ed9ad1..88fc8c0 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,32 +9,18 @@ GEM
safe_yaml (~> 1.0.0)
diff-lcs (1.3)
docile (1.1.5)
- ffi (1.9.25)
- formatador (0.2.5)
- guard (2.14.2)
- formatador (>= 0.2.4)
- listen (>= 2.7, < 4.0)
- lumberjack (>= 1.0.12, < 2.0)
- nenv (~> 0.1)
- notiffany (~> 0.0)
- pry (>= 0.9.12)
- shellany (~> 0.0)
- thor (>= 0.18.1)
- guard-compat (1.2.1)
- guard-rspec (4.7.3)
- guard (~> 2.1)
- guard-compat (~> 1.1)
- rspec (>= 2.99.0, < 4.0)
- listen (3.0.8)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
+ guard (1.5.4)
+ listen (>= 0.4.2)
+ lumberjack (>= 1.0.2)
+ pry (>= 0.9.10)
+ thor (>= 0.14.6)
+ guard-rspec (2.1.2)
+ guard (>= 1.1)
+ rspec (~> 2.11)
+ listen (0.5.3)
lumberjack (1.0.13)
method_source (0.9.0)
multi_json (1.13.1)
- nenv (0.3.0)
- notiffany (0.1.1)
- nenv (~> 0.1)
- shellany (~> 0.0)
parallel (1.12.1)
parser (2.5.1.2)
ast (~> 2.4.0)
@@ -46,25 +32,17 @@ GEM
rainbow (2.2.2)
rake
rake (12.3.1)
- rb-fsevent (0.10.3)
- rb-inotify (0.9.10)
- ffi (>= 0.5.0, < 2)
- rspec (3.7.0)
- rspec-core (~> 3.7.0)
- rspec-expectations (~> 3.7.0)
- rspec-mocks (~> 3.7.0)
- rspec-core (3.7.1)
- rspec-support (~> 3.7.0)
- rspec-expectations (3.7.0)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.7.0)
+ rspec (2.99.0)
+ rspec-core (~> 2.99.0)
+ rspec-expectations (~> 2.99.0)
+ rspec-mocks (~> 2.99.0)
+ rspec-core (2.99.2)
+ rspec-expectations (2.99.2)
+ diff-lcs (>= 1.1.3, < 2.0)
rspec-its (1.0.1)
rspec-core (>= 2.99.0.beta1)
rspec-expectations (>= 2.99.0.beta1)
- rspec-mocks (3.7.0)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.7.0)
- rspec-support (3.7.1)
+ rspec-mocks (2.99.4)
rubocop (0.49.1)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
@@ -74,7 +52,6 @@ GEM
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.9.0)
safe_yaml (1.0.4)
- shellany (0.0.1)
simplecov (0.9.2)
docile (~> 1.1.0)
multi_json (~> 1.0)
@@ -82,7 +59,7 @@ GEM
simplecov-html (0.9.0)
thor (0.20.0)
unicode-display_width (1.4.0)
- vcr (4.0.0)
+ vcr (2.4.0)
webmock (1.9.3)
addressable (>= 2.2.7)
crack (>= 0.3.2)
@@ -91,13 +68,14 @@ PLATFORMS
ruby
DEPENDENCIES
- guard-rspec (~> 4.0)
- listen (~> 3.0.0)
- rspec (~> 3.0)
+ guard (~> 1.5.0)
+ guard-rspec (~> 2.1.0)
+ listen (~> 0.5.0)
+ rspec (~> 2.0)
rspec-its (~> 1.0.0)
rubocop (= 0.49.1)
simplecov (~> 0.9.0)
- vcr (~> 4.0)
+ vcr (~> 2.4.0)
webmock (~> 1.9.0)
BUNDLED WITH
diff --git a/Guardfile b/Guardfile
index 2f3a73e..421eaf3 100644
--- a/Guardfile
+++ b/Guardfile
@@ -1,7 +1,23 @@
+# A sample Guardfile
# More info at https://github.com/guard/guard#readme
-guard :rspec, cmd: 'bundle exec rspec' do
+guard 'rspec' do
watch(%r{^spec/.+_spec\.rb$})
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
+
+ # Rails example
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
+ watch('config/routes.rb') { "spec/routing" }
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
+
+ # Capybara features specs
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
+
+ # Turnip features and steps
+ watch(%r{^spec/acceptance/(.+)\.feature$})
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
diff --git a/bin/authorized_keys b/bin/authorized_keys
index 24484f1..ca01646 100755
--- a/bin/authorized_keys
+++ b/bin/authorized_keys
@@ -10,16 +10,16 @@
# command="/bin/gitlab-shell key-#",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...
#
-full_key = ARGV[0]
-abort "# No key provided" if full_key.nil? || full_key.empty?
+key = ARGV[0]
+abort "# No key provided" if key.nil? || key.empty?
require_relative "../lib/gitlab_init"
require_relative "../lib/gitlab_net"
require_relative "../lib/gitlab_keys"
-authorized_key = GitlabNet.new.authorized_key(full_key)
+authorized_key = GitlabNet.new.authorized_key(key)
if authorized_key.nil?
- puts "# No key was found for #{full_key}"
+ puts "# No key was found for #{key}"
else
- puts GitlabKeys.key_line("key-#{authorized_key['id']}", authorized_key['key'])
+ puts GitlabKeys.key_line("key-#{authorized_key['id']}", authorized_key["key"])
end
diff --git a/bin/gitlab-keys b/bin/gitlab-keys
index c0284e8..9eb1950 100755
--- a/bin/gitlab-keys
+++ b/bin/gitlab-keys
@@ -13,7 +13,7 @@ require_relative '../lib/gitlab_init'
# /bin/gitlab-keys rm-key key-23 "ssh-rsa AAAAx321..."
#
# /bin/gitlab-keys list-keys
-#
+#
# /bin/gitlab-keys clear
#
diff --git a/bin/gitlab-shell-authorized-keys-check b/bin/gitlab-shell-authorized-keys-check
index b2cd24c..2ea1a74 100755
--- a/bin/gitlab-shell-authorized-keys-check
+++ b/bin/gitlab-shell-authorized-keys-check
@@ -5,7 +5,7 @@
# command for a given ssh key fingerprint
#
# Ex.
-# bin/gitlab-shell-authorized-keys-check <expected-username> <actual-username> <public-key>
+# bin/gitlab-shell-authorized-keys-check <username> <public-key>
#
# Returns
# command="/bin/gitlab-shell key-#",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA...
@@ -27,16 +27,16 @@ abort '# No username provided' if actual_username.nil? || actual_username == ''
# Normally, these would both be 'git', but it can be configured by the user
exit 0 unless expected_username == actual_username
-full_key = ARGV[2]
-abort "# No key provided" if full_key.nil? || full_key == ''
+key = ARGV[2]
+abort "# No key provided" if key.nil? || key == ''
require_relative '../lib/gitlab_init'
require_relative '../lib/gitlab_net'
require_relative '../lib/gitlab_keys'
-authorized_key = GitlabNet.new.authorized_key(full_key)
+authorized_key = GitlabNet.new.authorized_key(key)
if authorized_key.nil?
- puts "# No key was found for #{full_key}"
+ puts "# No key was found for #{key}"
else
puts GitlabKeys.key_line("key-#{authorized_key['id']}", authorized_key['key'])
end
diff --git a/bin/gitlab-shell-authorized-principals-check b/bin/gitlab-shell-authorized-principals-check
index 4b39cac..aa6d427 100755
--- a/bin/gitlab-shell-authorized-principals-check
+++ b/bin/gitlab-shell-authorized-principals-check
@@ -6,7 +6,7 @@
# the right options.
#
# Ex.
-# bin/gitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]
+# bin/gitlab-shell-authorized-keys-check <key-id> <principal1> [<principal2>...]
#
# Returns one line per principal passed in, e.g.:
# command="/bin/gitlab-shell username-{KEY_ID}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty {PRINCIPAL}
@@ -23,9 +23,9 @@ key_id = ARGV[0]
abort '# No key_id provided' if key_id.nil? || key_id == ''
principals = ARGV[1..-1]
-principals.each do |principal|
- abort '# An invalid principal was provided' if principal.nil? || principal == ''
-end
+principals.each { |principal|
+ abort '# An invalid principal was provided' if principal.nil? || principal == ''
+}
require_relative '../lib/gitlab_init'
require_relative '../lib/gitlab_net'
diff --git a/hooks/post-receive b/hooks/post-receive
index 33d9f8d..30f4be1 100755
--- a/hooks/post-receive
+++ b/hooks/post-receive
@@ -4,15 +4,15 @@
# will be processed properly.
refs = $stdin.read
-gl_id = ENV.delete('GL_ID')
+key_id = ENV.delete('GL_ID')
gl_repository = ENV['GL_REPOSITORY']
repo_path = Dir.pwd
require_relative '../lib/gitlab_custom_hook'
require_relative '../lib/gitlab_post_receive'
-if GitlabPostReceive.new(gl_repository, repo_path, gl_id, refs).exec &&
- GitlabCustomHook.new(repo_path, gl_id).post_receive(refs)
+if GitlabPostReceive.new(gl_repository, repo_path, key_id, refs).exec &&
+ GitlabCustomHook.new(repo_path, key_id).post_receive(refs)
exit 0
else
exit 1
diff --git a/hooks/pre-receive b/hooks/pre-receive
index 66c61d9..6ce5879 100755
--- a/hooks/pre-receive
+++ b/hooks/pre-receive
@@ -4,7 +4,7 @@
# will be processed properly.
refs = $stdin.read
-gl_id = ENV.delete('GL_ID')
+key_id = ENV.delete('GL_ID')
protocol = ENV.delete('GL_PROTOCOL')
repo_path = Dir.pwd
gl_repository = ENV['GL_REPOSITORY']
@@ -23,8 +23,8 @@ require_relative '../lib/gitlab_net'
# last so that it only runs if everything else succeeded. On post-receive on the
# other hand, we run GitlabPostReceive first because the push is already done
# and we don't want to skip it if the custom hook fails.
-if GitlabAccess.new(gl_repository, repo_path, gl_id, refs, protocol).exec &&
- GitlabCustomHook.new(repo_path, gl_id).pre_receive(refs) &&
+if GitlabAccess.new(gl_repository, repo_path, key_id, refs, protocol).exec &&
+ GitlabCustomHook.new(repo_path, key_id).pre_receive(refs) &&
increase_reference_counter(gl_repository, repo_path)
exit 0
else
diff --git a/hooks/update b/hooks/update
index 263a3e8..4c2fc08 100755
--- a/hooks/update
+++ b/hooks/update
@@ -7,11 +7,11 @@ ref_name = ARGV[0]
old_value = ARGV[1]
new_value = ARGV[2]
repo_path = Dir.pwd
-gl_id = ENV.delete('GL_ID')
+key_id = ENV.delete('GL_ID')
require_relative '../lib/gitlab_custom_hook'
-if GitlabCustomHook.new(repo_path, gl_id).update(ref_name, old_value, new_value)
+if GitlabCustomHook.new(repo_path, key_id).update(ref_name, old_value, new_value)
exit 0
else
exit 1
diff --git a/lib/action.rb b/lib/action.rb
deleted file mode 100644
index 1f9cc6c..0000000
--- a/lib/action.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require_relative 'action/base'
-require_relative 'action/gitaly'
-require_relative 'action/git_lfs_authenticate'
-require_relative 'action/api_2fa_recovery'
-
-module Action
-end
diff --git a/lib/action/api_2fa_recovery.rb b/lib/action/api_2fa_recovery.rb
deleted file mode 100644
index 06f8057..0000000
--- a/lib/action/api_2fa_recovery.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-require_relative '../action'
-require_relative '../gitlab_logger'
-
-module Action
- class API2FARecovery < Base
- def initialize(actor)
- @actor = actor
- end
-
- def execute(_, _)
- recover
- end
-
- private
-
- attr_reader :actor
-
- def continue?(question)
- puts "#{question} (yes/no)"
- STDOUT.flush # Make sure the question gets output before we wait for input
- response = STDIN.gets.chomp
- puts '' # Add a buffer in the output
- response == 'yes'
- end
-
- def recover
- continue = continue?(
- "Are you sure you want to generate new two-factor recovery codes?\n" \
- "Any existing recovery codes you saved will be invalidated."
- )
-
- unless continue
- puts 'New recovery codes have *not* been generated. Existing codes will remain valid.'
- return
- end
-
- resp = api.two_factor_recovery_codes(actor)
- if resp['success']
- codes = resp['recovery_codes'].join("\n")
- $logger.info('API 2FA recovery success', user: actor.log_username)
- puts "Your two-factor authentication recovery codes are:\n\n" \
- "#{codes}\n\n" \
- "During sign in, use one of the codes above when prompted for\n" \
- "your two-factor code. Then, visit your Profile Settings and add\n" \
- "a new device so you do not lose access to your account again."
- true
- else
- $logger.info('API 2FA recovery error', user: actor.log_username)
- puts "An error occurred while trying to generate new recovery codes.\n" \
- "#{resp['message']}"
- end
- end
- end
-end
diff --git a/lib/action/base.rb b/lib/action/base.rb
deleted file mode 100644
index fe8c836..0000000
--- a/lib/action/base.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'json'
-
-require_relative '../gitlab_config'
-require_relative '../gitlab_net'
-require_relative '../gitlab_metrics'
-
-module Action
- class Base
- def initialize
- raise NotImplementedError
- end
-
- def self.create_from_json(_)
- raise NotImplementedError
- end
-
- private
-
- def config
- @config ||= GitlabConfig.new
- end
-
- def api
- @api ||= GitlabNet.new
- end
- end
-end
diff --git a/lib/action/git_lfs_authenticate.rb b/lib/action/git_lfs_authenticate.rb
deleted file mode 100644
index 8c5294d..0000000
--- a/lib/action/git_lfs_authenticate.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-require_relative '../action'
-require_relative '../gitlab_logger'
-
-module Action
- class GitLFSAuthenticate < Base
- def initialize(actor, repo_name)
- @actor = actor
- @repo_name = repo_name
- end
-
- def execute(_, _)
- GitlabMetrics.measure('lfs-authenticate') do
- $logger.info('Processing LFS authentication', user: actor.log_username)
- lfs_access = api.lfs_authenticate(actor, repo_name)
- return unless lfs_access
-
- puts lfs_access.authentication_payload
- end
- true
- end
-
- private
-
- attr_reader :actor, :repo_name
- end
-end
diff --git a/lib/action/gitaly.rb b/lib/action/gitaly.rb
deleted file mode 100644
index 6630b1d..0000000
--- a/lib/action/gitaly.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-require_relative '../action'
-require_relative '../gitlab_logger'
-require_relative '../gitlab_net'
-
-module Action
- class Gitaly < Base
- REPOSITORY_PATH_NOT_PROVIDED = "Repository path not provided. Please make sure you're using GitLab v8.10 or later.".freeze
- MIGRATED_COMMANDS = {
- 'git-upload-pack' => File.join(ROOT_PATH, 'bin', 'gitaly-upload-pack'),
- 'git-upload-archive' => File.join(ROOT_PATH, 'bin', 'gitaly-upload-archive'),
- 'git-receive-pack' => File.join(ROOT_PATH, 'bin', 'gitaly-receive-pack')
- }.freeze
-
- def initialize(actor, gl_repository, gl_username, git_config_options, git_protocol, repository_path, gitaly)
- @actor = actor
- @gl_repository = gl_repository
- @gl_username = gl_username
- @git_config_options = git_config_options
- @git_protocol = git_protocol
- @repository_path = repository_path
- @gitaly = gitaly
- end
-
- def self.create_from_json(actor, json)
- new(actor,
- json['gl_repository'],
- json['gl_username'],
- json['git_config_options'],
- json['git_protocol'],
- json['repository_path'],
- json['gitaly'])
- end
-
- def execute(command, args)
- raise ArgumentError, REPOSITORY_PATH_NOT_PROVIDED unless repository_path
- raise InvalidRepositoryPathError unless valid_repository?
-
- $logger.info('Performing Gitaly command', user: actor.log_username)
- process(command, args)
- end
-
- private
-
- attr_reader :actor, :gl_repository, :gl_username, :git_config_options, :repository_path, :gitaly
-
- def git_protocol
- @git_protocol || ENV['GIT_PROTOCOL'] # TODO: tidy this up
- end
-
- def process(command, args)
- executable = command
- args = [repository_path]
-
- if MIGRATED_COMMANDS.key?(executable) && gitaly
- executable = MIGRATED_COMMANDS[executable]
- gitaly_address = gitaly['address']
- args = [gitaly_address, JSON.dump(gitaly_request)]
- end
-
- args_string = [File.basename(executable), *args].join(' ')
- $logger.info('executing git command', command: args_string, user: actor.log_username)
-
- exec_cmd(executable, *args)
- end
-
- def exec_cmd(*args)
- env = exec_env
- env['GITALY_TOKEN'] = gitaly['token'] if gitaly && gitaly.include?('token')
-
- if git_trace_available?
- env.merge!(
- 'GIT_TRACE' => config.git_trace_log_file,
- 'GIT_TRACE_PACKET' => config.git_trace_log_file,
- 'GIT_TRACE_PERFORMANCE' => config.git_trace_log_file
- )
- end
-
- # We use 'chdir: ROOT_PATH' to let the next executable know where config.yml is.
- Kernel.exec(env, *args, unsetenv_others: true, chdir: ROOT_PATH)
- end
-
- def exec_env
- {
- 'HOME' => ENV['HOME'],
- 'PATH' => ENV['PATH'],
- 'LD_LIBRARY_PATH' => ENV['LD_LIBRARY_PATH'],
- 'LANG' => ENV['LANG'],
- 'GL_ID' => actor.identifier,
- 'GL_PROTOCOL' => GitlabNet::GL_PROTOCOL,
- 'GL_REPOSITORY' => gl_repository,
- 'GL_USERNAME' => gl_username
- }
- end
-
- def gitaly_request
- # The entire gitaly_request hash should be built in gitlab-ce and passed
- # on as-is. For now we build a fake one on the spot.
- {
- 'repository' => gitaly['repository'],
- 'gl_repository' => gl_repository,
- 'gl_id' => actor.identifier,
- 'gl_username' => gl_username,
- 'git_config_options' => git_config_options,
- 'git_protocol' => git_protocol
- }
- end
-
- def valid_repository?
- File.absolute_path(repository_path) == repository_path
- end
-
- def git_trace_available?
- return false unless config.git_trace_log_file
-
- if Pathname(config.git_trace_log_file).relative?
- $logger.warn('git trace log path must be absolute, ignoring', git_trace_log_file: config.git_trace_log_file)
- return false
- end
-
- begin
- File.open(config.git_trace_log_file, 'a') { nil }
- return true
- rescue => ex
- $logger.warn('Failed to open git trace log file', git_trace_log_file: config.git_trace_log_file, error: ex.to_s)
- return false
- end
- end
- end
-end
diff --git a/lib/actor.rb b/lib/actor.rb
deleted file mode 100644
index 4e8b3b8..0000000
--- a/lib/actor.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require_relative 'actor/base'
-require_relative 'actor/key'
-require_relative 'actor/user'
-require_relative 'actor/username'
-
-module Actor
- class UnsupportedActorError < StandardError; end
-
- def self.new_from(str, audit_usernames: false)
- case str
- when Key.id_regex
- Key.from(str, audit_usernames: audit_usernames)
- when User.id_regex
- User.from(str, audit_usernames: audit_usernames)
- when Username.id_regex
- Username.from(str, audit_usernames: audit_usernames)
- else
- raise UnsupportedActorError
- end
- end
-end
diff --git a/lib/actor/base.rb b/lib/actor/base.rb
deleted file mode 100644
index 0510c60..0000000
--- a/lib/actor/base.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-module Actor
- class Base
- attr_reader :id
-
- def initialize(id, audit_usernames: false)
- @id = id
- @audit_usernames = audit_usernames
- end
-
- def self.from(str, audit_usernames: false)
- new(str.gsub(/#{identifier_prefix}-/, ''), audit_usernames: audit_usernames)
- end
-
- def self.identifier_key
- raise NotImplementedError
- end
-
- def self.identifier_prefix
- raise NotImplementedError
- end
-
- def self.id_regex
- raise NotImplementedError
- end
-
- def username
- raise NotImplementedError
- end
-
- def identifier
- "#{self.class.identifier_prefix}-#{id}"
- end
-
- def identifier_key
- self.class.identifier_key
- end
-
- def log_username
- audit_usernames? ? username : "#{label} with identifier #{identifier}"
- end
-
- private
-
- attr_reader :audit_usernames
-
- alias audit_usernames? audit_usernames
-
- def klass_name
- self.class.to_s.split('::')[-1]
- end
-
- def label
- klass_name.downcase
- end
- end
-end
diff --git a/lib/actor/key.rb b/lib/actor/key.rb
deleted file mode 100644
index 46f013a..0000000
--- a/lib/actor/key.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require_relative 'base'
-require_relative '../gitlab_net'
-
-module Actor
- class Key < Base
- ANONYMOUS_USER = 'Anonymous'.freeze
-
- alias key_id id
-
- def self.identifier_prefix
- 'key'.freeze
- end
-
- def self.identifier_key
- 'key_id'.freeze
- end
-
- def self.id_regex
- /\Akey\-\d+\Z/
- end
-
- def username
- @username ||= begin
- user = GitlabNet.new.discover(self)
- user ? "@#{user['username']}" : ANONYMOUS_USER
- end
- end
- end
-end
diff --git a/lib/actor/user.rb b/lib/actor/user.rb
deleted file mode 100644
index 55ba7f1..0000000
--- a/lib/actor/user.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require_relative 'base'
-
-module Actor
- class User < Base
- alias username identifier
-
- def self.identifier_prefix
- 'user'.freeze
- end
-
- def self.identifier_key
- 'user_id'.freeze
- end
-
- def self.id_regex
- /\Auser\-\d+\Z/
- end
- end
-end
diff --git a/lib/actor/username.rb b/lib/actor/username.rb
deleted file mode 100644
index cd9d6e5..0000000
--- a/lib/actor/username.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require_relative 'base'
-require_relative 'key'
-
-module Actor
- class Username < Key
- def self.identifier_prefix
- 'username'.freeze
- end
-
- def self.identifier_key
- 'username'.freeze
- end
-
- def self.id_regex
- /\Ausername\-[a-z0-9-]+\z/
- end
-
- private
-
- # Override Base#label
- def label
- 'user'
- end
- end
-end
diff --git a/lib/errors.rb b/lib/errors.rb
deleted file mode 100644
index 7bef3b4..0000000
--- a/lib/errors.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class UnknownError < StandardError; end
-class AccessDeniedError < StandardError; end
-class InvalidRepositoryPathError < StandardError; end
-class DisallowedCommandError < StandardError; end
diff --git a/lib/gitlab_access.rb b/lib/gitlab_access.rb
index 6683ee7..e1a5e35 100644
--- a/lib/gitlab_access.rb
+++ b/lib/gitlab_access.rb
@@ -1,28 +1,34 @@
-require 'json'
-
-require_relative 'errors'
-require_relative 'actor'
require_relative 'gitlab_init'
require_relative 'gitlab_net'
+require_relative 'gitlab_access_status'
require_relative 'names_helper'
require_relative 'gitlab_metrics'
require_relative 'object_dirs_helper'
+require 'json'
class GitlabAccess
+ class AccessDeniedError < StandardError; end
+
include NamesHelper
- def initialize(gl_repository, repo_path, gl_id, changes, protocol)
+ attr_reader :config, :gl_repository, :repo_path, :changes, :protocol
+
+ def initialize(gl_repository, repo_path, actor, changes, protocol)
+ @config = GitlabConfig.new
@gl_repository = gl_repository
@repo_path = repo_path.strip
- @gl_id = gl_id
+ @actor = actor
@changes = changes.lines
@protocol = protocol
end
def exec
- GitlabMetrics.measure('check-access:git-receive-pack') do
- api.check_access('git-receive-pack', gl_repository, repo_path, actor, changes, protocol, env: ObjectDirsHelper.all_attributes.to_json)
+ status = GitlabMetrics.measure('check-access:git-receive-pack') do
+ api.check_access('git-receive-pack', @gl_repository, @repo_path, @actor, @changes, @protocol, env: ObjectDirsHelper.all_attributes.to_json)
end
+
+ raise AccessDeniedError, status.message unless status.allowed?
+
true
rescue GitlabNet::ApiUnreachableError
$stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
@@ -32,19 +38,9 @@ class GitlabAccess
false
end
- private
-
- attr_reader :gl_repository, :repo_path, :gl_id, :changes, :protocol
+ protected
def api
- @api ||= GitlabNet.new
- end
-
- def config
- @config ||= GitlabConfig.new
- end
-
- def actor
- @actor ||= Actor.new_from(gl_id, audit_usernames: config.audit_usernames)
+ GitlabNet.new
end
end
diff --git a/lib/gitlab_access_status.rb b/lib/gitlab_access_status.rb
new file mode 100644
index 0000000..afb5a9e
--- /dev/null
+++ b/lib/gitlab_access_status.rb
@@ -0,0 +1,34 @@
+require 'json'
+
+class GitAccessStatus
+ attr_reader :message, :gl_repository, :gl_id, :gl_username, :repository_path, :gitaly, :git_protocol, :git_config_options
+
+ def initialize(status, message, gl_repository:, gl_id:, gl_username:, repository_path:, gitaly:, git_protocol:, git_config_options:)
+ @status = status
+ @message = message
+ @gl_repository = gl_repository
+ @gl_id = gl_id
+ @gl_username = gl_username
+ @git_config_options = git_config_options
+ @repository_path = repository_path
+ @gitaly = gitaly
+ @git_protocol = git_protocol
+ end
+
+ def self.create_from_json(json)
+ values = JSON.parse(json)
+ new(values["status"],
+ values["message"],
+ gl_repository: values["gl_repository"],
+ gl_id: values["gl_id"],
+ gl_username: values["gl_username"],
+ git_config_options: values["git_config_options"],
+ repository_path: values["repository_path"],
+ gitaly: values["gitaly"],
+ git_protocol: values["git_protocol"])
+ end
+
+ def allowed?
+ @status
+ end
+end
diff --git a/lib/gitlab_custom_hook.rb b/lib/gitlab_custom_hook.rb
index de6eb38..67096df 100644
--- a/lib/gitlab_custom_hook.rb
+++ b/lib/gitlab_custom_hook.rb
@@ -5,9 +5,9 @@ require_relative 'gitlab_metrics'
class GitlabCustomHook
attr_reader :vars, :config
- def initialize(repo_path, gl_id)
+ def initialize(repo_path, key_id)
@repo_path = repo_path
- @vars = { 'GL_ID' => gl_id }
+ @vars = { 'GL_ID' => key_id }
@config = GitlabConfig.new
end
diff --git a/lib/gitlab_keys.rb b/lib/gitlab_keys.rb
index d0463e2..3ee2882 100644
--- a/lib/gitlab_keys.rb
+++ b/lib/gitlab_keys.rb
@@ -9,7 +9,6 @@ class GitlabKeys # rubocop:disable Metrics/ClassLength
attr_accessor :auth_file, :key
- # TODO: whatever is not a great name
def self.command(whatever)
"#{ROOT_PATH}/bin/gitlab-shell #{whatever}"
end
@@ -22,7 +21,6 @@ class GitlabKeys # rubocop:disable Metrics/ClassLength
command(key_id)
end
- # TODO: whatever is not a great name
def self.whatever_line(command, trailer)
"command=\"#{command}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty #{trailer}"
end
diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb
index 9ea18aa..28d1f0d 100644
--- a/lib/gitlab_net.rb
+++ b/lib/gitlab_net.rb
@@ -1,20 +1,23 @@
+require 'net/http'
+require 'openssl'
require 'json'
-require_relative 'errors'
+require_relative 'gitlab_config'
require_relative 'gitlab_logger'
require_relative 'gitlab_access'
require_relative 'gitlab_lfs_authentication'
+require_relative 'httpunix'
require_relative 'http_helper'
-require_relative 'action'
-class GitlabNet
+class GitlabNet # rubocop:disable Metrics/ClassLength
include HTTPHelper
+ class ApiUnreachableError < StandardError; end
+ class NotFound < StandardError; end
+
CHECK_TIMEOUT = 5
- GL_PROTOCOL = 'ssh'.freeze
- API_INACCESSIBLE_ERROR = 'API is not accessible'.freeze
- def check_access(cmd, gl_repository, repo, actor, changes, protocol = GL_PROTOCOL, env: {})
+ def check_access(cmd, gl_repository, repo, who, changes, protocol, env: {})
changes = changes.join("\n") unless changes.is_a?(String)
params = {
@@ -26,27 +29,57 @@ class GitlabNet
env: env
}
- params[actor.identifier_key.to_sym] = actor.id
+ who_sym, _, who_v = self.class.parse_who(who)
+ params[who_sym] = who_v
- resp = post("#{internal_api_endpoint}/allowed", params)
+ url = "#{internal_api_endpoint}/allowed"
+ resp = post(url, params)
- determine_action(actor, resp)
+ if resp.code == '200'
+ GitAccessStatus.create_from_json(resp.body)
+ else
+ GitAccessStatus.new(false,
+ 'API is not accessible',
+ gl_repository: nil,
+ gl_id: nil,
+ gl_username: nil,
+ git_config_options: nil,
+ repository_path: nil,
+ gitaly: nil,
+ git_protocol: nil)
+ end
end
- def discover(actor)
- resp = get("#{internal_api_endpoint}/discover?#{actor.identifier_key}=#{actor.id}")
- JSON.parse(resp.body) if resp.code == HTTP_SUCCESS
- rescue JSON::ParserError, ApiUnreachableError
- nil
+ def discover(who)
+ _, who_k, who_v = self.class.parse_who(who)
+
+ resp = get("#{internal_api_endpoint}/discover?#{who_k}=#{who_v}")
+
+ JSON.parse(resp.body) rescue nil
end
- def lfs_authenticate(actor, repo)
- params = { project: sanitize_path(repo) }
- params[actor.identifier_key.to_sym] = actor.id
+ def lfs_authenticate(gl_id, repo)
+ id_sym, _, id = self.class.parse_who(gl_id)
+
+ if id_sym == :key_id
+ params = {
+ project: sanitize_path(repo),
+ key_id: id
+ }
+ elsif id_sym == :user_id
+ params = {
+ project: sanitize_path(repo),
+ user_id: id
+ }
+ else
+ raise ArgumentError, "lfs_authenticate() got unsupported GL_ID='#{gl_id}'!"
+ end
resp = post("#{internal_api_endpoint}/lfs_authenticate", params)
- GitlabLfsAuthentication.build_from_json(resp.body) if resp.code == HTTP_SUCCESS
+ if resp.code == '200'
+ GitlabLfsAuthentication.build_from_json(resp.body)
+ end
end
def broadcast_message
@@ -61,7 +94,11 @@ class GitlabNet
url += "&gl_repository=#{URI.escape(gl_repository)}" if gl_repository
resp = get(url)
- resp.code == HTTP_SUCCESS ? JSON.parse(resp.body) : []
+ if resp.code == '200'
+ JSON.parse(resp.body)
+ else
+ []
+ end
rescue
[]
end
@@ -70,17 +107,19 @@ class GitlabNet
get("#{internal_api_endpoint}/check", options: { read_timeout: CHECK_TIMEOUT })
end
- def authorized_key(full_key)
- resp = get("#{internal_api_endpoint}/authorized_keys?key=#{URI.escape(full_key, '+/=')}")
- JSON.parse(resp.body) if resp.code == HTTP_SUCCESS
+ def authorized_key(key)
+ resp = get("#{internal_api_endpoint}/authorized_keys?key=#{URI.escape(key, '+/=')}")
+ JSON.parse(resp.body) if resp.code == "200"
rescue
nil
end
- def two_factor_recovery_codes(actor)
- params = { actor.identifier_key.to_sym => actor.id }
- resp = post("#{internal_api_endpoint}/two_factor_recovery_codes", params)
- JSON.parse(resp.body) if resp.code == HTTP_SUCCESS
+ def two_factor_recovery_codes(gl_id)
+ id_sym, _, id = self.class.parse_who(gl_id)
+
+ resp = post("#{internal_api_endpoint}/two_factor_recovery_codes", id_sym => id)
+
+ JSON.parse(resp.body) if resp.code == '200'
rescue
{}
end
@@ -89,50 +128,51 @@ class GitlabNet
params = { gl_repository: gl_repository, project: repo_path }
resp = post("#{internal_api_endpoint}/notify_post_receive", params)
- resp.code == HTTP_SUCCESS
+ resp.code == '200'
rescue
false
end
- def post_receive(gl_repository, actor, changes)
- params = { gl_repository: gl_repository, identifier: actor.identifier, changes: changes }
+ def post_receive(gl_repository, identifier, changes)
+ params = {
+ gl_repository: gl_repository,
+ identifier: identifier,
+ changes: changes
+ }
resp = post("#{internal_api_endpoint}/post_receive", params)
- raise NotFoundError if resp.code == HTTP_NOT_FOUND
- JSON.parse(resp.body) if resp.code == HTTP_SUCCESS
+ raise NotFound if resp.code == '404'
+
+ JSON.parse(resp.body) if resp.code == '200'
end
def pre_receive(gl_repository)
resp = post("#{internal_api_endpoint}/pre_receive", gl_repository: gl_repository)
- raise NotFoundError if resp.code == HTTP_NOT_FOUND
- JSON.parse(resp.body) if resp.code == HTTP_SUCCESS
- end
+ raise NotFound if resp.code == '404'
- private
-
- def sanitize_path(repo)
- repo.delete("'")
+ JSON.parse(resp.body) if resp.code == '200'
end
- def determine_action(actor, resp)
- json = JSON.parse(resp.body)
- message = json['message']
-
- case resp.code
- when HTTP_SUCCESS
- # TODO: This raise can be removed once internal API can respond with correct
- # HTTP status codes, instead of relying upon parsing the body and
- # accessing the 'status' key.
- raise AccessDeniedError, message unless json['status']
-
- Action::Gitaly.create_from_json(actor, json)
- when HTTP_UNAUTHORIZED, HTTP_NOT_FOUND
- raise AccessDeniedError, message
+ def self.parse_who(who)
+ if who.start_with?("key-")
+ value = who.gsub("key-", "")
+ raise ArgumentError, "who='#{who}' is invalid!" unless value =~ /\A[0-9]+\z/
+ [:key_id, 'key_id', value]
+ elsif who.start_with?("user-")
+ value = who.gsub("user-", "")
+ raise ArgumentError, "who='#{who}' is invalid!" unless value =~ /\A[0-9]+\z/
+ [:user_id, 'user_id', value]
+ elsif who.start_with?("username-")
+ [:username, 'username', who.gsub("username-", "")]
else
- raise UnknownError, "#{API_INACCESSIBLE_ERROR}: #{message}"
+ raise ArgumentError, "who='#{who}' is invalid!"
end
- rescue JSON::ParserError
- raise UnknownError, API_INACCESSIBLE_ERROR
+ end
+
+ protected
+
+ def sanitize_path(repo)
+ repo.delete("'")
end
end
diff --git a/lib/gitlab_post_receive.rb b/lib/gitlab_post_receive.rb
index 9248582..cb9931d 100644
--- a/lib/gitlab_post_receive.rb
+++ b/lib/gitlab_post_receive.rb
@@ -8,18 +8,20 @@ require 'securerandom'
class GitlabPostReceive
include NamesHelper
- def initialize(gl_repository, repo_path, gl_id, changes)
+ attr_reader :config, :gl_repository, :repo_path, :changes, :jid
+
+ def initialize(gl_repository, repo_path, actor, changes)
@config = GitlabConfig.new
@gl_repository = gl_repository
@repo_path = repo_path.strip
- @gl_id = gl_id
+ @actor = actor
@changes = changes
@jid = SecureRandom.hex(12)
end
def exec
response = GitlabMetrics.measure("post-receive") do
- api.post_receive(gl_repository, actor, changes)
+ api.post_receive(gl_repository, @actor, changes)
end
return false unless response
@@ -33,18 +35,12 @@ class GitlabPostReceive
false
end
- private
-
- attr_reader :config, :gl_repository, :repo_path, :gl_id, :changes, :jid
+ protected
def api
@api ||= GitlabNet.new
end
- def actor
- @actor ||= Actor.new_from(gl_id, audit_usernames: config.audit_usernames)
- end
-
def print_merge_request_links(merge_request_urls)
return if merge_request_urls.empty?
puts
@@ -104,6 +100,8 @@ class GitlabPostReceive
puts "=" * total_width
end
+ private
+
def parse_broadcast_msg(msg, text_length)
msg ||= ""
# just return msg if shorter than or equal to text length
diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb
index bd7b783..2057ea9 100644
--- a/lib/gitlab_shell.rb
+++ b/lib/gitlab_shell.rb
@@ -3,120 +3,301 @@ require 'pathname'
require_relative 'gitlab_net'
require_relative 'gitlab_metrics'
-require_relative 'actor'
-class GitlabShell
- API_2FA_RECOVERY_CODES_COMMAND = '2fa_recovery_codes'.freeze
+class GitlabShell # rubocop:disable Metrics/ClassLength
+ class AccessDeniedError < StandardError; end
+ class DisallowedCommandError < StandardError; end
+ class InvalidRepositoryPathError < StandardError; end
- GIT_UPLOAD_PACK_COMMAND = 'git-upload-pack'.freeze
- GIT_RECEIVE_PACK_COMMAND = 'git-receive-pack'.freeze
- GIT_UPLOAD_ARCHIVE_COMMAND = 'git-upload-archive'.freeze
- GIT_LFS_AUTHENTICATE_COMMAND = 'git-lfs-authenticate'.freeze
+ GIT_COMMANDS = %w(git-upload-pack git-receive-pack git-upload-archive git-lfs-authenticate).freeze
+ GITALY_MIGRATED_COMMANDS = {
+ 'git-upload-pack' => File.join(ROOT_PATH, 'bin', 'gitaly-upload-pack'),
+ 'git-upload-archive' => File.join(ROOT_PATH, 'bin', 'gitaly-upload-archive'),
+ 'git-receive-pack' => File.join(ROOT_PATH, 'bin', 'gitaly-receive-pack')
+ }.freeze
+ API_COMMANDS = %w(2fa_recovery_codes).freeze
+ GL_PROTOCOL = 'ssh'.freeze
- GIT_COMMANDS = [GIT_UPLOAD_PACK_COMMAND, GIT_RECEIVE_PACK_COMMAND,
- GIT_UPLOAD_ARCHIVE_COMMAND, GIT_LFS_AUTHENTICATE_COMMAND].freeze
-
- Struct.new('ParsedCommand', :command, :git_access_command, :repo_name, :args)
+ attr_accessor :gl_id, :gl_repository, :repo_name, :command, :git_access, :git_protocol
+ attr_reader :repo_path
def initialize(who)
+ who_sym, = GitlabNet.parse_who(who)
+ if who_sym == :username
+ @who = who
+ else
+ @gl_id = who
+ end
@config = GitlabConfig.new
- @actor = Actor.new_from(who, audit_usernames: @config.audit_usernames)
end
# The origin_cmd variable contains UNTRUSTED input. If the user ran
# ssh git@gitlab.example.com 'evil command', then origin_cmd contains
# 'evil command'.
def exec(origin_cmd)
- if !origin_cmd || origin_cmd.empty?
- puts "Welcome to GitLab, #{actor.username}!"
+ unless origin_cmd
+ puts "Welcome to GitLab, #{username}!"
return true
end
- parsed_command = parse_cmd(origin_cmd)
- action = determine_action(parsed_command)
- action.execute(parsed_command.command, parsed_command.args)
+ args = Shellwords.shellwords(origin_cmd)
+ args = parse_cmd(args)
+
+ if GIT_COMMANDS.include?(args.first)
+ GitlabMetrics.measure('verify-access') { verify_access }
+ elsif !defined?(@gl_id)
+ # We're processing an API command like 2fa_recovery_codes, but
+ # don't have a @gl_id yet, that means we're in the "username"
+ # mode and need to materialize it, calling the "user" method
+ # will do that and call the /discover method.
+ user
+ end
+
+ process_cmd(args)
+
+ true
rescue GitlabNet::ApiUnreachableError
$stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
false
- rescue AccessDeniedError, UnknownError => ex
- $logger.warn('Access denied', command: origin_cmd, user: actor.log_username)
+ rescue AccessDeniedError => ex
+ $logger.warn('Access denied', command: origin_cmd, user: log_username)
+
$stderr.puts "GitLab: #{ex.message}"
false
rescue DisallowedCommandError
- $logger.warn('Denied disallowed command', command: origin_cmd, user: actor.log_username)
- $stderr.puts 'GitLab: Disallowed command'
+ $logger.warn('Denied disallowed command', command: origin_cmd, user: log_username)
+
+ $stderr.puts "GitLab: Disallowed command"
false
rescue InvalidRepositoryPathError
- $stderr.puts 'GitLab: Invalid repository path'
+ $stderr.puts "GitLab: Invalid repository path"
false
end
- private
-
- attr_reader :config, :actor
-
- def parse_cmd(cmd)
- args = Shellwords.shellwords(cmd)
+ protected
+ def parse_cmd(args)
# Handle Git for Windows 2.14 using "git upload-pack" instead of git-upload-pack
if args.length == 3 && args.first == 'git'
- command = "git-#{args[1]}"
- args = [command, args.last]
+ @command = "git-#{args[1]}"
+ args = [@command, args.last]
else
- command = args.first
+ @command = args.first
end
- git_access_command = command
+ @git_access = @command
- if command == API_2FA_RECOVERY_CODES_COMMAND
- return Struct::ParsedCommand.new(command, git_access_command, nil, args)
- end
+ return args if API_COMMANDS.include?(@command)
- raise DisallowedCommandError unless GIT_COMMANDS.include?(command)
+ raise DisallowedCommandError unless GIT_COMMANDS.include?(@command)
- case command
+ case @command
when 'git-lfs-authenticate'
raise DisallowedCommandError unless args.count >= 2
- repo_name = args[1]
- git_access_command = case args[2]
- when 'download'
- GIT_UPLOAD_PACK_COMMAND
- when 'upload'
- GIT_RECEIVE_PACK_COMMAND
- else
- raise DisallowedCommandError
- end
+ @repo_name = args[1]
+ case args[2]
+ when 'download'
+ @git_access = 'git-upload-pack'
+ when 'upload'
+ @git_access = 'git-receive-pack'
+ else
+ raise DisallowedCommandError
+ end
else
raise DisallowedCommandError unless args.count == 2
- repo_name = args.last
+ @repo_name = args.last
end
- Struct::ParsedCommand.new(command, git_access_command, repo_name, args)
+ args
end
- def determine_action(parsed_command)
- return Action::API2FARecovery.new(actor) if parsed_command.command == API_2FA_RECOVERY_CODES_COMMAND
+ def verify_access
+ status = api.check_access(@git_access, nil, @repo_name, @who || @gl_id, '_any', GL_PROTOCOL)
+
+ raise AccessDeniedError, status.message unless status.allowed?
+
+ self.repo_path = status.repository_path
+ @gl_repository = status.gl_repository
+ @git_protocol = ENV['GIT_PROTOCOL']
+ @gitaly = status.gitaly
+ @username = status.gl_username
+ @git_config_options = status.git_config_options
+ if defined?(@who)
+ @gl_id = status.gl_id
+ end
+ end
- GitlabMetrics.measure('verify-access') do
- # GitlabNet#check_access will raise exception in the event of a problem
- initial_action = api.check_access(
- parsed_command.git_access_command,
- nil,
- parsed_command.repo_name,
- actor,
- '_any'
+ def process_cmd(args)
+ return send("api_#{@command}") if API_COMMANDS.include?(@command)
+
+ if @command == 'git-lfs-authenticate'
+ GitlabMetrics.measure('lfs-authenticate') do
+ $logger.info('Processing LFS authentication', user: log_username)
+ lfs_authenticate
+ end
+ return
+ end
+
+ executable = @command
+ args = [repo_path]
+
+ if GITALY_MIGRATED_COMMANDS.key?(executable) && @gitaly
+ executable = GITALY_MIGRATED_COMMANDS[executable]
+
+ gitaly_address = @gitaly['address']
+
+ # The entire gitaly_request hash should be built in gitlab-ce and passed
+ # on as-is. For now we build a fake one on the spot.
+ gitaly_request = {
+ 'repository' => @gitaly['repository'],
+ 'gl_repository' => @gl_repository,
+ 'gl_id' => @gl_id,
+ 'gl_username' => @username,
+ 'git_config_options' => @git_config_options,
+ 'git_protocol' => @git_protocol
+ }
+
+ args = [gitaly_address, JSON.dump(gitaly_request)]
+ end
+
+ args_string = [File.basename(executable), *args].join(' ')
+ $logger.info('executing git command', command: args_string, user: log_username)
+ exec_cmd(executable, *args)
+ end
+
+ # This method is not covered by Rspec because it ends the current Ruby process.
+ def exec_cmd(*args)
+ # If you want to call a command without arguments, use
+ # exec_cmd(['my_command', 'my_command']) . Otherwise use
+ # exec_cmd('my_command', 'my_argument', ...).
+ if args.count == 1 && !args.first.is_a?(Array)
+ raise DisallowedCommandError
+ end
+
+ env = {
+ 'HOME' => ENV['HOME'],
+ 'PATH' => ENV['PATH'],
+ 'LD_LIBRARY_PATH' => ENV['LD_LIBRARY_PATH'],
+ 'LANG' => ENV['LANG'],
+ 'GL_ID' => @gl_id,
+ 'GL_PROTOCOL' => GL_PROTOCOL,
+ 'GL_REPOSITORY' => @gl_repository,
+ 'GL_USERNAME' => @username
+ }
+ if @gitaly && @gitaly.include?('token')
+ env['GITALY_TOKEN'] = @gitaly['token']
+ end
+
+ if git_trace_available?
+ env.merge!(
+ 'GIT_TRACE' => @config.git_trace_log_file,
+ 'GIT_TRACE_PACKET' => @config.git_trace_log_file,
+ 'GIT_TRACE_PERFORMANCE' => @config.git_trace_log_file
)
+ end
- case parsed_command.command
- when GIT_LFS_AUTHENTICATE_COMMAND
- Action::GitLFSAuthenticate.new(actor, parsed_command.repo_name)
+ # We use 'chdir: ROOT_PATH' to let the next executable know where config.yml is.
+ Kernel.exec(env, *args, unsetenv_others: true, chdir: ROOT_PATH)
+ end
+
+ def api
+ GitlabNet.new
+ end
+
+ def user
+ return @user if defined?(@user)
+
+ begin
+ if defined?(@who)
+ @user = api.discover(@who)
+ @gl_id = "user-#{@user['id']}"
else
- initial_action
+ @user = api.discover(@gl_id)
end
+ rescue GitlabNet::ApiUnreachableError
+ @user = nil
end
end
- def api
- @api ||= GitlabNet.new
+ def username_from_discover
+ return nil unless user && user['username']
+
+ "@#{user['username']}"
+ end
+
+ def username
+ @username ||= username_from_discover || 'Anonymous'
+ end
+
+ # User identifier to be used in log messages.
+ def log_username
+ @config.audit_usernames ? username : "user with id #{@gl_id}"
+ end
+
+ def lfs_authenticate
+ lfs_access = api.lfs_authenticate(@gl_id, @repo_name)
+
+ return unless lfs_access
+
+ puts lfs_access.authentication_payload
+ end
+
+ private
+
+ def continue?(question)
+ puts "#{question} (yes/no)"
+ STDOUT.flush # Make sure the question gets output before we wait for input
+ continue = STDIN.gets.chomp
+ puts '' # Add a buffer in the output
+ continue == 'yes'
+ end
+
+ def api_2fa_recovery_codes
+ continue = continue?(
+ "Are you sure you want to generate new two-factor recovery codes?\n" \
+ "Any existing recovery codes you saved will be invalidated."
+ )
+
+ unless continue
+ puts 'New recovery codes have *not* been generated. Existing codes will remain valid.'
+ return
+ end
+
+ resp = api.two_factor_recovery_codes(@gl_id)
+ if resp['success']
+ codes = resp['recovery_codes'].join("\n")
+ puts "Your two-factor authentication recovery codes are:\n\n" \
+ "#{codes}\n\n" \
+ "During sign in, use one of the codes above when prompted for\n" \
+ "your two-factor code. Then, visit your Profile Settings and add\n" \
+ "a new device so you do not lose access to your account again."
+ else
+ puts "An error occurred while trying to generate new recovery codes.\n" \
+ "#{resp['message']}"
+ end
+ end
+
+ def git_trace_available?
+ return false unless @config.git_trace_log_file
+
+ if Pathname(@config.git_trace_log_file).relative?
+ $logger.warn('git trace log path must be absolute, ignoring', git_trace_log_file: @config.git_trace_log_file)
+ return false
+ end
+
+ begin
+ File.open(@config.git_trace_log_file, 'a') { nil }
+ return true
+ rescue => ex
+ $logger.warn('Failed to open git trace log file', git_trace_log_file: @config.git_trace_log_file, error: ex.to_s)
+ return false
+ end
+ end
+
+ def repo_path=(repo_path)
+ raise ArgumentError, "Repository path not provided. Please make sure you're using GitLab v8.10 or later." unless repo_path
+ raise InvalidRepositoryPathError if File.absolute_path(repo_path) != repo_path
+
+ @repo_path = repo_path
end
end
diff --git a/lib/http_helper.rb b/lib/http_helper.rb
index 9c7e564..62d0c51 100644
--- a/lib/http_helper.rb
+++ b/lib/http_helper.rb
@@ -1,20 +1,5 @@
-require 'net/http'
-require 'openssl'
-
-require_relative 'gitlab_config'
-require_relative 'httpunix'
-
module HTTPHelper
READ_TIMEOUT = 300
- HTTP_SUCCESS = '200'.freeze
- HTTP_MULTIPLE_CHOICES = '300'.freeze
- HTTP_UNAUTHORIZED = '401'.freeze
- HTTP_NOT_FOUND = '404'.freeze
-
- HTTP_SUCCESS_LIKE = [HTTP_SUCCESS, HTTP_MULTIPLE_CHOICES].freeze
-
- class ApiUnreachableError < StandardError; end
- class NotFoundError < StandardError; end
protected
@@ -91,7 +76,7 @@ module HTTPHelper
$logger.info('finished HTTP request', method: method.to_s.upcase, url: url, duration: Time.new - start_time)
end
- if HTTP_SUCCESS_LIKE.include?(response.code)
+ if response.code == "200"
$logger.debug('Received response', code: response.code, body: response.body)
else
$logger.error('Call failed', method: method.to_s.upcase, url: url, code: response.code, body: response.body)
@@ -124,7 +109,7 @@ module HTTPHelper
end
def secret_token
- @secret_token ||= File.read(config.secret_file)
+ @secret_token ||= File.read config.secret_file
end
def read_timeout
diff --git a/spec/action/api_2fa_recovery.rb_spec.rb b/spec/action/api_2fa_recovery.rb_spec.rb
deleted file mode 100644
index 70091e9..0000000
--- a/spec/action/api_2fa_recovery.rb_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/action/api_2fa_recovery'
-
-describe Action::API2FARecovery do
- let(:key_id) { '1' }
- let(:actor) { Actor::Key.new(key_id) }
- let(:username) { 'testuser' }
- let(:discover_payload) { { 'username' => username } }
- let(:api) { double(GitlabNet) }
-
- before do
- allow(GitlabNet).to receive(:new).and_return(api)
- allow(api).to receive(:discover).with(actor).and_return(discover_payload)
- end
-
- subject do
- described_class.new(actor)
- end
-
- describe '#execute' do
- context 'with an invalid repsonse' do
- it 'returns nil' do
- expect($stdin).to receive(:gets).and_return("meh\n")
-
- expect do
- expect(subject.execute(nil, nil)).to be_nil
- end.to output(/New recovery codes have \*not\* been generated/).to_stdout
- end
- end
-
- context 'with a negative response' do
- before do
- expect(subject).to receive(:continue?).and_return(false)
- end
-
- it 'returns nil' do
- expect do
- expect(subject.execute(nil, nil)).to be_nil
- end.to output(/New recovery codes have \*not\* been generated/).to_stdout
- end
- end
-
-
- context 'with an affirmative response' do
- let(:recovery_codes) { %w{ 8dfe0f433208f40b289904c6072e4a72 c33cee7fd0a73edb56e61b785e49af03 } }
-
- before do
- expect(subject).to receive(:continue?).and_return(true)
- expect(api).to receive(:two_factor_recovery_codes).with(actor).and_return(response)
- end
-
- context 'with a unsuccessful response' do
- let(:response) { { 'success' => false } }
-
- it 'puts error message to stdout' do
- expect do
- expect(subject.execute(nil, nil)).to be_falsey
- end.to output(/An error occurred while trying to generate new recovery codes/).to_stdout
- end
- end
-
- context 'with a successful response' do
- let(:response) { { 'success' => true, 'recovery_codes' => recovery_codes } }
-
- it 'puts information message including recovery codes to stdout' do
- expect do
- expect(subject.execute(nil, nil)).to be_truthy
- end.to output(Regexp.new(recovery_codes.join("\n"))).to_stdout
- end
- end
- end
- end
-end
diff --git a/spec/action/base_spec.rb b/spec/action/base_spec.rb
deleted file mode 100644
index e986378..0000000
--- a/spec/action/base_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/action/base'
-
-describe Action::Base do
- describe '.create_from_json' do
- it 'raises a NotImplementedError exeption' do
- expect do
- described_class.create_from_json('nomatter')
- end.to raise_error(NotImplementedError)
- end
- end
-end
diff --git a/spec/action/git_lfs_authenticate_spec.rb b/spec/action/git_lfs_authenticate_spec.rb
deleted file mode 100644
index 07e844f..0000000
--- a/spec/action/git_lfs_authenticate_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/action/git_lfs_authenticate'
-
-describe Action::GitLFSAuthenticate do
- let(:key_id) { '1' }
- let(:repo_name) { 'gitlab-ci.git' }
- let(:actor) { Actor::Key.new(key_id) }
- let(:username) { 'testuser' }
- let(:discover_payload) { { 'username' => username } }
- let(:api) { double(GitlabNet) }
-
- before do
- allow(GitlabNet).to receive(:new).and_return(api)
- allow(api).to receive(:discover).with(actor).and_return(discover_payload)
- end
-
- subject do
- described_class.new(actor, repo_name)
- end
-
- describe '#execute' do
- context 'when response from API is not a success' do
- before do
- expect(api).to receive(:lfs_authenticate).with(actor, repo_name).and_return(nil)
- end
-
- it 'returns nil' do
- expect(subject.execute(nil, nil)).to be_nil
- end
- end
-
- context 'when response from API is a success' do
- let(:username) { 'testuser' }
- let(:lfs_token) { '1234' }
- let(:repository_http_path) { "/tmp/#{repo_name}" }
- let(:gitlab_lfs_authentication) { GitlabLfsAuthentication.new(username, lfs_token, repository_http_path) }
-
- before do
- expect(api).to receive(:lfs_authenticate).with(actor, repo_name).and_return(gitlab_lfs_authentication)
- end
-
- it 'puts payload to stdout' do
- expect($stdout).to receive(:puts).with('{"header":{"Authorization":"Basic dGVzdHVzZXI6MTIzNA=="},"href":"/tmp/gitlab-ci.git/info/lfs/"}')
- expect(subject.execute(nil, nil)).to be_truthy
- end
- end
- end
-end
diff --git a/spec/action/gitaly_spec.rb b/spec/action/gitaly_spec.rb
deleted file mode 100644
index 7b34ccd..0000000
--- a/spec/action/gitaly_spec.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/action/gitaly'
-
-describe Action::Gitaly do
- let(:git_trace_log_file_valid) { '/tmp/git_trace_performance.log' }
- let(:git_trace_log_file_invalid) { "/bleep-bop#{git_trace_log_file_valid}" }
- let(:git_trace_log_file_relative) { "..#{git_trace_log_file_valid}" }
- let(:key_id) { '1' }
- let(:key_str) { 'key-1' }
- let(:key) { Actor::Key.new(key_id) }
- let(:gl_repository) { 'project-1' }
- let(:gl_username) { 'testuser' }
- let(:git_config_options) { ['receive.MaxInputSize=10000'] }
- let(:git_protocol) { 'version=2' }
- let(:tmp_repos_path) { File.join(ROOT_PATH, 'tmp', 'repositories') }
- let(:repo_name) { 'gitlab-ci.git' }
- let(:repository_path) { File.join(tmp_repos_path, repo_name) }
- let(:gitaly_address) { 'unix:gitaly.socket' }
- let(:gitaly_token) { '123456' }
- let(:gitaly) do
- {
- 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default' },
- 'address' => gitaly_address,
- 'token' => gitaly_token
- }
- end
-
- describe '.create_from_json' do
- it 'returns an instance of Action::Gitaly' do
- json = {
- "gl_repository" => gl_repository,
- "gl_username" => gl_username,
- "repository_path" => repository_path,
- "gitaly" => gitaly
- }
- expect(described_class.create_from_json(key_id, json)).to be_instance_of(Action::Gitaly)
- end
- end
-
- subject do
- described_class.new(key, gl_repository, gl_username, git_config_options, git_protocol, repository_path, gitaly)
- end
-
- describe '#execute' do
- let(:args) { [ repository_path ] }
- let(:base_exec_env) do
- {
- 'HOME' => ENV['HOME'],
- 'PATH' => ENV['PATH'],
- 'LD_LIBRARY_PATH' => ENV['LD_LIBRARY_PATH'],
- 'LANG' => ENV['LANG'],
- 'GL_ID' => key_str,
- 'GL_PROTOCOL' => GitlabNet::GL_PROTOCOL,
- 'GL_REPOSITORY' => gl_repository,
- 'GL_USERNAME' => gl_username,
- 'GITALY_TOKEN' => gitaly_token,
- }
- end
- let(:with_trace_exec_env) do
- base_exec_env.merge({
- 'GIT_TRACE' => git_trace_log_file,
- 'GIT_TRACE_PACKET' => git_trace_log_file,
- 'GIT_TRACE_PERFORMANCE' => git_trace_log_file
- })
- end
- let(:gitaly_request) do
- {
- 'repository' => gitaly['repository'],
- 'gl_repository' => gl_repository,
- 'gl_id' => key_str,
- 'gl_username' => gl_username,
- 'git_config_options' => git_config_options,
- 'git_protocol' => git_protocol
- }
- end
-
- context 'for migrated commands' do
- context 'such as git-upload-pack' do
- let(:git_trace_log_file) { nil }
- let(:command) { 'git-upload-pack' }
-
- before do
- allow_any_instance_of(GitlabConfig).to receive(:git_trace_log_file).and_return(git_trace_log_file)
- end
-
- context 'with an invalid config.git_trace_log_file' do
- let(:git_trace_log_file) { git_trace_log_file_invalid }
-
- it 'returns true' do
- expect(Kernel).to receive(:exec).with(
- base_exec_env,
- described_class::MIGRATED_COMMANDS[command],
- gitaly_address,
- JSON.dump(gitaly_request),
- unsetenv_others: true,
- chdir: ROOT_PATH
- ).and_return(true)
-
- expect(subject.execute(command, args)).to be_truthy
- end
- end
-
- context 'with n relative config.git_trace_log_file' do
- let(:git_trace_log_file) { git_trace_log_file_relative }
-
- it 'returns true' do
- expect(Kernel).to receive(:exec).with(
- base_exec_env,
- described_class::MIGRATED_COMMANDS[command],
- gitaly_address,
- JSON.dump(gitaly_request),
- unsetenv_others: true,
- chdir: ROOT_PATH
- ).and_return(true)
-
- expect(subject.execute(command, args)).to be_truthy
- end
- end
-
- context 'with a valid config.git_trace_log_file' do
- let(:git_trace_log_file) { git_trace_log_file_valid }
-
- it 'returns true' do
- expect(Kernel).to receive(:exec).with(
- with_trace_exec_env,
- described_class::MIGRATED_COMMANDS[command],
- gitaly_address,
- JSON.dump(gitaly_request),
- unsetenv_others: true,
- chdir: ROOT_PATH
- ).and_return(true)
-
- expect(subject.execute(command, args)).to be_truthy
- end
- end
- end
- end
- end
-end
diff --git a/spec/actor/base_spec.rb b/spec/actor/base_spec.rb
deleted file mode 100644
index 26f899d..0000000
--- a/spec/actor/base_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/actor/base'
-
-describe Actor::Base do
- describe '.identifier_key' do
- it 'raises a NotImplementedError exception' do
- expect do
- described_class.identifier_key
- end.to raise_error(NotImplementedError)
- end
- end
-
- describe '.identifier_prefix' do
- it 'raises a NotImplementedError exception' do
- expect do
- described_class.identifier_prefix
- end.to raise_error(NotImplementedError)
- end
- end
-
- describe '.id_regex' do
- it 'raises a NotImplementedError exception' do
- expect do
- described_class.id_regex
- end.to raise_error(NotImplementedError)
- end
- end
-end
diff --git a/spec/actor/key_spec.rb b/spec/actor/key_spec.rb
deleted file mode 100644
index e61a083..0000000
--- a/spec/actor/key_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/actor/key'
-
-describe Actor::Key do
- let(:key_id) { '1' }
- let(:username) { 'testuser' }
- let(:api) { double(GitlabNet) }
-
- let(:discover_payload) { { 'username' => username } }
- let(:audit_usernames) { nil }
-
- before do
- allow(GitlabNet).to receive(:new).and_return(api)
- allow(api).to receive(:discover).with(subject).and_return(discover_payload)
- end
-
- describe '.from' do
- it 'returns an instance of Actor::Key' do
- expect(described_class.from('key-1')).to be_a(Actor::Key)
- end
-
- it 'has a key_id == 1' do
- expect(described_class.from('key-1').key_id).to eq '1'
- end
- end
-
- describe '.identifier_prefix' do
- it "returns 'key'" do
- expect(described_class.identifier_prefix).to eql 'key'
- end
- end
-
- describe '.identifier_key' do
- it "returns 'key_id'" do
- expect(described_class.identifier_key).to eql 'key_id'
- end
- end
-
- subject { described_class.new(key_id, audit_usernames: audit_usernames) }
-
- describe '#username' do
- context 'with a valid user' do
- it "returns '@testuser'" do
- expect(subject.username).to eql '@testuser'
- end
- end
-
- context 'without a valid user' do
- let(:discover_payload) { nil }
-
- it "returns 'Anonymous'" do
- expect(subject.username).to eql 'Anonymous'
- end
- end
- end
-
- describe '#identifier' do
- it "returns 'key-1'" do
- expect(subject.identifier).to eql 'key-1'
- end
- end
-
- describe '#log_username' do
- context 'when audit_usernames is true' do
- let(:audit_usernames) { true }
-
- it "returns 'testuser'" do
- expect(subject.log_username).to eql '@testuser'
- end
- end
-
- context 'when audit_usernames is false' do
- let(:audit_usernames) { false }
-
- it "returns 'key with identifier key-1'" do
- expect(subject.log_username).to eql 'key with identifier key-1'
- end
- end
- end
-end
diff --git a/spec/actor/user_spec.rb b/spec/actor/user_spec.rb
deleted file mode 100644
index 311fe73..0000000
--- a/spec/actor/user_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/actor/user'
-
-describe Actor::User do
- let(:user_id) { '1' }
- let(:username) { 'testuser' }
- let(:audit_usernames) { nil }
-
- describe '.from' do
- it 'returns an instance of Actor::User' do
- expect(described_class.from('user-1')).to be_a(Actor::User)
- end
-
- it 'has an id == 1' do
- expect(described_class.from('user-1').id).to eq '1'
- end
- end
-
- describe '.identifier_prefix' do
- it "returns 'user'" do
- expect(described_class.identifier_prefix).to eql 'user'
- end
- end
-
- describe '.identifier_key' do
- it "returns 'user_id'" do
- expect(described_class.identifier_key).to eql 'user_id'
- end
- end
-
- subject { described_class.new(user_id, audit_usernames: audit_usernames) }
-
- describe '#username' do
- it "returns 'user-1'" do
- expect(subject.username).to eql 'user-1'
- end
- end
-
- describe '#identifier' do
- it "returns 'user-1'" do
- expect(subject.identifier).to eql 'user-1'
- end
- end
-
- describe '#log_username' do
- context 'when audit_usernames is true' do
- let(:audit_usernames) { true }
-
- it "returns 'user-1'" do
- expect(subject.log_username).to eql 'user-1'
- end
- end
-
- context 'when audit_usernames is false' do
- let(:audit_usernames) { false }
-
- it "returns 'user with identifier user-1'" do
- expect(subject.log_username).to eql 'user with identifier user-1'
- end
- end
- end
-end
diff --git a/spec/actor/username_spec.rb b/spec/actor/username_spec.rb
deleted file mode 100644
index a02bf12..0000000
--- a/spec/actor/username_spec.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-require_relative '../spec_helper'
-require_relative '../../lib/actor/username'
-
-describe Actor::Username do
- let(:username) { 'testuser' }
- let(:api) { double(GitlabNet) }
-
- let(:discover_payload) { { 'username' => username } }
- let(:audit_usernames) { nil }
-
- before do
- allow(GitlabNet).to receive(:new).and_return(api)
- allow(api).to receive(:discover).with(subject).and_return(discover_payload)
- end
-
- describe '.from' do
- it 'returns an instance of Actor::Username' do
- expect(described_class.from("username-#{username}")).to be_a(Actor::Username)
- end
-
- it 'has an id == 1' do
- expect(described_class.from('username-1').id).to eq '1'
- end
- end
-
- describe '.identifier_prefix' do
- it "returns 'user'" do
- expect(described_class.identifier_prefix).to eql 'username'
- end
- end
-
- describe '.identifier_key' do
- it "returns 'username'" do
- expect(described_class.identifier_key).to eql 'username'
- end
- end
-
- subject { described_class.new(username, audit_usernames: audit_usernames) }
-
- describe '#username' do
- context 'without a valid user' do
- it "returns '@testuser'" do
- expect(subject.username).to eql "@#{username}"
- end
- end
-
- context 'without a valid user' do
- let(:discover_payload) { nil }
-
- it "returns 'Anonymous'" do
- expect(subject.username).to eql 'Anonymous'
- end
- end
- end
-
- describe '#identifier' do
- it "returns 'username-testuser'" do
- expect(subject.identifier).to eql 'username-testuser'
- end
- end
-
- describe '#log_username' do
- context 'when audit_usernames is true' do
- let(:audit_usernames) { true }
-
- it "returns '@testuser'" do
- expect(subject.log_username).to eql "@#{username}"
- end
- end
-
- context 'when audit_usernames is false' do
- let(:audit_usernames) { false }
-
- it "returns 'user with identifier username-testuser'" do
- expect(subject.log_username).to eql "user with identifier username-#{username}"
- end
- end
- end
-end
diff --git a/spec/actor_spec.rb b/spec/actor_spec.rb
deleted file mode 100644
index 57cc718..0000000
--- a/spec/actor_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require_relative 'spec_helper'
-require_relative '../lib/actor'
-
-describe Actor do
- describe '.new_from' do
- context 'for an unsupported Actor type' do
- it 'raises a NotImplementedError exception' do
- expect do
- described_class.new_from('unsupported-1')
- end.to raise_error(Actor::UnsupportedActorError)
- end
- end
-
- context 'for a supported Actor type' do
- context 'of Key' do
- it 'returns an instance of Key' do
- expect(described_class.new_from('key-1')).to be_a(Actor::Key)
- end
- end
-
- context 'of User' do
- it 'returns an instance of User' do
- expect(described_class.new_from('user-1')).to be_a(Actor::User)
- end
- end
-
- context 'of Username' do
- it 'returns an instance of Username' do
- expect(described_class.new_from('username-john1')).to be_a(Actor::Username)
- end
- end
- end
- end
-end
diff --git a/spec/gitlab_access_spec.rb b/spec/gitlab_access_spec.rb
index c99959e..7c1e6b4 100644
--- a/spec/gitlab_access_spec.rb
+++ b/spec/gitlab_access_spec.rb
@@ -7,28 +7,32 @@ describe GitlabAccess do
let(:repo_path) { File.join(repository_path, repo_name) + ".git" }
let(:api) do
double(GitlabNet).tap do |api|
- allow(api).to receive(:check_access).and_return(
- Action::Gitaly.new(
- 'key-1',
- 'project-1',
- 'testuser',
- ['receive.MaxInputSize=10000'],
- 'version=2',
- '/home/git/repositories',
- nil
- )
- )
+ api.stub(check_access: GitAccessStatus.new(true,
+ 'ok',
+ gl_repository: 'project-1',
+ gl_id: 'user-123',
+ gl_username: 'testuser',
+ git_config_options: ['receive.MaxInputSize=10000'],
+ repository_path: '/home/git/repositories',
+ gitaly: nil,
+ git_protocol: 'version=2'))
end
end
subject do
GitlabAccess.new(nil, repo_path, 'key-123', 'wow', 'ssh').tap do |access|
- allow(access).to receive(:exec_cmd).and_return(:exec_called)
- allow(access).to receive(:api).and_return(api)
+ access.stub(exec_cmd: :exec_called)
+ access.stub(api: api)
end
end
before do
- allow_any_instance_of(GitlabConfig).to receive(:repos_path).and_return(repository_path)
+ GitlabConfig.any_instance.stub(repos_path: repository_path)
+ end
+
+ describe :initialize do
+ it { subject.repo_path.should == repo_path }
+ it { subject.changes.should == ['wow'] }
+ it { subject.protocol.should == 'ssh' }
end
describe "#exec" do
@@ -40,7 +44,17 @@ describe GitlabAccess do
context "access is denied" do
before do
- allow(api).to receive(:check_access).and_raise(AccessDeniedError)
+ api.stub(check_access: GitAccessStatus.new(
+ false,
+ 'denied',
+ gl_repository: nil,
+ gl_id: nil,
+ gl_username: nil,
+ git_config_options: nil,
+ repository_path: nil,
+ gitaly: nil,
+ git_protocol: nil
+ ))
end
it "returns false" do
@@ -50,7 +64,7 @@ describe GitlabAccess do
context "API connection fails" do
before do
- allow(api).to receive(:check_access).and_raise(GitlabNet::ApiUnreachableError)
+ api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
end
it "returns false" do
diff --git a/spec/gitlab_config_spec.rb b/spec/gitlab_config_spec.rb
index dd7e3bc..a1c52a0 100644
--- a/spec/gitlab_config_spec.rb
+++ b/spec/gitlab_config_spec.rb
@@ -3,55 +3,29 @@ require_relative '../lib/gitlab_config'
describe GitlabConfig do
let(:config) { GitlabConfig.new }
- let(:config_data) do
- {
- # 'user' => 'git',
- # 'http_settings' => {
- # 'self_signed_cert' => false
- # },
- # 'log_level' => 'ERROR',
- # 'audit_usernames' => true,
- # 'log_format' => 'json', # Not sure on other values?
- # 'git_trace_log_file' => nil
- }
- end
-
- before do
- expect(YAML).to receive(:load_file).and_return(config_data)
- end
- describe '#gitlab_url' do
+ describe :gitlab_url do
let(:url) { 'http://test.com' }
-
subject { config.gitlab_url }
-
- before { config_data['gitlab_url'] = url }
+ before { config.send(:config)['gitlab_url'] = url }
it { should_not be_empty }
it { should eq(url) }
context 'remove trailing slashes' do
- before { config_data['gitlab_url'] = url + '//' }
+ before { config.send(:config)['gitlab_url'] = url + '//' }
it { should eq(url) }
end
end
- describe '#audit_usernames' do
+ describe :audit_usernames do
subject { config.audit_usernames }
it("returns false by default") { should eq(false) }
end
- describe '#log_level' do
- subject { config.log_level }
-
- it 'returns "INFO" by default' do
- should eq('INFO')
- end
- end
-
- describe '#log_format' do
+ describe :log_format do
subject { config.log_format }
it 'returns "text" by default' do
diff --git a/spec/gitlab_keys_spec.rb b/spec/gitlab_keys_spec.rb
index 3cd6798..7011ca0 100644
--- a/spec/gitlab_keys_spec.rb
+++ b/spec/gitlab_keys_spec.rb
@@ -65,9 +65,9 @@ describe GitlabKeys do
describe :initialize do
let(:gitlab_keys) { build_gitlab_keys('add-key', 'key-741', 'ssh-rsa AAAAB3NzaDAxx2E') }
- it { expect(gitlab_keys.key).to eql 'ssh-rsa AAAAB3NzaDAxx2E' }
- it { expect(gitlab_keys.instance_variable_get(:@command)).to eql 'add-key' }
- it { expect(gitlab_keys.instance_variable_get(:@key_id)).to eql 'key-741' }
+ it { gitlab_keys.key.should == 'ssh-rsa AAAAB3NzaDAxx2E' }
+ it { gitlab_keys.instance_variable_get(:@command).should == 'add-key' }
+ it { gitlab_keys.instance_variable_get(:@key_id).should == 'key-741' }
end
describe :add_key do
@@ -77,7 +77,7 @@ describe GitlabKeys do
create_authorized_keys_fixture
gitlab_keys.send :add_key
auth_line = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-741\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaDAxx2E"
- expect(File.read(tmp_authorized_keys_path)).to eql "existing content\n#{auth_line}\n"
+ File.read(tmp_authorized_keys_path).should == "existing content\n#{auth_line}\n"
end
context "without file writing" do
@@ -85,12 +85,12 @@ describe GitlabKeys do
before { create_authorized_keys_fixture }
it "should log an add-key event" do
- expect($logger).to receive(:info).with("Adding key", {:key_id=>"key-741", :public_key=>"ssh-rsa AAAAB3NzaDAxx2E"})
+ $logger.should_receive(:info).with("Adding key", {:key_id=>"key-741", :public_key=>"ssh-rsa AAAAB3NzaDAxx2E"})
gitlab_keys.send :add_key
end
it "should return true" do
- expect(gitlab_keys.send(:add_key)).to be_truthy
+ gitlab_keys.send(:add_key).should be_truthy
end
end
end
@@ -104,7 +104,7 @@ describe GitlabKeys do
create_authorized_keys_fixture
gitlab_keys.send :add_key
auth_line1 = 'key-741 AAAAB3NzaDAxx2E'
- expect(gitlab_keys.send(:list_keys)).to eql "#{auth_line1}\n"
+ gitlab_keys.send(:list_keys).should == "#{auth_line1}\n"
end
end
@@ -118,9 +118,10 @@ describe GitlabKeys do
end
it 'outputs the key IDs, separated by newlines' do
- expect do
+ output = capture_stdout do
gitlab_keys.send(:list_key_ids)
- end.to output("1\n2\n3\n9000\n").to_stdout
+ end
+ output.should match "1\n2\n3\n9000"
end
end
@@ -129,38 +130,38 @@ describe GitlabKeys do
let(:fake_stdin) { StringIO.new("key-12\tssh-dsa ASDFASGADG\nkey-123\tssh-rsa GFDGDFSGSDFG\n", 'r') }
before do
create_authorized_keys_fixture
- allow(gitlab_keys).to receive(:stdin).and_return(fake_stdin)
+ gitlab_keys.stub(stdin: fake_stdin)
end
it "adds lines at the end of the file" do
gitlab_keys.send :batch_add_keys
auth_line1 = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-12\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dsa ASDFASGADG"
auth_line2 = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-123\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa GFDGDFSGSDFG"
- expect(File.read(tmp_authorized_keys_path)).to eql "existing content\n#{auth_line1}\n#{auth_line2}\n"
+ File.read(tmp_authorized_keys_path).should == "existing content\n#{auth_line1}\n#{auth_line2}\n"
end
context "with invalid input" do
let(:fake_stdin) { StringIO.new("key-12\tssh-dsa ASDFASGADG\nkey-123\tssh-rsa GFDGDFSGSDFG\nfoo\tbar\tbaz\n", 'r') }
it "aborts" do
- expect(gitlab_keys).to receive(:abort)
+ gitlab_keys.should_receive(:abort)
gitlab_keys.send :batch_add_keys
end
end
context "without file writing" do
before do
- expect(gitlab_keys).to receive(:open).and_yield(double(:file, puts: nil, chmod: nil))
+ gitlab_keys.should_receive(:open).and_yield(double(:file, puts: nil, chmod: nil))
end
it "should log an add-key event" do
- expect($logger).to receive(:info).with("Adding key", key_id: 'key-12', public_key: "ssh-dsa ASDFASGADG")
- expect($logger).to receive(:info).with("Adding key", key_id: 'key-123', public_key: "ssh-rsa GFDGDFSGSDFG")
+ $logger.should_receive(:info).with("Adding key", key_id: 'key-12', public_key: "ssh-dsa ASDFASGADG")
+ $logger.should_receive(:info).with("Adding key", key_id: 'key-123', public_key: "ssh-rsa GFDGDFSGSDFG")
gitlab_keys.send :batch_add_keys
end
it "should return true" do
- expect(gitlab_keys.send(:batch_add_keys)).to be_truthy
+ gitlab_keys.send(:batch_add_keys).should be_truthy
end
end
end
@@ -186,22 +187,22 @@ describe GitlabKeys do
end
gitlab_keys.send :rm_key
erased_line = delete_line.gsub(/./, '#')
- expect(File.read(tmp_authorized_keys_path)).to eql "existing content\n#{erased_line}\n#{other_line}\n"
+ File.read(tmp_authorized_keys_path).should == "existing content\n#{erased_line}\n#{other_line}\n"
end
context "without file writing" do
before do
- allow(gitlab_keys).to receive(:open)
- allow(gitlab_keys).to receive(:lock).and_yield
+ gitlab_keys.stub(:open)
+ gitlab_keys.stub(:lock).and_yield
end
it "should log an rm-key event" do
- expect($logger).to receive(:info).with("Removing key", key_id: "key-741")
+ $logger.should_receive(:info).with("Removing key", key_id: "key-741")
gitlab_keys.send :rm_key
end
it "should return true" do
- expect(gitlab_keys.send(:rm_key)).to be_truthy
+ gitlab_keys.send(:rm_key).should be_truthy
end
end
@@ -218,7 +219,7 @@ describe GitlabKeys do
end
gitlab_keys.send :rm_key
erased_line = delete_line.gsub(/./, '#')
- expect(File.read(tmp_authorized_keys_path)).to eql "existing content\n#{erased_line}\n#{other_line}\n"
+ File.read(tmp_authorized_keys_path).should == "existing content\n#{erased_line}\n#{other_line}\n"
end
end
end
@@ -227,8 +228,8 @@ describe GitlabKeys do
let(:gitlab_keys) { build_gitlab_keys('clear') }
it "should return true" do
- allow(gitlab_keys).to receive(:open)
- expect(gitlab_keys.send(:clear)).to be_truthy
+ gitlab_keys.stub(:open)
+ gitlab_keys.send(:clear).should be_truthy
end
end
@@ -241,7 +242,7 @@ describe GitlabKeys do
end
it 'returns false if opening raises an exception' do
- expect(gitlab_keys).to receive(:open_auth_file).and_raise("imaginary error")
+ gitlab_keys.should_receive(:open_auth_file).and_raise("imaginary error")
expect(gitlab_keys.exec).to eq(false)
end
@@ -256,51 +257,51 @@ describe GitlabKeys do
describe :exec do
it 'add-key arg should execute add_key method' do
gitlab_keys = build_gitlab_keys('add-key')
- expect(gitlab_keys).to receive(:add_key)
+ gitlab_keys.should_receive(:add_key)
gitlab_keys.exec
end
it 'batch-add-keys arg should execute batch_add_keys method' do
gitlab_keys = build_gitlab_keys('batch-add-keys')
- expect(gitlab_keys).to receive(:batch_add_keys)
+ gitlab_keys.should_receive(:batch_add_keys)
gitlab_keys.exec
end
it 'rm-key arg should execute rm_key method' do
gitlab_keys = build_gitlab_keys('rm-key')
- expect(gitlab_keys).to receive(:rm_key)
+ gitlab_keys.should_receive(:rm_key)
gitlab_keys.exec
end
it 'clear arg should execute clear method' do
gitlab_keys = build_gitlab_keys('clear')
- expect(gitlab_keys).to receive(:clear)
+ gitlab_keys.should_receive(:clear)
gitlab_keys.exec
end
it 'check-permissions arg should execute check_permissions method' do
gitlab_keys = build_gitlab_keys('check-permissions')
- expect(gitlab_keys).to receive(:check_permissions)
+ gitlab_keys.should_receive(:check_permissions)
gitlab_keys.exec
end
it 'should puts message if unknown command arg' do
gitlab_keys = build_gitlab_keys('change-key')
- expect(gitlab_keys).to receive(:puts).with('not allowed')
+ gitlab_keys.should_receive(:puts).with('not allowed')
gitlab_keys.exec
end
it 'should log a warning on unknown commands' do
gitlab_keys = build_gitlab_keys('nooope')
- allow(gitlab_keys).to receive(:puts).and_return(nil)
- expect($logger).to receive(:warn).with("Attempt to execute invalid gitlab-keys command", command: '"nooope"')
+ gitlab_keys.stub(puts: nil)
+ $logger.should_receive(:warn).with("Attempt to execute invalid gitlab-keys command", command: '"nooope"')
gitlab_keys.exec
end
end
describe :lock do
before do
- allow_any_instance_of(GitlabKeys).to receive(:lock_file).and_return(tmp_lock_file_path)
+ GitlabKeys.any_instance.stub(lock_file: tmp_lock_file_path)
end
it "should raise exception if operation lasts more then timeout" do
@@ -309,7 +310,7 @@ describe GitlabKeys do
key.send :lock, 1 do
sleep 2
end
- end.to raise_error(Timeout::Error)
+ end.to raise_error
end
it "should actually lock file" do
@@ -334,7 +335,7 @@ describe GitlabKeys do
end
thr1.join
- expect($global).to eql "foobar"
+ $global.should == "foobar"
end
end
@@ -352,7 +353,7 @@ describe GitlabKeys do
def create_authorized_keys_fixture(existing_content: 'existing content')
FileUtils.mkdir_p(File.dirname(tmp_authorized_keys_path))
open(tmp_authorized_keys_path, 'w') { |file| file.puts(existing_content) }
- allow(gitlab_keys).to receive(:auth_file).and_return(tmp_authorized_keys_path)
+ gitlab_keys.stub(auth_file: tmp_authorized_keys_path)
end
def tmp_authorized_keys_path
diff --git a/spec/gitlab_lfs_authentication_spec.rb b/spec/gitlab_lfs_authentication_spec.rb
index 5516bb5..9e93a07 100644
--- a/spec/gitlab_lfs_authentication_spec.rb
+++ b/spec/gitlab_lfs_authentication_spec.rb
@@ -16,22 +16,22 @@ describe GitlabLfsAuthentication do
end
describe '#build_from_json' do
- it { expect(subject.username).to eql 'dzaporozhets' }
- it { expect(subject.lfs_token).to eql 'wsnys8Zm8Jn7zyhHTAAK' }
- it { expect(subject.repository_http_path).to eql 'http://gitlab.dev/repo' }
+ it { subject.username.should == 'dzaporozhets' }
+ it { subject.lfs_token.should == 'wsnys8Zm8Jn7zyhHTAAK' }
+ it { subject.repository_http_path.should == 'http://gitlab.dev/repo' }
end
describe '#authentication_payload' do
result = "{\"header\":{\"Authorization\":\"Basic ZHphcG9yb3poZXRzOndzbnlzOFptOEpuN3p5aEhUQUFL\"},\"href\":\"http://gitlab.dev/repo/info/lfs/\"}"
- it { expect(subject.authentication_payload).to eq(result) }
+ it { subject.authentication_payload.should eq(result) }
it 'should be a proper JSON' do
payload = subject.authentication_payload
json_payload = JSON.parse(payload)
- expect(json_payload['header']['Authorization']).to eq('Basic ZHphcG9yb3poZXRzOndzbnlzOFptOEpuN3p5aEhUQUFL')
- expect(json_payload['href']).to eq('http://gitlab.dev/repo/info/lfs/')
+ json_payload['header']['Authorization'].should eq('Basic ZHphcG9yb3poZXRzOndzbnlzOFptOEpuN3p5aEhUQUFL')
+ json_payload['href'].should eq('http://gitlab.dev/repo/info/lfs/')
end
end
end
diff --git a/spec/gitlab_logger_spec.rb b/spec/gitlab_logger_spec.rb
index 31c6cff..934b6fa 100644
--- a/spec/gitlab_logger_spec.rb
+++ b/spec/gitlab_logger_spec.rb
@@ -6,7 +6,7 @@ describe :convert_log_level do
subject { convert_log_level :extreme }
it "converts invalid log level to Logger::INFO" do
- expect($stderr).to receive(:puts).at_least(:once)
+ $stderr.should_receive(:puts).at_least(:once)
should eq(Logger::INFO)
end
end
diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb
index 8df6fd3..be2f4ba 100644
--- a/spec/gitlab_net_spec.rb
+++ b/spec/gitlab_net_spec.rb
@@ -1,5 +1,6 @@
require_relative 'spec_helper'
require_relative '../lib/gitlab_net'
+require_relative '../lib/gitlab_access_status'
describe GitlabNet, vcr: true do
let(:gitlab_net) { described_class.new }
@@ -7,66 +8,57 @@ describe GitlabNet, vcr: true do
let(:base_api_endpoint) { 'http://localhost:3000/api/v4' }
let(:internal_api_endpoint) { 'http://localhost:3000/api/v4/internal' }
let(:project) { 'gitlab-org/gitlab-test.git' }
-
- let(:actor1) { Actor.new_from('key-1') }
- let(:bad_actor1) { Actor.new_from('key-777') }
- let(:actor2) { Actor.new_from('user-1') }
-
+ let(:key) { 'key-1' }
+ let(:key2) { 'key-2' }
let(:secret) { "0a3938d9d95d807e94d937af3a4fbbea\n" }
before do
$logger = double('logger').as_null_object
- allow(gitlab_net).to receive(:base_api_endpoint).and_return(base_api_endpoint)
- allow(gitlab_net).to receive(:secret_token).and_return(secret)
+ gitlab_net.stub(:base_api_endpoint).and_return(base_api_endpoint)
+ gitlab_net.stub(:secret_token).and_return(secret)
end
describe '#check' do
it 'should return 200 code for gitlab check' do
VCR.use_cassette("check-ok") do
result = gitlab_net.check
- expect(result.code).to eql('200')
+ result.code.should == '200'
end
end
it 'adds the secret_token to request' do
VCR.use_cassette("check-ok") do
- allow_any_instance_of(Net::HTTP::Get).to receive(:set_form_data).with(hash_including(secret_token: secret))
+ Net::HTTP::Get.any_instance.should_receive(:set_form_data).with(hash_including(secret_token: secret))
gitlab_net.check
end
end
it "raises an exception if the connection fails" do
- allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(StandardError)
- expect do gitlab_net.check end.to raise_error(GitlabNet::ApiUnreachableError)
+ Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
+ expect { gitlab_net.check }.to raise_error(GitlabNet::ApiUnreachableError)
end
end
describe '#discover' do
- it 'returns user has based on key id' do
+ it 'should return user has based on key id' do
VCR.use_cassette("discover-ok") do
- user = gitlab_net.discover(actor1)
- expect(user['name']).to eql 'Administrator'
- expect(user['username']).to eql 'root'
- end
- end
-
- it 'returns nil if the user cannot be found' do
- VCR.use_cassette("discover-not-found") do
- expect(gitlab_net.discover(actor1)).to be_nil
+ user = gitlab_net.discover(key)
+ user['name'].should == 'Administrator'
+ user['username'].should == 'root'
end
end
it 'adds the secret_token to request' do
VCR.use_cassette("discover-ok") do
- allow_any_instance_of(Net::HTTP::Get).to receive(:set_form_data).with(hash_including(secret_token: secret))
- gitlab_net.discover(actor1)
+ Net::HTTP::Get.any_instance.should_receive(:set_form_data).with(hash_including(secret_token: secret))
+ gitlab_net.discover(key)
end
end
it "raises an exception if the connection fails" do
VCR.use_cassette("discover-ok") do
- allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(StandardError)
- expect(gitlab_net.discover(actor1)).to be_nil
+ Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
+ expect { gitlab_net.discover(key) }.to raise_error(GitlabNet::ApiUnreachableError)
end
end
end
@@ -75,10 +67,10 @@ describe GitlabNet, vcr: true do
context 'lfs authentication succeeded' do
it 'should return the correct data' do
VCR.use_cassette('lfs-authenticate-ok') do
- lfs_access = gitlab_net.lfs_authenticate(actor1, project)
- expect(lfs_access.username).to eql 'root'
- expect(lfs_access.lfs_token).to eql 'Hyzhyde_wLUeyUQsR3tHGTG8eNocVQm4ssioTEsBSdb6KwCSzQ'
- expect(lfs_access.repository_http_path).to eql URI.join(internal_api_endpoint.sub('api/v4', ''), project).to_s
+ lfs_access = gitlab_net.lfs_authenticate(key, project)
+ lfs_access.username.should == 'root'
+ lfs_access.lfs_token.should == 'Hyzhyde_wLUeyUQsR3tHGTG8eNocVQm4ssioTEsBSdb6KwCSzQ'
+ lfs_access.repository_http_path.should == URI.join(internal_api_endpoint.sub('api/v4', ''), project).to_s
end
end
end
@@ -89,7 +81,7 @@ describe GitlabNet, vcr: true do
it 'should return message' do
VCR.use_cassette("broadcast_message-ok") do
result = gitlab_net.broadcast_message
- expect(result["message"]).to eql "Message"
+ result["message"].should == "Message"
end
end
end
@@ -98,7 +90,7 @@ describe GitlabNet, vcr: true do
it 'should return nil' do
VCR.use_cassette("broadcast_message-none") do
result = gitlab_net.broadcast_message
- expect(result).to eql({})
+ result.should == {}
end
end
end
@@ -110,13 +102,13 @@ describe GitlabNet, vcr: true do
let(:encoded_changes) { "123456%20789012%20refs/heads/test%0A654321%20210987%20refs/tags/tag" }
it "sends the given arguments as encoded URL parameters" do
- expect(gitlab_net).to receive(:get).with("#{internal_api_endpoint}/merge_request_urls?project=#{project}&changes=#{encoded_changes}&gl_repository=#{gl_repository}")
+ gitlab_net.should_receive(:get).with("#{internal_api_endpoint}/merge_request_urls?project=#{project}&changes=#{encoded_changes}&gl_repository=#{gl_repository}")
gitlab_net.merge_request_urls(gl_repository, project, changes)
end
it "omits the gl_repository parameter if it's nil" do
- expect(gitlab_net).to receive(:get).with("#{internal_api_endpoint}/merge_request_urls?project=#{project}&changes=#{encoded_changes}")
+ gitlab_net.should_receive(:get).with("#{internal_api_endpoint}/merge_request_urls?project=#{project}&changes=#{encoded_changes}")
gitlab_net.merge_request_urls(nil, project, changes)
end
@@ -143,7 +135,8 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.pre_receive(gl_repository) }
it 'sends the correct parameters and returns the request body parsed' do
- allow_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(hash_including(params))
+ Net::HTTP::Post.any_instance.should_receive(:set_form_data)
+ .with(hash_including(params))
VCR.use_cassette("pre-receive") { subject }
end
@@ -154,9 +147,9 @@ describe GitlabNet, vcr: true do
end
end
- it 'throws a NotFoundError when pre-receive is not available' do
+ it 'throws a NotFound error when pre-receive is not available' do
VCR.use_cassette("pre-receive-not-found") do
- expect do subject end.to raise_error(GitlabNet::NotFoundError)
+ expect { subject }.to raise_error(GitlabNet::NotFound)
end
end
end
@@ -165,7 +158,7 @@ describe GitlabNet, vcr: true do
let(:gl_repository) { "project-1" }
let(:changes) { "123456 789012 refs/heads/test\n654321 210987 refs/tags/tag" }
let(:params) do
- { gl_repository: gl_repository, identifier: actor1.identifier, changes: changes }
+ { gl_repository: gl_repository, identifier: key, changes: changes }
end
let(:merge_request_urls) do
[{
@@ -175,10 +168,11 @@ describe GitlabNet, vcr: true do
}]
end
- subject { gitlab_net.post_receive(gl_repository, actor1, changes) }
+ subject { gitlab_net.post_receive(gl_repository, key, changes) }
it 'sends the correct parameters' do
- allow_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(hash_including(params))
+ Net::HTTP::Post.any_instance.should_receive(:set_form_data).with(hash_including(params))
+
VCR.use_cassette("post-receive") do
subject
@@ -193,9 +187,9 @@ describe GitlabNet, vcr: true do
end
end
- it 'throws a NotFoundError when post-receive is not available' do
+ it 'throws a NotFound error when post-receive is not available' do
VCR.use_cassette("post-receive-not-found") do
- expect do subject end.to raise_error(GitlabNet::NotFoundError)
+ expect { subject }.to raise_error(GitlabNet::NotFound)
end
end
end
@@ -206,21 +200,21 @@ describe GitlabNet, vcr: true do
it "should return nil when the resource is not implemented" do
VCR.use_cassette("ssh-key-not-implemented") do
result = gitlab_net.authorized_key("whatever")
- expect(result).to be_nil
+ result.should be_nil
end
end
it "should return nil when the fingerprint is not found" do
VCR.use_cassette("ssh-key-not-found") do
result = gitlab_net.authorized_key("whatever")
- expect(result).to be_nil
+ result.should be_nil
end
end
it "should return a ssh key with a valid fingerprint" do
VCR.use_cassette("ssh-key-ok") do
result = gitlab_net.authorized_key(ssh_key)
- expect(result).to eql({
+ result.should eq({
"can_push" => false,
"created_at" => "2017-06-21T09:50:07.150Z",
"id" => 99,
@@ -234,7 +228,7 @@ describe GitlabNet, vcr: true do
describe '#two_factor_recovery_codes' do
it 'returns two factor recovery codes' do
VCR.use_cassette('two-factor-recovery-codes') do
- result = gitlab_net.two_factor_recovery_codes(actor1)
+ result = gitlab_net.two_factor_recovery_codes(key)
expect(result['success']).to be_truthy
expect(result['recovery_codes']).to eq(['f67c514de60c4953','41278385fc00c1e0'])
end
@@ -242,7 +236,7 @@ describe GitlabNet, vcr: true do
it 'returns false when recovery codes cannot be generated' do
VCR.use_cassette('two-factor-recovery-codes-fail') do
- result = gitlab_net.two_factor_recovery_codes(bad_actor1)
+ result = gitlab_net.two_factor_recovery_codes('key-777')
expect(result['success']).to be_falsey
expect(result['message']).to eq('Could not find the given key')
end
@@ -258,7 +252,7 @@ describe GitlabNet, vcr: true do
it 'sets the arguments as form parameters' do
VCR.use_cassette('notify-post-receive') do
- allow_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(hash_including(params))
+ Net::HTTP::Post.any_instance.should_receive(:set_form_data).with(hash_including(params))
gitlab_net.notify_post_receive(gl_repository, repo_path)
end
end
@@ -271,159 +265,92 @@ describe GitlabNet, vcr: true do
end
describe '#check_access' do
- context 'something is wrong with the API response' do
- context 'but response is JSON parsable' do
- it 'raises an UnknownError exception' do
- VCR.use_cassette('failed-push') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
- end.to raise_error(UnknownError, 'API is not accessible: An internal server error occurred')
- end
- end
- end
-
- context 'but response is not JSON parsable' do
- it 'raises an UnknownError exception' do
- VCR.use_cassette('failed-push-unparsable') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
- end.to raise_error(UnknownError, 'API is not accessible')
- end
- end
- end
- end
-
context 'ssh key with access nil, to project' do
- it 'should allow push access for host' do
- VCR.use_cassette('allowed-push') do
- action = gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
- expect(action).to be_instance_of(Action::Gitaly)
+ it 'should allow pull access for host' do
+ VCR.use_cassette("allowed-pull") do
+ access = gitlab_net.check_access('git-receive-pack', nil, project, key, changes, 'ssh')
+ access.allowed?.should be_truthy
end
end
it 'adds the secret_token to the request' do
- VCR.use_cassette('allowed-pull') do
- allow_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(hash_including(secret_token: secret))
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
+ VCR.use_cassette("allowed-pull") do
+ Net::HTTP::Post.any_instance.should_receive(:set_form_data).with(hash_including(secret_token: secret))
+ gitlab_net.check_access('git-receive-pack', nil, project, key, changes, 'ssh')
end
end
- it 'should allow pull access for host' do
- VCR.use_cassette("allowed-pull") do
- action = gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'ssh')
- expect(action).to be_instance_of(Action::Gitaly)
+ it 'should allow push access for host' do
+ VCR.use_cassette("allowed-push") do
+ access = gitlab_net.check_access('git-upload-pack', nil, project, key, changes, 'ssh')
+ access.allowed?.should be_truthy
end
end
end
context 'ssh access has been disabled' do
it 'should deny pull access for host' do
- VCR.use_cassette('ssh-pull-disabled-old') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
- end
-
VCR.use_cassette('ssh-pull-disabled') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
+ access = gitlab_net.check_access('git-upload-pack', nil, project, key, changes, 'ssh')
+ access.allowed?.should be_falsey
+ access.message.should eq 'Git access over SSH is not allowed'
end
end
it 'should deny push access for host' do
- VCR.use_cassette('ssh-push-disabled-old') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
- end
-
VCR.use_cassette('ssh-push-disabled') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
+ access = gitlab_net.check_access('git-receive-pack', nil, project, key, changes, 'ssh')
+ access.allowed?.should be_falsey
+ access.message.should eq 'Git access over SSH is not allowed'
end
end
end
context 'http access has been disabled' do
it 'should deny pull access for host' do
- VCR.use_cassette('http-pull-disabled-old') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Pulling over HTTP is not allowed.')
- end
-
VCR.use_cassette('http-pull-disabled') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Pulling over HTTP is not allowed.')
+ access = gitlab_net.check_access('git-upload-pack', nil, project, key, changes, 'http')
+ access.allowed?.should be_falsey
+ access.message.should eq 'Pulling over HTTP is not allowed.'
end
end
it 'should deny push access for host' do
- VCR.use_cassette('http-push-disabled-old') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Pushing over HTTP is not allowed.')
- end
-
- VCR.use_cassette('http-push-disabled') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor1, changes, 'http')
- end.to raise_error(AccessDeniedError, 'Pushing over HTTP is not allowed.')
+ VCR.use_cassette("http-push-disabled") do
+ access = gitlab_net.check_access('git-receive-pack', nil, project, key, changes, 'http')
+ access.allowed?.should be_falsey
+ access.message.should eq 'Pushing over HTTP is not allowed.'
end
end
end
context 'ssh key without access to project' do
it 'should deny pull access for host' do
- VCR.use_cassette('ssh-pull-project-denied-old') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
- end
-
- VCR.use_cassette('ssh-pull-project-denied') do
- expect do
- gitlab_net.check_access('git-receive-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
+ VCR.use_cassette("ssh-pull-project-denied") do
+ access = gitlab_net.check_access('git-receive-pack', nil, project, key2, changes, 'ssh')
+ access.allowed?.should be_falsey
end
end
it 'should deny push access for host' do
- VCR.use_cassette('ssh-push-project-denied-old') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
- end
-
- VCR.use_cassette('ssh-push-project-denied') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
+ VCR.use_cassette("ssh-push-project-denied") do
+ access = gitlab_net.check_access('git-upload-pack', nil, project, key2, changes, 'ssh')
+ access.allowed?.should be_falsey
end
end
it 'should deny push access for host (with user)' do
- VCR.use_cassette('ssh-push-project-denied-with-user-old') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
- end
-
- VCR.use_cassette('ssh-push-project-denied-with-user') do
- expect do
- gitlab_net.check_access('git-upload-pack', nil, project, actor2, changes, 'ssh')
- end.to raise_error(AccessDeniedError, 'Git access over SSH is not allowed')
+ VCR.use_cassette("ssh-push-project-denied-with-user") do
+ access = gitlab_net.check_access('git-upload-pack', nil, project, 'user-2', changes, 'ssh')
+ access.allowed?.should be_falsey
end
end
end
it "raises an exception if the connection fails" do
- allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(StandardError)
+ Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
expect {
- gitlab_net.check_access('git-upload-pack', nil, project, actor1, changes, 'ssh')
+ gitlab_net.check_access('git-upload-pack', nil, project, 'user-1', changes, 'ssh')
}.to raise_error(GitlabNet::ApiUnreachableError)
end
end
@@ -450,8 +377,8 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.send :http_client_for, URI('https://localhost/') }
before do
- allow(gitlab_net).to receive(:cert_store)
- allow(gitlab_net.send(:config)).to receive(:http_settings).and_return({ 'self_signed_cert' => true })
+ gitlab_net.stub :cert_store
+ gitlab_net.send(:config).stub(:http_settings) { {'self_signed_cert' => true} }
end
its(:verify_mode) { should eq(OpenSSL::SSL::VERIFY_NONE) }
@@ -471,11 +398,11 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.send :http_request_for, :get, url }
before do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('user').and_return(user)
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('password').and_return(password)
- expect(Net::HTTP::Get).to receive(:new).with('/', {}).and_return(get)
- expect(get).to receive(:basic_auth).with(user, password).once
- expect(get).to receive(:set_form_data).with(hash_including(secret_token: secret)).once
+ gitlab_net.send(:config).http_settings.stub(:[]).with('user') { user }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('password') { password }
+ Net::HTTP::Get.should_receive(:new).with('/', {}).and_return(get)
+ get.should_receive(:basic_auth).with(user, password).once
+ get.should_receive(:set_form_data).with(hash_including(secret_token: secret)).once
end
it { should_not be_nil }
@@ -485,11 +412,11 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.send :http_request_for, :get, url, params: params, headers: headers }
before do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('user').and_return(user)
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('password').and_return(password)
- expect(Net::HTTP::Get).to receive(:new).with('/', headers).and_return(get)
- expect(get).to receive(:basic_auth).with(user, password).once
- expect(get).to receive(:set_form_data).with({ 'key1' => 'value1', secret_token: secret }).once
+ gitlab_net.send(:config).http_settings.stub(:[]).with('user') { user }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('password') { password }
+ Net::HTTP::Get.should_receive(:new).with('/', headers).and_return(get)
+ get.should_receive(:basic_auth).with(user, password).once
+ get.should_receive(:set_form_data).with({ 'key1' => 'value1', secret_token: secret }).once
end
it { should_not be_nil }
@@ -499,11 +426,11 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.send :http_request_for, :get, url, headers: headers }
before do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('user').and_return(user)
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('password').and_return(password)
- expect(Net::HTTP::Get).to receive(:new).with('/', headers).and_return(get)
- expect(get).to receive(:basic_auth).with(user, password).once
- expect(get).to receive(:set_form_data).with(hash_including(secret_token: secret)).once
+ gitlab_net.send(:config).http_settings.stub(:[]).with('user') { user }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('password') { password }
+ Net::HTTP::Get.should_receive(:new).with('/', headers).and_return(get)
+ get.should_receive(:basic_auth).with(user, password).once
+ get.should_receive(:set_form_data).with(hash_including(secret_token: secret)).once
end
it { should_not be_nil }
@@ -514,12 +441,12 @@ describe GitlabNet, vcr: true do
subject { gitlab_net.send :http_request_for, :get, url, options: options }
before do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('user').and_return(user)
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('password').and_return(password)
- expect(Net::HTTP::Get).to receive(:new).with('/', {}).and_return(get)
- expect(get).to receive(:basic_auth).with(user, password).once
- expect(get).to receive(:body=).with({ 'key2' => 'value2', secret_token: secret }.to_json).once
- expect(get).to_not receive(:set_form_data)
+ gitlab_net.send(:config).http_settings.stub(:[]).with('user') { user }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('password') { password }
+ Net::HTTP::Get.should_receive(:new).with('/', {}).and_return(get)
+ get.should_receive(:basic_auth).with(user, password).once
+ get.should_receive(:body=).with({ 'key2' => 'value2', secret_token: secret }.to_json).once
+ get.should_not_receive(:set_form_data)
end
it { should_not be_nil }
@@ -530,7 +457,7 @@ describe GitlabNet, vcr: true do
context 'Unix socket' do
it 'sets the Host header to "localhost"' do
gitlab_net = described_class.new
- expect(gitlab_net).to receive(:secret_token).and_return(secret)
+ gitlab_net.should_receive(:secret_token).and_return(secret)
request = gitlab_net.send(:http_request_for, :get, URI('http+unix://%2Ffoo'))
@@ -542,12 +469,12 @@ describe GitlabNet, vcr: true do
describe '#cert_store' do
let(:store) do
double(OpenSSL::X509::Store).tap do |store|
- allow(OpenSSL::X509::Store).to receive(:new).and_return(store)
+ OpenSSL::X509::Store.stub(:new) { store }
end
end
before :each do
- expect(store).to receive(:set_default_paths).once
+ store.should_receive(:set_default_paths).once
end
after do
@@ -555,17 +482,17 @@ describe GitlabNet, vcr: true do
end
it "calls add_file with http_settings['ca_file']" do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('ca_file').and_return('test_file')
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('ca_path').and_return(nil)
- expect(store).to receive(:add_file).with('test_file')
- expect(store).to_not receive(:add_path)
+ gitlab_net.send(:config).http_settings.stub(:[]).with('ca_file') { 'test_file' }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('ca_path') { nil }
+ store.should_receive(:add_file).with('test_file')
+ store.should_not_receive(:add_path)
end
it "calls add_path with http_settings['ca_path']" do
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('ca_file').and_return(nil)
- allow(gitlab_net.send(:config).http_settings).to receive(:[]).with('ca_path').and_return('test_path')
- expect(store).to_not receive(:add_file)
- expect(store).to receive(:add_path).with('test_path')
+ gitlab_net.send(:config).http_settings.stub(:[]).with('ca_file') { nil }
+ gitlab_net.send(:config).http_settings.stub(:[]).with('ca_path') { 'test_path' }
+ store.should_not_receive(:add_file)
+ store.should_receive(:add_path).with('test_path')
end
end
end
diff --git a/spec/gitlab_post_receive_spec.rb b/spec/gitlab_post_receive_spec.rb
index c41cceb..46e6158 100644
--- a/spec/gitlab_post_receive_spec.rb
+++ b/spec/gitlab_post_receive_spec.rb
@@ -5,13 +5,13 @@ require 'gitlab_post_receive'
describe GitlabPostReceive do
let(:repository_path) { "/home/git/repositories" }
let(:repo_name) { 'dzaporozhets/gitlab-ci' }
- let(:gl_id) { 'key-123' }
+ let(:actor) { 'key-123' }
let(:changes) { "123456 789012 refs/heads/tést\n654321 210987 refs/tags/tag" }
let(:wrongly_encoded_changes) { changes.encode("ISO-8859-1").force_encoding("UTF-8") }
let(:base64_changes) { Base64.encode64(wrongly_encoded_changes) }
let(:repo_path) { File.join(repository_path, repo_name) + ".git" }
let(:gl_repository) { "project-1" }
- let(:gitlab_post_receive) { GitlabPostReceive.new(gl_repository, repo_path, gl_id, wrongly_encoded_changes) }
+ let(:gitlab_post_receive) { GitlabPostReceive.new(gl_repository, repo_path, actor, wrongly_encoded_changes) }
let(:broadcast_message) { "test " * 10 + "message " * 10 }
let(:enqueued_at) { Time.new(2016, 6, 23, 6, 59) }
let(:new_merge_request_urls) do
@@ -31,7 +31,7 @@ describe GitlabPostReceive do
before do
$logger = double('logger').as_null_object # Global vars are bad
- allow_any_instance_of(GitlabConfig).to receive(:repos_path).and_return(repository_path)
+ GitlabConfig.any_instance.stub(repos_path: repository_path)
end
describe "#exec" do
@@ -63,7 +63,7 @@ describe GitlabPostReceive do
context 'when contains long url string at end' do
let(:broadcast_message) { "test " * 10 + "message " * 10 + "https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url" }
- it 'doesnt truncate url' do
+ it 'doesnt truncate url' do
expect_any_instance_of(GitlabNet).to receive(:post_receive).and_return(response)
assert_broadcast_message_printed_keep_long_url_end(gitlab_post_receive)
assert_new_mr_printed(gitlab_post_receive)
@@ -75,7 +75,7 @@ describe GitlabPostReceive do
context 'when contains long url string at start' do
let(:broadcast_message) { "https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url " + "test " * 10 + "message " * 11}
- it 'doesnt truncate url' do
+ it 'doesnt truncate url' do
expect_any_instance_of(GitlabNet).to receive(:post_receive).and_return(response)
assert_broadcast_message_printed_keep_long_url_start(gitlab_post_receive)
assert_new_mr_printed(gitlab_post_receive)
@@ -87,7 +87,7 @@ describe GitlabPostReceive do
context 'when contains long url string in middle' do
let(:broadcast_message) { "test " * 11 + "https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url " + "message " * 11}
- it 'doesnt truncate url' do
+ it 'doesnt truncate url' do
expect_any_instance_of(GitlabNet).to receive(:post_receive).and_return(response)
assert_broadcast_message_printed_keep_long_url_middle(gitlab_post_receive)
assert_new_mr_printed(gitlab_post_receive)
@@ -198,7 +198,7 @@ describe GitlabPostReceive do
expect(gitlab_post_receive).to receive(:puts).with(
" message message message message message message message message"
).ordered
-
+
expect(gitlab_post_receive).to receive(:puts).with(
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
).ordered
@@ -215,7 +215,7 @@ describe GitlabPostReceive do
"========================================================================"
).ordered
expect(gitlab_post_receive).to receive(:puts).ordered
-
+
expect(gitlab_post_receive).to receive(:puts).with(
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
).ordered
@@ -244,7 +244,7 @@ describe GitlabPostReceive do
"========================================================================"
).ordered
expect(gitlab_post_receive).to receive(:puts).ordered
-
+
expect(gitlab_post_receive).to receive(:puts).with(
" test test test test test test test test test test test"
).ordered
diff --git a/spec/gitlab_shell_spec.rb b/spec/gitlab_shell_spec.rb
index 5b8c8a5..a68cd9e 100644
--- a/spec/gitlab_shell_spec.rb
+++ b/spec/gitlab_shell_spec.rb
@@ -1,6 +1,6 @@
require_relative 'spec_helper'
require_relative '../lib/gitlab_shell'
-require_relative '../lib/action'
+require_relative '../lib/gitlab_access_status'
describe GitlabShell do
before do
@@ -8,210 +8,572 @@ describe GitlabShell do
FileUtils.mkdir_p(tmp_repos_path)
end
- after { FileUtils.rm_rf(tmp_repos_path) }
+ after do
+ FileUtils.rm_rf(tmp_repos_path)
+ end
+
+ subject do
+ ARGV[0] = gl_id
+ GitlabShell.new(gl_id).tap do |shell|
+ shell.stub(exec_cmd: :exec_called)
+ shell.stub(api: api)
+ end
+ end
- subject { described_class.new(who) }
+ let(:git_config_options) { ['receive.MaxInputSize=10000'] }
- let(:who) { 'key-1' }
- let(:audit_usernames) { true }
- let(:actor) { Actor.new_from(who, audit_usernames: audit_usernames) }
+ let(:gitaly_check_access) { GitAccessStatus.new(
+ true,
+ 'ok',
+ gl_repository: gl_repository,
+ gl_id: gl_id,
+ gl_username: gl_username,
+ git_config_options: git_config_options,
+ repository_path: repo_path,
+ gitaly: { 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default'} , 'address' => 'unix:gitaly.socket' },
+ git_protocol: git_protocol
+ )
+ }
+
+ let(:api) do
+ double(GitlabNet).tap do |api|
+ api.stub(discover: { 'name' => 'John Doe', 'username' => 'testuser' })
+ api.stub(check_access: GitAccessStatus.new(
+ true,
+ 'ok',
+ gl_repository: gl_repository,
+ gl_id: gl_id,
+ gl_username: gl_username,
+ git_config_options: nil,
+ repository_path: repo_path,
+ gitaly: nil,
+ git_protocol: git_protocol))
+ api.stub(two_factor_recovery_codes: {
+ 'success' => true,
+ 'recovery_codes' => %w[f67c514de60c4953 41278385fc00c1e0]
+ })
+ end
+ end
+
+ let(:gl_id) { "key-#{rand(100) + 100}" }
+ let(:ssh_cmd) { nil }
let(:tmp_repos_path) { File.join(ROOT_PATH, 'tmp', 'repositories') }
+
let(:repo_name) { 'gitlab-ci.git' }
let(:repo_path) { File.join(tmp_repos_path, repo_name) }
let(:gl_repository) { 'project-1' }
+ let(:gl_id) { 'user-1' }
let(:gl_username) { 'testuser' }
let(:git_config_options) { ['receive.MaxInputSize=10000'] }
let(:git_protocol) { 'version=2' }
- let(:api) { double(GitlabNet) }
- let(:config) { double(GitlabConfig) }
-
- let(:gitaly_action) { Action::Gitaly.new(
- actor,
- gl_repository,
- gl_username,
- git_config_options,
- git_protocol,
- repo_path,
- { 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default' } , 'address' => 'unix:gitaly.socket' })
- }
- let(:api_2fa_recovery_action) { Action::API2FARecovery.new(actor) }
- let(:git_lfs_authenticate_action) { Action::GitLFSAuthenticate.new(actor, repo_name) }
-
before do
- allow(GitlabConfig).to receive(:new).and_return(config)
- allow(config).to receive(:audit_usernames).and_return(audit_usernames)
+ GitlabConfig.any_instance.stub(audit_usernames: false)
+ end
- allow(Actor).to receive(:new_from).with(who, audit_usernames: audit_usernames).and_return(actor)
+ describe :initialize do
+ let(:ssh_cmd) { 'git-receive-pack' }
- allow(GitlabNet).to receive(:new).and_return(api)
- allow(api).to receive(:discover).with(actor).and_return('username' => gl_username)
+ its(:gl_id) { should == gl_id }
end
- describe '#exec' do
- context "when we don't have a valid user" do
- before do
- allow(api).to receive(:discover).with(actor).and_return(nil)
+ describe :parse_cmd do
+ describe 'git' do
+ context 'w/o namespace' do
+ let(:ssh_args) { %w(git-upload-pack gitlab-ci.git) }
+
+ before do
+ subject.send :parse_cmd, ssh_args
+ end
+
+ its(:repo_name) { should == 'gitlab-ci.git' }
+ its(:command) { should == 'git-upload-pack' }
end
- it 'prints Welcome.. and returns true' do
- expect {
- expect(subject.exec(nil)).to be_truthy
- }.to output("Welcome to GitLab, Anonymous!\n").to_stdout
+ context 'namespace' do
+ let(:repo_name) { 'dmitriy.zaporozhets/gitlab-ci.git' }
+ let(:ssh_args) { %w(git-upload-pack dmitriy.zaporozhets/gitlab-ci.git) }
+
+ before do
+ subject.send :parse_cmd, ssh_args
+ end
+
+ its(:repo_name) { should == 'dmitriy.zaporozhets/gitlab-ci.git' }
+ its(:command) { should == 'git-upload-pack' }
end
- end
- context 'when we have a valid user' do
- context 'when origin_cmd is nil' do
- it 'prints Welcome.. and returns true' do
- expect {
- expect(subject.exec(nil)).to be_truthy
- }.to output("Welcome to GitLab, @testuser!\n").to_stdout
+ context 'with an invalid number of arguments' do
+ let(:ssh_args) { %w(foobar) }
+
+ it "should raise an DisallowedCommandError" do
+ expect { subject.send :parse_cmd, ssh_args }.to raise_error(GitlabShell::DisallowedCommandError)
end
end
- context 'when origin_cmd is empty' do
- it 'prints Welcome.. and returns true' do
- expect {
- expect(subject.exec('')).to be_truthy
- }.to output("Welcome to GitLab, @testuser!\n").to_stdout
+ context 'with an API command' do
+ before do
+ subject.send :parse_cmd, ssh_args
+ end
+
+ context 'when generating recovery codes' do
+ let(:ssh_args) { %w(2fa_recovery_codes) }
+
+ it 'sets the correct command' do
+ expect(subject.command).to eq('2fa_recovery_codes')
+ end
+
+ it 'does not set repo name' do
+ expect(subject.repo_name).to be_nil
+ end
end
end
end
- context 'when origin_cmd is invalid' do
- it 'prints a message to stderr and returns false' do
- expect {
- expect(subject.exec("git-invalid-command #{repo_name}")).to be_falsey
- }.to output("GitLab: Disallowed command\n").to_stderr
+ describe 'git-lfs' do
+ let(:repo_name) { 'dzaporozhets/gitlab.git' }
+ let(:ssh_args) { %w(git-lfs-authenticate dzaporozhets/gitlab.git download) }
+
+ before do
+ subject.send :parse_cmd, ssh_args
end
+
+ its(:repo_name) { should == 'dzaporozhets/gitlab.git' }
+ its(:command) { should == 'git-lfs-authenticate' }
+ its(:git_access) { should == 'git-upload-pack' }
end
- context 'when origin_cmd is valid, but incomplete' do
- it 'prints a message to stderr and returns false' do
- expect {
- expect(subject.exec('git-upload-pack')).to be_falsey
- }.to output("GitLab: Disallowed command\n").to_stderr
+ describe 'git-lfs old clients' do
+ let(:repo_name) { 'dzaporozhets/gitlab.git' }
+ let(:ssh_args) { %w(git-lfs-authenticate dzaporozhets/gitlab.git download long_oid) }
+
+ before do
+ subject.send :parse_cmd, ssh_args
end
+
+ its(:repo_name) { should == 'dzaporozhets/gitlab.git' }
+ its(:command) { should == 'git-lfs-authenticate' }
+ its(:git_access) { should == 'git-upload-pack' }
+ end
+ end
+
+ describe :exec do
+ let(:gitaly_message) do
+ JSON.dump(
+ 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default' },
+ 'gl_repository' => gl_repository,
+ 'gl_id' => gl_id,
+ 'gl_username' => gl_username,
+ 'git_config_options' => git_config_options,
+ 'git_protocol' => git_protocol
+ )
end
- context 'when origin_cmd is git-lfs-authenticate' do
- context 'but incomplete' do
- it 'prints a message to stderr and returns false' do
- expect {
- expect(subject.exec('git-lfs-authenticate')).to be_falsey
- }.to output("GitLab: Disallowed command\n").to_stderr
- end
+ before do
+ allow(ENV).to receive(:[]).with('GIT_PROTOCOL').and_return(git_protocol)
+ end
+
+ shared_examples_for 'upload-pack' do |command|
+ let(:ssh_cmd) { "#{command} gitlab-ci.git" }
+ after { subject.exec(ssh_cmd) }
+
+ it "should process the command" do
+ subject.should_receive(:process_cmd).with(%w(git-upload-pack gitlab-ci.git))
end
- context 'but invalid' do
- it 'prints a message to stderr and returns false' do
- expect {
- expect(subject.exec("git-lfs-authenticate #{repo_name} invalid")).to be_falsey
- }.to output("GitLab: Disallowed command\n").to_stderr
- end
+ it "should execute the command" do
+ subject.should_receive(:exec_cmd).with('git-upload-pack', repo_path)
+ end
+
+ it "should log the command execution" do
+ message = "executing git command"
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:info).with(message, command: "git-upload-pack #{repo_path}", user: user_string)
+ end
+
+ it "should use usernames if configured to do so" do
+ GitlabConfig.any_instance.stub(audit_usernames: true)
+ $logger.should_receive(:info).with("executing git command", hash_including(user: 'testuser'))
end
end
- context 'when origin_cmd is 2fa_recovery_codes' do
- let(:origin_cmd) { '2fa_recovery_codes' }
- let(:git_access) { '2fa_recovery_codes' }
+ context 'git-upload-pack' do
+ it_behaves_like 'upload-pack', 'git-upload-pack'
+ end
+
+ context 'git upload-pack' do
+ it_behaves_like 'upload-pack', 'git upload-pack'
+ end
+ context 'gitaly-upload-pack' do
+ let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" }
before do
- expect(Action::API2FARecovery).to receive(:new).with(actor).and_return(api_2fa_recovery_action)
+ api.stub(check_access: gitaly_check_access)
+ end
+ after { subject.exec(ssh_cmd) }
+
+ it "should process the command" do
+ subject.should_receive(:process_cmd).with(%w(git-upload-pack gitlab-ci.git))
end
- it 'returns true' do
- expect(api_2fa_recovery_action).to receive(:execute).with('2fa_recovery_codes', %w{ 2fa_recovery_codes }).and_return(true)
- expect(subject.exec(origin_cmd)).to be_truthy
+ it "should execute the command" do
+ subject.should_receive(:exec_cmd).with(File.join(ROOT_PATH, "bin/gitaly-upload-pack"), 'unix:gitaly.socket', gitaly_message)
+ end
+
+ it "should log the command execution" do
+ message = "executing git command"
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:info).with(message, command: "gitaly-upload-pack unix:gitaly.socket #{gitaly_message}", user: user_string)
+ end
+
+ it "should use usernames if configured to do so" do
+ GitlabConfig.any_instance.stub(audit_usernames: true)
+ $logger.should_receive(:info).with("executing git command", hash_including(user: 'testuser'))
end
end
- context 'when access to the repo is denied' do
+ context 'git-receive-pack' do
+ let(:ssh_cmd) { "git-receive-pack gitlab-ci.git" }
+ after { subject.exec(ssh_cmd) }
+
+ it "should process the command" do
+ subject.should_receive(:process_cmd).with(%w(git-receive-pack gitlab-ci.git))
+ end
+
+ it "should execute the command" do
+ subject.should_receive(:exec_cmd).with('git-receive-pack', repo_path)
+ end
+
+ it "should log the command execution" do
+ message = "executing git command"
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:info).with(message, command: "git-receive-pack #{repo_path}", user: user_string)
+ end
+ end
+
+ context 'gitaly-receive-pack' do
+ let(:ssh_cmd) { "git-receive-pack gitlab-ci.git" }
before do
- expect(api).to receive(:check_access).with('git-upload-pack', nil, repo_name, actor, '_any').and_raise(AccessDeniedError, 'Sorry, access denied')
+ api.stub(check_access: gitaly_check_access)
+ end
+ after { subject.exec(ssh_cmd) }
+
+ it "should process the command" do
+ subject.should_receive(:process_cmd).with(%w(git-receive-pack gitlab-ci.git))
+ end
+
+ it "should execute the command" do
+ subject.should_receive(:exec_cmd).with(File.join(ROOT_PATH, "bin/gitaly-receive-pack"), 'unix:gitaly.socket', gitaly_message)
+ end
+
+ it "should log the command execution" do
+ message = "executing git command"
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:info).with(message, command: "gitaly-receive-pack unix:gitaly.socket #{gitaly_message}", user: user_string)
+ end
+
+ it "should use usernames if configured to do so" do
+ GitlabConfig.any_instance.stub(audit_usernames: true)
+ $logger.should_receive(:info).with("executing git command", hash_including(user: 'testuser'))
+ end
+ end
+
+ shared_examples_for 'upload-archive' do |command|
+ let(:ssh_cmd) { "#{command} gitlab-ci.git" }
+ let(:exec_cmd_params) { ['git-upload-archive', repo_path] }
+ let(:exec_cmd_log_params) { exec_cmd_params }
+
+ after { subject.exec(ssh_cmd) }
+
+ it "should process the command" do
+ subject.should_receive(:process_cmd).with(%w(git-upload-archive gitlab-ci.git))
end
- it 'prints a message to stderr and returns false' do
- expect($stderr).to receive(:puts).with('GitLab: Sorry, access denied')
- expect(subject.exec("git-upload-pack #{repo_name}")).to be_falsey
+ it "should execute the command" do
+ subject.should_receive(:exec_cmd).with(*exec_cmd_params)
+ end
+
+ it "should log the command execution" do
+ message = "executing git command"
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:info).with(message, command: exec_cmd_log_params.join(' '), user: user_string)
+ end
+
+ it "should use usernames if configured to do so" do
+ GitlabConfig.any_instance.stub(audit_usernames: true)
+ $logger.should_receive(:info).with("executing git command", hash_including(user: 'testuser'))
end
end
- context 'when the API is unavailable' do
+ context 'git-upload-archive' do
+ it_behaves_like 'upload-archive', 'git-upload-archive'
+ end
+
+ context 'git upload-archive' do
+ it_behaves_like 'upload-archive', 'git upload-archive'
+ end
+
+ context 'gitaly-upload-archive' do
before do
- expect(api).to receive(:check_access).with('git-upload-pack', nil, repo_name, actor, '_any').and_raise(GitlabNet::ApiUnreachableError)
+ api.stub(check_access: gitaly_check_access)
end
- it 'prints a message to stderr and returns false' do
- expect($stderr).to receive(:puts).with('GitLab: Failed to authorize your Git request: internal API unreachable')
- expect(subject.exec("git-upload-pack #{repo_name}")).to be_falsey
+ it_behaves_like 'upload-archive', 'git-upload-archive' do
+ let(:gitaly_executable) { "gitaly-upload-archive" }
+ let(:exec_cmd_params) do
+ [
+ File.join(ROOT_PATH, "bin", gitaly_executable),
+ 'unix:gitaly.socket',
+ gitaly_message
+ ]
+ end
+ let(:exec_cmd_log_params) do
+ [gitaly_executable, 'unix:gitaly.socket', gitaly_message]
+ end
end
end
- context 'when access has been verified OK' do
+ context 'arbitrary command' do
+ let(:ssh_cmd) { 'arbitrary command' }
+ after { subject.exec(ssh_cmd) }
+
+ it "should not process the command" do
+ subject.should_not_receive(:process_cmd)
+ end
+
+ it "should not execute the command" do
+ subject.should_not_receive(:exec_cmd)
+ end
+
+ it "should log the attempt" do
+ message = 'Denied disallowed command'
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:warn).with(message, command: 'arbitrary command', user: user_string)
+ end
+ end
+
+ context 'no command' do
+ after { subject.exec(nil) }
+
+ it "should call api.discover" do
+ api.should_receive(:discover).with(gl_id)
+ end
+ end
+
+ context "failed connection" do
+ let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' }
+
before do
- expect(api).to receive(:check_access).with(git_access, nil, repo_name, actor, '_any').and_return(gitaly_action)
+ api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
end
+ after { subject.exec(ssh_cmd) }
- context 'when origin_cmd is git-upload-pack' do
- let(:origin_cmd) { 'git-upload-pack' }
- let(:git_access) { 'git-upload-pack' }
+ it "should not process the command" do
+ subject.should_not_receive(:process_cmd)
+ end
- it 'returns true' do
- expect(gitaly_action).to receive(:execute).with('git-upload-pack', %W{git-upload-pack #{repo_name}}).and_return(true)
- expect(subject.exec("#{origin_cmd} #{repo_name}")).to be_truthy
+ it "should not execute the command" do
+ subject.should_not_receive(:exec_cmd)
+ end
+ end
+
+ context 'with an API command' do
+ before do
+ allow(subject).to receive(:continue?).and_return(true)
+ end
+
+ context 'when generating recovery codes' do
+ let(:ssh_cmd) { '2fa_recovery_codes' }
+ after do
+ subject.exec(ssh_cmd)
end
- context 'but repo path is invalid' do
- it 'prints a message to stderr and returns false' do
- expect(gitaly_action).to receive(:execute).with('git-upload-pack', %W{git-upload-pack #{repo_name}}).and_raise(InvalidRepositoryPathError)
- expect($stderr).to receive(:puts).with('GitLab: Invalid repository path')
- expect(subject.exec("#{origin_cmd} #{repo_name}")).to be_falsey
- end
+ it 'does not call verify_access' do
+ expect(subject).not_to receive(:verify_access)
end
- context "but we're using an old git version for Windows 2.14" do
- it 'returns true' do
- expect(gitaly_action).to receive(:execute).with('git-upload-pack', %W{git-upload-pack #{repo_name}}).and_return(true)
- expect(subject.exec("git upload-pack #{repo_name}")).to be_truthy #NOTE: 'git upload-pack' vs. 'git-upload-pack'
+ it 'calls the corresponding method' do
+ expect(subject).to receive(:api_2fa_recovery_codes)
+ end
+
+ it 'outputs recovery codes' do
+ expect($stdout).to receive(:puts)
+ .with(/f67c514de60c4953\n41278385fc00c1e0/)
+ end
+
+ context 'when the process is unsuccessful' do
+ it 'displays the error to the user' do
+ api.stub(two_factor_recovery_codes: {
+ 'success' => false,
+ 'message' => 'Could not find the given key'
+ })
+
+ expect($stdout).to receive(:puts)
+ .with(/Could not find the given key/)
end
end
end
+ end
+ end
+
+ describe :validate_access do
+ let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" }
+
+ describe 'check access with api' do
+ after { subject.exec(ssh_cmd) }
+
+ it "should call api.check_access" do
+ api.should_receive(:check_access).with('git-upload-pack', nil, 'gitlab-ci.git', gl_id, '_any', 'ssh')
+ end
- context 'when origin_cmd is git-lfs-authenticate' do
- let(:origin_cmd) { 'git-lfs-authenticate' }
- let(:lfs_access) { double(GitlabLfsAuthentication, authentication_payload: fake_payload)}
+ it "should disallow access and log the attempt if check_access returns false status" do
+ api.stub(check_access: GitAccessStatus.new(
+ false,
+ 'denied',
+ gl_repository: nil,
+ gl_id: nil,
+ gl_username: nil,
+ git_config_options: nil,
+ repository_path: nil,
+ gitaly: nil,
+ git_protocol: nil))
+ message = 'Access denied'
+ user_string = "user with id #{gl_id}"
+ $logger.should_receive(:warn).with(message, command: 'git-upload-pack gitlab-ci.git', user: user_string)
+ end
+ end
+ describe 'set the repository path' do
+ context 'with a correct path' do
+ before { subject.exec(ssh_cmd) }
+
+ its(:repo_path) { should == repo_path }
+ end
+
+ context "with a path that doesn't match an absolute path" do
before do
- expect(Action::GitLFSAuthenticate).to receive(:new).with(actor, repo_name).and_return(git_lfs_authenticate_action)
+ File.stub(:absolute_path) { 'y/gitlab-ci.git' }
+ end
+
+ it "refuses to assign the path" do
+ $stderr.should_receive(:puts).with("GitLab: Invalid repository path")
+ expect(subject.exec(ssh_cmd)).to be_falsey
end
+ end
+ end
+ end
- context 'upload' do
- let(:git_access) { 'git-receive-pack' }
+ describe :exec_cmd do
+ let(:shell) { GitlabShell.new(gl_id) }
+ let(:env) do
+ {
+ 'HOME' => ENV['HOME'],
+ 'PATH' => ENV['PATH'],
+ 'LD_LIBRARY_PATH' => ENV['LD_LIBRARY_PATH'],
+ 'LANG' => ENV['LANG'],
+ 'GL_ID' => gl_id,
+ 'GL_PROTOCOL' => 'ssh',
+ 'GL_REPOSITORY' => gl_repository,
+ 'GL_USERNAME' => 'testuser'
+ }
+ end
+ let(:exec_options) { { unsetenv_others: true, chdir: ROOT_PATH } }
+ before do
+ Kernel.stub(:exec)
+ shell.gl_repository = gl_repository
+ shell.git_protocol = git_protocol
+ shell.instance_variable_set(:@username, gl_username)
+ end
- it 'returns true' do
- expect(git_lfs_authenticate_action).to receive(:execute).with('git-lfs-authenticate', %w{ git-lfs-authenticate gitlab-ci.git upload }).and_return(true)
- expect(subject.exec("#{origin_cmd} #{repo_name} upload")).to be_truthy
- end
+ it "uses Kernel::exec method" do
+ Kernel.should_receive(:exec).with(env, 1, 2, exec_options).once
+ shell.send :exec_cmd, 1, 2
+ end
+
+ it "refuses to execute a lone non-array argument" do
+ expect { shell.send :exec_cmd, 1 }.to raise_error(GitlabShell::DisallowedCommandError)
+ end
+
+ it "allows one argument if it is an array" do
+ Kernel.should_receive(:exec).with(env, [1, 2], exec_options).once
+ shell.send :exec_cmd, [1, 2]
+ end
+
+ context "when specifying a git_tracing log file" do
+ let(:git_trace_log_file) { '/tmp/git_trace_performance.log' }
+
+ before do
+ GitlabConfig.any_instance.stub(git_trace_log_file: git_trace_log_file)
+ shell
+ end
+
+ it "uses GIT_TRACE_PERFORMANCE" do
+ expected_hash = hash_including(
+ 'GIT_TRACE' => git_trace_log_file,
+ 'GIT_TRACE_PACKET' => git_trace_log_file,
+ 'GIT_TRACE_PERFORMANCE' => git_trace_log_file
+ )
+ Kernel.should_receive(:exec).with(expected_hash, [1, 2], exec_options).once
+
+ shell.send :exec_cmd, [1, 2]
+ end
+
+ context "when provides a relative path" do
+ let(:git_trace_log_file) { 'git_trace_performance.log' }
+
+ it "does not uses GIT_TRACE*" do
+ # If we try to use it we'll show a warning to the users
+ expected_hash = hash_excluding(
+ 'GIT_TRACE', 'GIT_TRACE_PACKET', 'GIT_TRACE_PERFORMANCE'
+ )
+ Kernel.should_receive(:exec).with(expected_hash, [1, 2], exec_options).once
+
+ shell.send :exec_cmd, [1, 2]
end
- context 'download' do
- let(:git_access) { 'git-upload-pack' }
+ it "writes an entry on the log" do
+ message = 'git trace log path must be absolute, ignoring'
- it 'returns true' do
- expect(git_lfs_authenticate_action).to receive(:execute).with('git-lfs-authenticate', %w{ git-lfs-authenticate gitlab-ci.git download }).and_return(true)
- expect(subject.exec("#{origin_cmd} #{repo_name} download")).to be_truthy
- end
+ expect($logger).to receive(:warn).
+ with(message, git_trace_log_file: git_trace_log_file)
- context 'for old git-lfs clients' do
- it 'returns true' do
- expect(git_lfs_authenticate_action).to receive(:execute).with('git-lfs-authenticate', %w{ git-lfs-authenticate gitlab-ci.git download long_oid }).and_return(true)
- expect(subject.exec("#{origin_cmd} #{repo_name} download long_oid")).to be_truthy
- end
- end
+ Kernel.should_receive(:exec).with(env, [1, 2], exec_options).once
+ shell.send :exec_cmd, [1, 2]
+ end
+ end
+
+ context "when provides a file not writable" do
+ before do
+ expect(File).to receive(:open).with(git_trace_log_file, 'a').and_raise(Errno::EACCES)
+ end
+
+ it "does not uses GIT_TRACE*" do
+ # If we try to use it we'll show a warning to the users
+ expected_hash = hash_excluding(
+ 'GIT_TRACE', 'GIT_TRACE_PACKET', 'GIT_TRACE_PERFORMANCE'
+ )
+ Kernel.should_receive(:exec).with(expected_hash, [1, 2], exec_options).once
+
+ shell.send :exec_cmd, [1, 2]
+ end
+
+ it "writes an entry on the log" do
+ message = 'Failed to open git trace log file'
+ error = 'Permission denied'
+
+ expect($logger).to receive(:warn).
+ with(message, git_trace_log_file: git_trace_log_file, error: error)
+
+ Kernel.should_receive(:exec).with(env, [1, 2], exec_options).once
+ shell.send :exec_cmd, [1, 2]
end
end
end
end
+
+ describe :api do
+ let(:shell) { GitlabShell.new(gl_id) }
+ subject { shell.send :api }
+
+ it { should be_a(GitlabNet) }
+ end
end
diff --git a/spec/names_helper_spec.rb b/spec/names_helper_spec.rb
index 11383da..f2a95e5 100644
--- a/spec/names_helper_spec.rb
+++ b/spec/names_helper_spec.rb
@@ -5,8 +5,8 @@ describe NamesHelper do
include NamesHelper
describe :extract_ref_name do
- it { expect(extract_ref_name('refs/heads/awesome-feature')).to eql 'awesome-feature' }
- it { expect(extract_ref_name('refs/tags/v2.2.1')).to eql 'v2.2.1' }
- it { expect(extract_ref_name('refs/tags/releases/v2.2.1')).to eql 'releases/v2.2.1' }
+ it { extract_ref_name('refs/heads/awesome-feature').should == 'awesome-feature' }
+ it { extract_ref_name('refs/tags/v2.2.1').should == 'v2.2.1' }
+ it { extract_ref_name('refs/tags/releases/v2.2.1').should == 'releases/v2.2.1' }
end
end
diff --git a/spec/vcr_cassettes/allowed-pull.yml b/spec/vcr_cassettes/allowed-pull.yml
index 0b22d7a..1636fd5 100644
--- a/spec/vcr_cassettes/allowed-pull.yml
+++ b/spec/vcr_cassettes/allowed-pull.yml
@@ -5,7 +5,7 @@ http_interactions:
uri: http://localhost:3000/api/v4/internal/allowed
body:
encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
+ string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
headers:
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
diff --git a/spec/vcr_cassettes/allowed-push.yml b/spec/vcr_cassettes/allowed-push.yml
index bea28bb..b073476 100644
--- a/spec/vcr_cassettes/allowed-push.yml
+++ b/spec/vcr_cassettes/allowed-push.yml
@@ -5,7 +5,7 @@ http_interactions:
uri: http://localhost:3000/api/v4/internal/allowed
body:
encoding: US-ASCII
- string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
+ string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
headers:
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
diff --git a/spec/vcr_cassettes/discover-not-found.yml b/spec/vcr_cassettes/discover-not-found.yml
deleted file mode 100644
index db03b02..0000000
--- a/spec/vcr_cassettes/discover-not-found.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: http://localhost:3000/api/v4/internal/discover?key_id=1
- body:
- encoding: US-ASCII
- string: secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 404
- message: Not Found
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '42'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 10:44:49 GMT
- Etag:
- - W/"63b4ab301951bea83c4fc398eba8e307"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - dc11b8d4-1972-417b-8305-2c35c849405c
- X-Runtime:
- - '0.230170'
- body:
- encoding: UTF-8
- string: '{"message":"404 Not found"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 10:44:49 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/failed-push-unparsable.yml b/spec/vcr_cassettes/failed-push-unparsable.yml
deleted file mode 100644
index fbc09ec..0000000
--- a/spec/vcr_cassettes/failed-push-unparsable.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 500
- message: Internal Server Error
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '155'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 10:44:52 GMT
- Etag:
- - W/"45654cae433b5a9c5fbba1d45d382e52"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 67ab4954-19e6-42ce-aae6-55c8ae5a365e
- X-Runtime:
- - '0.230871'
- body:
- encoding: UTF-8
- string: '""'
- http_version:
- recorded_at: Wed, 21 Jun 2017 10:44:52 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/failed-push.yml b/spec/vcr_cassettes/failed-push.yml
deleted file mode 100644
index 334aabd..0000000
--- a/spec/vcr_cassettes/failed-push.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 500
- message: Internal Server Error
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '155'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 10:44:52 GMT
- Etag:
- - W/"45654cae433b5a9c5fbba1d45d382e52"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 67ab4954-19e6-42ce-aae6-55c8ae5a365e
- X-Runtime:
- - '0.230871'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"An internal server error occurred"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 10:44:52 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/http-pull-disabled-old.yml b/spec/vcr_cassettes/http-pull-disabled-old.yml
deleted file mode 100644
index 23ef3e5..0000000
--- a/spec/vcr_cassettes/http-pull-disabled-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=http&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '62'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 10:32:01 GMT
- Etag:
- - W/"71e09fcf8a60a03cd1acc22806386ead"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 70bdecc9-0078-4a4b-aa6b-cac1b2578886
- X-Runtime:
- - '0.324202'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Pulling over HTTP is not allowed."}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 10:32:01 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/http-pull-disabled.yml b/spec/vcr_cassettes/http-pull-disabled.yml
index 34cf634..23ef3e5 100644
--- a/spec/vcr_cassettes/http-pull-disabled.yml
+++ b/spec/vcr_cassettes/http-pull-disabled.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/http-push-disabled-old.yml b/spec/vcr_cassettes/http-push-disabled-old.yml
deleted file mode 100644
index 676e5b8..0000000
--- a/spec/vcr_cassettes/http-push-disabled-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=http&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '62'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 10:32:01 GMT
- Etag:
- - W/"7f14e23ac07cc8b0a53c567fcf9432fd"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 573f3584-87c6-41cb-a5bf-5e7ee76d4250
- X-Runtime:
- - '0.266135'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Pushing over HTTP is not allowed."}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 10:32:01 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/http-push-disabled.yml b/spec/vcr_cassettes/http-push-disabled.yml
index e7e185e..676e5b8 100644
--- a/spec/vcr_cassettes/http-push-disabled.yml
+++ b/spec/vcr_cassettes/http-push-disabled.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/ssh-pull-disabled-old.yml b/spec/vcr_cassettes/ssh-pull-disabled-old.yml
deleted file mode 100644
index 55ce261..0000000
--- a/spec/vcr_cassettes/ssh-pull-disabled-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '63'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 12:23:57 GMT
- Etag:
- - W/"76a32010244f80700d5e1ba8a55d094c"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 096ae253-c6fe-4360-b4d4-48f4b5435ca6
- X-Runtime:
- - '6.377187'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Git access over SSH is not allowed"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 12:23:57 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-pull-disabled.yml b/spec/vcr_cassettes/ssh-pull-disabled.yml
index 92fc36a..55ce261 100644
--- a/spec/vcr_cassettes/ssh-pull-disabled.yml
+++ b/spec/vcr_cassettes/ssh-pull-disabled.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/ssh-pull-project-denied-old.yml b/spec/vcr_cassettes/ssh-pull-project-denied-old.yml
deleted file mode 100644
index c16e608..0000000
--- a/spec/vcr_cassettes/ssh-pull-project-denied-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=2&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '63'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 12:24:04 GMT
- Etag:
- - W/"76a32010244f80700d5e1ba8a55d094c"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - c843a5a3-fc08-46eb-aa45-caceae515638
- X-Runtime:
- - '7.359835'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Git access over SSH is not allowed"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 12:24:04 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-pull-project-denied.yml b/spec/vcr_cassettes/ssh-pull-project-denied.yml
index 61a71db..c16e608 100644
--- a/spec/vcr_cassettes/ssh-pull-project-denied.yml
+++ b/spec/vcr_cassettes/ssh-pull-project-denied.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/ssh-push-disabled-old.yml b/spec/vcr_cassettes/ssh-push-disabled-old.yml
deleted file mode 100644
index c061791..0000000
--- a/spec/vcr_cassettes/ssh-push-disabled-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '63'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 12:23:57 GMT
- Etag:
- - W/"76a32010244f80700d5e1ba8a55d094c"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 93620e06-fda9-4be5-855e-300f5d62fa3c
- X-Runtime:
- - '0.207159'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Git access over SSH is not allowed"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 12:23:57 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-push-disabled.yml b/spec/vcr_cassettes/ssh-push-disabled.yml
index 5ca2642..c061791 100644
--- a/spec/vcr_cassettes/ssh-push-disabled.yml
+++ b/spec/vcr_cassettes/ssh-push-disabled.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/ssh-push-project-denied-old.yml b/spec/vcr_cassettes/ssh-push-project-denied-old.yml
deleted file mode 100644
index 5107d15..0000000
--- a/spec/vcr_cassettes/ssh-push-project-denied-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&key_id=2&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '63'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 12:24:04 GMT
- Etag:
- - W/"76a32010244f80700d5e1ba8a55d094c"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 8ce54f29-9ed0-46e5-aedb-37edaa3d52da
- X-Runtime:
- - '0.228256'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Git access over SSH is not allowed"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 12:24:04 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-push-project-denied-with-user-old.yml b/spec/vcr_cassettes/ssh-push-project-denied-with-user-old.yml
deleted file mode 100644
index b461b5b..0000000
--- a/spec/vcr_cassettes/ssh-push-project-denied-with-user-old.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: http://localhost:3000/api/v4/internal/allowed
- body:
- encoding: US-ASCII
- string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&gl_repository&project=gitlab-org%2Fgitlab-test.git&protocol=ssh&env=%7B%7D&user_id=2&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - Ruby
- Content-Type:
- - application/x-www-form-urlencoded
- response:
- status:
- code: 200
- message: OK
- headers:
- Cache-Control:
- - max-age=0, private, must-revalidate
- Content-Length:
- - '63'
- Content-Type:
- - application/json
- Date:
- - Wed, 21 Jun 2017 12:24:05 GMT
- Etag:
- - W/"76a32010244f80700d5e1ba8a55d094c"
- Vary:
- - Origin
- X-Frame-Options:
- - SAMEORIGIN
- X-Request-Id:
- - 3b242d73-d860-48ac-8fef-80e2d0d3daca
- X-Runtime:
- - '0.342469'
- body:
- encoding: UTF-8
- string: '{"status":false,"message":"Git access over SSH is not allowed"}'
- http_version:
- recorded_at: Wed, 21 Jun 2017 12:24:05 GMT
-recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-push-project-denied-with-user.yml b/spec/vcr_cassettes/ssh-push-project-denied-with-user.yml
index 01be21b..b461b5b 100644
--- a/spec/vcr_cassettes/ssh-push-project-denied-with-user.yml
+++ b/spec/vcr_cassettes/ssh-push-project-denied-with-user.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate
diff --git a/spec/vcr_cassettes/ssh-push-project-denied.yml b/spec/vcr_cassettes/ssh-push-project-denied.yml
index b23dd8d..5107d15 100644
--- a/spec/vcr_cassettes/ssh-push-project-denied.yml
+++ b/spec/vcr_cassettes/ssh-push-project-denied.yml
@@ -17,8 +17,8 @@ http_interactions:
- application/x-www-form-urlencoded
response:
status:
- code: 401
- message: Unauthorized
+ code: 200
+ message: OK
headers:
Cache-Control:
- max-age=0, private, must-revalidate