eligible 2.6.1 → 2.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a05ae8ed310f92bfdb9169633be20e586d904bf
4
- data.tar.gz: 7bc7e0bce25b7e2584414c6c63b08f85740be705
3
+ metadata.gz: 3c044453aea1d5ef70a34c8e8b2e08bd0bdd9e65
4
+ data.tar.gz: 3219b7cba1332fb1a8b9cf8254f731242aa05bd4
5
5
  SHA512:
6
- metadata.gz: 2bac9428455a3ca9b8361f75d30d79b0b61ef590c6778a4f4a7f2f36b7afec21b72c2f89eed0364e94e2a907c019966ab93d8892135cf4941df5ee71f52dfb4f
7
- data.tar.gz: c42fe8b8b825e9dd3227d86292fae9f7953e7ddd72e1703faafcda5cd1d876e791c54ad78814cc19facf2e666a2999d4ba6a451a5c37a525da7678256e90b503
6
+ metadata.gz: eceba947c63c89845382f4bfdc5734bc78eee5ae190bcdc7a6fb51675b2f896da9c7ed9bd2b0e66ce425d4606a6ffbf4d7d7c8a866e768863f3b187c8c690760
7
+ data.tar.gz: 2555d78ea46984e2b12afca36cd79a76d6887868bbd4fdafae7406afa0e9c9472ac522484e7f4cb38761b804b9195b83b173c14f5f67835e3c1004edbc99cb95
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.3
data/ChangeLog CHANGED
@@ -1,9 +1,13 @@
1
+ 2016-08-31 Eligible <support@eligible.com>
2
+ * 2.6.2
3
+ - New APIs added in testing mode, no public-facing changes
4
+
1
5
  2016-05-10 Eligible <support@eligible.com>
2
6
  * 2.6.1
3
- - Suppressing ssl_verify_callback return code warning
4
- - Added new endpoints: received_pdf, precert and referral
5
- - Refactored the code and fixed couple of bugs
6
- - Documentation updates for the endpoints
7
+ - Suppressing ssl_verify_callback return code warning
8
+ - Added new endpoints: received_pdf, precert and referral
9
+ - Refactored the code and fixed couple of bugs
10
+ - Documentation updates for the endpoints
7
11
 
8
12
  2016-02-23 Eligible <support@eligible.com>
9
13
 
data/lib/eligible.rb CHANGED
@@ -8,6 +8,7 @@ require 'rest_client'
8
8
  require 'multi_json'
9
9
 
10
10
  require 'eligible/version'
11
+ require 'eligible/encryptor'
11
12
  require 'eligible/util'
12
13
  require 'eligible/json'
13
14
  require 'eligible/eligible_object'
@@ -28,6 +29,8 @@ require 'eligible/payer'
28
29
  require 'eligible/preauth_resource'
29
30
  require 'eligible/precert'
30
31
  require 'eligible/referral'
32
+ require 'eligible/public_key'
33
+ require 'eligible/lockbox'
31
34
 
32
35
  # Errors
33
36
  require 'eligible/errors/eligible_error'
@@ -0,0 +1,115 @@
1
+ require 'openssl'
2
+
3
+ module Eligible
4
+ # A simple wrapper for the standard OpenSSL library
5
+ module Encryptor
6
+
7
+ extend self
8
+
9
+ # The default options to use when calling the <tt>encrypt</tt> and <tt>decrypt</tt> methods
10
+ #
11
+ # Defaults to { algorithm: 'aes-256-gcm',
12
+ # auth_data: '',
13
+ # insecure_mode: false,
14
+ # hmac_iterations: 2000,
15
+ # v2_gcm_iv: false }
16
+ #
17
+ # Run 'openssl list-cipher-commands' in your terminal to view a list all cipher algorithms that are supported on your platform
18
+ def default_options
19
+ @default_options ||= { algorithm: 'aes-256-cbc',
20
+ auth_data: '',
21
+ insecure_mode: false,
22
+ hmac_iterations: 2000,
23
+ v2_gcm_iv: false }
24
+ end
25
+
26
+ # Encrypts a <tt>:value</tt> with a specified <tt>:key</tt> and <tt>:iv</tt>.
27
+ #
28
+ # Optionally accepts <tt>:salt</tt>, <tt>:auth_data</tt>, <tt>:algorithm</tt>, <tt>:hmac_iterations</tt>, and <tt>:insecure_mode</tt> options.
29
+ #
30
+ # Example
31
+ #
32
+ # encrypted_value = Encryptor.encrypt(value: 'some string to encrypt', key: 'some secret key', iv: 'some unique value', salt: 'another unique value')
33
+ # # or
34
+ # encrypted_value = Encryptor.encrypt('some string to encrypt', key: 'some secret key', iv: 'some unique value', salt: 'another unique value')
35
+ def encrypt(*args, &block)
36
+ crypt :encrypt, *args, &block
37
+ end
38
+
39
+ # Decrypts a <tt>:value</tt> with a specified <tt>:key</tt> and <tt>:iv</tt>.
40
+ #
41
+ # Optionally accepts <tt>:salt</tt>, <tt>:auth_data</tt>, <tt>:algorithm</tt>, <tt>:hmac_iterations</tt>, and <tt>:insecure_mode</tt> options.
42
+ #
43
+ # Example
44
+ #
45
+ # decrypted_value = Encryptor.decrypt(value: 'some encrypted string', key: 'some secret key', iv: 'some unique value', salt: 'another unique value')
46
+ # # or
47
+ # decrypted_value = Encryptor.decrypt('some encrypted string', key: 'some secret key', iv: 'some unique value', salt: 'another unique value')
48
+ def decrypt(*args, &block)
49
+ crypt :decrypt, *args, &block
50
+ end
51
+
52
+ protected
53
+
54
+ def crypt(cipher_method, *args) #:nodoc:
55
+ options = default_options.merge(value: args.first).merge(args.last.is_a?(Hash) ? args.last : {})
56
+ raise ArgumentError.new('must specify a key') if options[:key].to_s.empty?
57
+ cipher = OpenSSL::Cipher.new(options[:algorithm])
58
+ cipher.send(cipher_method)
59
+ unless options[:insecure_mode]
60
+ raise ArgumentError.new("key must be #{cipher.key_len} bytes or longer") if options[:key].bytesize < cipher.key_len
61
+ raise ArgumentError.new('must specify an iv') if options[:iv].to_s.empty?
62
+ raise ArgumentError.new("iv must be #{cipher.iv_len} bytes or longer") if options[:iv].bytesize < cipher.iv_len
63
+ end
64
+ if options[:iv]
65
+ # This is here for backwards compatibility for Encryptor v2.0.0.
66
+ cipher.iv = options[:iv] if options[:v2_gcm_iv]
67
+ if options[:salt].nil?
68
+ # Use a non-salted cipher.
69
+ # This behaviour is retained for backwards compatibility. This mode
70
+ # is not secure and new deployments should use the :salt options
71
+ # wherever possible.
72
+ cipher.key = options[:key]
73
+ else
74
+ # Use an explicit salt (which can be persisted into a database on a
75
+ # per-column basis, for example). This is the preferred (and more
76
+ # secure) mode of operation.
77
+ cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(options[:key], options[:salt], options[:hmac_iterations], cipher.key_len)
78
+ end
79
+ cipher.iv = options[:iv] unless options[:v2_gcm_iv]
80
+ else
81
+ # This is deprecated and needs to be changed.
82
+ cipher.pkcs5_keyivgen(options[:key])
83
+ end
84
+ yield cipher, options if block_given?
85
+ value = options[:value]
86
+ if cipher.authenticated?
87
+ if encryption?(cipher_method)
88
+ cipher.auth_data = options[:auth_data]
89
+ else
90
+ value = extract_cipher_text(options[:value])
91
+ cipher.auth_tag = extract_auth_tag(options[:value])
92
+ # auth_data must be set after auth_tag has been set when decrypting
93
+ # See http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-auth_data-3D
94
+ cipher.auth_data = options[:auth_data]
95
+ end
96
+ end
97
+ result = cipher.update(value)
98
+ result << cipher.final
99
+ result << cipher.auth_tag if cipher.authenticated? && encryption?(cipher_method)
100
+ result
101
+ end
102
+
103
+ def encryption?(cipher_method)
104
+ cipher_method == :encrypt
105
+ end
106
+
107
+ def extract_cipher_text(value)
108
+ value[0..-17]
109
+ end
110
+
111
+ def extract_auth_tag(value)
112
+ value[-16..-1]
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,39 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module Eligible
5
+ class Lockbox < APIResource
6
+ def self.get(params, api_key = nil)
7
+ send_request(:get, api_url('lockboxes', params, :lockbox_id), api_key, params, :lockbox_id)
8
+ end
9
+
10
+ def self.all(params, api_key = nil)
11
+ send_request(:get, api_url('lockboxes'), api_key, params)
12
+ end
13
+
14
+ def self.extract_private_key(params)
15
+ private_key = Util.value(params, :private_key)
16
+ fail ArgumentError, "Private key is required for decryption" if private_key.nil?
17
+ private_key
18
+ end
19
+
20
+ def self.delete_private_key!(params)
21
+ params.delete('private_key')
22
+ params.delete(:private_key)
23
+ end
24
+
25
+ def self.decrypt_data(data, encrypted_data_key, private_key)
26
+ pkey = OpenSSL::PKey::RSA.new(private_key)
27
+ aes_key = pkey.private_decrypt(Base64.decode64(encrypted_data_key))
28
+ sha_key = Digest::SHA256.hexdigest(aes_key)
29
+ Encryptor.decrypt(value: Base64.decode64(data), key: sha_key, insecure_mode: true)
30
+ end
31
+
32
+ def self.get_and_decrypt_from_lockbox(params, api_key = nil)
33
+ private_key = extract_private_key(params)
34
+ delete_private_key!(params)
35
+ req = get(params, api_key).to_hash
36
+ decrypt_data(req[:encrypted_data], req[:encrypted_key], private_key)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ require 'openssl'
2
+
3
+ module Eligible
4
+ class PublicKey < APIResource
5
+ def self.get(params, api_key = nil)
6
+ send_request(:get, api_url('public_keys', params, :key_id), api_key, params, :key_id)
7
+ end
8
+
9
+ def self.post(params, api_key = nil)
10
+ send_request(:post, api_url('public_keys'), api_key, params)
11
+ end
12
+
13
+ def self.activate(params, api_key = nil)
14
+ key_id = Util.value(params, :key_id)
15
+ send_request(:get, "/public_keys/#{key_id}/activate.json", api_key, params, :key_id)
16
+ end
17
+
18
+ def self.all(params, api_key = nil)
19
+ send_request(:get, api_url('public_keys'), api_key, params)
20
+ end
21
+
22
+ def self.create_pair
23
+ rsa_key = OpenSSL::PKey::RSA.new(4096)
24
+ [ rsa_key.to_pem, rsa_key.public_key.to_pem ]
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Eligible
2
- VERSION = '2.6.1'.freeze
2
+ VERSION = '2.6.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eligible
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.1
4
+ version: 2.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katelyn Gleaon
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-05-10 00:00:00.000000000 Z
13
+ date: 2016-08-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -110,6 +110,7 @@ files:
110
110
  - ".gitignore"
111
111
  - ".rspec"
112
112
  - ".rubocop.yml"
113
+ - ".ruby-version"
113
114
  - ChangeLog
114
115
  - Gemfile
115
116
  - LICENSE
@@ -124,6 +125,7 @@ files:
124
125
  - lib/eligible/customer.rb
125
126
  - lib/eligible/demographic.rb
126
127
  - lib/eligible/eligible_object.rb
128
+ - lib/eligible/encryptor.rb
127
129
  - lib/eligible/enrollment.rb
128
130
  - lib/eligible/errors/api_connection_error.rb
129
131
  - lib/eligible/errors/api_error.rb
@@ -131,12 +133,14 @@ files:
131
133
  - lib/eligible/errors/eligible_error.rb
132
134
  - lib/eligible/errors/invalid_request_error.rb
133
135
  - lib/eligible/json.rb
136
+ - lib/eligible/lockbox.rb
134
137
  - lib/eligible/medicare.rb
135
138
  - lib/eligible/original_signature_pdf.rb
136
139
  - lib/eligible/payer.rb
137
140
  - lib/eligible/payment.rb
138
141
  - lib/eligible/preauth_resource.rb
139
142
  - lib/eligible/precert.rb
143
+ - lib/eligible/public_key.rb
140
144
  - lib/eligible/received_pdf.rb
141
145
  - lib/eligible/referral.rb
142
146
  - lib/eligible/ticket.rb