trustev 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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