mastercard_api_core 0.0.1

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,141 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ require 'uri'
28
+ require 'cgi'
29
+ require 'digest/sha1'
30
+ require 'base64'
31
+
32
+ module MasterCard
33
+ module Core
34
+ module Util
35
+ extend self
36
+ def validateURL(url)
37
+ #
38
+ # Validates that the given string is a valid URL
39
+ return !URI.regexp.match(url).nil?
40
+
41
+ end
42
+
43
+ def normalizeParams(url,params)
44
+ #
45
+ # Combines the query parameters of url and extra params into a single queryString.
46
+ # All the query string parameters are lexicographically sorted
47
+ query = URI.parse(url).query
48
+
49
+ unless query.nil?
50
+ query = CGI.parse(URI.parse(url).query)
51
+ end
52
+
53
+ unless query.nil?
54
+ query = params.merge(query)
55
+ else
56
+ query = params
57
+ end
58
+
59
+ normalizedParams = Hash.new
60
+ #Sort the parameters and
61
+ query.sort.map do |key,value|
62
+ if value.is_a?(Array)
63
+ value = value.join(",")
64
+ end
65
+
66
+ normalizedParams[key] = value
67
+ end
68
+
69
+ return normalizedParams.map{ |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join("&")
70
+ end
71
+
72
+
73
+ def normalizeUrl(url)
74
+ #Removes the query parameters from the URL
75
+ url = URI.parse(url)
76
+ return "#{url.scheme}://#{url.host}#{url.path}"
77
+
78
+ end
79
+
80
+ def subMap(inputMap,keyList)
81
+ #
82
+ #Returns a dict containing key, value from inputMap for keys in keyList
83
+ #Matched keys are removed from inputMap
84
+ ##
85
+ subMap = Hash.new
86
+ keyList.each do |key|
87
+ if inputMap.key?(key)
88
+ subMap[key] = inputMap[key]
89
+ inputMap.delete(key)
90
+ end
91
+ end
92
+ return subMap
93
+ end
94
+
95
+
96
+ def getReplacedPath(path,inputMap)
97
+ ##
98
+ #Replaces the {var} variables in path with value from inputMap
99
+ #The replaced values are removed from inputPath
100
+
101
+ #>>> getReplacedPath("http://localhost:8080/{var1}/car",{"var1" => 1})
102
+ # "http://localhost:8080/1/car"
103
+ #
104
+ #
105
+
106
+ pathRegex = /{(.*?)}/
107
+ matches = path.to_enum(:scan, pathRegex).map { Regexp.last_match }
108
+
109
+
110
+ matches.each do |match|
111
+ begin
112
+ path["#{match[0]}"] = "%s"%inputMap.fetch(match[1])
113
+ inputMap.delete(match[1])
114
+ rescue
115
+ raise KeyError, "Key \"#{match[1]}\" is not present in the input."
116
+ end
117
+ end
118
+
119
+ return path
120
+ end
121
+
122
+ def base64Encode(text)
123
+ #
124
+ #Base 64 encodes the text
125
+ return Base64.strict_encode64(text)
126
+ end
127
+
128
+ def sha1Base64Encode(text)
129
+ #
130
+ #Base 64 encodes the SHA1 digest of text
131
+ return base64Encode(Digest::SHA1.digest text)
132
+ end
133
+
134
+ def uriRfc3986Encode(value)
135
+ #
136
+ #RFC 3986 encodes the value
137
+ return CGI.escape(value)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ module MasterCard
28
+ module Security
29
+ class Authentication
30
+
31
+ def signRequest(uri,request)
32
+ raise NotImplementedError.new("This method should be overridden by the class")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,211 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ require "mastercard/security/authentication"
28
+ require "mastercard/security/util"
29
+ require "mastercard/core/util"
30
+ require "openssl"
31
+
32
+ module MasterCard
33
+ module Security
34
+ module OAuth
35
+ include MasterCard::Security
36
+
37
+ class OAuthAuthentication < Authentication
38
+ include MasterCard::Core::Util
39
+
40
+ def initialize(clientId,privateKey,key_alias,password)
41
+
42
+ @clientId = clientId
43
+ @privateKey = privateKey
44
+ @alias = key_alias
45
+ @password = password
46
+
47
+ end
48
+
49
+ def getClientId
50
+ return @clientId
51
+ end
52
+
53
+ def getPrivateKey
54
+ return @privateKey
55
+ end
56
+
57
+ def getOAuthBaseParameters(url, method, body)
58
+ oAuthParameters = OAuthParameters.new
59
+ oAuthParameters.setOAuthConsumerKey(@clientId)
60
+ oAuthParameters.setOAuthNonce(Util.getNonce())
61
+ oAuthParameters.setOAuthTimestamp(Util.getTimestamp())
62
+ oAuthParameters.setOAuthSignatureMethod("RSA-SHA1")
63
+ oAuthParameters.setOAuthVersion("1.0")
64
+
65
+ if body.nil?
66
+ body = ""
67
+ end
68
+
69
+ begin
70
+ body = body.to_json
71
+ rescue
72
+ #Do nothing and hope for the best
73
+ end
74
+
75
+ encodedHash = sha1Base64Encode(body)
76
+ oAuthParameters.setOAuthBodyHash(encodedHash)
77
+
78
+ return oAuthParameters
79
+ end
80
+
81
+ def getBaseString(url,method,params,oAuthParams)
82
+ #Merge the query string parameters
83
+ unless params.nil?
84
+ mergeParams = oAuthParams.merge(params)
85
+ else
86
+ mergeParams = oAuthParams
87
+ end
88
+
89
+ normalParams = normalizeParams(url,mergeParams)
90
+ normalUrl = normalizeUrl(url)
91
+ method = method.upcase
92
+
93
+ return "#{uriRfc3986Encode(method)}&#{uriRfc3986Encode(normalUrl)}&#{uriRfc3986Encode(normalParams)}"
94
+ end
95
+
96
+
97
+ def signRequest(url,request,method,data,params)
98
+
99
+ oauth_key = getOAuthKey(url,method,data,params)
100
+ request.add_field(OAuthParameters::AUTHORIZATION,oauth_key)
101
+ return request
102
+
103
+ end
104
+
105
+ def getOAuthKey(url,method,body,params)
106
+
107
+ #Get all the base parameters such as nonce and timestamp
108
+ oAuthBaseParameters = getOAuthBaseParameters(url,method,body)
109
+ #Get the base string
110
+ baseString = getBaseString(url, method, params,oAuthBaseParameters.getBaseParametersHash())
111
+
112
+ #Sign the base string using the private key
113
+ signature = signMessage(baseString)
114
+
115
+ #Set the signature in the Base parameters
116
+ oAuthBaseParameters.setOAuthSignature(signature)
117
+
118
+ #Get the updated base parameteres dict
119
+ oAuthBaseParametersHash = oAuthBaseParameters.getBaseParametersHash()
120
+
121
+ paramStr = oAuthBaseParametersHash.map { |k,v| "#{uriRfc3986Encode(k)}=\"#{uriRfc3986Encode(v.to_s)}\""}.join(",")
122
+
123
+ #Generate the header value for OAuth Header
124
+ return "#{OAuthParameters::OAUTH_KEY} #{paramStr}"
125
+
126
+
127
+ end
128
+
129
+
130
+ def signMessage(message)
131
+ #
132
+ #Signs the message using the private key with sha1 as digest
133
+ privateKeyFile = File.read(@privateKey)
134
+
135
+ p12 = OpenSSL::PKCS12.new(privateKeyFile, @password)
136
+ sign = p12.key.sign OpenSSL::Digest::SHA1.new, message
137
+
138
+ return base64Encode(sign)
139
+
140
+ end
141
+
142
+ end
143
+
144
+ class OAuthParameters
145
+
146
+ OAUTH_BODY_HASH_KEY = "oauth_body_hash"
147
+ OAUTH_CALLBACK_KEY = "oauth_callback"
148
+ OAUTH_CONSUMER_KEY = "oauth_consumer_key"
149
+ OAUTH_CONSUMER_SECRET = "oauth_consumer_secret"
150
+ OAUTH_NONCE_KEY = "oauth_nonce"
151
+ OAUTH_KEY = "OAuth"
152
+ AUTHORIZATION = "Authorization"
153
+ OAUTH_SIGNATURE_KEY = "oauth_signature"
154
+ OAUTH_SIGNATURE_METHOD_KEY = "oauth_signature_method"
155
+ OAUTH_TIMESTAMP_KEY = "oauth_timestamp"
156
+ OAUTH_TOKEN_KEY = "oauth_token"
157
+ OAUTH_TOKEN_SECRET_KEY = "oauth_token_secret"
158
+ OAUTH_VERIFIER_KEY = "oauth_verifier"
159
+ REALM_KEY = "realm"
160
+ XOAUTH_REQUESTOR_ID_KEY = "xoauth_requestor_id"
161
+ OAUTH_VERSION = "oauth_version"
162
+
163
+
164
+ def initialize
165
+ @baseParameters = Hash.new
166
+ end
167
+
168
+ def put(key,value)
169
+ @baseParameters[key] = value
170
+ end
171
+
172
+ def setOAuthConsumerKey(consumerKey)
173
+ put(OAuthParameters::OAUTH_CONSUMER_KEY, consumerKey)
174
+ end
175
+
176
+ def setOAuthNonce(oAuthNonce)
177
+ put(OAuthParameters::OAUTH_NONCE_KEY, oAuthNonce)
178
+ end
179
+
180
+ def setOAuthTimestamp(timestamp)
181
+ put(OAuthParameters::OAUTH_TIMESTAMP_KEY, timestamp)
182
+ end
183
+
184
+ def setOAuthSignatureMethod(signatureMethod)
185
+ put(OAuthParameters::OAUTH_SIGNATURE_METHOD_KEY, signatureMethod)
186
+ end
187
+
188
+ def setOAuthSignature(signature)
189
+ put(OAuthParameters::OAUTH_SIGNATURE_KEY, signature)
190
+ end
191
+
192
+ def setOAuthBodyHash(bodyHash)
193
+ put(OAuthParameters::OAUTH_BODY_HASH_KEY, bodyHash)
194
+ end
195
+
196
+ def setOAuthVersion(version)
197
+ put(OAuthParameters::OAUTH_VERSION, version)
198
+ end
199
+
200
+ def getBaseParametersHash
201
+ return @baseParameters
202
+ end
203
+
204
+
205
+ end
206
+
207
+
208
+
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ module MasterCard
28
+ module Security
29
+ module Util
30
+ extend self
31
+
32
+ def getTimestamp()
33
+ #
34
+ # Returns the UTC timestamp (seconds passed since epoch)
35
+ return Time.now.getutc.to_i
36
+ end
37
+
38
+ def getNonce(len = 16)
39
+ # Returns a random string of length=len
40
+ o = [('a'..'z'), ('A'..'Z'), (0..9)].map { |i| i.to_a }.flatten
41
+ return (0...len).map { o[rand(o.length)] }.join
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ require 'mastercard/core/config'
28
+ require 'mastercard/security/oauth'
29
+ require 'mastercard/core/model'