trustev 0.1.0

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.
@@ -0,0 +1,47 @@
1
+ require 'digest'
2
+
3
+ module Trustev
4
+ class Authenticate
5
+
6
+ SERVICE_URL = 'AuthenticationService.svc/rest/Token'
7
+
8
+ def self.retrieve_token
9
+
10
+ raise Error.new('No Username provided.') unless Trustev.username
11
+ raise Error.new('No Password provided.') unless Trustev.password
12
+ raise Error.new('No Shared Secret provided.') unless Trustev.shared_secret
13
+
14
+ time = Time.now.utc
15
+
16
+ body = {
17
+ UserName: Trustev.username,
18
+ Password: password(time),
19
+ Sha256Hash: sha256hash(time),
20
+ Timestamp: "\/Date(#{time.to_i*1000})\/"
21
+ }
22
+
23
+ response = Trustev.send_request SERVICE_URL, body, 'POST', true, false
24
+ Trustev.token = response[:Token][:APIToken]
25
+ Trustev.token_expire = response[:Token][:ExpireAt][/\((.*)\)/m, 1].to_i/1000
26
+ end
27
+
28
+ private
29
+
30
+ def self.password(time)
31
+ generate_hash Trustev.password, time
32
+ end
33
+
34
+ def self.sha256hash(time)
35
+ generate_hash Trustev.username, time
36
+ end
37
+
38
+ def self.generate_hash(modifier, time)
39
+ sha256 = Digest::SHA256.new
40
+ sha256 << "#{time.strftime '%Y%m%d%H%M%S'}.#{modifier}"
41
+ hash_part_1 = sha256.hexdigest
42
+ sha256 = Digest::SHA256.new
43
+ sha256 << "#{hash_part_1}.#{Trustev.shared_secret}"
44
+ sha256.hexdigest
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ require 'digest'
2
+
3
+ module Trustev
4
+ class DigitalSignature
5
+
6
+ def initialize(digital_signature, timestamp, session_id, stage_1='')
7
+
8
+ raise Error.new('No Username provided.') unless Trustev.username
9
+ raise Error.new('No Password provided.') unless Trustev.password
10
+ raise Error.new('No Shared Secret provided.') unless Trustev.shared_secret
11
+ raise Error.new('No Private Key provided.') unless Trustev.private_key
12
+
13
+ @digital_signature = digital_signature
14
+ @timestamp = timestamp
15
+ @session_id = session_id
16
+ @stage_1 = stage_1
17
+ @stage_1 = ".#{stage_1}" unless @stage_1.empty?
18
+ end
19
+
20
+ def valid?
21
+ build_signature == @digital_signature
22
+ end
23
+
24
+ def invalid?
25
+ !valid?
26
+ end
27
+
28
+ private
29
+
30
+ def build_signature
31
+ sha256 = Digest::SHA256.new
32
+ sha256 << "#{Trustev.username}.#{Trustev.private_key}.#{@timestamp}#{@stage_1}"
33
+ stage_2 = sha256.hexdigest
34
+
35
+ sha256 = Digest::SHA256.new
36
+ sha256 << "#{stage_2}.#{Trustev.private_key}.#{@session_id}"
37
+ sha256.hexdigest
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ module Trustev
2
+ class Error < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+
6
+ def initialize(message=nil, http_status=nil, trustev_message=nil)
7
+ @message = "#{message} #{trustev_message}"
8
+ @http_status = http_status
9
+
10
+ super(message)
11
+ end
12
+
13
+ def to_s
14
+ status_string = @http_status.nil? ? '' : "(Status #{@http_status}) "
15
+ "#{status_string}#{@message}"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Trustev
2
+ class Profile
3
+
4
+ SERVICE_URL = 'ProfileService.svc/rest/Transaction'
5
+
6
+ SOURCES = [0, 1, 2, 3, 4, 5, 6, 7, 8]
7
+
8
+ PARAMETERS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
9
+
10
+ def initialize(transaction_number)
11
+ raise Error.new('Transaction Number is required') if transaction_number.nil?
12
+ @transaction_number = transaction_number
13
+ end
14
+
15
+ def retrieve_scores
16
+ Trustev.send_request "#{SERVICE_URL}/#{@transaction_number}", [], 'GET', true
17
+ end
18
+
19
+ def get_overall_score
20
+ get_score(7, 0)
21
+ end
22
+
23
+ def get_score(source_id, parameter_id)
24
+ raise Error.new('Invalid Source') if SOURCES.index(source_id).nil?
25
+ raise Error.new('Invalid Parameter') if PARAMETERS.index(parameter_id).nil?
26
+ response = retrieve_scores
27
+ response[:Profile][:Sources].each do | source |
28
+ if source[:Source] == source_id
29
+ source[:Scores].each { | score | return score[:Score] if score[:Parameter] == parameter_id }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,57 @@
1
+ module Trustev
2
+ class Social
3
+
4
+ SERVICE_URL = 'SocialService.svc/rest/Profile'
5
+ SOCIAL_NETWORK_TYPES = [0, 1, 2, 3]
6
+
7
+ def self.create(social_networks=[])
8
+ validate(social_networks)
9
+ Trustev.send_request SERVICE_URL, build(social_networks), 'POST'
10
+ end
11
+
12
+ def self.update(social_network)
13
+ validate([social_network])
14
+ Trustev.send_request "#{SERVICE_URL}/#{social_network[:type]}/#{social_network[:id]}", build([social_network]), 'PUT'
15
+ end
16
+
17
+ def self.delete(social_network_type, social_network_id)
18
+ Trustev.send_request "#{SERVICE_URL}/#{social_network_type}/#{social_network_id}", {}, 'DELETE'
19
+ end
20
+
21
+ private
22
+
23
+ def self.validate(social_networks)
24
+ raise Error.new('Social Network array is empty') if social_networks.size == 0
25
+ social_networks.each do | social_network |
26
+ raise Error.new('Invalid Social Network Type') if SOCIAL_NETWORK_TYPES.index(social_network[:type]).nil?
27
+ raise Error.new('Social Network Type is required') if social_network[:type].nil?
28
+ raise Error.new('Social Network ID is required') if social_network[:id].nil?
29
+ raise Error.new('Short Term Access Token is required') if social_network[:short_term_token].nil?
30
+ raise Error.new('Long Term Access Token is required') if social_network[:long_term_token].nil?
31
+ raise Error.new('Short Term Access Token Expiry is required') if social_network[:short_term_expiry].nil?
32
+ raise Error.new('Long Term Access Token Expiry is required') if social_network[:long_term_expiry].nil?
33
+ raise Error.new('Social Network Secret is required') if social_network[:secret].nil?
34
+ end
35
+ end
36
+
37
+ def self.build(social_networks)
38
+ social_network_data = {
39
+ SocialNetworks: []
40
+ }
41
+
42
+ social_networks.each do | social_network |
43
+ social_network_data[:SocialNetworks].push({
44
+ Type: social_network[:type],
45
+ Id: social_network[:id],
46
+ ShortTermAccessToken: social_network[:short_term_token],
47
+ LongTermAccessToken: social_network[:long_term_token],
48
+ ShortTermAccessTokenExpiry: "\/Date(#{social_network[:short_term_expiry]})\/",
49
+ LongTermAccessTokenExpiry: "\/Date(#{social_network[:long_term_expiry]})\/",
50
+ Secret: social_network[:secret]
51
+ })
52
+ end
53
+
54
+ social_network_data
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,200 @@
1
+ require 'digest'
2
+
3
+ module Trustev
4
+ class Transaction
5
+
6
+ SERVICE_URL = 'TransactionService.svc/rest/Transaction'
7
+
8
+ CURRENCY_CODES = %w(ADP AED AFA AFN ALK ALL AMD ANG AOA AOK AON AOR ARA ARP ARS
9
+ ARY ATS AUD AWG AYM AZM AZN BAD BAM BBD BDT BEC BEF BEL BGJ
10
+ BGK BGL BGN BHD BIF BMD BND BOB BOP BOV BRB BRC BRE BRL BRN
11
+ BRR BSD BTN BUK BWP BYB BYR BZD CAD CDF CHC CHE CHF CHW CLF
12
+ CLP CNX CNY COP COU CRC CSD CSJ CSK CUC CUP CVE CYP CZK DDM
13
+ DEM DJF DKK DOP DZD ECS ECV EEK EGP EQE ERN ESA ESB ESP ETB
14
+ EUR FIM FJD FKP FRF GBP GEK GEL GHC GHP GHS GIP GMD GNE GNF
15
+ GNS GQE GRD GTQ GWE GWP GYD HKD HNL HRD HRK HTG HUF IDR IEP
16
+ ILP ILR ILS INR IQD IRR ISJ ISK ITL JMD JOD JPY KES KGS KHR
17
+ KMF KPW KRW KWD KYD KZT LAJ LAK LBP LKR LRD LSL LSM LTL LTT
18
+ LUC LUF LUL LVL LVR LYD MAD MAF MDL MGA MGF MKD MLF MMK MNT
19
+ MOP MRO MTL MTP MUR MVQ MVR MWK MXN MXP MXV MYR MZE MZM MZN
20
+ NAD NGN NIC NIO NLG NOK NPR NZD OMR PAB PEH PEI PEN PES PGK
21
+ PHP PKR PLN PLZ PTE PYG QAR RHD ROK ROL RON RSD RUB RUR RWF
22
+ SAR SBD SCR SDD SDG SDP SEK SGD SHP SIT SKK SLL SOS SRD SRG
23
+ SSP STD SUR SVC SYP SZL THB TJR TJS TMM TMT TND TOP TPE TRL
24
+ TRY TTD TWD TZS UAH UAK UGS UGW UGX USD USN USS UYI UYN UYP
25
+ UYU UZS VEB VEF VNC VND VUV WST XAF XAG XAU XBA XBB XBC XBD
26
+ XCD XDR XEU XFO XFU XOF XPD XPF XPT XRE XSU XTS XUA XXX YDD
27
+ YER YUD YUM YUN ZAL ZAR ZMK ZRN ZRZ ZWC ZWD ZWL ZWN ZWR)
28
+
29
+ COUNTRY_CODES = %w(AC AD AE AF AG AI AL AM AN AO AQ AR AS AT AU AW AX AZ BA BB BD
30
+ BE BF BG BH BI BJ BM BN BO BR BS BT BV BW BY BZ CA CC CD CF CG
31
+ CH CI CK CL CM CN CO CR CU CV CX CY CZ DE DJ DK DM DO DZ EC EE
32
+ EG ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN
33
+ GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ
34
+ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC
35
+ LI LK LR LS LT LU LV LY MA MC MD ME MG MH MK ML MM MN MO MP MQ
36
+ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NS NU
37
+ NZ OM PA PE PF PG PH PK PL PM PN PR PT PW PY QA RE RO RS RU RW
38
+ SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR ST SV SY SZ TA TC
39
+ TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ
40
+ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW)
41
+
42
+ ADDRESS_TYPES = [0, 1, 2]
43
+
44
+ STATUS_TYPES = [0, 1, 2, 3, 5, 8]
45
+
46
+ REASON_TYPES = [0, 1, 2, 3, 4]
47
+
48
+ def initialize(transaction_number)
49
+ raise Error.new('TransactionNumber is required.') if transaction_number.nil?
50
+ @transaction_number = transaction_number
51
+ end
52
+
53
+ def create(transaction=nil)
54
+ raise Error.new('Transaction options are missing') if transaction.nil?
55
+ validate(transaction)
56
+ Trustev.send_request SERVICE_URL, build(transaction), 'POST'
57
+ end
58
+
59
+ def update(transaction=nil)
60
+ raise Error.new('Transaction options are missing') if transaction.nil?
61
+ validate(transaction)
62
+ Trustev.send_request "#{SERVICE_URL}/#{@transaction_number}", build(transaction), 'PUT'
63
+ end
64
+
65
+ def set_status(status, reason, comment)
66
+ raise Error.new('Invalid Status Code') if STATUS_TYPES.index(status).nil?
67
+ raise Error.new('Invalid Reason Code') if REASON_TYPES.index(reason).nil?
68
+ raise Error.new('Status comment cannot be blank') if comment.nil? || comment.empty?
69
+ body = {
70
+ Status: status,
71
+ Reason: reason,
72
+ Comment: comment
73
+ }
74
+ Trustev.send_request "#{SERVICE_URL}/#{@transaction_number}/Status", body, 'PUT'
75
+ end
76
+
77
+ def set_bin(bin)
78
+ raise Error.new('BIN is required') if bin.nil?
79
+ body = {
80
+ BINNumber: bin
81
+ }
82
+ Trustev.send_request "#{SERVICE_URL}/#{@transaction_number}/BIN", body, 'PUT'
83
+ end
84
+
85
+ private
86
+
87
+ def validate(transaction)
88
+ raise Error.new('Session ID is required.') if transaction[:session_id].nil?
89
+ unless transaction[:social_network].nil?
90
+ raise Error.new('Social Network Type is required') if transaction[:social_network][:type].nil? && !transaction[:social_network][:id].nil?
91
+ raise Error.new('Social Network ID is required') if transaction[:social_network][:id].nil? && !transaction[:social_network][:type].nil?
92
+ end
93
+ raise Error.new('Invalid Currency Code') if CURRENCY_CODES.index(transaction[:transaction_data][:currency_code]).nil?
94
+ raise Error.new('Total Transaction Value is required') if transaction[:transaction_data][:total_transaction_value].nil?
95
+ transaction[:transaction_data][:address].each_with_index do | address, i |
96
+ transaction[:transaction_data][:address][i] = validate_address address
97
+ end
98
+ raise Error.new('Customer is required') if transaction[:customer].nil?
99
+ transaction[:customer][:address].each_with_index do | address, i |
100
+ transaction[:customer][:address][i] = validate_address address
101
+ end
102
+ raise Error.new('Customer email is required') if transaction[:customer][:email].nil? || transaction[:customer][:email].size == 0
103
+ end
104
+
105
+ def validate_address(address)
106
+ address[:country_code] = 'NS' if address[:country_code].nil?
107
+ raise Error.new('Invalid Country Code') if COUNTRY_CODES.index(address[:country_code]).nil?
108
+ raise Error.new('Invalid Address Type') if ADDRESS_TYPES.index(address[:type]).nil?
109
+ address
110
+ end
111
+
112
+ def build(transaction)
113
+ built_transaction = {
114
+ TransactionNumber: @transaction_number,
115
+ TransactionData: {
116
+ Currency: transaction[:transaction_data][:currency_code],
117
+ TotalDelivery: transaction[:transaction_data][:total_delivery] || 0,
118
+ TotalBeforeTax: transaction[:transaction_data][:total_before_tax] || 0,
119
+ TotalDiscount: transaction[:transaction_data][:total_discount] || 0,
120
+ TotalTax: transaction[:transaction_data][:total_tax] || 0,
121
+ TotalTransactionValue: transaction[:transaction_data][:total_transaction_value],
122
+ Timestamp: "\/Date(#{transaction[:transaction_data][:timestamp]})\/"
123
+ },
124
+ Customer: {
125
+ FirstName: transaction[:customer][:first_name] || ' ',
126
+ LastName: transaction[:customer][:last_name] || ' ',
127
+ PhoneNumber: transaction[:customer][:phone_number] || '0000',
128
+ Email: []
129
+ },
130
+ SessionId: transaction[:session_id]
131
+ }
132
+
133
+ built_transaction[:Customer][:DateOfBirth] =
134
+ "\/Date(#{transaction[:customer][:dob]})\/" unless transaction[:customer][:dob].nil?
135
+
136
+ unless transaction[:social_network].nil?
137
+ built_transaction[:SocialNetwork] = {
138
+ Type: transaction[:social_network][:type],
139
+ Id: transaction[:social_network][:id]
140
+ }
141
+ end
142
+
143
+ unless transaction[:transaction_data][:address].nil? || transaction[:transaction_data][:address].size == 0
144
+ built_transaction[:TransactionData][:Address] = []
145
+ transaction[:transaction_data][:address].each do | address |
146
+ built_transaction[:TransactionData][:Address].push(address_to_object address)
147
+ end
148
+ end
149
+
150
+ unless transaction[:transaction_data][:item].nil? || transaction[:transaction_data][:item].size == 0
151
+ built_transaction[:TransactionData][:Item] = []
152
+ transaction[:transaction_data][:item].each do | item |
153
+ built_transaction[:TransactionData][:Item].push({
154
+ Name: item[:name] || ' ',
155
+ URL: item[:url] || ' ',
156
+ ImageURL: item[:image_url] || ' ',
157
+ Quantity: item[:quantity] || 0,
158
+ TotalBeforeTax: item[:total_before_tax] || 0,
159
+ TotalDiscount: item[:total_discount] || 0,
160
+ TotalTax: item[:total_tax] || 0,
161
+ TotalItemValue: item[:total_item_value] || 0
162
+ })
163
+ end
164
+ end
165
+
166
+ transaction[:customer][:email].each do | email |
167
+ built_transaction[:Customer][:Email].push({
168
+ IsDefault: email[:is_default] || false,
169
+ EmailAddress: email[:address] || ' '
170
+ })
171
+ end
172
+
173
+ unless transaction[:customer][:address].nil? || transaction[:customer][:address].size == 0
174
+ built_transaction[:Customer][:Address] = []
175
+ transaction[:customer][:address].each do | address |
176
+ address_object = address_to_object address
177
+ address_object[:IsDefault] = address[:is_default] || false
178
+ built_transaction[:Customer][:Address].push(address_object)
179
+ end
180
+ end
181
+
182
+ built_transaction
183
+ end
184
+
185
+ def address_to_object(address)
186
+ {
187
+ Type: address[:type],
188
+ FirstName: address[:first_name] || ' ',
189
+ LastName: address[:last_name] || ' ',
190
+ Address1: address[:address_1] || ' ',
191
+ Address2: address[:address_2] || ' ',
192
+ Address3: address[:address_3] || ' ',
193
+ City: address[:city] || ' ',
194
+ State: address[:state] || ' ',
195
+ PostalCode: address[:postal_code] || ' ',
196
+ CountryIsoA2Code: address[:country_code]
197
+ }
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,3 @@
1
+ module Trustev
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe Trustev::Authenticate do
4
+
5
+ describe 'when an authentication token is requested' do
6
+ it 'must set the authentication token' do
7
+ Trustev::Authenticate.retrieve_token
8
+ Trustev.token.wont_be_nil
9
+ Trustev.token_expire.wont_be_nil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe Trustev::DigitalSignature do
4
+
5
+ before do
6
+ @expected_signature = '690de8cb3703b536852e4683843940c1555fc48685fdb705061a62d33f581f43'
7
+ end
8
+
9
+ describe 'when a digital signature is verified' do
10
+ it 'must say it is valid' do
11
+ signature = Trustev::DigitalSignature.new(
12
+ @expected_signature,
13
+ '20141106213006',
14
+ '4cec59b2-37f9-461e-9abc-861267e1a4d7',
15
+ ''
16
+ )
17
+ signature.invalid?.must_equal false
18
+ end
19
+ end
20
+
21
+ describe 'when an invalid digital signature is verified' do
22
+ it 'must say it is NOT valid' do
23
+ signature = Trustev::DigitalSignature.new(
24
+ @expected_signature,
25
+ '20151106213006',
26
+ '4cec59b2-37f9-461e-9abc-861267e1a4d7',
27
+ ''
28
+ )
29
+ signature.invalid?.must_equal true
30
+ end
31
+ end
32
+ end