mastercard_api_core 0.0.1

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