apipie-bindings 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +18 -3
- data/README.md +1 -1
- data/doc/release_notes.md +6 -0
- data/lib/apipie_bindings.rb +1 -0
- data/lib/apipie_bindings/api.rb +46 -14
- data/lib/apipie_bindings/credentials.rb +22 -0
- data/lib/apipie_bindings/exceptions.rb +4 -0
- data/lib/apipie_bindings/version.rb +1 -1
- data/test/unit/action_test.rb +4 -2
- data/test/unit/api_test.rb +48 -5
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c09e522a914498b0cc1edbefcbcfc9a31bdde5e
|
4
|
+
data.tar.gz: 64e1e5df75c1c34e48bacfbee89b918a82d4d67b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87f289b0d316e15d468abdf01bad936c9692dd9834ac0fc8e847225f26c54400778b1c8134cf800b1dad6c4e2cb66861ca44e935d537c7d3b641e2074ac9a434
|
7
|
+
data.tar.gz: ceeeab2bf484187e116bdcf72c3f32a148e282ec3234ed59c38211b85d0a55631ebb73648067a5923c0e97db23abe86a2c8b5657aa27e9b735c3dbd7c2643a71
|
data/LICENSE
CHANGED
@@ -1,5 +1,20 @@
|
|
1
|
-
|
1
|
+
Copyright 2014 Martin Bačovský and contributors
|
2
2
|
|
3
|
-
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
4
10
|
|
5
|
-
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
data/doc/release_notes.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
3
|
|
4
|
+
### 0.0.11 (2014-11-09)
|
5
|
+
* Added lazy loading of credentials ([#7408](http://projects.theforeman.org/issues/7408))
|
6
|
+
* Separate caches for different API versions ([#18](http://github.com/Apipie/apipie-bindings/issues/18))
|
7
|
+
* Change license to MIT
|
8
|
+
* List missing parameter names in validation exception message
|
9
|
+
|
4
10
|
### 0.0.10 (2014-09-18)
|
5
11
|
* apipie-bindings should enforce required params, BZ 1116803 ([#6820](http://projects.theforeman.org/issues/6820))
|
6
12
|
|
data/lib/apipie_bindings.rb
CHANGED
data/lib/apipie_bindings/api.rb
CHANGED
@@ -21,6 +21,10 @@ module ApipieBindings
|
|
21
21
|
# * *:consumer_key* (String) OAuth key
|
22
22
|
# * *:consumer_secret* (String) OAuth secret
|
23
23
|
# * *:options* (Hash) options passed to OAuth
|
24
|
+
# @option config [AbstractCredentials] :credentials object implementing {AbstractCredentials}
|
25
|
+
# interface e.g. {https://github.com/theforeman/hammer-cli-foreman/blob/master/lib/hammer_cli_foreman/credentials.rb HammerCLIForeman::BasicCredentials}
|
26
|
+
# This is prefered way to pass credentials. Credentials acquired form :credentials object take
|
27
|
+
# precedence over explicite params
|
24
28
|
# @option config [Hash] :headers additional headers to send with the requests
|
25
29
|
# @option config [String] :api_version ('1') version of the API
|
26
30
|
# @option config [String] :language prefered locale for the API description
|
@@ -30,6 +34,9 @@ module ApipieBindings
|
|
30
34
|
# to cache the JSON description of the API
|
31
35
|
# @option config [String] :apidoc_cache_name ('default.json') name of te cache file.
|
32
36
|
# If there is cache in the :apidoc_cache_dir, it is used.
|
37
|
+
# @option config [String] :apidoc_authenticated (true) whether or not does the call to
|
38
|
+
# obtain API description use authentication. It is useful to avoid unnecessary prompts
|
39
|
+
# for credentials
|
33
40
|
# @option config [Hash] :fake_responses ({}) responses to return if used in dry run mode
|
34
41
|
# @option config [Bool] :dry_run (false) dry run mode allows to test your scripts
|
35
42
|
# and not touch the API. The results are taken form exemples in the API description
|
@@ -56,8 +63,9 @@ module ApipieBindings
|
|
56
63
|
@api_version = config[:api_version] || 1
|
57
64
|
@language = config[:language]
|
58
65
|
apidoc_cache_base_dir = config[:apidoc_cache_base_dir] || File.join(File.expand_path('~/.cache'), 'apipie_bindings')
|
59
|
-
@apidoc_cache_dir = config[:apidoc_cache_dir] || File.join(apidoc_cache_base_dir, @uri.tr(':/', '_'))
|
66
|
+
@apidoc_cache_dir = config[:apidoc_cache_dir] || File.join(apidoc_cache_base_dir, @uri.tr(':/', '_'), "v#{@api_version}")
|
60
67
|
@apidoc_cache_name = config[:apidoc_cache_name] || set_default_name
|
68
|
+
@apidoc_authenticated = (config[:apidoc_authenticated].nil? ? true : config[:apidoc_authenticated])
|
61
69
|
@dry_run = config[:dry_run] || false
|
62
70
|
@aggressive_cache_checking = config[:aggressive_cache_checking] || false
|
63
71
|
@fake_responses = config[:fake_responses] || {}
|
@@ -79,15 +87,13 @@ module ApipieBindings
|
|
79
87
|
|
80
88
|
log.debug "Global headers: #{headers.ai}"
|
81
89
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
:oauth => config[:oauth],
|
90
|
+
@credentials = config[:credentials] if config[:credentials] && config[:credentials].respond_to?(:to_params)
|
91
|
+
|
92
|
+
@resource_config = {
|
86
93
|
:timeout => config[:timeout],
|
87
94
|
:headers => headers
|
88
95
|
}.merge(options)
|
89
96
|
|
90
|
-
@client = RestClient::Resource.new(config[:uri], resource_config)
|
91
97
|
@config = config
|
92
98
|
end
|
93
99
|
|
@@ -141,6 +147,7 @@ module ApipieBindings
|
|
141
147
|
# @param [Hash] headers extra headers to be sent with the request
|
142
148
|
# @param [Hash] options options to influence the how the call is processed
|
143
149
|
# * *:response* (Symbol) *:raw* - skip parsing JSON in response
|
150
|
+
# * *:with_authentication* (Bool) *true* - use rest client with/without auth configuration
|
144
151
|
# @example show user data
|
145
152
|
# call(:users, :show, :id => 1)
|
146
153
|
def call(resource_name, action_name, params={}, headers={}, options={})
|
@@ -166,6 +173,7 @@ module ApipieBindings
|
|
166
173
|
# @param [Hash] options options to influence the how the call is processed
|
167
174
|
# * *:response* (Symbol) *:raw* - skip parsing JSON in response
|
168
175
|
# * *:reduce_response_log* (Bool) - do not show response content in the log.
|
176
|
+
# * *:with_authentication* (Bool) *true* - use rest client with/without auth configuration
|
169
177
|
# @example show user data
|
170
178
|
# http_call('get', '/api/users/1')
|
171
179
|
def http_call(http_method, path, params={}, headers={}, options={})
|
@@ -196,7 +204,10 @@ module ApipieBindings
|
|
196
204
|
response = RestClient::Response.create(ex.response, net_http_resp, args)
|
197
205
|
else
|
198
206
|
begin
|
199
|
-
|
207
|
+
apidoc_without_auth = (path =~ /\/apidoc\//) && !@apidoc_authenticated
|
208
|
+
authenticate = options[:with_authentication].nil? ? !apidoc_without_auth : options[:with_authentication]
|
209
|
+
client = authenticate ? authenticated_client : unauthenticated_client
|
210
|
+
response = call_client(client, path, args)
|
200
211
|
update_cache(response.headers[:apipie_checksum])
|
201
212
|
rescue => e
|
202
213
|
log.debug e.message + "\n" +
|
@@ -227,19 +238,13 @@ module ApipieBindings
|
|
227
238
|
|
228
239
|
def check_cache
|
229
240
|
begin
|
230
|
-
response = http_call('get', "/apidoc/apipie_checksum", {}, {:accept => "application/json"})
|
241
|
+
response = http_call('get', "/apidoc/apipie_checksum", {}, { :accept => "application/json" })
|
231
242
|
response['checksum']
|
232
243
|
rescue
|
233
244
|
nil
|
234
245
|
end
|
235
246
|
end
|
236
247
|
|
237
|
-
def log
|
238
|
-
@logger
|
239
|
-
end
|
240
|
-
|
241
|
-
private
|
242
|
-
|
243
248
|
def retrieve_apidoc
|
244
249
|
FileUtils.mkdir_p(@apidoc_cache_dir) unless File.exists?(@apidoc_cache_dir)
|
245
250
|
if language
|
@@ -264,6 +269,33 @@ module ApipieBindings
|
|
264
269
|
load_apidoc
|
265
270
|
end
|
266
271
|
|
272
|
+
def log
|
273
|
+
@logger
|
274
|
+
end
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def call_client(client, path, args)
|
279
|
+
client[path].send(*args)
|
280
|
+
end
|
281
|
+
|
282
|
+
def authenticated_client
|
283
|
+
unless @client_with_auth
|
284
|
+
resource_config = @resource_config.merge({
|
285
|
+
:user => @config[:username],
|
286
|
+
:password => @config[:password],
|
287
|
+
:oauth => @config[:oauth],
|
288
|
+
})
|
289
|
+
resource_config.merge!(@credentials.to_params) if @credentials
|
290
|
+
@client_with_auth = RestClient::Resource.new(@config[:uri], resource_config)
|
291
|
+
end
|
292
|
+
@client_with_auth
|
293
|
+
end
|
294
|
+
|
295
|
+
def unauthenticated_client
|
296
|
+
@client_without_auth ||= RestClient::Resource.new(@config[:uri], @resource_config)
|
297
|
+
end
|
298
|
+
|
267
299
|
def retrieve_apidoc_call(path, options={})
|
268
300
|
begin
|
269
301
|
http_call('get', path, {},
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ApipieBindings
|
2
|
+
|
3
|
+
# AbstractCredentials class can hold your logic to get
|
4
|
+
# users credentials. It defines interface that can be used
|
5
|
+
# by ApipieBindings when the credentials are needed to create connection
|
6
|
+
class AbstractCredentials
|
7
|
+
|
8
|
+
# Convert credentials to hash usable for merging to RestClient configuration
|
9
|
+
# @return [Hash]
|
10
|
+
def to_params
|
11
|
+
{}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Check that credentials storage is empty
|
15
|
+
def empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Clear credentials storage
|
19
|
+
def clear
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/test/unit/action_test.rb
CHANGED
@@ -42,14 +42,16 @@ describe ApipieBindings::Action do
|
|
42
42
|
|
43
43
|
|
44
44
|
it "should validate incorrect params" do
|
45
|
-
proc do
|
45
|
+
e = proc do
|
46
46
|
resource.action(:create).validate!({ :architecture => { :foo => "foo" } })
|
47
47
|
end.must_raise(ApipieBindings::MissingArgumentsError)
|
48
|
+
e.message.must_match /: name$/
|
48
49
|
|
49
|
-
proc do
|
50
|
+
e = proc do
|
50
51
|
# completely different sub-hash; should still fail
|
51
52
|
resource.action(:create).validate!({ :organization => { :name => "acme" } })
|
52
53
|
end.must_raise(ApipieBindings::MissingArgumentsError)
|
54
|
+
e.message.must_match /: name$/
|
53
55
|
end
|
54
56
|
|
55
57
|
it "should accept correct params" do
|
data/test/unit/api_test.rb
CHANGED
@@ -17,9 +17,6 @@ describe ApipieBindings::API do
|
|
17
17
|
api.resources.map(&:name).must_equal [:architectures]
|
18
18
|
end
|
19
19
|
|
20
|
-
# it "should have apidoc_cache_file available" do
|
21
|
-
# end
|
22
|
-
|
23
20
|
it "should call the method" do
|
24
21
|
params = { :a => 1 }
|
25
22
|
headers = { :content_type => 'application/json' }
|
@@ -143,8 +140,54 @@ describe ApipieBindings::API do
|
|
143
140
|
|
144
141
|
it "should obey :apidoc_cache_base_dir to generate apidoc_cache_dir" do
|
145
142
|
Dir.mktmpdir do |dir|
|
146
|
-
api = ApipieBindings::API.new({:uri => 'http://example.com', :apidoc_cache_base_dir => dir})
|
147
|
-
api.apidoc_cache_file.must_equal File.join(dir, 'http___example.com', 'default.json')
|
143
|
+
api = ApipieBindings::API.new({:uri => 'http://example.com', :apidoc_cache_base_dir => dir, :api_version => 2})
|
144
|
+
api.apidoc_cache_file.must_equal File.join(dir, 'http___example.com', 'v2', 'default.json')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "credentials" do
|
150
|
+
|
151
|
+
let(:fake_empty_response) {
|
152
|
+
data = ApipieBindings::Example.new('', '', '', 200, '[]')
|
153
|
+
net_http_resp = Net::HTTPResponse.new(1.0, data.status, "")
|
154
|
+
RestClient::Response.create(data.response, net_http_resp, {})
|
155
|
+
}
|
156
|
+
|
157
|
+
it "should call credentials to_param when :credentials are set and doing authenticated call" do
|
158
|
+
Dir.mktmpdir do |dir|
|
159
|
+
credentials = ApipieBindings::AbstractCredentials.new
|
160
|
+
api = ApipieBindings::API.new({
|
161
|
+
:uri => 'http://example.com', :apidoc_cache_base_dir => dir, :api_version => 2,
|
162
|
+
:credentials => credentials})
|
163
|
+
credentials.expects(:to_params).returns({:password => 'xxx'})
|
164
|
+
api.stubs(:call_client).returns(fake_empty_response)
|
165
|
+
|
166
|
+
api.http_call(:get, '/path')
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should not require credentials for loading apidoc when :apidoc_authenticated => false" do
|
171
|
+
Dir.mktmpdir do |dir|
|
172
|
+
api = ApipieBindings::API.new({
|
173
|
+
:uri => 'http://example.com', :apidoc_cache_base_dir => dir, :api_version => 2,
|
174
|
+
:apidoc_authenticated => false })
|
175
|
+
api.expects(:unauthenticated_client)
|
176
|
+
api.stubs(:call_client).returns(fake_empty_response)
|
177
|
+
|
178
|
+
api.retrieve_apidoc
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should not require credentials for loading checksum when :apidoc_authenticated => false" do
|
183
|
+
Dir.mktmpdir do |dir|
|
184
|
+
api = ApipieBindings::API.new({
|
185
|
+
:uri => 'http://example.com', :apidoc_cache_base_dir => dir, :api_version => 2,
|
186
|
+
:apidoc_authenticated => false })
|
187
|
+
api.expects(:unauthenticated_client)
|
188
|
+
api.stubs(:call_client).returns(fake_empty_response)
|
189
|
+
|
190
|
+
api.check_cache
|
148
191
|
end
|
149
192
|
end
|
150
193
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apipie-bindings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Bačovský
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09
|
11
|
+
date: 2014-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -206,6 +206,7 @@ files:
|
|
206
206
|
- lib/apipie_bindings.rb
|
207
207
|
- lib/apipie_bindings/action.rb
|
208
208
|
- lib/apipie_bindings/api.rb
|
209
|
+
- lib/apipie_bindings/credentials.rb
|
209
210
|
- lib/apipie_bindings/example.rb
|
210
211
|
- lib/apipie_bindings/exceptions.rb
|
211
212
|
- lib/apipie_bindings/indifferent_hash.rb
|
@@ -229,7 +230,7 @@ files:
|
|
229
230
|
- test/unit/test_helper.rb
|
230
231
|
homepage: http://github.com/Apipie/apipie-bindings
|
231
232
|
licenses:
|
232
|
-
-
|
233
|
+
- MIT
|
233
234
|
metadata: {}
|
234
235
|
post_install_message:
|
235
236
|
rdoc_options: []
|
@@ -263,4 +264,3 @@ test_files:
|
|
263
264
|
- test/unit/resource_test.rb
|
264
265
|
- test/unit/route_test.rb
|
265
266
|
- test/unit/test_helper.rb
|
266
|
-
has_rdoc: yard
|