Class: Shhh::App::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/shhh/app/cli.rb

Overview

This is the main interface class for the CLI application. It is responsible for parsing user's input, providing help, examples, coordination of various sub-systems (such as PrivateKey detection), etc.

Besides holding the majority of the application state, it contains two primary public methods: #new and #run.

The constructor is responsible for parsing the flags and determining the the application is about to do. It sets up input/output, but doesn't really execute any encryption or decryption. This happens in the #run method called immediately after #new.

{Shh{Shh::App{Shh::App::CLI} module effectively performs the translation of the opts object (of type Slop::Result) and interpretation of users intentions. It holds on to opts for the duration of the program.

Responsibility Delegated

The responsibility of determining the private key from various options provided is performed by the PrivateKey::Handler instance. See there for more details.

Subsequently, #run method handles the finding of the appropriate Shhh::App::Commands::Command subclass to respond to user's request. Command registry, sorting, command dependencies, and finding them is done by the Coommands module.

User input is handled by the Input::Handler instance, while the output is provided by the procs in the Output classes.

Finally, the Mac OS-X -specific usage of the KeyChain, is encapsulated in a cross-platform way inside the Keychain module.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ CLI


56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/shhh/app/cli.rb', line 56

def initialize(argv)
  begin
    self.opts = parse(argv.dup)
  rescue StandardError => e
    error exception: e
    return
  end
  configure_color(argv)
  select_output_stream

  initialize_input_handler
  initialize_key_handler
  self.action        = { opts[:encrypt] => :encr, opts[:decrypt] => :decr }[true]
end

Instance Attribute Details

#actionObject

Returns the value of attribute action


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def action
  @action
end

#input_handlerObject

Returns the value of attribute input_handler


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def input_handler
  @input_handler
end

#keyObject

Returns the value of attribute key


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def key
  @key
end

#key_handlerObject

Returns the value of attribute key_handler


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def key_handler
  @key_handler
end

#optsObject

Returns the value of attribute opts


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def opts
  @opts
end

#output_procObject

Returns the value of attribute output_proc


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def output_proc
  @output_proc
end

#passwordObject

Returns the value of attribute password


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def password
  @password
end

Returns the value of attribute print_proc


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def print_proc
  @print_proc
end

#write_procObject

Returns the value of attribute write_proc


53
54
55
# File 'lib/shhh/app/cli.rb', line 53

def write_proc
  @write_proc
end

Instance Method Details

#commandObject


120
121
122
123
# File 'lib/shhh/app/cli.rb', line 120

def command
  @command_class ||= Shhh::App::Commands.find_command_class(opts)
  @command       ||= @command_class.new(self) if @command_class
end

#editorObject


116
117
118
# File 'lib/shhh/app/cli.rb', line 116

def editor
  ENV['EDITOR'] || '/bin/vi'
end

#error(hash) ⇒ Object


112
113
114
# File 'lib/shhh/app/cli.rb', line 112

def error(hash)
  Shhh::App.error(hash.merge(config: (opts ? opts.to_hash : {})))
end

#runObject


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/shhh/app/cli.rb', line 71

def run
  return Shhh::App.exit_code if Shhh::App.exit_code != 0
  unless opts[:generate]
    self.key = PrivateKey::Handler.new(opts,
                                       input_handler).key
  end

  if command
    result = command.run
    output_proc.call(result)
  else
    # command was not found. Reset output to printing, and return an error.
    self.output_proc = print_proc
    command_not_found_error!
  end

rescue ::OpenSSL::Cipher::CipherError => e
  error type:      'Cipher Error',
        details:   e.message,
        reason:    'Perhaps either the secret is invalid, or encrypted data is corrupt.',
        exception: e

rescue Shhh::Errors::InvalidEncodingPrivateKey => e
  error type:      'Private Key Error',
        details:   'Private key does not appear to be properly encoded. ',
        reason:    (opts[:password] ? nil : 'Perhaps the key is password-protected?'),
        exception: e

rescue Shhh::Errors::InvalidPasswordPrivateKey => e
  error type:      'Error',
        details:   'Invalid password, private key can not decrypted.'

rescue Shhh::Errors::Error => e
  error type:      'Error',
        details:   e.message,
        exception: e

rescue StandardError => e
  error exception: e
end