oauth2_api_client 2.0.0 → 3.1.1

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: cb758d909c7cbeae49beef096ef7b8b0eedb5e038c8a403fac15388d6fc71884
4
- data.tar.gz: 86186e7192b22b2fddb16e6bd03c005efbe58d3f159585ef8ad2ec1cd9a79d4b
3
+ metadata.gz: 33e0e15f43fe027760355c1a403da0d02b30412b064984102234744fc8da65b7
4
+ data.tar.gz: bf10a1428e0a797daa31f32b7712d2525eddab710c2ba12d244e95b968489314
5
5
  SHA512:
6
- metadata.gz: 5cbb79317198bd5c8bf2e3139ee5646be1d035ef7a95950ed05e0b35aad4b8bde1556b80294e73ee2c3823e6ce863fbc09ce26989fb6677b81fed0157c04aae6
7
- data.tar.gz: ce5ef6661c8226f38770f2abc8cae7f33bc6b5efb6eaac11819fd8848ab084cc236374797d92c5d505a4d2142a6e677b0d17f1e2c0d0d910fb44b201bdf0537c
6
+ metadata.gz: 46dbbbd595379cc1217f272247149d0ce8084651704c2264301e28dcc8ece22b2c8cc2b9b108d38140eaf1f46145cfde1fb600e24a5434f00a013948e79b22c3
7
+ data.tar.gz: d3b38d88ac90e9550971f5320b5cca814be87ade495a8bd999047faebd310f41beecbe45ac16e35fd2ba1e54bbea7b443f13f670e1c119e3a08931b6ea7476ef
@@ -0,0 +1,21 @@
1
+ on: push
2
+ name: test
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ strategy:
7
+ fail-fast: false
8
+ matrix:
9
+ ruby:
10
+ - 2.6
11
+ - 2.7
12
+ - 3.0
13
+ steps:
14
+ - uses: actions/checkout@v1
15
+ - uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ - run: gem install bundler
19
+ - run: bundle
20
+ - run: bundle exec rspec
21
+ - run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -1,6 +1,12 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
3
 
4
+ Gemspec/RequiredRubyVersion:
5
+ Enabled: false
6
+
7
+ Gemspec/RequireMFA:
8
+ Enabled: false
9
+
4
10
  Metrics/ParameterLists:
5
11
  Enabled: false
6
12
 
data/CHANGELOG.md CHANGED
@@ -1,6 +1,26 @@
1
1
 
2
2
  # CHANGELOG
3
3
 
4
+ # v3.1.1
5
+
6
+ * Added oauth2 version constraint
7
+
8
+ # v3.1.0
9
+
10
+ * Added uri to `Oauth2ApiClient::ReponseError` exception message
11
+
12
+ # v3.0.0
13
+
14
+ * [BREAKING] Renamed `Oauth2ApiClient::HttpError` to
15
+ `Oauth2ApiClient::ResponseError`
16
+ * Added http error exception classes like e.g.
17
+ `Oauth2ApiClient::ResponseError::NotFound`,
18
+ `Oauth2ApiClient::ResponseError::InternalServerError`, etc.
19
+
20
+ # v2.1.0
21
+
22
+ * Include the response code and body in `HttpError#to_s`
23
+
4
24
  # v2.0.0
5
25
 
6
26
  * `TokenProvider` added
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # oauth2_api_client
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/mrkamel/oauth2_api_client.svg?branch=master)](http://travis-ci.org/mrkamel/oauth2_api_client)
3
+ [![Build](https://github.com/mrkamel/oauth2_api_client/workflows/test/badge.svg)](https://github.com/mrkamel/oauth2_api_client/actions?query=workflow%3Atest+branch%3Amaster)
4
4
  [![Gem Version](https://badge.fury.io/rb/oauth2_api_client.svg)](http://badge.fury.io/rb/oauth2_api_client)
5
5
 
6
- Oauth2ApiClient is small, but powerful client around
6
+ Oauth2ApiClient is a 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
9
  oauth2 for authentication.
@@ -12,7 +12,7 @@ oauth2 for authentication.
12
12
  client = Oauth2ApiClient.new(base_url: "https://api.example.com", token "oauth2 token")
13
13
 
14
14
  client.post("/orders", json: { address: "..." }).status.success?
15
- client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse
15
+ client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse(:json)
16
16
  # ...
17
17
  ```
18
18
 
@@ -33,6 +33,12 @@ client = Oauth2ApiClient.new(
33
33
  )
34
34
  ```
35
35
 
36
+ Please note, `get`, `post`, `put`, etc. will raise
37
+ `Oauth2ApiClient::ResponseError` unless the response code is 2xx. More
38
+ specifically, it will e.g. raise `Oauth2ApiClient::ResponseError::NotFound` for
39
+ a 404 status code, `Oauth2ApiClient::ResponseError::InternalServerError` for a
40
+ 500 status code, etc.
41
+
36
42
  ## Install
37
43
 
38
44
  Add this line to your application's Gemfile:
@@ -0,0 +1,100 @@
1
+ class Oauth2ApiClient
2
+ # The ResponseError class is the main exception class of Oauth2ApiClient and is
3
+ # raised when a request fails with some status code other than 2xx. Using
4
+ # the exception object, you still have access to the response. Moreover,
5
+ # there are exception classes for all 4xx and 5xx errors.
6
+ #
7
+ # @example
8
+ # begin
9
+ # client.post("/orders", json: { address: "..." })
10
+ # rescue Oauth2ApiClient::ResponseError::NotFound => e
11
+ # e.response # => HTTP::Response
12
+ # rescue Oauth2ApiClient::ResponseError::BadRequest => e
13
+ # # ...
14
+ # rescue Oauth2ApiClient::ResponseError => e
15
+ # # ...
16
+ # end
17
+
18
+ class ResponseError < StandardError
19
+ STATUSES = {
20
+ 400 => "Bad Request",
21
+ 401 => "Unauthorized",
22
+ 402 => "Payment Required",
23
+ 403 => "Forbidden",
24
+ 404 => "Not Found",
25
+ 405 => "Method Not Allowed",
26
+ 406 => "Not Acceptable",
27
+ 407 => "Proxy Authentication Required",
28
+ 408 => "Request Timeout",
29
+ 409 => "Conflict",
30
+ 410 => "Gone",
31
+ 411 => "Length Required",
32
+ 412 => "Precondition Failed",
33
+ 413 => "Payload Too Large",
34
+ 414 => "URI Too Long",
35
+ 415 => "Unsupported Media Type",
36
+ 416 => "Range Not Satisfiable",
37
+ 417 => "Expectation Failed",
38
+ 418 => "I'm A Teapot",
39
+ 421 => "Too Many Connections From This IP",
40
+ 422 => "Unprocessable Entity",
41
+ 423 => "Locked",
42
+ 424 => "Failed Dependency",
43
+ 425 => "Unordered Collection",
44
+ 426 => "Upgrade Required",
45
+ 428 => "Precondition Required",
46
+ 429 => "Too Many Requests",
47
+ 431 => "Request Header Fields Too Large",
48
+ 449 => "Retry With",
49
+ 450 => "Blocked By Windows Parental Controls",
50
+
51
+ 500 => "Internal Server Error",
52
+ 501 => "Not Implemented",
53
+ 502 => "Bad Gateway",
54
+ 503 => "Service Unavailable",
55
+ 504 => "Gateway Timeout",
56
+ 505 => "HTTP Version Not Supported",
57
+ 506 => "Variant Also Negotiates",
58
+ 507 => "Insufficient Storage",
59
+ 508 => "Loop Detected",
60
+ 509 => "Bandwidth Limit Exceeded",
61
+ 510 => "Not Extended",
62
+ 511 => "Network Authentication Required"
63
+ }
64
+
65
+ attr_reader :response
66
+
67
+ def initialize(response)
68
+ super()
69
+
70
+ @response = response
71
+ end
72
+
73
+ def to_s
74
+ "#{self.class.name} (#{response.code}, #{response.uri}): #{response.body}"
75
+ end
76
+
77
+ # @api private
78
+ #
79
+ # Returns the exception class for a status code of the given response.
80
+
81
+ def self.for(response)
82
+ return const_get(const_name(STATUSES[response.code])).new(response) if STATUSES.key?(response.code)
83
+
84
+ new(response)
85
+ end
86
+
87
+ # @api private
88
+ #
89
+ # Returns a sanitized version to be used as a constant name for a given
90
+ # http error message.
91
+
92
+ def self.const_name(message)
93
+ message.gsub(/[^a-zA-Z0-9]/, "")
94
+ end
95
+
96
+ STATUSES.each do |_code, message|
97
+ const_set(const_name(message), Class.new(self))
98
+ end
99
+ end
100
+ end
@@ -1,3 +1,3 @@
1
1
  class Oauth2ApiClient
2
- VERSION = "2.0.0"
2
+ VERSION = "3.1.1"
3
3
  end
@@ -1,11 +1,10 @@
1
1
  require "ruby2_keywords"
2
2
  require "oauth2"
3
3
  require "http"
4
- require "ruby2_keywords"
5
4
  require "active_support"
6
5
 
7
6
  require "oauth2_api_client/version"
8
- require "oauth2_api_client/http_error"
7
+ require "oauth2_api_client/response_error"
9
8
  require "oauth2_api_client/token_provider"
10
9
 
11
10
  # The Oauth2ApiClient class is a client wrapped around the oauth2 and http-rb
@@ -28,7 +27,7 @@ class Oauth2ApiClient
28
27
  # )
29
28
  #
30
29
  # client.post("/orders", json: { address: "..." }).status.success?
31
- # client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse
30
+ # client.headers("User-Agent" => "API Client").timeout(read: 5, write: 5).get("/orders").parse(:json)
32
31
  #
33
32
  # @example
34
33
  # client = Oauth2ApiClient.new(
@@ -41,7 +40,7 @@ class Oauth2ApiClient
41
40
  # )
42
41
  # )
43
42
 
44
- def initialize(base_url:, base_request: HTTP, token:)
43
+ def initialize(base_url:, token:, base_request: HTTP)
45
44
  @base_url = base_url
46
45
  @token = token
47
46
  @request = base_request
@@ -79,7 +78,7 @@ class Oauth2ApiClient
79
78
 
80
79
  return response if response.status.success?
81
80
 
82
- raise HttpError.new(response.status.to_s, response)
81
+ raise ResponseError.for(response)
83
82
  end
84
83
  end
85
84
 
@@ -88,7 +87,7 @@ class Oauth2ApiClient
88
87
 
89
88
  begin
90
89
  yield
91
- rescue HttpError => e
90
+ rescue ResponseError => e
92
91
  if !retried && e.response.status.unauthorized? && @token.respond_to?(:invalidate_token)
93
92
  @token.invalidate_token
94
93
 
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency "activesupport"
28
28
  spec.add_dependency "http"
29
- spec.add_dependency "oauth2"
29
+ spec.add_dependency "oauth2", ">= 1.4.2"
30
30
  spec.add_dependency "ruby2_keywords"
31
31
  end
@@ -0,0 +1,20 @@
1
+ require File.expand_path("../spec_helper", __dir__)
2
+
3
+ RSpec.describe Oauth2ApiClient::ResponseError do
4
+ describe "#to_s" do
5
+ it "returns the message" do
6
+ response = double(code: 401, body: "unauthorized", uri: "http://example.com/")
7
+
8
+ expect(described_class.new(response).to_s).to eq("Oauth2ApiClient::ResponseError (401, http://example.com/): unauthorized")
9
+ end
10
+ end
11
+
12
+ describe ".for" do
13
+ it "returns the exception class for the status code of the given response" do
14
+ expect(described_class.for(double(code: 400, body: "body"))).to be_instance_of(Oauth2ApiClient::ResponseError::BadRequest)
15
+ expect(described_class.for(double(code: 404, body: "body"))).to be_instance_of(Oauth2ApiClient::ResponseError::NotFound)
16
+ expect(described_class.for(double(code: 500, body: "body"))).to be_instance_of(Oauth2ApiClient::ResponseError::InternalServerError)
17
+ expect(described_class.for(double(code: 503, body: "body"))).to be_instance_of(Oauth2ApiClient::ResponseError::ServiceUnavailable)
18
+ end
19
+ end
20
+ end
@@ -123,7 +123,7 @@ RSpec.describe Oauth2ApiClient do
123
123
  )
124
124
  )
125
125
 
126
- expect { client.get("/path") }.to raise_error(described_class::HttpError)
126
+ expect { client.get("/path") }.to raise_error("Oauth2ApiClient::ResponseError::Unauthorized (401, http://localhost/api/path): unauthorized")
127
127
  end
128
128
  end
129
129
  end
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: 2.0.0
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-21 00:00:00.000000000 Z
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: 1.4.2
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: 1.4.2
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: ruby2_keywords
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -144,19 +144,20 @@ executables: []
144
144
  extensions: []
145
145
  extra_rdoc_files: []
146
146
  files:
147
+ - ".github/workflows/test.yml"
147
148
  - ".gitignore"
148
149
  - ".rubocop.yml"
149
- - ".travis.yml"
150
150
  - CHANGELOG.md
151
151
  - Gemfile
152
152
  - LICENSE.txt
153
153
  - README.md
154
154
  - Rakefile
155
155
  - lib/oauth2_api_client.rb
156
- - lib/oauth2_api_client/http_error.rb
156
+ - lib/oauth2_api_client/response_error.rb
157
157
  - lib/oauth2_api_client/token_provider.rb
158
158
  - lib/oauth2_api_client/version.rb
159
159
  - oauth2_api_client.gemspec
160
+ - spec/oauth2_api_client/response_error_spec.rb
160
161
  - spec/oauth2_api_client/token_provider_spec.rb
161
162
  - spec/oauth2_api_client_spec.rb
162
163
  - spec/spec_helper.rb
@@ -164,7 +165,7 @@ homepage: https://github.com/mrkamel/oauth2_api_client
164
165
  licenses:
165
166
  - MIT
166
167
  metadata: {}
167
- post_install_message:
168
+ post_install_message:
168
169
  rdoc_options: []
169
170
  require_paths:
170
171
  - lib
@@ -179,11 +180,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
180
  - !ruby/object:Gem::Version
180
181
  version: '0'
181
182
  requirements: []
182
- rubygems_version: 3.0.3
183
- signing_key:
183
+ rubygems_version: 3.3.3
184
+ signing_key:
184
185
  specification_version: 4
185
186
  summary: Small but powerful client around oauth2 and http-rb to interact with APIs
186
187
  test_files:
188
+ - spec/oauth2_api_client/response_error_spec.rb
187
189
  - spec/oauth2_api_client/token_provider_spec.rb
188
190
  - spec/oauth2_api_client_spec.rb
189
191
  - spec/spec_helper.rb
data/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - ruby-2.6.2
5
- - ruby-2.7.1
6
- install:
7
- - travis_retry bundle install
8
- script:
9
- - bundle exec rspec
10
- - bundle exec rubocop
@@ -1,10 +0,0 @@
1
- class Oauth2ApiClient
2
- class HttpError < StandardError
3
- attr_reader :message, :response
4
-
5
- def initialize(message, response)
6
- @message = message
7
- @response = response
8
- end
9
- end
10
- end