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 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