From ecba183b60eb0798ecf1736659ed7d0a995d0f01 Mon Sep 17 00:00:00 2001 From: Ash McKenzie Date: Thu, 26 Jul 2018 19:06:20 +1000 Subject: Utilise new Actions * Move gitaly, git-lfs and 2FA logic out from gitlab_shell.rb * Streamline parsing of origin_cmd in GitlabShell * Utilise proper HTTP status codes sent from the API * Also support 200 OK with status of true/false (ideally get rid of this) * Use HTTP status constants * Use attr_reader definitions (var over @var) * Rspec deprecation fixes --- lib/gitlab_net.rb | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'lib/gitlab_net.rb') diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb index 191ecf5..3bc8f2d 100644 --- a/lib/gitlab_net.rb +++ b/lib/gitlab_net.rb @@ -1,15 +1,18 @@ require 'json' +require_relative 'errors' require_relative 'gitlab_logger' require_relative 'gitlab_access' require_relative 'gitlab_lfs_authentication' require_relative 'http_helper' +require_relative 'action' -class GitlabNet # rubocop:disable Metrics/ClassLength +class GitlabNet include HTTPHelper CHECK_TIMEOUT = 5 GL_PROTOCOL = 'ssh'.freeze + API_INACCESSIBLE_ERROR = 'API is not accessible'.freeze def check_access(cmd, gl_repository, repo, key_id, changes, protocol = GL_PROTOCOL, env: {}) changes = changes.join("\n") unless changes.is_a?(String) @@ -26,22 +29,15 @@ class GitlabNet # rubocop:disable Metrics/ClassLength resp = post("#{internal_api_endpoint}/allowed", params) - if resp.code == '200' - GitAccessStatus.create_from_json(resp.body) - else - GitAccessStatus.new(false, - 'API is not accessible', - gl_repository: nil, - gl_username: nil, - repository_path: nil, - gitaly: nil) - end + determine_action(key_id, resp) end def discover(key) key_id = key.gsub("key-", "") resp = get("#{internal_api_endpoint}/discover?key_id=#{key_id}") - JSON.parse(resp.body) rescue nil + JSON.parse(resp.body) + rescue JSON::ParserError, ApiUnreachableError + nil end def lfs_authenticate(key, repo) @@ -97,11 +93,7 @@ class GitlabNet # rubocop:disable Metrics/ClassLength end def post_receive(gl_repository, identifier, changes) - params = { - gl_repository: gl_repository, - identifier: identifier, - changes: changes - } + params = { gl_repository: gl_repository, identifier: identifier, changes: changes } resp = post("#{internal_api_endpoint}/post_receive", params) raise NotFound if resp.code == HTTP_NOT_FOUND @@ -120,4 +112,25 @@ class GitlabNet # rubocop:disable Metrics/ClassLength def sanitize_path(repo) repo.delete("'") end + + def determine_action(key_id, 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(key_id, json) + when HTTP_UNAUTHORIZED, HTTP_NOT_FOUND + raise AccessDeniedError, message + else + raise UnknownError, "#{API_INACCESSIBLE_ERROR}: #{message}" + end + rescue JSON::ParserError + raise UnknownError, API_INACCESSIBLE_ERROR + end end -- cgit v1.2.1