lib/github/auth/cli.rb
require 'thor'
module GitHub::Auth
# Command Line Interface for parsing and executing commands
class CLI < Thor
class_option :host, type: :string
class_option :path, type: :string
option :users, type: :array, required: true
option :command, type: :string
desc 'add', 'Add GitHub users to authorized keys'
long_desc <<-LONGDESC
`gh-auth add` is used to add one or more GitHub user's public SSH keys
to ~/.ssh/authorized_keys. All keys stored on github.com for that
user will be added.
> $ gh-auth add --users=chrishunt zachmargolis
\x5> Adding 6 key(s) to '/Users/chris/.ssh/authorized_keys'
By default, users will be granted normal shell access. If you'd like to
specify an ssh command that should execute when the user connects, use
the `--command` option.
> $ gh-auth add --users=chrishunt --command="tmux attach"
LONGDESC
def add
on_keys_file :write!,
"Adding #{keys.count} key(s) to '#{keys_file.path}'",
{ command: options[:command] }
end
option :users, type: :array, required: true
desc 'remove', 'Remove GitHub users from authorized keys'
long_desc <<-LONGDESC
`gh-auth remove` is used to remove one or more GitHub user's public SSH
keys from ~/.ssh/authorized_keys. All keys stored on github.com for
that user will be removed.
> $ gh-auth remove --users=chrishunt zachmargolis
\x5> Removing 6 key(s) to '/Users/chris/.ssh/authorized_keys'
LONGDESC
def remove
on_keys_file :delete!,
"Removing #{keys.count} key(s) from '#{keys_file.path}'"
end
desc 'list', 'List all GitHub users already added to authorized keys'
long_desc <<-LONGDESC
`gh-auth list` will list all GitHub users that have been added to
~/.ssh/authorized_keys by `gh-auth`.
> $ gh-auth list
\x5> chrishunt, zachmargolis
LONGDESC
def list
rescue_keys_file_errors { puts keys_file.github_users.join(' ') }
end
desc 'version', 'Show gh-auth version'
def version
puts GitHub::Auth::VERSION
end
private
def keys
@keys ||= begin
Array(options[:users]).map { |user| keys_for user }.flatten.compact
end
end
def on_keys_file(action, message, options = {})
puts message
rescue_keys_file_errors { keys_file(options).send action, keys }
end
def rescue_keys_file_errors
yield
rescue KeysFile::PermissionDeniedError
puts 'Permission denied!'
puts
puts "Make sure you have write permissions for '#{keys_file.path}'"
rescue KeysFile::FileDoesNotExistError
puts "Keys file does not exist!"
puts
puts "Create one now and try again:"
puts
puts " $ touch #{keys_file.path}"
end
def keys_for(username)
GitHub::Auth::KeysClient.new(
hostname: github_hostname,
username: username
).keys
rescue GitHub::Auth::KeysClient::GitHubUserDoesNotExistError
puts "GitHub user '#{username}' does not exist"
rescue GitHub::Auth::KeysClient::GitHubUnavailableError
puts "GitHub appears to be unavailable :("
puts
puts "https://status.github.com"
end
def keys_file(options = {})
GitHub::Auth::KeysFile.new \
options.merge path: keys_file_path
end
def keys_file_path
options[:path] || GitHub::Auth::KeysFile::DEFAULT_PATH
end
def github_hostname
options[:host] || GitHub::Auth::KeysClient::DEFAULT_HOSTNAME
end
end
end