encrypt_env 1.1.7 → 1.2.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 +11 -3
- data/lib/encrypt_env.rb +140 -62
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39d324cf43ef142486ae13f849ef25d421c4b84a889bfb620ba02febe43734ac
|
4
|
+
data.tar.gz: 3744f4b529dfe535d98dd94392b0aa527e102c8cbfb57696e53469794dbb0203
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e660e1d3390110ddbdfae62a8e4d0c331e6703c696af4202f158fedd5227a165b59bcf3d43449fa6d96f21658cf260db7d607f46faf070aefdc206cfa9a92b0
|
7
|
+
data.tar.gz: 07ed2e14def1acebde149fdba0f9e22d2c85ddfdf9fc1d08c9d0ee0fdbe0cc85f19f9b762361a7e2d97ff99efc7cbd1c49fde82057b755d98bde20556c8e7030
|
data/bin/encrypt_env
CHANGED
@@ -11,13 +11,21 @@ if action == 'setup'
|
|
11
11
|
EncryptEnv.setup
|
12
12
|
exit 0
|
13
13
|
elsif action == 'show'
|
14
|
-
|
14
|
+
if argv[0]
|
15
|
+
EncryptEnv.show(argv[0])
|
16
|
+
else
|
17
|
+
EncryptEnv.show
|
18
|
+
end
|
15
19
|
exit 0
|
16
20
|
elsif action == 'all'
|
17
|
-
EncryptEnv.
|
21
|
+
EncryptEnv.show('all')
|
18
22
|
exit 0
|
19
23
|
elsif action == 'edit'
|
20
|
-
|
24
|
+
if argv[0]
|
25
|
+
EncryptEnv.edit(argv[0])
|
26
|
+
else
|
27
|
+
EncryptEnv.edit
|
28
|
+
end
|
21
29
|
exit 0
|
22
30
|
elsif ['help', '--help', '-h'].include?(action)
|
23
31
|
puts <<~HELP
|
data/lib/encrypt_env.rb
CHANGED
@@ -8,34 +8,86 @@ require 'tempfile'
|
|
8
8
|
require 'json'
|
9
9
|
|
10
10
|
# gem 'encrypt_env'
|
11
|
+
# rubocop:disable Metrics/ClassLength
|
12
|
+
# rubocop:disable Metrics/MethodLength
|
11
13
|
class EncryptEnv
|
12
|
-
private_class_method def self.
|
13
|
-
|
14
|
+
private_class_method def self.define_option
|
15
|
+
puts "Options to 'encrypt secrets.yml' file"
|
16
|
+
puts '1. Generate only one master.key and one encrypted file for all environment'
|
17
|
+
puts '2. Generate master.key and encrypted file for each environment'
|
18
|
+
|
19
|
+
loop do
|
20
|
+
@opt = gets.chomp.to_i
|
21
|
+
break if @opt == 1 || @opt == 2
|
22
|
+
|
23
|
+
puts "Please enter '1' or '2'!"
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "Your option is #{@opt}"
|
14
27
|
end
|
15
28
|
|
16
|
-
private_class_method def self.
|
17
|
-
if File.file?("#{
|
18
|
-
|
19
|
-
elsif
|
20
|
-
|
29
|
+
private_class_method def self.load_curr_opt
|
30
|
+
if File.file?("#{Dir.pwd}/config/secrets.yml.enc")
|
31
|
+
@opt = 1
|
32
|
+
elsif Dir["#{Dir.pwd}/config/secrets_*.yml.enc"].length.positive?
|
33
|
+
@opt = 2
|
21
34
|
else
|
22
|
-
|
35
|
+
puts 'You must setup first to encrypt file!'
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private_class_method def self.current_env
|
41
|
+
unless defined?(Rails)
|
42
|
+
env = `rails r "print Rails.env"`
|
43
|
+
return env
|
23
44
|
end
|
45
|
+
Rails.env
|
46
|
+
end
|
47
|
+
|
48
|
+
private_class_method def self.check_key_existence(env = nil)
|
49
|
+
file_name = env.nil? ? 'master.key' : "master_#{env}.key"
|
50
|
+
return if File.file?("#{Dir.pwd}/config/#{file_name}")
|
51
|
+
# return if Dir["#{Dir.pwd}/config/master_*.key"].length.positive? && @opt == 2
|
52
|
+
return if ENV.key?('MASTER_KEY')
|
53
|
+
|
54
|
+
puts 'Please provide master key!'
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
private_class_method def self.load_master_key(env = nil)
|
59
|
+
check_key_existence(env)
|
60
|
+
file_path = env ? "#{Dir.pwd}/config/master_#{env}.key" : "#{Dir.pwd}/config/master.key"
|
61
|
+
key = File.file?(file_path) ? File.read(file_path).strip : ENV['MASTER_KEY']
|
24
62
|
@master_key = [key].pack('H*')
|
25
|
-
true
|
26
63
|
end
|
27
64
|
|
28
|
-
private_class_method def self.
|
29
|
-
if @
|
30
|
-
|
31
|
-
|
32
|
-
|
65
|
+
private_class_method def self.generate_keys
|
66
|
+
if @opt == 1
|
67
|
+
key = OpenSSL::Random.random_bytes(16)
|
68
|
+
File.open("#{Dir.pwd}/config/master.key", 'w') { |file| file.write(key.unpack('H*')[0]) }
|
69
|
+
else
|
70
|
+
to_hash_type(@content_to_encrypt).each_key do |env|
|
71
|
+
next if env == 'default'
|
72
|
+
|
73
|
+
key = OpenSSL::Random.random_bytes(16)
|
74
|
+
File.open("#{Dir.pwd}/config/master_#{env}.key", 'w') { |file| file.write(key.unpack('H*')[0]) }
|
75
|
+
end
|
33
76
|
end
|
34
|
-
true
|
35
77
|
end
|
36
78
|
|
37
|
-
private_class_method def self.
|
38
|
-
|
79
|
+
private_class_method def self.load_content_to_encrypt
|
80
|
+
secret_file = File.expand_path("#{Dir.pwd}/config/secrets.yml")
|
81
|
+
@content_to_encrypt = File.read(secret_file)
|
82
|
+
end
|
83
|
+
|
84
|
+
private_class_method def self.to_hash_type(raw_data)
|
85
|
+
HashWithIndifferentAccess.new(YAML.load(raw_data, aliases: true))
|
86
|
+
end
|
87
|
+
|
88
|
+
private_class_method def self.load_encrypted_data(env = nil)
|
89
|
+
file_path = env ? "#{Dir.pwd}/config/secrets_#{env}.yml.enc" : "#{Dir.pwd}/config/secrets.yml.enc"
|
90
|
+
hex_string = File.read(file_path)
|
39
91
|
raw_data = [hex_string].pack('H*')
|
40
92
|
|
41
93
|
encrypted = raw_data.slice(0, raw_data.length - 28)
|
@@ -44,8 +96,8 @@ class EncryptEnv
|
|
44
96
|
{ encrypted: encrypted, iv: iv, tag: tag }
|
45
97
|
end
|
46
98
|
|
47
|
-
private_class_method def self.encrypt(content)
|
48
|
-
|
99
|
+
private_class_method def self.encrypt(content, typ = nil)
|
100
|
+
file_path = typ ? "#{Dir.pwd}/config/secrets_#{typ}.yml.enc" : "#{Dir.pwd}/config/secrets.yml.enc"
|
49
101
|
cipher = OpenSSL::Cipher.new('aes-128-gcm')
|
50
102
|
cipher.encrypt
|
51
103
|
cipher.key = @master_key
|
@@ -54,16 +106,15 @@ class EncryptEnv
|
|
54
106
|
encrypted = cipher.update(content) + cipher.final
|
55
107
|
tag = cipher.auth_tag
|
56
108
|
hex_string = (encrypted + iv + tag).unpack('H*')[0]
|
57
|
-
File.open(
|
109
|
+
File.open(file_path, 'w') { |file| file.write(hex_string) }
|
58
110
|
end
|
59
111
|
|
60
|
-
private_class_method def self.decrypt
|
61
|
-
|
62
|
-
return unless master_key?
|
112
|
+
private_class_method def self.decrypt(env = nil)
|
113
|
+
load_master_key(env)
|
63
114
|
|
64
115
|
decipher = OpenSSL::Cipher.new('aes-128-gcm')
|
65
116
|
decipher.decrypt
|
66
|
-
data =
|
117
|
+
data = load_encrypted_data(env)
|
67
118
|
encrypted = data[:encrypted]
|
68
119
|
decipher.key = @master_key
|
69
120
|
decipher.iv = data[:iv]
|
@@ -71,59 +122,86 @@ class EncryptEnv
|
|
71
122
|
decipher.auth_data = ''
|
72
123
|
|
73
124
|
@raw_decrypted = decipher.update(encrypted) + decipher.final
|
74
|
-
@decrypted =
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
path_root
|
80
|
-
secret_file = File.expand_path("#{@path_root}/config/secrets.yml")
|
81
|
-
key = OpenSSL::Random.random_bytes(16)
|
82
|
-
# save key in master.key file
|
83
|
-
File.open("#{@path_root}/config/master.key", 'w') { |file| file.write(key.unpack('H*')[0]) }
|
84
|
-
encrypt(File.read(secret_file))
|
85
|
-
File.rename(secret_file, "#{@path_root}/config/secrets.yml.old")
|
86
|
-
system("echo '/config/master.key' >> #{@path_root}/.gitignore")
|
87
|
-
system("echo '/config/secrets.yml.old' >> #{@path_root}/.gitignore")
|
88
|
-
system("echo 'Set up complete!'")
|
125
|
+
@decrypted = to_hash_type(@raw_decrypted)
|
126
|
+
# Catch error if master key is wrong
|
127
|
+
rescue OpenSSL::Cipher::CipherError
|
128
|
+
puts 'Master key is wrong!'
|
129
|
+
exit
|
89
130
|
end
|
90
131
|
|
91
|
-
def self.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
encrypt(File.read(f.path))
|
100
|
-
@decrypted = nil
|
132
|
+
private_class_method def self.all_decrypted_object
|
133
|
+
obj = {}
|
134
|
+
env_lst = Dir["#{Dir.pwd}/config/secrets_*.yml.enc"].map do |path|
|
135
|
+
path.scan(/secrets_(.*)\.yml\.enc/).flatten.first
|
136
|
+
end
|
137
|
+
env_lst.each do |e|
|
138
|
+
decrypt(e)
|
139
|
+
obj[e] = @decrypted
|
101
140
|
end
|
141
|
+
obj
|
102
142
|
end
|
103
143
|
|
104
144
|
def self.secrets_all
|
105
|
-
return
|
145
|
+
return all_decrypted_object if @opt == 2
|
106
146
|
|
107
|
-
|
147
|
+
decrypt
|
148
|
+
@decrypted
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.secrets(env = nil)
|
152
|
+
load_curr_opt unless @opt
|
153
|
+
return secrets_all if env == 'all'
|
108
154
|
|
109
|
-
|
155
|
+
if @opt == 1
|
156
|
+
decrypt
|
157
|
+
@decrypted[env || current_env]
|
158
|
+
else
|
159
|
+
decrypt(env || current_env)
|
160
|
+
@decrypted
|
161
|
+
end
|
110
162
|
end
|
111
163
|
|
112
|
-
def self.
|
113
|
-
|
164
|
+
def self.setup
|
165
|
+
define_option
|
166
|
+
load_content_to_encrypt
|
167
|
+
generate_keys
|
114
168
|
|
115
|
-
|
116
|
-
|
117
|
-
|
169
|
+
if @opt == 1
|
170
|
+
load_master_key
|
171
|
+
encrypt(@content_to_encrypt)
|
172
|
+
else
|
173
|
+
to_hash_type(@content_to_encrypt).each do |env, value|
|
174
|
+
next if env == 'default'
|
175
|
+
|
176
|
+
load_master_key(env)
|
177
|
+
encrypt(value.to_hash.to_yaml, env)
|
178
|
+
end
|
118
179
|
end
|
119
|
-
|
180
|
+
|
181
|
+
File.rename("#{Dir.pwd}/config/secrets.yml", "#{Dir.pwd}/config/secrets.yml.old")
|
182
|
+
system("echo '/config/master*.key' >> #{Dir.pwd}/.gitignore")
|
183
|
+
system("echo '/config/secrets.yml.old' >> #{Dir.pwd}/.gitignore")
|
184
|
+
system("echo 'Set up complete!'")
|
120
185
|
end
|
121
186
|
|
122
|
-
def self.
|
123
|
-
|
187
|
+
def self.edit(env = nil)
|
188
|
+
load_curr_opt unless @opt
|
189
|
+
env ||= current_env if @opt == 2
|
190
|
+
return unless decrypt(env)
|
191
|
+
|
192
|
+
Tempfile.create("secrets_#{env}.yml") do |f|
|
193
|
+
f.write(@raw_decrypted)
|
194
|
+
f.flush
|
195
|
+
f.rewind
|
196
|
+
system("vim #{f.path}")
|
197
|
+
encrypt(File.read(f.path), env)
|
198
|
+
@decrypted = nil
|
199
|
+
end
|
124
200
|
end
|
125
201
|
|
126
|
-
def self.
|
127
|
-
jj
|
202
|
+
def self.show(env = nil)
|
203
|
+
jj secrets(env)
|
128
204
|
end
|
129
205
|
end
|
206
|
+
# rubocop:enable Metrics/ClassLength
|
207
|
+
# rubocop:enable Metrics/MethodLength
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encrypt_env
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.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-
|
11
|
+
date: 2022-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Encrypts and decrypts environment variables
|
14
14
|
email: nhutan2001@gmail.com
|