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.
- 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:
|