leeloo 0.0.16 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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