oauth2 1.4.7 → 1.4.9

Sign up to get free protection for your applications and to get access to all the features.
data/lib/oauth2/client.rb CHANGED
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'logger'
3
5
 
4
6
  module OAuth2
7
+ ConnectionError = Class.new(Faraday::ConnectionFailed)
5
8
  # The OAuth2::Client class
6
9
  class Client # rubocop:disable Metrics/ClassLength
7
10
  RESERVED_PARAM_KEYS = %w[headers parse].freeze
@@ -16,17 +19,18 @@ module OAuth2
16
19
  #
17
20
  # @param [String] client_id the client_id value
18
21
  # @param [String] client_secret the client_secret value
19
- # @param [Hash] opts the options to create the client with
20
- # @option opts [String] :site the OAuth2 provider site host
21
- # @option opts [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
22
- # @option opts [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
23
- # @option opts [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
24
- # @option opts [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
25
- # @option opts [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
26
- # @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
27
- # @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow
28
- # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error on responses with 400+ status codes
29
- # @option opts [Proc] :extract_access_token proc that extracts the access token from the response
22
+ # @param [Hash] options the options to create the client with
23
+ # @option options [String] :site the OAuth2 provider site host
24
+ # @option options [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
25
+ # @option options [String] :authorize_url ('oauth/authorize') absolute or relative URL path to the Authorization endpoint
26
+ # @option options [String] :token_url ('oauth/token') absolute or relative URL path to the Token endpoint
27
+ # @option options [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
28
+ # @option options [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
29
+ # @option options [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
30
+ # @option options [FixNum] :max_redirects (5) maximum number of redirects to follow
31
+ # @option options [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error on responses with 400+ status codes
32
+ # @option options [Logger] :logger (::Logger.new($stdout)) which logger to use when OAUTH_DEBUG is enabled
33
+ # @option options [Proc] (DEPRECATED) :extract_access_token proc that extracts the access token from the response
30
34
  # @yield [builder] The Faraday connection builder
31
35
  def initialize(client_id, client_secret, options = {}, &block)
32
36
  opts = options.dup
@@ -34,24 +38,22 @@ module OAuth2
34
38
  @secret = client_secret
35
39
  @site = opts.delete(:site)
36
40
  ssl = opts.delete(:ssl)
37
-
38
- @options = {
39
- :authorize_url => '/oauth/authorize',
40
- :token_url => '/oauth/token',
41
- :token_method => :post,
42
- :auth_scheme => :request_body,
43
- :connection_opts => {},
44
- :connection_build => block,
45
- :max_redirects => 5,
46
- :raise_errors => true,
47
- :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN,
48
- }.merge(opts)
41
+ @options = {:authorize_url => 'oauth/authorize',
42
+ :token_url => 'oauth/token',
43
+ :token_method => :post,
44
+ :auth_scheme => :request_body,
45
+ :connection_opts => {},
46
+ :connection_build => block,
47
+ :max_redirects => 5,
48
+ :raise_errors => true,
49
+ :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN, # DEPRECATED
50
+ :logger => ::Logger.new($stdout)}.merge(opts)
49
51
  @options[:connection_opts][:ssl] = ssl if ssl
50
52
  end
51
53
 
52
54
  # Set the site host
53
55
  #
54
- # @param [String] the OAuth2 provider site host
56
+ # @param value [String] the OAuth2 provider site host
55
57
  def site=(value)
56
58
  @connection = nil
57
59
  @site = value
@@ -59,15 +61,16 @@ module OAuth2
59
61
 
60
62
  # The Faraday connection object
61
63
  def connection
62
- @connection ||= begin
63
- conn = Faraday.new(site, options[:connection_opts])
64
- if options[:connection_build]
65
- conn.build do |b|
66
- options[:connection_build].call(b)
64
+ @connection ||=
65
+ Faraday.new(site, options[:connection_opts]) do |builder|
66
+ oauth_debug_logging(builder)
67
+ if options[:connection_build]
68
+ options[:connection_build].call(builder)
69
+ else
70
+ builder.request :url_encoded # form-encode POST params
71
+ builder.adapter Faraday.default_adapter # make requests with Net::HTTP
67
72
  end
68
73
  end
69
- conn
70
- end
71
74
  end
72
75
 
73
76
  # The authorize endpoint URL of the OAuth2 provider
@@ -97,15 +100,18 @@ module OAuth2
97
100
  # code response for this request. Will default to client option
98
101
  # @option opts [Symbol] :parse @see Response::initialize
99
102
  # @yield [req] The Faraday request
100
- def request(verb, url, opts = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
101
- connection.response :logger, ::Logger.new($stdout) if ENV['OAUTH_DEBUG'] == 'true'
102
-
103
+ def request(verb, url, opts = {}) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
103
104
  url = connection.build_url(url).to_s
104
105
 
105
- response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
106
- req.params.update(opts[:params]) if opts[:params]
107
- yield(req) if block_given?
106
+ begin
107
+ response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
108
+ req.params.update(opts[:params]) if opts[:params]
109
+ yield(req) if block_given?
110
+ end
111
+ rescue Faraday::ConnectionFailed => e
112
+ raise ConnectionError, e
108
113
  end
114
+
109
115
  response = Response.new(response, :parse => opts[:parse])
110
116
 
111
117
  case response.status
@@ -118,7 +124,13 @@ module OAuth2
118
124
  verb = :get
119
125
  opts.delete(:body)
120
126
  end
121
- request(verb, response.headers['location'], opts)
127
+ location = response.headers['location']
128
+ if location
129
+ request(verb, location, opts)
130
+ else
131
+ error = Error.new(response)
132
+ raise(error, "Got #{response.status} status code, but no Location header was present")
133
+ end
122
134
  when 200..299, 300..399
123
135
  # on non-redirecting 3xx statuses, just return the response
124
136
  response
@@ -136,11 +148,11 @@ module OAuth2
136
148
 
137
149
  # Initializes an AccessToken by making a request to the token endpoint
138
150
  #
139
- # @param [Hash] params a Hash of params for the token endpoint
140
- # @param [Hash] access token options, to pass to the AccessToken object
141
- # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
151
+ # @param params [Hash] a Hash of params for the token endpoint
152
+ # @param access_token_opts [Hash] access token options, to pass to the AccessToken object
153
+ # @param access_token_class [Class] class of access token for easier subclassing OAuth2::AccessToken
142
154
  # @return [AccessToken] the initialized AccessToken
143
- def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
155
+ def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity Metrics/AbcSize, Metrics/MethodLength
144
156
  params = params.map do |key, value|
145
157
  if RESERVED_PARAM_KEYS.include?(key)
146
158
  [key.to_sym, value]
@@ -150,7 +162,7 @@ module OAuth2
150
162
  end
151
163
  params = Hash[params]
152
164
 
153
- params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
165
+ params = authenticator.apply(params)
154
166
  opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
155
167
  headers = params.delete(:headers) || {}
156
168
  if options[:token_method] == :post
@@ -160,8 +172,9 @@ module OAuth2
160
172
  opts[:params] = params
161
173
  opts[:headers] = {}
162
174
  end
163
- opts[:headers].merge!(headers)
164
- response = request(options[:token_method], token_url, opts)
175
+ opts[:headers] = opts[:headers].merge(headers)
176
+ http_method = options[:token_method]
177
+ response = request(http_method, token_url, opts)
165
178
 
166
179
  access_token = begin
167
180
  build_access_token(response, access_token_opts, extract_access_token)
@@ -169,37 +182,45 @@ module OAuth2
169
182
  nil
170
183
  end
171
184
 
172
- if options[:raise_errors] && !access_token
185
+ response_contains_token = access_token || (
186
+ response.parsed.is_a?(Hash) &&
187
+ (response.parsed['access_token'] || response.parsed['id_token'])
188
+ )
189
+
190
+ if options[:raise_errors] && !response_contains_token
173
191
  error = Error.new(response)
174
192
  raise(error)
193
+ elsif !response_contains_token
194
+ return nil
175
195
  end
196
+
176
197
  access_token
177
198
  end
178
199
 
179
200
  # The Authorization Code strategy
180
201
  #
181
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
202
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
182
203
  def auth_code
183
204
  @auth_code ||= OAuth2::Strategy::AuthCode.new(self)
184
205
  end
185
206
 
186
207
  # The Implicit strategy
187
208
  #
188
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2
209
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.2
189
210
  def implicit
190
211
  @implicit ||= OAuth2::Strategy::Implicit.new(self)
191
212
  end
192
213
 
193
214
  # The Resource Owner Password Credentials strategy
194
215
  #
195
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3
216
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
196
217
  def password
197
218
  @password ||= OAuth2::Strategy::Password.new(self)
198
219
  end
199
220
 
200
221
  # The Client Credentials strategy
201
222
  #
202
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4
223
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.4
203
224
  def client_credentials
204
225
  @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
205
226
  end
@@ -219,10 +240,10 @@ module OAuth2
219
240
  #
220
241
  # @api semipublic
221
242
  #
222
- # @see https://tools.ietf.org/html/rfc6749#section-4.1
223
- # @see https://tools.ietf.org/html/rfc6749#section-4.1.3
224
- # @see https://tools.ietf.org/html/rfc6749#section-4.2.1
225
- # @see https://tools.ietf.org/html/rfc6749#section-10.6
243
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1
244
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
245
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1
246
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-10.6
226
247
  # @return [Hash] the params to add to a request or URL
227
248
  def redirection_params
228
249
  if options[:redirect_uri]
@@ -239,19 +260,33 @@ module OAuth2
239
260
 
240
261
  private
241
262
 
263
+ # Returns the authenticator object
264
+ #
265
+ # @return [Authenticator] the initialized Authenticator
266
+ def authenticator
267
+ Authenticator.new(id, secret, options[:auth_scheme])
268
+ end
269
+
270
+ # Builds the access token from the response of the HTTP call
271
+ #
272
+ # @return [AccessToken] the initialized AccessToken
242
273
  def build_access_token(response, access_token_opts, extract_access_token)
243
274
  parsed_response = response.parsed.dup
244
275
  return unless parsed_response.is_a?(Hash)
245
276
 
246
277
  hash = parsed_response.merge(access_token_opts)
247
278
 
248
- # Provide backwards compatibility for old AcessToken.form_hash pattern
249
- # Should be deprecated in 2.x
279
+ # Provide backwards compatibility for old AccessToken.form_hash pattern
280
+ # Will be deprecated in 2.x
250
281
  if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
251
282
  extract_access_token.from_hash(self, hash)
252
283
  else
253
284
  extract_access_token.call(self, hash)
254
285
  end
255
286
  end
287
+
288
+ def oauth_debug_logging(builder)
289
+ builder.response :logger, options[:logger], :bodies => true if ENV['OAUTH_DEBUG'] == 'true'
290
+ end
256
291
  end
257
292
  end
data/lib/oauth2/error.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  class Error < StandardError
3
5
  attr_reader :response, :code, :description
@@ -23,7 +25,7 @@ module OAuth2
23
25
  def error_message(response_body, opts = {})
24
26
  message = []
25
27
 
26
- opts[:error_description] && message << opts[:error_description]
28
+ opts[:error_description] && (message << opts[:error_description])
27
29
 
28
30
  error_message = if opts[:error_description] && opts[:error_description].respond_to?(:encoding)
29
31
  script_encoding = opts[:error_description].encoding
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  require 'digest'
3
5
  require 'openssl'
@@ -95,24 +97,22 @@ module OAuth2
95
97
  #
96
98
  # @param [String] alg the algorithm to use (one of 'hmac-sha-1', 'hmac-sha-256')
97
99
  def algorithm=(alg)
98
- @algorithm = begin
99
- case alg.to_s
100
- when 'hmac-sha-1'
101
- begin
102
- OpenSSL::Digest('SHA1').new
103
- rescue StandardError
104
- OpenSSL::Digest.new('SHA1')
105
- end
106
- when 'hmac-sha-256'
107
- begin
108
- OpenSSL::Digest('SHA256').new
109
- rescue StandardError
110
- OpenSSL::Digest.new('SHA256')
111
- end
112
- else
113
- raise(ArgumentError, 'Unsupported algorithm')
114
- end
115
- end
100
+ @algorithm = case alg.to_s
101
+ when 'hmac-sha-1'
102
+ begin
103
+ OpenSSL::Digest('SHA1').new
104
+ rescue StandardError
105
+ OpenSSL::Digest.new('SHA1')
106
+ end
107
+ when 'hmac-sha-256'
108
+ begin
109
+ OpenSSL::Digest('SHA256').new
110
+ rescue StandardError
111
+ OpenSSL::Digest.new('SHA256')
112
+ end
113
+ else
114
+ raise(ArgumentError, 'Unsupported algorithm')
115
+ end
116
116
  end
117
117
 
118
118
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'multi_json'
2
4
  require 'multi_xml'
3
5
  require 'rack'
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'jwt'
2
4
 
3
5
  module OAuth2
4
6
  module Strategy
5
7
  # The Client Assertion Strategy
6
8
  #
7
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.3
9
+ # @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-10#section-4.1.3
8
10
  #
9
11
  # Sample usage:
10
12
  # client = OAuth2::Client.new(client_id, client_secret,
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  module Strategy
3
5
  # The Authorization Code Strategy
4
6
  #
5
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
7
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
6
8
  class AuthCode < Base
7
9
  # The required query parameters for the authorize URL
8
10
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  module Strategy
3
5
  class Base
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  module Strategy
3
5
  # The Client Credentials Strategy
4
6
  #
5
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4
7
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.4
6
8
  class ClientCredentials < Base
7
9
  # Not used for this strategy
8
10
  #
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  module Strategy
3
5
  # The Implicit Strategy
4
6
  #
5
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2
7
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.2
6
8
  class Implicit < Base
7
9
  # The required query parameters for the authorize URL
8
10
  #
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
4
  module Strategy
3
5
  # The Resource Owner Password Credentials Authorization Strategy
4
6
  #
5
- # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3
7
+ # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
6
8
  class Password < Base
7
9
  # Not used for this strategy
8
10
  #
@@ -24,7 +24,7 @@ module OAuth2
24
24
  #
25
25
  # @return [Integer]
26
26
  def patch
27
- 7
27
+ 9
28
28
  end
29
29
 
30
30
  # The pre-release version, if any
data/lib/oauth2.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'oauth2/error'
2
4
  require 'oauth2/authenticator'
3
5
  require 'oauth2/client'
@@ -0,0 +1,11 @@
1
+ # RS256
2
+
3
+ ## How keys were made
4
+
5
+ ```shell
6
+ # No passphrase
7
+ # Generates the public and private keys:
8
+ ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key
9
+ # Converts the key to PEM format
10
+ openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
11
+ ```
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,14 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5hdXV/4YSymY1T9VNvK2
3
+ bWRfulwIty1RnAPNINQmfh3aRRkV+PNrbC2Crji9G0AHmQwgW1bZ3kgkkpIm6RVn
4
+ 44fHvBvuXkZ9ABgXw0d2cLIHmwOFxSKmWAm/EW//GszUTLLLsMZUe2udtFJW0jxX
5
+ B2GRY0WVYuo6Oo58RCeP719lw3Ags0YF9/IobxKkGd4BautUPw6ZszAa3o+j0zR7
6
+ 4x7ouPxybZAOuPsMxqanyeYJeH4osJjLMYV9qem9uG2sj7GENJ8UszcpmGbqxBhe
7
+ xPEB7mgDeONIF0XJF23zdOf8ANE5mAU2h2v7M6moAfkdUzJ+j48+VT2omHAzAL5y
8
+ Ncmrl2xiWdyoxOw1Y1UmfEmJYV5VgGYyZ12JZRKY+szPT+vR+MDuYxbquF40O7kv
9
+ kFNBfL1yCpzfSQCLnEs4rX8qRzZXciLeyq4Ht5FLuRFgxjA//XI8LAmp0u7gk+Q7
10
+ FUH1UgW3kmJDTG0XaxQxYTBSIO7mcmyjDyBgKVuQmt5E1ycFeteOVdPD/CG/fPYh
11
+ thvc4UytEFwsMdNy3iD6/wuUH68tAKam28UZaOb0qK+00cQQD8fulY9rKtSL10Lv
12
+ JFWUOa/SJyLvk9vUmfvFn182il1nX6GpyxyMmE/FCnH4CT/DjrSZf08mOO8eL5of
13
+ YHMK/oiXr1eODqx+pOwClNsCAwEAAQ==
14
+ -----END PUBLIC KEY-----
data/spec/helper.rb CHANGED
@@ -1,25 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  DEBUG = ENV['DEBUG'] == 'true'
4
+ RUN_COVERAGE = ENV['CI_CODECOV'] || ENV['CI'].nil?
2
5
 
3
6
  ruby_version = Gem::Version.new(RUBY_VERSION)
7
+ minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
8
+ coverage = minimum_version.call('2.7') && RUN_COVERAGE
9
+ debug = minimum_version.call('2.5') && DEBUG
4
10
 
5
- if ruby_version >= Gem::Version.new('2.7')
6
- require 'simplecov'
7
- require 'coveralls'
8
-
9
- SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
10
-
11
- SimpleCov.start do
12
- add_filter '/spec'
13
- minimum_coverage(95)
14
- end
15
- end
16
-
17
- require 'byebug' if DEBUG && ruby_version >= Gem::Version.new('2.4')
11
+ require 'simplecov' if coverage
12
+ require 'byebug' if debug
18
13
 
19
14
  require 'oauth2'
20
15
  require 'addressable/uri'
21
16
  require 'rspec'
22
17
  require 'rspec/stubbed_env'
18
+ require 'rspec/pending_for'
23
19
  require 'silent_stream'
24
20
 
25
21
  RSpec.configure do |config|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe OAuth2::AccessToken do
2
4
  subject { described_class.new(client, token) }
3
5
 
@@ -30,7 +32,7 @@ describe OAuth2::AccessToken do
30
32
  expect(target.params['foo']).to eq('bar')
31
33
  end
32
34
 
33
- def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
35
+ def assert_initialized_token(target)
34
36
  expect(target.token).to eq(token)
35
37
  expect(target).to be_expires
36
38
  expect(target.params.keys).to include('foo')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe OAuth2::Authenticator do
2
4
  subject do
3
5
  described_class.new(client_id, client_secret, mode)