bubbles-rest-client 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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