oauth2_api_client 1.0.0 → 2.0.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +19 -9
- data/lib/oauth2_api_client.rb +28 -42
- data/lib/oauth2_api_client/token_provider.rb +74 -0
- data/lib/oauth2_api_client/version.rb +1 -1
- data/spec/oauth2_api_client/token_provider_spec.rb +82 -0
- data/spec/oauth2_api_client_spec.rb +29 -93
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb758d909c7cbeae49beef096ef7b8b0eedb5e038c8a403fac15388d6fc71884
|
4
|
+
data.tar.gz: 86186e7192b22b2fddb16e6bd03c005efbe58d3f159585ef8ad2ec1cd9a79d4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cbb79317198bd5c8bf2e3139ee5646be1d035ef7a95950ed05e0b35aad4b8bde1556b80294e73ee2c3823e6ce863fbc09ce26989fb6677b81fed0157c04aae6
|
7
|
+
data.tar.gz: ce5ef6661c8226f38770f2abc8cae7f33bc6b5efb6eaac11819fd8848ab084cc236374797d92c5d505a4d2142a6e677b0d17f1e2c0d0d910fb44b201bdf0537c
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -6,23 +6,33 @@
|
|
6
6
|
Oauth2ApiClient is small, but powerful client around
|
7
7
|
[oauth2](https://github.com/oauth-xx/oauth2) and
|
8
8
|
[http-rb](https://github.com/httprb/http) to interact with APIs which use
|
9
|
-
oauth2 for authentication
|
9
|
+
oauth2 for authentication.
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
client = Oauth2ApiClient.new(
|
13
|
-
base_url: "https://api.example.com/",
|
14
|
-
client_id: "the client id",
|
15
|
-
client_secret: "the client secret",
|
16
|
-
oauth_token_url: "https://auth.example.com/oauth2/token",
|
17
|
-
max_token_ttl: 3600, # optional
|
18
|
-
cache: Rails.cache # optional
|
19
|
-
)
|
12
|
+
client = Oauth2ApiClient.new(base_url: "https://api.example.com", token "oauth2 token")
|
20
13
|
|
21
14
|
client.post("/orders", json: { address: "..." }).status.success?
|
22
15
|
client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse
|
23
16
|
# ...
|
24
17
|
```
|
25
18
|
|
19
|
+
Oauth2ApiClient is capable of generating oauth2 tokens, when a client id,
|
20
|
+
client secret and oauth token url is given with automatic token caching and
|
21
|
+
renewal on expiry, including retry of the current request.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
client = Oauth2ApiClient.new(
|
25
|
+
base_url: "https://api.example.com",
|
26
|
+
token: Oauth2ApiClient::TokenProvider.new(
|
27
|
+
client_id: "client id",
|
28
|
+
client_secret: "client secret",
|
29
|
+
token_url: "https.//auth.example.com/oauth2/token",
|
30
|
+
cache: Rails.cache, # optional,
|
31
|
+
max_token_ttl: 1800 # optional
|
32
|
+
)
|
33
|
+
)
|
34
|
+
```
|
35
|
+
|
26
36
|
## Install
|
27
37
|
|
28
38
|
Add this line to your application's Gemfile:
|
data/lib/oauth2_api_client.rb
CHANGED
@@ -6,6 +6,7 @@ require "active_support"
|
|
6
6
|
|
7
7
|
require "oauth2_api_client/version"
|
8
8
|
require "oauth2_api_client/http_error"
|
9
|
+
require "oauth2_api_client/token_provider"
|
9
10
|
|
10
11
|
# The Oauth2ApiClient class is a client wrapped around the oauth2 and http-rb
|
11
12
|
# gem to interact with APIs using oauth2 for authentication with automatic
|
@@ -15,46 +16,35 @@ class Oauth2ApiClient
|
|
15
16
|
# Creates a new Oauth2ApiClient
|
16
17
|
#
|
17
18
|
# @param base_url [String] The base url of the API to interact with
|
18
|
-
# @param
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# Defaults to `ActiveSupport::Cache::MemoryStore.new`
|
23
|
-
# @param max_token_ttl [#to_i] The max lifetime of the token in the cache
|
24
|
-
# @param base_request You can pass some http-rb rqeuest as the base. Useful,
|
25
|
-
# if some information needs to be passed with every request. Defaults to
|
26
|
-
# `HTTP`
|
19
|
+
# @param token [String, Oauth2ApiClient::TokenProvider] Allows to pass an
|
20
|
+
# existing token received via external sources or an instance of
|
21
|
+
# `Oauth2ApiClient::TokenProvider` which is capable of generating
|
22
|
+
# tokens when client id, client secret, etc. is given
|
27
23
|
#
|
28
24
|
# @example
|
29
25
|
# client = Oauth2ApiClient.new(
|
30
|
-
# base_url: "https://api.example.com
|
31
|
-
#
|
32
|
-
# client_secret: "the client secret",
|
33
|
-
# oauth_token_url: "https://auth.example.com/oauth2/token",
|
34
|
-
# cache: Rails.cache,
|
35
|
-
# base_request: HTTP.headers("User-Agent" => "API client")
|
26
|
+
# base_url: "https://api.example.com",
|
27
|
+
# token: "the api token"
|
36
28
|
# )
|
37
29
|
#
|
38
30
|
# client.post("/orders", json: { address: "..." }).status.success?
|
39
31
|
# client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# client = Oauth2ApiClient.new(
|
35
|
+
# base_url: "https://api.example.com",
|
36
|
+
# token: Oauth2ApiClient::TokenProvider.new(
|
37
|
+
# client_id: "the client id",
|
38
|
+
# client_secret: "the client secret",
|
39
|
+
# oauth_token_url: "https://auth.example.com/oauth2/token",
|
40
|
+
# cache: Rails.cache
|
41
|
+
# )
|
42
|
+
# )
|
40
43
|
|
41
|
-
def initialize(base_url:,
|
44
|
+
def initialize(base_url:, base_request: HTTP, token:)
|
42
45
|
@base_url = base_url
|
43
|
-
@
|
44
|
-
@client_secret = client_secret
|
45
|
-
@oauth_token_url = oauth_token_url
|
46
|
-
@max_token_ttl = max_token_ttl
|
47
|
-
@cache = cache
|
46
|
+
@token = token
|
48
47
|
@request = base_request
|
49
|
-
|
50
|
-
oauth_uri = URI.parse(oauth_token_url)
|
51
|
-
|
52
|
-
@oauth_client = OAuth2::Client.new(
|
53
|
-
@client_id,
|
54
|
-
@client_secret,
|
55
|
-
site: URI.parse("#{oauth_uri.scheme}://#{oauth_uri.host}:#{oauth_uri.port}/").to_s,
|
56
|
-
token_url: oauth_uri.path
|
57
|
-
)
|
58
48
|
end
|
59
49
|
|
60
50
|
# Returns a oauth2 token to use for authentication
|
@@ -62,9 +52,7 @@ class Oauth2ApiClient
|
|
62
52
|
# @return [String] The token
|
63
53
|
|
64
54
|
def token
|
65
|
-
@
|
66
|
-
@oauth_client.client_credentials.get_token.token
|
67
|
-
end
|
55
|
+
@token.respond_to?(:to_str) ? @token.to_str : @token.token
|
68
56
|
end
|
69
57
|
|
70
58
|
[:timeout, :headers, :cookies, :via, :encoding, :accept, :auth, :basic_auth].each do |method|
|
@@ -85,13 +73,9 @@ class Oauth2ApiClient
|
|
85
73
|
|
86
74
|
private
|
87
75
|
|
88
|
-
def cache_key
|
89
|
-
@cache_key ||= ["oauth_api_client", @base_url, @oauth_token_url, @client_id].join("|")
|
90
|
-
end
|
91
|
-
|
92
76
|
def execute(verb, path, options = {})
|
93
77
|
with_retry do
|
94
|
-
response = @request.auth("Bearer #{token}").send(verb,
|
78
|
+
response = @request.auth("Bearer #{token}").send(verb, "#{@base_url}#{path}", options)
|
95
79
|
|
96
80
|
return response if response.status.success?
|
97
81
|
|
@@ -105,13 +89,15 @@ class Oauth2ApiClient
|
|
105
89
|
begin
|
106
90
|
yield
|
107
91
|
rescue HttpError => e
|
108
|
-
|
92
|
+
if !retried && e.response.status.unauthorized? && @token.respond_to?(:invalidate_token)
|
93
|
+
@token.invalidate_token
|
109
94
|
|
110
|
-
|
95
|
+
retried = true
|
111
96
|
|
112
|
-
|
97
|
+
retry
|
98
|
+
end
|
113
99
|
|
114
|
-
|
100
|
+
raise
|
115
101
|
end
|
116
102
|
end
|
117
103
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
class Oauth2ApiClient
|
4
|
+
# The TokenProvider class is responsible for obtaining and caching an oauth2
|
5
|
+
# token, when client id, client secret and token url is given.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# Oauth2ApiClient::TokenProvider.new(
|
9
|
+
# client_id: "client id",
|
10
|
+
# client_secret: "client secret",
|
11
|
+
# token_url: "https://auth.example.com/oauth2/token",
|
12
|
+
# cache: Rails.cache, # optional
|
13
|
+
# max_token_ttl: 1800 # optional
|
14
|
+
# )
|
15
|
+
|
16
|
+
class TokenProvider
|
17
|
+
# Creates a new TokenProvider instance.
|
18
|
+
#
|
19
|
+
# @param client_id [String] The client id
|
20
|
+
# @param client_secret [String] The client secret
|
21
|
+
# @param token_url [String] The oauth2 endpoint for generating tokens
|
22
|
+
# @param cache An ActiveSupport compatible cache implementation. Defaults
|
23
|
+
# to `ActiveSupport::Cache::MemoryStore.new`
|
24
|
+
# @param max_token_ttl [#to_i] A maximum token lifetime. Defaults to 3600
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# Oauth2ApiClient::TokenProvider.new(
|
28
|
+
# client_id: "client id",
|
29
|
+
# client_secret: "client secret",
|
30
|
+
# token_url: "https://auth.example.com/oauth2/token",
|
31
|
+
# )
|
32
|
+
|
33
|
+
def initialize(client_id:, client_secret:, token_url:, cache: ActiveSupport::Cache::MemoryStore.new, max_token_ttl: 3600)
|
34
|
+
@client_id = client_id
|
35
|
+
@client_secret = client_secret
|
36
|
+
@token_url = token_url
|
37
|
+
@max_token_ttl = max_token_ttl
|
38
|
+
@cache = cache
|
39
|
+
|
40
|
+
oauth_uri = URI.parse(token_url)
|
41
|
+
|
42
|
+
@oauth_client = OAuth2::Client.new(
|
43
|
+
@client_id,
|
44
|
+
@client_secret,
|
45
|
+
site: URI.parse("#{oauth_uri.scheme}://#{oauth_uri.host}:#{oauth_uri.port}/").to_s,
|
46
|
+
token_url: oauth_uri.path
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the oauth2 token, either from the cache, or newly generated
|
51
|
+
#
|
52
|
+
# @return [String] the token
|
53
|
+
|
54
|
+
def token
|
55
|
+
@cache.fetch(cache_key, expires_in: @max_token_ttl.to_i) do
|
56
|
+
@oauth_client.client_credentials.get_token.token
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Invalidates the cached token, i.e. removes it from the cache
|
61
|
+
#
|
62
|
+
# @return [String] the token
|
63
|
+
|
64
|
+
def invalidate_token
|
65
|
+
@cache.delete(cache_key)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def cache_key
|
71
|
+
@cache_key ||= ["oauth_api_client", @token_url, @client_id].join("|")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path("../spec_helper", __dir__)
|
2
|
+
|
3
|
+
RSpec.describe Oauth2ApiClient::TokenProvider do
|
4
|
+
before do
|
5
|
+
token_response = {
|
6
|
+
access_token: "access_token",
|
7
|
+
token_type: "bearer",
|
8
|
+
expires_in: 3600,
|
9
|
+
refresh_token: "refresh_token",
|
10
|
+
scope: "create"
|
11
|
+
}
|
12
|
+
|
13
|
+
stub_request(:post, "http://localhost/oauth2/token")
|
14
|
+
.to_return(status: 200, body: JSON.generate(token_response), headers: { "Content-Type" => "application/json" })
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#token" do
|
18
|
+
it "returns a oauth2 token" do
|
19
|
+
token_provider = described_class.new(
|
20
|
+
client_id: "client_id",
|
21
|
+
client_secret: "client_secret",
|
22
|
+
token_url: "http://localhost/oauth2/token"
|
23
|
+
)
|
24
|
+
|
25
|
+
expect(token_provider.token).to eq("access_token")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the cached token if existing" do
|
29
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
30
|
+
|
31
|
+
allow(cache).to receive(:fetch).and_return("cached_token")
|
32
|
+
|
33
|
+
token_provider = described_class.new(
|
34
|
+
client_id: "client_id",
|
35
|
+
client_secret: "client_secret",
|
36
|
+
token_url: "http://localhost/oauth2/token",
|
37
|
+
cache: cache
|
38
|
+
)
|
39
|
+
|
40
|
+
expect(token_provider.token).to eq("cached_token")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "caches the token" do
|
44
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
45
|
+
|
46
|
+
allow(cache).to receive(:fetch).and_yield
|
47
|
+
|
48
|
+
token_provider = described_class.new(
|
49
|
+
client_id: "client_id",
|
50
|
+
client_secret: "client_secret",
|
51
|
+
token_url: "http://localhost/oauth2/token",
|
52
|
+
max_token_ttl: 60,
|
53
|
+
cache: cache
|
54
|
+
)
|
55
|
+
|
56
|
+
token_provider.token
|
57
|
+
|
58
|
+
expect(cache).to have_received(:fetch).with("oauth_api_client|http://localhost/oauth2/token|client_id", expires_in: 60)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#invalidate_token" do
|
63
|
+
it "deletes the token from the cache" do
|
64
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
65
|
+
|
66
|
+
token_provider = described_class.new(
|
67
|
+
client_id: "client_id",
|
68
|
+
client_secret: "client_secret",
|
69
|
+
token_url: "http://localhost/oauth2/token",
|
70
|
+
cache: cache
|
71
|
+
)
|
72
|
+
|
73
|
+
token_provider.token
|
74
|
+
|
75
|
+
expect(cache.read("oauth_api_client|http://localhost/oauth2/token|client_id")).not_to be_nil
|
76
|
+
|
77
|
+
token_provider.invalidate_token
|
78
|
+
|
79
|
+
expect(cache.read("oauth_api_client|http://localhost/oauth2/token|client_id")).to be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -31,63 +31,30 @@ RSpec.describe Oauth2ApiClient do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "#token" do
|
34
|
-
it "returns
|
35
|
-
client = described_class.new(
|
36
|
-
base_url: "http://localhost/",
|
37
|
-
client_id: "client_id",
|
38
|
-
client_secret: "client_secret",
|
39
|
-
oauth_token_url: "http://localhost/oauth2/token"
|
40
|
-
)
|
34
|
+
it "returns the supplier token" do
|
35
|
+
client = described_class.new(base_url: "http://localhost/", token: "access_token")
|
41
36
|
|
42
37
|
expect(client.token).to eq("access_token")
|
43
38
|
end
|
44
39
|
|
45
|
-
it "returns
|
46
|
-
cache = ActiveSupport::Cache::MemoryStore.new
|
47
|
-
|
48
|
-
allow(cache).to receive(:fetch).and_return("cached_token")
|
49
|
-
|
50
|
-
client = described_class.new(
|
51
|
-
base_url: "http://localhost/",
|
52
|
-
client_id: "client_id",
|
53
|
-
client_secret: "client_secret",
|
54
|
-
oauth_token_url: "http://localhost/oauth2/token",
|
55
|
-
cache: cache
|
56
|
-
)
|
57
|
-
|
58
|
-
expect(client.token).to eq("cached_token")
|
59
|
-
end
|
60
|
-
|
61
|
-
it "caches the token" do
|
62
|
-
cache = ActiveSupport::Cache::MemoryStore.new
|
63
|
-
|
64
|
-
allow(cache).to receive(:fetch).and_yield
|
65
|
-
|
40
|
+
it "returns a oauth2 token" do
|
66
41
|
client = described_class.new(
|
67
42
|
base_url: "http://localhost/",
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
43
|
+
token: described_class::TokenProvider.new(
|
44
|
+
client_id: "client_id",
|
45
|
+
client_secret: "client_secret",
|
46
|
+
token_url: "http://localhost/oauth2/token"
|
47
|
+
)
|
73
48
|
)
|
74
49
|
|
75
|
-
client.token
|
76
|
-
|
77
|
-
expect(cache).to have_received(:fetch).with("oauth_api_client|http://localhost/|http://localhost/oauth2/token|client_id", expires_in: 60)
|
50
|
+
expect(client.token).to eq("access_token")
|
78
51
|
end
|
79
52
|
end
|
80
53
|
|
81
54
|
[:timeout, :headers, :cookies, :via, :encoding, :accept, :auth, :basic_auth].each do |method|
|
82
55
|
describe "##{method}" do
|
83
56
|
it "creates a dupped instance" do
|
84
|
-
client = described_class.new(
|
85
|
-
base_url: "http://localhost/",
|
86
|
-
client_id: "client_id",
|
87
|
-
client_secret: "client_secret",
|
88
|
-
oauth_token_url: "http://localhost/oauth2/token",
|
89
|
-
base_request: HttpTestRequest.new
|
90
|
-
)
|
57
|
+
client = described_class.new(base_url: "http://localhost/", token: "token", base_request: HttpTestRequest.new)
|
91
58
|
|
92
59
|
client1 = client.send(method, "key1")
|
93
60
|
client2 = client1.send(method, "key1")
|
@@ -96,13 +63,7 @@ RSpec.describe Oauth2ApiClient do
|
|
96
63
|
end
|
97
64
|
|
98
65
|
it "extends the request" do
|
99
|
-
client = described_class.new(
|
100
|
-
base_url: "http://localhost/",
|
101
|
-
client_id: "client_id",
|
102
|
-
client_secret: "client_secret",
|
103
|
-
oauth_token_url: "http://localhost/oauth2/token",
|
104
|
-
base_request: HttpTestRequest.new
|
105
|
-
)
|
66
|
+
client = described_class.new(base_url: "http://localhost/", token: "token", base_request: HttpTestRequest.new)
|
106
67
|
|
107
68
|
client1 = client.send(method, "key1")
|
108
69
|
client2 = client1.send(method, "key2")
|
@@ -115,76 +76,51 @@ RSpec.describe Oauth2ApiClient do
|
|
115
76
|
|
116
77
|
describe "request" do
|
117
78
|
it "prepends the base url" do
|
118
|
-
stub_request(:get, "http://localhost/path?key=value")
|
79
|
+
stub_request(:get, "http://localhost/api/path?key=value")
|
119
80
|
.to_return(status: 200, body: "ok")
|
120
81
|
|
121
|
-
client = described_class.new(
|
122
|
-
base_url: "http://localhost/",
|
123
|
-
client_id: "client_id",
|
124
|
-
client_secret: "client_secret",
|
125
|
-
oauth_token_url: "http://localhost/oauth2/token"
|
126
|
-
)
|
82
|
+
client = described_class.new(base_url: "http://localhost/api", token: "token")
|
127
83
|
|
128
84
|
expect(client.get("/path", params: { key: "value" }).to_s).to eq("ok")
|
129
85
|
end
|
130
86
|
|
131
87
|
it "passes the token in the authentication header" do
|
132
|
-
stub_request(:get, "http://localhost/path")
|
88
|
+
stub_request(:get, "http://localhost/api/path")
|
133
89
|
.with(headers: { "Authorization" => "Bearer access_token" })
|
134
90
|
.to_return(status: 200, body: "ok", headers: {})
|
135
91
|
|
136
|
-
client = described_class.new(
|
137
|
-
base_url: "http://localhost/",
|
138
|
-
client_id: "client_id",
|
139
|
-
client_secret: "client_secret",
|
140
|
-
oauth_token_url: "http://localhost/oauth2/token"
|
141
|
-
)
|
92
|
+
client = described_class.new(base_url: "http://localhost/api", token: "access_token")
|
142
93
|
|
143
94
|
expect(client.get("/path").to_s).to eq("ok")
|
144
95
|
end
|
145
96
|
|
146
|
-
it "invalidates the cached token when an http unauthorized status is returned" do
|
147
|
-
stub_request(:get, "http://localhost/path")
|
148
|
-
.to_return(status: 401, body: "unauthorized")
|
149
|
-
|
150
|
-
cache = ActiveSupport::Cache::MemoryStore.new
|
151
|
-
|
152
|
-
client = described_class.new(
|
153
|
-
base_url: "http://localhost/",
|
154
|
-
client_id: "client_id",
|
155
|
-
client_secret: "client_secret",
|
156
|
-
oauth_token_url: "http://localhost/oauth2/token",
|
157
|
-
cache: cache
|
158
|
-
)
|
159
|
-
|
160
|
-
expect { client.get("/path") }.to raise_error(described_class::HttpError)
|
161
|
-
|
162
|
-
expect(cache.read("oauth_api_client|http://localhost/|http://localhost/oauth2/token|client_id")).to be_nil
|
163
|
-
end
|
164
|
-
|
165
97
|
it "retries the request when an http unauthorized status is returned" do
|
166
|
-
stub_request(:get, "http://localhost/path")
|
98
|
+
stub_request(:get, "http://localhost/api/path")
|
167
99
|
.to_return({ status: 401, body: "unauthorized" }, { status: 200, body: "ok" })
|
168
100
|
|
169
101
|
client = described_class.new(
|
170
|
-
base_url: "http://localhost/",
|
171
|
-
|
172
|
-
|
173
|
-
|
102
|
+
base_url: "http://localhost/api",
|
103
|
+
token: described_class::TokenProvider.new(
|
104
|
+
client_id: "client_id",
|
105
|
+
client_secret: "client_secret",
|
106
|
+
token_url: "http://localhost/oauth2/token"
|
107
|
+
)
|
174
108
|
)
|
175
109
|
|
176
110
|
expect(client.get("/path").to_s).to eq("ok")
|
177
111
|
end
|
178
112
|
|
179
113
|
it "raises if the retried request also fails" do
|
180
|
-
stub_request(:get, "http://localhost/path")
|
114
|
+
stub_request(:get, "http://localhost/api/path")
|
181
115
|
.to_return(status: 401, body: "unauthorized")
|
182
116
|
|
183
117
|
client = described_class.new(
|
184
|
-
base_url: "http://localhost/",
|
185
|
-
|
186
|
-
|
187
|
-
|
118
|
+
base_url: "http://localhost/api",
|
119
|
+
token: described_class::TokenProvider.new(
|
120
|
+
client_id: "client_id",
|
121
|
+
client_secret: "client_secret",
|
122
|
+
token_url: "http://localhost/oauth2/token"
|
123
|
+
)
|
188
124
|
)
|
189
125
|
|
190
126
|
expect { client.get("/path") }.to raise_error(described_class::HttpError)
|
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:
|
4
|
+
version: 2.0.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: 2020-06-
|
11
|
+
date: 2020-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -154,8 +154,10 @@ files:
|
|
154
154
|
- Rakefile
|
155
155
|
- lib/oauth2_api_client.rb
|
156
156
|
- lib/oauth2_api_client/http_error.rb
|
157
|
+
- lib/oauth2_api_client/token_provider.rb
|
157
158
|
- lib/oauth2_api_client/version.rb
|
158
159
|
- oauth2_api_client.gemspec
|
160
|
+
- spec/oauth2_api_client/token_provider_spec.rb
|
159
161
|
- spec/oauth2_api_client_spec.rb
|
160
162
|
- spec/spec_helper.rb
|
161
163
|
homepage: https://github.com/mrkamel/oauth2_api_client
|
@@ -182,5 +184,6 @@ signing_key:
|
|
182
184
|
specification_version: 4
|
183
185
|
summary: Small but powerful client around oauth2 and http-rb to interact with APIs
|
184
186
|
test_files:
|
187
|
+
- spec/oauth2_api_client/token_provider_spec.rb
|
185
188
|
- spec/oauth2_api_client_spec.rb
|
186
189
|
- spec/spec_helper.rb
|