oauth2_api_client 3.1.1 → 3.3.0

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: 33e0e15f43fe027760355c1a403da0d02b30412b064984102234744fc8da65b7
4
- data.tar.gz: bf10a1428e0a797daa31f32b7712d2525eddab710c2ba12d244e95b968489314
3
+ metadata.gz: b846fd82d5e91d799c60adb483691d92a8ee508e3d602c624f9dea0f7d924af5
4
+ data.tar.gz: 983f980480afb33623d5733ab5cafc019d6e9e2b93048cd5f6a3e9536acd7dc8
5
5
  SHA512:
6
- metadata.gz: 46dbbbd595379cc1217f272247149d0ce8084651704c2264301e28dcc8ece22b2c8cc2b9b108d38140eaf1f46145cfde1fb600e24a5434f00a013948e79b22c3
7
- data.tar.gz: d3b38d88ac90e9550971f5320b5cca814be87ade495a8bd999047faebd310f41beecbe45ac16e35fd2ba1e54bbea7b443f13f670e1c119e3a08931b6ea7476ef
6
+ metadata.gz: 457d37f335df145f62464d7d380fbf2506bd8003ef38e2f471073513a38851dbe8ef5ad78d9763065e4bb0fa48f83fff832686705c50005b49f26a92c0c41e41
7
+ data.tar.gz: 4b8f9a70d1afc7de2890196d34bef86e1006dae031ea60b7cef075442281bad8f3a3156bbb33fece19de67fcff404fbfdd834518388ac37f315daba4e7ea4b27
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
 
2
2
  # CHANGELOG
3
3
 
4
+ # v3.3.0
5
+
6
+ * Add Oauth2ApiClient#params to set default query params
7
+
8
+ # v3.2.1
9
+
10
+ * Fix thread safety issue of http-rb
11
+
12
+ # v3.2.0
13
+
14
+ * Allow passing `nil` as token for unprotected APIs
15
+
4
16
  # v3.1.1
5
17
 
6
18
  * Added oauth2 version constraint
data/README.md CHANGED
@@ -16,6 +16,13 @@ client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/or
16
16
  # ...
17
17
  ```
18
18
 
19
+ In case an API is unprotected and you still want to use Oauth2ApiClient, you
20
+ can simply not pass any token:
21
+
22
+ ```ruby
23
+ client = Oauth2ApiClient.new(base_url: "...")
24
+ ```
25
+
19
26
  Oauth2ApiClient is capable of generating oauth2 tokens, when a client id,
20
27
  client secret and oauth token url is given with automatic token caching and
21
28
  renewal on expiry, including retry of the current request.
@@ -39,6 +46,17 @@ specifically, it will e.g. raise `Oauth2ApiClient::ResponseError::NotFound` for
39
46
  a 404 status code, `Oauth2ApiClient::ResponseError::InternalServerError` for a
40
47
  500 status code, etc.
41
48
 
49
+ ## Default query params
50
+
51
+ In addition to the DSL of http-rb Oauth2ApiClient allows to set default query
52
+ params, which can be useful for some APIs:
53
+
54
+ ```ruby
55
+ client = Oauth2ApiClient.new(base_url: "https://api.example.com").params(key1: "value1")
56
+ client.get("/path", params: { key2: "value" })
57
+ #=> GET https://api.example.com/path?key1=value1&key2=value2
58
+ ```
59
+
42
60
  ## Install
43
61
 
44
62
  Add this line to your application's Gemfile:
@@ -1,3 +1,3 @@
1
1
  class Oauth2ApiClient
2
- VERSION = "3.1.1"
2
+ VERSION = "3.3.0"
3
3
  end
@@ -40,7 +40,7 @@ class Oauth2ApiClient
40
40
  # )
41
41
  # )
42
42
 
43
- def initialize(base_url:, token:, base_request: HTTP)
43
+ def initialize(base_url:, token: nil, base_request: HTTP)
44
44
  @base_url = base_url
45
45
  @token = token
46
46
  @request = base_request
@@ -51,9 +51,17 @@ class Oauth2ApiClient
51
51
  # @return [String] The token
52
52
 
53
53
  def token
54
+ return if @token.nil?
55
+
54
56
  @token.respond_to?(:to_str) ? @token.to_str : @token.token
55
57
  end
56
58
 
59
+ def params(parms = {})
60
+ dup.tap do |client|
61
+ client.instance_variable_set(:@params, (@params || {}).merge(parms))
62
+ end
63
+ end
64
+
57
65
  [:timeout, :headers, :cookies, :via, :encoding, :accept, :auth, :basic_auth].each do |method|
58
66
  define_method method do |*args|
59
67
  dup.tap do |client|
@@ -74,7 +82,14 @@ class Oauth2ApiClient
74
82
 
75
83
  def execute(verb, path, options = {})
76
84
  with_retry do
77
- response = @request.auth("Bearer #{token}").send(verb, "#{@base_url}#{path}", options)
85
+ request = @request
86
+ request = request.headers({}) # Prevent thread-safety issue of http-rb: https://github.com/httprb/http/issues/558
87
+ request = request.auth("Bearer #{token}") if token
88
+
89
+ opts = options.dup
90
+ opts[:params] = @params.merge(opts.fetch(:params, {})) if @params
91
+
92
+ response = request.send(verb, "#{@base_url}#{path}", opts)
78
93
 
79
94
  return response if response.status.success?
80
95
 
@@ -15,7 +15,6 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
20
  spec.add_development_dependency "bundler"
@@ -51,6 +51,62 @@ RSpec.describe Oauth2ApiClient do
51
51
  end
52
52
  end
53
53
 
54
+ describe "#params" do
55
+ it "creates a dupped instance" do
56
+ client = described_class.new(base_url: "http://localhost")
57
+
58
+ client1 = client.params(key1: "value1")
59
+ client2 = client1.params(key2: "value2")
60
+
61
+ expect(client1.object_id).not_to eq(client2.object_id)
62
+ end
63
+
64
+ it "merges the params" do
65
+ client = described_class.new(base_url: "http://localhost")
66
+
67
+ client1 = client.params(key1: "value1")
68
+ client2 = client1.params(key2: "value2")
69
+
70
+ expect(client2.instance_variable_get(:@params)).to eq(key1: "value1", key2: "value2")
71
+ end
72
+
73
+ it "merges the params with passed params in requests" do
74
+ stub_request(:get, "http://localhost/api/path?key1=value1&key2=value2")
75
+ .to_return(status: 200, body: "ok")
76
+
77
+ client = described_class.new(base_url: "http://localhost/api", token: "token").params(key1: "value1")
78
+
79
+ expect(client.get("/path", params: { key2: "value2" }).to_s).to eq("ok")
80
+ end
81
+
82
+ it "overwrites the default params when neccessary" do
83
+ stub_request(:get, "http://localhost/api/path?key=value2")
84
+ .to_return(status: 200, body: "ok")
85
+
86
+ client = described_class.new(base_url: "http://localhost/api", token: "token").params(key: "value1")
87
+
88
+ expect(client.get("/path", params: { key: "value2" }).to_s).to eq("ok")
89
+ end
90
+
91
+ it "passes the default params only when no params are given" do
92
+ stub_request(:get, "http://localhost/api/path?key=value")
93
+ .to_return(status: 200, body: "ok")
94
+
95
+ client = described_class.new(base_url: "http://localhost/api", token: "token").params(key: "value")
96
+
97
+ expect(client.get("/path").to_s).to eq("ok")
98
+ end
99
+
100
+ it "passes the params only when no default params are given" do
101
+ stub_request(:get, "http://localhost/api/path?key=value")
102
+ .to_return(status: 200, body: "ok")
103
+
104
+ client = described_class.new(base_url: "http://localhost/api", token: "token")
105
+
106
+ expect(client.get("/path", params: { key: "value" }).to_s).to eq("ok")
107
+ end
108
+ end
109
+
54
110
  [:timeout, :headers, :cookies, :via, :encoding, :accept, :auth, :basic_auth].each do |method|
55
111
  describe "##{method}" do
56
112
  it "creates a dupped instance" do
@@ -84,7 +140,7 @@ RSpec.describe Oauth2ApiClient do
84
140
  expect(client.get("/path", params: { key: "value" }).to_s).to eq("ok")
85
141
  end
86
142
 
87
- it "passes the token in the authentication header" do
143
+ it "passes the token in the authorization header" do
88
144
  stub_request(:get, "http://localhost/api/path")
89
145
  .with(headers: { "Authorization" => "Bearer access_token" })
90
146
  .to_return(status: 200, body: "ok", headers: {})
@@ -94,6 +150,16 @@ RSpec.describe Oauth2ApiClient do
94
150
  expect(client.get("/path").to_s).to eq("ok")
95
151
  end
96
152
 
153
+ it "does not pass any authorization header when no token is provided" do
154
+ stub_request(:get, "http://localhost/api/path")
155
+ .with { |request| !request.headers.keys.map(&:to_s).map(&:downcase).include?("authorization") }
156
+ .to_return(status: 200, body: "ok", headers: {})
157
+
158
+ client = described_class.new(base_url: "http://localhost/api")
159
+
160
+ expect(client.get("/path").to_s).to eq("ok")
161
+ end
162
+
97
163
  it "retries the request when an http unauthorized status is returned" do
98
164
  stub_request(:get, "http://localhost/api/path")
99
165
  .to_return({ status: 401, body: "unauthorized" }, { status: 200, body: "ok" })
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth2_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-17 00:00:00.000000000 Z
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -184,8 +184,4 @@ rubygems_version: 3.3.3
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: Small but powerful client around oauth2 and http-rb to interact with APIs
187
- test_files:
188
- - spec/oauth2_api_client/response_error_spec.rb
189
- - spec/oauth2_api_client/token_provider_spec.rb
190
- - spec/oauth2_api_client_spec.rb
191
- - spec/spec_helper.rb
187
+ test_files: []