class Travis::CLI::Sshkey

def check_access(gh)

def check_access(gh)
  gh["repos/#{slug}"]
rescue GH::Error
  error "GitHub account has no read access to #{color slug, :bold}"
end

def delete_key

def delete_key
  return if interactive? && !danger_zone?("Remove SSH key for #{color slug, :info}?")
  say "Removing ssh key for #{color slug, :info}"
  ssh_key.delete
rescue Travis::Client::NotFound
  warn 'no key found to remove'
end

def display_key

def display_key
  say "Current SSH key: #{color(ssh_key.description, :info)}"
  say "Finger print:    #{color(ssh_key.fingerprint, :info)}"
rescue Travis::Client::NotFound
  say 'No custom SSH key installed.'
  exit 1 if check?
end

def generate_key

def generate_key
  access_token = nil
  github.with_token do |token|
    access_token = github_auth(token)
  end
  raise Travis::Client::GitHubLoginFailed, 'all GitHub tokens given were invalid' unless access_token
  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 '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:)
  empty_line
  say 'You can store the private key to reuse it for other repositories (travis sshkey --upload FILE).'
  return unless 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

def github

def github
  @github ||= begin
    load_gh
    Tools::Github.new(session.config['github']) do |g|
      g.note          = "token for fetching dependencies for #{slug} (Travis CI)"
      g.explode       = explode?
      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') }
    end
  end
end

def login_header

def login_header
  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

def remove_passphrase(value)

def remove_passphrase(value)
  return value unless Tools::SSLKey.has_passphrase? value
  return Tools::SSLKey.remove_passphrase(value, passphrase) || error('wrong pass phrase') if passphrase
  error 'Key is encrypted, but missing --passphrase option' unless interactive?
  say 'The private key is protected by a pass phrase.'
  result = Tools::SSLKey.remove_passphrase(value, ask('Enter pass phrase: ') { |q| q.echo = '*' }) until result
  empty_line
  result
end

def run

def run
  delete_key                            if delete?
  update_key File.read(upload), upload  if upload?
  update_key $stdin.read, 'stdin'       if stdin?
  generate_key                          if generate?
  display_key
end

def update_key(value, file)

def update_key(value, file)
  error "#{file} does not look like a private key" unless value.lines.first =~ /PRIVATE KEY/
  value = remove_passphrase(value)
  self.description ||= ask('Key description: ') { |q| q.default = 'Custom Key' } if interactive?
  say "Updating ssh key for #{color slug, :info} with key from #{color file, :info}"
  empty_line
  ssh_key.update(value:, description: description || file)
end