miiCardConsumers 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/certs/sts.miicard.com.pem +98 -0
- data/lib/miiCardConsumers.rb +410 -23
- metadata +5 -3
@@ -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-----
|
data/lib/miiCardConsumers.rb
CHANGED
@@ -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
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
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
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
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.
|
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-
|
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:
|