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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 098dd40c3f091686952bd78105c343ee87535f61
4
- data.tar.gz: 9d2cd112b855fd23afd076990794aad0793c4a9b
3
+ metadata.gz: 0e862602465b2d95c4feb017e60d9aa0c7ba4d01
4
+ data.tar.gz: 0f70ab560a3e158f98c665dca412f6b95a8dd065
5
5
  SHA512:
6
- metadata.gz: 2de952ef104e432eead8554f0f5a7d6a2113c080f1b84b2a0a303937d51bf9dc8ce92574fc5fa53e3cd1bd47eba1e6decb20f2d7e8d9ae10a131741a9b62b128
7
- data.tar.gz: 7a13f27912aecad17c15a54e93f300071053f9fcda62fb77b6af64425a48a81182fb5322570d053b26e65a7f4e6d020e364ce314079985a959f0e5d6239d8fc4
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
- headers['X-API-Token'] = x_api_token if x_api_token
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
- Api.reset_service_token
180
- headers['X-API-Token'] = Api.service_token
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
- # The token is also assigned to the instance variable @service_token.
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
- @service_token = response.body['authentication']['token']
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
- response = Api.request rr.uri, :get, headers: {}, x_api_token: Api.service_token
145
- return unless response.success?
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(:_setup, raw, response)
189
+ rr.send :_setup, raw, response
153
190
  rr
154
191
  end
155
192
 
data/lib/ocean/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ocean
2
- VERSION = "3.2.0"
2
+ VERSION = "3.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocean-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Bengtson