sym 2.8.2 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +29 -22
  3. data/.envrc +7 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +158 -920
  6. data/.rubocop_todo.yml +115 -0
  7. data/.travis.yml +16 -26
  8. data/CHANGELOG.md +239 -167
  9. data/Gemfile +1 -0
  10. data/LICENSE +2 -2
  11. data/README.adoc +675 -0
  12. data/README.pdf +29732 -19
  13. data/Rakefile +10 -4
  14. data/bin/changelog +34 -0
  15. data/bin/sym.completion.bash +6 -4
  16. data/codecov.yml +29 -0
  17. data/design/sym-class-dependency-future-refactor.png +0 -0
  18. data/design/sym-class-dependency-vertical.png +0 -0
  19. data/design/sym-class-dependency.graffle +0 -0
  20. data/design/sym-class-dependency.png +0 -0
  21. data/design/sym-help.png +0 -0
  22. data/exe/keychain +3 -3
  23. data/exe/sym +8 -5
  24. data/lib/ruby_warnings.rb +7 -0
  25. data/lib/sym.rb +2 -8
  26. data/lib/sym/app.rb +7 -9
  27. data/lib/sym/app/args.rb +3 -2
  28. data/lib/sym/app/cli.rb +34 -23
  29. data/lib/sym/app/cli_slop.rb +17 -11
  30. data/lib/sym/app/commands.rb +1 -1
  31. data/lib/sym/app/commands/base_command.rb +2 -1
  32. data/lib/sym/app/commands/bash_completion.rb +3 -3
  33. data/lib/sym/app/commands/keychain_add_key.rb +1 -1
  34. data/lib/sym/app/commands/open_editor.rb +1 -1
  35. data/lib/sym/app/commands/password_protect_key.rb +4 -4
  36. data/lib/sym/app/commands/show_examples.rb +6 -6
  37. data/lib/sym/app/input/handler.rb +8 -2
  38. data/lib/sym/app/keychain.rb +15 -9
  39. data/lib/sym/app/output/base.rb +1 -1
  40. data/lib/sym/app/output/noop.rb +2 -1
  41. data/lib/sym/app/password/cache.rb +1 -1
  42. data/lib/sym/app/password/providers.rb +3 -6
  43. data/lib/sym/app/private_key/decryptor.rb +2 -2
  44. data/lib/sym/app/private_key/detector.rb +4 -7
  45. data/lib/sym/app/private_key/key_source_check.rb +2 -3
  46. data/lib/sym/application.rb +9 -14
  47. data/lib/sym/configuration.rb +1 -5
  48. data/lib/sym/constants.rb +40 -24
  49. data/lib/sym/data.rb +2 -2
  50. data/lib/sym/data/wrapper_struct.rb +20 -12
  51. data/lib/sym/errors.rb +13 -2
  52. data/lib/sym/extensions/instance_methods.rb +11 -12
  53. data/lib/sym/extensions/stdlib.rb +2 -3
  54. data/lib/sym/extensions/with_retry.rb +1 -1
  55. data/lib/sym/extensions/with_timeout.rb +1 -1
  56. data/lib/sym/version.rb +54 -5
  57. data/sym.gemspec +38 -35
  58. metadata +132 -66
  59. data/.codeclimate.yml +0 -30
  60. data/README.md +0 -623
  61. data/lib/sym/app/password/providers/drb_provider.rb +0 -41
data/Rakefile CHANGED
@@ -1,7 +1,8 @@
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
 
6
7
  def shell(*args)
7
8
  puts "running: #{args.join(' ')}"
@@ -24,13 +25,18 @@ end
24
25
  task :build => :permissions
25
26
 
26
27
  YARD::Rake::YardocTask.new(:doc) do |t|
27
- 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') }
28
+ t.files = %w(lib/**/*.rb exe/*.rb - README.adoc CHANGELOG.md LICENSE)
29
+ t.options.unshift('--title', '"Sym – Symmetric Encryption for Humins"')
30
+ t.after = -> { Thread.new { sleep 5; 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
 
40
+
41
+
42
+
data/bin/changelog ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+ # vim: ft=bash
3
+ unset DEBUG
4
+
5
+ [[ -d ~/.bashmatic ]] || bash -c "$(curl -fsSL http://bit.ly/bashmatic-1-2-0)"
6
+ source "${HOME}/.bashmatic/init.sh" 1>/dev/null
7
+
8
+ function chlog() {
9
+ run.set-all abort-on-error show-output-on
10
+
11
+ command -v github_changelog_generator >/dev/null || {
12
+ h1 'Installing changelog ruby gem...'
13
+ gem.install github_changelog_generator
14
+ }
15
+
16
+ if [[ -z "${GITHUB_TOKEN}" ]]; then
17
+ error "Please set GITHUB_TOKEN environment variable."
18
+ return 1
19
+ else
20
+ info "GitHub token found, starting CHANGELOG generation..."
21
+ fi
22
+
23
+ run "github_changelog_generator --no-verbose -u kigster -p sym -t ${GITHUB_TOKEN}"
24
+ }
25
+
26
+ chlog "$@"
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
@@ -14,14 +14,16 @@
14
14
  bash_version=$(bash --version | awk '{FS="version"}{print $4}')
15
15
  bash_version=${bash_version:0:1}
16
16
 
17
- declare -a bash_completion_locations=(/usr/local/etc/bash_completion /usr/etc/bash_completion /etc/bash_completion)
18
- loaded=false
19
- for file in ${bash_completion_locations[@]}; do
17
+ [[ -z $(type _filedir 2>/dev/null) ]] && {
18
+ declare -a bash_completion_locations=(/usr/local/etc/bash_completion /usr/etc/bash_completion /etc/bash_completion)
19
+ loaded=false
20
+ for file in ${bash_completion_locations[@]}; do
20
21
  [[ -s ${file} ]] && {
21
22
  source ${file}
22
23
  break
23
24
  }
24
- done
25
+ done
26
+ }
25
27
 
26
28
  _sym_long_opts() {
27
29
  sym -h | grep -- '--' | egrep '^ -' | awk '{print $2}' | sort
data/codecov.yml ADDED
@@ -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/
Binary file
Binary file
data/design/sym-help.png CHANGED
Binary file
data/exe/keychain CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib_path = File.expand_path(File.dirname(__FILE__) + '/../lib')
3
+ lib_path = File.expand_path("#{File.dirname(__FILE__)}/../lib")
4
4
  $LOAD_PATH << lib_path if File.exist?(lib_path) && !$LOAD_PATH.include?(lib_path)
5
5
 
6
6
  require 'sym'
@@ -9,7 +9,7 @@ require 'sym/app/keychain'
9
9
  require 'colored2'
10
10
 
11
11
  def usage
12
- puts 'Usage: ' + 'keychain'.bold.blue + ' name [ add <contents> | find | delete ]'.bold.green
12
+ puts "Usage: #{'keychain'.bold.blue}#{' name [ add <contents> | find | delete ]'.bold.green}"
13
13
  exit 0
14
14
  end
15
15
 
@@ -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,18 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
+ # vim: ft=ruby
2
3
 
3
- lib_path = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ require_relative '../lib/ruby_warnings'
5
+
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)
5
8
 
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
- STDERR.flush
14
- STDERR.puts "Interrupt, #{e.message}, exiting."
15
- STDERR.flush
16
+ $stderr.flush
17
+ warn "Interrupt, #{e.message}, exiting."
18
+ $stderr.flush
16
19
  exit 1
17
20
  end
18
21
 
@@ -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
@@ -14,24 +14,18 @@ Sym::Configuration.configure do |config|
14
14
  config.compression_enabled = true
15
15
  config.compression_level = Zlib::BEST_COMPRESSION
16
16
  config.encrypted_file_extension = 'enc'
17
- config.default_key_file = Sym::Constants::SYM_KEY_FILE
17
+ config.default_key_file = Sym::Constants.sym_key_file
18
18
 
19
19
  config.password_cache_timeout = 300
20
20
 
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
  }
data/lib/sym/app.rb CHANGED
@@ -16,16 +16,14 @@ module Sym
16
16
  #
17
17
  module App
18
18
  class << self
19
- attr_accessor :exit_code
20
- attr_accessor :stdin, :stdout, :stderr
21
-
19
+ attr_accessor :exit_code, :stdin, :stdout, :stderr
22
20
  end
23
21
 
24
22
  self.exit_code = 0
25
23
 
26
- self.stdin = STDIN
27
- self.stdout = STDOUT
28
- self.stderr = STDERR
24
+ self.stdin = $stdin
25
+ self.stdout = $stdout
26
+ self.stderr = $stderr
29
27
 
30
28
  def self.out
31
29
  self.stderr
@@ -45,7 +43,7 @@ module Sym
45
43
 
46
44
  lines = []
47
45
 
48
- error_type = "#{(type || exception.class.name)}"
46
+ error_type = "#{type || exception.class.name}"
49
47
  error_details = (details || exception.message)
50
48
 
51
49
  operation = command ? "to #{command.class.short_name.to_s.humanize.downcase}" : ''
@@ -56,7 +54,7 @@ module Sym
56
54
  lines << exception.backtrace.join("\n").red.bold if config[:trace]
57
55
  lines << "\n"
58
56
  else
59
- lines << " ✖ Sym Error #{operation}:".bold.red + (reason ? " #{reason} ".red.italic: " #{error_details}")[0..70] + ' '.normal + "\n"
57
+ lines << "#{" ✖ Sym Error #{operation}:".bold.red}#{(reason ? " #{reason} ".red.italic: " #{error_details}")[0..70]}#{' '.normal}\n"
60
58
  lines << "#{comments}" if comments
61
59
  end
62
60
 
@@ -66,7 +64,7 @@ module Sym
66
64
  self.exit_code = 1
67
65
  end
68
66
 
69
- def self.is_osx?
67
+ def self.osx?
70
68
  Gem::Platform.local.os.eql?('darwin')
71
69
  end
72
70
 
data/lib/sym/app/args.rb CHANGED
@@ -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
data/lib/sym/app/cli.rb CHANGED
@@ -56,11 +56,10 @@ module Sym
56
56
  # brings in #parse(Array[String] args)
57
57
  include CLISlop
58
58
 
59
- attr_accessor :opts, :application, :outputs, :stdin, :stdout, :stderr, :kernel
60
-
61
-
62
- def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = nil)
59
+ attr_accessor :opts, :application, :outputs, :stdin, :stdout, :stderr, :kernel, :args
63
60
 
61
+ def initialize(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr, kernel = nil)
62
+ self.args = argv
64
63
  self.stdin = stdin
65
64
  self.stdout = stdout
66
65
  self.stderr = stderr
@@ -72,37 +71,44 @@ module Sym
72
71
 
73
72
  begin
74
73
  # Re-map any legacy options to the new options
75
- self.opts = parse(argv)
76
- if opts[:sym_args]
77
- append_sym_args(argv)
78
- self.opts = parse(argv)
74
+ self.opts = parse(args)
75
+
76
+ if opts[:user_home]
77
+ Constants.user_home = opts[:user_home]
78
+ raise InvalidSymHomeDirectory, "#{opts[:user_home]} does not exist!" unless Dir.exist?(Constants.user_home)
79
+ end
80
+
81
+ # Deal with SYM_ARGS and -A
82
+ if opts[:sym_args] && non_empty_array?(sym_args)
83
+ args << sym_args
84
+ args.flatten!
85
+ args.compact!
86
+ args.delete('-A')
87
+ args.delete('--sym-args')
88
+ self.opts = parse(args)
79
89
  end
80
90
 
81
91
  # Disable coloring if requested, or if piping STDOUT
82
92
  if opts[:no_color] || !self.stdout.tty?
83
93
  Colored2.disable! # reparse options without the colors to create new help msg
84
- self.opts = parse(argv)
94
+ self.opts = parse(args)
85
95
  end
86
96
 
87
97
  rescue StandardError => e
88
98
  log :error, "#{e.message}" if opts
89
99
  error exception: e
90
- exit 127 if stdin == STDIN
100
+ quit!(127) if stdin == $stdin
91
101
  end
92
102
 
93
- self.application = ::Sym::Application.new(opts, stdin, stdout, stderr, kernel)
103
+ self.application = ::Sym::Application.new(self.opts, stdin, stdout, stderr, kernel)
94
104
  end
95
105
 
96
- def append_sym_args(argv)
97
- if env_args = sym_args
98
- argv << env_args.split(' ')
99
- argv.flatten!
100
- argv.compact!
101
- end
106
+ def quit!(code = 0)
107
+ exit(code)
102
108
  end
103
109
 
104
110
  def sym_args
105
- ENV[Sym::Constants::ENV_ARGS_VARIABLE_NAME]
111
+ (ENV['SYM_ARGS']&.split(/\s+/) || [])
106
112
  end
107
113
 
108
114
  def execute!
@@ -132,15 +138,20 @@ module Sym
132
138
  end
133
139
 
134
140
  def opts_present
135
- o = opts.to_hash
136
- o.keys.map { |k| opts[k] ? nil : k }.compact.each { |k| o.delete(k) }
137
- o
141
+ opts.to_hash.tap do |o|
142
+ o.keys.map { |k| opts[k] ? nil : k }.compact.each { |k| o.delete(k) }
143
+ end
144
+ end
145
+
146
+ def log(*args)
147
+ Sym::App.log(*args, **opts.to_hash)
138
148
  end
139
149
 
150
+
140
151
  private
141
152
 
142
- def log(*args)
143
- Sym::App.log(*args, **(opts.to_hash))
153
+ def non_empty_array?(object)
154
+ object.is_a?(Array) && !object.empty?
144
155
  end
145
156
 
146
157
  def error(hash)
@@ -19,7 +19,7 @@ module Sym
19
19
  o.separator ' 5) use -i to paste/type the key interactively'.dark
20
20
  o.separator ' 6) default key file (if present) at '.dark + Sym.default_key_file.magenta.bold
21
21
  o.separator ' '
22
- o.separator ' ' + key_spec + ' = -k/--key [ key | file | keychain | env variable name ]'.green.bold
22
+ o.separator " #{key_spec}#{' = -k/--key [ key | file | keychain | env variable name ]'.green.bold}"
23
23
  o.separator ' -i/--interactive'.green.bold
24
24
  o.separator ''
25
25
  o.separator ' Encrypt/Decrypt from STDIN/file/args, to STDOUT/file:'.dark
@@ -48,33 +48,34 @@ module Sym
48
48
  o.separator 'Modes:'.yellow
49
49
  o.bool '-e', '--encrypt', ' encrypt mode'
50
50
  o.bool '-d', '--decrypt', ' decrypt mode'
51
- o.string '-t', '--edit', '[file] '.blue + ' edit encrypted file in an $EDITOR', default: nil
51
+ o.string '-t', '--edit', "#{'[file] '.blue} edit encrypted file in an $EDITOR", default: nil
52
52
  o.string '-n', '--negate', '[file] '.blue + " encrypts any regular #{'file'.green} into #{'file.enc'.green}" + "\n" +
53
53
  " conversely decrypts #{'file.enc'.green} into #{'file'.green}."
54
54
  o.separator ' '
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?
59
- o.string '-x', '--keychain', '[key-name] '.blue + 'write the key to OS-X Keychain'
58
+
59
+ if Sym::App.osx?
60
+ o.string '-x', '--keychain', "#{'[key-name] '.blue}write the key to OS-X Keychain"
60
61
  end
61
62
 
62
63
  o.separator ' '
63
64
  o.separator 'Read existing private key from:'.yellow
64
- o.string '-k', '--key', '[key-spec]'.blue + ' private key, key file, or keychain'
65
+ o.string '-k', '--key', "#{'[key-spec]'.blue} private key, key file, or keychain"
65
66
  o.bool '-i', '--interactive', ' Paste or type the key interactively'
66
67
 
67
68
  o.separator ' '
68
69
  o.separator 'Password Cache:'.yellow
69
70
  o.bool '-c', '--cache-passwords', ' enable password cache'
70
- o.integer '-u', '--cache-timeout', '[seconds]'.blue + ' expire passwords after'
71
+ o.integer '-z', '--cache-timeout', "#{'[seconds]'.blue} expire passwords after"
71
72
  o.string '-r', '--cache-provider', '[provider]'.blue + ' cache provider, one of ' + "#{Sym::App::Password::Providers.provider_list}"
72
73
 
73
74
  o.separator ' '
74
75
  o.separator 'Data to Encrypt/Decrypt:'.yellow
75
- o.string '-s', '--string', '[string]'.blue + ' specify a string to encrypt/decrypt'
76
- o.string '-f', '--file', '[file] '.blue + ' filename to read from'
77
- o.string '-o', '--output', '[file] '.blue + ' filename to write to'
76
+ o.string '-s', '--string', "#{'[string]'.blue} specify a string to encrypt/decrypt"
77
+ o.string '-f', '--file', "#{'[file] '.blue} filename to read from"
78
+ o.string '-o', '--output', "#{'[file] '.blue} filename to write to"
78
79
 
79
80
  o.separator ' '
80
81
  o.separator 'Flags:'.yellow
@@ -89,8 +90,13 @@ module Sym
89
90
 
90
91
  o.separator ' '
91
92
  o.separator 'Utility:'.yellow
92
- o.string '-B', '--bash-support', '[file]'.blue + ' append bash completion & utils to a file'+ "\n" +
93
- ' such as ~/.bash_profile or ~/.bashrc'
93
+ o.separator " The following flag helps with Sym installation by hooking to \n" +
94
+ " your #{'~/.bashrc'.bold.yellow}. If you are running Sym on an environment without \n" +
95
+ " user home available, you may need to force set user's home to any existing\n" +
96
+ " directory using the #{'--user-home'.bold.blue} flag.\n"
97
+
98
+ o.string '-B', '--bash-support', "#{'[file]'.blue} append bash completion & utils to a file\n such as ~/.bash_profile or ~/.bashrc"
99
+ o.string '-u', '--user-home', '[DIR]'.blue + " Overrides #{'${HOME}'.green} ==> supports AWS Lambda\n"
94
100
 
95
101
  o.separator ' '
96
102
  o.separator 'Help & Examples:'.yellow