oauth2 1.4.10 → 2.0.0.rc1

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.
@@ -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
- 10
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.10
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
8
- - Erik Michaels-Ober
9
8
  - Michael Bleigh
9
+ - Erik Michaels-Ober
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-07-01 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
+ - - ">="
121
+ - !ruby/object:Gem::Version
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
+ - - ">="
115
135
  - !ruby/object:Gem::Version
116
- version: '2.3'
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
@@ -216,22 +236,16 @@ dependencies:
216
236
  name: rubocop-lts
217
237
  requirement: !ruby/object:Gem::Requirement
218
238
  requirements:
219
- - - ">="
220
- - !ruby/object:Gem::Version
221
- version: 2.0.3
222
239
  - - "~>"
223
240
  - !ruby/object:Gem::Version
224
- version: '2.0'
241
+ version: '8.0'
225
242
  type: :development
226
243
  prerelease: false
227
244
  version_requirements: !ruby/object:Gem::Requirement
228
245
  requirements:
229
- - - ">="
230
- - !ruby/object:Gem::Version
231
- version: 2.0.3
232
246
  - - "~>"
233
247
  - !ruby/object:Gem::Version
234
- version: '2.0'
248
+ version: '8.0'
235
249
  - !ruby/object:Gem::Dependency
236
250
  name: silent_stream
237
251
  requirement: !ruby/object:Gem::Requirement
@@ -265,8 +279,8 @@ files:
265
279
  - lib/oauth2/authenticator.rb
266
280
  - lib/oauth2/client.rb
267
281
  - lib/oauth2/error.rb
268
- - lib/oauth2/mac_token.rb
269
282
  - lib/oauth2/response.rb
283
+ - lib/oauth2/snaky_hash.rb
270
284
  - lib/oauth2/strategy/assertion.rb
271
285
  - lib/oauth2/strategy/auth_code.rb
272
286
  - lib/oauth2/strategy/base.rb
@@ -278,27 +292,14 @@ homepage: https://github.com/oauth-xx/oauth2
278
292
  licenses:
279
293
  - MIT
280
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
281
298
  bug_tracker_uri: https://github.com/oauth-xx/oauth2/issues
282
- changelog_uri: https://github.com/oauth-xx/oauth2/blob/v1.4.10/CHANGELOG.md
283
- documentation_uri: https://www.rubydoc.info/gems/oauth2/1.4.10
284
- source_code_uri: https://github.com/oauth-xx/oauth2/tree/v1.4.10
299
+ documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.0.rc1
285
300
  wiki_uri: https://github.com/oauth-xx/oauth2/wiki
286
- funding_uri: https://github.com/sponsors/pboling
287
301
  rubygems_mfa_required: 'true'
288
- post_install_message: |2+
289
-
290
- You have installed oauth2 version 1.4.10, which is EOL.
291
- No further support is anticipated for the 1.4.x series.
292
-
293
- OAuth2 version 2 is released.
294
- There are BREAKING changes, but most will not encounter them, and upgrading should be easy!
295
-
296
- Please see:
297
- • https://github.com/oauth-xx/oauth2#what-is-new-for-v20
298
- • https://github.com/oauth-xx/oauth2/blob/master/CHANGELOG.md
299
-
300
- Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
301
-
302
+ post_install_message:
302
303
  rdoc_options: []
303
304
  require_paths:
304
305
  - lib
@@ -306,14 +307,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
306
307
  requirements:
307
308
  - - ">="
308
309
  - !ruby/object:Gem::Version
309
- version: 1.9.0
310
+ version: 2.2.0
310
311
  required_rubygems_version: !ruby/object:Gem::Requirement
311
312
  requirements:
312
- - - ">="
313
+ - - ">"
313
314
  - !ruby/object:Gem::Version
314
- version: '0'
315
+ version: 1.3.1
315
316
  requirements: []
316
- rubygems_version: 3.3.16
317
+ rubygems_version: 3.3.15
317
318
  signing_key:
318
319
  specification_version: 4
319
320
  summary: A Ruby wrapper for the OAuth 2.0 protocol.