class Donjon::Configurator

Public Class Methods

new(settings:) click to toggle source
# File lib/donjon/configurator.rb, line 7
def initialize(settings:)
  @settings = settings
end

Public Instance Methods

run() click to toggle source
# File lib/donjon/configurator.rb, line 11
def run
  _get_name
  _get_repo
  _get_private_key_path
  _save_user
  _thank_user if changes?
  nil
end

Private Instance Methods

_check_key(path, password = nil) click to toggle source
# File lib/donjon/configurator.rb, line 95
def _check_key(path, password = nil)
  unless _is_key_encrypted?(path)
    _shell.say 'That key is not password-protected. Sorry, I\' not taking that risk!', :red
    exit 1
  end

  if password.nil?
    _shell.say "I'll now try to load your private key.", :green
    _shell.say "Please enter your key password (I won't store it anywhere)", :green
    $stdout.write "> "
    $stdout.flush
    password = $stdin.get_password
  end

  key = OpenSSL::PKey::RSA.new(path.read, password)
  if key.n.num_bits != 2_048
    _shell.say "Sorry, that key isn't 2,048 bits long.", :red
    exit 1
  end

  _shell.say "Okay, that key seems valid.", :green
  OpenStruct.new key: key.public_key, path: path
end
_default_name() click to toggle source
# File lib/donjon/configurator.rb, line 158
def _default_name
  ENV['USER'] || ENV['LOGNAME']
end
_get_existing_key() click to toggle source
# File lib/donjon/configurator.rb, line 82
def _get_existing_key
  _shell.say('What is the path to your key? [~/.ssh/id_rsa]', :green)
  ans = _shell.ask('>')
  ans = '~/.ssh/id_rsa' if ans.empty?
  path = Pathname.new(ans).expand_path
  if !path.exist?
    _shell.say 'Sorry, cannot find that file.', :red
    exit 1
  end
  _check_key(path)
end
_get_key_path() click to toggle source
# File lib/donjon/configurator.rb, line 61
def _get_key_path
  @_key_path ||= begin
    _shell.say [
      'Do you want to use an existing private key or create one?',
      'If you use an existing key, it needs to be an encrypted, 2048-bit RSA key.',
      'Use [e]xisting or [c]reate?',
    ].join("\n"), :green
    ans = _shell.ask('>')

    case ans
    when /[Ee]/
      _get_existing_key
    when /[Cc]/
      _get_new_key
    else
      _shell.say 'No idea what you mean, sorry.', :red
      exit 1
    end
  end
end
_get_name() click to toggle source
# File lib/donjon/configurator.rb, line 45
def _get_name
  @settings.user_name ||= begin
    changes!
    _shell.say "Hi! How do you want to be called? [#{_default_name}]", :green
    ans = _shell.ask '>'
    ans.empty? ? _default_name : ans
  end
end
_get_new_key() click to toggle source
# File lib/donjon/configurator.rb, line 119
def _get_new_key
  _shell.say "Where do you want to store your new key? [~/.ssh/donjon_rsa]", :green
  ans = _shell.ask('>')
  ans = '~/.ssh/donjon_rsa' if ans.empty?
  path = Pathname.new(ans).expand_path

  _shell.say "Please enter a password for your new key (I won't store it anywhere)", :green
  $stdout.write "> "
  $stdout.flush
  password = $stdin.get_password
  
  command = "ssh-keygen -q -t rsa -b 2048 -N '#{password}' -f #{path}"
  unless system(command)
    _shell.say "Sorry, key generation failed!", :red
    exit 1
  end

  _check_key(path, password)
end
_get_private_key_path() click to toggle source
# File lib/donjon/configurator.rb, line 54
def _get_private_key_path
  @settings.private_key ||= begin
    changes!
    _get_key_path.path.to_s
  end
end
_get_repo() click to toggle source
# File lib/donjon/configurator.rb, line 34
def _get_repo
  path = @settings.vault_path ||= begin
    changes!
    _shell.say "Where do you want your vault? [~/.donjon]", :green
    ans = _shell.ask('>')
    ans = '~/.donjon' if ans.empty?
    Pathname.new(ans).expand_path.to_s
  end
  Donjon::Repository.new(path)
end
_is_key_encrypted?(path) click to toggle source
# File lib/donjon/configurator.rb, line 151
def _is_key_encrypted?(path)
  OpenSSL::PKey::RSA.new(path.read, '')
  return false
rescue OpenSSL::PKey::RSAError
  return true
end
_save_user() click to toggle source
# File lib/donjon/configurator.rb, line 139
def _save_user
  if user = User.find(repo: _get_repo, name: _get_name)
    if user.key.to_pem.strip != _get_key_path.key.to_pem.strip
      _shell.say "There's already a user with your name in the vault, and the public keys don't match. I'm afraid I'm a bit stumped.", :red
      exit 1
    end
    return
  end
  User.new(name: _get_name, repo: _get_repo, key: _get_key_path.key).save
  nil
end
_shell() click to toggle source
# File lib/donjon/configurator.rb, line 162
def _shell
  Shell.instance
end
_thank_user() click to toggle source
# File lib/donjon/configurator.rb, line 30
def _thank_user
  _shell.say "Thanks! All your settings are saved.", [:green, :bold]
end
changes!() click to toggle source
# File lib/donjon/configurator.rb, line 26
def changes!
  @changes = true
end
changes?() click to toggle source
# File lib/donjon/configurator.rb, line 22
def changes?
  !!@changes
end