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