ocean-rails 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ocean/api.rb +14 -5
- data/lib/ocean/api_remote_resource.rb +42 -5
- data/lib/ocean/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e862602465b2d95c4feb017e60d9aa0c7ba4d01
|
4
|
+
data.tar.gz: 0f70ab560a3e158f98c665dca412f6b95a8dd065
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c67589b6dcee0ae611df937f0086c3ee61d4b7b52d814a785d819f3227005daefbf2f64951a4f2897e4680a76a6519356975316c4f620235a348e648cae4e67d
|
7
|
+
data.tar.gz: c690688b2acd71632fc1be92d4bcda692464fab52039e6496722f97ba7d45830ed4aeafa3cf93df270738f4fd512ac834a4c678e641fbcc3f696005b49d9faa7
|
data/lib/ocean/api.rb
CHANGED
@@ -146,6 +146,7 @@ class Api
|
|
146
146
|
# +ssl_verifyhost+ (2 by default), controls SSL host verification.
|
147
147
|
#
|
148
148
|
def self.request(url, http_method, args: nil, headers: {}, body: nil,
|
149
|
+
credentials: nil,
|
149
150
|
x_api_token: headers['X-API-Token'],
|
150
151
|
reauthentication: true,
|
151
152
|
ssl_verifypeer: true, ssl_verifyhost: 2)
|
@@ -153,7 +154,8 @@ class Api
|
|
153
154
|
headers['Accept'] = "application/json"
|
154
155
|
headers['Content-Type'] = "application/json" if [:post, :put].include?(http_method)
|
155
156
|
headers['User-Agent'] = "Ocean"
|
156
|
-
|
157
|
+
x_api_token = Api.authenticate(*Api.decode_credentials(credentials)) if x_api_token.blank? && credentials.present?
|
158
|
+
headers['X-API-Token'] = x_api_token if x_api_token.present?
|
157
159
|
|
158
160
|
while (true) do
|
159
161
|
request = Typhoeus::Request.new(url,
|
@@ -176,8 +178,13 @@ class Api
|
|
176
178
|
raise Api::NoResponseError, "Api.request could not obtain a response"
|
177
179
|
elsif [400, 419].include?(response.status) && reauthentication && x_api_token.present?
|
178
180
|
# Re-authenticate and retry
|
179
|
-
|
180
|
-
|
181
|
+
if credentials
|
182
|
+
x_api_token = Api.authenticate(*Api.decode_credentials(credentials))
|
183
|
+
headers['X-API-Token'] = x_api_token
|
184
|
+
else
|
185
|
+
Api.reset_service_token
|
186
|
+
headers['X-API-Token'] = Api.service_token
|
187
|
+
end
|
181
188
|
reauthentication = false # This prevents us from ending up here twice
|
182
189
|
else
|
183
190
|
# Failed
|
@@ -342,7 +349,7 @@ class Api
|
|
342
349
|
#
|
343
350
|
# Authenticates against the Auth service (which must be deployed and running) with
|
344
351
|
# a given +username+ and +password+. If successful, the authentication token is returned.
|
345
|
-
#
|
352
|
+
# If the credentials match the service's own, the token is also assigned to the instance variable @service_token.
|
346
353
|
# If not successful, +nil+ is returned.
|
347
354
|
#
|
348
355
|
def self.authenticate(username=API_USER, password=API_PASSWORD)
|
@@ -350,7 +357,9 @@ class Api
|
|
350
357
|
{'X-API-Authenticate' => encode_credentials(username, password)})
|
351
358
|
case response.status
|
352
359
|
when 201
|
353
|
-
|
360
|
+
token = response.body['authentication']['token']
|
361
|
+
@service_token = token if username == API_USER && password == API_PASSWORD
|
362
|
+
token
|
354
363
|
when 400
|
355
364
|
# Malformed credentials. Don't repeat the request.
|
356
365
|
nil
|
@@ -56,12 +56,36 @@ class Api
|
|
56
56
|
# <tt>thing.get!</tt> returns an Api::RemoteResource if successful. If not, raises an exception.
|
57
57
|
# <tt>thing.get</tt> does the same, but returns nil if unsuccessful.
|
58
58
|
#
|
59
|
+
# Exceptions:
|
60
|
+
#
|
61
|
+
# GetFailed raised when the GET to obtain the remote resource has failed.
|
62
|
+
# WrongContentType raised when the Content-Type doesn't match :content_type.
|
63
|
+
# UnparseableJson raised when the response body doesn't parse as JSON.
|
64
|
+
# JsonIsNoResource raised when the structure of the parsed JSON body is not a resource.
|
65
|
+
#
|
66
|
+
# To parse as a resource, the JSON must be a wrapped Ocean resource of this format:
|
67
|
+
#
|
68
|
+
# {"thing": {
|
69
|
+
# "_links": {
|
70
|
+
# "self": {"href": "https://....", type: "application/json"},
|
71
|
+
# ...
|
72
|
+
# },
|
73
|
+
# "foo": 2,
|
74
|
+
# "bar": [1,2,3],
|
75
|
+
# ...
|
76
|
+
# }
|
77
|
+
#
|
78
|
+
# The above is a Thing resource, wrapped with its type. Attributes should appear in the inner
|
79
|
+
# hash, which must have at least a _links hyperlink attribute with a href and a content type.
|
80
|
+
#
|
59
81
|
class RemoteResource
|
60
82
|
|
61
83
|
attr_reader :uri, :content_type, :retries, :backoff_time, :backoff_rate, :backoff_max
|
62
|
-
attr_reader :raw, :resource, :resource_type, :status, :headers
|
84
|
+
attr_reader :raw, :resource, :resource_type, :status, :headers, :credentials, :x_api_token
|
85
|
+
attr_reader :status_message
|
63
86
|
|
64
87
|
def initialize(uri, type="application/json",
|
88
|
+
credentials: nil, x_api_token: nil,
|
65
89
|
retries: 3, backoff_time: 1, backoff_rate: 2, backoff_max: 30)
|
66
90
|
super()
|
67
91
|
@uri = uri
|
@@ -75,7 +99,10 @@ class Api
|
|
75
99
|
@resource = nil
|
76
100
|
@resource_type = nil
|
77
101
|
@status = nil
|
102
|
+
@status_message = nil
|
78
103
|
@headers = nil
|
104
|
+
@credentials = credentials
|
105
|
+
@x_api_token = x_api_token
|
79
106
|
end
|
80
107
|
|
81
108
|
def present?
|
@@ -129,6 +156,7 @@ class Api
|
|
129
156
|
end
|
130
157
|
|
131
158
|
|
159
|
+
class GetFailed < StandardError; end
|
132
160
|
class WrongContentType < StandardError; end
|
133
161
|
class UnparseableJson < StandardError; end
|
134
162
|
class JsonIsNoResource < StandardError; end
|
@@ -137,19 +165,28 @@ class Api
|
|
137
165
|
private
|
138
166
|
|
139
167
|
attr_accessor :present
|
140
|
-
attr_writer :raw, :resource, :resource_type, :status, :headers
|
168
|
+
attr_writer :raw, :resource, :resource_type, :status, :headers, :status_message
|
141
169
|
|
142
170
|
|
143
171
|
def self._retrieve(rr)
|
144
|
-
|
145
|
-
|
172
|
+
if rr.credentials.present? && rr.credentials != Api.encode_credentials(API_USER, API_PASSWORD)
|
173
|
+
credentials = rr.credentials
|
174
|
+
token = rr.x_api_token
|
175
|
+
else
|
176
|
+
credentials = nil
|
177
|
+
token = rr.x_api_token || Api.service_token
|
178
|
+
end
|
179
|
+
response = Api.request rr.uri, :get, headers: {}, credentials: credentials, x_api_token: token
|
180
|
+
rr.send :status=, response.status
|
181
|
+
rr.send :status_message=, response.message
|
182
|
+
raise GetFailed unless response.success?
|
146
183
|
raise WrongContentType unless response.headers['Content-Type'] == rr.content_type
|
147
184
|
begin
|
148
185
|
raw = response.body
|
149
186
|
rescue JSON::ParserError
|
150
187
|
raise UnparseableJson
|
151
188
|
end
|
152
|
-
rr.send
|
189
|
+
rr.send :_setup, raw, response
|
153
190
|
rr
|
154
191
|
end
|
155
192
|
|
data/lib/ocean/version.rb
CHANGED