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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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