eco-helpers 2.4.9 → 2.5.1
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/CHANGELOG.md +24 -1
- data/eco-helpers.gemspec +1 -1
- data/lib/eco/api/common/loaders/case_base.rb +2 -3
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +97 -47
- data/lib/eco/api/common/people/default_parsers/select_parser.rb +2 -2
- data/lib/eco/api/common/people/default_parsers/xls_parser.rb +0 -1
- data/lib/eco/api/common/people/entry_factory.rb +13 -8
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +2 -2
- data/lib/eco/api/common/session/base_session.rb +1 -2
- data/lib/eco/api/common/session/environment.rb +6 -10
- data/lib/eco/api/common/session/helpers/prompt_user.rb +18 -18
- data/lib/eco/api/common/session/mailer.rb +1 -3
- data/lib/eco/api/common/session/s3_uploader.rb +1 -3
- data/lib/eco/api/common/session/sftp.rb +6 -4
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +5 -4
- data/lib/eco/api/session/config/api.rb +4 -2
- data/lib/eco/api/usecases/base_case.rb +0 -2
- data/lib/eco/api/usecases/base_io.rb +0 -3
- data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +1 -1
- data/lib/eco/api/usecases/ooze_samples/ooze_from_doc_case.rb +1 -2
- data/lib/eco/api/usecases/ooze_samples/ooze_run_base_case.rb +0 -1
- data/lib/eco/api/usecases/ooze_samples/ooze_update_case.rb +0 -1
- data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +1 -1
- data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +0 -2
- data/lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb +0 -1
- data/lib/eco/api/usecases/ooze_samples.rb +0 -1
- data/lib/eco/api/usecases/use_case.rb +4 -1
- data/lib/eco/api/usecases/use_case_chain.rb +1 -4
- data/lib/eco/api/usecases/use_case_io.rb +0 -2
- data/lib/eco/api.rb +0 -2
- data/lib/eco/cli/config/default/options.rb +11 -1
- data/lib/eco/csv.rb +4 -7
- data/lib/eco/data/files/directory.rb +0 -3
- data/lib/eco/data/files/encoding.rb +75 -0
- data/lib/eco/data/files/helpers.rb +15 -37
- data/lib/eco/data/files.rb +1 -0
- data/lib/eco/data/fuzzy_match.rb +8 -4
- data/lib/eco/data.rb +0 -1
- data/lib/eco/version.rb +1 -1
- data/lib/eco-helpers.rb +1 -1
- metadata +5 -6
- data/lib/eco/data/crypto/encryption.rb +0 -321
- data/lib/eco/data/crypto.rb +0 -7
@@ -1,321 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
# 'json'
|
3
|
-
require 'base64'
|
4
|
-
#require 'pp'
|
5
|
-
|
6
|
-
require_relative '../../cli/scripting'
|
7
|
-
|
8
|
-
# see some ramblings here: http://distributed-frostbite.blogspot.com/2010/06/file-encryption-in-ruby-with-openssl.html
|
9
|
-
|
10
|
-
|
11
|
-
def run! # this will run only if called from command line (not when require'd nor load'd)
|
12
|
-
include Eco::CLI::Scripting
|
13
|
-
include Eco::Data::Crypto
|
14
|
-
# script arguments
|
15
|
-
keygen = get_arg("-keygen")
|
16
|
-
filename = get_arg("-keygen", with_param: true)
|
17
|
-
ssh = get_arg("-ssh")
|
18
|
-
length = get_arg("-length", with_param: true)
|
19
|
-
check_rsa_pairs = get_arg("-keypairs")
|
20
|
-
key_filename = get_arg("-keypairs", with_param: true)
|
21
|
-
|
22
|
-
# methods
|
23
|
-
case true
|
24
|
-
when keygen
|
25
|
-
puts "++ keygen RSA ++"
|
26
|
-
#pp ::OpenSSL.constants.sort
|
27
|
-
cr = Eco::Data::Crypto::OpenSSL.new
|
28
|
-
case true
|
29
|
-
when ssh
|
30
|
-
puts "think about installing this library: https://rubygems.org/gems/sshkey"
|
31
|
-
puts "GitHub: https://github.com/bensie/sshkey"
|
32
|
-
puts "or add this Ruby solution to convert to ssh-rsa: https://stackoverflow.com/a/3162593/4352306"
|
33
|
-
exit(1)
|
34
|
-
cr.rsa_keygen_ssh(filename: filename)
|
35
|
-
else
|
36
|
-
cr.rsa_keygen(filename: filename)
|
37
|
-
end
|
38
|
-
when check_rsa_pairs
|
39
|
-
puts "++ checking file pairs ++"
|
40
|
-
begin
|
41
|
-
key_filename = "rsa" if !key_filename
|
42
|
-
priv = File.read(key_filename + '.pem')
|
43
|
-
pub = File.read(key_filename + '.pub')
|
44
|
-
rescue
|
45
|
-
puts "could not find files with basename: #{key_filename}"
|
46
|
-
exit(1)
|
47
|
-
end
|
48
|
-
cr = Eco::Data::Crypto::OpenSSL.new
|
49
|
-
equals = cr.rsa_keypairs?(priv, pub)
|
50
|
-
if equals
|
51
|
-
puts "the pair #{key_filename} seem to be for one to another!"
|
52
|
-
else
|
53
|
-
puts "those files with base name #{key_filename} are not a rsa pair"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
|
59
|
-
module Eco
|
60
|
-
module Data
|
61
|
-
#TODO study how to encrypt uniquely the api key in the configuration file
|
62
|
-
#TODO study how RSA could boost team-shared Drive folder (updates, and people files should be encrypted via public key)
|
63
|
-
module Crypto
|
64
|
-
# file conf definitions
|
65
|
-
THIS_FILENAME = __FILE__
|
66
|
-
MY_NAME = File.basename(THIS_FILENAME, File.extname(THIS_FILENAME)) # ".rb"
|
67
|
-
PATH = File.dirname(THIS_FILENAME)
|
68
|
-
WORKING_DIR = PATH + "/" + MY_NAME
|
69
|
-
PARSER_FILE = WORKING_DIR + "/json_parser.json" # .dll
|
70
|
-
|
71
|
-
class OpenSSL
|
72
|
-
DEFAULT_KEY_LENGTH = 256
|
73
|
-
DEFAULT_RSA_LENGTH = 2048
|
74
|
-
SALT_LENGTH = 128
|
75
|
-
SALT_SEED = "$%!@_halt9000"
|
76
|
-
BLOCK_OCTETS = 512
|
77
|
-
attr_accessor :salt_seed
|
78
|
-
attr_reader :digest, :pkcs5, :kdf, :cipher, :rsa
|
79
|
-
attr_reader :salt
|
80
|
-
def initialize(init = {})
|
81
|
-
@digest = ::OpenSSL::Digest
|
82
|
-
@pkcs5 = ::OpenSSL::PKCS5
|
83
|
-
#@kdf = ::OpenSSL::KDF
|
84
|
-
@cipher = ::OpenSSL::Cipher
|
85
|
-
self.salt_seed = SALT_SEED
|
86
|
-
@rsa = ::OpenSSL::PKey::RSA
|
87
|
-
end
|
88
|
-
def salt_seed=(value)
|
89
|
-
@salt_seed = value
|
90
|
-
@salt = self.pbkdf2(@salt_seed, salt: @salt_seed, length: SALT_LENGTH)
|
91
|
-
end
|
92
|
-
def sha256 (str = nil)
|
93
|
-
sha = @digest.SHA256.new
|
94
|
-
digest = sha.digest(str) unless !str
|
95
|
-
sha.reset
|
96
|
-
digest
|
97
|
-
end
|
98
|
-
def sha512 (str = nil)
|
99
|
-
sha = @digest.SHA512.new
|
100
|
-
digest = sha.digest(str) unless !str
|
101
|
-
sha.reset
|
102
|
-
digest
|
103
|
-
end
|
104
|
-
# default hmac hash to "sha256" -> https://github.com/hueniverse/iron/issues/55
|
105
|
-
def pbkdf2 (pass, salt: @salt || "salt", iterations: 1000, length: DEFAULT_KEY_LENGTH, hash: "sha256")
|
106
|
-
octets = length.div(8)
|
107
|
-
#puts "this has been called"
|
108
|
-
#puts "pass: #{pass}"
|
109
|
-
#puts "salt: #{salt}"
|
110
|
-
#puts "iterations: #{iterations}"
|
111
|
-
#puts "length: #{length}"
|
112
|
-
#puts "hash: #{hash}"
|
113
|
-
@pkcs5.pbkdf2_hmac(pass, salt, iterations, octets, hash)
|
114
|
-
end
|
115
|
-
def pbkdf2_sha1 (pass, salt: @salt, iterations: 1000, length: DEFAULT_KEY_LENGTH)
|
116
|
-
#self.pbkdf2(pass, salt: salt, iterations: iternations, length: length, hash: "sha1")
|
117
|
-
@pkcs5.pbkdf2_hmac(pass, salt, iterations, octets, "sha1")
|
118
|
-
end
|
119
|
-
=begin
|
120
|
-
def scrypt (pass, salt: @salt, cost: 14, length: DEFAULT_KEY_LENGTH)
|
121
|
-
block_size = 8
|
122
|
-
parallelization = 1
|
123
|
-
octets = length.div(8)
|
124
|
-
@kdf.scrypt(pass, salt: salt, N: 2**cost, r: block_size, p: parallelization, length: octets)
|
125
|
-
end
|
126
|
-
=end
|
127
|
-
def aes256_pass(pass)
|
128
|
-
self.pbkdf2(pass, length: 256)
|
129
|
-
end
|
130
|
-
def aes256_encrypt(data, key: nil, iv: nil, block_octets: BLOCK_OCTETS)
|
131
|
-
block_bits = block_bits * 8
|
132
|
-
cipher = @cipher.new('aes-256-cbc')
|
133
|
-
cipher.encrypt
|
134
|
-
|
135
|
-
if key ; cipher.key = key
|
136
|
-
else ; key = cipher.random_key
|
137
|
-
end
|
138
|
-
if iv ; cipher.iv = iv
|
139
|
-
else ; iv = cipher.random_iv
|
140
|
-
end
|
141
|
-
|
142
|
-
str_c = ""
|
143
|
-
while str.length > 0
|
144
|
-
str_c += cipher.update(str.slice!(0, block_bits))
|
145
|
-
end
|
146
|
-
str_c += cipher.final
|
147
|
-
return str_c
|
148
|
-
#EncryptedData.new({content: str_c, key: key, iv: iv})
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
def aes256_decrypt(data, key: , iv: , block_octets: BLOCK_OCTETS)
|
153
|
-
block_bits = block_bits * 8
|
154
|
-
#validation = encrypted_data && encrypted_data.key && encrypted_data.iv
|
155
|
-
# return nil unless validation
|
156
|
-
cipher = @cipher.new('aes-256-cbc')
|
157
|
-
cipher.decrypt
|
158
|
-
cipher.key = key
|
159
|
-
cipher.iv = iv
|
160
|
-
#cipher.key = encrypted_data.key
|
161
|
-
#cipher.iv = encrypted_data.iv
|
162
|
-
#str_c = encrypted_data.content
|
163
|
-
str_c = data
|
164
|
-
str = ""
|
165
|
-
while str_c.length > 0
|
166
|
-
str += cipher.update(str_c.slice!(0, block_bits))
|
167
|
-
#puts str[-50..-1] || str
|
168
|
-
end
|
169
|
-
str += cipher.final
|
170
|
-
return str
|
171
|
-
end
|
172
|
-
def rsa_keygen(length = DEFAULT_RSA_LENGTH, filename: "rsa")
|
173
|
-
filename = "rsa" if !filename
|
174
|
-
key = @rsa.new(length)
|
175
|
-
File.open('./' + filename + '.pem',"w") {|fd| fd << key.to_pem }
|
176
|
-
File.open('./' + filename + '.pub',"w") {|fd| fd << key.public_key.to_pem }
|
177
|
-
end
|
178
|
-
def rsa_keygen_ssh(length = DEFAULT_RSA_LENGTH, filename: "rsa")
|
179
|
-
# to do conersion pem to ssh-rsa: https://stackoverflow.com/a/3162593/4352306
|
180
|
-
# conversion explained here: http://blog.oddbit.com/2011/05/08/converting-openssh-public-keys/
|
181
|
-
# much simpler developed in php here: https://stackoverflow.com/a/5524323/4352306
|
182
|
-
filename = "rsa" if !filename
|
183
|
-
key = @rsa.new(length)
|
184
|
-
File.open('./' + filename + '.der',"w") {|fd| fd << key.ssh_type }
|
185
|
-
File.open('./' + filename + '.pub',"w") {|fd| fd << key.public_key.ssh_type }
|
186
|
-
end
|
187
|
-
def rsa_keypairs?(private_key, public_key)
|
188
|
-
str_original = "See, my mule don’t like people laughing"
|
189
|
-
|
190
|
-
pub_key = @rsa.new(public_key)
|
191
|
-
str_original.force_encoding(Encoding::UTF_8)
|
192
|
-
encrypted_data = Base64.encode64(pub_key.public_encrypt(str_original))
|
193
|
-
|
194
|
-
priv_key = @rsa.new(private_key)
|
195
|
-
begin # see here: https://stackoverflow.com/a/13251160/4352306 (padding error when false pub key)
|
196
|
-
decrypted_data = priv_key.private_decrypt(Base64.decode64(encrypted_data))
|
197
|
-
# OpenSSL core Ruby library is written in C which uses different encoding (ASCII-8BIT)
|
198
|
-
# that's why we force UTF-8 encoding (before and after encryption)
|
199
|
-
# see this answer: https://stackoverflow.com/a/27326915/4352306
|
200
|
-
decrypted_data.force_encoding(Encoding::UTF_8)
|
201
|
-
rescue
|
202
|
-
return false
|
203
|
-
end
|
204
|
-
|
205
|
-
puts "encrypted string: #{str_original}"
|
206
|
-
puts "decrypted string: #{decrypted_data}"
|
207
|
-
return (decrypted_data == str_original)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
|
212
|
-
class EncryptedData
|
213
|
-
attr_reader :key, :iv, :content
|
214
|
-
def initialize(init = {})
|
215
|
-
@key = init[:key]
|
216
|
-
@iv = init[:iv]
|
217
|
-
@content = init[:content]
|
218
|
-
@sha = sha256(@content)
|
219
|
-
load() if !@key || !@iv
|
220
|
-
end
|
221
|
-
def load (file = nil)
|
222
|
-
parser = get_parser(file)
|
223
|
-
sha64 = Base64.encode64(@sha) if @sha
|
224
|
-
if parser.key?(sha64)
|
225
|
-
#puts "found key!"
|
226
|
-
meta = parser[sha64]
|
227
|
-
key64, iv64 = meta.values_at("key", "iv")
|
228
|
-
@key = Base64.decode64(key64) if key64
|
229
|
-
@iv = Base64.decode64(iv64) if iv64
|
230
|
-
else
|
231
|
-
#puts "key not found! #{sha64}"
|
232
|
-
end
|
233
|
-
end
|
234
|
-
def save (file = nil)
|
235
|
-
parser = get_parser(file)
|
236
|
-
sha64 = Base64.encode64(@sha) if @sha
|
237
|
-
#puts "save key: #{sha64}"
|
238
|
-
if parser.key?(sha64)
|
239
|
-
meta = parser[sha64]
|
240
|
-
else
|
241
|
-
meta = {key: nil, iv: nil}
|
242
|
-
parser[sha64] = meta
|
243
|
-
end
|
244
|
-
meta[:key] = Base64.encode64(@key) if @key
|
245
|
-
meta[:iv] = Base64.encode64(@iv) if @iv
|
246
|
-
set_parser(file, parser)
|
247
|
-
end
|
248
|
-
|
249
|
-
private
|
250
|
-
def get_parser (file = nil)
|
251
|
-
file = PARSER_FILE if !file
|
252
|
-
# create the directory unless it exists
|
253
|
-
Dir.mkdir(WORKING_DIR) unless Dir.exist?(WORKING_DIR)
|
254
|
-
parser = {}
|
255
|
-
if File.file?(file)
|
256
|
-
fd = File.open(file,"r")
|
257
|
-
parser = JSON.load(fd)
|
258
|
-
fd.close
|
259
|
-
end
|
260
|
-
return parser
|
261
|
-
end
|
262
|
-
def set_parser (file = nil, parser = {})
|
263
|
-
file = PARSER_FILE if !file
|
264
|
-
# create the directory unless it exists
|
265
|
-
Dir.mkdir(WORKING_DIR) unless Dir.exist?(WORKING_DIR)
|
266
|
-
fd = File.open(file,"w")
|
267
|
-
fd << parser.to_json
|
268
|
-
fd.close
|
269
|
-
end
|
270
|
-
def sha256 (str = nil)
|
271
|
-
sha = OpenSSL::Digest::SHA256.new
|
272
|
-
digest = sha.digest(str) unless !str
|
273
|
-
sha.reset
|
274
|
-
digest
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def self.encrypt (str)
|
279
|
-
cipher = OpenSSL::Cipher.new('aes-256-cbc')
|
280
|
-
cipher.encrypt
|
281
|
-
key = cipher.random_key
|
282
|
-
iv = cipher.random_iv
|
283
|
-
|
284
|
-
str_c = ""
|
285
|
-
while str.length > 0
|
286
|
-
str_c += cipher.update(str.slice!(0, 4096))
|
287
|
-
end
|
288
|
-
str_c += cipher.final
|
289
|
-
EncryptedData.new({content: str_c, key: key, iv: iv})
|
290
|
-
end
|
291
|
-
|
292
|
-
def self.decrypt (encrypted_data)
|
293
|
-
unless encrypted_data && encrypted_data.key && encrypted_data.iv
|
294
|
-
return nil
|
295
|
-
end
|
296
|
-
cipher = OpenSSL::Cipher.new('aes-256-cbc')
|
297
|
-
cipher.decrypt
|
298
|
-
cipher.key = encrypted_data.key
|
299
|
-
cipher.iv = encrypted_data.iv
|
300
|
-
str_c = encrypted_data.content
|
301
|
-
str = ""
|
302
|
-
while str_c.length > 0
|
303
|
-
str += cipher.update(str_c.slice!(0, 4096))
|
304
|
-
#puts str[-50..-1] || str
|
305
|
-
end
|
306
|
-
str += cipher.final
|
307
|
-
return str
|
308
|
-
end
|
309
|
-
|
310
|
-
end
|
311
|
-
=begin
|
312
|
-
class Includer
|
313
|
-
include Crypto
|
314
|
-
end
|
315
|
-
CRYPTO = Includer.new
|
316
|
-
=end
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
|
321
|
-
run! if __FILE__==$0
|