leeloo 0.0.16 → 0.4.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
  SHA256:
3
- metadata.gz: 9214d0cb6dfd5872b74cd14707a591f5550b5c80bb7df2492c056009001d9cd8
4
- data.tar.gz: cb5bb412d04bbafe54d043eb9dd272b07b71e11a2c44ff0f42447632a6a156a8
3
+ metadata.gz: 7117e8aaf24a2b7dec0e8d516f81aa6491b9d1e8360907d99e1f41848fdeae87
4
+ data.tar.gz: e687c77e4e8a17f9bbe9ece480da789c80327f1d6bc8831da04ddd1a7b0d677a
5
5
  SHA512:
6
- metadata.gz: f2ad8d579c173689b65c7216f2705fa82e764846503c6b028019002f117e7caeb0085bbdf75f9e792d8b5d54265e2e226543c4e409c264df46a12f8b3893f315
7
- data.tar.gz: 9d91319a9b71a4786b361e3068aea55c767ddf0acb8e619e7f115b97df4b23fd0859d1cb77d0e68d81215de2fe19a1e49c5273743734755dbae53fa9c94ca3fa
6
+ metadata.gz: 8690b0dd0e1e8788332c30ae6c54a144749aba2b04574ddaabfd3336b5fbf1a3b289943d3b8ec098ec07d139c73ff0095667c2cfc7588c9eeef60a5807d72754
7
+ data.tar.gz: 5e5f54a09b03a45e9b574adbad70268d1aec1cdc4fbc7adf0228798a115130bbddd88ca560cf70c54fb6960dc0d719be86513b5d01acb6f36f8e5d0724abcf18
@@ -1,12 +1,14 @@
1
1
  require 'leeloo/version'
2
+ require 'leeloo/controller'
2
3
  require 'leeloo/command'
3
- require 'leeloo/secret'
4
+ require 'leeloo/preferences'
4
5
  require 'leeloo/keystore'
5
- require 'leeloo/config'
6
+ require 'leeloo/secret'
7
+ require 'leeloo/output'
8
+ require 'leeloo/server'
6
9
 
7
10
  module Leeloo
8
11
  def self.start
9
- Config.load
10
12
  Command.new.run
11
13
  end
12
14
  end
@@ -1,7 +1,5 @@
1
1
  require 'commander/import'
2
2
  require 'securerandom'
3
- require 'clipboard'
4
-
5
3
 
6
4
  class String
7
5
  def truncate(max)
@@ -27,106 +25,101 @@ module Leeloo
27
25
 
28
26
  default_command :"list"
29
27
 
30
- command :"init" do |c|
31
- c.syntax = 'leeloo init'
32
- c.description = "Initialize leeloo and private keystore"
28
+ command :list do |c|
29
+ c.syntax = 'leeloo list [options]'
30
+ c.description = "Display secrets list of keystore"
31
+ c.option '--ascii', nil, 'display secrets without unicode tree'
32
+ c.option '--keystore STRING', String, 'a selected keystore'
33
+
33
34
  c.action do |args, options|
34
- abort("a secret key PGP is mandatory") if Keystore::secret_key_empty?
35
- Config::init
36
- say "Initialization completed"
35
+ SecretsController.new(options).display
37
36
  end
38
37
  end
39
38
 
40
- command :"list-keystore" do |c|
41
- c.syntax = 'leeloo keystore'
42
- c.description = "Display keystores list"
39
+ command :search do |c|
40
+ c.syntax = 'leeloo search name'
41
+ c.description = "Display secrets containing name pattern"
43
42
  c.option '--ascii', nil, 'display secrets without unicode tree'
43
+ c.option '--keystore STRING', String, 'a selected keystore'
44
44
 
45
45
  c.action do |args, options|
46
-
47
- Config::list_keystores options.ascii
46
+ abort "name is missing" unless args.length == 1
47
+ name = args.first
48
+ ctl = SecretsController.new(options)
49
+ ctl.search(name)
50
+ ctl.display
48
51
  end
49
52
  end
50
- alias_command :keystore, :"list-keystore"
51
53
 
52
- command :"list-secret" do |c|
53
- c.syntax = 'leeloo list [options]'
54
- c.description = "Display secrets list of keystore"
55
- c.option '--keystore STRING', String, 'a selected keystore'
54
+ command :keystore do |c|
55
+ c.syntax = 'leeloo keystores'
56
+ c.description = "Display current keystores"
56
57
  c.option '--ascii', nil, 'display secrets without unicode tree'
57
58
 
58
59
  c.action do |args, options|
59
- options.default :keystore => Config.default['keystore']
60
-
61
- Secret::list Config.get_keystore(options.keystore), options.ascii
60
+ KeystoreController.new(options).display
62
61
  end
63
62
  end
64
- alias_command :list, :"list-secret"
65
- alias_command :secrets, :"list-secret"
66
63
 
67
- command :"add-keystore" do |c|
68
- c.syntax = 'leeloo add-keystore <name> <path>'
69
- c.description = "Add a new keystore"
64
+ command "keystore remove" do |c|
65
+ c.syntax = 'leeloo keystore remove <name>'
66
+ c.description = "remove a keystore (path/to/keystore is not destroyed)"
70
67
 
71
- c.action do |args, options|
72
-
73
- abort "name or path are missing" unless args.length == 2
68
+ c.action do |args, options|args
69
+ abort "name is missing" unless args.length == 1
74
70
  name = args.first
75
- keystore = args.last
76
-
77
- Keystore.add_keystore name, keystore
78
- Config.add_keystore name, keystore
79
- say "keystore #{name} added"
71
+ ctl = KeystoreController.new(options)
72
+ ctl.remove(name)
73
+ ctl.display
80
74
  end
81
75
  end
82
76
 
83
- command :"remote-keystore" do |c|
84
- c.syntax = "leeloo remote <repository>"
85
- c.description = "add a remote repository to synchronize keystore"
86
- c.option '--keystore STRING', String, 'a selected keystore'
77
+ command "keystore add" do |c|
78
+ c.syntax = 'leeloo keystore add <name> <path/to/keystore>'
79
+ c.description = "add a keystore"
87
80
 
88
81
  c.action do |args, options|
89
- abort "repository is missing" unless args.length == 1
90
- repository = args.first
91
- Keystore.add_remote Config.get_keystore(options.keystore), repository
92
- say "remote added successfully"
82
+ abort "name or path is missing" unless args.length == 2
83
+ name = args.first
84
+ path = args.last
85
+ ctl = KeystoreController.new(options)
86
+ ctl.add(name, path)
87
+ ctl.display
93
88
  end
94
89
  end
95
- alias_command :remote, :"remote-keystore"
96
90
 
97
- command :"sync-keystore" do |c|
98
- c.syntax = "leeloo sync"
99
- c.description = "sync secrets with git repository (if configured)"
100
- c.option '--keystore STRING', String, 'a selected keystore'
91
+ command "keystore default" do |c|
92
+ c.syntax = 'leeloo keystore default name'
93
+ c.description = "set the default keystore"
101
94
 
102
95
  c.action do |args, options|
103
- options.default :keystore => Config.default['keystore']
104
- synchronized = Keystore.sync_keystore Config.get_keystore(options.keystore)
105
- if synchronized
106
- say "secrets synchronized successfully"
107
- else
108
- abort "call remote-keystore before sync-keystore"
109
- end
96
+ abort "name is missing" unless args.length == 1
97
+ name = args.first
98
+ ctl = KeystoreController.new(options)
99
+ ctl.set_default(name)
100
+ ctl.display
110
101
  end
111
102
  end
112
- alias_command :sync, :"sync-keystore"
113
103
 
114
- command :"sign-secret" do |c|
115
- c.syntax = 'leeloo sign'
116
- c.description = "(re)sign all secrets from a given keystore"
104
+ command :read do |c|
105
+ c.syntax = 'leeloo read <name>'
106
+ c.description = "Display a secret from a keystore"
107
+ c.option '--keystore STRING', String, 'a selected keystore'
108
+ c.option '--clipboard', nil, 'copy to clipboard'
117
109
  c.option '--keystore STRING', String, 'a selected keystore'
118
110
 
119
111
  c.action do |args, options|
120
- options.default :keystore => Config.default['keystore']
121
- signed = Secret.sign_secrets Config.get_keystore(options.keystore)
122
- say "secrets signed successfully" if signed
112
+ abort "name is missing" unless args.length == 1
113
+ name = args.first
114
+ ctl = SecretController.new(options)
115
+ ctl.read(name)
116
+ ctl.display
123
117
  end
124
118
  end
125
- alias_command :sign, :"sign-secret"
126
119
 
127
- command :"add-secret" do |c|
128
- c.syntax = 'leeloo add <name>'
129
- c.description = "Add a new secret in a keystore"
120
+ command :write do |c|
121
+ c.syntax = 'leeloo write <name> <secret>'
122
+ c.description = "Write a secret from a keystore"
130
123
  c.option '--keystore STRING', String, 'a selected keystore'
131
124
  c.option '--generate INTEGER', Integer, 'a number of randomized characters'
132
125
  c.option '--stdin', nil, 'secret given by stdin pipe'
@@ -135,87 +128,101 @@ module Leeloo
135
128
  c.action do |args, options|
136
129
  abort "name is missing" unless args.length == 1
137
130
  name = args.first
131
+ ctl = SecretController.new(options)
132
+ ctl.write(name)
133
+ ctl.display
134
+ end
135
+ end
138
136
 
139
- options.default :keystore => Config.default['keystore']
140
- keystore = Config.get_keystore(options.keystore)
141
-
142
- secret = nil
143
- secret = STDIN.read if options.stdin
144
- secret = SecureRandom.base64(32).truncate(options.generate.to_i) if options.generate
145
-
146
- unless secret
147
- secret = password "secret"
148
- confirm = password "confirm it"
149
- abort "not the same secret" unless secret == confirm
150
- end
137
+ command :translate do |c|
138
+ c.syntax = 'leeloo translate'
139
+ c.description = "translate stdin by replacing key ${my/secret} by the current value"
140
+ c.option '--keystore STRING', String, 'a selected keystore'
151
141
 
152
- Secret.add_secret keystore, name, secret
153
- say "#{name} added successfully"
154
- Clipboard.copy secret if options.clipboard
155
- say secret unless options.clipboard
142
+ c.action do |args, options|
143
+ ctl = TranslateController.new(options)
144
+ ctl.translate
145
+ ctl.display
156
146
  end
157
147
  end
158
- alias_command :write, :"add-secret"
159
- alias_command :add, :"add-secret"
160
- alias_command :insert, :"add-secret"
161
- alias_command :set, :"add-secret"
162
148
 
163
- command :"read-secret" do |c|
164
- c.syntax = 'leeloo read <name>'
165
- c.description = "Display a secret from a keystore"
149
+ command :remove do |c|
150
+ c.syntax = 'leeloo delete <name>'
151
+ c.description = "Delete a secret from a keystore"
166
152
  c.option '--keystore STRING', String, 'a selected keystore'
167
- c.option '--clipboard', nil, 'copy to clipboard'
168
- c.option '--to /path/to/file', String, 'for binary file'
169
153
 
170
154
  c.action do |args, options|
171
155
  abort "name is missing" unless args.length == 1
172
156
  name = args.first
157
+ ctl = SecretController.new(options)
158
+ ctl.remove(name)
159
+ ctl.display
160
+ end
161
+ end
162
+
163
+ command :sync do |c|
164
+ c.syntax = 'leeloo sync'
165
+ c.description = "Synchronize a keystore"
166
+ c.option '--keystore STRING', String, 'a selected keystore'
167
+
168
+ c.action do |args, options|
169
+ ctl = KeystoreController.new(options)
170
+ ctl.sync
171
+ ctl.display
172
+ end
173
+ end
173
174
 
174
- options.default :keystore => Config.default['keystore']
175
- keystore = Config.get_keystore(options.keystore)
175
+ command :init do |c|
176
+ c.syntax = 'leeloo init'
177
+ c.description = "Initialize a keystore"
178
+ c.option '--keystore STRING', String, 'a selected keystore'
176
179
 
177
- begin
178
- secret = Secret.read_secret keystore, name
180
+ c.action do |args, options|
181
+ ctl = KeystoreController.new(options)
182
+ ctl.init
183
+ ctl.display
184
+ end
185
+ end
179
186
 
180
- if (options.to)
181
- File.open(options.to, 'w') { |file| file.write(secret) }
182
- say "stored to #{options.to}"
183
- else
184
- say secret unless options.clipboard
185
- Clipboard.copy secret if options.clipboard
186
- end
187
+ command :share do |c|
188
+ c.syntax = 'leeloo share <name>'
189
+ c.description = "share a secret with someone"
190
+ c.option '--keystore STRING', String, 'a selected keystore'
187
191
 
188
- rescue
189
- abort "unable to find #{name}"
190
- end
192
+ c.action do |args, options|
193
+ abort "name is missing" unless args.length == 1
194
+ name = args.first
195
+ ctl = ShareController.new(options)
196
+ ctl.token(name)
197
+ ctl.display
198
+ ctl.start_server
191
199
  end
192
- alias_command :read, :"read-secret"
193
- alias_command :get, :"read-secret"
194
200
  end
195
201
 
196
- command :"remove-secret" do |c|
197
- c.syntax = 'leeloo remove <name>'
198
- c.description = "Remove a secret from a keystore"
202
+ command :token do |c|
203
+ c.syntax = 'leeloo token <name>'
204
+ c.description = "generate an access token for a given secret"
199
205
  c.option '--keystore STRING', String, 'a selected keystore'
200
206
 
201
207
  c.action do |args, options|
202
208
  abort "name is missing" unless args.length == 1
203
209
  name = args.first
210
+ ctl = ShareController.new(options)
211
+ ctl.token(name)
212
+ ctl.display
213
+ end
214
+ end
204
215
 
205
- options.default :keystore => Config.default['keystore']
206
- keystore = Config.get_keystore(options.keystore)
216
+ command :server do |c|
217
+ c.syntax = 'leeloo server'
218
+ c.description = "start a server access token"
207
219
 
208
- begin
209
- Secret.delete_secret keystore, name
210
- say "#{name} removed successfully"
211
- rescue
212
- abort "unable to find #{name}"
213
- end
220
+ c.action do |args, options|
221
+ ctl = ShareController.new(options)
222
+ ctl.start_server
214
223
  end
215
- alias_command :remove, :"remove-secret"
216
- alias_command :delete, :"remove-secret"
217
- alias_command :erase, :"remove-secret"
218
224
  end
225
+
219
226
  end
220
227
  end
221
228
  end
@@ -0,0 +1,122 @@
1
+ module Leeloo
2
+ class OutputFactory
3
+ def self.create options
4
+ output = nil
5
+ if options.ascii
6
+ output = Ascii.new
7
+ else
8
+ output = Terminal.new
9
+ end
10
+ if options.clipboard
11
+ ClipboardOutputDecorator.new output
12
+ else
13
+ output
14
+ end
15
+ end
16
+ end
17
+
18
+ class Controller
19
+ def display
20
+ end
21
+ end
22
+
23
+ class PrivateLocalFileSystemController < Controller
24
+ def initialize options
25
+ @preferences = PrivateLocalFileSystemPreferences.new.load
26
+ @keystore = @preferences.keystore(options.keystore)
27
+ @output = OutputFactory.create(options)
28
+ @options = options
29
+ end
30
+ end
31
+
32
+ class SecretsController < PrivateLocalFileSystemController
33
+ def initialize options
34
+ super options
35
+ @secrets = @preferences.keystore(@options.keystore).secrets
36
+ end
37
+ def search name
38
+ @secrets = @secrets.select { |secret| secret.name.downcase.include? name.downcase } || []
39
+ end
40
+ def display
41
+ @output.render_secrets @secrets
42
+ end
43
+ end
44
+
45
+ class SecretController < PrivateLocalFileSystemController
46
+ def read name
47
+ @secret = @keystore.secret_from_name(name)
48
+ end
49
+ def write name
50
+ phrase = nil
51
+
52
+ phrase = STDIN.read if @options.stdin
53
+ phrase = SecureRandom.base64(32).truncate(@options.generate.to_i) if @options.generate
54
+
55
+ unless phrase
56
+ phrase = password "secret"
57
+ confirm = password "confirm it"
58
+ abort "not the same secret" unless phrase == confirm
59
+ end
60
+
61
+ @secret = @keystore.secret_from_name(name)
62
+ @secret.write(phrase)
63
+ end
64
+ def remove name
65
+ @secret = @keystore.secret_from_name(name)
66
+ @secret.erase
67
+ end
68
+ def display
69
+ @output.render_secret @secret
70
+ end
71
+ end
72
+
73
+ class TranslateController < PrivateLocalFileSystemController
74
+ def translate
75
+ @text = STDIN.read
76
+ @text.scan(/\$\{.*\}/).each do |secret|
77
+ begin
78
+ @text.gsub! secret, (@keystore.secret_from_name(secret[2..-2])).read.to_s.strip
79
+ rescue => exception
80
+ # silent
81
+ end
82
+ end
83
+ end
84
+ def display
85
+ @output.render_text @text
86
+ end
87
+ end
88
+
89
+ class KeystoreController < PrivateLocalFileSystemController
90
+ def add name, path
91
+ @preferences.add_keystore({"name" => name, "path" => path, "cypher" => "gpg", "vc" => "git"})
92
+ @preferences.keystore(name).init
93
+ end
94
+ def remove name
95
+ @preferences.remove_keystore name
96
+ end
97
+ def set_default name
98
+ @preferences.set_default_keystore name
99
+ end
100
+ def sync
101
+ @keystore.sync
102
+ end
103
+ def init
104
+ @keystore.init
105
+ end
106
+ def display
107
+ @output.render_preferences @preferences
108
+ end
109
+ end
110
+
111
+ class ShareController < PrivateLocalFileSystemController
112
+ def token name
113
+ @footprint = @keystore.footprint_of(name)
114
+ end
115
+ def start_server
116
+ Server.new.start @preferences
117
+ end
118
+ def display
119
+ @output.render_footprint @footprint
120
+ end
121
+ end
122
+ end