leeloo 0.4.1 → 0.5.0
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/lib/leeloo/command.rb +80 -4
- data/lib/leeloo/controller.rb +31 -1
- data/lib/leeloo/keystore.rb +50 -1
- data/lib/leeloo/output.rb +28 -2
- data/lib/leeloo/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b19454b20e434ee86fcca39a6cdf98f48dec70b5c775daff8709baf9b7359c12
|
4
|
+
data.tar.gz: c06c7449acb7c866ef2ee5be22c78fa97ee0d61a530bd575a8059daa1edb6fad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 056f03b0d8e76f92555e6a0ff50ed3da651055c9e9a2f246fd8714d907c200739a0d2f1dd013824b037dc24e2034d4e0d8f31aec023d928aa253a52f9b67d470
|
7
|
+
data.tar.gz: b872f7ef01b45a69edcb686dbccc5e5e02affc49c518eebde9eae60e7085e44eea8bda720bb68aa9c0766ba69139fb33c0ef48a93db04e2ba7329fc56fc059bc
|
data/lib/leeloo/command.rb
CHANGED
@@ -23,11 +23,24 @@ module Leeloo
|
|
23
23
|
program :help, 'GitHub', 'https://github.com/sylvek'
|
24
24
|
program :help_formatter, :compact
|
25
25
|
|
26
|
-
default_command :
|
26
|
+
default_command :wrapper
|
27
|
+
|
28
|
+
command :wrapper do |c|
|
29
|
+
c.action do |args, options|
|
30
|
+
unless args == []
|
31
|
+
name = args.first
|
32
|
+
ctl = SecretController.new(options)
|
33
|
+
ctl.read(name)
|
34
|
+
ctl.display
|
35
|
+
else
|
36
|
+
SecretsController.new(options).display
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
27
40
|
|
28
41
|
command :list do |c|
|
29
42
|
c.syntax = 'leeloo list [options]'
|
30
|
-
c.description = "Display secrets list of keystore"
|
43
|
+
c.description = "Display secrets list of stored on a keystore"
|
31
44
|
c.option '--ascii', nil, 'display secrets without unicode tree'
|
32
45
|
c.option '--keystore STRING', String, 'a selected keystore'
|
33
46
|
|
@@ -101,6 +114,58 @@ module Leeloo
|
|
101
114
|
end
|
102
115
|
end
|
103
116
|
|
117
|
+
command :key do |c|
|
118
|
+
c.syntax = 'leeloo keys'
|
119
|
+
c.description = "list keys from this keystore"
|
120
|
+
c.option '--ascii', nil, 'display secrets without unicode tree'
|
121
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
122
|
+
|
123
|
+
c.action do |args, options|
|
124
|
+
ctl = KeysController.new(options)
|
125
|
+
ctl.display
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
command "key sync" do |c|
|
130
|
+
c.syntax = 'leeloo keys sync'
|
131
|
+
c.description = "synchronize secrets with keys"
|
132
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
133
|
+
|
134
|
+
c.action do |args, options|
|
135
|
+
ctl = KeysController.new(options)
|
136
|
+
ctl.sync
|
137
|
+
ctl.display
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
command "key add" do |c|
|
142
|
+
c.syntax = 'leeloo key add <email>'
|
143
|
+
c.description = "add a dedicated key"
|
144
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
145
|
+
|
146
|
+
c.action do |args, options|
|
147
|
+
abort "email is missing" unless args.length == 1
|
148
|
+
email = args.first
|
149
|
+
ctl = KeysController.new(options)
|
150
|
+
ctl.add_key(email)
|
151
|
+
ctl.display
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
command "key remove" do |c|
|
156
|
+
c.syntax = 'leeloo key remove <email>'
|
157
|
+
c.description = "remove a dedicated key"
|
158
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
159
|
+
|
160
|
+
c.action do |args, options|
|
161
|
+
abort "email is missing" unless args.length == 1
|
162
|
+
email = args.first
|
163
|
+
ctl = KeysController.new(options)
|
164
|
+
ctl.remove_key(email)
|
165
|
+
ctl.display
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
104
169
|
command :read do |c|
|
105
170
|
c.syntax = 'leeloo read <name>'
|
106
171
|
c.description = "Display a secret from a keystore"
|
@@ -160,7 +225,7 @@ module Leeloo
|
|
160
225
|
end
|
161
226
|
end
|
162
227
|
|
163
|
-
command
|
228
|
+
command "keystore sync" do |c|
|
164
229
|
c.syntax = 'leeloo sync'
|
165
230
|
c.description = "Synchronize a keystore"
|
166
231
|
c.option '--keystore STRING', String, 'a selected keystore'
|
@@ -172,7 +237,18 @@ module Leeloo
|
|
172
237
|
end
|
173
238
|
end
|
174
239
|
|
175
|
-
command
|
240
|
+
command "keystore export" do |c|
|
241
|
+
c.syntax = 'leeloo export'
|
242
|
+
c.description = "Export all secrets from a keystore"
|
243
|
+
c.option '--keystore STRING', String, 'a selected keystore'
|
244
|
+
|
245
|
+
c.action do |args, options|
|
246
|
+
ctl = ExportController.new(options)
|
247
|
+
ctl.display
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
command "keystore init" do |c|
|
176
252
|
c.syntax = 'leeloo init'
|
177
253
|
c.description = "Initialize a keystore"
|
178
254
|
c.option '--keystore STRING', String, 'a selected keystore'
|
data/lib/leeloo/controller.rb
CHANGED
@@ -32,16 +32,46 @@ module Leeloo
|
|
32
32
|
class SecretsController < PrivateLocalFileSystemController
|
33
33
|
def initialize options
|
34
34
|
super options
|
35
|
-
@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)
|
data/lib/leeloo/keystore.rb
CHANGED
@@ -79,6 +79,10 @@ module Leeloo
|
|
79
79
|
find_secrets "#{@path}/secrets"
|
80
80
|
end
|
81
81
|
|
82
|
+
def keys
|
83
|
+
[]
|
84
|
+
end
|
85
|
+
|
82
86
|
def find_secrets path
|
83
87
|
elements = []
|
84
88
|
Dir.glob("#{path}/**") do |element|
|
@@ -121,7 +125,10 @@ module Leeloo
|
|
121
125
|
def initialize name, path
|
122
126
|
super name, path
|
123
127
|
FileUtils.mkdir_p "#{@path}/keys"
|
128
|
+
populate_recipients
|
129
|
+
end
|
124
130
|
|
131
|
+
def populate_recipients
|
125
132
|
@recipients = []
|
126
133
|
Dir.glob("#{path}/keys/*") { |key| @recipients << File.basename(key) }
|
127
134
|
@recipients.each { |key| GPGME::Key.import(File.open("#{path}/keys/#{key}")) }
|
@@ -129,7 +136,30 @@ module Leeloo
|
|
129
136
|
|
130
137
|
def init
|
131
138
|
super
|
132
|
-
|
139
|
+
File.write("#{@path}/keys/do_not_remove_me", "do not remove me")
|
140
|
+
end
|
141
|
+
|
142
|
+
def keys
|
143
|
+
available = GPGME::Key.find(:public, nil, ).map { |key| key.email }
|
144
|
+
actual = Dir.glob("#{@path}/keys/**").map { |path| path.split('/').last }
|
145
|
+
available.map { |email| actual.include?(email) ? "#{email}::true" : "#{email}::false" }
|
146
|
+
end
|
147
|
+
|
148
|
+
def add_key email
|
149
|
+
paths = []
|
150
|
+
GPGME::Key.find(:public, email).each do |key|
|
151
|
+
key.export(:output => File.open("#{path}/keys/#{key.uids.first.email}", "w+"))
|
152
|
+
paths << "#{path}/keys/#{key.uids.first.email}"
|
153
|
+
end
|
154
|
+
return paths
|
155
|
+
end
|
156
|
+
|
157
|
+
def remove_key email
|
158
|
+
if File.exist?("#{path}/keys/#{email}")
|
159
|
+
File.delete("#{path}/keys/#{email}")
|
160
|
+
return "#{path}/keys/#{email}"
|
161
|
+
end
|
162
|
+
return nil
|
133
163
|
end
|
134
164
|
|
135
165
|
def secret_of path
|
@@ -172,6 +202,25 @@ module Leeloo
|
|
172
202
|
secret_of @keystore.secret_from_name(element)
|
173
203
|
end
|
174
204
|
|
205
|
+
def keys
|
206
|
+
@keystore.keys
|
207
|
+
end
|
208
|
+
|
209
|
+
def add_key email
|
210
|
+
@keystore.add_key(email).each do |path|
|
211
|
+
@git.add path
|
212
|
+
@git.commit "#{email} added"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def remove_key email
|
217
|
+
deleted = @keystore.remove_key email
|
218
|
+
if deleted
|
219
|
+
@git.add deleted
|
220
|
+
@git.commit "#{email} removed"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
175
224
|
def secrets
|
176
225
|
@keystore.secrets
|
177
226
|
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 = {
|
73
|
-
secrets.sort_by(&:name).each { |secret| sort(hash[
|
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)
|
data/lib/leeloo/version.rb
CHANGED
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
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sylvek
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commander
|
@@ -201,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
201
|
- !ruby/object:Gem::Version
|
202
202
|
version: '0'
|
203
203
|
requirements: []
|
204
|
-
rubygems_version: 3.
|
204
|
+
rubygems_version: 3.2.32
|
205
205
|
signing_key:
|
206
206
|
specification_version: 4
|
207
207
|
summary: The easiest way to share securely your secrets
|