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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -1
  3. data/eco-helpers.gemspec +1 -1
  4. data/lib/eco/api/common/loaders/case_base.rb +2 -3
  5. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +97 -47
  6. data/lib/eco/api/common/people/default_parsers/select_parser.rb +2 -2
  7. data/lib/eco/api/common/people/default_parsers/xls_parser.rb +0 -1
  8. data/lib/eco/api/common/people/entry_factory.rb +13 -8
  9. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +2 -2
  10. data/lib/eco/api/common/session/base_session.rb +1 -2
  11. data/lib/eco/api/common/session/environment.rb +6 -10
  12. data/lib/eco/api/common/session/helpers/prompt_user.rb +18 -18
  13. data/lib/eco/api/common/session/mailer.rb +1 -3
  14. data/lib/eco/api/common/session/s3_uploader.rb +1 -3
  15. data/lib/eco/api/common/session/sftp.rb +6 -4
  16. data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +5 -4
  17. data/lib/eco/api/session/config/api.rb +4 -2
  18. data/lib/eco/api/usecases/base_case.rb +0 -2
  19. data/lib/eco/api/usecases/base_io.rb +0 -3
  20. data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +1 -1
  21. data/lib/eco/api/usecases/ooze_samples/ooze_from_doc_case.rb +1 -2
  22. data/lib/eco/api/usecases/ooze_samples/ooze_run_base_case.rb +0 -1
  23. data/lib/eco/api/usecases/ooze_samples/ooze_update_case.rb +0 -1
  24. data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +1 -1
  25. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +0 -2
  26. data/lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb +0 -1
  27. data/lib/eco/api/usecases/ooze_samples.rb +0 -1
  28. data/lib/eco/api/usecases/use_case.rb +4 -1
  29. data/lib/eco/api/usecases/use_case_chain.rb +1 -4
  30. data/lib/eco/api/usecases/use_case_io.rb +0 -2
  31. data/lib/eco/api.rb +0 -2
  32. data/lib/eco/cli/config/default/options.rb +11 -1
  33. data/lib/eco/csv.rb +4 -7
  34. data/lib/eco/data/files/directory.rb +0 -3
  35. data/lib/eco/data/files/encoding.rb +75 -0
  36. data/lib/eco/data/files/helpers.rb +15 -37
  37. data/lib/eco/data/files.rb +1 -0
  38. data/lib/eco/data/fuzzy_match.rb +8 -4
  39. data/lib/eco/data.rb +0 -1
  40. data/lib/eco/version.rb +1 -1
  41. data/lib/eco-helpers.rb +1 -1
  42. metadata +5 -6
  43. data/lib/eco/data/crypto/encryption.rb +0 -321
  44. 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
@@ -1,7 +0,0 @@
1
- module Eco
2
- module Data
3
- module Crypto
4
- end
5
- end
6
- end
7
- require_relative 'crypto/encryption'