encrypt_env 1.2.2 → 1.3.2
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/bin/encrypt_env +34 -4
- data/lib/encrypt_env/version.rb +5 -0
- data/lib/encrypt_env.rb +116 -24
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1c84dbd7de0bdce6a21e412fbadf6652fa6828283e034478408f0d1ac9e7a26
|
4
|
+
data.tar.gz: 8b40b35df40234c55fc6210bbb720564b3a342195636d2b3e8c4b17d0bb38fd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 871c3408a490cdc32e486eff60e787961c1915aa65fc3d7bba6cd10b15b3439b0a9d4b941abf0459427019ca0736bec381c567958c88c86d5542f35e63880cce
|
7
|
+
data.tar.gz: 0bcbbe97212f1ef1ce7c49b6184dd07ab1b3beb09a2abfc0e290abe5951b5c794e2df0a1340a38389dd825b563f966a5ae897ccecb361271165e31cc0130f46c
|
data/bin/encrypt_env
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require 'encrypt_env'
|
6
|
+
require_relative '../lib/encrypt_env/version'
|
6
7
|
|
7
8
|
argv = ARGV
|
8
9
|
action = argv.shift
|
@@ -27,17 +28,46 @@ elsif action == 'edit'
|
|
27
28
|
EncryptEnv.edit
|
28
29
|
end
|
29
30
|
exit 0
|
31
|
+
elsif action == 'get'
|
32
|
+
key = argv[0]
|
33
|
+
env = argv[1]
|
34
|
+
EncryptEnv.valueof(key, env)
|
35
|
+
exit 0
|
36
|
+
elsif action == 'new'
|
37
|
+
key = argv[0]
|
38
|
+
env = argv[1]
|
39
|
+
EncryptEnv.update_variable(key, env, true)
|
40
|
+
exit 0
|
41
|
+
elsif action == 'update'
|
42
|
+
key = argv[0]
|
43
|
+
env = argv[1]
|
44
|
+
EncryptEnv.update_variable(key, env, false)
|
45
|
+
exit 0
|
46
|
+
elsif action == 'delete'
|
47
|
+
key = argv[0]
|
48
|
+
env = argv[1]
|
49
|
+
EncryptEnv.delete_variable(key, env)
|
50
|
+
exit 0
|
51
|
+
elsif ['-v', '--version', 'version'].include?(action)
|
52
|
+
puts Version::VERSION
|
53
|
+
exit 0
|
30
54
|
elsif ['help', '--help', '-h'].include?(action)
|
31
55
|
puts <<~HELP
|
32
56
|
Usage:
|
33
|
-
encrypt_env setup
|
34
|
-
encrypt_env
|
35
|
-
encrypt_env
|
36
|
-
encrypt_env edit
|
57
|
+
encrypt_env setup # To setup for the firt time
|
58
|
+
encrypt_env show all # To show all environment variables
|
59
|
+
encrypt_env show / encrypt_env show [environment] # To show environment variables
|
60
|
+
encrypt_env edit / encrypt_env edit [environment] # To edit environment variables
|
61
|
+
encrypt_env add variable_name [environment] # To add environment variable
|
62
|
+
encrypt_env get variable_name [environment] # To show value of specific variable
|
63
|
+
encrypt_env update variable_name [environment] # To edit value of specific variable
|
64
|
+
encrypt_env delete variable_name [environment] # To delete specific variable
|
65
|
+
Or: Visit "https://github.com/nnhutan/encrypt_env" for more information
|
37
66
|
HELP
|
38
67
|
|
39
68
|
exit 0
|
40
69
|
else
|
41
70
|
puts "Unknown action: #{action}"
|
71
|
+
puts "Use 'encrypt_env -h' for more help"
|
42
72
|
exit 1
|
43
73
|
end
|
data/lib/encrypt_env.rb
CHANGED
@@ -11,6 +11,8 @@ require 'json'
|
|
11
11
|
# rubocop:disable Metrics/ClassLength
|
12
12
|
# rubocop:disable Metrics/MethodLength
|
13
13
|
class EncryptEnv
|
14
|
+
@root_path = Dir.pwd
|
15
|
+
|
14
16
|
private_class_method def self.define_option
|
15
17
|
puts "Options to 'encrypt secrets.yml' file"
|
16
18
|
puts '1. Generate only one master.key and one encrypted file for all environment'
|
@@ -27,13 +29,12 @@ class EncryptEnv
|
|
27
29
|
end
|
28
30
|
|
29
31
|
private_class_method def self.load_curr_opt
|
30
|
-
if File.file?("#{
|
32
|
+
if File.file?("#{@root_path}/config/secrets.yml.enc")
|
31
33
|
@opt = 1
|
32
|
-
elsif Dir["#{
|
34
|
+
elsif Dir["#{@root_path}/config/secrets_*.yml.enc"].length.positive?
|
33
35
|
@opt = 2
|
34
36
|
else
|
35
|
-
|
36
|
-
exit
|
37
|
+
raise 'You must setup first to encrypt file!'
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -47,17 +48,21 @@ class EncryptEnv
|
|
47
48
|
|
48
49
|
private_class_method def self.check_key_existence(env = nil)
|
49
50
|
file_name = env.nil? ? 'master.key' : "master_#{env}.key"
|
50
|
-
return if File.file?("#{
|
51
|
-
# return if Dir["#{Dir.pwd}/config/master_*.key"].length.positive? && @opt == 2
|
51
|
+
return if File.file?("#{@root_path}/config/#{file_name}")
|
52
52
|
return if ENV.key?('MASTER_KEY')
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
message = env ? "Missing key of #{env} environment!" : 'Missing master key!'
|
55
|
+
raise message
|
56
56
|
end
|
57
57
|
|
58
58
|
private_class_method def self.load_master_key(env = nil)
|
59
|
-
|
60
|
-
|
59
|
+
begin
|
60
|
+
check_key_existence(env)
|
61
|
+
rescue StandardError => e
|
62
|
+
raise e.message
|
63
|
+
end
|
64
|
+
|
65
|
+
file_path = env ? "#{@root_path}/config/master_#{env}.key" : "#{@root_path}/config/master.key"
|
61
66
|
key = File.file?(file_path) ? File.read(file_path).strip : ENV['MASTER_KEY']
|
62
67
|
@master_key = [key].pack('H*')
|
63
68
|
end
|
@@ -65,28 +70,28 @@ class EncryptEnv
|
|
65
70
|
private_class_method def self.generate_keys
|
66
71
|
if @opt == 1
|
67
72
|
key = OpenSSL::Random.random_bytes(16)
|
68
|
-
File.open("#{
|
73
|
+
File.open("#{@root_path}/config/master.key", 'w') { |file| file.write(key.unpack('H*')[0]) }
|
69
74
|
else
|
70
75
|
to_hash_type(@content_to_encrypt).each_key do |env|
|
71
76
|
next if env == 'default'
|
72
77
|
|
73
78
|
key = OpenSSL::Random.random_bytes(16)
|
74
|
-
File.open("#{
|
79
|
+
File.open("#{@root_path}/config/master_#{env}.key", 'w') { |file| file.write(key.unpack('H*')[0]) }
|
75
80
|
end
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
79
84
|
private_class_method def self.load_content_to_encrypt
|
80
|
-
secret_file = File.expand_path("#{
|
85
|
+
secret_file = File.expand_path("#{@root_path}/config/secrets.yml")
|
81
86
|
@content_to_encrypt = File.read(secret_file)
|
82
87
|
end
|
83
88
|
|
84
89
|
private_class_method def self.to_hash_type(raw_data)
|
85
|
-
HashWithIndifferentAccess.new(YAML.load(raw_data, aliases: true))
|
90
|
+
HashWithIndifferentAccess.new(::YAML.load(raw_data, aliases: true))
|
86
91
|
end
|
87
92
|
|
88
93
|
private_class_method def self.load_encrypted_data(env = nil)
|
89
|
-
file_path = env ? "#{
|
94
|
+
file_path = env ? "#{@root_path}/config/secrets_#{env}.yml.enc" : "#{@root_path}/config/secrets.yml.enc"
|
90
95
|
hex_string = File.read(file_path)
|
91
96
|
raw_data = [hex_string].pack('H*')
|
92
97
|
|
@@ -97,7 +102,7 @@ class EncryptEnv
|
|
97
102
|
end
|
98
103
|
|
99
104
|
private_class_method def self.encrypt(content, typ = nil)
|
100
|
-
file_path = typ ? "#{
|
105
|
+
file_path = typ ? "#{@root_path}/config/secrets_#{typ}.yml.enc" : "#{@root_path}/config/secrets.yml.enc"
|
101
106
|
cipher = OpenSSL::Cipher.new('aes-128-gcm')
|
102
107
|
cipher.encrypt
|
103
108
|
cipher.key = @master_key
|
@@ -110,7 +115,11 @@ class EncryptEnv
|
|
110
115
|
end
|
111
116
|
|
112
117
|
private_class_method def self.decrypt(env = nil)
|
113
|
-
|
118
|
+
begin
|
119
|
+
load_master_key(env)
|
120
|
+
rescue StandardError => e
|
121
|
+
raise e.message
|
122
|
+
end
|
114
123
|
|
115
124
|
decipher = OpenSSL::Cipher.new('aes-128-gcm')
|
116
125
|
decipher.decrypt
|
@@ -125,13 +134,13 @@ class EncryptEnv
|
|
125
134
|
@decrypted = to_hash_type(@raw_decrypted)
|
126
135
|
# Catch error if master key is wrong
|
127
136
|
rescue OpenSSL::Cipher::CipherError
|
128
|
-
|
129
|
-
|
137
|
+
message = env ? "Master key of #{env} environment is wrong!" : 'Master key is wrong!'
|
138
|
+
raise message
|
130
139
|
end
|
131
140
|
|
132
141
|
private_class_method def self.all_decrypted_object
|
133
142
|
obj = {}
|
134
|
-
env_lst = Dir["#{
|
143
|
+
env_lst = Dir["#{@root_path}/config/secrets_*.yml.enc"].map do |path|
|
135
144
|
path.scan(/secrets_(.*)\.yml\.enc/).flatten.first
|
136
145
|
end
|
137
146
|
env_lst.each do |e|
|
@@ -159,6 +168,10 @@ class EncryptEnv
|
|
159
168
|
decrypt(env || current_env)
|
160
169
|
@decrypted
|
161
170
|
end
|
171
|
+
rescue StandardError => e
|
172
|
+
puts e.message
|
173
|
+
@have_error = true
|
174
|
+
{}
|
162
175
|
end
|
163
176
|
|
164
177
|
def self.setup
|
@@ -178,9 +191,9 @@ class EncryptEnv
|
|
178
191
|
end
|
179
192
|
end
|
180
193
|
|
181
|
-
File.rename("#{
|
182
|
-
system("echo '/config/master*.key' >> #{
|
183
|
-
system("echo '/config/secrets.yml.old' >> #{
|
194
|
+
File.rename("#{@root_path}/config/secrets.yml", "#{@root_path}/config/secrets.yml.old")
|
195
|
+
system("echo '/config/master*.key' >> #{@root_path}/.gitignore")
|
196
|
+
system("echo '/config/secrets.yml.old' >> #{@root_path}/.gitignore")
|
184
197
|
system("echo 'Set up complete!'")
|
185
198
|
end
|
186
199
|
|
@@ -197,10 +210,89 @@ class EncryptEnv
|
|
197
210
|
encrypt(File.read(f.path), env)
|
198
211
|
@decrypted = nil
|
199
212
|
end
|
213
|
+
rescue StandardError => e
|
214
|
+
puts e.message
|
200
215
|
end
|
201
216
|
|
202
217
|
def self.show(env = nil)
|
203
|
-
|
218
|
+
require 'awesome_print'
|
219
|
+
require 'date'
|
220
|
+
value = secrets(env)
|
221
|
+
ap(value) unless @have_error
|
222
|
+
# jj value unless @have_error
|
223
|
+
@have_error = false
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.valueof(key, env = nil)
|
227
|
+
tail_msg = env ? " in '#{env}' environent" : nil
|
228
|
+
value = secrets(env)
|
229
|
+
unless value.key?(key)
|
230
|
+
puts "key '#{key}' does not exist#{tail_msg}!"
|
231
|
+
return
|
232
|
+
end
|
233
|
+
puts value[key]
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.delete_variable(key, env = nil)
|
237
|
+
load_curr_opt unless @opt
|
238
|
+
if @opt == 1
|
239
|
+
puts 'Only for option 2!'
|
240
|
+
return
|
241
|
+
end
|
242
|
+
|
243
|
+
tail_msg = env ? " in '#{env}' environent" : nil
|
244
|
+
confirm = "Really? You want to delete '#{key}'#{tail_msg}? (y/n)"
|
245
|
+
puts confirm
|
246
|
+
a = $stdin.gets.chomp
|
247
|
+
return unless a == 'y'
|
248
|
+
|
249
|
+
value = secrets(env)
|
250
|
+
|
251
|
+
unless value.key?(key)
|
252
|
+
puts "#{key} does not exist#{tail_msg}!"
|
253
|
+
return
|
254
|
+
end
|
255
|
+
|
256
|
+
value.delete(key)
|
257
|
+
encrypt(value.to_hash.to_yaml, env || current_env)
|
258
|
+
puts "Delete '#{key}' successfully!"
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.update_variable(key, env = nil, add_variable = false)
|
262
|
+
load_curr_opt unless @opt
|
263
|
+
if @opt == 1
|
264
|
+
puts 'Only for option 2!'
|
265
|
+
return
|
266
|
+
end
|
267
|
+
tail_msg = env ? " in '#{env}' environment" : nil
|
268
|
+
|
269
|
+
value = secrets(env)
|
270
|
+
if add_variable && value.key?(key)
|
271
|
+
puts "Key existed#{tail_msg}!"
|
272
|
+
return
|
273
|
+
end
|
274
|
+
|
275
|
+
if !value.key?(key) && !add_variable
|
276
|
+
puts "'#{key}' does not exist#{tail_msg}. You want to add '#{key}' as the new key? (y/n)"
|
277
|
+
a = $stdin.gets.chomp
|
278
|
+
return unless a == 'y'
|
279
|
+
|
280
|
+
add_variable = true
|
281
|
+
end
|
282
|
+
|
283
|
+
action = add_variable && 'add' || 'edit'
|
284
|
+
file_name = env ? "#{action}_#{key}_#{env}" : "#{action}_#{key}"
|
285
|
+
|
286
|
+
Tempfile.create(file_name) do |f|
|
287
|
+
f.write(value[key])
|
288
|
+
f.flush
|
289
|
+
f.rewind
|
290
|
+
system("vim #{f.path}")
|
291
|
+
new_value = File.read(f.path)
|
292
|
+
value[key] = new_value.strip
|
293
|
+
encrypt(value.to_hash.to_yaml, env || current_env)
|
294
|
+
@decrypted = nil
|
295
|
+
end
|
204
296
|
end
|
205
297
|
end
|
206
298
|
# rubocop:enable Metrics/ClassLength
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encrypt_env
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nhu Tan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
12
|
-
dependencies:
|
11
|
+
date: 2022-08-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: awesome_print
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.9.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.9'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.9.2
|
13
33
|
description: Encrypts and decrypts environment variables
|
14
34
|
email: nhutan2001@gmail.com
|
15
35
|
executables:
|
@@ -19,6 +39,7 @@ extra_rdoc_files: []
|
|
19
39
|
files:
|
20
40
|
- bin/encrypt_env
|
21
41
|
- lib/encrypt_env.rb
|
42
|
+
- lib/encrypt_env/version.rb
|
22
43
|
homepage: https://github.com/nnhutan/encrypt_env.git
|
23
44
|
licenses:
|
24
45
|
- MIT
|