kbsecret 0.6.5 → 0.7.0.pre.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 061dc3ef77cf2be8317743c5c7a661dc906ccc66
4
- data.tar.gz: f09cd15ecf6ca22c7660528002e131c44aa9cf82
3
+ metadata.gz: d6b4bbb559dfea85bc7b7d767db97dd609ec9117
4
+ data.tar.gz: '009586cb565eb93ba6ea4d605527748dbb9d7ad5'
5
5
  SHA512:
6
- metadata.gz: 5e18ecf145719006f1065ba076c079bbaaeec4adcaec38f881bb368c95f445c8992838e3017b88954fb3f86c66eaef52bac35916489a1285eeb8ed03f88fc030
7
- data.tar.gz: b569a9c09826835a5e09dda8523960e6d062ef7c6e34ab22212345284cc259ce97c331da3910d479b70c5a41cafadefce4f3b4bc20c1ba860f5f035d0a874242
6
+ metadata.gz: 19a290acff300d2ff4b1f7bf5fe58bd94586fc1c05757aa53dc5126794e51bfd7ceafb5a2a309e557b1456ff9d01664d354602b6494104fc0a49937aa7b5821d
7
+ data.tar.gz: aa0b5abe37669dfabbdc2f904aa5edd10e8b8144afbaab639d2504360339a30bd9b0a1b2539a82c08d3cef9cb63f5ca24d9838b4ae271f9fe1ec03c401681628
data/README.md CHANGED
@@ -50,7 +50,7 @@ Documentation is available on [RubyDoc](http://www.rubydoc.info/gems/kbsecret/).
50
50
  ```bash
51
51
  # create a new login record under the default session
52
52
  $ kbsecret new login gmail
53
- Username?
53
+ Username? bob@gmail.com
54
54
  Password?
55
55
 
56
56
  # list all records under the default session
@@ -60,7 +60,7 @@ gmail
60
60
  # show the requested login record
61
61
  $ kbsecret login gmail
62
62
  Label: gmail
63
- Username: foo@example.com
63
+ Username: bob@gmail.com
64
64
  Password: barbazquux
65
65
 
66
66
  # create a new session between 3 keybase users (foo, bar, and baz)
@@ -73,7 +73,7 @@ dev-team
73
73
 
74
74
  # add an environment record to the dev-team session
75
75
  $ kbsecret new environment api-key -s dev-team
76
- Variable?
76
+ Variable? BRAND_NEW_API
77
77
  Value?
78
78
 
79
79
  # list all records under the dev-team session
@@ -82,7 +82,7 @@ api-key
82
82
 
83
83
  # get all environment records in dev-team in an easy-to-source format
84
84
  $ kbsecret env -s dev-team --all
85
- export API_KEY='0xBADBEEF'
85
+ export BRAND_NEW_API='0xBADBEEF'
86
86
  ```
87
87
 
88
88
  ### Manual Pages
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret dump-fields [options] <record>
@@ -17,11 +17,11 @@ cmd = CLI.new do
17
17
  o.string "-i", "--ifs", "separate terse pairs with this string", default: CLI.ifs
18
18
  end
19
19
 
20
- dreck do
20
+ c.dreck do
21
21
  string :label
22
22
  end
23
23
 
24
- ensure_session!
24
+ c.ensure_session!
25
25
  end
26
26
 
27
27
  label = cmd.args[:label]
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret env [options] <record [record ...]>
@@ -17,13 +17,13 @@ cmd = CLI.new do
17
17
  o.bool "-v", "--value-only", "print only the environment value, not the key"
18
18
  end
19
19
 
20
- unless opts.all?
21
- dreck do
20
+ unless c.opts.all?
21
+ c.dreck do
22
22
  list :string, :labels
23
23
  end
24
24
  end
25
25
 
26
- ensure_session!
26
+ c.ensure_session!
27
27
  end
28
28
 
29
29
  records = cmd.session.records :environment
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "kbsecret"
5
+
6
+ include KBSecret
7
+
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
+ o.banner = <<~EOS
11
+ Usage:
12
+ kbsecret new-generator [options] <new|rm> <generator>
13
+ EOS
14
+
15
+ o.string "-F", "--format", "the format of the secrets generated", default: "hex"
16
+ o.integer "-l", "--length", "the length, in bytes, of the secrets generated",
17
+ default: 16
18
+ o.bool "-f", "--force", "force generator creation (ignore overwrite)"
19
+ end
20
+
21
+ c.dreck do
22
+ string :command
23
+ string :generator
24
+ end
25
+
26
+ c.ensure_generator! :argument if c.args[:command] == "rm"
27
+ end
28
+
29
+ case cmd.args[:command]
30
+ when "new"
31
+ if Config.generator?(cmd.args[:generator]) && !cmd.opts.force?
32
+ cmd.die "Refusing to overwrite an existing generator without --force."
33
+ end
34
+
35
+ Config.configure_generator(cmd.args[:generator],
36
+ format: cmd.opts[:format],
37
+ length: cmd.opts[:length])
38
+ when "rm"
39
+ Config.deconfigure_generator(cmd.args[:generator])
40
+ else
41
+ cmd.die "Unknown subcommand: '#{cmd.args[:command]}'."
42
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "kbsecret"
5
+
6
+ include KBSecret
7
+
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
+ o.banner = <<~EOS
11
+ Usage:
12
+ kbsecret generators [options]
13
+ EOS
14
+
15
+ o.bool "-a", "--show-all", "show each generator in depth (i.e. metadata)"
16
+ end
17
+ end
18
+
19
+ Config[:generators].each do |label, config|
20
+ puts label
21
+
22
+ next unless cmd.opts.show_all?
23
+
24
+ puts <<~EOS
25
+ \tFormat: #{config[:format]}
26
+ \tLength: #{config[:length]}
27
+ EOS
28
+ end
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret login [options] <record [record ...]>
@@ -18,13 +18,13 @@ cmd = CLI.new do
18
18
  o.string "-i", "--ifs", "separate terse fields with this string", default: CLI.ifs
19
19
  end
20
20
 
21
- unless opts.all?
22
- dreck do
21
+ unless c.opts.all?
22
+ c.dreck do
23
23
  list :string, :labels
24
24
  end
25
25
  end
26
26
 
27
- ensure_session!
27
+ c.ensure_session!
28
28
  end
29
29
 
30
30
  records = cmd.session.records :login
@@ -22,6 +22,9 @@ cmd = CLI.create do |c|
22
22
  o.bool "-f", "--force", "force creation (ignore overwrites, etc.)"
23
23
  o.bool "-a", "--args", "use trailing arguments as fields, even with a tty"
24
24
  o.bool "-e", "--echo", "echo input to tty (only affects interactive input)"
25
+ o.bool "-G", "--generate", "generate secret fields (interactive only)"
26
+ o.string "-g", "--generator", "the generator to use for secret fields",
27
+ default: :default
25
28
  end
26
29
 
27
30
  c.dreck do
@@ -30,6 +33,7 @@ cmd = CLI.create do |c|
30
33
  list :string, :fields if c.opts.args?
31
34
  end
32
35
 
36
+ c.ensure_generator!
33
37
  c.ensure_type! :argument
34
38
  c.ensure_session!
35
39
  end
@@ -42,19 +46,23 @@ if cmd.session.record?(label) && !cmd.opts.force?
42
46
  cmd.die "Refusing to overwrite an existing record without --force."
43
47
  end
44
48
 
49
+ if cmd.opts.generate?
50
+ generator = cmd.guard { Generator.new cmd.opts[:generator] }
51
+ end
52
+
45
53
  fields = if $stdin.tty? && !cmd.opts.args?
46
54
  prompt = TTY::Prompt.new
47
55
  klass = Record.class_for(resolved_type)
48
56
  klass.data_fields.map do |field|
49
- prompt.ask "#{field.capitalize}?",
50
- echo: !klass.sensitive?(field) || cmd.opts.echo?
57
+ if cmd.opts.generate? && klass.sensitive?(field)
58
+ generator.secret
59
+ else
60
+ prompt.ask "#{field.capitalize}?",
61
+ echo: !klass.sensitive?(field) || cmd.opts.echo?
62
+ end
51
63
  end
52
64
  else
53
65
  cmd.args[:fields]
54
66
  end
55
67
 
56
- begin
57
- cmd.session.add_record(resolved_type, label, *fields)
58
- rescue => e
59
- cmd.die "#{e}."
60
- end
68
+ cmd.guard { cmd.session.add_record(resolved_type, label, *fields) }
@@ -6,8 +6,8 @@ require "kbsecret"
6
6
 
7
7
  include KBSecret
8
8
 
9
- cmd = CLI.new do
10
- slop do |o|
9
+ cmd = CLI.create do |c|
10
+ c.slop do |o|
11
11
  o.banner = <<~EOS
12
12
  Usage:
13
13
  kbsecret new-session [options] --label <label> --root <dir>
@@ -6,8 +6,8 @@ require "clipboard"
6
6
 
7
7
  include KBSecret
8
8
 
9
- cmd = CLI.new do
10
- slop do |o|
9
+ cmd = CLI.create do |c|
10
+ c.slop do |o|
11
11
  o.banner = <<~EOS
12
12
  Usage:
13
13
  kbsecret pass [options] <record>
@@ -17,11 +17,11 @@ cmd = CLI.new do
17
17
  o.bool "-c", "--clipboard", "dump the password in the clipboard"
18
18
  end
19
19
 
20
- dreck do
20
+ c.dreck do
21
21
  string :label
22
22
  end
23
23
 
24
- ensure_session!
24
+ c.ensure_session!
25
25
  end
26
26
 
27
27
  label = cmd.args[:label]
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret raw-edit [options] <record>
@@ -15,11 +15,11 @@ cmd = CLI.new do
15
15
  o.string "-s", "--session", "the session to search in", default: :default
16
16
  end
17
17
 
18
- dreck do
18
+ c.dreck do
19
19
  string :label
20
20
  end
21
21
 
22
- ensure_session!
22
+ c.ensure_session!
23
23
  end
24
24
 
25
25
  label = cmd.args[:label]
@@ -8,8 +8,8 @@ include KBSecret
8
8
 
9
9
  $VERBOSE = nil # tty-prompt blasts us with irrelevant warnings on 2.4
10
10
 
11
- cmd = CLI.new do
12
- slop do |o|
11
+ cmd = CLI.create do |c|
12
+ c.slop do |o|
13
13
  o.banner = <<~EOS
14
14
  Usage:
15
15
  kbsecret rm [options] <record>
@@ -19,11 +19,11 @@ cmd = CLI.new do
19
19
  o.bool "-i", "--interactive", "ask for confirmation before deleting"
20
20
  end
21
21
 
22
- dreck do
22
+ c.dreck do
23
23
  string :label
24
24
  end
25
25
 
26
- ensure_session!
26
+ c.ensure_session!
27
27
  end
28
28
 
29
29
  label = cmd.args[:label]
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret rm-session [options] <session>
@@ -15,11 +15,11 @@ cmd = CLI.new do
15
15
  o.bool "-d", "--delete", "unlink the session in addition to deconfiguration"
16
16
  end
17
17
 
18
- dreck do
18
+ c.dreck do
19
19
  string :session
20
20
  end
21
21
 
22
- ensure_session! :argument
22
+ c.ensure_session! :argument
23
23
  end
24
24
 
25
25
  label = cmd.args[:session]
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret sessions [options]
@@ -6,8 +6,8 @@ require "base64"
6
6
 
7
7
  include KBSecret
8
8
 
9
- cmd = CLI.new do
10
- slop do |o|
9
+ cmd = CLI.create do |c|
10
+ c.slop do |o|
11
11
  o.banner = <<~EOS
12
12
  Usage:
13
13
  kbsecret stash-file <record> [file]
@@ -18,12 +18,12 @@ cmd = CLI.new do
18
18
  o.bool "-b", "--base64", "encode the file as base64"
19
19
  end
20
20
 
21
- dreck errors: false do
21
+ c.dreck errors: false do
22
22
  string :label
23
23
  string :filename
24
24
  end
25
25
 
26
- ensure_session!
26
+ c.ensure_session!
27
27
  end
28
28
 
29
29
  label = cmd.args[:label]
@@ -5,8 +5,8 @@ require "kbsecret"
5
5
 
6
6
  include KBSecret
7
7
 
8
- cmd = CLI.new do
9
- slop cmds: %w[start suspend complete] do |o|
8
+ cmd = CLI.create do |c|
9
+ c.slop cmds: %w[start suspend complete] do |o|
10
10
  o.banner = <<~EOS
11
11
  Usage:
12
12
  kbsecret todo <start|suspend|complete> <record>
@@ -15,12 +15,12 @@ cmd = CLI.new do
15
15
  o.string "-s", "--session", "the session to search in", default: :default
16
16
  end
17
17
 
18
- dreck do
18
+ c.dreck do
19
19
  string :command
20
20
  string :label
21
21
  end
22
22
 
23
- ensure_session!
23
+ c.ensure_session!
24
24
  end
25
25
 
26
26
  label = cmd.args[:label]
@@ -43,5 +43,5 @@ when "complete"
43
43
  todo.complete!
44
44
  puts "#{todo.label}: '#{todo.todo}' marked as completed at #{todo.stop}"
45
45
  else
46
- cmd.die "Unknown action: #{command}."
46
+ cmd.die "Unknown subcommand: '#{cmd.args[:command]}'."
47
47
  end
@@ -7,6 +7,7 @@ require_relative "kbsecret/config"
7
7
  require_relative "kbsecret/exceptions"
8
8
  require_relative "kbsecret/record"
9
9
  require_relative "kbsecret/session"
10
+ require_relative "kbsecret/generator"
10
11
  require_relative "kbsecret/cli"
11
12
 
12
13
  # The primary namespace for kbsecret.
@@ -98,12 +98,10 @@ module KBSecret
98
98
  # the `--session` option. If `:argument` is passed, then the session is expected
99
99
  # to be in the argument list labeled as `:argument` by Dreck.
100
100
  # @return [void]
101
- # @raise [RuntimeError] if the expected session is not configured.
102
101
  # @note {#slop} and {#dreck} should be called before this, depending on whether
103
102
  # options or arguments are being tested for a valid session.
104
103
  def ensure_session!(where = :option)
105
104
  label = where == :option ? @opts[:session] : @args[:session]
106
- raise "Unknown session: '#{label}'" unless Config.session? label
107
105
  @session = Session.new label: label
108
106
  end
109
107
 
@@ -114,11 +112,27 @@ module KBSecret
114
112
  # `--type` option. If `:argument` is passed, then the type is expected to
115
113
  # be in the argument list labeled as `:type` by Dreck.
116
114
  # @return [void]
115
+ # @note {#slop} and {#dreck} should be called before this, depending on whether
116
+ # options or arguments are being tested for a valid session.
117
117
  def ensure_type!(where = :option)
118
118
  type = where == :option ? @opts[:type] : @args[:type]
119
119
  Record.class_for type
120
120
  end
121
121
 
122
+ # Ensure that a generator profile passed in as an option or argument already
123
+ # exists (i.e., is already configured).
124
+ # @param where [Symbol] Where to look for the session label to test.
125
+ # If `:option` is passed, then the generator is expected to be the value of
126
+ # the `--generator` option. If `:argument` is passed, then the type is expected
127
+ # to be in the argument list labeled as `:generator` by Dreck.
128
+ # @return [void]
129
+ # @note {#slop} and {#dreck} should be called before this, depending on whether
130
+ # options or arguments are being tested for a valid session.
131
+ def ensure_generator!(where = :option)
132
+ gen = where == :option ? @opts[:generator] : @args[:generator]
133
+ Config.generator gen
134
+ end
135
+
122
136
  # "Guard" a block by propagating any exceptions as fatal (unrecoverable)
123
137
  # errors.
124
138
  # @return [Object] the result of the block
@@ -6,30 +6,48 @@ require "fileutils"
6
6
  module KBSecret
7
7
  # Global and per-session configuration for kbsecret.
8
8
  class Config
9
- # the configuration directory
9
+ # The configuration directory.
10
10
  # @api private
11
11
  CONFIG_DIR = File.expand_path("~/.config/kbsecret").freeze
12
12
 
13
- # the configuration file
13
+ # The configuration file.
14
14
  # @api private
15
15
  CONFIG_FILE = File.join(CONFIG_DIR, "config.yml").freeze
16
16
 
17
+ # The default session configuration.
18
+ DEFAULT_SESSION = {
19
+ default: {
20
+ users: [Keybase.current_user],
21
+ root: "default",
22
+ },
23
+ }.freeze
24
+
25
+ # The default generator configuration.
26
+ DEFAULT_GENERATOR = {
27
+ default: {
28
+ format: "hex",
29
+ length: 16,
30
+ },
31
+ }.freeze
32
+
17
33
  # configuration defaults
18
34
  # @api private
19
35
  DEFAULT_CONFIG = {
20
- mount: "/keybase",
21
- sessions: {
22
- default: {
23
- users: [Keybase.current_user],
24
- root: "default",
25
- },
26
- },
27
-
28
36
  session_root: File.join("/keybase/private/",
29
37
  Keybase.current_user,
30
38
  "kbsecret"),
39
+
40
+ mount: "/keybase",
41
+ sessions: DEFAULT_SESSION,
42
+ generators: DEFAULT_GENERATOR,
31
43
  }.freeze
32
44
 
45
+ # Writes the user's configuration to disk.
46
+ # @return [void]
47
+ def self.sync!
48
+ File.open(CONFIG_FILE, "w") { |io| io.write @config.to_yaml }
49
+ end
50
+
33
51
  # Retrieve a configured value.
34
52
  # @param key [String] the configuration key to retrieve
35
53
  # @return [Object] the corresponding configuration
@@ -40,8 +58,13 @@ module KBSecret
40
58
  # Retrieve a session's configuration.
41
59
  # @param sess [String, Symbol] the session's label
42
60
  # @return [Hash] the session configuration
61
+ # @raise [SessionUnknownError] if no such session exists
43
62
  def self.session(sess)
44
- @config[:sessions][sess.to_sym]
63
+ hsh = @config[:sessions][sess.to_sym]
64
+
65
+ raise SessionUnknownError, sess unless hsh
66
+
67
+ hsh
45
68
  end
46
69
 
47
70
  # @return [Array<Symbol>] all configured session labels
@@ -61,7 +84,7 @@ module KBSecret
61
84
  # @return [void]
62
85
  def self.configure_session(label, hsh)
63
86
  @config[:sessions][label.to_sym] = hsh
64
- File.open(CONFIG_FILE, "w") { |io| io.write @config.to_yaml }
87
+ sync!
65
88
  end
66
89
 
67
90
  # Deconfigure a session.
@@ -72,7 +95,47 @@ module KBSecret
72
95
  # with a session, see {KBSecret::Session#unlink!}.
73
96
  def self.deconfigure_session(label)
74
97
  @config[:sessions].delete(label.to_sym)
75
- File.open(CONFIG_FILE, "w") { |io| io.write @config.to_yaml }
98
+ sync!
99
+ end
100
+
101
+ # Retrieve a generator's configuration.
102
+ # @param gen [String, Symbol] the generator's label
103
+ # @return [Hash] the generator configuration
104
+ # @raise [GeneratorUnknownError] if no such generator exists
105
+ def self.generator(gen)
106
+ hsh = @config[:generators][gen.to_sym]
107
+
108
+ raise GeneratorUnknownError, gen unless hsh
109
+
110
+ hsh
111
+ end
112
+
113
+ # @return [Array<Symbol>] all configured session labels
114
+ def self.generator_labels
115
+ @config[:generators].keys
116
+ end
117
+
118
+ # @param gen [String, Symbol] the generator label
119
+ # @return [Boolean] whether or not the given generator is configured
120
+ def self.generator?(gen)
121
+ generator_labels.include?(gen.to_sym)
122
+ end
123
+
124
+ # Configure a secret generator.
125
+ # @param label [String, Symbol] the generator label (profile name)
126
+ # @param hsh [Hash] the generator configuration
127
+ # @return [void]
128
+ def self.configure_generator(label, **hsh)
129
+ @config[:generators][label.to_sym] = hsh
130
+ sync!
131
+ end
132
+
133
+ # Deconfigure a generator.
134
+ # @param label [String, Symbol] the generator label (profile name)
135
+ # @return [void]
136
+ def self.deconfigure_generator(label)
137
+ @config[:generators].delete(label.to_sym)
138
+ sync!
76
139
  end
77
140
 
78
141
  if File.exist?(CONFIG_FILE)
@@ -80,10 +143,13 @@ module KBSecret
80
143
  else
81
144
  user_config = DEFAULT_CONFIG
82
145
  FileUtils.mkdir_p CONFIG_DIR
83
- File.open(CONFIG_FILE, "w") { |io| io.write DEFAULT_CONFIG.to_yaml }
84
146
  end
85
147
 
86
148
  @config = DEFAULT_CONFIG.merge(user_config)
149
+ @config[:sessions].merge!(DEFAULT_SESSION)
150
+ @config[:generators].merge!(DEFAULT_GENERATOR)
151
+
87
152
  FileUtils.mkdir_p @config[:session_root]
153
+ sync!
88
154
  end
89
155
  end
@@ -26,4 +26,32 @@ module KBSecret
26
26
  super "Needed #{exp} arguments for this record, got #{act}"
27
27
  end
28
28
  end
29
+
30
+ # Raised during session lookup if an unknown session is requested.
31
+ class SessionUnknownError < KBSecretError
32
+ def initialize(sess)
33
+ super "Unknown session: '#{sess}'"
34
+ end
35
+ end
36
+
37
+ # Raised during generator lookup if an unknown profile is requested.
38
+ class GeneratorUnknownError < KBSecretError
39
+ def initialize(gen)
40
+ super "Unknown generator profile: '#{gen}'"
41
+ end
42
+ end
43
+
44
+ # Raised during generator creation if an unknown generator format is requested.
45
+ class GeneratorFormatError < KBSecretError
46
+ def initialize(fmt)
47
+ super "Unknown generator format: '#{fmt}'"
48
+ end
49
+ end
50
+
51
+ # Raised during generator creation if a non-positive generator length is requested.
52
+ class GeneratorLengthError < KBSecretError
53
+ def initialize(length)
54
+ super "Bad secret generator length (#{length}, must be positive)"
55
+ end
56
+ end
29
57
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module KBSecret
6
+ # Generates secret values (passwords, environment keys, etc) for storage by {KBSecret}.
7
+ class Generator
8
+ # All generator formats known by {Generator}.
9
+ GENERATOR_TYPES = %i[hex base64].freeze
10
+
11
+ # @return [Symbol] the format of the generator
12
+ attr_reader :format
13
+
14
+ # @return [Integer] the length, in bytes of secrets generated by the generator
15
+ attr_reader :length
16
+
17
+ # @param profile [Symbol, String] the label of the generator profile to use
18
+ # @raise [GeneratorLengthError] if the profile has a non-positive length
19
+ # @raise [GeneratorFormatError] if the profile has an unknown format
20
+ def initialize(profile = :default)
21
+ @format = Config.generator(profile)[:format].to_sym
22
+ @length = Config.generator(profile)[:length].to_i
23
+
24
+ raise GeneratorLengthError, @length unless @length.positive?
25
+ raise GeneratorFormatError, @format unless GENERATOR_TYPES.include?(@format)
26
+ end
27
+
28
+ # @return [String] a new secret based on the {format} and {length} of the {Generator}
29
+ # @example
30
+ # g = KBSecret::Generator.new # => #<KBSecret::Generator @format="hex", @length=16>
31
+ # g.secret # => "a927f1e7ffa1a039a9cd31c45bc181e3"
32
+ def secret
33
+ SecureRandom.send(@format, @length)
34
+ end
35
+ end
36
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module KBSecret
4
4
  # kbsecret's current version
5
- VERSION = "0.6.5"
5
+ VERSION = "0.7.0.pre.1"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kbsecret
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Woodruff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-09 00:00:00.000000000 Z
11
+ date: 2017-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fpm
@@ -159,7 +159,9 @@ executables:
159
159
  - kbsecret-login
160
160
  - kbsecret-raw-edit
161
161
  - kbsecret-todo
162
+ - kbsecret-generator
162
163
  - kbsecret-new
164
+ - kbsecret-generators
163
165
  - kbsecret-dump-fields
164
166
  - kbsecret-stash-file
165
167
  - kbsecret-rm-session
@@ -176,6 +178,8 @@ files:
176
178
  - bin/kbsecret
177
179
  - bin/kbsecret-dump-fields
178
180
  - bin/kbsecret-env
181
+ - bin/kbsecret-generator
182
+ - bin/kbsecret-generators
179
183
  - bin/kbsecret-list
180
184
  - bin/kbsecret-login
181
185
  - bin/kbsecret-new
@@ -191,6 +195,7 @@ files:
191
195
  - lib/kbsecret/cli.rb
192
196
  - lib/kbsecret/config.rb
193
197
  - lib/kbsecret/exceptions.rb
198
+ - lib/kbsecret/generator.rb
194
199
  - lib/kbsecret/record.rb
195
200
  - lib/kbsecret/record/abstract.rb
196
201
  - lib/kbsecret/record/environment.rb
@@ -215,9 +220,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
215
220
  version: 2.3.0
216
221
  required_rubygems_version: !ruby/object:Gem::Requirement
217
222
  requirements:
218
- - - ">="
223
+ - - ">"
219
224
  - !ruby/object:Gem::Version
220
- version: '0'
225
+ version: 1.3.1
221
226
  requirements: []
222
227
  rubyforge_project:
223
228
  rubygems_version: 2.6.11