latchsdk 1.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35cad8b46afdbb0663e511f2f384c393d3321e50
4
+ data.tar.gz: 3c9c9773b086842240fb9c5c3674b4088f081f02
5
+ SHA512:
6
+ metadata.gz: 9586fc07284b9b32bbe75c5b3d8f014aa7690a4c8139d3bbf937993c5fa91f62505587b28f19829b6f206f5eec7d03a46b67b6a30e3bc28f0c91c1b72ae2fe40
7
+ data.tar.gz: 1464d1d793df1cb735aee5e9c21749574b9060df6a729f8cbfbfedb0b24bfddad858682dee526a14861db2f1330f32c3f3402785c6241b86495db44dc91f2070
@@ -0,0 +1,217 @@
1
+ #Latch Ruby SDK - Set of reusable classes to allow developers integrate Latch on their applications.
2
+ #Copyright (C) 2013 Eleven Paths
3
+ #
4
+ #This library is free software; you can redistribute it and/or
5
+ #modify it under the terms of the GNU Lesser General Public
6
+ #License as published by the Free Software Foundation; either
7
+ #version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ #This library is distributed in the hope that it will be useful,
10
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ #Lesser General Public License for more details.
13
+ #
14
+ #You should have received a copy of the GNU Lesser General Public
15
+ #License along with this library; if not, write to the Free Software
16
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'rubygems'
19
+ require 'base64'
20
+ require 'cgi'
21
+ require 'net/http'
22
+ require 'openssl'
23
+ require 'json'
24
+
25
+ require_relative 'latchsdk/LatchResponse'
26
+
27
+ class Latch
28
+
29
+ attr_accessor :api_host
30
+ API_HOST = "https://latch.elevenpaths.com"
31
+ API_VERSION = "0.6"
32
+ API_CHECK_STATUS_URL = "/api/0.6/status"
33
+ API_PAIR_URL = "/api/0.6/pair"
34
+ API_PAIR_WITH_ID_URL = "/api/0.6/pairWithId"
35
+ API_UNPAIR_URL = "/api/0.6/unpair"
36
+
37
+ AUTHORIZATION_HEADER_NAME = "Authorization"
38
+ DATE_HEADER_NAME = "X-11Paths-Date"
39
+ AUTHORIZATION_METHOD = "11PATHS"
40
+ AUTHORIZATION_HEADER_FIELD_SEPARATOR = " "
41
+
42
+ HMAC_ALGORITHM = "sha1"
43
+
44
+ X_11PATHS_HEADER_PREFIX = "X-11Paths-"
45
+ X_11PATHS_HEADER_SEPARATOR = ":"
46
+
47
+
48
+
49
+
50
+
51
+ # The custom header consists of three parts, the method, the appId and the signature.
52
+ # This method returns the specified part if it exists.
53
+ # @param $part The zero indexed part to be returned
54
+ # @param $header The HTTP header value from which to extract the part
55
+ # @return string the specified part from the header or an empty string if not existent
56
+ def getPartFromHeader(part, header)
57
+ if (header.empty?)
58
+ parts = header.split(AUTHORIZATION_HEADER_FIELD_SEPARATOR)
59
+ if(parts.length > part)
60
+ return parts[part]
61
+ end
62
+ end
63
+ return ""
64
+ end
65
+
66
+ # @param $authorizationHeader Authorization HTTP Header
67
+ # @return string the Authorization method. Typical values are "Basic", "Digest" or "11PATHS"
68
+ def getAuthMethodFromHeader(authorizationHeader)
69
+ getPartFromHeader(0, authorizationHeader)
70
+ end
71
+
72
+ # @param $authorizationHeader Authorization HTTP Header
73
+ # @return string the requesting application Id. Identifies the application using the API
74
+ def getAppIdFromHeader(authorizationHeader)
75
+ getPartFromHeader(1, authorizationHeader)
76
+ end
77
+
78
+
79
+ # @param $authorizationHeader Authorization HTTP Header
80
+ # @return string the signature of the current request. Verifies the identity of the application using the API
81
+ def getSignatureFromHeader(authorizationHeader)
82
+ getPartFromHeader(2, authorizationHeader)
83
+ end
84
+
85
+
86
+ # Create an instance of the class with the Application ID and secret obtained from Eleven Paths
87
+ # @param $appId
88
+ # @param $secretKey
89
+ def initialize(appid, secret)
90
+ @appid = appid
91
+ @secret = secret
92
+ @api_host = API_HOST
93
+ end
94
+
95
+
96
+ def http_get(url, headers)
97
+ uri = URI.parse(url)
98
+ http = Net::HTTP.new(uri.host, uri.port)
99
+
100
+ if (uri.default_port == 443)
101
+ http.use_ssl = true
102
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
103
+ end
104
+
105
+
106
+ request = Net::HTTP::Get.new(uri.request_uri)
107
+
108
+ headers.map do |key,value|
109
+ request[key] = value
110
+ end
111
+
112
+ response = http.request(request)
113
+ response.body
114
+ end
115
+
116
+
117
+ def http_get_proxy(url)
118
+ LatchResponse.new(http_get(api_host + url, authenticationHeaders('GET', url, nil)))
119
+ end
120
+
121
+
122
+ def pairWithId(accountId)
123
+ http_get_proxy(API_PAIR_WITH_ID_URL + '/' + accountId)
124
+ end
125
+
126
+
127
+ def pair(token)
128
+ http_get_proxy(API_PAIR_URL + '/' + token)
129
+ end
130
+
131
+
132
+ def status(accountId)
133
+ http_get_proxy(API_CHECK_STATUS_URL + '/' + accountId)
134
+ end
135
+
136
+
137
+ def operationStatus(accountId, operationId)
138
+ http_get_proxy(API_CHECK_STATUS_URL + "/" + accountId + '/' + operationId)
139
+ end
140
+
141
+
142
+ def unpair(accountId)
143
+ http_get_proxy(API_UNPAIR_URL + '/' + accountId)
144
+ end
145
+
146
+
147
+
148
+ # @param $data the string to sign
149
+ # @return string base64 encoding of the HMAC-SHA1 hash of the data parameter using {@code secretKey} as cipher key.
150
+ def signData(data)
151
+ Base64.encode64(OpenSSL::HMAC.digest(HMAC_ALGORITHM, @secret, data))
152
+ end
153
+
154
+
155
+ # Calculate the authentication headers to be sent with a request to the API
156
+ # @param $HTTPMethod the HTTP Method, currently only GET is supported
157
+ # @param $queryString the urlencoded string including the path (from the first forward slash) and the parameters
158
+ # @param $xHeaders HTTP headers specific to the 11-paths API. null if not needed.
159
+ # @param $utc the Universal Coordinated Time for the Date HTTP header
160
+ # @return array a map with the Authorization and Date headers needed to sign a Latch API request
161
+ def authenticationHeaders(httpMethod, queryString, xHeaders=nil, utc=nil)
162
+ if (utc == nil)
163
+ utc = getCurrentUTC
164
+ end
165
+
166
+ stringToSign = (httpMethod.upcase).strip + "\n" +
167
+ utc.to_s + "\n" +
168
+ getSerializedHeaders(xHeaders) + "\n" +
169
+ queryString.strip
170
+
171
+ authorizationHeader = AUTHORIZATION_METHOD +
172
+ AUTHORIZATION_HEADER_FIELD_SEPARATOR +
173
+ @appid +
174
+ AUTHORIZATION_HEADER_FIELD_SEPARATOR +
175
+ signData(stringToSign).chop
176
+
177
+ headers = {}
178
+ headers[AUTHORIZATION_HEADER_NAME] = authorizationHeader
179
+ headers[DATE_HEADER_NAME] = utc
180
+ return headers
181
+ end
182
+
183
+
184
+
185
+ # Prepares and returns a string ready to be signed from the 11-paths specific HTTP headers received
186
+ # @param $xHeaders a non necessarily ordered map of the HTTP headers to be ordered without duplicates.
187
+ # @return a String with the serialized headers, an empty string if no headers are passed, or null if there's a problem
188
+ # such as non 11paths specific headers
189
+ def getSerializedHeaders(xHeaders)
190
+ if(xHeaders != nil)
191
+ headers = xHeaders.inject({}) do |xHeaders, keys|
192
+ hash[keys[0].downcase] = keys[1]
193
+ hash
194
+ end
195
+
196
+
197
+ serializedHeaders = ''
198
+
199
+ headers.sort.map do |key,value|
200
+ if(key.downcase == X_11PATHS_HEADER_PREFIX.downcase)
201
+ puts "Error serializing headers. Only specific " + X_11PATHS_HEADER_PREFIX + " headers need to be singed"
202
+ return nil
203
+ end
204
+ serializedHeaders += key + X_11PATHS_HEADER_SEPARATOR + value + ' '
205
+ end
206
+ substitute = 'utf-8'
207
+ return serializedHeaders.gsub(/^[#{substitute}]+|[#{substitute}]+$/, '')
208
+ else
209
+ return ""
210
+ end
211
+ end
212
+
213
+ # @return a string representation of the current time in UTC to be used in a Date HTTP Header
214
+ def getCurrentUTC
215
+ Time.now.utc
216
+ end
217
+ end
@@ -0,0 +1,47 @@
1
+ #Latch Ruby SDK - Set of reusable classes to allow developers integrate Latch on their applications.
2
+ #Copyright (C) 2013 Eleven Paths
3
+ #
4
+ #This library is free software; you can redistribute it and/or
5
+ #modify it under the terms of the GNU Lesser General Public
6
+ #License as published by the Free Software Foundation; either
7
+ #version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ #This library is distributed in the hope that it will be useful,
10
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ #Lesser General Public License for more details.
13
+ #
14
+ #You should have received a copy of the GNU Lesser General Public
15
+ #License along with this library; if not, write to the Free Software
16
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'rubygems'
19
+ require 'json'
20
+
21
+ class Error
22
+
23
+ attr_reader :code
24
+ attr_reader :message
25
+
26
+ # @param string json a Json representation of an error with "code" and "message" elements
27
+ def initialize(json)
28
+ if (json.is_a?(String))
29
+ json = JSON.Parse(json)
30
+ end
31
+
32
+ if(json.has_key?("code") && json.has_key?("message"))
33
+ @code = json["code"]
34
+ @message = json["message"]
35
+ else
36
+ puts "Error creating error object from string " + json
37
+ end
38
+ end
39
+
40
+ # JSON representing the Error Object
41
+ def to_json
42
+ error = {}
43
+ error["code"] = @code
44
+ error["message"] = @message
45
+ error.to_json
46
+ end
47
+ end
@@ -0,0 +1,61 @@
1
+ #Latch Ruby SDK - Set of reusable classes to allow developers integrate Latch on their applications.
2
+ #Copyright (C) 2013 Eleven Paths
3
+ #
4
+ #This library is free software; you can redistribute it and/or
5
+ #modify it under the terms of the GNU Lesser General Public
6
+ #License as published by the Free Software Foundation; either
7
+ #version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ #This library is distributed in the hope that it will be useful,
10
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ #Lesser General Public License for more details.
13
+ #
14
+ #You should have received a copy of the GNU Lesser General Public
15
+ #License along with this library; if not, write to the Free Software
16
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'rubygems'
19
+ require 'json'
20
+ require_relative 'Error'
21
+
22
+
23
+ # This class models a response from any of the endpoints in the Latch API.
24
+ # It consists of a "data" and an "error" elements. Although normally only one of them will be
25
+ # present, they are not mutually exclusive, since errors can be non fatal, and therefore a response
26
+ # could have valid information in the data field and at the same time inform of an error.
27
+ class LatchResponse
28
+
29
+ attr_accessor :data
30
+ attr_accessor :error
31
+
32
+
33
+ # @param jsonString a json string received from one of the methods of the Latch API
34
+ def initialize(jsonString)
35
+ json = JSON.parse(jsonString)
36
+
37
+ if(json != nil)
38
+ if (json.has_key?("data"))
39
+ @data = json["data"]
40
+ end
41
+
42
+ if (json.has_key?("error"))
43
+ @error = Error.new(json["error"])
44
+ end
45
+ end
46
+ end
47
+
48
+ # Get JSON String that represents the LatchResponse object
49
+ def to_json
50
+ response = {}
51
+
52
+ if (@data != nil)
53
+ response["data"] = @data
54
+ end
55
+
56
+ if (@error != nil)
57
+ response["error"] = @error.to_json
58
+ end
59
+ response.to_json
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: latchsdk
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.1'
5
+ platform: ruby
6
+ authors:
7
+ - ElevenPaths
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This SDK allows developers to integrate Latch on their Ruby services.
14
+ Latch is a service that lets end-users add an extra level of security to their online
15
+ accounts and services. With this version of the SDK, developers can pair and unpair
16
+ users and check their latches status. For more information please visit https://latch.elevenpaths.com
17
+ or the SDK page on GitHub https://github.com/ElevenPaths/latch-sdk-ruby
18
+ email: it@11paths.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - lib/latchsdk.rb
24
+ - lib/latchsdk/Error.rb
25
+ - lib/latchsdk/LatchResponse.rb
26
+ homepage: https://github.com/ElevenPaths/latch-sdk-ruby
27
+ licenses:
28
+ - LGPL
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project: Latchsdk
46
+ rubygems_version: 2.1.11
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: This SDK allows developers to integrate Latch on their Ruby services.
50
+ test_files: []
51
+ has_rdoc: