kbsecret 1.2.0 → 1.3.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 +4 -4
- data/README.md +5 -5
- data/bin/kbsecret +6 -14
- data/lib/kbsecret/cli/command/abstract.rb +51 -0
- data/lib/kbsecret/cli/command/conf.rb +42 -0
- data/lib/kbsecret/cli/command/cp.rb +54 -0
- data/lib/kbsecret/cli/command/dump_fields.rb +53 -0
- data/lib/kbsecret/cli/command/env.rb +66 -0
- data/lib/kbsecret/cli/command/generator.rb +62 -0
- data/lib/kbsecret/cli/command/generators.rb +37 -0
- data/lib/kbsecret/cli/command/list.rb +48 -0
- data/lib/kbsecret/cli/command/login.rb +66 -0
- data/lib/kbsecret/cli/command/new.rb +82 -0
- data/lib/kbsecret/cli/command/pass.rb +51 -0
- data/lib/kbsecret/cli/command/raw_edit.rb +46 -0
- data/lib/kbsecret/cli/command/rm.rb +58 -0
- data/lib/kbsecret/cli/command/session.rb +128 -0
- data/lib/kbsecret/cli/command/sessions.rb +47 -0
- data/lib/kbsecret/cli/command/stash_file.rb +62 -0
- data/lib/kbsecret/cli/command/todo.rb +78 -0
- data/lib/kbsecret/cli/command.rb +45 -0
- data/lib/kbsecret/cli.rb +6 -4
- data/lib/kbsecret/config.rb +4 -3
- data/lib/kbsecret/record/abstract.rb +2 -2
- data/lib/kbsecret/record.rb +9 -7
- data/lib/kbsecret/version.rb +1 -1
- metadata +22 -20
- data/lib/kbsecret/cli/kbsecret-conf +0 -31
- data/lib/kbsecret/cli/kbsecret-cp +0 -44
- data/lib/kbsecret/cli/kbsecret-dump-fields +0 -39
- data/lib/kbsecret/cli/kbsecret-env +0 -53
- data/lib/kbsecret/cli/kbsecret-generator +0 -42
- data/lib/kbsecret/cli/kbsecret-generators +0 -28
- data/lib/kbsecret/cli/kbsecret-list +0 -36
- data/lib/kbsecret/cli/kbsecret-login +0 -53
- data/lib/kbsecret/cli/kbsecret-new +0 -68
- data/lib/kbsecret/cli/kbsecret-pass +0 -37
- data/lib/kbsecret/cli/kbsecret-raw-edit +0 -31
- data/lib/kbsecret/cli/kbsecret-rm +0 -44
- data/lib/kbsecret/cli/kbsecret-session +0 -105
- data/lib/kbsecret/cli/kbsecret-sessions +0 -38
- data/lib/kbsecret/cli/kbsecret-stash-file +0 -48
- data/lib/kbsecret/cli/kbsecret-todo +0 -47
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "clipboard"
|
4
|
+
|
5
|
+
module KBSecret
|
6
|
+
class CLI
|
7
|
+
module Command
|
8
|
+
# The implementation of `kbsecret pass`.
|
9
|
+
class Pass < Abstract
|
10
|
+
def initialize(argv)
|
11
|
+
super(argv) do |cli|
|
12
|
+
cli.slop do |o|
|
13
|
+
o.banner = <<~HELP
|
14
|
+
Usage:
|
15
|
+
kbsecret pass [options] <record>
|
16
|
+
HELP
|
17
|
+
|
18
|
+
o.string "-s", "--session", "the session to search in", default: :default
|
19
|
+
o.bool "-c", "--clipboard", "dump the password in the clipboard"
|
20
|
+
end
|
21
|
+
|
22
|
+
cli.dreck do
|
23
|
+
string :label
|
24
|
+
end
|
25
|
+
|
26
|
+
cli.ensure_session!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @see Command::Abstract#setup!
|
31
|
+
def setup!
|
32
|
+
@record = cli.session[cli.args[:label]]
|
33
|
+
end
|
34
|
+
|
35
|
+
# @see Command::Abstract#validate!
|
36
|
+
def validate!
|
37
|
+
cli.die "No such login record." unless @record && @record.type == :login
|
38
|
+
end
|
39
|
+
|
40
|
+
# @see Command::Abstract#run!
|
41
|
+
def run!
|
42
|
+
if cli.opts.clipboard?
|
43
|
+
Clipboard.copy @record.password
|
44
|
+
else
|
45
|
+
puts @record.password
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KBSecret
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# The implementation of `kbsecret raw-edit`.
|
7
|
+
class RawEdit < Abstract
|
8
|
+
def initialize(argv)
|
9
|
+
super(argv) do |cli|
|
10
|
+
cli.slop do |o|
|
11
|
+
o.banner = <<~HELP
|
12
|
+
Usage:
|
13
|
+
kbsecret raw-edit [options] <record>
|
14
|
+
HELP
|
15
|
+
|
16
|
+
o.string "-s", "--session", "the session to search in", default: :default
|
17
|
+
end
|
18
|
+
|
19
|
+
cli.dreck do
|
20
|
+
string :label
|
21
|
+
end
|
22
|
+
|
23
|
+
cli.ensure_session!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @see Command::Abstract#setup!
|
28
|
+
def setup!
|
29
|
+
@record = cli.session[cli.args[:label]]
|
30
|
+
end
|
31
|
+
|
32
|
+
# @see Command::Abstract#validate!
|
33
|
+
def validate!
|
34
|
+
cli.die "Missing $EDITOR." unless ENV["EDITOR"]
|
35
|
+
cli.die "No such record." unless @record
|
36
|
+
end
|
37
|
+
|
38
|
+
# @see Command::Abstract#run!
|
39
|
+
def run!
|
40
|
+
Process.spawn("#{ENV["EDITOR"]} #{@record.path}")
|
41
|
+
@record.sync! # just to bump the timestamp
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-prompt"
|
4
|
+
|
5
|
+
module KBSecret
|
6
|
+
class CLI
|
7
|
+
module Command
|
8
|
+
# The implementation of `kbsecret rm`.
|
9
|
+
class Rm < Abstract
|
10
|
+
def initialize(argv)
|
11
|
+
super(argv) do |cli|
|
12
|
+
cli.slop do |o|
|
13
|
+
o.banner = <<~HELP
|
14
|
+
Usage:
|
15
|
+
kbsecret rm [options] <record [record ...]>
|
16
|
+
HELP
|
17
|
+
|
18
|
+
o.string "-s", "--session", "the session containing the record", default: :default
|
19
|
+
o.bool "-i", "--interactive", "ask for confirmation before deleting"
|
20
|
+
end
|
21
|
+
|
22
|
+
cli.dreck do
|
23
|
+
list :string, :labels
|
24
|
+
end
|
25
|
+
|
26
|
+
cli.ensure_session!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @see Command::Abstract#setup!
|
31
|
+
def setup!
|
32
|
+
@selected_records = cli.session.records.select do |record|
|
33
|
+
cli.args[:labels].include? record.label
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see Command::Abstract#validate!
|
38
|
+
def validate!
|
39
|
+
cli.die "No such record(s)." if @selected_records.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
# @see Command::Abstract#run!
|
43
|
+
def run!
|
44
|
+
$VERBOSE = nil # tty-prompt blasts us with irrelevant warnings on 2.4
|
45
|
+
|
46
|
+
tty = TTY::Prompt.new
|
47
|
+
|
48
|
+
confirm = if cli.opts.interactive?
|
49
|
+
tty.yes?("Delete '#{selected_records.join(", ")}'?")
|
50
|
+
else true
|
51
|
+
end
|
52
|
+
|
53
|
+
@selected_records.each { |r| cli.session.delete_record(r.label) } if confirm
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KBSecret
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# The implementation of `kbsecret session`.
|
7
|
+
class Session < Abstract
|
8
|
+
# The list of subcommands supported by `kbsecret session`.
|
9
|
+
SUBCOMMANDS = %w[new rm].freeze
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
super(argv) do |cli|
|
13
|
+
cli.slop cmds: SUBCOMMANDS do |o|
|
14
|
+
o.banner = <<~HELP
|
15
|
+
Usage:
|
16
|
+
kbsecret session [options] <new|rm> <label>
|
17
|
+
HELP
|
18
|
+
|
19
|
+
o.string "-t", "--team", "the team to create the session under"
|
20
|
+
o.array "-u", "--users", "the Keybase users", default: [Keybase::Local.current_user]
|
21
|
+
o.string "-r", "--root", "the secret root directory"
|
22
|
+
o.bool "-c", "--create-team", "create the Keybase team if it does not exist"
|
23
|
+
o.bool "-f", "--force", "force creation (ignore overwrites, etc.)"
|
24
|
+
o.bool "-n", "--no-notify", "do not send a notification to session members"
|
25
|
+
o.bool "-d", "--delete", "unlink the session in addition to deconfiguration"
|
26
|
+
end
|
27
|
+
|
28
|
+
cli.dreck do
|
29
|
+
string :command
|
30
|
+
string :session
|
31
|
+
end
|
32
|
+
|
33
|
+
cli.ensure_session! :argument if cli.args[:command] == "rm"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see Command::Abstract#setup!
|
38
|
+
def setup!
|
39
|
+
@label = cli.args[:session]
|
40
|
+
@subcmd = cli.args[:command]
|
41
|
+
end
|
42
|
+
|
43
|
+
# @see Command::Abstract#validate!
|
44
|
+
def validate!
|
45
|
+
cli.die "Unknown subcommand: #{@subcmd}." unless SUBCOMMANDS.include?(@subcmd)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see Command::Abstract#run!
|
49
|
+
def run!
|
50
|
+
case @subcmd
|
51
|
+
when "new"
|
52
|
+
new_session
|
53
|
+
when "rm"
|
54
|
+
rm_session
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
# @return [void]
|
60
|
+
def new_session
|
61
|
+
if Config.session?(@label) && !cli.opts.force?
|
62
|
+
cli.die "Refusing to overwrite a session without --force."
|
63
|
+
end
|
64
|
+
|
65
|
+
if cli.opts[:team]
|
66
|
+
teams = Keybase::Local::Team.list_self_memberships.teams
|
67
|
+
|
68
|
+
unless teams.map(&:fq_name).include?(cli.opts[:team])
|
69
|
+
if cli.opts.create_team?
|
70
|
+
cli.guard do
|
71
|
+
Keybase::Local::Team.create_team cli.opts[:team]
|
72
|
+
Keybase::Local::Team.add_members cli.opts[:team], users: [{
|
73
|
+
username: Keybase::Local.current_user,
|
74
|
+
role: "admin",
|
75
|
+
}]
|
76
|
+
end
|
77
|
+
else
|
78
|
+
cli.die "No such team (either nonexistent or non-member)."
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
Config.configure_session(@label, team: cli.opts[:team], root: @label)
|
83
|
+
else
|
84
|
+
cli.die "Missing `-r', `--root' option." unless cli.opts[:root]
|
85
|
+
|
86
|
+
cli.opts[:users].each do |user|
|
87
|
+
cli.die "Nonexistent Keybase user: #{user}." unless Keybase::API.user? user
|
88
|
+
end
|
89
|
+
|
90
|
+
unless cli.opts[:users].include? Keybase::Local.current_user
|
91
|
+
cli.warn "You didn't include yourself in the user list, but I'll add you."
|
92
|
+
cli.opts[:users] << Keybase::Local.current_user
|
93
|
+
end
|
94
|
+
|
95
|
+
Config.configure_session(@label, users: cli.opts[:users], root: cli.opts[:root])
|
96
|
+
|
97
|
+
unless cli.opts.no_notify? && cli.opts[:users] != [Keybase::Local.current_user]
|
98
|
+
users = cli.opts[:users].join(",")
|
99
|
+
|
100
|
+
Keybase::Local::Chat.send_message cli.opts[:users], <<~MESSAGE
|
101
|
+
You've been added to a KBSecret session!
|
102
|
+
|
103
|
+
To access this session, please run the following:
|
104
|
+
|
105
|
+
```
|
106
|
+
$ kbsecret session new -r '#{cli.opts[:root]}' -u #{users} <label>
|
107
|
+
```
|
108
|
+
|
109
|
+
If you don't have KBSecret installed, you can install it from `gem`:
|
110
|
+
|
111
|
+
```
|
112
|
+
$ gem install kbsecret
|
113
|
+
```
|
114
|
+
MESSAGE
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# @api private
|
120
|
+
# @return [void]
|
121
|
+
def rm_session
|
122
|
+
cli.session.unlink! if cli.opts.delete?
|
123
|
+
Config.deconfigure_session @label
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KBSecret
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# The implementation of `kbsecret sessions`.
|
7
|
+
class Sessions < Abstract
|
8
|
+
def initialize(argv)
|
9
|
+
super(argv) do |cli|
|
10
|
+
cli.slop do |o|
|
11
|
+
o.banner = <<~HELP
|
12
|
+
Usage:
|
13
|
+
kbsecret sessions [options]
|
14
|
+
HELP
|
15
|
+
|
16
|
+
o.bool "-a", "--show-all", "show each session in depth (i.e. metadata)"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @see Command::Abstract#run!
|
22
|
+
def run!
|
23
|
+
Config.session_labels.each do |sess_name|
|
24
|
+
session_hash = Config.session(sess_name)
|
25
|
+
session = cli.guard { Session[sess_name] }
|
26
|
+
|
27
|
+
puts sess_name
|
28
|
+
|
29
|
+
next unless cli.opts.show_all?
|
30
|
+
|
31
|
+
if session_hash[:team]
|
32
|
+
puts <<~DETAIL
|
33
|
+
\tTeam: #{session_hash[:team]}
|
34
|
+
\tSecrets root: #{session_hash[:root]} (#{session.path})
|
35
|
+
DETAIL
|
36
|
+
else
|
37
|
+
puts <<~DETAIL
|
38
|
+
\tUsers: #{session_hash[:users].join(", ")}
|
39
|
+
\tSecrets root: #{session_hash[:root]} (#{session.path})
|
40
|
+
DETAIL
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module KBSecret
|
6
|
+
class CLI
|
7
|
+
module Command
|
8
|
+
# The implementation of `kbsecret stash-file`.
|
9
|
+
class StashFile < Abstract
|
10
|
+
def initialize(argv)
|
11
|
+
super(argv) do |cli|
|
12
|
+
cli.slop do |o|
|
13
|
+
o.banner = <<~HELP
|
14
|
+
Usage:
|
15
|
+
kbsecret stash-file <record> [file]
|
16
|
+
HELP
|
17
|
+
|
18
|
+
o.string "-s", "--session", "the session to add to", default: :default
|
19
|
+
o.bool "-f", "--force", "force creation (ignore overwrites, etc.)"
|
20
|
+
o.bool "-b", "--base64", "encode the file as base64"
|
21
|
+
end
|
22
|
+
|
23
|
+
cli.dreck do
|
24
|
+
string :label
|
25
|
+
string :filename
|
26
|
+
end
|
27
|
+
|
28
|
+
cli.ensure_session!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @see Command::Abstract#setup!
|
33
|
+
def setup!
|
34
|
+
@label = cli.args[:label]
|
35
|
+
@filename = cli.args[:filename]
|
36
|
+
end
|
37
|
+
|
38
|
+
# @see Command::Abstract#validate!
|
39
|
+
def validate!
|
40
|
+
if cli.session.record?(@label) && !cli.opts.force?
|
41
|
+
cli.die "Refusing to overwrite a record without --force."
|
42
|
+
end
|
43
|
+
|
44
|
+
cli.die "No such file." unless File.file?(@filename) || @filename == "-"
|
45
|
+
end
|
46
|
+
|
47
|
+
# @see Command::Abstract#run!
|
48
|
+
def run!
|
49
|
+
contents = if @filename == "-"
|
50
|
+
STDIN.read
|
51
|
+
elsif File.file?(@filename)
|
52
|
+
File.read(@filename)
|
53
|
+
end
|
54
|
+
|
55
|
+
contents = Base64.encode64(contents) if cli.opts.base64?
|
56
|
+
|
57
|
+
cli.guard { cli.session.add_record(:unstructured, @label, contents) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KBSecret
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# The implementation of `kbsecret todo`.
|
7
|
+
class Todo < Abstract
|
8
|
+
# The list of subcommands supported by `kbsecret todo`.
|
9
|
+
SUBCOMMANDS = %w[start suspend complete].freeze
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
super(argv) do |cli|
|
13
|
+
cli.slop cmds: SUBCOMMANDS do |o|
|
14
|
+
o.banner = <<~HELP
|
15
|
+
Usage:
|
16
|
+
kbsecret todo <start|suspend|complete> <record>
|
17
|
+
HELP
|
18
|
+
|
19
|
+
o.string "-s", "--session", "the session to search in", default: :default
|
20
|
+
end
|
21
|
+
|
22
|
+
cli.dreck do
|
23
|
+
string :command
|
24
|
+
string :label
|
25
|
+
end
|
26
|
+
|
27
|
+
cli.ensure_session!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see Command::Abstract#setup!
|
32
|
+
def setup!
|
33
|
+
@todo = cli.session[cli.args[:label]]
|
34
|
+
@subcmd = cli.args[:command]
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see Command::Abstract#validate!
|
38
|
+
def validate!
|
39
|
+
cli.die "No such todo record:." unless @todo && @todo.type == :todo
|
40
|
+
cli.die "Unknown subcommand: #{@subcmd}." unless SUBCOMMANDS.include?(@subcmd)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @see Command::Abstract#setup!
|
44
|
+
def run!
|
45
|
+
case @subcmd
|
46
|
+
when "start" then start_todo
|
47
|
+
when "suspend" then suspend_todo
|
48
|
+
when "complete" then complete_todo
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Starts the todo associated with the current invocation, unless already started.
|
53
|
+
# @return [void]
|
54
|
+
def start_todo
|
55
|
+
cli.die "That task is already started!" if @todo.started?
|
56
|
+
@todo.start!
|
57
|
+
puts "#{@todo.label}: '#{@todo.todo}' marked as started at #{@todo.start}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Suspends the todo associated with the current invocation, unless already suspended.
|
61
|
+
# @return [void]
|
62
|
+
def suspend_todo
|
63
|
+
cli.die "That task is already suspended!" if @todo.suspended?
|
64
|
+
@todo.suspend!
|
65
|
+
puts "#{@todo.label}: '#{@todo.todo}' marked as suspended at #{@todo.stop}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# Completes the todo associated with the current invocation, unless already completed.
|
69
|
+
# @return [void]
|
70
|
+
def complete_todo
|
71
|
+
cli.die "That task is already completed!" if @todo.completed?
|
72
|
+
@todo.complete!
|
73
|
+
puts "#{@todo.label}: '#{@todo.todo}' marked as completed at #{@todo.stop}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# we have to require abstract first because ruby's module resolution is bad
|
4
|
+
require_relative "command/abstract"
|
5
|
+
Dir[File.join(__dir__, "command/*.rb")].each { |t| require_relative t }
|
6
|
+
|
7
|
+
module KBSecret
|
8
|
+
class CLI
|
9
|
+
# The namespace for {KBSecret}'s internal commands.
|
10
|
+
module Command
|
11
|
+
module_function
|
12
|
+
|
13
|
+
# @return [Array<Class>] the class objects of all non-abstract commands
|
14
|
+
def command_classes
|
15
|
+
klasses = constants.map(&Command.method(:const_get)).grep(Class)
|
16
|
+
klasses.delete(Command::Abstract)
|
17
|
+
klasses
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array<String>] the CLI-friendly names of all commands
|
21
|
+
def command_names
|
22
|
+
command_classes.map(&:command_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param command_name [String] the CLI-friendly name of the command
|
26
|
+
# @return [Class, nil] the command class corresponding to the given name, or `nil`
|
27
|
+
def command_for(command_name)
|
28
|
+
klass = command_classes.find { |c| c.command_name == command_name }
|
29
|
+
# TODO: raise here if nil?
|
30
|
+
klass
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param command_name [String] the CLI-friendly name of the command to run
|
34
|
+
# @param args [Array<String>] the arguments, if any, to pass to the command
|
35
|
+
# @return [void]
|
36
|
+
def run!(command_name, *args)
|
37
|
+
klass = command_for command_name
|
38
|
+
cmd = klass.new(args)
|
39
|
+
cmd.setup!
|
40
|
+
cmd.validate!
|
41
|
+
cmd.run!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/kbsecret/cli.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "cli/command"
|
4
|
+
|
3
5
|
require "slop"
|
4
6
|
require "dreck"
|
5
7
|
require "abbrev"
|
@@ -47,14 +49,14 @@ module KBSecret
|
|
47
49
|
#
|
48
50
|
# cmd.opts # => Slop::Result
|
49
51
|
# cmd.args # => Dreck::Result
|
50
|
-
def self.create(&block)
|
51
|
-
CLI.new(&block)
|
52
|
+
def self.create(argv = ARGV, &block)
|
53
|
+
CLI.new(argv, &block)
|
52
54
|
end
|
53
55
|
|
54
56
|
# @api private
|
55
57
|
# @deprecated see {create}
|
56
|
-
def initialize
|
57
|
-
@argv =
|
58
|
+
def initialize(argv = ARGV)
|
59
|
+
@argv = argv.dup
|
58
60
|
guard { yield self }
|
59
61
|
end
|
60
62
|
|
data/lib/kbsecret/config.rb
CHANGED
@@ -65,7 +65,7 @@ module KBSecret
|
|
65
65
|
# Writes the user's configuration to disk.
|
66
66
|
# @return [void]
|
67
67
|
def self.sync!
|
68
|
-
File.
|
68
|
+
File.write(CONFIG_FILE, @config.to_yaml)
|
69
69
|
end
|
70
70
|
|
71
71
|
# Retrieve a configured value.
|
@@ -167,8 +167,6 @@ module KBSecret
|
|
167
167
|
user_config = if File.exist?(CONFIG_FILE)
|
168
168
|
YAML.load_file(CONFIG_FILE)
|
169
169
|
else
|
170
|
-
FileUtils.mkdir_p CONFIG_DIR
|
171
|
-
FileUtils.mkdir_p CUSTOM_TYPES_DIR
|
172
170
|
DEFAULT_CONFIG
|
173
171
|
end
|
174
172
|
|
@@ -182,6 +180,9 @@ module KBSecret
|
|
182
180
|
@config[:sessions].merge!(DEFAULT_SESSION)
|
183
181
|
@config[:generators].merge!(DEFAULT_GENERATOR)
|
184
182
|
|
183
|
+
FileUtils.mkdir_p CONFIG_DIR
|
184
|
+
FileUtils.mkdir_p CUSTOM_TYPES_DIR
|
185
|
+
|
185
186
|
sync!
|
186
187
|
end
|
187
188
|
end
|
@@ -5,7 +5,7 @@ require "forwardable"
|
|
5
5
|
|
6
6
|
module KBSecret
|
7
7
|
module Record
|
8
|
-
# Represents an abstract
|
8
|
+
# Represents an abstract {KBSecret} record that can be subclassed to produce
|
9
9
|
# more useful records.
|
10
10
|
# @abstract
|
11
11
|
class Abstract
|
@@ -61,7 +61,7 @@ module KBSecret
|
|
61
61
|
@timestamp = Time.now.to_i
|
62
62
|
sync!
|
63
63
|
end
|
64
|
-
]
|
64
|
+
], __FILE__, __LINE__ - 10
|
65
65
|
end
|
66
66
|
|
67
67
|
# @param field [Symbol] the field's name
|
data/lib/kbsecret/record.rb
CHANGED
@@ -12,22 +12,24 @@ Dir[File.join(__dir__, "record/*.rb")].each { |t| require_relative t }
|
|
12
12
|
module KBSecret
|
13
13
|
# The namespace for {KBSecret} record types.
|
14
14
|
module Record
|
15
|
+
module_function
|
16
|
+
|
15
17
|
# @return [Array<Class>] the class objects of all non-abstract record types
|
16
|
-
def
|
18
|
+
def record_classes
|
17
19
|
klasses = constants.map(&Record.method(:const_get)).grep(Class)
|
18
20
|
klasses.delete(Record::Abstract)
|
19
21
|
klasses
|
20
22
|
end
|
21
23
|
|
22
24
|
# @return [Array<Symbol>] the types of all records
|
23
|
-
def
|
25
|
+
def record_types
|
24
26
|
record_classes.map(&:type)
|
25
27
|
end
|
26
28
|
|
27
29
|
# @param type [String, Symbol] the record type
|
28
30
|
# @return [Class] the record class corresponding to the given type
|
29
31
|
# @raise [Exceptions::RecordTypeUnknownError] if the requested type is unknown
|
30
|
-
def
|
32
|
+
def class_for(type)
|
31
33
|
klass = record_classes.find { |c| c.type == type.to_sym }
|
32
34
|
raise Exceptions::RecordTypeUnknownError, type unless klass
|
33
35
|
klass
|
@@ -35,7 +37,7 @@ module KBSecret
|
|
35
37
|
|
36
38
|
# @param type [String, Symbol] the record type
|
37
39
|
# @return [Boolean] whether a record class exists of the given type
|
38
|
-
def
|
40
|
+
def type?(type)
|
39
41
|
return false unless type
|
40
42
|
record_types.include?(type.to_sym)
|
41
43
|
end
|
@@ -46,11 +48,11 @@ module KBSecret
|
|
46
48
|
# @return [Record::AbstractRecord] the loaded record
|
47
49
|
# @raise [Exceptions::RecordLoadError] if an error occurs during record loading
|
48
50
|
# @api private
|
49
|
-
def
|
51
|
+
def load_record!(session, path)
|
50
52
|
hsh = JSON.parse(File.read(path), symbolize_names: true)
|
51
53
|
klass = class_for hsh[:type]
|
52
|
-
klass
|
53
|
-
rescue JSON::JSONError
|
54
|
+
klass.load!(session, hsh)
|
55
|
+
rescue Exceptions::RecordTypeUnknownError, JSON::JSONError
|
54
56
|
raise Exceptions::RecordLoadError, path
|
55
57
|
end
|
56
58
|
end
|
data/lib/kbsecret/version.rb
CHANGED