sym 2.8.5 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +19 -12
  3. data/.envrc +7 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +150 -928
  6. data/.travis.yml +16 -28
  7. data/CHANGELOG.md +201 -174
  8. data/Gemfile +1 -0
  9. data/README.adoc +650 -0
  10. data/Rakefile +6 -2
  11. data/codecov.yml +29 -0
  12. data/exe/keychain +1 -1
  13. data/exe/sym +5 -2
  14. data/lib/ruby_warnings.rb +7 -0
  15. data/lib/sym.rb +1 -7
  16. data/lib/sym/app.rb +1 -1
  17. data/lib/sym/app/args.rb +3 -2
  18. data/lib/sym/app/cli.rb +1 -2
  19. data/lib/sym/app/cli_slop.rb +1 -1
  20. data/lib/sym/app/commands.rb +1 -1
  21. data/lib/sym/app/commands/base_command.rb +1 -1
  22. data/lib/sym/app/commands/bash_completion.rb +2 -2
  23. data/lib/sym/app/commands/open_editor.rb +1 -1
  24. data/lib/sym/app/commands/password_protect_key.rb +4 -4
  25. data/lib/sym/app/commands/show_examples.rb +1 -1
  26. data/lib/sym/app/keychain.rb +15 -9
  27. data/lib/sym/app/output/noop.rb +2 -1
  28. data/lib/sym/app/password/cache.rb +1 -1
  29. data/lib/sym/app/password/providers.rb +2 -3
  30. data/lib/sym/app/private_key/decryptor.rb +2 -2
  31. data/lib/sym/app/private_key/detector.rb +4 -7
  32. data/lib/sym/application.rb +5 -10
  33. data/lib/sym/constants.rb +4 -4
  34. data/lib/sym/data/wrapper_struct.rb +20 -12
  35. data/lib/sym/errors.rb +11 -2
  36. data/lib/sym/extensions/instance_methods.rb +7 -8
  37. data/lib/sym/extensions/stdlib.rb +0 -1
  38. data/lib/sym/extensions/with_retry.rb +1 -1
  39. data/lib/sym/extensions/with_timeout.rb +1 -1
  40. data/lib/sym/version.rb +30 -5
  41. data/sym.gemspec +35 -35
  42. metadata +86 -68
  43. data/README.md +0 -620
  44. data/lib/sym/app/password/providers/drb_provider.rb +0 -41
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
  require 'yard'
4
5
  require 'timeout'
5
6
 
@@ -25,14 +26,17 @@ task :build => :permissions
25
26
 
26
27
  YARD::Rake::YardocTask.new(:doc) do |t|
27
28
  t.files = %w(lib/**/*.rb exe/*.rb - README.md LICENSE)
28
- t.options.unshift('--title','"Sym – Symmetric Key Encryption for Your Data"')
29
- t.after = ->() { exec('open doc/index.html') }
29
+ t.options.unshift('--title', '"Sym – Symmetric Key Encryption for Your Data"')
30
+ t.after = -> { exec('open doc/index.html') }
30
31
  end
31
32
 
32
33
  RSpec::Core::RakeTask.new(:spec)
33
34
 
35
+ RuboCop::RakeTask.new
36
+
34
37
  task :default => :spec
35
38
 
36
39
 
37
40
 
38
41
 
42
+
@@ -0,0 +1,29 @@
1
+ codecov:
2
+ require_ci_to_pass: no
3
+
4
+ notify:
5
+ wait_for_ci: yes
6
+
7
+ parsers:
8
+ v1:
9
+ include_full_missed_files: true # To use with Ruby so we see files that have NO tests written
10
+
11
+ coverage:
12
+ range: 50..75
13
+ round: down
14
+ precision: 1
15
+ status:
16
+ project:
17
+ default: off
18
+ sym:
19
+ target: 70%
20
+ threshold: 10%
21
+ informational: true
22
+ if_not_found: success
23
+ if_ci_failed: error
24
+ paths:
25
+ - lib/
26
+ flags:
27
+ sym:
28
+ paths:
29
+ - lib/
@@ -32,7 +32,7 @@ puts data ? \
32
32
  Sym::App::KeyChain.new(key_name).send(action.to_sym, data) :
33
33
  Sym::App::KeyChain.new(key_name).send(action.to_sym)
34
34
  rescue StandardError => e
35
- STDERR.puts "#{e.message.red}"
35
+ warn "#{e.message.red}"
36
36
  end
37
37
 
38
38
 
data/exe/sym CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+ # vim: ft=ruby
3
+
4
+ require_relative '../lib/ruby_warnings'
2
5
 
3
6
  lib_path = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
7
  $LOAD_PATH << lib_path if File.exist?(lib_path) && !$LOAD_PATH.include?(lib_path)
@@ -6,12 +9,12 @@ $LOAD_PATH << lib_path if File.exist?(lib_path) && !$LOAD_PATH.include?(lib_path
6
9
  require 'sym'
7
10
  require 'sym/app'
8
11
 
9
- #ARGV.any?{ |a| a =~ /^-/ } ?
12
+ # ARGV.any?{ |a| a =~ /^-/ } ?
10
13
  begin
11
14
  exit ::Sym::App::CLI.new(ARGV.dup).execute
12
15
  rescue Interrupt => e
13
16
  STDERR.flush
14
- STDERR.puts "Interrupt, #{e.message}, exiting."
17
+ warn "Interrupt, #{e.message}, exiting."
15
18
  STDERR.flush
16
19
  exit 1
17
20
  end
@@ -0,0 +1,7 @@
1
+ ruby_version = RbConfig::CONFIG['MAJOR'].to_i * 10 + RbConfig::CONFIG['MINOR'].to_i
2
+ if ruby_version >= 27
3
+ Warning[:deprecated] = false
4
+ ENV['RUBYOPT'] = '-W:no-deprecated'
5
+ else
6
+ ENV['RUBYOPT']="-W0"
7
+ end
data/lib/sym.rb CHANGED
@@ -21,17 +21,11 @@ Sym::Configuration.configure do |config|
21
21
  # When nil is selected, providers are auto-detected.
22
22
  config.password_cache_default_provider = nil
23
23
  config.password_cache_arguments = {
24
- drb: {
25
- opts: {
26
- uri: 'druby://127.0.0.1:24924'
27
- }
28
- },
29
24
  memcached: {
30
25
  args: %w(127.0.0.1:11211),
31
26
  opts: { namespace: 'sym',
32
27
  compress: true,
33
- expires_in: config.password_cache_timeout
34
- }
28
+ expires_in: config.password_cache_timeout}
35
29
 
36
30
  }
37
31
  }
@@ -66,7 +66,7 @@ module Sym
66
66
  self.exit_code = 1
67
67
  end
68
68
 
69
- def self.is_osx?
69
+ def self.osx?
70
70
  Gem::Platform.local.os.eql?('darwin')
71
71
  end
72
72
 
@@ -12,7 +12,7 @@ module Sym
12
12
 
13
13
  def initialize(opts)
14
14
  self.opts = opts
15
- self.selected_options = opts.keys.reject { |k| !opts[k] }
15
+ self.selected_options = opts.keys.select { |k| opts[k] }
16
16
  end
17
17
 
18
18
  def specify_key?
@@ -33,10 +33,11 @@ module Sym
33
33
  end
34
34
 
35
35
  def provided_options
36
- opts.to_hash.keys.reject { |k| !opts[k] }
36
+ opts.to_hash.keys.select { |k| opts[k] }
37
37
  end
38
38
 
39
39
  private
40
+
40
41
  def do?(list)
41
42
  !(list & selected_options).empty?
42
43
  end
@@ -60,7 +60,6 @@ module Sym
60
60
 
61
61
 
62
62
  def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = nil)
63
-
64
63
  self.stdin = stdin
65
64
  self.stdout = stdout
66
65
  self.stderr = stderr
@@ -140,7 +139,7 @@ module Sym
140
139
  private
141
140
 
142
141
  def log(*args)
143
- Sym::App.log(*args, **(opts.to_hash))
142
+ Sym::App.log(*args, **opts.to_hash)
144
143
  end
145
144
 
146
145
  def error(hash)
@@ -55,7 +55,7 @@ module Sym
55
55
  o.separator 'Create a new private key:'.yellow
56
56
  o.bool '-g', '--generate', ' generate a new private key'
57
57
  o.bool '-p', '--password', ' encrypt the key with a password'
58
- if Sym::App.is_osx?
58
+ if Sym::App.osx?
59
59
  o.string '-x', '--keychain', '[key-name] '.blue + 'write the key to OS-X Keychain'
60
60
  end
61
61
 
@@ -37,7 +37,7 @@ module Sym
37
37
  # Sort commands based on the #dependencies array, which itself is sorted
38
38
  # based on command dependencies.
39
39
  def sorted_commands
40
- @sorted_commands ||= self.commands.to_a.sort_by{|klass| dependencies.index(klass.short_name) }
40
+ @sorted_commands ||= self.commands.to_a.sort_by{ |klass| dependencies.index(klass.short_name) }
41
41
  @sorted_commands
42
42
  end
43
43
 
@@ -73,7 +73,7 @@ module Sym
73
73
  end
74
74
 
75
75
  def add_to_keychain_if_needed(key)
76
- if opts[:keychain] && Sym::App.is_osx?
76
+ if opts[:keychain] && Sym::App.osx?
77
77
  Sym::App::KeyChain.new(opts[:keychain], opts).add(key)
78
78
  else
79
79
  key
@@ -15,7 +15,7 @@ module Sym
15
15
  file = opts[:bash_support]
16
16
 
17
17
  out = ''
18
- Sym::Constants::Bash::Config.each_pair do |key, config|
18
+ Sym::Constants::Bash::CONFIG.each_pair do |key, config|
19
19
  script_name = key.to_s
20
20
 
21
21
  # This removes the old version of this file.
@@ -43,7 +43,7 @@ module Sym
43
43
  out << "\nPlease reload your terminal session to activate bash completion\n"
44
44
  out << "and other installed BASH utilities.\n"
45
45
  out << "\nAlternatively, just type #{"source #{file}".bold.green} to reload BASH.\n"
46
- out << "Also — go ahead and try running #{"sym -h".bold.blue} and #{"symit -h".bold.blue}.\n"
46
+ out << "Also — go ahead and try running #{'sym -h'.bold.blue} and #{'symit -h'.bold.blue}.\n"
47
47
  end
48
48
 
49
49
  private
@@ -48,7 +48,7 @@ module Sym
48
48
  end
49
49
 
50
50
  def timestamp
51
- @timestamp ||= Time.now.to_a.select { |d| d.is_a?(Fixnum) }.map { |d| '%02d' % d }[0..-3].reverse.join
51
+ @timestamp ||= Time.now.to_a.select { |d| d.is_a?(Integer) }.map { |d| '%02d' % d }[0..-3].reverse.join
52
52
  end
53
53
 
54
54
  def process(code)
@@ -16,10 +16,10 @@ module Sym
16
16
  the_key = self.key
17
17
 
18
18
  if opts[:password]
19
- encrypted_key, password = encrypt_with_password(the_key)
20
- add_password_to_the_cache(encrypted_key, password)
21
- the_key = encrypted_key
22
- end
19
+ encrypted_key, password = encrypt_with_password(the_key)
20
+ add_password_to_the_cache(encrypted_key, password)
21
+ the_key = encrypted_key
22
+ end
23
23
 
24
24
  add_to_keychain_if_needed(the_key)
25
25
 
@@ -56,7 +56,7 @@ Diff:
56
56
  # (c) 2016 Konstantin Gredeskoul. All rights reserved.'.green.bold)
57
57
 
58
58
 
59
- if Sym::App.is_osx?
59
+ if Sym::App.osx?
60
60
  output << example(comment: 'generate a new password-encrypted key, save it to your Keychain:',
61
61
  command: 'sym -gpcx staging.key')
62
62
 
@@ -39,11 +39,13 @@ module Sym
39
39
  self.key_name = key_name
40
40
  self.opts = opts
41
41
  self.class.validate!
42
- stderr_off
42
+ opts[:trace] ? stderr_on : stderr_off
43
43
  end
44
44
 
45
45
  def add(password)
46
- execute command(:add, "-U -w '#{password}' ")
46
+ delete rescue nil
47
+ sleep 0.1
48
+ execute command(:add, " -T /usr/bin/security -w '#{password}' ")
47
49
  end
48
50
 
49
51
  def find
@@ -56,10 +58,14 @@ module Sym
56
58
 
57
59
  def execute(command)
58
60
  command += ' 2>/dev/null' if stderr_disabled
59
- puts "> #{command.yellow.green}" if opts[:verbose]
61
+ puts "> #{command.yellow}" if opts[:verbose]
60
62
  output = `#{command}`
61
63
  result = $?
62
- raise Sym::Errors::KeyChainCommandError.new("Command error: #{result}, command: #{command}") unless result.success?
64
+ unless result.success?
65
+ warn "> ERROR running command:\n> $ #{output.red}" if !stderr_disabled && opts[:verbose]
66
+ raise Sym::Errors::KeyChainCommandError.new("Command error: #{result}, command: #{command}")
67
+ end
68
+
63
69
  output.chomp
64
70
  rescue Errno::ENOENT => e
65
71
  raise Sym::Errors::KeyChainCommandError.new("Command error: #{e.message}, command: #{command}")
@@ -80,16 +86,16 @@ module Sym
80
86
  out << extras if extras
81
87
  out = out.join
82
88
  # Do not actually ever run these commands on non MacOSX
83
- out = "echo Run this –\"#{out}\", on #{Sym::App.this_os}?\nAre you sure?" unless Sym::App.is_osx?
89
+ out = "echo Run this –\"#{out}\", on #{Sym::App.this_os}?\nAre you sure?" unless Sym::App.osx?
84
90
  out
85
91
  end
86
92
 
87
93
  def base_command(action)
88
94
  [
89
- "security #{action}-#{self.class.sub_section} ",
90
- "-a '#{self.class.user}' ",
91
- "-D '#{self.class.kind}' ",
92
- "-s '#{self.key_name}' "
95
+ "/usr/bin/security #{action}-#{self.class.sub_section} ",
96
+ "-a #{self.class.user} ",
97
+ "-D #{self.class.kind} ",
98
+ "-s #{self.key_name} "
93
99
  ]
94
100
  end
95
101
  end
@@ -7,7 +7,8 @@ module Sym
7
7
  required_option :quiet
8
8
 
9
9
  def output_proc
10
- ->(*) { ; }
10
+ ->(*) do
11
+ end
11
12
  end
12
13
  end
13
14
  end
@@ -36,7 +36,7 @@ module Sym
36
36
  self.enabled = opts[:enabled]
37
37
  self.verbose = opts[:verbose]
38
38
  self.timeout = opts[:timeout] || ::Sym::Configuration.config.password_cache_timeout
39
- self.provider = Providers.provider(opts[:provider], opts[:provider_opts] || {})
39
+ self.provider = Providers.provider(opts[:provider], **(opts[:provider_opts] || {}))
40
40
  self.enabled = false unless self.provider
41
41
  self
42
42
  end
@@ -15,7 +15,7 @@ module Sym
15
15
  self.providers << provider_class
16
16
  end
17
17
 
18
- # Detect first instance that is "alive?" and return it.
18
+ # Detect first instance tht is "alive?" and return it.
19
19
  def detect
20
20
  self.detected ||= self.providers.inject(nil) do |instance, provider_class|
21
21
  instance || (p = provider_class.new; p.alive? ? p : nil)
@@ -38,7 +38,7 @@ module Sym
38
38
 
39
39
  def provider_from_argument(p, **opts, &block)
40
40
  case p
41
- when String, Symbol
41
+ when String, Symbol
42
42
  provider_class_name = "#{p.to_s.capitalize}Provider"
43
43
  Sym::App::Password::Providers.const_defined?(provider_class_name) ?
44
44
  Sym::App::Password::Providers.const_get(provider_class_name).new(**opts, &block) :
@@ -53,4 +53,3 @@ end
53
53
 
54
54
  # Order is important — they are tried in this order for auto detect
55
55
  require 'sym/app/password/providers/memcached_provider'
56
- require 'sym/app/password/providers/drb_provider'
@@ -31,10 +31,10 @@ module Sym
31
31
  rescue ::OpenSSL::Cipher::CipherError => e
32
32
  input_handler.puts 'Invalid password. Please try again.'
33
33
 
34
- if ((retries += 1) < 3)
34
+ if (retries += 1) < 3
35
35
  retry
36
36
  else
37
- raise(Sym::Errors::InvalidPasswordProvidedForThePrivateKey.new('Invalid password.'))
37
+ raise(Sym::Errors::WrongPasswordForKey.new('Invalid password.'))
38
38
  end
39
39
  end
40
40
  else
@@ -23,11 +23,10 @@ module Sym
23
23
  # procs on a given string.
24
24
  def read!
25
25
  KeySourceCheck::CHECKS.each do |source_check|
26
- if result = source_check.detect(self) rescue nil
27
- if key_ = normalize_key(result.key)
28
- key_source_ = result.to_s
29
- return key_, key_source_
30
- end
26
+ next unless result = source_check.detect(self) rescue nil
27
+ if key_ = normalize_key(result.key)
28
+ key_source_ = result.to_s
29
+ return key_, key_source_
31
30
  end
32
31
  end
33
32
  nil
@@ -51,8 +50,6 @@ module Sym
51
50
  rescue
52
51
  nil
53
52
  end
54
- else
55
- nil
56
53
  end
57
54
  end
58
55
  end
@@ -32,7 +32,6 @@ module Sym
32
32
  :stdin, :stdout, :stderr, :kernel
33
33
 
34
34
  def initialize(opts, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = nil)
35
-
36
35
  self.stdin = stdin
37
36
  self.stdout = stdout
38
37
  self.stderr = stderr
@@ -115,12 +114,8 @@ module Sym
115
114
  end
116
115
 
117
116
  def process_output(result)
118
- unless result.is_a?(Hash)
119
- self.output.call(result)
120
- result
121
- else
122
- result
123
- end
117
+ self.output.call(result) unless result.is_a?(Hash)
118
+ result
124
119
  end
125
120
 
126
121
  private
@@ -182,7 +177,7 @@ module Sym
182
177
  args[:verbose] = opts[:verbose]
183
178
  args[:provider] = opts[:cache_provider] if opts[:cache_provider]
184
179
 
185
- self.password_cache = Sym::App::Password::Cache.instance.configure(args)
180
+ self.password_cache = Sym::App::Password::Cache.instance.configure(**args)
186
181
  end
187
182
 
188
183
  def process_edit_option
@@ -207,7 +202,7 @@ module Sym
207
202
  end
208
203
 
209
204
  def initialize_action
210
- self.action = if opts[:encrypt] then
205
+ self.action = if opts[:encrypt]
211
206
  :encr
212
207
  elsif opts[:decrypt]
213
208
  :decr
@@ -217,7 +212,7 @@ module Sym
217
212
  # If we are encrypting or decrypting, and no data has been provided, check if we
218
213
  # should read from STDIN
219
214
  def initialize_data_source
220
- if self.action && opts[:string].nil? && opts[:file].nil? && !(self.stdin.tty?)
215
+ if self.action && opts[:string].nil? && opts[:file].nil? && !self.stdin.tty?
221
216
  opts[:file] = '-'
222
217
  end
223
218
  end
@@ -5,12 +5,12 @@ module Sym
5
5
 
6
6
  BASH_FILES = Dir.glob("#{File.expand_path('../../../bin', __FILE__)}/sym.*.bash").freeze
7
7
 
8
- Config = {}
8
+ CONFIG = {}
9
9
 
10
10
  class << self
11
11
  def register_bash_files!
12
12
  BASH_FILES.each do |bash_file|
13
- register_bash_extension bash_file, Config
13
+ register_bash_extension bash_file, CONFIG
14
14
  end
15
15
  end
16
16
 
@@ -21,7 +21,7 @@ module Sym
21
21
  home_file = "#{Dir.home}/.#{source_file}"
22
22
 
23
23
  hash[source_file.gsub(/sym\./, '').gsub(/\.bash/, '').to_sym] = {
24
- dest: home_file,
24
+ dest: home_file,
25
25
  source: bash_file,
26
26
  script: "[[ -f #{home_file} ]] && source #{home_file}"
27
27
  }
@@ -37,7 +37,7 @@ module Sym
37
37
  end
38
38
 
39
39
  ENV_ARGS_VARIABLE_NAME = 'SYM_ARGS'.freeze
40
- SYM_KEY_FILE = "#{ENV['HOME']}/.sym.key"
40
+ SYM_KEY_FILE = "#{Dir.home}/.sym.key".freeze
41
41
 
42
42
  end
43
43
  end