ocean-rails 3.2.0 → 3.3.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.
- 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