Commit 2956630a authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'nice-error-message' into 'master'

Write errors to stderr to get git to abort and show them as such.

Addresses private issues https://dev.gitlab.org/gitlab/gitlab-shell/issues/33 and https://dev.gitlab.org/gitlab/gitlabhq/issues/2195.

![Screen_Shot_2015-04-06_at_13.05.43](https://gitlab.com/gitlab-org/gitlab-shell/uploads/56a4b9f4cc983da93afeb2b85252ec7e/Screen_Shot_2015-04-06_at_13.05.43.png)

See merge request !8
parents 63efd092 f64e5d4a
...@@ -13,6 +13,9 @@ require_relative '../lib/gitlab_init' ...@@ -13,6 +13,9 @@ require_relative '../lib/gitlab_init'
# #
# #
require File.join(ROOT_PATH, 'lib', 'gitlab_shell') require File.join(ROOT_PATH, 'lib', 'gitlab_shell')
GitlabShell.new.exec
exit if GitlabShell.new.exec
exit 0
else
exit 1
end
...@@ -14,5 +14,8 @@ if GitlabAccess.new(repo_path, key_id, refs).exec && ...@@ -14,5 +14,8 @@ if GitlabAccess.new(repo_path, key_id, refs).exec &&
GitlabCustomHook.new.pre_receive(refs, repo_path) GitlabCustomHook.new.pre_receive(refs, repo_path)
exit 0 exit 0
else else
# reset GL_ID env since we stop git push here
ENV['GL_ID'] = nil
exit 1 exit 1
end end
...@@ -5,6 +5,8 @@ require_relative 'names_helper' ...@@ -5,6 +5,8 @@ require_relative 'names_helper'
require 'json' require 'json'
class GitlabAccess class GitlabAccess
class AccessDeniedError < StandardError; end
include NamesHelper include NamesHelper
attr_reader :config, :repo_path, :repo_name, :changes attr_reader :config, :repo_path, :repo_name, :changes
...@@ -18,19 +20,16 @@ class GitlabAccess ...@@ -18,19 +20,16 @@ class GitlabAccess
end end
def exec def exec
begin status = api.check_access('git-receive-pack', @repo_name, @actor, @changes)
status = api.check_access('git-receive-pack', @repo_name, @actor, @changes)
return true if status.allowed?
message = status.message raise AccessDeniedError, status.message unless status.allowed?
rescue GitlabNet::ApiUnreachableError
message = "Failed to authorize your Git request: internal API unreachable"
end
# reset GL_ID env since we stop git push here true
ENV['GL_ID'] = nil rescue GitlabNet::ApiUnreachableError
puts "GitLab: #{message}" $stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
false
rescue AccessDeniedError => ex
$stderr.puts "GitLab: #{ex.message}"
false false
end end
......
...@@ -3,7 +3,9 @@ require 'shellwords' ...@@ -3,7 +3,9 @@ require 'shellwords'
require_relative 'gitlab_net' require_relative 'gitlab_net'
class GitlabShell class GitlabShell
class AccessDeniedError < StandardError; end
class DisallowedCommandError < StandardError; end class DisallowedCommandError < StandardError; end
class InvalidRepositoryPathError < StandardError; end
attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name
...@@ -15,31 +17,41 @@ class GitlabShell ...@@ -15,31 +17,41 @@ class GitlabShell
end end
def exec def exec
if @origin_cmd unless @origin_cmd
parse_cmd puts "Welcome to GitLab, #{username}!"
return true
end
raise DisallowedCommandError unless git_cmds.include?(@git_cmd) parse_cmd
ENV['GL_ID'] = @key_id raise DisallowedCommandError unless git_cmds.include?(@git_cmd)
access = api.check_access(@git_cmd, @repo_name, @key_id, '_any') ENV['GL_ID'] = @key_id
status = api.check_access(@git_cmd, @repo_name, @key_id, '_any')
if access.allowed? raise AccessDeniedError, status.message unless status.allowed?
process_cmd
else process_cmd
message = "gitlab-shell: Access denied for git command <#{@origin_cmd}> by #{log_username}."
$logger.warn message true
puts access.message
end
else
puts "Welcome to GitLab, #{username}!"
end
rescue GitlabNet::ApiUnreachableError => ex rescue GitlabNet::ApiUnreachableError => ex
puts "Failed to authorize your Git request: internal API unreachable" $stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
false
rescue AccessDeniedError => ex
message = "gitlab-shell: Access denied for git command <#{@origin_cmd}> by #{log_username}."
$logger.warn message
$stderr.puts "GitLab: #{ex.message}"
false
rescue DisallowedCommandError => ex rescue DisallowedCommandError => ex
message = "gitlab-shell: Attempt to execute disallowed command <#{@origin_cmd}> by #{log_username}." message = "gitlab-shell: Attempt to execute disallowed command <#{@origin_cmd}> by #{log_username}."
$logger.warn message $logger.warn message
puts 'Disallowed command'
$stderr.puts "GitLab: Disallowed command"
false
rescue InvalidRepositoryPathError => ex
$stderr.puts "GitLab: Invalid repository path"
false
end end
protected protected
...@@ -125,7 +137,7 @@ class GitlabShell ...@@ -125,7 +137,7 @@ class GitlabShell
if File.absolute_path(full_repo_path) == full_repo_path if File.absolute_path(full_repo_path) == full_repo_path
path path
else else
abort "Wrong repository path" raise InvalidRepositoryPathError
end end
end end
......
...@@ -241,7 +241,7 @@ describe GitlabShell do ...@@ -241,7 +241,7 @@ describe GitlabShell do
before { File.stub(:absolute_path) { 'y' } } before { File.stub(:absolute_path) { 'y' } }
subject { -> { shell.send(:escape_path, 'z') } } subject { -> { shell.send(:escape_path, 'z') } }
it { should raise_error(SystemExit, "Wrong repository path") } it { should raise_error(GitlabShell::InvalidRepositoryPathError) }
end end
def ssh_cmd(cmd) def ssh_cmd(cmd)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment