xhash_client 0.3.0 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7744b9f0b562d4f040b9bc1dd81c9410005c1ec9d8390cd4325c1befe6effcd
4
- data.tar.gz: b2a5b8a32776005f55b6d8f3fade17713994f978a4c666f8c4c093a7faf377d5
3
+ metadata.gz: 51cfc749e3e0033b38f6c080a3b879cb23d529d4ff2b18be8b51bb00dbaebe01
4
+ data.tar.gz: a63139c2bfe211afd2e9071577b791e194dbc5fe66512d8da5973bb8a8ddeaf4
5
5
  SHA512:
6
- metadata.gz: cfa44d85264d7d0a57444efa14171c9fc6ab7dcd683dfd63203623d6cd9d46c5c70c1a1dcf646bbc67e6f06a773167d0a45bfe822637e28ff9935804957c92eb
7
- data.tar.gz: 7cf8944d01ae81a9d95231ccad0ea53bbe75402a99c3ef8831e0bbe6c2f25880ff2cfb624818f439fb67449cd41890f1c1052adbfd57ff283f3c98125bf21353
6
+ metadata.gz: 8aa84976a5e204f2357f4be92aca1292369d8f0dab40fa89ef8e9cc4b7cdc11e7230cda637df725d5a3b7e07f4713b44bc0a7e6085d3a81201ce23da063f1df2
7
+ data.tar.gz: 64fdd3eaa5c9276b8ff27411e641e500b185d25041f672e71d7c6333019e9d40fc2e9950964a240b90af2b6f9dc979400591ed8a956a3341b6609b336e0c8a0c
@@ -0,0 +1,59 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+
52
+ # Mac
53
+ .DS_Store
54
+
55
+ # Windows
56
+ Thumbs.db
57
+
58
+ # WebStorm
59
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
+
4
+ # Declare your gem's dependencies in commons.gemspec.
5
+ # Bundler will treat runtime dependencies like base dependencies, and
6
+ # development dependencies will be added by default to the :development group.
7
+ gemspec
8
+
9
+ # Declare any dependencies that are still in development here instead of in
10
+ # your gemspec. These might include edge Rails or gems from your path or
11
+ # Git. Remember to move these dependencies to your gemspec before releasing
12
+ # your gem to rubygems.org.
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ xhash_client (0.3.4)
5
+ httparty (~> 0.16.0)
6
+ json (~> 2.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.7.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
13
+ crack (0.4.3)
14
+ safe_yaml (~> 1.0.0)
15
+ diff-lcs (1.3)
16
+ docile (1.3.2)
17
+ hashdiff (1.0.0)
18
+ httparty (0.16.4)
19
+ mime-types (~> 3.0)
20
+ multi_xml (>= 0.5.2)
21
+ json (2.2.0)
22
+ mime-types (3.3.1)
23
+ mime-types-data (~> 3.2015)
24
+ mime-types-data (3.2020.0512)
25
+ multi_xml (0.6.0)
26
+ public_suffix (4.0.1)
27
+ rspec (3.8.0)
28
+ rspec-core (~> 3.8.0)
29
+ rspec-expectations (~> 3.8.0)
30
+ rspec-mocks (~> 3.8.0)
31
+ rspec-core (3.8.2)
32
+ rspec-support (~> 3.8.0)
33
+ rspec-expectations (3.8.4)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.8.0)
36
+ rspec-mocks (3.8.1)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.8.0)
39
+ rspec-support (3.8.2)
40
+ safe_yaml (1.0.5)
41
+ simplecov (0.17.0)
42
+ docile (~> 1.1)
43
+ json (>= 1.8, < 3)
44
+ simplecov-html (~> 0.10.0)
45
+ simplecov-html (0.10.2)
46
+ webmock (3.7.2)
47
+ addressable (>= 2.3.6)
48
+ crack (>= 0.3.2)
49
+ hashdiff (>= 0.4.0, < 2.0.0)
50
+
51
+ PLATFORMS
52
+ ruby
53
+
54
+ DEPENDENCIES
55
+ rspec (~> 3.8)
56
+ simplecov (~> 0.17)
57
+ webmock (~> 3.7)
58
+ xhash_client!
59
+
60
+ BUNDLED WITH
61
+ 1.17.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Yellowme
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ # xhash-ruby
2
+ Ruby Bindings for Xhash API
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ # Default directory to look in is `/spec`
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ require 'singleton'
2
+
3
+ module Xhash
4
+ class ApiClient
5
+ include Xhash::JsonApi
6
+
7
+ def self.config
8
+ yield self
9
+ end
10
+
11
+ def self.api_base
12
+ @api_base
13
+ end
14
+
15
+ def self.api_base=(api_base)
16
+ @api_base = api_base
17
+ end
18
+
19
+ def self.api_key
20
+ @api_key
21
+ end
22
+
23
+ def self.api_key=(api_key)
24
+ @api_key = api_key
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,65 @@
1
+ require 'httparty'
2
+
3
+ module Xhash
4
+ module JsonApi
5
+ module ClassMethods
6
+ def default_headers
7
+ {
8
+ 'Content-type' => 'application/json', 'Authorization' => Xhash.api_key
9
+ }
10
+ end
11
+
12
+ def api_get(url:, headers: {})
13
+ custom_headers = headers.merge(default_headers)
14
+ response = HTTParty.get(Xhash.api_base + url, headers: custom_headers)
15
+
16
+ raise Xhash::Error.new(response) unless response_ok?(response)
17
+
18
+ begin
19
+ JSON.parse(response.body, symbolize_names: true)
20
+ rescue => exception
21
+ raise Xhash::MalformedResponse.new
22
+ end
23
+ end
24
+
25
+ def api_post(url:, body: {}, headers: {})
26
+ custom_headers = headers.merge(default_headers)
27
+
28
+ response =
29
+ HTTParty.post(
30
+ Xhash.api_base + url,
31
+ body: body.to_json, headers: custom_headers
32
+ )
33
+
34
+ raise Xhash::Error.new(response) unless response_ok?(response)
35
+
36
+ begin
37
+ JSON.parse(response.body, symbolize_names: true)
38
+ rescue => exception
39
+ raise Xhash::MalformedResponse.new
40
+ end
41
+ end
42
+
43
+ def api_post_multipart(url:, body: {}, headers: {})
44
+ custom_headers = headers.merge(default_headers)
45
+
46
+ response =
47
+ HTTParty.post(
48
+ Xhash.api_base + url,
49
+ multipart: true, body: body, headers: custom_headers
50
+ )
51
+
52
+ raise Xhash::Error.new(response) unless response_ok?(response)
53
+ response.body
54
+ end
55
+
56
+ def response_ok?(response)
57
+ !(response.code == 404 || response.code >= 500)
58
+ end
59
+ end
60
+
61
+ def self.included(base)
62
+ base.extend(ClassMethods)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,28 @@
1
+ module Xhash
2
+ class DatabaseLookup < ApiClient
3
+ def self.renapo(curp)
4
+ url = 'database-lookup/renapo'
5
+ body = { curp: curp }
6
+ response = api_post(url: url, body: body)
7
+ payload = response[:payload]
8
+
9
+ if payload.nil?
10
+ raise Xhash::MissingRequiredFieldError.new(
11
+ {
12
+ message: Xhash::ErrorMessage::MISSING_CURP, response: response
13
+ }
14
+ )
15
+ end
16
+
17
+ if payload[:name] == 'CURP INVALIDO'
18
+ raise Xhash::InvalidFieldError.new(
19
+ {
20
+ message: Xhash::ErrorMessage::INVALID_CURP, response: response
21
+ }
22
+ )
23
+ end
24
+
25
+ Xhash::CURP.new(*payload.values_at(*Xhash::CURP.members))
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ module Xhash
2
+ module DocumentType
3
+ module ID
4
+ INE_FRONT = 1
5
+ PASSPORT = 2
6
+ INE_REVERSE = 7
7
+ MILITARY_ID = 6
8
+ end
9
+ module ProofOfAddress
10
+ CFE = 3
11
+ AXTEL = 4
12
+ TELMEX = 5
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module Xhash
2
+ class Error < StandardError
3
+ attr_reader :message, :response
4
+
5
+ def initialize(options = {})
6
+ if options.is_a? Hash
7
+ @message = options[:message]
8
+ @response = options[:response]
9
+ else
10
+ @message = "Server error"
11
+ @response = options
12
+ end
13
+
14
+ super
15
+ end
16
+ end
17
+
18
+ class MissingRequiredFieldError < Error; end
19
+
20
+ class InvalidFieldError < Error; end
21
+
22
+ class MalformedResponse < Error; end
23
+ end
@@ -0,0 +1,8 @@
1
+ module Xhash
2
+ module ErrorMessage
3
+ INVALID_CURP = 'The selected CURP is invalid'
4
+ MISSING_CURP = 'The selected CURP is required'
5
+ INVALID_FILE = 'The selected document is invalid'
6
+ MISSING_FILE = 'The selected document is required'
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Xhash
2
+ module Formatters
3
+ def self.invalid_field_message_to_s(hash)
4
+ message = ''
5
+ hash.each { |key, value| message += value[0] + ' ' }
6
+ message.strip
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ module Xhash
2
+ class General < ApiClient
3
+ def self.store_data(*user_body)
4
+ url = 'store-data'
5
+ body = Hash[*user_body]
6
+ response = api_post(url: url, body: body)
7
+
8
+ unless response[:id]
9
+ raise Xhash::MissingRequiredFieldError.new(
10
+ {
11
+ message:
12
+ Xhash::Formatters.invalid_field_message_to_s(response),
13
+ response: response
14
+ }
15
+ )
16
+ end
17
+
18
+ Xhash::Customer.new(*response.values_at(*Xhash::Customer.members))
19
+ end
20
+
21
+ def self.get_customer(customer_id:)
22
+ url = "get-customer/#{customer_id}"
23
+ response = api_get(url: url)
24
+ payload = response[:payload]
25
+
26
+ if payload.nil?
27
+ raise Xhash::MissingRequiredFieldError.new(
28
+ {
29
+ message:
30
+ Xhash::Formatters.invalid_field_message_to_s(response),
31
+ response: response
32
+ }
33
+ )
34
+ end
35
+
36
+ Xhash::Customer.new(*payload.values_at(*Xhash::Customer.members))
37
+ end
38
+
39
+ def self.store_file(customer_id:, document_type:, document:)
40
+ url = 'store-file'
41
+ headers = { 'boundary' => '---011000010111000001101001' }
42
+ body = {
43
+ 'customer_id' => customer_id,
44
+ 'document_type' => document_type,
45
+ 'document' => document
46
+ }
47
+
48
+ response = api_post_multipart(url: url, body: body, headers: headers)
49
+
50
+ unless response == 'Image stored'
51
+ error = JSON.parse(response, symbolize_names: true)
52
+ raise Xhash::MissingRequiredFieldError.new(
53
+ {
54
+ message: Xhash::Formatters.invalid_field_message_to_s(error),
55
+ response: error
56
+ }
57
+ )
58
+ end
59
+
60
+ response
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,124 @@
1
+ module Xhash
2
+ class OCR < ApiClient
3
+ IDENTIFICATION_TYPES = ['INE', 'CARTILLA MILITAR', 'PASAPORTE']
4
+
5
+ def self.generic(document_url: nil, document_file: nil)
6
+ url = 'ocr'
7
+
8
+ if document_url.nil? and document_file.nil?
9
+ raise Xhash::MissingRequiredFieldError.new(
10
+ { message: Xhash::ErrorMessage::MISSING_FILE }
11
+ )
12
+ end
13
+
14
+ payload =
15
+ request_by_file_or_url(
16
+ url: url, document_url: document_url, document_file: document_file
17
+ )
18
+
19
+ is_identification = IDENTIFICATION_TYPES.include? payload[:type]
20
+
21
+ document =
22
+ if is_identification
23
+ Xhash::Identification.new(
24
+ *payload.values_at(*Xhash::Identification.members)
25
+ )
26
+ else
27
+ Xhash::ProofOfAddress.new(
28
+ *payload.values_at(*Xhash::ProofOfAddress.members)
29
+ )
30
+ end
31
+
32
+ document
33
+ end
34
+
35
+ def self.identification(document_url: nil, document_file: nil)
36
+ url = 'ocr/identification'
37
+
38
+ if document_url.nil? and document_file.nil?
39
+ raise Xhash::MissingRequiredFieldError.new(
40
+ { message: Xhash::ErrorMessage::MISSING_FILE }
41
+ )
42
+ end
43
+
44
+ payload =
45
+ request_by_file_or_url(
46
+ url: url, document_url: document_url, document_file: document_file
47
+ )
48
+
49
+ Xhash::Identification.new(
50
+ *payload.values_at(*Xhash::Identification.members)
51
+ )
52
+ end
53
+
54
+ def self.proof_of_address(document_url: nil, document_file: nil)
55
+ url = 'ocr/proof-of-address'
56
+
57
+ if document_url.nil? and document_file.nil?
58
+ raise Xhash::MissingRequiredFieldError.new(
59
+ { message: Xhash::ErrorMessage::MISSING_FILE }
60
+ )
61
+ end
62
+
63
+ payload =
64
+ request_by_file_or_url(
65
+ url: url, document_url: document_url, document_file: document_file
66
+ )
67
+
68
+ Xhash::ProofOfAddress.new(
69
+ *payload.values_at(*Xhash::ProofOfAddress.members)
70
+ )
71
+ end
72
+
73
+ def self.ine_reverse(document_url: nil, document_file: nil)
74
+ url = 'ocr/ine-reverse'
75
+
76
+ if document_url.nil? and document_file.nil?
77
+ raise Xhash::MissingRequiredFieldError.new(
78
+ { message: Xhash::ErrorMessage::MISSING_FILE }
79
+ )
80
+ end
81
+
82
+ payload =
83
+ request_by_file_or_url(
84
+ url: url, document_url: document_url, document_file: document_file
85
+ )
86
+
87
+ Xhash::Identification.new(
88
+ *payload.values_at(*Xhash::Identification.members)
89
+ )
90
+ end
91
+
92
+ private
93
+
94
+ def self.request_by_file_or_url(
95
+ url: nil, document_url: nil, document_file: nil
96
+ )
97
+ body = {
98
+ 'document_url' => document_url, 'document_file' => document_file
99
+ }.compact
100
+
101
+ response =
102
+ if document_file.nil?
103
+ api_post(
104
+ url: url,
105
+ body: body,
106
+ headers: { 'boundary' => '---011000010111000001101001' }
107
+ )
108
+ else
109
+ data = api_post_multipart(url: url, body: body)
110
+ JSON.parse(data, symbolize_names: true)
111
+ end
112
+
113
+ payload = response[:payload]
114
+
115
+ if payload.nil?
116
+ raise Xhash::InvalidFieldError.new(
117
+ { message: Xhash::ErrorMessage::INVALID_FILE }
118
+ )
119
+ end
120
+
121
+ payload
122
+ end
123
+ end
124
+ end