miiCardConsumers 2.3.0 → 2.4.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,98 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGCzCCBPOgAwIBAgIQOUeVqa/DtbhT+rwGo2fFdDANBgkqhkiG9w0BAQUFADCB
3
+ vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
4
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
5
+ YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
6
+ VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
7
+ HhcNMTIwNzEzMDAwMDAwWhcNMTQwNzEzMjM1OTU5WjCCATUxEzARBgsrBgEEAYI3
8
+ PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMREwDwYDVQQF
9
+ EwhTQzQwMDQ1OTELMAkGA1UEBhMCR0IxEzARBgNVBAgUCk1pZGxvdGhpYW4xEjAQ
10
+ BgNVBAcUCUVkaW5idXJnaDEYMBYGA1UEChQPbWlpQ2FyZCBMaW1pdGVkMTUwMwYD
11
+ VQQLFCxUZXJtcyBvZiB1c2UgYXQgd3d3LnZlcmlzaWduLmNvLnVrL3JwYSAoYykw
12
+ NTEiMCAGA1UECxMZQXV0aGVudGljYXRlZCBieSBWZXJpU2lnbjEnMCUGA1UECxMe
13
+ TWVtYmVyLCBWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMRgwFgYDVQQDFA9zdHMubWlp
14
+ Y2FyZC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDApAjYwzON
15
+ QgH2RO/G7fCs5uENV7mID0hlKw8O5rLfhGdIRrEAb8Lupa9uQAPo0bA4zXyH/JE1
16
+ JxDIdo1YL31Os6qP3wfoAnXKWB8Scz9Jk4mggmhJn+WLD0fHhmzKvY1Ac0bOrMqR
17
+ wq5FNcQfxNAUFKTwGuYoVBYobVJuBBwXMXCDrCEjsqsmnQ9SdTga8OONFQKdN678
18
+ NgyZEGLQrNUmwZQz93E6Hi4/1+1OebjtFmungFJkSQTG6un9SqtYAWGCZS+Dcgn7
19
+ p5K/h/bmAY3IisuSS/BnZPmBRPKc+mf0EzztY6aGv0O22J9sG+ipvwHHkADN89Qi
20
+ 69/gS1FXjB1ZAgMBAAGjggGJMIIBhTAaBgNVHREEEzARgg9zdHMubWlpY2FyZC5j
21
+ b20wCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwRAYDVR0gBD0wOzA5BgtghkgB
22
+ hvhFAQcXBjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20v
23
+ Y3BzMD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly9FVkludGwtY3JsLnZlcmlzaWdu
24
+ LmNvbS9FVkludGwyMDA2LmNybDA0BgNVHSUELTArBggrBgEFBQcDAQYIKwYBBQUH
25
+ AwIGCWCGSAGG+EIEAQYKKwYBBAGCNwoDAzAfBgNVHSMEGDAWgBROQ8gddu83U3pP
26
+ 8lhvlPM44tW93zBvBggrBgEFBQcBAQRjMGEwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v
27
+ Y3NwLnZlcmlzaWduLmNvbTA5BggrBgEFBQcwAoYtaHR0cDovL0VWSW50bC1haWEu
28
+ dmVyaXNpZ24uY29tL0VWSW50bDIwMDYuY2VyMA0GCSqGSIb3DQEBBQUAA4IBAQBH
29
+ D6dBvAlKkvXnKQh4bhwj+4s0sE8vMWj+0k3gezFAU1P6KUvu2rB0CwwrsR1DOnQD
30
+ B5FJP0ZJmNnN/jCjZcZlJiQNNm29VNuhUKmCy5V5DpOY1gNg9HVMzheVIQl3NG0B
31
+ BEqFG41F7NtR3+fZnUFywpGrrANWzh7G2dBnEF2vKgSw2zoFs8tC0hc5MOzW3ff6
32
+ FcDOX3zKZWP9NTJDfRv0Hk12IEs0+qToiyByHPCjub5RThaycgfIwu/K9KlGLcco
33
+ ph3sdlqg+WzieiP3C5ufdWtyfKSOkdHlOQWRiBU/Vz6dAZ+GhhghWiJU0o9dQ5lB
34
+ UhJXUKCEU/JHTepCLSgq
35
+ -----END CERTIFICATE-----
36
+ -----BEGIN CERTIFICATE-----
37
+ MIIGCjCCBPKgAwIBAgIQESoAbTflEG/WynzD77rMGDANBgkqhkiG9w0BAQUFADCB
38
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
39
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
40
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
41
+ ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
42
+ aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMTYxMTA3MjM1OTU5WjCBvjEL
43
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
44
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
45
+ aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMvVmVy
46
+ aVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0EwggEi
47
+ MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Voi6iDRkZM/NyrDu5xlzxXLZ
48
+ u0W8taj/g74cA9vtibcuEBolvFXKQaGfC88ZXnC5XjlLnjEcX4euKqqoK6IbOxAj
49
+ XxOx3QiMThTag4HjtYzjaO0kZ85Wtqybc5ZE24qMs9bwcZOO23FUSutzWWqPcFEs
50
+ A5+X0cwRerxiDZUqyRx1V+n1x+q6hDXLx4VafuRN4RGXfQ4gNEXb8aIJ6+s9nriW
51
+ Q140SwglHkMaotm3igE0PcP45a9PjP/NZfAjTsWXs1zakByChQ0GDcEitnsopAPD
52
+ TFPRWLxyvAg5/KB2qKjpS26IPeOzMSWMcylIDjJ5Bu09Q/T25On8fb6OCNUfAgMB
53
+ AAGjggH0MIIB8DAdBgNVHQ4EFgQUTkPIHXbvN1N6T/JYb5TzOOLVvd8wEgYDVR0T
54
+ AQH/BAgwBgEB/wIBADA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc
55
+ aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczA9BgNVHR8ENjA0MDKgMKAuhixo
56
+ dHRwOi8vRVZTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9wY2EzLWc1LmNybDAgBgNV
57
+ HSUEGTAXBglghkgBhvhCBAEGCmCGSAGG+EUBCAEwDgYDVR0PAQH/BAQDAgEGMBEG
58
+ CWCGSAGG+EIBAQQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglpbWFn
59
+ ZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNodHRw
60
+ Oi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjApBgNVHREEIjAgpB4wHDEa
61
+ MBgGA1UEAxMRQ2xhc3MzQ0EyMDQ4LTEtNDgwPQYIKwYBBQUHAQEEMTAvMC0GCCsG
62
+ AQUFBzABhiFodHRwOi8vRVZTZWN1cmUtb2NzcC52ZXJpc2lnbi5jb20wHwYDVR0j
63
+ BBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJKoZIhvcNAQEFBQADggEBAFqi
64
+ sb/rjdQ4qIBywtw4Lqyncfkro7tHu21pbxA2mIzHVi67vKtKm3rW8oKT4BT+is6D
65
+ t4Pbk4errGV5Sf1XqbHOCR+6EBXECQ5i4/kKJdVkmPDyqA92Mn6R5hjuvOfa0E6N
66
+ eLvincBZK8DOlQ0kDHLKNF5wIokrSrDxaIfz7kSNKEB3OW5IckUxXWs5DoYC6maZ
67
+ kzEP32fepp+MnUzOcW86Ifa5ND/5btia9z7a84Ffelxtj3z2mXS3/+QXXe1hXqtI
68
+ u5aNZkU5tBIK9nDpnHYiS2DpKhs0Sfei1GfAsSatE7rZhAHBq+GObXAWO3eskZq7
69
+ Gh/aWKfkT8Fhrryi/ks=
70
+ -----END CERTIFICATE-----
71
+ -----BEGIN CERTIFICATE-----
72
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
73
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
74
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
75
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
76
+ ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
77
+ aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
78
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
79
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
80
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
81
+ U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
82
+ aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
83
+ nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
84
+ t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
85
+ SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
86
+ BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
87
+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
88
+ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
89
+ BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
90
+ BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
91
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
92
+ MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
93
+ p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
94
+ 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
95
+ WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
96
+ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
97
+ hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
98
+ -----END CERTIFICATE-----
@@ -1,14 +1,39 @@
1
1
  require "oauth"
2
2
  require "json"
3
+ require "digest/sha1"
4
+ require "net/http"
5
+ require "openssl/x509"
3
6
 
4
7
  class MiiCardServiceUrls
5
8
  OAUTH_ENDPOINT = "https://sts.miicard.com/auth/OAuth.ashx"
6
9
  STS_SITE = "https://sts.miicard.com"
7
10
  CLAIMS_SVC = "https://sts.miicard.com/api/v1/Claims.svc/json"
11
+ FINANCIAL_SVC = "https://sts.miicard.com/api/v1/Financial.svc/json"
12
+ DIRECTORY_SVC = "https://sts.miicard.com/api/v1/Members"
8
13
 
14
+ # Deprecated - prefer the API-specific methods get_claims_method_url
15
+ # and get_financial_method_url
9
16
  def self.get_method_url(method_name)
10
17
  return MiiCardServiceUrls::CLAIMS_SVC + "/" + method_name
11
18
  end
19
+
20
+ def self.get_claims_method_url(method_name)
21
+ return MiiCardServiceUrls::CLAIMS_SVC + "/" + method_name
22
+ end
23
+
24
+ def self.get_financial_method_url(method_name)
25
+ return MiiCardServiceUrls::FINANCIAL_SVC + "/" + method_name
26
+ end
27
+
28
+ def self.get_directory_service_query_url(criterion, value, hashed = false)
29
+ to_return = DIRECTORY_SVC + "?" + criterion + "=" + value
30
+
31
+ if (hashed)
32
+ to_return = to_return + "&hashed=true"
33
+ end
34
+
35
+ return to_return
36
+ end
12
37
  end
13
38
 
14
39
  # Describes the overall status of an API call.
@@ -25,6 +50,10 @@ end
25
50
  module MiiApiErrorCode
26
51
  # The API call succeeded.
27
52
  SUCCESS = 0
53
+ # An unrecognised search criterion was supplied to the Directory API
54
+ UNKNOWN_SEARCH_CRITERION = 10
55
+ # No miiCard members matched the Directory API search criteria
56
+ NO_MATCHES = 11
28
57
  # The user has revoked access to your application. The user would
29
58
  # have to repeat the OAuth authorisation process before access would be
30
59
  # restored to your application.
@@ -34,6 +63,8 @@ module MiiApiErrorCode
34
63
  USER_SUBSCRIPTION_LAPSED = 200
35
64
  # Signifies that your account has not been enabled for transactional support.
36
65
  TRANSACTIONAL_SUPPORT_DISABLED = 1000
66
+ # Signifies that your account has not been enabled for Financial API support.
67
+ FINANCIAL_DATA_SUPPPORT_DISABLED = 1001
37
68
  # Signifies that your account's support status is development-only. This is the
38
69
  # case when your application hasn't yet been made live in the miiCard system, for example
39
70
  # while we process your billing details and perform final checks.
@@ -66,6 +97,34 @@ module WebPropertyType
66
97
  WEBSITE = 1
67
98
  end
68
99
 
100
+ module QualificationType
101
+ # Indicates that the Qualification relates to an academic award
102
+ ACADEMIC = 0
103
+ # Indicates that the Qualification relates to a professional certification
104
+ PROFESSIONAL = 1
105
+ end
106
+
107
+ module AuthenticationTokenType
108
+ # Specifies that no second factor was employed
109
+ NONE = 0
110
+ # Specifies that a soft token was employed, such as an SMS sent to
111
+ # a registered mobile device or software OATH provider
112
+ SOFT = 1
113
+ # Specifies that a hard token was employed, such as a YubiKey
114
+ HARD = 2
115
+ end
116
+
117
+ module RefreshState
118
+ # Indicates that a request to refresh financial data is in an incomplete, unknown
119
+ # state - probably indicating an error
120
+ UNKNOWN = 0
121
+ # Indicates that the requested financial data refresh has completed and the most
122
+ # recent available financial data can now be requested
123
+ DATA_AVAILABLE = 1
124
+ # Indicates that a requested financial data refresh is still in progress
125
+ IN_PROGRESS = 2
126
+ end
127
+
69
128
  # Base class for most verifiable identity data.
70
129
  class Claim
71
130
  attr_accessor :verified
@@ -194,12 +253,211 @@ class WebProperty < Claim
194
253
  end
195
254
  end
196
255
 
256
+ class Qualification
257
+ attr_accessor :type, :title, :data_provider, :data_provider_url
258
+
259
+ def initialize(type, title, data_provider, data_provider_url)
260
+ @type = type
261
+ @title = title
262
+ @data_provider = data_provider
263
+ @data_provider_url = data_provider_url
264
+ end
265
+
266
+ def self.from_hash(hash)
267
+ return Qualification.new(
268
+ hash["Type"],
269
+ hash["Title"],
270
+ hash["DataProvider"],
271
+ hash["DataProviderUrl"]
272
+ )
273
+ end
274
+ end
275
+
276
+ class GeographicLocation
277
+ attr_accessor :location_provider, :latitude, :longitude, :lat_long_accuracy_metres
278
+ attr_accessor :approximate_address
279
+
280
+ def initialize(location_provider, latitude, longitude, lat_long_accuracy_metres, approximate_address)
281
+ @location_provider = location_provider
282
+ @latitude = latitude
283
+ @longitude = longitude
284
+ @lat_long_accuracy_metres = lat_long_accuracy_metres
285
+ @approximate_address = approximate_address
286
+ end
287
+
288
+ def self.from_hash(hash)
289
+ postal_address = hash["ApproximateAddress"]
290
+ postal_address_parsed = nil
291
+ unless (postal_address.nil?)
292
+ postal_address_parsed = PostalAddress::from_hash(postal_address)
293
+ end
294
+
295
+ return GeographicLocation.new(
296
+ hash["LocationProvider"],
297
+ hash["Latitude"],
298
+ hash["Longitude"],
299
+ hash["LatLongAccuracyMetres"],
300
+ postal_address_parsed
301
+ )
302
+ end
303
+ end
304
+
305
+ class AuthenticationDetails
306
+ attr_accessor :authentication_time_utc, :second_factor_token_type, :second_factor_provider, :locations
307
+
308
+ def initialize(authentication_time_utc, second_factor_token_type, second_factor_provider, locations)
309
+ @authentication_time_utc = authentication_time_utc
310
+ @second_factor_token_type = second_factor_token_type
311
+ @second_factor_provider = second_factor_provider
312
+ @locations = locations
313
+ end
314
+
315
+ def self.from_hash(hash)
316
+ locations = hash["Locations"]
317
+ locations_parsed = nil
318
+ unless (locations.nil? || locations.empty?)
319
+ locations_parsed = locations.map{|item| GeographicLocation::from_hash(item)}
320
+ end
321
+
322
+ return AuthenticationDetails.new(
323
+ (Util::parse_dot_net_json_datetime(hash['AuthenticationTimeUtc']) rescue nil),
324
+ hash['SecondFactorTokenType'],
325
+ hash['SecondFactorProvider'],
326
+ locations_parsed
327
+ )
328
+ end
329
+ end
330
+
331
+ class FinancialRefreshStatus
332
+ attr_accessor :state
333
+
334
+ def initialize(state)
335
+ @state = state
336
+ end
337
+
338
+ def self.from_hash(hash)
339
+ @state = hash['State']
340
+ end
341
+ end
342
+
343
+ class FinancialTransaction
344
+ attr_accessor :date, :amount_credited, :amount_debited, :description, :id
345
+
346
+ def initialize(date, amount_credited, amount_debited, description, id)
347
+ @date = date
348
+ @amount_credited = amount_credited
349
+ @amount_debited = amount_debited
350
+ @description = description
351
+ @id = id
352
+ end
353
+
354
+ def self.from_hash(hash)
355
+ return FinancialTransaction.new(
356
+ (Util::parse_dot_net_json_datetime(hash['Date']) rescue nil),
357
+ hash['AmountCredited'],
358
+ hash['AmountDebited'],
359
+ hash['Description'],
360
+ hash['ID']
361
+ )
362
+ end
363
+ end
364
+
365
+ class FinancialAccount
366
+ attr_accessor :account_name, :holder, :sort_code, :account_number, :type, :from_date, :last_updated_utc
367
+ attr_accessor :closing_balance, :debits_sum, :debits_count, :credits_sum, :credits_count, :currency_iso
368
+ attr_accessor :transactions
369
+
370
+ def initialize(account_name, holder, sort_code, account_number, type, from_date, last_updated_utc, closing_balance, debits_sum, debits_count, credits_sum, credits_count, currency_iso, transactions)
371
+ @account_name = account_name
372
+ @holder = holder
373
+ @sort_code = sort_code
374
+ @account_number = account_number
375
+ @type = type
376
+ @from_date = from_date
377
+ @last_updated_utc = last_updated_utc
378
+ @closing_balance = closing_balance
379
+ @debits_sum = debits_sum
380
+ @debits_count = debits_count
381
+ @credits_sum = credits_sum
382
+ @credits_count = credits_count
383
+ @currency_iso = currency_iso
384
+ @transactions = transactions
385
+ end
386
+
387
+ def self.from_hash(hash)
388
+ transactions = hash["Transactions"]
389
+ transactions_parsed = nil
390
+ unless (transactions.nil? || transactions.empty?)
391
+ transactions_parsed = transactions.map{|item| FinancialTransaction::from_hash(item)}
392
+ end
393
+
394
+ return FinancialAccount.new(
395
+ hash['AccountName'],
396
+ hash['Holder'],
397
+ hash['SortCode'],
398
+ hash['AccountNumber'],
399
+ hash['Type'],
400
+ (Util::parse_dot_net_json_datetime(hash['FromDate']) rescue nil),
401
+ (Util::parse_dot_net_json_datetime(hash['LastUpdatedUtc']) rescue nil),
402
+ hash['ClosingBalance'],
403
+ hash['DebitsSum'],
404
+ hash['DebitsCount'],
405
+ hash['CreditsSum'],
406
+ hash['CreditsCount'],
407
+ hash['CurrencyIso'],
408
+ transactions_parsed
409
+ )
410
+ end
411
+ end
412
+
413
+ class FinancialProvider
414
+ attr_accessor :provider_name, :financial_accounts
415
+
416
+ def initialize(provider_name, financial_accounts)
417
+ @provider_name = provider_name
418
+ @financial_accounts = financial_accounts
419
+ end
420
+
421
+ def self.from_hash(hash)
422
+ accounts = hash["FinancialAccounts"]
423
+ accounts_parsed = nil
424
+ unless (accounts.nil? || accounts.empty?)
425
+ accounts_parsed = accounts.map{|item| FinancialAccount::from_hash(item)}
426
+ end
427
+
428
+ return FinancialProvider.new(
429
+ hash['ProviderName'],
430
+ accounts_parsed
431
+ )
432
+ end
433
+ end
434
+
435
+ class MiiFinancialData
436
+ attr_accessor :financial_providers
437
+
438
+ def initialize(financial_providers)
439
+ @financial_providers = financial_providers
440
+ end
441
+
442
+ def self.from_hash(hash)
443
+ financial_providers = hash["FinancialProviders"]
444
+ financial_providers_parsed = nil
445
+ unless (financial_providers.nil? || financial_providers.empty?)
446
+ financial_providers_parsed = financial_providers.map{|item| FinancialProvider::from_hash(item)}
447
+ end
448
+
449
+ return MiiFinancialData.new(
450
+ financial_providers_parsed
451
+ )
452
+ end
453
+ end
454
+
197
455
  class MiiUserProfile
198
456
  attr_accessor :username, :salutation, :first_name, :middle_name, :last_name
199
457
  attr_accessor :previous_first_name, :previous_middle_name, :previous_last_name
200
458
  attr_accessor :last_verified, :profile_url, :profile_short_url, :card_image_url, :email_addresses, :identities, :postal_addresses
201
459
  attr_accessor :phone_numbers, :web_properties, :identity_assured, :has_public_profile
202
- attr_accessor :public_profile, :date_of_birth
460
+ attr_accessor :public_profile, :date_of_birth, :qualifications, :age
203
461
 
204
462
  def initialize(
205
463
  username,
@@ -222,7 +480,9 @@ class MiiUserProfile
222
480
  identity_assured,
223
481
  has_public_profile,
224
482
  public_profile,
225
- date_of_birth
483
+ date_of_birth,
484
+ qualifications,
485
+ age
226
486
  )
227
487
 
228
488
  @username= username
@@ -246,6 +506,8 @@ class MiiUserProfile
246
506
  @has_public_profile = has_public_profile
247
507
  @public_profile = public_profile
248
508
  @date_of_birth = date_of_birth
509
+ @qualifications = qualifications
510
+ @age = age
249
511
  end
250
512
 
251
513
  def self.from_hash(hash)
@@ -278,6 +540,12 @@ class MiiUserProfile
278
540
  unless (web_properties.nil? || web_properties.empty?)
279
541
  web_properties_parsed = web_properties.map{|item| WebProperty::from_hash(item)}
280
542
  end
543
+
544
+ qualifications = hash["Qualifications"]
545
+ qualifications_parsed = nil
546
+ unless (qualifications.nil? || qualifications.empty?)
547
+ qualifications_parsed = qualifications.map{|item| Qualification::from_hash(item)}
548
+ end
281
549
 
282
550
  public_profile = hash["PublicProfile"]
283
551
  public_profile_parsed = nil
@@ -306,7 +574,9 @@ class MiiUserProfile
306
574
  hash['IdentityAssured'],
307
575
  hash['HasPublicProfile'],
308
576
  public_profile_parsed,
309
- (Util::parse_dot_net_json_datetime(hash['DateOfBirth']) rescue nil)
577
+ (Util::parse_dot_net_json_datetime(hash['DateOfBirth']) rescue nil),
578
+ qualifications_parsed,
579
+ hash['Age']
310
580
  )
311
581
  end
312
582
  end
@@ -396,71 +666,188 @@ class MiiCardOAuthServiceBase
396
666
  @access_token = access_token
397
667
  @access_token_secret = access_token_secret
398
668
  end
669
+
670
+ protected
671
+ def make_request(url, post_data, payload_processor, wrapped_response, array_type_payload = false)
672
+ consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret, {:site => MiiCardServiceUrls::STS_SITE, :request_token_path => MiiCardServiceUrls::OAUTH_ENDPOINT, :access_token_path => MiiCardServiceUrls::OAUTH_ENDPOINT, :authorize_path => MiiCardServiceUrls::OAUTH_ENDPOINT })
673
+ access_token = OAuth::AccessToken.new(consumer, @access_token, @access_token_secret)
674
+
675
+ response = access_token.post(url, post_data.to_json(), { 'Content-Type' => 'application/json' })
676
+
677
+ if wrapped_response
678
+ return MiiApiResponse::from_hash(JSON.parse(response.body), payload_processor, array_type_payload)
679
+ elsif !payload_processor.nil?
680
+ return payload_processor.call(response.body)
681
+ else
682
+ return response.body
683
+ end
684
+ end
399
685
  end
400
686
 
401
687
  class MiiCardOAuthClaimsService < MiiCardOAuthServiceBase
402
688
  def initialize(consumer_key, consumer_secret, access_token, access_token_secret)
403
689
  super(consumer_key, consumer_secret, access_token, access_token_secret)
404
690
  end
691
+
692
+ def get_method_url(method)
693
+ return MiiCardServiceUrls.get_claims_method_url(method)
694
+ end
405
695
 
406
696
  def get_claims
407
- return make_request(MiiCardServiceUrls.get_method_url('GetClaims'), nil, MiiUserProfile.method(:from_hash), true)
697
+ return make_request(get_method_url('GetClaims'), nil, MiiUserProfile.method(:from_hash), true)
408
698
  end
409
699
 
410
700
  def is_social_account_assured(social_account_id, social_account_type)
411
701
  params = Hash["socialAccountId", social_account_id, "socialAccountType", social_account_type]
412
702
 
413
- return make_request(MiiCardServiceUrls.get_method_url('IsSocialAccountAssured'), params, nil, true)
703
+ return make_request(get_method_url('IsSocialAccountAssured'), params, nil, true)
414
704
  end
415
705
 
416
706
  def is_user_assured
417
- return make_request(MiiCardServiceUrls.get_method_url('IsUserAssured'), nil, nil, true)
707
+ return make_request(get_method_url('IsUserAssured'), nil, nil, true)
418
708
  end
419
709
 
420
710
  def assurance_image(type)
421
711
  params = Hash["type", type]
422
712
 
423
- return make_request(MiiCardServiceUrls.get_method_url('AssuranceImage'), params, nil, false)
713
+ return make_request(get_method_url('AssuranceImage'), params, nil, false)
424
714
  end
425
715
 
426
716
  def get_card_image(snapshot_id, show_email_address, show_phone_number, format)
427
717
  params = Hash["SnapshotId", snapshot_id, "ShowEmailAddress", show_email_address, "ShowPhoneNumber", show_phone_number, "Format", format]
428
718
 
429
- return make_request(MiiCardServiceUrls.get_method_url('GetCardImage'), params, nil, false)
719
+ return make_request(get_method_url('GetCardImage'), params, nil, false)
430
720
  end
431
721
 
432
722
  def get_identity_snapshot_details(snapshot_id = nil)
433
723
  params = Hash["snapshotId", snapshot_id]
434
724
 
435
- return make_request(MiiCardServiceUrls.get_method_url('GetIdentitySnapshotDetails'), params, IdentitySnapshotDetails.method(:from_hash), true, true)
725
+ return make_request(get_method_url('GetIdentitySnapshotDetails'), params, IdentitySnapshotDetails.method(:from_hash), true, true)
436
726
  end
437
727
 
438
728
  def get_identity_snapshot(snapshot_id)
439
729
  params = Hash["snapshotId", snapshot_id]
440
730
 
441
- return make_request(MiiCardServiceUrls.get_method_url('GetIdentitySnapshot'), params, IdentitySnapshot.method(:from_hash), true)
731
+ return make_request(get_method_url('GetIdentitySnapshot'), params, IdentitySnapshot.method(:from_hash), true)
442
732
  end
443
733
 
444
734
  def get_identity_snapshot_pdf(snapshot_id)
445
735
  params = Hash["snapshotId", snapshot_id]
446
736
 
447
- return make_request(MiiCardServiceUrls.get_method_url('GetIdentitySnapshotPdf'), params, nil, false)
737
+ return make_request(get_method_url('GetIdentitySnapshotPdf'), params, nil, false)
448
738
  end
739
+
740
+ def get_authentication_details(snapshot_id = nil)
741
+ params = Hash["snapshotId", snapshot_id]
742
+
743
+ return make_request(get_method_url('GetAuthenticationDetails'), params, AuthenticationDetails.method(:from_hash), true)
744
+ end
745
+ end
746
+
747
+ class MiiCardOAuthFinancialService < MiiCardOAuthServiceBase
748
+ def initialize(consumer_key, consumer_secret, access_token, access_token_secret)
749
+ super(consumer_key, consumer_secret, access_token, access_token_secret)
750
+ end
449
751
 
450
- private
451
- def make_request(url, post_data, payload_processor, wrapped_response, array_type_payload = false)
452
- consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret, {:site => MiiCardServiceUrls::STS_SITE, :request_token_path => MiiCardServiceUrls::OAUTH_ENDPOINT, :access_token_path => MiiCardServiceUrls::OAUTH_ENDPOINT, :authorize_path => MiiCardServiceUrls::OAUTH_ENDPOINT })
453
- access_token = OAuth::AccessToken.new(consumer, @access_token, @access_token_secret)
454
-
455
- response = access_token.post(url, post_data.to_json(), { 'Content-Type' => 'application/json' })
752
+ def get_method_url(method)
753
+ return MiiCardServiceUrls.get_financial_method_url(method)
754
+ end
755
+
756
+ def is_refresh_in_progress
757
+ return make_request(get_method_url('IsRefreshInProgress'), nil, nil, true)
758
+ end
759
+
760
+ def refresh_financial_data
761
+ return make_request(get_method_url('RefreshFinancialData'), nil, FinancialRefreshStatus.method(:from_hash), true)
762
+ end
763
+
764
+ def get_financial_transactions
765
+ return make_request(get_method_url('GetFinancialTransactions'), nil, MiiFinancialData.method(:from_hash), true)
766
+ end
767
+ end
768
+
769
+ class MiiCardDirectoryService
770
+ CRITERION_USERNAME = "username"
771
+ CRITERION_EMAIL = "email"
772
+ CRITERION_PHONE = "phone"
773
+ CRITERION_TWITTER = "twitter"
774
+ CRITERION_FACEBOOK = "facebook"
775
+ CRITERION_LINKEDIN = "linkedin"
776
+ CRITERION_GOOGLE = "google"
777
+ CRITERION_MICROSOFT_ID = "liveid"
778
+ CRITERION_EBAY = "ebay"
779
+ CRITERION_VERITAS_VITAE = "veritasvitae"
780
+
781
+ def find_by_email(email, hashed = false)
782
+ return find_by(CRITERION_EMAIL, email, hashed)
783
+ end
784
+
785
+ def find_by_phone_number(phone, hashed = false)
786
+ return find_by(CRITERION_PHONE, phone, hashed)
787
+ end
788
+
789
+ def find_by_username(username, hashed = false)
790
+ return find_by(CRITERION_USERNAME, username, hashed)
791
+ end
792
+
793
+ def find_by_twitter(twitter_handle_or_profile_url, hashed = false)
794
+ return find_by(CRITERION_TWITTER, twitter_handle_or_profile_url, hashed)
795
+ end
796
+
797
+ def find_by_facebook(facebook_url, hashed = false)
798
+ return find_by(CRITERION_FACEBOOK, facebook_url, hashed)
799
+ end
800
+
801
+ def find_by_linkedin(linkedin_www_url, hashed = false)
802
+ return find_by(CRITERION_LINKEDIN, linkedin_www_url, hashed)
803
+ end
804
+
805
+ def find_by_google(google_handle_or_profile_url, hashed = false)
806
+ return find_by(CRITERION_GOOGLE, google_handle_or_profile_url, hashed)
807
+ end
808
+
809
+ def find_by_microsoft_id(microsoft_id_url, hashed = false)
810
+ return find_by(CRITERION_MICROSOFT_ID, microsoft_id_url, hashed)
811
+ end
812
+
813
+ def find_by_ebay(ebay_handle_or_profile_url, hashed = false)
814
+ return find_by(CRITERION_EBAY, ebay_handle_or_profile_url, hashed)
815
+ end
816
+
817
+ def find_by_veritas_vitae(veritas_vitae_vv_number_or_profile_url, hashed = false)
818
+ return find_by(CRITERION_VERITAS_VITAE, veritas_vitae_vv_number_or_profile_url, hashed)
819
+ end
820
+
821
+ def find_by(criterion, value, hashed = false)
822
+ url = MiiCardServiceUrls::get_directory_service_query_url(criterion, value, hashed)
823
+ uri = URI.parse(url)
824
+
825
+ cert_store = OpenSSL::X509::Store.new
826
+ cert_store.set_default_paths
827
+
828
+ http = Net::HTTP.new(uri.host, uri.port)
829
+ http.use_ssl = true
830
+ http.cert_store = cert_store
831
+ http.ca_file = File.join(File.dirname(__FILE__), "certs/sts.miicard.com.pem")
832
+
833
+ request = Net::HTTP::Get.new(url)
834
+ request['Content-type'] = 'application/json'
456
835
 
457
- if wrapped_response
458
- return MiiApiResponse::from_hash(JSON.parse(response.body), payload_processor, array_type_payload)
459
- elsif !payload_processor.nil?
460
- return payload_processor.call(response.body)
461
- else
462
- return response.body
836
+ response = (http.request(request) rescue nil)
837
+
838
+ if !response.nil? && !response.body.to_s.empty?
839
+ # Try parsing the response as a MiiApiResponse of MiiUserProfile
840
+ parsed_response = (MiiApiResponse::from_hash(JSON.parse(response.body), MiiUserProfile.method(:from_hash)) rescue nil)
841
+ if !parsed_response.nil? && !parsed_response.data.nil?
842
+ to_return = parsed_response.data
843
+ end
463
844
  end
845
+
846
+ return to_return
847
+ end
848
+
849
+ def self.hash_identifier(identifier)
850
+ return Digest::SHA1.hexdigest(identifier.downcase)
464
851
  end
465
852
  end
466
853
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miiCardConsumers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-25 00:00:00.000000000 Z
12
+ date: 2013-10-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth
@@ -52,9 +52,11 @@ extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
54
  - lib/miiCardConsumers.rb
55
+ - lib/certs/sts.miicard.com.pem
55
56
  - test/test_miiCardConsumers.rb
56
57
  homepage: http://www.miicard.com/developers
57
- licenses: []
58
+ licenses:
59
+ - BSD
58
60
  post_install_message:
59
61
  rdoc_options: []
60
62
  require_paths: