bubbles-rest-client 0.4.1 → 0.5.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.
@@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency "webmock", "~> 3.5"
41
41
  spec.add_development_dependency "vcr", "~> 3.0"
42
42
  spec.add_development_dependency "rspec", "~> 3.8"
43
+ spec.add_development_dependency "os"
43
44
  spec.add_dependency "addressable", "~> 2.5"
44
45
  spec.add_dependency "rest-client", "~> 2.0"
45
- end
46
+ end
@@ -10,11 +10,9 @@ require 'json'
10
10
 
11
11
  module Bubbles
12
12
  class Resources < RestClientResources
13
- def initialize
14
- # def initialize(env, api_key)
15
- # @environment = get_environment env
16
- # @api_key = api_key
17
- # @auth_token = nil
13
+ def initialize(api_key='')
14
+ super
15
+
18
16
  @packageName = Bubbles::VersionInformation.package_name
19
17
  @versionName = Bubbles::VersionInformation.version_name
20
18
  @versionCode = Bubbles::VersionInformation.version_code
@@ -29,4 +27,3 @@ module Bubbles
29
27
  end
30
28
  end
31
29
  end
32
-
@@ -43,6 +43,7 @@ module Bubbles
43
43
  @environment_host = '127.0.0.1'
44
44
  @environment_port = '1234'
45
45
  @environment_api_key = nil
46
+ @environment_api_key_name = 'X-API-Key'
46
47
 
47
48
  @endpoints = Hash.new
48
49
  end
@@ -53,7 +54,8 @@ module Bubbles
53
54
  # Note that this constructs a new +RestEnvironment+ and returns it, rather than returning an existing object.
54
55
  #
55
56
  def environment
56
- RestEnvironment.new(@environment_scheme, @environment_host, @environment_port, @environment_api_key)
57
+ RestEnvironment.new(@environment_scheme, @environment_host, @environment_port, @environment_api_key,
58
+ @environment_api_key_name)
57
59
  end
58
60
 
59
61
  ##
@@ -66,7 +68,9 @@ module Bubbles
66
68
  # config.environment = {
67
69
  # :scheme => 'https',
68
70
  # :host => 'stage.api.somehost.com',
69
- # :port => '443'
71
+ # :port => '443',
72
+ # :api_key => 'something',
73
+ # :api_key_name => 'X-API-Key' # Optional
70
74
  # }
71
75
  # end
72
76
  #
@@ -75,6 +79,11 @@ module Bubbles
75
79
  @environment_host = env[:host]
76
80
  @environment_port = env[:port]
77
81
  @environment_api_key = env[:api_key]
82
+ if env.has_key? :api_key_name
83
+ @environment_api_key_name = env[:api_key_name]
84
+ else
85
+ @environment_api_key_name = 'X-API-Key'
86
+ end
78
87
  end
79
88
 
80
89
  ##
@@ -129,18 +138,24 @@ module Bubbles
129
138
  Bubbles::RestEnvironment.class_exec do
130
139
  if endpoint.has_uri_params?
131
140
  define_method(endpoint_name_as_sym) do |auth_token, uri_params|
132
- RestClientResources.execute_get_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers
141
+ RestClientResources.execute_get_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
133
142
  end
134
143
  else
135
144
  define_method(endpoint_name_as_sym) do |auth_token|
136
- RestClientResources.execute_get_authenticated self, endpoint, auth_token,{}, endpoint.additional_headers
145
+ RestClientResources.execute_get_authenticated self, endpoint, auth_token, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
137
146
  end
138
147
  end
139
148
  end
140
149
  else
141
150
  Bubbles::RestEnvironment.class_exec do
142
- define_method(endpoint_name_as_sym) do
143
- RestClientResources.execute_get_unauthenticated self, endpoint, endpoint.additional_headers
151
+ if endpoint.has_uri_params?
152
+ define_method(endpoint_name_as_sym) do |uri_params|
153
+ RestClientResources.execute_get_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
154
+ end
155
+ else
156
+ define_method(endpoint_name_as_sym) do
157
+ RestClientResources.execute_get_unauthenticated self, endpoint, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
158
+ end
144
159
  end
145
160
  end
146
161
  end
@@ -148,79 +163,56 @@ module Bubbles
148
163
  if endpoint.authenticated?
149
164
  Bubbles::RestEnvironment.class_exec do
150
165
  define_method(endpoint_name_as_sym) do |auth_token, data|
151
- RestClientResources.execute_post_authenticated self, endpoint, auth_token, data, endpoint.additional_headers
166
+ RestClientResources.execute_post_authenticated self, endpoint, auth_token, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
152
167
  end
153
168
  end
154
169
  else
155
- if endpoint.api_key_required?
156
- Bubbles::RestEnvironment.class_exec do
157
- define_method(endpoint_name_as_sym) do |data|
158
- additional_headers = endpoint.additional_headers
159
- if endpoint.encode_authorization_header?
160
- count = 0
161
- auth_value = ''
162
- endpoint.encode_authorization.each { |auth_key|
163
- if data[auth_key]
164
- if count > 0
165
- auth_value = auth_value + ':' + data[auth_key]
166
- else
167
- auth_value = data[auth_key]
168
- end
169
-
170
- count = count + 1
171
-
172
- data.delete(auth_key)
173
- end
174
- }
175
-
176
- additional_headers[:Authorization] = 'Basic ' + Base64.strict_encode64(auth_value)
177
- end
178
-
179
- RestClientResources.execute_post_with_api_key self, endpoint, self.api_key, data, additional_headers
170
+ Bubbles::RestEnvironment.class_exec do
171
+ define_method(endpoint_name_as_sym) do |data|
172
+ composite_headers = endpoint.additional_headers
173
+ if endpoint.encode_authorization_header?
174
+ auth_value = RestClientResources.get_encoded_authorization(endpoint, data)
175
+ composite_headers = RestClientResources.build_composite_headers(endpoint.additional_headers, {
176
+ :Authorization => 'Basic ' + Base64.strict_encode64(auth_value)
177
+ })
180
178
  end
179
+
180
+ RestClientResources.execute_post_unauthenticated self, endpoint, data, composite_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
181
181
  end
182
- else
183
- raise 'Unauthenticated POST requests without an API key are not allowed'
184
182
  end
185
183
  end
186
184
  elsif endpoint.method == :delete
187
- if endpoint.authenticated?
188
- Bubbles::RestEnvironment.class_exec do
189
- if endpoint.has_uri_params?
185
+ if endpoint.has_uri_params?
186
+ if endpoint.authenticated?
187
+ Bubbles::RestEnvironment.class_exec do
190
188
  define_method(endpoint_name_as_sym) do |auth_token, uri_params|
191
- RestClientResources.execute_delete_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers
189
+ RestClientResources.execute_delete_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
190
+ end
191
+ end
192
+ else
193
+ Bubbles::RestEnvironment.class_exec do
194
+ define_method(endpoint_name_as_sym) do |uri_params|
195
+ RestClientResources.execute_delete_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
192
196
  end
193
- else
194
- # NOTE: While MDN states that DELETE requests with a body are allowed, it seems that a number of
195
- # documentation sites discourage its use. Thus, it's possible that, depending on the server API
196
- # framework, the DELETE request could be rejected. As such, we're disallowing it here, BUT if we
197
- # get feedback from users that it should be supported, we can add support for it.
198
- raise 'DELETE requests without URI parameters are not allowed'
199
- # define_method(endpoint_name_as_sym) do |auth_token|
200
- # RestClientResources.execute_delete_authenticated self, endpoint, auth_token, {}
201
- # end
202
197
  end
203
198
  end
204
199
  else
205
- raise 'Unauthenticated DELETE requests are not allowed'
206
- # Bubbles::RestEnvironment.class_exec do
207
- # define_method(endpoint_name_as_sym) do
208
- # RestClientResources.execute_delete_unauthenticated self, endpoint
209
- # end
210
- # end
200
+ # XXX_jwir3: While MDN states that DELETE requests with a body are allowed, it seems that a number of
201
+ # documentation sites discourage its use. Thus, it's possible that, depending on the server API
202
+ # framework, the DELETE request could be rejected. In addition, RestClient doesn't seem to support DELETE
203
+ # requests with a body, so we're a bit stuck on this one, even if we wanted to support it.
204
+ raise 'DELETE requests without URI parameters are not allowed'
211
205
  end
212
206
  elsif endpoint.method == :patch
213
207
  if endpoint.authenticated?
214
208
  Bubbles::RestEnvironment.class_exec do
215
209
  if endpoint.has_uri_params?
216
210
  define_method(endpoint_name_as_sym) do |auth_token, uri_params, data|
217
- RestClientResources.execute_patch_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers
211
+ RestClientResources.execute_patch_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
218
212
  end
219
213
  else
220
214
  define_method(endpoint_name_as_sym) do |auth_token, data|
221
- # TODO: Nothing tests this case. We need something to test this case or we run the risk of
222
- # it having bugs (uri_params was nil previously!)
223
- RestClientResources.execute_patch_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers
215
+ RestClientResources.execute_patch_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
224
216
  end
225
217
  end
226
218
  end
@@ -228,11 +220,11 @@ module Bubbles
228
220
  Bubbles::RestEnvironment.class_exec do
229
221
  if endpoint.has_uri_params?
230
222
  define_method(endpoint_name_as_sym) do |uri_params, data|
231
- RestClientResources.execute_patch_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers
223
+ RestClientResources.execute_patch_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
232
224
  end
233
225
  else
234
226
  define_method(endpoint_name_as_sym) do |data|
235
- RestClientResources.execute_patch_unauthenticated self, endpoint, {}, data, endpoint.additional_headers
227
+ RestClientResources.execute_patch_unauthenticated self, endpoint, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
236
228
  end
237
229
  end
238
230
  end
@@ -242,26 +234,23 @@ module Bubbles
242
234
  Bubbles::RestEnvironment.class_exec do
243
235
  if endpoint.has_uri_params?
244
236
  define_method(endpoint_name_as_sym) do |auth_token, uri_params, data|
245
- RestClientResources.execute_put_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers
237
+ RestClientResources.execute_put_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
246
238
  end
247
239
  else
248
240
  define_method(endpoint_name_as_sym) do |auth_token, data|
249
- # TODO: Nothing tests this case. We need something to test this case or we run the risk of
250
- # it having bugs (uri_params was nil previously!)
251
- RestClientResources.execute_put_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers
241
+ RestClientResources.execute_put_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
252
242
  end
253
243
  end
254
244
  end
255
245
  else
256
- # raise 'Unauthenticated PUT requests are not implemented'
257
246
  Bubbles::RestEnvironment.class_exec do
258
247
  if endpoint.has_uri_params?
259
248
  define_method(endpoint_name_as_sym) do |uri_params, data|
260
- RestClientResources.execute_put_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers
249
+ RestClientResources.execute_put_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
261
250
  end
262
251
  else
263
252
  define_method(endpoint_name_as_sym) do |data|
264
- RestClientResources.execute_put_unauthenticated self, endpoint, {}, data, endpoint.additional_headers
253
+ RestClientResources.execute_put_unauthenticated self, endpoint, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
265
254
  end
266
255
  end
267
256
  end
@@ -271,23 +260,11 @@ module Bubbles
271
260
  Bubbles::RestEnvironment.class_exec do
272
261
  if endpoint.has_uri_params?
273
262
  define_method(endpoint_name_as_sym) do |auth_token, uri_params|
274
- RestClientResources.execute_head_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers
263
+ RestClientResources.execute_head_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
275
264
  end
276
265
  else
277
266
  define_method(endpoint_name_as_sym) do |auth_token|
278
- RestClientResources.execute_head_authenticated self, endpoint, auth_token, {}, endpoint.additional_headers
279
- end
280
- end
281
- end
282
- elsif endpoint.api_key_required?
283
- Bubbles::RestEnvironment.class_exec do
284
- if endpoint.has_uri_params?
285
- define_method(endpoint_name_as_sym) do |uri_params|
286
- RestClientResources.execute_head_unauthenticated_with_uri_params self, endpoint, self.api_key, uri_params, endpoint.additional_headers
287
- end
288
- else
289
- define_method(endpoint_name_as_sym) do
290
- RestClientResources.execute_head_unauthenticated self, endpoint, self.api_key, endpoint.additional_headers
267
+ RestClientResources.execute_head_authenticated self, endpoint, auth_token, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
291
268
  end
292
269
  end
293
270
  end
@@ -295,11 +272,11 @@ module Bubbles
295
272
  Bubbles::RestEnvironment.class_exec do
296
273
  if endpoint.has_uri_params?
297
274
  define_method(endpoint_name_as_sym) do |uri_params|
298
- RestClientResources.execute_head_unauthenticated self, endpoint, uri_params, endpoint.additional_headers
275
+ RestClientResources.execute_head_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
299
276
  end
300
277
  else
301
278
  define_method(endpoint_name_as_sym) do
302
- RestClientResources.execute_head_unauthenticated self, endpoint, {}, endpoint.additional_headers
279
+ RestClientResources.execute_head_unauthenticated self, endpoint, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
303
280
  end
304
281
  end
305
282
  end
@@ -146,13 +146,10 @@ module Bubbles
146
146
  #
147
147
  # @param [RestEnvironment] env The +RestEnvironment+ to use to access this +Endpoint+.
148
148
  #
149
- # @return [String] A +String+ containing the full URL to access this +Endpoint+ on the given {RestEnvironment}.
149
+ # @return [Addressable::URI] An +Addressable::URI+ containing the full URL to access this +Endpoint+ on the given
150
+ # +RestEnvironment+.
150
151
  #
151
152
  def get_expanded_url(env, uri_params = {})
152
- unless uri_params
153
- uri_params = {}
154
- end
155
-
156
153
  url = get_base_url env
157
154
 
158
155
  if is_complex?
@@ -240,7 +237,7 @@ module Bubbles
240
237
  # for the +Endpoint+, to be defined on {RestClientResources}; false, otherwise.
241
238
  #
242
239
  def name?
243
- @name == nil
240
+ @name != nil
244
241
  end
245
242
 
246
243
  ##
@@ -11,20 +11,19 @@ module Bubbles
11
11
  # Create a new instance of +RestClientResources+.
12
12
  #
13
13
  # @param env The +RestEnvironment+ that should be used for this set of resources.
14
- # @param api_key The API key to use to send to the host for unauthenticated requests.
14
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
15
+ # to +nil+.
16
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
17
+ # +"X-API-Key"+.
15
18
  #
16
- def initialize(env, api_key)
17
- unless env
18
- env = :local
19
- end
20
-
19
+ def initialize(env, api_key = nil, api_key_name='X-API-Key')
21
20
  unless api_key
22
21
  api_key = ''
23
22
  end
24
23
 
25
- @environment = get_environment env
26
24
  @api_key = api_key
27
25
  @auth_token = nil
26
+ @api_key_name = api_key_name
28
27
  end
29
28
 
30
29
  ##
@@ -37,14 +36,11 @@ module Bubbles
37
36
  #
38
37
  # @return [RestClient::Response] The +Response+ resulting from the execution of the GET call.
39
38
  #
40
- def self.execute_get_unauthenticated(env, endpoint, additional_headers = {})
41
- execute_rest_call(env, endpoint, nil, nil, additional_headers) do |env, url, data, headers|
42
- if env.scheme == 'https'
43
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
44
- .get(headers)
45
- else
46
- next RestClient.get(url.to_s, headers)
47
- end
39
+ def self.execute_get_unauthenticated(env, endpoint, uri_params, additional_headers = {}, api_key = nil, api_key_name='X-API-Key')
40
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
41
+
42
+ execute_rest_call(env, endpoint, nil, nil, composite_headers, uri_params) do |env, url, data, headers|
43
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).get(headers)
48
44
  end
49
45
  end
50
46
 
@@ -59,17 +55,18 @@ module Bubbles
59
55
  # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
60
56
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
61
57
  # call. Defaults to an empty +Hash+.
58
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
59
+ # to +nil+.
60
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
61
+ # +"X-API-Key"+.
62
62
  #
63
63
  # @return [RestClient::Response] The +Response+ resulting from the execution of the GET call.
64
64
  #
65
- def self.execute_get_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {})
66
- execute_rest_call(env, endpoint, nil, auth_token, additional_headers, uri_params) do |env, url, data, headers|
67
- if env.scheme == 'https'
68
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
69
- .get(headers)
70
- else
71
- next RestClient.get(url.to_s, headers)
72
- end
65
+ def self.execute_get_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
66
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
67
+
68
+ execute_rest_call(env, endpoint, nil, auth_token, composite_headers, uri_params) do |env, url, data, headers|
69
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).get(headers)
73
70
  end
74
71
  end
75
72
 
@@ -83,17 +80,18 @@ module Bubbles
83
80
  # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
84
81
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
85
82
  # call. Defaults to an empty +Hash+.
83
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
84
+ # to +nil+.
85
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
86
+ # +"X-API-Key"+.
86
87
  #
87
88
  # @return [RestClient::Response] The +Response+ resulting from the execution of the GET call.
88
89
  #
89
- def self.execute_head_unauthenticated(env, endpoint, uri_params, additional_headers = {})
90
- execute_rest_call(env, endpoint, nil, nil, additional_headers, uri_params) do |env, url, data, headers|
91
- if env.scheme == 'https'
92
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
93
- .head(headers)
94
- else
95
- next RestClient.head(url.to_s, headers)
96
- end
90
+ def self.execute_head_unauthenticated(env, endpoint, uri_params, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
91
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
92
+
93
+ execute_rest_call(env, endpoint, nil, nil, composite_headers, uri_params) do |env, url, data, headers|
94
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).head(headers)
97
95
  end
98
96
  end
99
97
 
@@ -109,50 +107,18 @@ module Bubbles
109
107
  # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
110
108
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
111
109
  # call. Defaults to an empty +Hash+.
110
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
111
+ # to +nil+.
112
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
113
+ # +"X-API-Key"+.
112
114
  #
113
115
  # @return [RestClient::Response] The +Response+ resulting from the execution of the HEAD call.
114
116
  #
115
- def self.execute_head_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {})
116
- execute_rest_call(env, endpoint, nil, auth_token, additional_headers, uri_params) do |env, url, data, headers|
117
- if env.scheme == 'https'
118
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
119
- .head(headers)
120
- else
121
- next RestClient.head(url.to_s, headers)
122
- end
123
- end
124
- end
125
-
126
- ##
127
- # Execute a HEAD request without authentication but with some parameters encoded in the URI string.
128
- #
129
- # @param [RestEnvironment] env The +RestEnvironment+ to use to execute the request
130
- # @param [Endpoint] endpoint The +Endpoint+ which should be requested
131
- # @param [String] api_key The API key to use to validate the client.
132
- # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
133
- # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
134
- # call. Defaults to an empty +Hash+.
135
- #
136
- # @return [RestClient::Response] The +Response+ resulting from the execution of the HEAD call.
137
- #
138
- def self.execute_head_unauthenticated_with_uri_params(env, endpoint, api_key, uri_params, additional_headers = {})
139
- composite_headers = {
140
- 'X-Api-Key' => api_key
141
- }
142
-
143
- unless additional_headers.empty?
144
- additional_headers.each { |nextHeader|
145
- composite_headers[nextHeader[0]] = nextHeader[1]
146
- }
147
- end
117
+ def self.execute_head_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
118
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
148
119
 
149
- execute_rest_call(env, endpoint, nil, nil, composite_headers, uri_params) do |env, url, data, headers|
150
- if env.scheme == 'https'
151
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
152
- .head(headers)
153
- else
154
- next RestClient.head(url.to_s, headers)
155
- end
120
+ execute_rest_call(env, endpoint, nil, auth_token, composite_headers, uri_params) do |env, url, data, headers|
121
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).head(headers)
156
122
  end
157
123
  end
158
124
 
@@ -165,27 +131,18 @@ module Bubbles
165
131
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
166
132
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
167
133
  # call. Defaults to an empty +Hash+.
134
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
135
+ # to +nil+.
136
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
137
+ # +"X-API-Key"+.
168
138
  #
169
139
  # @return [RestClient::Response] The +Response+ resulting from the execution of the POST call.
170
140
  #
171
- def self.execute_post_with_api_key(env, endpoint, api_key, data, additional_headers = {})
172
- composite_headers = {
173
- 'X-Api-Key' => api_key
174
- }
175
-
176
- unless additional_headers.nil?
177
- additional_headers.each { |nextHeader|
178
- composite_headers[nextHeader[0]] = nextHeader[1]
179
- }
180
- end
141
+ def self.execute_post_unauthenticated(env, endpoint, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
142
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
181
143
 
182
144
  execute_rest_call(env, endpoint, data, nil, composite_headers) do |env, url, data, headers|
183
- if env.scheme == 'https'
184
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
185
- .post(data.to_json, headers)
186
- else
187
- next RestClient.post url.to_s, data.to_json, headers
188
- end
145
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).post(data.to_json, headers)
189
146
  end
190
147
  end
191
148
 
@@ -199,18 +156,18 @@ module Bubbles
199
156
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
200
157
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
201
158
  # call. Defaults to an empty +Hash+.
159
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
160
+ # to +nil+.
161
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
162
+ # +"X-API-Key"+.
202
163
  #
203
164
  # @return [RestClient::Response] The +Response+ resulting from the execution of the POST call.
204
165
  #
205
- def self.execute_post_authenticated(env, endpoint, auth_token, data, additional_headers = {})
206
- return execute_rest_call(env, endpoint, data, auth_token, additional_headers) do |env, url, data, headers|
207
- if env.scheme == 'https'
208
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
209
- .post(data.to_json, headers)
166
+ def self.execute_post_authenticated(env, endpoint, auth_token, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
167
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
210
168
 
211
- else
212
- next RestClient.post(url.to_s, data.to_json, headers)
213
- end
169
+ return execute_rest_call(env, endpoint, data, auth_token, composite_headers) do |env, url, data, headers|
170
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).post(data.to_json, headers)
214
171
  end
215
172
  end
216
173
 
@@ -225,18 +182,18 @@ module Bubbles
225
182
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
226
183
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
227
184
  # call. Defaults to an empty +Hash+.
185
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
186
+ # to +nil+.
187
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
188
+ # +"X-API-Key"+.
228
189
  #
229
190
  # @return [RestClient::Response] The +Response+ resulting from the execution of the PATCH call.
230
191
  #
231
- def self.execute_patch_authenticated(env, endpoint, auth_token, uri_params, data, additional_headers = {})
232
- return execute_rest_call(env, endpoint, data, auth_token, additional_headers, uri_params) do |env, url, data, headers|
233
- if env.scheme == 'https'
234
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
235
- .patch(data.to_json, headers)
192
+ def self.execute_patch_authenticated(env, endpoint, auth_token, uri_params, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
193
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
236
194
 
237
- else
238
- next RestClient.patch(url.to_s, data.to_json, headers)
239
- end
195
+ return execute_rest_call(env, endpoint, data, auth_token, composite_headers, uri_params) do |env, url, data, headers|
196
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).patch(data.to_json, headers)
240
197
  end
241
198
  end
242
199
 
@@ -249,17 +206,18 @@ module Bubbles
249
206
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
250
207
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
251
208
  # call. Defaults to an empty +Hash+.
209
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
210
+ # to +nil+.
211
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
212
+ # +"X-API-Key"+.
252
213
  #
253
214
  # @return [RestClient::Response] The +Response+ resulting from the execution of the PATCH call.
254
215
  #
255
- def self.execute_patch_unauthenticated(env, endpoint, uri_params, data, additional_headers = {})
256
- return execute_rest_call(env, endpoint, data, nil, additional_headers, uri_params) do |env, url, data, headers|
257
- if env.scheme == 'https'
258
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
259
- .patch(data.to_json, headers)
260
- else
261
- next RestClient.patch(url.to_s, data.to_json, headers)
262
- end
216
+ def self.execute_patch_unauthenticated(env, endpoint, uri_params, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
217
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
218
+
219
+ return execute_rest_call(env, endpoint, data, nil, composite_headers, uri_params) do |env, url, data, headers|
220
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).patch(data.to_json, headers)
263
221
  end
264
222
  end
265
223
 
@@ -274,18 +232,18 @@ module Bubbles
274
232
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
275
233
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
276
234
  # call. Defaults to an empty +Hash+.
235
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
236
+ # to +nil+.
237
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
238
+ # +"X-API-Key"+.
277
239
  #
278
240
  # @return [RestClient::Response] The +Response+ resulting from the execution of the PUT call.
279
241
  #
280
- def self.execute_put_authenticated(env, endpoint, auth_token, uri_params, data, additional_headers = {})
281
- return execute_rest_call(env, endpoint, data, auth_token, additional_headers, uri_params) do |env, url, data, headers|
282
- if env.scheme == 'https'
283
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
284
- .put(data.to_json, headers)
242
+ def self.execute_put_authenticated(env, endpoint, auth_token, uri_params, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
243
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
285
244
 
286
- else
287
- next RestClient.put(url.to_s, data.to_json, headers)
288
- end
245
+ return execute_rest_call(env, endpoint, data, auth_token, composite_headers, uri_params) do |env, url, data, headers|
246
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).put(data.to_json, headers)
289
247
  end
290
248
  end
291
249
 
@@ -298,17 +256,18 @@ module Bubbles
298
256
  # @param [Hash] data A +Hash+ of key-value pairs that will be sent in the body of the http request.
299
257
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
300
258
  # call. Defaults to an empty +Hash+.
259
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
260
+ # to +nil+.
261
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
262
+ # +"X-API-Key"+.
301
263
  #
302
264
  # @return [RestClient::Response] The +Response+ resulting from the execution of the PUT call.
303
265
  #
304
- def self.execute_put_unauthenticated(env, endpoint, uri_params, data, additional_headers = {})
305
- return execute_rest_call(env, endpoint, data, nil, additional_headers, uri_params) do |env, url, data, headers|
306
- if env.scheme == 'https'
307
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
308
- .put(data.to_json, headers)
309
- else
310
- next RestClient.put(url.to_s, data.to_json, headers)
311
- end
266
+ def self.execute_put_unauthenticated(env, endpoint, uri_params, data, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
267
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
268
+
269
+ return execute_rest_call(env, endpoint, data, nil, composite_headers, uri_params) do |env, url, data, headers|
270
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).put(data.to_json, headers)
312
271
  end
313
272
  end
314
273
 
@@ -322,17 +281,41 @@ module Bubbles
322
281
  # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
323
282
  # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
324
283
  # call. Defaults to an empty +Hash+.
284
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
285
+ # to +nil+.
286
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
287
+ # +"X-API-Key"+.
325
288
  #
326
289
  # @return [RestClient::Response] The +Response+ resulting from the execution of the DELETE call.
327
290
  #
328
- def self.execute_delete_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {})
329
- execute_rest_call(env, endpoint, nil, auth_token, additional_headers, uri_params) do |env, url, data, headers|
330
- if env.scheme == 'https'
331
- next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
332
- .delete(headers)
333
- else
334
- next RestClient.delete(url.to_s, headers)
335
- end
291
+ def self.execute_delete_authenticated(env, endpoint, auth_token, uri_params, additional_headers = {}, api_key = nil, api_key_name = 'X-API-Key')
292
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
293
+
294
+ execute_rest_call(env, endpoint, nil, auth_token, composite_headers, uri_params) do |env, url, data, headers|
295
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).delete(headers)
296
+ end
297
+ end
298
+
299
+ ##
300
+ # Execute a DELETE request without authentication.
301
+ #
302
+ # @param [RestEnvironment] env The +RestEnvironment+ to use to execute the request
303
+ # @param [Endpoint] endpoint The +Endpoint+ which should be requested
304
+ # @param [Hash] uri_params A +Hash+ of identifiers to values to replace in the URI string.
305
+ # @param [Hash] additional_headers A +Hash+ of key-value pairs that will be sent as additional headers in the API
306
+ # call. Defaults to an empty +Hash+.
307
+ # @param [String] api_key (Optional) The API key to use to send to the host for unauthenticated requests. Defaults
308
+ # to +nil+.
309
+ # @param [String] api_key_name (Optional) The name of the header in which to send the API key. Defaults to
310
+ # +"X-API-Key"+.
311
+ #
312
+ # @return [RestClient::Response] The +Response+ resulting from the execution of the DELETE call.
313
+ #
314
+ def self.execute_delete_unauthenticated(env, endpoint, uri_params, additional_headers = {}, api_key = nil, api_key_name = 'X-Api-Key')
315
+ composite_headers = self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers)
316
+
317
+ execute_rest_call(env, endpoint, nil, nil, composite_headers, uri_params) do |env, url, data, headers|
318
+ next RestClient::Resource.new(url.to_s, :verify_ssl => OpenSSL::SSL::VERIFY_NONE).delete(headers)
336
319
  end
337
320
  end
338
321
 
@@ -355,8 +338,81 @@ module Bubbles
355
338
  # self.local_environment
356
339
  # end
357
340
 
341
+ ##
342
+ # Build a set of headers from two existing sets.
343
+ #
344
+ # This takes two sets of headers, as +Hash+es and merges them to create a single +Hash+ with all of the members of
345
+ # the previous two.
346
+ #
347
+ # @param [Hash] headers A set of existing headers.
348
+ # @param [Hash] additional_headers Another set of headers
349
+ #
350
+ # @return A +Hash+ containing all of the members of the input parameters. Key conflicts will be resolved to the
351
+ # benefit of +additional_headers+, meaning that whatever is in the value of the key within the
352
+ # +additional_headers+ +Hash+ will be used.
353
+ #
354
+ def self.build_composite_headers(headers, additional_headers)
355
+ composite_headers = headers
356
+
357
+ unless additional_headers.empty?
358
+ additional_headers.each { |nextHeader|
359
+ composite_headers[nextHeader[0]] = nextHeader[1]
360
+ }
361
+ end
362
+
363
+ composite_headers
364
+ end
365
+
366
+ ##
367
+ # Retrieve an encoded authorization (username and password) for a given
368
+ # +Endpoint+ and data set.
369
+ #
370
+ # @param endpoint The +Endpoint+ that this authorization will be used for.
371
+ # @param data A set of elements (typically username and password) that
372
+ # should be encoded.
373
+ #
374
+ # @return A +String+ containing an encoding of the values passed in as
375
+ # +data+, concatenated with a colon.
376
+ #
377
+ def self.get_encoded_authorization(endpoint, data)
378
+ count = 0
379
+ auth_value = ''
380
+ endpoint.encode_authorization.each { |auth_key|
381
+ if data[auth_key]
382
+ if count > 0
383
+ auth_value = auth_value + ':' + data[auth_key]
384
+ else
385
+ auth_value = data[auth_key]
386
+ end
387
+
388
+ count = count + 1
389
+
390
+ data.delete(auth_key)
391
+ end
392
+ }
393
+
394
+ auth_value
395
+ end
396
+
358
397
  private
359
398
 
399
+ def self.get_headers_with_api_key(endpoint, api_key, api_key_name, additional_headers = {})
400
+ if api_key and endpoint.api_key_required?
401
+ composite_headers = RestClientResources.build_composite_headers(additional_headers, {
402
+ api_key_name.to_s => api_key,
403
+ :content_type => :json,
404
+ :accept => :json
405
+ })
406
+ else
407
+ composite_headers = RestClientResources.build_composite_headers(additional_headers, {
408
+ :content_type => :json,
409
+ :accept => :json
410
+ })
411
+ end
412
+
413
+ composite_headers
414
+ end
415
+
360
416
  ##
361
417
  # Execute a REST call to the API.
362
418
  #
@@ -376,8 +432,12 @@ module Bubbles
376
432
  # will return an +OpenStruct+; otherwise, the +Response+ will be returned.
377
433
  #
378
434
  def self.execute_rest_call(env, endpoint, data, auth_token, headers, uri_params = {}, &block)
435
+ unless headers
436
+ raise ArgumentError.new('Expected headers to be non-nil')
437
+ end
438
+
379
439
  unless block
380
- raise ArgumentError('This method requires that a block is given.')
440
+ raise ArgumentError.new('This method requires that a block is given')
381
441
  end
382
442
 
383
443
  url = endpoint.get_expanded_url env, uri_params
@@ -387,23 +447,19 @@ module Bubbles
387
447
  data = {}
388
448
  end
389
449
 
390
- if headers == nil
391
- headers = {
392
- :content_type => :json
393
- }
394
- else
395
- headers[:content_type] = :json
396
- end
397
-
398
450
  unless auth_token == nil
399
451
  headers[:authorization] = 'Bearer ' + auth_token
400
452
  end
401
453
 
402
- headers[:accept] = :json
403
-
404
454
  response = block.call(env, url, data, headers)
405
- rescue Errno::ECONNREFUSED
455
+
456
+ rescue *[SocketError, Errno::ECONNREFUSED]
406
457
  response = { :error => 'Unable to connect to host ' + env.host.to_s + ':' + env.port.to_s }.to_json
458
+ if endpoint.return_type == :body_as_object
459
+ response = JSON.parse(response, object_class: OpenStruct)
460
+ end
461
+
462
+ return response
407
463
  end
408
464
 
409
465
  if endpoint.return_type == :body_as_object and endpoint.method != :head
@@ -415,4 +471,4 @@ module Bubbles
415
471
  response
416
472
  end
417
473
  end
418
- end
474
+ end