oauth2 1.4.9 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,15 +10,22 @@ module OAuth2
10
10
  #
11
11
  # Sample usage:
12
12
  # client = OAuth2::Client.new(client_id, client_secret,
13
- # :site => 'http://localhost:8080')
13
+ # :site => 'http://localhost:8080',
14
+ # :auth_scheme => :request_body)
14
15
  #
15
- # params = {:hmac_secret => "some secret",
16
- # # or :private_key => "private key string",
17
- # :iss => "http://localhost:3001",
18
- # :prn => "me@here.com",
19
- # :exp => Time.now.utc.to_i + 3600}
16
+ # claim_set = {
17
+ # :iss => "http://localhost:3001",
18
+ # :aud => "http://localhost:8080/oauth2/token"
19
+ # :sub => "me@example.com",
20
+ # :exp => Time.now.utc.to_i + 3600,
21
+ # }
20
22
  #
21
- # access = client.assertion.get_token(params)
23
+ # encoding = {
24
+ # :algorithm => 'HS256',
25
+ # :key => 'secret_key',
26
+ # }
27
+ #
28
+ # access = client.assertion.get_token(claim_set, encoding)
22
29
  # access.token # actual access_token string
23
30
  # access.get("/api/stuff") # making api calls with access token in header
24
31
  #
@@ -32,45 +39,63 @@ module OAuth2
32
39
 
33
40
  # Retrieve an access token given the specified client.
34
41
  #
35
- # @param [Hash] params assertion params
36
- # pass either :hmac_secret or :private_key, but not both.
42
+ # @param [Hash] claims the hash representation of the claims that should be encoded as a JWT (JSON Web Token)
43
+ #
44
+ # For reading on JWT and claim keys:
45
+ # @see https://github.com/jwt/ruby-jwt
46
+ # @see https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
47
+ # @see https://datatracker.ietf.org/doc/html/rfc7523#section-3
48
+ # @see https://www.iana.org/assignments/jwt/jwt.xhtml
49
+ #
50
+ # There are many possible claim keys, and applications may ask for their own custom keys.
51
+ # Some typically required ones:
52
+ # :iss (issuer)
53
+ # :aud (audience)
54
+ # :sub (subject) -- formerly :prn https://datatracker.ietf.org/doc/html/draft-ietf-oauth-json-web-token-06#appendix-F
55
+ # :exp, (expiration time) -- in seconds, e.g. Time.now.utc.to_i + 3600
56
+ #
57
+ # Note that this method does *not* validate presence of those four claim keys indicated as required by RFC 7523.
58
+ # There are endpoints that may not conform with this RFC, and this gem should still work for those use cases.
59
+ #
60
+ # @param [Hash] encoding_opts a hash containing instructions on how the JWT should be encoded
61
+ # @option algorithm [String] the algorithm with which you would like the JWT to be encoded
62
+ # @option key [Object] the key with which you would like to encode the JWT
37
63
  #
38
- # params :hmac_secret, secret string.
39
- # params :private_key, private key string.
64
+ # These two options are passed directly to `JWT.encode`. For supported encoding arguments:
65
+ # @see https://github.com/jwt/ruby-jwt#algorithms-and-usage
66
+ # @see https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
40
67
  #
41
- # params :iss, issuer
42
- # params :aud, audience, optional
43
- # params :prn, principal, current user
44
- # params :exp, expired at, in seconds, like Time.now.utc.to_i + 3600
68
+ # The object type of `:key` may depend on the value of `:algorithm`. Sample arguments:
69
+ # get_token(claim_set, {:algorithm => 'HS256', :key => 'secret_key'})
70
+ # get_token(claim_set, {:algorithm => 'RS256', :key => OpenSSL::PKCS12.new(File.read('my_key.p12'), 'not_secret')})
45
71
  #
46
- # @param [Hash] opts options
47
- def get_token(params = {}, opts = {})
48
- hash = build_request(params)
49
- @client.get_token(hash, opts.merge('refresh_token' => nil))
72
+ # @param [Hash] request_opts options that will be used to assemble the request
73
+ # @option request_opts [String] :scope the url parameter `scope` that may be required by some endpoints
74
+ # @see https://datatracker.ietf.org/doc/html/rfc7521#section-4.1
75
+ #
76
+ # @param [Hash] response_opts this will be merged with the token response to create the AccessToken object
77
+ # @see the access_token_opts argument to Client#get_token
78
+
79
+ def get_token(claims, encoding_opts, request_opts = {}, response_opts = {})
80
+ assertion = build_assertion(claims, encoding_opts)
81
+ params = build_request(assertion, request_opts)
82
+
83
+ @client.get_token(params, response_opts.merge('refresh_token' => nil))
50
84
  end
51
85
 
52
- def build_request(params)
53
- assertion = build_assertion(params)
86
+ private
87
+
88
+ def build_request(assertion, request_opts = {})
54
89
  {
55
- :grant_type => 'assertion',
56
- :assertion_type => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
57
- :assertion => assertion,
58
- :scope => params[:scope],
59
- }
90
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
91
+ assertion: assertion,
92
+ }.merge(request_opts)
60
93
  end
61
94
 
62
- def build_assertion(params)
63
- claims = {
64
- :iss => params[:iss],
65
- :aud => params[:aud],
66
- :prn => params[:prn],
67
- :exp => params[:exp],
68
- }
69
- if params[:hmac_secret]
70
- JWT.encode(claims, params[:hmac_secret], 'HS256')
71
- elsif params[:private_key]
72
- JWT.encode(claims, params[:private_key], 'RS256')
73
- end
95
+ def build_assertion(claims, encoding_opts)
96
+ raise ArgumentError.new(message: 'Please provide an encoding_opts hash with :algorithm and :key') if !encoding_opts.is_a?(Hash) || (%i[algorithm key] - encoding_opts.keys).any?
97
+
98
+ JWT.encode(claims, encoding_opts[:key], encoding_opts[:algorithm])
74
99
  end
75
100
  end
76
101
  end
@@ -17,6 +17,7 @@ module OAuth2
17
17
  #
18
18
  # @param [Hash] params additional query parameters for the URL
19
19
  def authorize_url(params = {})
20
+ assert_valid_params(params)
20
21
  @client.authorize_url(authorize_params.merge(params))
21
22
  end
22
23
 
@@ -28,8 +29,18 @@ module OAuth2
28
29
  # @note that you must also provide a :redirect_uri with most OAuth 2.0 providers
29
30
  def get_token(code, params = {}, opts = {})
30
31
  params = {'grant_type' => 'authorization_code', 'code' => code}.merge(@client.redirection_params).merge(params)
32
+ params_dup = params.dup
33
+ params.each_key do |key|
34
+ params_dup[key.to_s] = params_dup.delete(key) if key.is_a?(Symbol)
35
+ end
31
36
 
32
- @client.get_token(params, opts)
37
+ @client.get_token(params_dup, opts)
38
+ end
39
+
40
+ private
41
+
42
+ def assert_valid_params(params)
43
+ raise(ArgumentError, 'client_secret is not allowed in authorize URL query params') if params.key?(:client_secret) || params.key?('client_secret')
33
44
  end
34
45
  end
35
46
  end
@@ -17,6 +17,7 @@ module OAuth2
17
17
  #
18
18
  # @param [Hash] params additional query parameters for the URL
19
19
  def authorize_url(params = {})
20
+ assert_valid_params(params)
20
21
  @client.authorize_url(authorize_params.merge(params))
21
22
  end
22
23
 
@@ -26,6 +27,12 @@ module OAuth2
26
27
  def get_token(*)
27
28
  raise(NotImplementedError, 'The token is accessed differently in this strategy')
28
29
  end
30
+
31
+ private
32
+
33
+ def assert_valid_params(params)
34
+ raise(ArgumentError, 'client_secret is not allowed in authorize URL query params') if params.key?(:client_secret) || params.key?('client_secret')
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -2,36 +2,43 @@
2
2
 
3
3
  module OAuth2
4
4
  module Version
5
- VERSION = to_s
5
+ VERSION = '2.0.0.rc1'.freeze
6
6
 
7
7
  module_function
8
8
 
9
+ # The version number as a string
10
+ #
11
+ # @return [String]
12
+ def to_s
13
+ VERSION
14
+ end
15
+
9
16
  # The major version
10
17
  #
11
18
  # @return [Integer]
12
19
  def major
13
- 1
20
+ to_a[0].to_i
14
21
  end
15
22
 
16
23
  # The minor version
17
24
  #
18
25
  # @return [Integer]
19
26
  def minor
20
- 4
27
+ to_a[1].to_i
21
28
  end
22
29
 
23
30
  # The patch version
24
31
  #
25
32
  # @return [Integer]
26
33
  def patch
27
- 9
34
+ to_a[2].to_i
28
35
  end
29
36
 
30
37
  # The pre-release version, if any
31
38
  #
32
39
  # @return [String, NilClass]
33
40
  def pre
34
- nil
41
+ to_a[3]
35
42
  end
36
43
 
37
44
  # The version number as a hash
@@ -39,10 +46,10 @@ module OAuth2
39
46
  # @return [Hash]
40
47
  def to_h
41
48
  {
42
- :major => major,
43
- :minor => minor,
44
- :patch => patch,
45
- :pre => pre,
49
+ major: major,
50
+ minor: minor,
51
+ patch: patch,
52
+ pre: pre,
46
53
  }
47
54
  end
48
55
 
@@ -50,16 +57,7 @@ module OAuth2
50
57
  #
51
58
  # @return [Array]
52
59
  def to_a
53
- [major, minor, patch, pre].compact
54
- end
55
-
56
- # The version number as a string
57
- #
58
- # @return [String]
59
- def to_s
60
- v = [major, minor, patch].compact.join('.')
61
- v += "-#{pre}" if pre
62
- v
60
+ VERSION.split('.')
63
61
  end
64
62
  end
65
63
  end
data/lib/oauth2.rb CHANGED
@@ -1,6 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # includes modules from stdlib
4
+ require 'cgi'
5
+ require 'time'
6
+
7
+ # third party gems
8
+ require 'rash'
9
+
10
+ # includes gem files
11
+ require 'oauth2/version'
3
12
  require 'oauth2/error'
13
+ require 'oauth2/snaky_hash'
4
14
  require 'oauth2/authenticator'
5
15
  require 'oauth2/client'
6
16
  require 'oauth2/strategy/base'
@@ -10,5 +20,8 @@ require 'oauth2/strategy/password'
10
20
  require 'oauth2/strategy/client_credentials'
11
21
  require 'oauth2/strategy/assertion'
12
22
  require 'oauth2/access_token'
13
- require 'oauth2/mac_token'
14
23
  require 'oauth2/response'
24
+
25
+ # The namespace of this library
26
+ module OAuth2
27
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.9
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
8
8
  - Michael Bleigh
9
9
  - Erik Michaels-Ober
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-02-20 00:00:00.000000000 Z
13
+ date: 2022-06-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday
@@ -53,123 +53,143 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: multi_json
56
+ name: multi_xml
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.3'
61
+ version: '0.5'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.3'
68
+ version: '0.5'
69
69
  - !ruby/object:Gem::Dependency
70
- name: multi_xml
70
+ name: rack
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0.5'
75
+ version: '1.2'
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: '3'
76
79
  type: :runtime
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
80
- - - "~>"
83
+ - - ">="
81
84
  - !ruby/object:Gem::Version
82
- version: '0.5'
85
+ version: '1.2'
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '3'
83
89
  - !ruby/object:Gem::Dependency
84
- name: rack
90
+ name: rash_alt
85
91
  requirement: !ruby/object:Gem::Requirement
86
92
  requirements:
87
93
  - - ">="
88
94
  - !ruby/object:Gem::Version
89
- version: '1.2'
95
+ version: '0.4'
90
96
  - - "<"
91
97
  - !ruby/object:Gem::Version
92
- version: '3'
98
+ version: '1'
93
99
  type: :runtime
94
100
  prerelease: false
95
101
  version_requirements: !ruby/object:Gem::Requirement
96
102
  requirements:
97
103
  - - ">="
98
104
  - !ruby/object:Gem::Version
99
- version: '1.2'
105
+ version: '0.4'
100
106
  - - "<"
101
107
  - !ruby/object:Gem::Version
102
- version: '3'
108
+ version: '1'
103
109
  - !ruby/object:Gem::Dependency
104
110
  name: addressable
105
111
  requirement: !ruby/object:Gem::Requirement
106
112
  requirements:
107
- - - "~>"
113
+ - - ">="
108
114
  - !ruby/object:Gem::Version
109
- version: '2.3'
115
+ version: '2'
110
116
  type: :development
111
117
  prerelease: false
112
118
  version_requirements: !ruby/object:Gem::Requirement
113
119
  requirements:
114
- - - "~>"
120
+ - - ">="
115
121
  - !ruby/object:Gem::Version
116
- version: '2.3'
122
+ version: '2'
123
+ - !ruby/object:Gem::Dependency
124
+ name: backports
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '3'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '3'
117
137
  - !ruby/object:Gem::Dependency
118
138
  name: bundler
119
139
  requirement: !ruby/object:Gem::Requirement
120
140
  requirements:
121
141
  - - ">="
122
142
  - !ruby/object:Gem::Version
123
- version: '1.16'
143
+ version: '2'
124
144
  type: :development
125
145
  prerelease: false
126
146
  version_requirements: !ruby/object:Gem::Requirement
127
147
  requirements:
128
148
  - - ">="
129
149
  - !ruby/object:Gem::Version
130
- version: '1.16'
150
+ version: '2'
131
151
  - !ruby/object:Gem::Dependency
132
152
  name: rake
133
153
  requirement: !ruby/object:Gem::Requirement
134
154
  requirements:
135
- - - "~>"
155
+ - - ">="
136
156
  - !ruby/object:Gem::Version
137
- version: '12.3'
157
+ version: '12'
138
158
  type: :development
139
159
  prerelease: false
140
160
  version_requirements: !ruby/object:Gem::Requirement
141
161
  requirements:
142
- - - "~>"
162
+ - - ">="
143
163
  - !ruby/object:Gem::Version
144
- version: '12.3'
164
+ version: '12'
145
165
  - !ruby/object:Gem::Dependency
146
166
  name: rexml
147
167
  requirement: !ruby/object:Gem::Requirement
148
168
  requirements:
149
- - - "~>"
169
+ - - ">="
150
170
  - !ruby/object:Gem::Version
151
- version: '3.2'
171
+ version: '3'
152
172
  type: :development
153
173
  prerelease: false
154
174
  version_requirements: !ruby/object:Gem::Requirement
155
175
  requirements:
156
- - - "~>"
176
+ - - ">="
157
177
  - !ruby/object:Gem::Version
158
- version: '3.2'
178
+ version: '3'
159
179
  - !ruby/object:Gem::Dependency
160
180
  name: rspec
161
181
  requirement: !ruby/object:Gem::Requirement
162
182
  requirements:
163
- - - "~>"
183
+ - - ">="
164
184
  - !ruby/object:Gem::Version
165
- version: '3.0'
185
+ version: '3'
166
186
  type: :development
167
187
  prerelease: false
168
188
  version_requirements: !ruby/object:Gem::Requirement
169
189
  requirements:
170
- - - "~>"
190
+ - - ">="
171
191
  - !ruby/object:Gem::Version
172
- version: '3.0'
192
+ version: '3'
173
193
  - !ruby/object:Gem::Dependency
174
194
  name: rspec-block_is_expected
175
195
  requirement: !ruby/object:Gem::Requirement
@@ -212,6 +232,20 @@ dependencies:
212
232
  - - ">="
213
233
  - !ruby/object:Gem::Version
214
234
  version: '0'
235
+ - !ruby/object:Gem::Dependency
236
+ name: rubocop-lts
237
+ requirement: !ruby/object:Gem::Requirement
238
+ requirements:
239
+ - - "~>"
240
+ - !ruby/object:Gem::Version
241
+ version: '8.0'
242
+ type: :development
243
+ prerelease: false
244
+ version_requirements: !ruby/object:Gem::Requirement
245
+ requirements:
246
+ - - "~>"
247
+ - !ruby/object:Gem::Version
248
+ version: '8.0'
215
249
  - !ruby/object:Gem::Dependency
216
250
  name: silent_stream
217
251
  requirement: !ruby/object:Gem::Requirement
@@ -236,15 +270,17 @@ extra_rdoc_files: []
236
270
  files:
237
271
  - CHANGELOG.md
238
272
  - CODE_OF_CONDUCT.md
273
+ - CONTRIBUTING.md
239
274
  - LICENSE
240
275
  - README.md
276
+ - SECURITY.md
241
277
  - lib/oauth2.rb
242
278
  - lib/oauth2/access_token.rb
243
279
  - lib/oauth2/authenticator.rb
244
280
  - lib/oauth2/client.rb
245
281
  - lib/oauth2/error.rb
246
- - lib/oauth2/mac_token.rb
247
282
  - lib/oauth2/response.rb
283
+ - lib/oauth2/snaky_hash.rb
248
284
  - lib/oauth2/strategy/assertion.rb
249
285
  - lib/oauth2/strategy/auth_code.rb
250
286
  - lib/oauth2/strategy/base.rb
@@ -252,33 +288,18 @@ files:
252
288
  - lib/oauth2/strategy/implicit.rb
253
289
  - lib/oauth2/strategy/password.rb
254
290
  - lib/oauth2/version.rb
255
- - spec/fixtures/README.md
256
- - spec/fixtures/RS256/jwtRS256.key
257
- - spec/fixtures/RS256/jwtRS256.key.pub
258
- - spec/helper.rb
259
- - spec/oauth2/access_token_spec.rb
260
- - spec/oauth2/authenticator_spec.rb
261
- - spec/oauth2/client_spec.rb
262
- - spec/oauth2/mac_token_spec.rb
263
- - spec/oauth2/response_spec.rb
264
- - spec/oauth2/strategy/assertion_spec.rb
265
- - spec/oauth2/strategy/auth_code_spec.rb
266
- - spec/oauth2/strategy/base_spec.rb
267
- - spec/oauth2/strategy/client_credentials_spec.rb
268
- - spec/oauth2/strategy/implicit_spec.rb
269
- - spec/oauth2/strategy/password_spec.rb
270
- - spec/oauth2/version_spec.rb
271
291
  homepage: https://github.com/oauth-xx/oauth2
272
292
  licenses:
273
293
  - MIT
274
294
  metadata:
295
+ homepage_uri: https://github.com/oauth-xx/oauth2
296
+ source_code_uri: https://github.com/oauth-xx/oauth2/tree/v2.0.0.rc1
297
+ changelog_uri: https://github.com/oauth-xx/oauth2/blob/v2.0.0.rc1/CHANGELOG.md
275
298
  bug_tracker_uri: https://github.com/oauth-xx/oauth2/issues
276
- changelog_uri: https://github.com/oauth-xx/oauth2/blob/v1.4.9/CHANGELOG.md
277
- documentation_uri: https://www.rubydoc.info/gems/oauth2/1.4.9
278
- source_code_uri: https://github.com/oauth-xx/oauth2/tree/v1.4.9
299
+ documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.0.rc1
279
300
  wiki_uri: https://github.com/oauth-xx/oauth2/wiki
280
301
  rubygems_mfa_required: 'true'
281
- post_install_message:
302
+ post_install_message:
282
303
  rdoc_options: []
283
304
  require_paths:
284
305
  - lib
@@ -286,31 +307,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
286
307
  requirements:
287
308
  - - ">="
288
309
  - !ruby/object:Gem::Version
289
- version: 1.9.0
310
+ version: 2.2.0
290
311
  required_rubygems_version: !ruby/object:Gem::Requirement
291
312
  requirements:
292
- - - ">="
313
+ - - ">"
293
314
  - !ruby/object:Gem::Version
294
- version: 1.3.5
315
+ version: 1.3.1
295
316
  requirements: []
296
- rubygems_version: 3.3.7
297
- signing_key:
317
+ rubygems_version: 3.3.15
318
+ signing_key:
298
319
  specification_version: 4
299
320
  summary: A Ruby wrapper for the OAuth 2.0 protocol.
300
- test_files:
301
- - spec/fixtures/README.md
302
- - spec/fixtures/RS256/jwtRS256.key
303
- - spec/fixtures/RS256/jwtRS256.key.pub
304
- - spec/helper.rb
305
- - spec/oauth2/access_token_spec.rb
306
- - spec/oauth2/authenticator_spec.rb
307
- - spec/oauth2/client_spec.rb
308
- - spec/oauth2/mac_token_spec.rb
309
- - spec/oauth2/response_spec.rb
310
- - spec/oauth2/strategy/assertion_spec.rb
311
- - spec/oauth2/strategy/auth_code_spec.rb
312
- - spec/oauth2/strategy/base_spec.rb
313
- - spec/oauth2/strategy/client_credentials_spec.rb
314
- - spec/oauth2/strategy/implicit_spec.rb
315
- - spec/oauth2/strategy/password_spec.rb
316
- - spec/oauth2/version_spec.rb
321
+ test_files: []