oauth2_api_client 3.1.1 → 3.3.0

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
  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: []