leeloo 0.4.0 → 0.5.2

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: 45be4ecf01ce08cd7317d3c6f9d8a612d999b972efdcbfe322a964a06f77a303
4
- data.tar.gz: bd3a8767c2c1d70cdc21856b180cb7f3651c9777471f70a35af810130650d4ef
3
+ metadata.gz: dd35144ab160594e6b4c3d05ea7eeaf175cc99fb79fc3b93cea31000df120ab3
4
+ data.tar.gz: 32537a5e8670c43d6463e1d713a61f49a7601d435957ecd98eeaf48c2a8658bd
5
5
  SHA512:
6
- metadata.gz: 1ec00409e8ac173872aac71537aad50d40f93a24634b1b101b6f46b59d658696c2480d6e5157fd7cd1d864acc4cc6ec5e421eed6ff74f560c4e25f57ecd7bd27
7
- data.tar.gz: 1d259f7fc29192bcf6d1cd3a7f7f92d8e9244d79e11741f2fce8f82f8aab0d7cfd5c96ad120c16aa018b8c69540e937e6986a8f18a297a7d137d748e5e19511d
6
+ metadata.gz: 8469474876e92a015bce39b25cfc418c1f9d55b763b8de44763121eb4e379c64716c43b2fd2789c536cf0a8891e828e0c1782519ae3d549054f8527a2bd2c50a
7
+ data.tar.gz: d98949b84ac056b71302f038748da0ad6986a81af3a63fad52b73c7db204c91d87e8cd4b4b6db02c4049e379a9817278b77d453bf04b53f6f46089317e12c907
@@ -23,11 +23,34 @@ module Leeloo
23
23
  program :help, 'GitHub', 'https://github.com/sylvek'
24
24
  program :help_formatter, :compact
25
25
 
26
- default_command :"list"
26
+ default_command :wrapper
27
+
28
+ command :wrapper do |c|
29
+ c.syntax = 'leeloo [options]'
30
+ c.description = "Display secrets"
31
+ c.option '--ascii', nil, 'display secrets without unicode tree'
32
+ c.option '--keystore STRING', String, 'a selected keystore'
33
+ c.option '--clipboard', nil, 'copy to clipboard'
34
+ c.action do |args, options|
35
+ unless args == []
36
+ name = args.first
37
+ ctl = SecretController.new(options)
38
+ ctl.read(name)
39
+ ctl.display
40
+ else
41
+ SecretsController.new(options).display
42
+ end
43
+ end
44
+ end
45
+
46
+ command :init do |c|
47
+ c.syntax = 'leeloo init'
48
+ c.description = "Just to be compatible with passwordstore.org"
49
+ end
27
50
 
28
51
  command :list do |c|
29
52
  c.syntax = 'leeloo list [options]'
30
- c.description = "Display secrets list of keystore"
53
+ c.description = "Display secrets list of stored on a keystore"
31
54
  c.option '--ascii', nil, 'display secrets without unicode tree'
32
55
  c.option '--keystore STRING', String, 'a selected keystore'
33
56
 
@@ -61,7 +84,7 @@ module Leeloo
61
84
  end
62
85
  end
63
86
 
64
- command "keystore remove" do |c|
87
+ command :"keystore remove" do |c|
65
88
  c.syntax = 'leeloo keystore remove <name>'
66
89
  c.description = "remove a keystore (path/to/keystore is not destroyed)"
67
90
 
@@ -74,7 +97,7 @@ module Leeloo
74
97
  end
75
98
  end
76
99
 
77
- command "keystore add" do |c|
100
+ command :"keystore add" do |c|
78
101
  c.syntax = 'leeloo keystore add <name> <path/to/keystore>'
79
102
  c.description = "add a keystore"
80
103
 
@@ -88,7 +111,7 @@ module Leeloo
88
111
  end
89
112
  end
90
113
 
91
- command "keystore default" do |c|
114
+ command :"keystore default" do |c|
92
115
  c.syntax = 'leeloo keystore default name'
93
116
  c.description = "set the default keystore"
94
117
 
@@ -101,12 +124,63 @@ module Leeloo
101
124
  end
102
125
  end
103
126
 
127
+ command :key do |c|
128
+ c.syntax = 'leeloo keys'
129
+ c.description = "list keys from this keystore"
130
+ c.option '--ascii', nil, 'display secrets without unicode tree'
131
+ c.option '--keystore STRING', String, 'a selected keystore'
132
+
133
+ c.action do |args, options|
134
+ ctl = KeysController.new(options)
135
+ ctl.display
136
+ end
137
+ end
138
+
139
+ command :"key sync" do |c|
140
+ c.syntax = 'leeloo keys sync'
141
+ c.description = "synchronize secrets with keys"
142
+ c.option '--keystore STRING', String, 'a selected keystore'
143
+
144
+ c.action do |args, options|
145
+ ctl = KeysController.new(options)
146
+ ctl.sync
147
+ ctl.display
148
+ end
149
+ end
150
+
151
+ command :"key add" do |c|
152
+ c.syntax = 'leeloo key add <email>'
153
+ c.description = "add a dedicated key"
154
+ c.option '--keystore STRING', String, 'a selected keystore'
155
+
156
+ c.action do |args, options|
157
+ abort "email is missing" unless args.length == 1
158
+ email = args.first
159
+ ctl = KeysController.new(options)
160
+ ctl.add_key(email)
161
+ ctl.display
162
+ end
163
+ end
164
+
165
+ command :"key remove" do |c|
166
+ c.syntax = 'leeloo key remove <email>'
167
+ c.description = "remove a dedicated key"
168
+ c.option '--keystore STRING', String, 'a selected keystore'
169
+
170
+ c.action do |args, options|
171
+ abort "email is missing" unless args.length == 1
172
+ email = args.first
173
+ ctl = KeysController.new(options)
174
+ ctl.remove_key(email)
175
+ ctl.display
176
+ end
177
+ end
178
+
104
179
  command :read do |c|
105
180
  c.syntax = 'leeloo read <name>'
106
181
  c.description = "Display a secret from a keystore"
107
182
  c.option '--keystore STRING', String, 'a selected keystore'
108
183
  c.option '--clipboard', nil, 'copy to clipboard'
109
- c.option '--keystore STRING', String, 'a selected keystore'
110
184
 
111
185
  c.action do |args, options|
112
186
  abort "name is missing" unless args.length == 1
@@ -133,6 +207,23 @@ module Leeloo
133
207
  ctl.display
134
208
  end
135
209
  end
210
+ alias_command :insert, :write
211
+
212
+ command :generate do |c|
213
+ c.syntax = 'leeloo generate <name> <number of randomized characters>'
214
+ c.description = "Generate a secret from a keystore"
215
+ c.option '--keystore STRING', String, 'a selected keystore'
216
+ c.option '--clipboard', nil, 'copy to clipboard'
217
+
218
+ c.action do |args, options|
219
+ abort "name or number are missing" unless args.length == 2
220
+ name = args.first
221
+ options.__hash__[:generate] = args.last.to_i
222
+ ctl = SecretController.new(options)
223
+ ctl.write(name)
224
+ ctl.display
225
+ end
226
+ end
136
227
 
137
228
  command :translate do |c|
138
229
  c.syntax = 'leeloo translate'
@@ -156,11 +247,13 @@ module Leeloo
156
247
  name = args.first
157
248
  ctl = SecretController.new(options)
158
249
  ctl.remove(name)
159
- ctl.display
250
+ #ctl.display
251
+ puts "done."
160
252
  end
161
253
  end
254
+ alias_command :rm, :remove
162
255
 
163
- command :sync do |c|
256
+ command :"keystore sync" do |c|
164
257
  c.syntax = 'leeloo sync'
165
258
  c.description = "Synchronize a keystore"
166
259
  c.option '--keystore STRING', String, 'a selected keystore'
@@ -172,7 +265,18 @@ module Leeloo
172
265
  end
173
266
  end
174
267
 
175
- command :init do |c|
268
+ command :"keystore export" do |c|
269
+ c.syntax = 'leeloo export'
270
+ c.description = "Export all secrets from a keystore"
271
+ c.option '--keystore STRING', String, 'a selected keystore'
272
+
273
+ c.action do |args, options|
274
+ ctl = ExportController.new(options)
275
+ ctl.display
276
+ end
277
+ end
278
+
279
+ command :"keystore init" do |c|
176
280
  c.syntax = 'leeloo init'
177
281
  c.description = "Initialize a keystore"
178
282
  c.option '--keystore STRING', String, 'a selected keystore'
@@ -32,16 +32,46 @@ module Leeloo
32
32
  class SecretsController < PrivateLocalFileSystemController
33
33
  def initialize options
34
34
  super options
35
- @secrets = @preferences.keystore(@options.keystore).secrets
35
+ @secrets = @keystore.secrets
36
36
  end
37
37
  def search name
38
38
  @secrets = @secrets.select { |secret| secret.name.downcase.include? name.downcase } || []
39
39
  end
40
+ def list
41
+ @secrets
42
+ end
40
43
  def display
41
44
  @output.render_secrets @secrets
42
45
  end
43
46
  end
44
47
 
48
+ class ExportController < PrivateLocalFileSystemController
49
+ def display
50
+ @keystore.secrets.each do |secret|
51
+ @output.render_name_and_secret(secret.name, @keystore.secret_from_name(secret.name))
52
+ end
53
+ end
54
+ end
55
+
56
+ class KeysController < PrivateLocalFileSystemController
57
+ def add_key email
58
+ @keystore.add_key(email)
59
+ end
60
+ def remove_key email
61
+ @keystore.remove_key(email)
62
+ end
63
+ def sync
64
+ @keystore.secrets.each do |secret|
65
+ phrase = @keystore.secret_from_name(secret.name).read
66
+ @keystore.secret_from_name(secret.name).write(phrase)
67
+ end
68
+ end
69
+ def display
70
+ @keys = @keystore.keys
71
+ @output.render_keys @keys
72
+ end
73
+ end
74
+
45
75
  class SecretController < PrivateLocalFileSystemController
46
76
  def read name
47
77
  @secret = @keystore.secret_from_name(name)
@@ -53,8 +83,8 @@ module Leeloo
53
83
  phrase = SecureRandom.base64(32).truncate(@options.generate.to_i) if @options.generate
54
84
 
55
85
  unless phrase
56
- phrase = password "secret"
57
- confirm = password "confirm it"
86
+ phrase = password "Enter password for #{name}"
87
+ confirm = password "Confirm it"
58
88
  abort "not the same secret" unless phrase == confirm
59
89
  end
60
90
 
@@ -72,6 +72,7 @@ module Leeloo
72
72
  def initialize name, path
73
73
  super name
74
74
  @path = path
75
+ FileUtils.touch "#{@path}/.gpg-id"
75
76
  FileUtils.mkdir_p "#{@path}/secrets"
76
77
  end
77
78
 
@@ -79,6 +80,10 @@ module Leeloo
79
80
  find_secrets "#{@path}/secrets"
80
81
  end
81
82
 
83
+ def keys
84
+ []
85
+ end
86
+
82
87
  def find_secrets path
83
88
  elements = []
84
89
  Dir.glob("#{path}/**") do |element|
@@ -121,7 +126,10 @@ module Leeloo
121
126
  def initialize name, path
122
127
  super name, path
123
128
  FileUtils.mkdir_p "#{@path}/keys"
129
+ populate_recipients
130
+ end
124
131
 
132
+ def populate_recipients
125
133
  @recipients = []
126
134
  Dir.glob("#{path}/keys/*") { |key| @recipients << File.basename(key) }
127
135
  @recipients.each { |key| GPGME::Key.import(File.open("#{path}/keys/#{key}")) }
@@ -129,7 +137,30 @@ module Leeloo
129
137
 
130
138
  def init
131
139
  super
132
- GPGME::Key.find(:public, nil, ).each { |key| key.export(:output => File.open("#{path}/keys/#{key.uids.first.email}", "w+")) }
140
+ File.write("#{@path}/keys/do_not_remove_me", "do not remove me")
141
+ end
142
+
143
+ def keys
144
+ available = GPGME::Key.find(:public, nil, ).map { |key| key.email }
145
+ actual = Dir.glob("#{@path}/keys/**").map { |path| path.split('/').last }
146
+ available.map { |email| actual.include?(email) ? "#{email}::true" : "#{email}::false" }
147
+ end
148
+
149
+ def add_key email
150
+ paths = []
151
+ GPGME::Key.find(:public, email).each do |key|
152
+ key.export(:output => File.open("#{path}/keys/#{key.uids.first.email}", "w+"))
153
+ paths << "#{path}/keys/#{key.uids.first.email}"
154
+ end
155
+ return paths
156
+ end
157
+
158
+ def remove_key email
159
+ if File.exist?("#{path}/keys/#{email}")
160
+ File.delete("#{path}/keys/#{email}")
161
+ return "#{path}/keys/#{email}"
162
+ end
163
+ return nil
133
164
  end
134
165
 
135
166
  def secret_of path
@@ -172,6 +203,25 @@ module Leeloo
172
203
  secret_of @keystore.secret_from_name(element)
173
204
  end
174
205
 
206
+ def keys
207
+ @keystore.keys
208
+ end
209
+
210
+ def add_key email
211
+ @keystore.add_key(email).each do |path|
212
+ @git.add path
213
+ @git.commit "#{email} added"
214
+ end
215
+ end
216
+
217
+ def remove_key email
218
+ deleted = @keystore.remove_key email
219
+ if deleted
220
+ @git.add deleted
221
+ @git.commit "#{email} removed"
222
+ end
223
+ end
224
+
175
225
  def secrets
176
226
  @keystore.secrets
177
227
  end
data/lib/leeloo/output.rb CHANGED
@@ -21,6 +21,12 @@ module Leeloo
21
21
  def render_text text
22
22
  end
23
23
 
24
+ def render_name_and_secret name, secret
25
+ end
26
+
27
+ def render_keys keys
28
+ end
29
+
24
30
  def render_footprint footprint
25
31
  end
26
32
 
@@ -46,10 +52,20 @@ module Leeloo
46
52
  end
47
53
  end
48
54
 
55
+ def render_name_and_secret name, secret
56
+ self.render_text name
57
+ self.render_secret secret
58
+ self.render_text '------'
59
+ end
60
+
49
61
  def render_text text
50
62
  puts text
51
63
  end
52
64
 
65
+ def render_keys keys
66
+ self.render_text keys
67
+ end
68
+
53
69
  def render_footprint footprint
54
70
  puts "token:"
55
71
  puts Base64.strict_encode64 footprint.to_json
@@ -69,11 +85,21 @@ module Leeloo
69
85
  end
70
86
 
71
87
  def render_secrets secrets
72
- hash = {:secrets => []}
73
- secrets.sort_by(&:name).each { |secret| sort(hash[:secrets], secret.name) }
88
+ hash = {'Password Store' => []}
89
+ secrets.sort_by(&:name).each { |secret| sort(hash['Password Store'], secret.name) }
74
90
  puts TTY::Tree.new(hash).render
75
91
  end
76
92
 
93
+ def render_keys keys
94
+ rows = []
95
+ keys.each do |key|
96
+ splitted = key.split('::')
97
+ is_present = '*' if splitted[1] == 'true'
98
+ rows << [splitted[0], is_present]
99
+ end
100
+ puts TTY::Table.new(header: ['Email', 'Selected'], rows: rows).render(:ascii)
101
+ end
102
+
77
103
  def sort array, element
78
104
  if element
79
105
  e = element.split("/", 2)
@@ -1,4 +1,4 @@
1
1
  module Leeloo
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.5.2'.freeze
3
3
  DESCRIPTION = "The easiest way to share securely your secrets".freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leeloo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sylvek
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-07 00:00:00.000000000 Z
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -94,20 +94,34 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webrick
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.7'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.7'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: bundler
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '2.0'
117
+ version: '2'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '2.0'
124
+ version: '2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rake
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +150,20 @@ dependencies:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
152
  version: '3.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec_junit_formatter
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.4'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.4'
139
167
  description: The easiest way to share securely your secrets
140
168
  email:
141
169
  - smaucourt@gmail.com
@@ -158,7 +186,7 @@ homepage: https://github.com/sylvek/leeloo
158
186
  licenses:
159
187
  - MIT
160
188
  metadata: {}
161
- post_install_message:
189
+ post_install_message:
162
190
  rdoc_options: []
163
191
  require_paths:
164
192
  - lib
@@ -173,8 +201,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
201
  - !ruby/object:Gem::Version
174
202
  version: '0'
175
203
  requirements: []
176
- rubygems_version: 3.0.4
177
- signing_key:
204
+ rubygems_version: 3.3.3
205
+ signing_key:
178
206
  specification_version: 4
179
207
  summary: The easiest way to share securely your secrets
180
208
  test_files: []