apipie-bindings 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff423fb9cfff64a08d97f4a3709b25e03efa1289
4
- data.tar.gz: 589750c97d73e14a76480b7f286652706fcb2871
3
+ metadata.gz: 7c09e522a914498b0cc1edbefcbcfc9a31bdde5e
4
+ data.tar.gz: 64e1e5df75c1c34e48bacfbee89b918a82d4d67b
5
5
  SHA512:
6
- metadata.gz: d98b130b8d4bfc3d0f8b8b55da47491ab310d0a3bc5a9bfc6486863d02153bcff05656584225a164e7b746b4f32dcf998fb5f38faf6e1d0faae3884878abd7f9
7
- data.tar.gz: eefe52e4281fde2e644eb2be132d2f4045d9803966f8ab4016a8f2fb1b9adb158d75ac0e29c9e35ea24e803870ee694f433c16570726aa4add3f23b2fd075522
6
+ metadata.gz: 87f289b0d316e15d468abdf01bad936c9692dd9834ac0fc8e847225f26c54400778b1c8134cf800b1dad6c4e2cb66861ca44e935d537c7d3b641e2074ac9a434
7
+ data.tar.gz: ceeeab2bf484187e116bdcf72c3f32a148e282ec3234ed59c38211b85d0a55631ebb73648067a5923c0e97db23abe86a2c8b5657aa27e9b735c3dbd7c2643a71
data/LICENSE CHANGED
@@ -1,5 +1,20 @@
1
- This program and entire repository is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
1
+ Copyright 2014 Martin Bačovský and contributors
2
2
 
3
- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
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
- You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
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
@@ -84,4 +84,4 @@ TODO
84
84
  License
85
85
  -------
86
86
 
87
- This project is licensed under the GPLv3+.
87
+ This project is licensed under the MIT license.
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
 
@@ -1,4 +1,5 @@
1
1
  require 'apipie_bindings/version'
2
+ require 'apipie_bindings/credentials'
2
3
  require 'apipie_bindings/exceptions'
3
4
  require 'apipie_bindings/inflector'
4
5
  require 'apipie_bindings/indifferent_hash'
@@ -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
- resource_config = {
83
- :user => config[:username],
84
- :password => config[:password],
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
- response = @client[path].send(*args)
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
@@ -10,6 +10,10 @@ module ApipieBindings
10
10
  @params = params
11
11
  end
12
12
 
13
+ def to_s
14
+ "#{super}: #{params.join(',')}"
15
+ end
16
+
13
17
  end
14
18
 
15
19
  end
@@ -1,5 +1,5 @@
1
1
  module ApipieBindings
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.0.10'
3
+ @version ||= Gem::Version.new '0.0.11'
4
4
  end
5
5
  end
@@ -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
@@ -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.10
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-18 00:00:00.000000000 Z
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
- - GPL-3
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