lib/travis/tools/github.rb in travis-1.10.1.travis.1341.9 vs lib/travis/tools/github.rb in travis-1.11.0

- old
+ new

@@ -8,23 +8,19 @@ class Github TOKEN_SIZE = 40 GITHUB_API = 'api.github.com' GITHUB_HOST = 'github.com' - attr_accessor :api_url, :scopes, :github_token, :github_login, :drop_token, :callback, :explode, :after_tokens, - :ask_login, :ask_password, :ask_otp, :login_header, :auto_token, :auto_password, :manual_login, :note, - :netrc_path, :hub_path, :oauth_paths, :composer_path, :git_config_keys, :debug, :no_token, :check_token + attr_accessor :api_url, :scopes, :github_token, :drop_token, :callback, :explode, :after_tokens, + :login_header, :auto_token, :note, + :hub_path, :oauth_paths, :composer_path, :git_config_keys, :debug, :no_token, :check_token def initialize(options = nil) @check_token = true - @manual_login = true @ask_login = proc { raise "ask_login callback not set" } @after_tokens = proc { } - @ask_password = proc { |_| raise "ask_password callback not set" } - @ask_otp = proc { |_| raise "ask_otp callback not set" } @debug = proc { |_| } - @netrc_path = '~/.netrc' @hub_path = ENV['HUB_CONFIG'] || '~/.config/hub' @oauth_paths = ['~/.github-oauth-token'] @composer_path = "~/.composer/config.json" @note = 'temporary token' @git_config_keys = %w[github.token github.oauth-token] @@ -35,18 +31,10 @@ def with_token each_token { |t| break yield(t) } end - def with_basic_auth(&block) - user, password = ask_credentials - basic_auth(user, password, true) do |gh, _| - gh['user'] # so otp kicks in - yield gh - end - end - def each_token require 'gh' unless defined? GH possible_tokens { |t| yield(t) if acceptable?(t) } ensure callback, self.callback = self.callback, nil @@ -59,57 +47,25 @@ def possible_tokens(&block) return block[github_token] if github_token if auto_token - netrc_tokens(&block) git_tokens(&block) hub_tokens(&block) oauth_file_tokens(&block) github_for_mac_token(&block) issuepost_token(&block) composer_token(&block) end - if auto_password - possible_logins do |user, password| - yield login(user, password, false) - end + if github_token || auto_token + after_tokens.call + elsif login_header + login_header.call end - - if manual_login - user, password = ask_credentials - yield login(user, password, true) - end - - after_tokens.call end - def ask_credentials - login_header.call if login_header - user = github_login || ask_login.call - password = ask_password.arity == 0 ? ask_password.call : ask_password.call(user) - [user, password] - end - - def possible_logins(&block) - netrc_logins(&block) - hub_logins(&block) - keychain_login(&block) - end - - def netrc_tokens - netrc.each do |entry| - next unless entry["machine"] == api_host or entry["machine"] == host - entry.values_at("token", "login", "password").each do |entry| - next if entry.to_s.size != TOKEN_SIZE - debug "found oauth token in netrc" - yield entry - end - end - end - def git_tokens return unless System.has? 'git' git_config_keys.each do |key| `git config --get-all #{key}`.each_line do |line| token = line.strip @@ -125,11 +81,10 @@ end end def hub_tokens hub.fetch(host, []).each do |entry| - next if github_login and github_login != entry["user"] yield entry["oauth_token"] if entry["oauth_token"] end end def oauth_file_tokens(&block) @@ -139,49 +94,10 @@ yield token unless token.empty? end end end - def netrc_logins - netrc.each do |entry| - next unless entry["machine"] == api_host or entry["machine"] == host - next if github_login and github_login != entry["login"] - yield entry["login"], entry["password"] if entry["login"] and entry["password"] - end - end - - def hub_logins - hub.fetch(host, []).each do |entry| - next if github_login and github_login != entry["user"] - yield entry["user"], entry["password"] if entry["user"] and entry["password"] - end - end - - def keychain_login - if github_login - security(:internet, :w, "-s #{host} -a #{github_login}", "#{host} password for #{github_login}") do |password| - yield github_login, password if password and not password.empty? - end - else - security(:internet, :g, "-s #{host}", "#{host} login and password") do |data| - username = data[/^\s+"acct"<blob>="(.*)"$/, 1].to_s - password = data[/^password: "(.*)"$/, 1].to_s - yield username, password unless username.empty? or password.empty? - end - end - end - - def netrc - file(netrc_path, []) do |contents| - contents.scan(/^\s*(\S+)\s+(\S+)\s*$/).inject([]) do |mapping, (key, value)| - mapping << {} if key == "machine" - mapping.last[key] = value if mapping.last - mapping - end - end - end - def hub file(hub_path, {}) do |contents| YAML.load(contents) end end @@ -190,11 +106,10 @@ security(:generic, :w, "-l issuepost.github.access_token", "issuepost token", &block) if host == 'github.com' end def github_for_mac_token(&block) command = '-s "github.com/mac"' - command << " -a #{github_login}" if github_login security(:internet, :w, command, "GitHub for Mac token", &block) if host == 'github.com' end def host api_host == GITHUB_API ? GITHUB_HOST : api_host @@ -203,55 +118,15 @@ def api_host return GITHUB_API unless api_url api_url[%r{^(?:https?://)?([^/]+)}, 1] end - def basic_auth(user, password, die = true, otp = nil, &block) - gh = GH.with(:username => user, :password => password) - with_otp(gh, user, otp, &block) - rescue GH::Error => error - raise gh_error(error) if die - end - - def login(user, password, die = true, otp = nil) - basic_auth(user, password, die, otp) do |gh, new_otp| - reply = create_token(gh) - auth_href = reply['_links']['self']['href'] - self.callback = proc { with_otp(gh, user, new_otp) { |g| g.delete(auth_href) } } if drop_token - reply['token'] - end - end - - def create_token(gh) - gh.post('/authorizations', :scopes => scopes, :note => note) - rescue GH::Error => error - # token might already exist due to bug in earlier CLI version, we'll have to delete it first - raise error unless error.info[:response_status] == 422 and error.info[:response_body].to_s =~ /already_exists/ - raise error unless reply = gh['/authorizations'].detect { |a| a['note'] == note } - gh.delete(reply['_links']['self']['href']) - retry - end - - def with_otp(gh, user, otp, &block) - gh = GH.with(gh.options.merge(:headers => { "X-GitHub-OTP" => otp })) if otp - block.call(gh, otp) - rescue GH::Error => error - raise error unless error.info[:response_status] == 401 and error.info[:response_headers]['x-github-otp'].to_s =~ /required/ - otp = ask_otp.arity == 0 ? ask_otp.call : ask_otp.call(user) - retry - end - def acceptable?(token) return true unless check_token gh = GH.with(:token => token) user = gh['user'] - if github_login and github_login != user['login'] - debug "token is not acceptable: identifies %p instead of %p" % [user['login'], github_login] - false - else - true - end + true rescue GH::Error => error debug "token is not acceptable: #{gh_error(error)}" false end