flexirest 1.10.3 → 1.10.4

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
  SHA256:
3
- metadata.gz: 53b34d9600101b9d80a61559054a3599242a7739b12845df02bde410c5858d94
4
- data.tar.gz: e7398bcc97a8a0f89fb3380110e126e482d5fc1e14a973dd9e34208f28634814
3
+ metadata.gz: 9a072753fe6a84d8f13ae90d26cdff777e78fc129d4555b5188ae0c0be35ad78
4
+ data.tar.gz: 7e6ecfe247cc9f021a3e35f9cf4d3b28a6743694b53a2ca32c0ea988a2113276
5
5
  SHA512:
6
- metadata.gz: 32014dfe143032f040ae140cdcf562f05832f74d0b05e692b8f866d4636363b6f7ffcbe0a4de0e7a895c8b1722aef0f6736f34c130916dc5c02869caa198434a
7
- data.tar.gz: a7f3cb00fd3451c4f06ef32bf6e148f90d4046c1cce7526a8bfe6c247e2d65dcd68a0d924f85683ef052929432ddf341768578a7591b37db8b7729ed96053c80
6
+ metadata.gz: 561fdb72c84a9bd3d0a353f46d4761179df66f3e45967bec4b4b620c6f818dca0058388b5f83c2d2455da1f21fa90a72ec0f73ab056fbf086dab522cc8f48fd7
7
+ data.tar.gz: 95d6f2852392a23c82a5ae0e157a9ad1bc391c4846e79946eab75236c1c3b409c8193a3550e42b9e19676b94a3cccda28e6f0ddf438e47b3e77de9c66669006a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.4
4
+
5
+ Enhancement:
6
+
7
+ - Implement support for in-header Basic Auth (thanks to François Ferrandis for the PR)
8
+
3
9
  ## 1.10.3
4
10
 
5
11
  Enhancement:
@@ -40,6 +40,30 @@ Or if it's called from a class context:
40
40
  Person.find(id: 1234)
41
41
  ```
42
42
 
43
+ ### Basic authentication method
44
+
45
+ Flexirest provides two methods for HTTP Basic Auth. The default method is `:url`:
46
+
47
+ ```ruby
48
+ class Person < Flexirest::Base
49
+ basic_auth_method :url
50
+ end
51
+ # Includes the credentials in the URL:
52
+ # https://my_username:my_password@example.com/
53
+ ```
54
+
55
+ But you might want to keep the credentials out of your logs and use the `:header` method:
56
+
57
+ ```ruby
58
+ class Person < Flexirest::Base
59
+ basic_auth_method :header
60
+ end
61
+ # Clean URL:
62
+ # https://example.com/
63
+ # with the base64 encoded credentials:
64
+ # Authorization: Basic YXBpOmViNjkzZWMtODI1MmMtZDYzMDEtMDJmZDAtZDBmYjctYzM0ODU=
65
+ ```
66
+
43
67
  ## Api-Auth
44
68
 
45
69
  Using the [Api-Auth](https://github.com/mgomes/api_auth) integration it is very easy to sign requests. Include the Api-Auth gem in your `Gemfile` and then add it to your application. Then simply configure Api-Auth one time in your app and all requests will be signed from then on.
data/docs/raw-requests.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # *Flexirest:* Raw requests
2
2
 
3
- Sometimes you have have a URL that you just want to force through, but have the response handled in the same way as normal objects or you want to have the callbacks run (say for authentication). The easiest way to do that is to call `_request` on the class:
3
+ Sometimes you have a URL that you just want to force through, but have the response handled in the same way as normal objects or you want to have the callbacks run (say for authentication). The easiest way to do that is to call `_request` on the class:
4
4
 
5
5
  ```ruby
6
6
  class Person < Flexirest::Base
@@ -135,6 +135,23 @@ module Flexirest
135
135
  @@password = value
136
136
  end
137
137
 
138
+ DEFAULT_BASIC_URL_METHOD = :url
139
+
140
+ def basic_auth_method(value = nil)
141
+ if value.nil? # Used as a getter method
142
+ if @basic_auth_method.nil? && superclass.respond_to?(:basic_auth_method)
143
+ superclass.basic_auth_method
144
+ else
145
+ @basic_auth_method || DEFAULT_BASIC_URL_METHOD
146
+ end
147
+ else # Used as a setter method
148
+ unless [:header, :url].include?(value)
149
+ raise %(Invalid basic_auth_method #{value.inspect}. Valid methods are :url (default) and :header.)
150
+ end
151
+ @basic_auth_method = value
152
+ end
153
+ end
154
+
138
155
  def alias_type(value = nil)
139
156
  @alias_type ||= nil
140
157
  if value.nil?
@@ -311,6 +328,7 @@ module Flexirest
311
328
  @adapter = Faraday.default_adapter
312
329
  @api_auth_access_id = nil
313
330
  @api_auth_secret_key = nil
331
+ @basic_auth_method = :url
314
332
  end
315
333
 
316
334
  private
@@ -32,6 +32,10 @@ module Flexirest
32
32
  !@object.respond_to?(:dirty?)
33
33
  end
34
34
 
35
+ def model_class
36
+ object_is_class? ? @object : @object.class
37
+ end
38
+
35
39
  def class_name
36
40
  if object_is_class?
37
41
  @object.name
@@ -124,6 +128,18 @@ module Flexirest
124
128
  ret
125
129
  end
126
130
 
131
+ def inject_basic_auth_in_url(url)
132
+ url.gsub!(%r{//(.)}, "//#{username}:#{password}@\\1") if !url[%r{//[^/]*:[^/]*@}]
133
+ end
134
+
135
+ def using_basic_auth?
136
+ !!username
137
+ end
138
+
139
+ def basic_auth_digest
140
+ Base64.strict_encode64("#{username}:#{password}")
141
+ end
142
+
127
143
  def request_body_type
128
144
  if @method[:options][:request_body_type]
129
145
  @method[:options][:request_body_type]
@@ -527,7 +543,9 @@ module Flexirest
527
543
  else
528
544
  _, @base_url, @url = parts
529
545
  end
530
- base_url.gsub!(%r{//(.)}, "//#{username}:#{password}@\\1") if username && !base_url[%r{//[^/]*:[^/]*@}]
546
+ if using_basic_auth? && model_class.basic_auth_method == :url
547
+ inject_basic_auth_in_url(base_url)
548
+ end
531
549
  connection = Flexirest::ConnectionManager.get_connection(base_url)
532
550
  end
533
551
  else
@@ -540,7 +558,9 @@ module Flexirest
540
558
  else
541
559
  base_url = parts[0]
542
560
  end
543
- base_url.gsub!(%r{//(.)}, "//#{username}:#{password}@\\1") if username && !base_url[%r{//[^/]*:[^/]*@}]
561
+ if using_basic_auth? && model_class.basic_auth_method == :url
562
+ inject_basic_auth_in_url(base_url)
563
+ end
544
564
  connection = Flexirest::ConnectionManager.get_connection(base_url)
545
565
  end
546
566
  if @method[:options][:direct]
@@ -566,6 +586,8 @@ module Flexirest
566
586
  :api_auth_secret_key => api_auth_secret_key,
567
587
  :api_auth_options => api_auth_options
568
588
  }
589
+ elsif using_basic_auth? && model_class.basic_auth_method == :header
590
+ http_headers["Authorization"] = "Basic #{basic_auth_digest}"
569
591
  end
570
592
  if @method[:options][:timeout]
571
593
  request_options[:timeout] = @method[:options][:timeout]
@@ -1,3 +1,3 @@
1
1
  module Flexirest
2
- VERSION = "1.10.3"
2
+ VERSION = "1.10.4"
3
3
  end
@@ -81,6 +81,26 @@ describe Flexirest::Request do
81
81
  get :all, "/"
82
82
  end
83
83
 
84
+ class AuthenticatedBasicHeaderExampleClient < Flexirest::Base
85
+ base_url "http://www.example.com"
86
+ username "john"
87
+ password "smith"
88
+ basic_auth_method :header
89
+ get :all, "/"
90
+ end
91
+
92
+ class AuthenticatedBasicHeaderExampleClientChildClass < AuthenticatedBasicHeaderExampleClient
93
+ get :child_method, "/"
94
+ end
95
+
96
+ class AuthenticatedBasicUrlExampleClient < Flexirest::Base
97
+ base_url "http://www.example.com"
98
+ username "john"
99
+ password "smith"
100
+ basic_auth_method :url
101
+ get :all, "/"
102
+ end
103
+
84
104
  class AuthenticatedProcExampleClient < Flexirest::Base
85
105
  base_url "http://www.example.com"
86
106
  username Proc.new { |obj| obj ? "bill-#{obj.id}" : "bill" }
@@ -314,13 +334,53 @@ describe Flexirest::Request do
314
334
  expect(servers.uniq.count).to eq(2)
315
335
  end
316
336
 
317
- it "should get an HTTP connection with authentication when called" do
337
+ it "should use the URL method for Basic HTTP Auth when no basic_auth_method is set" do
338
+ mocked_response = ::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{}))
339
+
318
340
  connection = double(Flexirest::Connection).as_null_object
319
341
  expect(Flexirest::ConnectionManager).to receive(:get_connection).with("http://john:smith@www.example.com").and_return(connection)
320
- expect(connection).to receive(:get).with("/", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{})))
342
+ expect(connection).to receive(:get).with("/", an_instance_of(Hash)).and_return(mocked_response)
321
343
  AuthenticatedExampleClient.all
322
344
  end
323
345
 
346
+ it "should use the headers method for Basic auth when basic_auth_method is set to :header" do
347
+ mocked_response = ::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{}))
348
+ headers_including_auth = hash_including({ "Authorization" => "Basic am9objpzbWl0aA==" })
349
+
350
+ connection = double(Flexirest::Connection).as_null_object
351
+ expect(Flexirest::ConnectionManager).to receive(:get_connection).with("http://www.example.com").and_return(connection)
352
+ expect(connection).to receive(:get).with("/", hash_including(headers: headers_including_auth)).and_return(mocked_response)
353
+ AuthenticatedBasicHeaderExampleClient.all
354
+ end
355
+
356
+ it "should raise an error if Basic HTTP method is not :header or :url" do
357
+ expect do
358
+ AuthenticatedExampleClient.class_eval do
359
+ basic_auth_method :some_invalid_value
360
+ end
361
+ end.to raise_error(RuntimeError, "Invalid basic_auth_method :some_invalid_value. Valid methods are :url (default) and :header.")
362
+ end
363
+
364
+ it "should use the setting set on the parent class" do
365
+ mocked_response = ::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{}))
366
+ headers_including_auth = hash_including({ "Authorization" => "Basic am9objpzbWl0aA==" })
367
+
368
+ connection = double(Flexirest::Connection).as_null_object
369
+ expect(Flexirest::ConnectionManager).to receive(:get_connection).with("http://www.example.com").and_return(connection)
370
+ expect(connection).to receive(:get).with("/", hash_including(headers: headers_including_auth)).and_return(mocked_response)
371
+ AuthenticatedBasicHeaderExampleClientChildClass.child_method
372
+ end
373
+
374
+ it "should use the URL method for Basic auth when basic_auth_method is set to :url (and not include Authorization header)" do
375
+ mocked_response = ::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{}))
376
+ headers_not_including_auth = hash_excluding("Authorization")
377
+
378
+ connection = double(Flexirest::Connection).as_null_object
379
+ expect(Flexirest::ConnectionManager).to receive(:get_connection).with("http://john:smith@www.example.com").and_return(connection)
380
+ expect(connection).to receive(:get).with("/", headers: headers_not_including_auth).and_return(mocked_response)
381
+ AuthenticatedBasicUrlExampleClient.all
382
+ end
383
+
324
384
  it "should get an HTTP connection with basic authentication using procs when called in a class context" do
325
385
  connection = double(Flexirest::Connection).as_null_object
326
386
  expect(Flexirest::ConnectionManager).to receive(:get_connection).with("http://bill:jones@www.example.com").and_return(connection)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flexirest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.3
4
+ version: 1.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jeffries
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-25 00:00:00.000000000 Z
11
+ date: 2021-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler