Skip to content

Commit

Permalink
Merge pull request #811 from travis-ci/sc-remove-username-auth
Browse files Browse the repository at this point in the history
Remove basic auth
  • Loading branch information
travis-architect committed Jan 3, 2022
2 parents 654e6e1 + 1a2d774 commit a166798
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 233 deletions.
39 changes: 4 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,22 +233,11 @@ default API endpoint dropped (was https://api.travis-ci.com/)
The `login` command will, well, log you in. That way, all subsequent commands that run against the same endpoint will be authenticated.

``` console
$ travis login
We need your GitHub login to identify you.
This information will not be sent to Travis CI, only to GitHub.
The password will not be displayed.

Try running with --github-token or --auto if you don't want to enter your password anyway.

Username: rkh
Password: *******************

Successfully logged in!
$ travis login --pro --github-token ghp_********
Successfully logged in as rkh!
```

As you can see above, it will ask you for your GitHub user name and password, but not send these to Travis CI. Instead, it will use them to create a GitHub API token, show the token to Travis, which then on its own checks if you really are who you say you are, and gives you an access token for the Travis API in return. The client will then delete the GitHub token again, just to be sure. But don't worry, all that happens under the hood and fully automatic.

If you don't want it to send your credentials to GitHub, you can create a GitHub token on your own and supply it via `--github-token`. In that case, the client will not delete the GitHub token (as it can't, it needs your password to do this). Travis CI will not store the token, though - after all, it already should have a valid token for you in the database.
You need to use a GitHub token and supply it via `--github-token`. Travis CI will not store the token, though - after all, it already should have a valid token for you in the database.
*NOTE*: When creating a GitHub token, see [GitHub Permissions used by travis-ci.com](https://docs.travis-ci.com/user/github-oauth-scopes/#travis-ci-for-private-projects) or [GitHub Permissions used by travis-ci.org](https://docs.travis-ci.com/user/github-oauth-scopes/#travis-ci-for-open-source-projects). The token permissions are dependent on use of travis-ci.com or travis-ci.org and not if they are public or private repositories.

A third option is for the really lazy: `--auto`. In this mode the client will try to find a GitHub token for you and just use that. This will only work if you have a [global GitHub token](https://help.github.com/articles/git-over-https-using-oauth-token) stored in your [.netrc](http://blogdown.io/c4d42f87-80dd-45d5-8927-4299cbdf261c/posts/574baa68-f663-4dcf-88b9-9d41310baf2f). If you haven't heard of this, it's worth looking into in general. Again: Travis CI will not store that token.
Expand Down Expand Up @@ -1560,26 +1549,6 @@ puts "Hello #{Travis::User.current.name}!"

Travis CI will not store that token.

It also ships with a tool for generating a GitHub token from a user name and password via the GitHub API:

``` ruby
require 'travis'
require 'travis/tools/github'

# drop_token will make the token a temporary one
github = Travis::Tools::Github.new(drop_token: true) do |g|
g.ask_login = -> { print("GitHub login: "); gets }
g.ask_password = -> { print("Password: "); gets }
g.ask_otp = -> { print("Two-factor token: "); gets }
end

github.with_token do |token|
Travis.github_auth(token)
end

puts "Hello #{Travis::User.current.name}!"
```

There is also `travis/auto_login`, which will try to read the CLI configuration or .netrc for a Travis CI or GitHub token to authenticate with automatically:

``` ruby
Expand Down Expand Up @@ -2027,7 +1996,7 @@ See also [Note on Ubuntu](#ubuntu) below.
For Ruby 2.3.x, be sure to have a compatible version of `faraday` installed; e.g.,
$ gem install faraday -v 1.0.1
### Development Version
You can also install the development version via RubyGems:
Expand Down
8 changes: 4 additions & 4 deletions examples/pro_auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
require 'travis/tools/github'
require 'highline/import' # so we can hide the password

github_token = ask("GitHub token: ")

# Set up GitHub tool for doing the login handshake.
github = Travis::Tools::Github.new(drop_token: true) do |g|
g.ask_login = -> { ask("GitHub login: ") }
g.ask_password = -> { ask("Password: ") { |q| q.echo = "*" } }
g.ask_otp = -> { ask("Two-factor token: ") }
g.github_token = github_token
end

# Create temporary GitHub token and use it to authenticate against Travis CI.
Expand All @@ -16,7 +16,7 @@

# Look up the current user.
user = Travis::Pro::User.current
puts "Hello #{user.name}!"
puts "Hello #{user.login}!"

# Display repositories the user is a member of.
repos = Travis::Pro::Repository.find_all(member: user.login)
Expand Down
19 changes: 3 additions & 16 deletions lib/travis/cli/login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ class Login < ApiCommand
description "authenticates against the API and stores the token"
on('-g', '--github-token TOKEN', 'identify by GitHub token')
on('-T', '--auto-token', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)')
on('-p', '--auto-password', 'try to load password from OSX keychain (will not be stored)')
on('-a', '--auto', 'shorthand for --auto-token --auto-password') { |c| c.auto_token = c.auto_password = true }
on('-u', '--user LOGIN', 'user to log in as') { |c,n| c.user_login = n }
on('-M', '--no-manual', 'do not use interactive login')
on('--list-github-token', 'instead of actually logging in, list found GitHub tokens')
on('--skip-token-check', 'don\'t verify the token with github')

Expand Down Expand Up @@ -55,17 +51,11 @@ def github
load_gh
Tools::Github.new(session.config['github']) do |g|
g.note = "temporary token to identify with the travis command line client against #{api_endpoint}"
g.manual_login = no_manual.nil?
g.explode = explode?
g.github_token = github_token
g.auto_token = auto_token
g.auto_password = auto_password
g.github_login = user_login
g.check_token = !skip_token_check?
g.drop_token = !list_github_token
g.ask_login = proc { ask("Username: ") }
g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
g.login_header = proc { login_header }
g.debug = proc { |log| debug(log) }
g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
Expand All @@ -74,12 +64,9 @@ def github
end

def login_header
say "We need your #{color("GitHub login", :important)} to identify you."
say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
say "The password will not be displayed."
empty_line
say "Try running with #{color("--github-token", :info)} or #{color("--auto", :info)} if you don't want to enter your password anyway."
empty_line
say "GitHub deprecated its Authorizations API exchanging a password for a token."
say "Please visit https://github.blog/2020-07-30-token-authentication-requirements-for-api-and-git-operations for more information."
say "Try running with #{color("--github-token", :info)} or #{color("--auto-token", :info)} ."
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/travis/cli/repo_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module CLI
class RepoCommand < ApiCommand
GIT_REGEX = %r{/?(.*/.+?)(\.git)?$}
TRAVIS = %r{^https://(staging-)?api\.travis-ci\.(org|com)}
on('-g', '--github-token TOKEN', 'identify by GitHub token')
on('-r', '--repo SLUG', 'repository to use (will try to detect from current git clone)') do |c, slug|
c.slug = slug
c.error "SLUG should be of the form OWNER/REPO" unless slug.split('/').compact.size == 2
Expand Down
10 changes: 6 additions & 4 deletions lib/travis/cli/setup/releases.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class Releases < Service
def run
deploy 'releases' do |config|
github.with_token { |t| config['api_key'] = t }
if config['api_key'].nil?
raise Travis::Client::GitHubLoginFailed, 'all GitHub tokens given were invalid'
end

config['file'] = ask("File to Upload: ").to_s
end
end
Expand All @@ -19,9 +23,7 @@ def github
load_gh
Tools::Github.new(session.config['github']) do |g|
g.drop_token = false
g.ask_login = proc { ask("Username: ") }
g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
g.github_token = github_token
g.debug = proc { |log| debug(log) }
g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
g.scopes = org? ? ['public_repo'] : ['repo']
Expand All @@ -32,4 +34,4 @@ def github
end
end
end
end
end
53 changes: 29 additions & 24 deletions lib/travis/cli/sshkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Sshkey < RepoCommand
on '-c', '--check', 'set exit code depending on key existing'
on '-g', '--generate', 'generate SSH key and set up for given GitHub user'
on '-p', '--passphrase PASSPHRASE', 'pass phrase to decrypt with when using --upload'
on '-g', '--github-token TOKEN', 'identify by GitHub token'

def_delegators :repository, :ssh_key

Expand Down Expand Up @@ -51,27 +52,34 @@ def delete_key
end

def generate_key
github.with_basic_auth do |gh|
login = gh['user']['login']
check_access(gh)
empty_line
access_token = nil
github.with_token do |token|
access_token = github_auth(token)
end
session.access_token = nil
unless access_token
raise Travis::Client::GitHubLoginFailed, "all GitHub tokens given were invalid"
end
gh = GH.with(token: github_token)
login = gh['user']['login']
check_access(gh)
empty_line

say "Generating RSA key."
private_key = Tools::SSLKey.generate_rsa
self.description ||= "key for fetching dependencies for #{slug} via #{login}"
say "Generating RSA key."
private_key = Tools::SSLKey.generate_rsa
self.description ||= "key for fetching dependencies for #{slug} via #{login}"

say "Uploading public key to GitHub."
gh.post("/user/keys", :title => "#{description} (Travis CI)", :key => Tools::SSLKey.rsa_ssh(private_key.public_key))
say "Uploading public key to GitHub."
gh.post("/user/keys", :title => "#{description} (Travis CI)", :key => Tools::SSLKey.rsa_ssh(private_key.public_key))

say "Uploading private key to Travis CI."
ssh_key.update(:value => private_key.to_s, :description => description)
say "Uploading private key to Travis CI."
ssh_key.update(:value => private_key.to_s, :description => description)

empty_line
say "You can store the private key to reuse it for other repositories (travis sshkey --upload FILE)."
if agree("Store private key? ") { |q| q.default = "no" }
path = ask("Path: ") { |q| q.default = "id_travis_rsa" }
File.write(path, private_key.to_s)
end
empty_line
say "You can store the private key to reuse it for other repositories (travis sshkey --upload FILE)."
if agree("Store private key? ") { |q| q.default = "no" }
path = ask("Path: ") { |q| q.default = "id_travis_rsa" }
File.write(path, private_key.to_s)
end
end

Expand All @@ -97,9 +105,7 @@ def github
Tools::Github.new(session.config['github']) do |g|
g.note = "token for fetching dependencies for #{slug} (Travis CI)"
g.explode = explode?
g.ask_login = proc { ask("Username: ") }
g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
g.github_token = github_token
g.login_header = proc { login_header }
g.debug = proc { |log| debug(log) }
g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
Expand All @@ -108,10 +114,9 @@ def github
end

def login_header
say "We need the #{color("GitHub login", :important)} for the account you want to add the key to."
say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
say "The password will not be displayed."
empty_line
say "GitHub deprecated its Authorizations API exchanging a password for a token."
say "Please visit https://github.blog/2020-07-30-token-authentication-requirements-for-api-and-git-operations for more information."
say "Try running with #{color("--github-token", :info)} or #{color("--auto-token", :info)} ."
end
end
end
Expand Down
1 change: 0 additions & 1 deletion lib/travis/client/auto_login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ def authenticate
def github
@github ||= Tools::Github.new(session.config['github']) do |g|
g.explode = true
g.manual_login = false
g.auto_token = @auto_token
g.after_tokens = proc { raise NoTokenError, "no suitable github token found" } if @raise
end
Expand Down
Loading

0 comments on commit a166798

Please sign in to comment.