travis 1.6.4.travis.410.4 → 1.6.4.travis.411.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTU4NGZjNTZmZDFmZjNmODkzOWMwNTQyYzljZjUyMTIxMWM3NzJlZg==
4
+ OTVmNWY5ZWVjOGE3MjAxYjAxZDFmZWJlZTM4MjVlMTQxNWJkZGIyYQ==
5
5
  data.tar.gz: !binary |-
6
- MTE0ZTQwMjA2MjI5NzcxYWQxNzNhNzhkMzFlMjIxOTI2MTc5YzhkZQ==
6
+ ZjFlYjIwMzEzYTNjOGVhZGQ5ZTdiMGU4Nzk4ZGZiNGM0ZGUwMjBkNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDkzMDJmZjY5MWU3MDQyNzQ2MWMyOTExODliNmRkZjY1NGI5NTQ2NTQ2ZjZl
10
- ZjFkMTZkMjU2MzkwYWM5OTZmMzMxNWU2NDkyM2EyMjkwZmQzN2Y0OTkzMTc0
11
- NzdlMjcwZDU1M2FjNTBmNzQwOWRkMGRjZjlmZmM2YTc2YTkxMDc=
9
+ MTkwZmZkZTA0ZjIwNGExZDEzM2ZhZWY3MmI1YmI1MTM4ZjMzN2U5YjBkMjZh
10
+ N2Y0ZDdiOTVkNWYxNzQ0NGE1NGIyZjZjNGVhYTM4ZGEwYmIzNTkzZDhhYmFj
11
+ MGY0YjQwMzVkNDJjMTQyOTNhOWUwZjg5ODdjZGMzZWRmYzJjOWM=
12
12
  data.tar.gz: !binary |-
13
- ZDY5MjAwN2U0Mjk4MWRhODE5OTY2OGUxODVlMGQwMWI1NTQ5ZmIxMDJiNTM3
14
- ZDc0ODdmMjNlYWJjM2RmNjkyY2JmYjkyNGU0MGU2NWNhODk2YzA0OGU5Njcw
15
- MzA4NzViYjE4NjczNTdiZTFiOTA1ZWY2NTIwODFmODY4MjlkMGM=
13
+ N2FmM2JlZmYzN2MxNTA3ZGNjMGVjZmEzYzZlZjhjNTAwNGRhNzM0NWJkNDVh
14
+ ZDY2NDhlOTJmNzBiZDNhODI5ZmUyNGMzOTI4ODJhNTJmM2ZiZjFjY2JkMzAy
15
+ OTk2MWY4MDNmMjAxNDVlMzc4MTQzODk0MWY4MDAwMTE1YTBmNmE=
data/assets/travis.sh CHANGED
@@ -36,7 +36,7 @@ if type compdef 1>/dev/null 2>/dev/null; then
36
36
  help) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" '*:file:_files' && return 0;;
37
37
  history) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "-r[repository to use (will try to detect from current git clone)]" "--repo[repository to use (will try to detect from current git clone)]" "-a[Only show history after a given build number]" "--after[Only show history after a given build number]" "-p[Only show history for the given Pull Request]" "--pull-request[Only show history for the given Pull Request]" "-b[Only show history for the given branch]" "--branch[Only show history for the given branch]" "-l[Maximum number of history items]" "--limit[Maximum number of history items]" "-d[Include date in output]" "--date[Include date in output]" "--all[Display all history items]" "--no-all[Display all history items]" '*:file:_files' && return 0;;
38
38
  init) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "-r[repository to use (will try to detect from current git clone)]" "--repo[repository to use (will try to detect from current git clone)]" "-s[don't trigger a sync if the repo is unknown]" "--skip-sync[don't trigger a sync if the repo is unknown]" "-f[override .travis.yml if it already exists]" "--force[override .travis.yml if it already exists]" "-k[do not enable project, only add .travis.yml]" "--skip-enable[do not enable project, only add .travis.yml]" "-p[print generated config instead of writing to file]" "--print-conf[print generated config instead of writing to file]" "--script[sets script option in .travis.yml (can be used more than once)]" "--before-script[sets before_script option in .travis.yml (can be used more than once)]" "--after-script[sets after_script option in .travis.yml (can be used more than once)]" "--after-success[sets after_success option in .travis.yml (can be used more than once)]" "--install[sets install option in .travis.yml (can be used more than once)]" "--before-install[sets before_install option in .travis.yml (can be used more than once)]" "--compiler[sets compiler option in .travis.yml (can be used more than once)]" "--otp-release[sets otp_release option in .travis.yml (can be used more than once)]" "--go[sets go option in .travis.yml (can be used more than once)]" "--jdk[sets jdk option in .travis.yml (can be used more than once)]" "--node-js[sets node_js option in .travis.yml (can be used more than once)]" "--perl[sets perl option in .travis.yml (can be used more than once)]" "--php[sets php option in .travis.yml (can be used more than once)]" "--python[sets python option in .travis.yml (can be used more than once)]" "--rvm[sets rvm option in .travis.yml (can be used more than once)]" "--scala[sets scala option in .travis.yml (can be used more than once)]" "--env[sets env option in .travis.yml (can be used more than once)]" "--gemfile[sets gemfile option in .travis.yml (can be used more than once)]" '*:file:_files' && return 0;;
39
- login) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "--github-token[identify by GitHub token]" "--auto[try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)]" '*:file:_files' && return 0;;
39
+ login) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "-g[identify by GitHub token]" "--github-token[identify by GitHub token]" "-T[try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)]" "--auto-token[try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)]" "-p[try to load password from OSX keychain (will not be stored)]" "--auto-password[try to load password from OSX keychain (will not be stored)]" "-a[shorthand for --auto-token --auto-password]" "--auto[shorthand for --auto-token --auto-password]" "-u[user to log in as]" "--user[user to log in as]" "-M[do not use interactive login]" "--no-manual[do not use interactive login]" "--list-github-token[instead of actually logging in, list found GitHub tokens]" "--skip-token-check[don't verify the token with github]" '*:file:_files' && return 0;;
40
40
  logout) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" '*:file:_files' && return 0;;
41
41
  logs) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "-r[repository to use (will try to detect from current git clone)]" "--repo[repository to use (will try to detect from current git clone)]" '*:file:_files' && return 0;;
42
42
  monitor) _arguments -s -S "-h[Display help]" "--help[Display help]" "-i[be interactive and colorful]" "--interactive[be interactive and colorful]" "--no-interactive[be interactive and colorful]" "-E[don't rescue exceptions]" "--explode[don't rescue exceptions]" "--no-explode[don't rescue exceptions]" "--skip-version-check[don't check if travis client is up to date]" "--skip-completion-check[don't check if auto-completion is set up]" "-e[Travis API server to talk to]" "--api-endpoint[Travis API server to talk to]" "-I[do not verify SSL certificate of API endpoint]" "--insecure[do not verify SSL certificate of API endpoint]" "--no-insecure[do not verify SSL certificate of API endpoint]" "--pro[short-cut for --api-endpoint 'https://api.travis-ci.com/']" "--org[short-cut for --api-endpoint 'https://api.travis-ci.org/']" "--staging[talks to staging system]" "-t[access token to use]" "--token[access token to use]" "--debug[show API requests]" "-X[use enterprise setup (optionally takes name for multiple setups)]" "--enterprise[use enterprise setup (optionally takes name for multiple setups)]" "--adapter[Faraday adapter to use for HTTP requests]" "-m[Only monitor my own repositories]" "--my-repos[Only monitor my own repositories]" "-r[monitor given repository (can be used more than once)]" "--repo[monitor given repository (can be used more than once)]" "-n[send out desktop notifications (optional type: osx, growl, libnotify)]" "--notify[send out desktop notifications (optional type: osx, growl, libnotify)]" "--no-notify[send out desktop notifications (optional type: osx, growl, libnotify)]" "-b[only monitor builds, not jobs]" "--builds[only monitor builds, not jobs]" "-p[monitor push events]" "--push[monitor push events]" "-P[monitor pull request events]" "--pull[monitor pull request events]" '*:file:_files' && return 0;;
@@ -76,7 +76,7 @@ elif type compctl 1>/dev/null 2>/dev/null; then
76
76
  help) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check");;
77
77
  history) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--repo" "-r" "--after" "-a" "--pull-request" "-p" "--branch" "-b" "--limit" "-l" "--date" "-d" "--all" "--no-all");;
78
78
  init) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--repo" "-r" "--skip-sync" "-s" "--force" "-f" "--skip-enable" "-k" "--print-conf" "-p" "--script" "--before-script" "--after-script" "--after-success" "--install" "--before-install" "--compiler" "--otp-release" "--go" "--jdk" "--node-js" "--perl" "--php" "--python" "--rvm" "--scala" "--env" "--gemfile");;
79
- login) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--github-token" "--auto");;
79
+ login) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--github-token" "-g" "--auto-token" "-T" "--auto-password" "-p" "--auto" "-a" "--user" "-u" "--no-manual" "-M" "--list-github-token" "--skip-token-check");;
80
80
  logout) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter");;
81
81
  logs) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--repo" "-r");;
82
82
  monitor) reply=("--help" "-h" "--interactive" "--no-interactive" "-i" "--explode" "--no-explode" "-E" "--skip-version-check" "--skip-completion-check" "--api-endpoint" "-e" "--insecure" "--no-insecure" "-I" "--pro" "--org" "--staging" "--token" "-t" "--debug" "--enterprise" "-X" "--adapter" "--my-repos" "-m" "--repo" "-r" "--notify" "--no-notify" "-n" "--builds" "-b" "--push" "-p" "--pull" "-P");;
@@ -117,7 +117,7 @@ elif type complete 1>/dev/null 2>/dev/null; then
117
117
  help) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check";;
118
118
  history) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --repo -r --after -a --pull-request -p --branch -b --limit -l --date -d --all --no-all";;
119
119
  init) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --repo -r --skip-sync -s --force -f --skip-enable -k --print-conf -p --script --before-script --after-script --after-success --install --before-install --compiler --otp-release --go --jdk --node-js --perl --php --python --rvm --scala --env --gemfile";;
120
- login) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --github-token --auto";;
120
+ login) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --github-token -g --auto-token -T --auto-password -p --auto -a --user -u --no-manual -M --list-github-token --skip-token-check";;
121
121
  logout) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter";;
122
122
  logs) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --repo -r";;
123
123
  monitor) options="--help -h --interactive --no-interactive -i --explode --no-explode -E --skip-version-check --skip-completion-check --api-endpoint -e --insecure --no-insecure -I --pro --org --staging --token -t --debug --enterprise -X --adapter --my-repos -m --repo -r --notify --no-notify -n --builds -b --push -p --pull -P";;
@@ -124,6 +124,7 @@ module Travis
124
124
  gh_config ||= {}
125
125
  gh_config[:ssl] = Travis::Client::Session::SSL_OPTIONS
126
126
  gh_config[:ssl] = { :verify => false } if gh_config[:api_url] and gh_config[:api_url] != "https://api.github.com"
127
+ gh_config.delete :scopes
127
128
 
128
129
  gh_config[:instrumenter] = proc do |type, payload, &block|
129
130
  next block.call unless type == 'http.gh'
@@ -1,71 +1,72 @@
1
1
  require 'travis/cli'
2
- require 'travis/tools/token_finder'
2
+ require 'travis/tools/github'
3
3
  require 'json'
4
4
 
5
5
  module Travis
6
6
  module CLI
7
7
  class Login < ApiCommand
8
8
  description "authenticates against the API and stores the token"
9
- on '--github-token TOKEN', 'identify by GitHub token'
10
- on '--auto', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)'
9
+ on('-g', '--github-token TOKEN', 'identify by GitHub token')
10
+ on('-T', '--auto-token', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)')
11
+ on('-p', '--auto-password', 'try to load password from OSX keychain (will not be stored)')
12
+ on('-a', '--auto', 'shorthand for --auto-token --auto-password') { |c| c.auto_token = c.auto_password = true }
13
+ on('-u', '--user LOGIN', 'user to log in as') { |c,n| c.user_login = n }
14
+ on('-M', '--no-manual', 'do not use interactive login')
15
+ on('--list-github-token', 'instead of actually logging in, list found GitHub tokens')
16
+ on('--skip-token-check', 'don\'t verify the token with github')
11
17
 
12
- skip :authenticate
13
- attr_accessor :github_login, :github_password, :github_token, :github_otp, :callback
18
+ attr_accessor :user_login
14
19
 
15
- def run
16
- self.github_token ||= Travis::Tools::TokenFinder.find(:explode => explode?, :github => github_endpoint.host) if auto?
17
- generate_github_token unless github_token
18
- endpoint_config['access_token'] = github_auth(github_token)
19
- success("Successfully logged in!")
20
- ensure
21
- callback.call if callback
20
+ def list_token
21
+ github.after_tokens = proc { }
22
+ github.each_token do |token|
23
+ say token
24
+ end
22
25
  end
23
26
 
24
- private
25
-
26
- def generate_github_token
27
- load_gh
28
- ask_info
29
-
30
- options = { :username => github_login, :password => github_password }
31
- options[:headers] = { "X-GitHub-OTP" => github_otp } if github_otp
32
- gh = GH.with(options)
33
-
34
- reply = gh.post('/authorizations', :scopes => github_scopes, :note => "temporary token to identify on #{api_endpoint}")
35
-
36
- self.github_token = reply['token']
37
- self.callback = proc { gh.delete reply['_links']['self']['href'] }
38
- rescue GH::Error => error
39
- if error.info[:response_status] == 401
40
- ask_2fa
41
- generate_github_token
42
- else
43
- raise error if explode?
44
- error(JSON.parse(error.info[:response_body])["message"])
45
- end
27
+ def login
28
+ github.with_token do |token|
29
+ endpoint_config['access_token'] = github_auth(token)
30
+ error("user mismatch: logged in as %p instead of %p" % [user.login, user_login]) if user_login and user.login != user_login
31
+ success("Successfully logged in as #{user.login}!")
46
32
  end
33
+ end
47
34
 
48
- def github_scopes
49
- ['user:email', org? ? 'public_repo' : 'repo']
50
- end
35
+ def run
36
+ list_github_token ? list_token : login
37
+ end
51
38
 
52
- def ask_info
53
- return if !github_login.nil?
54
- say "We need your #{color("GitHub login", :important)} to identify you."
55
- say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
56
- say "The password will not be displayed."
57
- empty_line
58
- say "Try running with #{color("--github-token", :info)} or #{color("--auto", :info)} if you don't want to enter your password anyways."
59
- empty_line
60
- self.github_login = ask("Username: ")
61
- self.github_password = ask("Password: ") { |q| q.echo = "*" }
62
- empty_line
39
+ def github
40
+ @github ||= begin
41
+ load_gh
42
+ Tools::Github.new(session.config['github']) do |g|
43
+ g.note = "temporary token to identify with the travis command line client against #{api_endpoint}"
44
+ g.manual_login = no_manual.nil?
45
+ g.explode = explode?
46
+ g.github_token = github_token
47
+ g.auto_token = auto_token
48
+ g.auto_password = auto_password
49
+ g.github_login = user_login
50
+ g.check_token = !skip_token_check?
51
+ g.drop_token = true
52
+ g.ask_login = proc { ask("Username: ") }
53
+ g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
54
+ g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
55
+ g.login_header = proc { login_header }
56
+ g.debug = proc { |log| debug(log) }
57
+ g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
58
+ end
63
59
  end
60
+ end
64
61
 
65
- def ask_2fa
66
- self.github_otp = ask "Two-factor authentication code: "
67
- empty_line
68
- end
62
+ def login_header
63
+ say "We need your #{color("GitHub login", :important)} to identify you."
64
+ say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
65
+ say "The password will not be displayed."
66
+ empty_line
67
+ say "Try running with #{color("--github-token", :info)} or #{color("--auto", :info)} if you don't want to enter your password anyways."
68
+ empty_line
69
+ end
69
70
  end
70
71
  end
71
72
  end
@@ -0,0 +1,260 @@
1
+ require 'travis/tools/system'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ module Travis
6
+ module Tools
7
+ class Github
8
+ TOKEN_SIZE = 40
9
+ GITHUB_API = 'api.github.com'
10
+ GITHUB_HOST = 'github.com'
11
+
12
+ attr_accessor :api_url, :scopes, :github_token, :github_login, :drop_token, :callback, :explode, :after_tokens,
13
+ :ask_login, :ask_password, :ask_otp, :login_header, :auto_token, :auto_password, :manual_login, :note,
14
+ :netrc_path, :hub_path, :oauth_paths, :composer_path, :git_config_keys, :debug, :no_token, :check_token
15
+
16
+ def initialize(options = nil)
17
+ @check_token = true
18
+ @manual_login = true
19
+ @ask_login = proc { raise "ask_login callback not set" }
20
+ @after_tokens = proc { }
21
+ @ask_password = proc { |_| raise "ask_password callback not set" }
22
+ @ask_otp = proc { |_| raise "ask_otp callback not set" }
23
+ @debug = proc { |_| }
24
+ @netrc_path = '~/.netrc'
25
+ @hub_path = ENV['HUB_CONFIG'] || '~/.config/hub'
26
+ @oauth_paths = ['~/.github-oauth-token']
27
+ @composer_path = "~/.composer/config.json"
28
+ @note = 'temporary token'
29
+ @git_config_keys = %w[github.token github.oauth-token]
30
+ @scopes = ['user', 'user:email', 'repo'] # overridden by value from /config
31
+ options.each_pair { |k,v| send("#{k}=", v) if respond_to? "#{k}=" } if options
32
+ yield self if block_given?
33
+ end
34
+
35
+ def with_token
36
+ each_token { |t| break yield(t) }
37
+ end
38
+
39
+ def each_token
40
+ require 'gh' unless defined? GH
41
+ possible_tokens { |t| yield(t) if acceptable?(t) }
42
+ ensure
43
+ callback, self.callback = self.callback, nil
44
+ callback.call if callback
45
+ end
46
+
47
+ def with_session(&block)
48
+ with_token { |t| GH.with(:token => t, &block) }
49
+ end
50
+
51
+ def possible_tokens(&block)
52
+ return block[github_token] if github_token
53
+
54
+ if auto_token
55
+ netrc_tokens(&block)
56
+ git_tokens(&block)
57
+ hub_tokens(&block)
58
+ oauth_file_tokens(&block)
59
+ github_for_mac_token(&block)
60
+ issuepost_token(&block)
61
+ composer_token(&block)
62
+ end
63
+
64
+ if auto_password
65
+ possible_logins do |user, password|
66
+ yield login(user, password, false)
67
+ end
68
+ end
69
+
70
+ if manual_login
71
+ login_header.call if login_header
72
+ user = github_login || ask_login.call
73
+ password = ask_password.call(user)
74
+ yield login(user, password, true)
75
+ end
76
+
77
+ after_tokens.call
78
+ end
79
+
80
+ def possible_logins(&block)
81
+ netrc_logins(&block)
82
+ hub_logins(&block)
83
+ keychain_login(&block)
84
+ end
85
+
86
+ def netrc_tokens
87
+ netrc.each do |entry|
88
+ next unless entry["machine"] == api_host or entry["machine"] == host
89
+ entry.values_at("token", "login", "password").each do |entry|
90
+ next if entry.to_s.size != TOKEN_SIZE
91
+ debug "found oauth token in netrc"
92
+ yield entry
93
+ end
94
+ end
95
+ end
96
+
97
+ def git_tokens
98
+ return unless System.has? 'git'
99
+ git_config_keys.each do |key|
100
+ `git config --get-all #{key}`.each_line do |line|
101
+ token = line.strip
102
+ yield token unless token.empty?
103
+ end
104
+ end
105
+ end
106
+
107
+ def composer_token
108
+ file(composer_path) do |content|
109
+ token = JSON.parse(content)['config'].fetch('github-oauth', {})[host]
110
+ yield token if token
111
+ end
112
+ end
113
+
114
+ def hub_tokens
115
+ hub.fetch(host, []).each do |entry|
116
+ next if github_login and github_login != entry["user"]
117
+ yield entry["oauth_token"] if entry["oauth_token"]
118
+ end
119
+ end
120
+
121
+ def oauth_file_tokens(&block)
122
+ oauth_paths.each do |path|
123
+ file(path) do |content|
124
+ token = content.strip
125
+ yield token unless token.empty?
126
+ end
127
+ end
128
+ end
129
+
130
+ def netrc_logins
131
+ netrc.each do |entry|
132
+ next unless entry["machine"] == api_host or entry["machine"] == host
133
+ next if github_login and github_login != entry["login"]
134
+ yield entry["login"], entry["password"] if entry["login"] and entry["password"]
135
+ end
136
+ end
137
+
138
+ def hub_logins
139
+ hub.fetch(host, []).each do |entry|
140
+ next if github_login and github_login != entry["user"]
141
+ yield entry["user"], entry["password"] if entry["user"] and entry["password"]
142
+ end
143
+ end
144
+
145
+ def keychain_login
146
+ if github_login
147
+ security(:internet, :w, "-s #{host} -a #{github_login}", "#{host} password for #{github_login}") do |password|
148
+ yield github_login, password if password and not password.empty?
149
+ end
150
+ else
151
+ security(:internet, :g, "-s #{host}", "#{host} login and password") do |data|
152
+ username = data[/^\s+"acct"<blob>="(.*)"$/, 1].to_s
153
+ password = data[/^password: "(.*)"$/, 1].to_s
154
+ yield username, password unless username.empty? or password.empty?
155
+ end
156
+ end
157
+ end
158
+
159
+ def netrc
160
+ file(netrc_path, []) do |contents|
161
+ contents.scan(/^\s*(\S+)\s+(\S+)\s*$/).inject([]) do |mapping, (key, value)|
162
+ mapping << {} if key == "machine"
163
+ mapping.last[key] = value if mapping.last
164
+ mapping
165
+ end
166
+ end
167
+ end
168
+
169
+ def hub
170
+ file(hub_path, {}) do |contents|
171
+ YAML.load(contents)
172
+ end
173
+ end
174
+
175
+ def issuepost_token(&block)
176
+ security(:generic, :w, "-l issuepost.github.access_token", "issuepost token", &block) if host == 'github.com'
177
+ end
178
+
179
+ def github_for_mac_token(&block)
180
+ command = '-s "github.com/mac"'
181
+ command << " -a #{github_login}" if github_login
182
+ security(:internet, :w, command, "GitHub for Mac token", &block) if host == 'github.com'
183
+ end
184
+
185
+ def host
186
+ api_host == GITHUB_API ? GITHUB_HOST : api_host
187
+ end
188
+
189
+ def api_host
190
+ return GITHUB_API unless api_url
191
+ api_url[%r{^(?:https?://)?([^/]+)}, 1]
192
+ end
193
+
194
+ def login(user, password, die = true, otp = nil)
195
+ opt = { :username => user, :password => password }
196
+ opt[:headers] = { "X-GitHub-OTP" => otp } if otp
197
+ gh = GH.with(opt)
198
+ reply = gh.post('/authorizations', :scopes => scopes, :note => note)
199
+ self.callback = proc { gh.delete reply['_links']['self']['href'] }
200
+ reply['token']
201
+ rescue GH::Error => error
202
+ if error.info[:response_status] == 401
203
+ login(user, password, die, ask_otp.call(user))
204
+ elsif die
205
+ raise gh_error(error)
206
+ end
207
+ end
208
+
209
+ def acceptable?(token)
210
+ return true unless check_token
211
+ gh = GH.with(:token => token)
212
+ user = gh['user']
213
+
214
+ if github_login and github_login != user['login']
215
+ debug "token is not acceptable: identifies %p instead of %p" % [user['login'], github_login]
216
+ false
217
+ else
218
+ true
219
+ end
220
+ rescue GH::Error => error
221
+ debug "token is not acceptable: #{gh_error(error)}"
222
+ false
223
+ end
224
+
225
+ private
226
+
227
+ def gh_error(error)
228
+ raise error if explode
229
+ JSON.parse(error.info[:response_body])["message"].to_s
230
+ end
231
+
232
+ def debug(line)
233
+ return unless @debug
234
+ @debug.call "Tools::Github: #{line}"
235
+ end
236
+
237
+ def security(type, key, arg, name)
238
+ return false unless System.has? 'security'
239
+ return false unless system "security find-#{type}-password #{arg} 2>/dev/null >/dev/null"
240
+ debug "requesting to load #{name} from keychain"
241
+ result = %x[security find-#{type}-password #{arg} -#{key} 2>&1].chomp
242
+ $?.success? ? yield(result) : debug("request denied")
243
+ rescue => e
244
+ raise e if explode
245
+ end
246
+
247
+ def file(path, default = nil)
248
+ path &&= File.expand_path(path)
249
+ @file ||= {}
250
+ @file[path] ||= if path and File.readable?(path)
251
+ debug "reading #{path}"
252
+ yield File.read(path)
253
+ end
254
+ @file[path] || default
255
+ rescue => e
256
+ raise e if explode
257
+ end
258
+ end
259
+ end
260
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Travis::CLI::Login do
4
4
  example "travis login", :unless => Travis::Tools::System.windows? do
5
- run_cli('login') { |i| i.puts('rkh', 'password') }.should be_success
5
+ run_cli('login', '-E', '--skip-token-check') { |i| i.puts('rkh', 'password') }.should be_success
6
6
  run_cli('whoami').out.should be == "rkh\n"
7
7
  end
8
8
 
@@ -7,6 +7,10 @@ module GH
7
7
  super
8
8
  end
9
9
 
10
+ def http(*)
11
+ raise NotImplementedError
12
+ end
13
+
10
14
  def post(key, body)
11
15
  raise GH::Error unless @authenticated and key == '/authorizations'
12
16
  frontend.load("url" => "https://api.github.com/authorizations/1", "token" => "github_token")
data/travis.gemspec CHANGED
@@ -171,10 +171,10 @@ Gem::Specification.new do |s|
171
171
  "lib/travis/tools/assets.rb",
172
172
  "lib/travis/tools/completion.rb",
173
173
  "lib/travis/tools/formatter.rb",
174
+ "lib/travis/tools/github.rb",
174
175
  "lib/travis/tools/notification.rb",
175
176
  "lib/travis/tools/safe_string.rb",
176
177
  "lib/travis/tools/system.rb",
177
- "lib/travis/tools/token_finder.rb",
178
178
  "lib/travis/version.rb",
179
179
  "spec/cli/cancel_spec.rb",
180
180
  "spec/cli/encrypt_spec.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: travis
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.4.travis.410.4
4
+ version: 1.6.4.travis.411.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Haase
@@ -364,10 +364,10 @@ files:
364
364
  - lib/travis/tools/assets.rb
365
365
  - lib/travis/tools/completion.rb
366
366
  - lib/travis/tools/formatter.rb
367
+ - lib/travis/tools/github.rb
367
368
  - lib/travis/tools/notification.rb
368
369
  - lib/travis/tools/safe_string.rb
369
370
  - lib/travis/tools/system.rb
370
- - lib/travis/tools/token_finder.rb
371
371
  - lib/travis/version.rb
372
372
  - spec/cli/cancel_spec.rb
373
373
  - spec/cli/encrypt_spec.rb
@@ -1,52 +0,0 @@
1
- require 'netrc'
2
- require 'yaml'
3
-
4
- module Travis
5
- module Tools
6
- # This is used when running `travis login --auto`
7
- class TokenFinder
8
- attr_accessor :netrc, :hub, :explode, :github
9
-
10
- def self.find(options = {})
11
- new(options).find
12
- end
13
-
14
- def initialize(options = {})
15
- self.netrc = options[:netrc] || Netrc.default_path
16
- self.hub = options[:hub] || ENV['HUB_CONFIG'] || '~/.config/hub'
17
- self.github = options[:github]
18
- self.github = 'github.com' if github.nil? or github == 'api.github.com'
19
- self.explode = options[:explode]
20
- end
21
-
22
- def hub=(file)
23
- @hub = File.expand_path(file)
24
- end
25
-
26
- def netrc=(file)
27
- @netrc = File.expand_path(file)
28
- end
29
-
30
- def find
31
- find_netrc || find_hub
32
- end
33
-
34
- def find_netrc
35
- return unless File.readable? netrc
36
- data = Netrc.read(netrc)[github]
37
- data.detect { |e| e.size == 40 } if data
38
- rescue => e
39
- raise e if explode
40
- end
41
-
42
- def find_hub
43
- return unless File.readable? hub
44
- data = YAML.load_file(File.expand_path(hub))
45
- data &&= Array(data[github])
46
- data.first['oauth_token'] if data.size == 1
47
- rescue => e
48
- raise e if explode
49
- end
50
- end
51
- end
52
- end