omniauth-oauth2 1.2.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 34d25ec93bea77d3d2003a6aa2072dfa427f9e37
4
- data.tar.gz: 89be10c650c34a5585147ef113f20c8f562b36f6
2
+ SHA256:
3
+ metadata.gz: f5cd52cdcb930eb0df65da3d7659a8e46f19db3426e0ecd8b3565b51e951331f
4
+ data.tar.gz: 6ed5b399aef49e82b265ff6175c849c44415f8b19f81ee5eb5d988ebb6c95fc8
5
5
  SHA512:
6
- metadata.gz: 19d5f076d435e34138b5beb42214e1a2cc22e3f6145e8030d64d644a91b250de0f3b7e34dda04d49a020e0bc3347b7cfdcb5b8942910cafec095286da1dbb310
7
- data.tar.gz: b997b90fa32ffa10c1e27ae5095acea1793ae9d4ecb160856de82a4a53a64cdcc60f9c352a8c114e50a50c13c3ff024174cbcdc573caa4411d18f17e95aba385
6
+ metadata.gz: e6bc5b97b326e37aa1e2ebb294b3459b57ba5dbb4d1e8b7e1709ed2dc9cfb8cc3b1b6f70ebbd0d5d830834af2472afe5b34762cf63f99a508334edee0d86b15a
7
+ data.tar.gz: 5c6cea848d8c9895495f7e931a3acfcee6e5e773824714e4de8bacfdc7aa70c3e40ad5cbce92b9a0d115f1dbd1f26aea7dc2b7a7bc02b1050cf38c501c3b7d45
@@ -0,0 +1,2 @@
1
+ github: bobbymcwho
2
+ tidelift: rubygems/omniauth-oauth2
@@ -0,0 +1,67 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-18.04
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu, macos]
16
+ ruby: [2.5, 2.6, 2.7, '3.0', 3.1, head, debug, truffleruby, truffleruby-head]
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ bundler-cache: true
24
+ - name: Install dependencies
25
+ run: bundle install
26
+ - name: Run tests
27
+ run: bundle exec rake
28
+ test-jruby:
29
+ runs-on: ubuntu-18.04
30
+ strategy:
31
+ fail-fast: false
32
+ matrix:
33
+ os: [ubuntu, macos]
34
+ jruby: [jruby, jruby-head]
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - name: Set up Ruby
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: ${{ matrix.jruby }}
41
+ bundler-cache: true
42
+ - name: Install dependencies
43
+ env:
44
+ JRUBY_OPTS: --debug
45
+ run: bundle install
46
+ - name: Run tests
47
+ env:
48
+ JRUBY_OPTS: --debug
49
+ run: bundle exec rake
50
+ coveralls:
51
+ runs-on: ubuntu-18.04
52
+ steps:
53
+ - uses: actions/checkout@v2
54
+ - name: Set up Ruby
55
+ uses: ruby/setup-ruby@v1
56
+ with:
57
+ ruby-version: 2.6
58
+ bundler-cache: true
59
+ - name: Install dependencies
60
+ run: bundle install
61
+ - name: Run tests
62
+ run: bundle exec rake
63
+ - name: Coveralls GitHub Action
64
+ uses: coverallsapp/github-action@v1.1.2
65
+ with:
66
+ github-token: ${{ secrets.github_token }}
67
+ path-to-lcov: './coverage/lcov/omniauth-oauth2.lcov'
data/.rubocop.yml CHANGED
@@ -1,82 +1,80 @@
1
1
  AllCops:
2
- Include:
3
- - 'Gemfile'
4
- - 'Rakefile'
5
- - 'omniauth-oauth2.gemspec'
6
-
7
- # Avoid long parameter lists
8
- ParameterLists:
9
- Max: 5
10
- CountKeywordArgs: true
2
+ NewCops: enable
11
3
 
12
- MethodLength:
13
- CountComments: false
4
+ Gemspec/RequiredRubyVersion:
5
+ Enabled: false
6
+
7
+ Layout/AccessModifierIndentation:
8
+ EnforcedStyle: outdent
9
+
10
+ Layout/LineLength:
11
+ AllowURI: true
12
+ Enabled: false
13
+
14
+ Layout/SpaceInsideHashLiteralBraces:
15
+ EnforcedStyle: no_space
16
+
17
+ Lint/MissingSuper:
18
+ Enabled: false
19
+
20
+ Metrics/AbcSize:
14
21
  Max: 18
15
22
 
16
- # Avoid more than `Max` levels of nesting.
17
- BlockNesting:
23
+ Metrics/BlockLength:
24
+ Exclude:
25
+ - spec/omniauth/strategies/oauth2_spec.rb
26
+
27
+ Metrics/BlockNesting:
18
28
  Max: 2
19
29
 
20
- # Align with the style guide.
21
- CollectionMethods:
30
+ Metrics/ClassLength:
31
+ Max: 110
32
+
33
+ Metrics/MethodLength:
34
+ CountComments: false
35
+ Max: 10
36
+
37
+ Metrics/ParameterLists:
38
+ Max: 4
39
+ CountKeywordArgs: true
40
+
41
+ Naming/FileName:
42
+ Exclude:
43
+ - lib/omniauth-oauth2.rb
44
+
45
+ Style/CollectionMethods:
22
46
  PreferredMethods:
23
47
  map: 'collect'
24
48
  reduce: 'inject'
25
49
  find: 'detect'
26
50
  find_all: 'select'
27
51
 
28
- # Do not force public/protected/private keyword to be indented at the same
29
- # level as the def keyword. My personal preference is to outdent these keywords
30
- # because I think when scanning code it makes it easier to identify the
31
- # sections of code and visually separate them. When the keyword is at the same
32
- # level I think it sort of blends in with the def keywords and makes it harder
33
- # to scan the code and see where the sections are.
34
- AccessModifierIndentation:
35
- Enabled: false
36
-
37
- # Limit line length
38
- LineLength:
52
+ Style/Documentation:
39
53
  Enabled: false
40
54
 
41
- # Disable documentation checking until a class needs to be documented once
42
- Documentation:
55
+ Style/DoubleNegation:
43
56
  Enabled: false
44
57
 
45
- # Enforce Ruby 1.8-compatible hash syntax
46
- HashSyntax:
47
- EnforcedStyle: hash_rockets
48
-
49
- # No spaces inside hash literals
50
- SpaceInsideHashLiteralBraces:
51
- EnforcedStyle: no_space
52
-
53
- # Allow dots at the end of lines
54
- DotPosition:
58
+ Style/ExpandPathArguments:
55
59
  Enabled: false
56
60
 
57
- # Don't require magic comment at the top of every file
58
- Encoding:
61
+ Style/FrozenStringLiteralComment:
59
62
  Enabled: false
60
63
 
61
- # Enforce outdenting of access modifiers (i.e. public, private, protected)
62
- AccessModifierIndentation:
63
- EnforcedStyle: outdent
64
+ Style/HashSyntax:
65
+ EnforcedStyle: hash_rockets
64
66
 
65
- EmptyLinesAroundAccessModifier:
66
- Enabled: true
67
+ Style/StderrPuts:
68
+ Enabled: false
67
69
 
68
- # Align ends correctly
69
- EndAlignment:
70
- AlignWith: variable
70
+ Style/StringLiterals:
71
+ EnforcedStyle: double_quotes
71
72
 
72
- # Indentation of when/else
73
- CaseIndentation:
74
- IndentWhenRelativeTo: end
75
- IndentOneStep: false
73
+ Style/TrailingCommaInArguments:
74
+ EnforcedStyleForMultiline: comma
76
75
 
77
- Lambda:
78
- Enabled: false
76
+ Style/TrailingCommaInHashLiteral:
77
+ EnforcedStyleForMultiline: comma
79
78
 
80
- FileName:
81
- Exclude:
82
- - 'lib/omniauth-oauth2.rb'
79
+ Style/TrailingCommaInArrayLiteral:
80
+ EnforcedStyleForMultiline: comma
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [v1.8.0](https://github.com/omniauth/omniauth-oauth2/releases/tag/v1.7.3)
2
+ - Relaxes allowed versions of the oauth2 gem. [#146](https://github.com/omniauth/omniauth-oauth2/pull/146)
3
+ - Requires omniauth `~> 2.0` [#152](https://github.com/omniauth/omniauth-oauth2/pull/152)
4
+
5
+ Please see https://github.com/omniauth/omniauth-oauth2/releases for changelog prior to 1.8.0
data/Gemfile CHANGED
@@ -1,24 +1,19 @@
1
- source 'http://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- gem 'rake'
4
-
5
- group :development do
6
- platforms :ruby_19, :ruby_20, :ruby_21 do
7
- gem 'guard'
8
- gem 'guard-rspec'
9
- gem 'guard-bundler'
10
- end
11
- end
3
+ gem "rake", "~> 13.0"
12
4
 
13
5
  group :test do
14
- gem 'coveralls', :require => false
15
- gem 'json', :platforms => [:jruby, :ruby_18, :ruby_19]
16
- gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
17
- gem 'rack-test'
18
- gem 'rspec', '~> 3.0.0'
19
- gem 'rubocop', '>= 0.21', :platforms => [:ruby_19, :ruby_20, :ruby_21]
20
- gem 'simplecov', :require => false
21
- gem 'webmock'
6
+ gem "addressable", "~> 2.3.8", :platforms => %i[jruby ruby_18]
7
+ gem 'coveralls_reborn', '~> 0.19.0', require: false
8
+ gem "json", :platforms => %i[jruby ruby_18 ruby_19]
9
+ gem "mime-types", "~> 1.25", :platforms => %i[jruby ruby_18]
10
+ gem "rack-test"
11
+ gem "rest-client", "~> 1.8.0", :platforms => %i[jruby ruby_18]
12
+ gem "rspec", "~> 3.2"
13
+ gem "rubocop", ">= 0.51", :platforms => %i[ruby_19 ruby_20 ruby_21 ruby_22 ruby_23 ruby_24]
14
+ gem 'simplecov-lcov'
15
+ gem 'tins', '~> 1.13', :platforms => %i[jruby_18 jruby_19 ruby_19]
16
+ gem "webmock", "~> 3.0"
22
17
  end
23
18
 
24
19
  # Specify your gem's dependencies in omniauth-oauth2.gemspec
data/README.md CHANGED
@@ -1,14 +1,11 @@
1
1
  # OmniAuth OAuth2
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/omniauth-oauth2.svg)][gem]
4
- [![Build Status](http://img.shields.io/travis/intridea/omniauth-oauth2.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/intridea/omniauth-oauth2.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/intridea/omniauth-oauth2.svg)][codeclimate]
4
+ [![Code Climate](http://img.shields.io/codeclimate/maintainability/intridea/omniauth-oauth2.svg)][codeclimate]
7
5
  [![Coverage Status](http://img.shields.io/coveralls/intridea/omniauth-oauth2.svg)][coveralls]
6
+ [![Security](https://hakiri.io/github/omniauth/omniauth-oauth2/master.svg)](https://hakiri.io/github/omniauth/omniauth-oauth2/master)
8
7
 
9
8
  [gem]: https://rubygems.org/gems/omniauth-oauth2
10
- [travis]: http://travis-ci.org/intridea/omniauth-oauth2
11
- [gemnasium]: https://gemnasium.com/intridea/omniauth-oauth2
12
9
  [codeclimate]: https://codeclimate.com/github/intridea/omniauth-oauth2
13
10
  [coveralls]: https://coveralls.io/r/intridea/omniauth-oauth2
14
11
 
@@ -34,6 +31,10 @@ module OmniAuth
34
31
  # initializing your consumer from the OAuth gem.
35
32
  option :client_options, {:site => "https://api.somesite.com"}
36
33
 
34
+ # You may specify that your strategy should use PKCE by setting
35
+ # the pkce option to true: https://tools.ietf.org/html/rfc7636
36
+ option :pkce, true
37
+
37
38
  # These are called after authentication has succeeded. If
38
39
  # possible, you should try to set the UID without making
39
40
  # additional calls (if the user id is returned with the token
@@ -64,4 +65,11 @@ end
64
65
 
65
66
  That's pretty much it!
66
67
 
67
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/intridea/omniauth-oauth2/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
68
+ ## OmniAuth-OAuth2 for Enterprise
69
+
70
+ Available as part of the Tidelift Subscription.
71
+
72
+ The maintainers of OmniAuth-OAuth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.](https://tidelift.com/subscription/pkg/rubygems-omniauth-oauth2?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise)
73
+
74
+ ## Supported Ruby Versions
75
+ OmniAuth is tested under 2.5, 2.6, 2.7, truffleruby, and JRuby.
data/Rakefile CHANGED
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
4
5
 
5
6
  RSpec::Core::RakeTask.new
6
7
 
7
8
  task :test => :spec
8
9
 
9
10
  begin
10
- require 'rubocop/rake_task'
11
+ require "rubocop/rake_task"
11
12
  RuboCop::RakeTask.new
12
13
  rescue LoadError
13
14
  task :rubocop do
14
- $stderr.puts 'RuboCop is disabled'
15
+ $stderr.puts "RuboCop is disabled"
15
16
  end
16
17
  end
17
18
 
18
- task :default => [:spec, :rubocop]
19
+ task :default => %i[spec rubocop]
data/SECURITY.md ADDED
@@ -0,0 +1,17 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Use this section to tell people about which versions of your project are
6
+ currently being supported with security updates.
7
+
8
+ | Version | Supported |
9
+ | ------- | ------------------ |
10
+ | 1.7.x | :white_check_mark: |
11
+ | <= 1.6.x | :x: |
12
+
13
+ ## Security contact information
14
+
15
+ To report a security vulnerability, please use the
16
+ [Tidelift security contact](https://tidelift.com/security).
17
+ Tidelift will coordinate the fix and disclosure.
@@ -1,10 +1,8 @@
1
- require 'oauth2'
2
- require 'omniauth'
3
- require 'securerandom'
4
- require 'socket' # for SocketError
5
- require 'timeout' # for Timeout::Error
6
- require 'faraday' # for Faraday::Error::TimeoutError and Faraday::Error::ConnectionFailed
7
- require 'multi_json' # for MultiJson::DecodeError
1
+ require "oauth2"
2
+ require "omniauth"
3
+ require "securerandom"
4
+ require "socket" # for SocketError
5
+ require "timeout" # for Timeout::Error
8
6
 
9
7
  module OmniAuth
10
8
  module Strategies
@@ -16,17 +14,32 @@ module OmniAuth
16
14
  class OAuth2
17
15
  include OmniAuth::Strategy
18
16
 
19
- args [:client_id, :client_secret]
17
+ def self.inherited(subclass)
18
+ OmniAuth::Strategy.included(subclass)
19
+ end
20
+
21
+ args %i[client_id client_secret]
20
22
 
21
23
  option :client_id, nil
22
24
  option :client_secret, nil
23
25
  option :client_options, {}
24
26
  option :authorize_params, {}
25
- option :authorize_options, [:scope]
27
+ option :authorize_options, %i[scope state]
26
28
  option :token_params, {}
27
29
  option :token_options, []
28
30
  option :auth_token_params, {}
29
31
  option :provider_ignores_state, false
32
+ option :pkce, false
33
+ option :pkce_verifier, nil
34
+ option :pkce_options, {
35
+ :code_challenge => proc { |verifier|
36
+ Base64.urlsafe_encode64(
37
+ Digest::SHA2.digest(verifier),
38
+ :padding => false,
39
+ )
40
+ },
41
+ :code_challenge_method => "S256",
42
+ }
30
43
 
31
44
  attr_accessor :access_token
32
45
 
@@ -34,15 +47,11 @@ module OmniAuth
34
47
  ::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
35
48
  end
36
49
 
37
- def callback_url
38
- full_host + script_name + callback_path
39
- end
40
-
41
50
  credentials do
42
- hash = {'token' => access_token.token}
43
- hash.merge!('refresh_token' => access_token.refresh_token) if access_token.expires? && access_token.refresh_token
44
- hash.merge!('expires_at' => access_token.expires_at) if access_token.expires?
45
- hash.merge!('expires' => access_token.expires?)
51
+ hash = {"token" => access_token.token}
52
+ hash["refresh_token"] = access_token.refresh_token if access_token.expires? && access_token.refresh_token
53
+ hash["expires_at"] = access_token.expires_at if access_token.expires?
54
+ hash["expires"] = access_token.expires?
46
55
  hash
47
56
  end
48
57
 
@@ -50,27 +59,34 @@ module OmniAuth
50
59
  redirect client.auth_code.authorize_url({:redirect_uri => callback_url}.merge(authorize_params))
51
60
  end
52
61
 
53
- def authorize_params
62
+ def authorize_params # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
54
63
  options.authorize_params[:state] = SecureRandom.hex(24)
55
- params = options.authorize_params.merge(options_for('authorize'))
64
+
56
65
  if OmniAuth.config.test_mode
57
66
  @env ||= {}
58
- @env['rack.session'] ||= {}
67
+ @env["rack.session"] ||= {}
59
68
  end
60
- session['omniauth.state'] = params[:state]
69
+
70
+ params = options.authorize_params
71
+ .merge(options_for("authorize"))
72
+ .merge(pkce_authorize_params)
73
+
74
+ session["omniauth.pkce.verifier"] = options.pkce_verifier if options.pkce
75
+ session["omniauth.state"] = params[:state]
76
+
61
77
  params
62
78
  end
63
79
 
64
80
  def token_params
65
- options.token_params.merge(options_for('token'))
81
+ options.token_params.merge(options_for("token")).merge(pkce_token_params)
66
82
  end
67
83
 
68
- def callback_phase # rubocop:disable CyclomaticComplexity
69
- error = request.params['error_reason'] || request.params['error']
70
- if error
71
- fail!(error, CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri']))
72
- elsif !options.provider_ignores_state && (request.params['state'].to_s.empty? || request.params['state'] != session.delete('omniauth.state'))
73
- fail!(:csrf_detected, CallbackError.new(:csrf_detected, 'CSRF detected'))
84
+ def callback_phase # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
85
+ error = request.params["error_reason"] || request.params["error"]
86
+ if !options.provider_ignores_state && (request.params["state"].to_s.empty? || request.params["state"] != session.delete("omniauth.state"))
87
+ fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected"))
88
+ elsif error
89
+ fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"]))
74
90
  else
75
91
  self.access_token = build_access_token
76
92
  self.access_token = access_token.refresh! if access_token.expired?
@@ -78,33 +94,52 @@ module OmniAuth
78
94
  end
79
95
  rescue ::OAuth2::Error, CallbackError => e
80
96
  fail!(:invalid_credentials, e)
81
- rescue ::MultiJson::DecodeError => e
82
- fail!(:invalid_response, e)
83
- rescue ::Timeout::Error, ::Errno::ETIMEDOUT, Faraday::Error::TimeoutError => e
97
+ rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
84
98
  fail!(:timeout, e)
85
- rescue ::SocketError, Faraday::Error::ConnectionFailed => e
99
+ rescue ::SocketError => e
86
100
  fail!(:failed_to_connect, e)
87
101
  end
88
102
 
89
103
  protected
90
104
 
105
+ def pkce_authorize_params
106
+ return {} unless options.pkce
107
+
108
+ options.pkce_verifier = SecureRandom.hex(64)
109
+
110
+ # NOTE: see https://tools.ietf.org/html/rfc7636#appendix-A
111
+ {
112
+ :code_challenge => options.pkce_options[:code_challenge]
113
+ .call(options.pkce_verifier),
114
+ :code_challenge_method => options.pkce_options[:code_challenge_method],
115
+ }
116
+ end
117
+
118
+ def pkce_token_params
119
+ return {} unless options.pkce
120
+
121
+ {:code_verifier => session.delete("omniauth.pkce.verifier")}
122
+ end
123
+
91
124
  def build_access_token
92
- verifier = request.params['code']
125
+ verifier = request.params["code"]
93
126
  client.auth_code.get_token(verifier, {:redirect_uri => callback_url}.merge(token_params.to_hash(:symbolize_keys => true)), deep_symbolize(options.auth_token_params))
94
127
  end
95
128
 
96
129
  def deep_symbolize(options)
97
- hash = {}
98
- options.each do |key, value|
130
+ options.each_with_object({}) do |(key, value), hash|
99
131
  hash[key.to_sym] = value.is_a?(Hash) ? deep_symbolize(value) : value
100
132
  end
101
- hash
102
133
  end
103
134
 
104
135
  def options_for(option)
105
136
  hash = {}
106
137
  options.send(:"#{option}_options").select { |key| options[key] }.each do |key|
107
- hash[key.to_sym] = options[key]
138
+ hash[key.to_sym] = if options[key].respond_to?(:call)
139
+ options[key].call(env)
140
+ else
141
+ options[key]
142
+ end
108
143
  end
109
144
  hash
110
145
  end
@@ -121,11 +156,11 @@ module OmniAuth
121
156
  end
122
157
 
123
158
  def message
124
- [error, error_reason, error_uri].compact.join(' | ')
159
+ [error, error_reason, error_uri].compact.join(" | ")
125
160
  end
126
161
  end
127
162
  end
128
163
  end
129
164
  end
130
165
 
131
- OmniAuth.config.add_camelization 'oauth2', 'OAuth2'
166
+ OmniAuth.config.add_camelization "oauth2", "OAuth2"
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module OAuth2
3
- VERSION = '1.2.0'
3
+ VERSION = "1.8.0".freeze
4
4
  end
5
5
  end
@@ -1,2 +1,2 @@
1
- require 'omniauth-oauth2/version'
2
- require 'omniauth/strategies/oauth2'
1
+ require "omniauth-oauth2/version"
2
+ require "omniauth/strategies/oauth2"
@@ -1,26 +1,24 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("../lib", __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'omniauth-oauth2/version'
3
+ require "omniauth-oauth2/version"
4
4
 
5
5
  Gem::Specification.new do |gem|
6
- gem.add_dependency 'faraday', ['>= 0.8', '< 0.10']
7
- gem.add_dependency 'multi_json', '~> 1.3'
8
- gem.add_dependency 'oauth2', '~> 1.0'
9
- gem.add_dependency 'omniauth', '~> 1.2'
6
+ gem.add_dependency "oauth2", [">= 1.4", "< 3"]
7
+ gem.add_dependency "omniauth", "~> 2.0"
10
8
 
11
- gem.add_development_dependency 'bundler', '~> 1.0'
9
+ gem.add_development_dependency "bundler", "~> 2.0"
12
10
 
13
- gem.authors = ['Michael Bleigh', 'Erik Michaels-Ober']
14
- gem.email = ['michael@intridea.com', 'sferik@gmail.com']
15
- gem.description = %q(An abstract OAuth2 strategy for OmniAuth.)
11
+ gem.authors = ["Michael Bleigh", "Erik Michaels-Ober", "Tom Milewski"]
12
+ gem.email = ["michael@intridea.com", "sferik@gmail.com", "tmilewski@gmail.com"]
13
+ gem.description = "An abstract OAuth2 strategy for OmniAuth."
16
14
  gem.summary = gem.description
17
- gem.homepage = 'https://github.com/intridea/omniauth-oauth2'
18
- gem.licenses = %w(MIT)
15
+ gem.homepage = "https://github.com/omniauth/omniauth-oauth2"
16
+ gem.licenses = %w[MIT]
19
17
 
20
18
  gem.executables = `git ls-files -- bin/*`.split("\n").collect { |f| File.basename(f) }
21
19
  gem.files = `git ls-files`.split("\n")
22
20
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
- gem.name = 'omniauth-oauth2'
24
- gem.require_paths = %w(lib)
21
+ gem.name = "omniauth-oauth2"
22
+ gem.require_paths = %w[lib]
25
23
  gem.version = OmniAuth::OAuth2::VERSION
26
24
  end
data/spec/helper.rb CHANGED
@@ -1,22 +1,29 @@
1
- $LOAD_PATH.unshift File.expand_path('..', __FILE__)
2
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ $LOAD_PATH.unshift File.expand_path("..", __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
3
 
4
- require 'simplecov'
5
- require 'coveralls'
4
+ if RUBY_VERSION >= "1.9"
5
+ require "simplecov"
6
+ require "simplecov-lcov"
7
+ require "coveralls"
6
8
 
7
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
- SimpleCov::Formatter::HTMLFormatter,
9
- Coveralls::SimpleCov::Formatter
10
- ]
11
- SimpleCov.start do
12
- minimum_coverage(76)
9
+ SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
10
+
11
+ SimpleCov.formatters = [
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ SimpleCov::Formatter::LcovFormatter,
14
+ Coveralls::SimpleCov::Formatter
15
+ ]
16
+
17
+ SimpleCov.start do
18
+ minimum_coverage(78.48)
19
+ end
13
20
  end
14
21
 
15
- require 'rspec'
16
- require 'rack/test'
17
- require 'webmock/rspec'
18
- require 'omniauth'
19
- require 'omniauth-oauth2'
22
+ require "rspec"
23
+ require "rack/test"
24
+ require "webmock/rspec"
25
+ require "omniauth"
26
+ require "omniauth-oauth2"
20
27
 
21
28
  RSpec.configure do |config|
22
29
  config.expect_with :rspec do |c|
@@ -1,9 +1,9 @@
1
- require 'helper'
1
+ require "helper"
2
2
 
3
3
  describe OmniAuth::Strategies::OAuth2 do
4
4
  def app
5
5
  lambda do |_env|
6
- [200, {}, ['Hello.']]
6
+ [200, {}, ["Hello."]]
7
7
  end
8
8
  end
9
9
  let(:fresh_strategy) { Class.new(OmniAuth::Strategies::OAuth2) }
@@ -16,65 +16,128 @@ describe OmniAuth::Strategies::OAuth2 do
16
16
  OmniAuth.config.test_mode = false
17
17
  end
18
18
 
19
- describe '#client' do
19
+ describe "Subclassing Behavior" do
20
20
  subject { fresh_strategy }
21
21
 
22
- it 'is initialized with symbolized client_options' do
23
- instance = subject.new(app, :client_options => {'authorize_url' => 'https://example.com'})
24
- expect(instance.client.options[:authorize_url]).to eq('https://example.com')
22
+ it "performs the OmniAuth::Strategy included hook" do
23
+ expect(OmniAuth.strategies).to include(OmniAuth::Strategies::OAuth2)
24
+ expect(OmniAuth.strategies).to include(subject)
25
+ end
26
+ end
27
+
28
+ describe "#client" do
29
+ subject { fresh_strategy }
30
+
31
+ it "is initialized with symbolized client_options" do
32
+ instance = subject.new(app, :client_options => {"authorize_url" => "https://example.com"})
33
+ expect(instance.client.options[:authorize_url]).to eq("https://example.com")
25
34
  end
26
35
 
27
- it 'sets ssl options as connection options' do
28
- instance = subject.new(app, :client_options => {'ssl' => {'ca_path' => 'foo'}})
29
- expect(instance.client.options[:connection_opts][:ssl]).to eq(:ca_path => 'foo')
36
+ it "sets ssl options as connection options" do
37
+ instance = subject.new(app, :client_options => {"ssl" => {"ca_path" => "foo"}})
38
+ expect(instance.client.options[:connection_opts][:ssl]).to eq(:ca_path => "foo")
30
39
  end
31
40
  end
32
41
 
33
- describe '#authorize_params' do
42
+ describe "#authorize_params" do
34
43
  subject { fresh_strategy }
35
44
 
36
- it 'includes any authorize params passed in the :authorize_params option' do
37
- instance = subject.new('abc', 'def', :authorize_params => {:foo => 'bar', :baz => 'zip'})
38
- expect(instance.authorize_params['foo']).to eq('bar')
39
- expect(instance.authorize_params['baz']).to eq('zip')
45
+ it "includes any authorize params passed in the :authorize_params option" do
46
+ instance = subject.new("abc", "def", :authorize_params => {:foo => "bar", :baz => "zip"})
47
+ expect(instance.authorize_params["foo"]).to eq("bar")
48
+ expect(instance.authorize_params["baz"]).to eq("zip")
49
+ end
50
+
51
+ it "includes top-level options that are marked as :authorize_options" do
52
+ instance = subject.new("abc", "def", :authorize_options => %i[scope foo state], :scope => "bar", :foo => "baz")
53
+ expect(instance.authorize_params["scope"]).to eq("bar")
54
+ expect(instance.authorize_params["foo"]).to eq("baz")
55
+ expect(instance.authorize_params["state"]).not_to be_empty
56
+ end
57
+
58
+ it "includes random state in the authorize params" do
59
+ instance = subject.new("abc", "def")
60
+ expect(instance.authorize_params.keys).to eq(["state"])
61
+ expect(instance.session["omniauth.state"]).not_to be_empty
40
62
  end
41
63
 
42
- it 'includes top-level options that are marked as :authorize_options' do
43
- instance = subject.new('abc', 'def', :authorize_options => [:scope, :foo, :state], :scope => 'bar', :foo => 'baz')
44
- expect(instance.authorize_params['scope']).to eq('bar')
45
- expect(instance.authorize_params['foo']).to eq('baz')
64
+ it "includes custom state in the authorize params" do
65
+ instance = subject.new("abc", "def", :state => proc { "qux" })
66
+ expect(instance.authorize_params.keys).to eq(["state"])
67
+ expect(instance.session["omniauth.state"]).to eq("qux")
46
68
  end
47
69
 
48
- it 'includes random state in the authorize params' do
49
- instance = subject.new('abc', 'def')
50
- expect(instance.authorize_params.keys).to eq(['state'])
51
- expect(instance.session['omniauth.state']).not_to be_empty
70
+ it "includes PKCE parameters if enabled" do
71
+ instance = subject.new("abc", "def", :pkce => true)
72
+ expect(instance.authorize_params[:code_challenge]).to be_a(String)
73
+ expect(instance.authorize_params[:code_challenge_method]).to eq("S256")
74
+ expect(instance.session["omniauth.pkce.verifier"]).to be_a(String)
52
75
  end
53
76
  end
54
77
 
55
- describe '#token_params' do
78
+ describe "#token_params" do
56
79
  subject { fresh_strategy }
57
80
 
58
- it 'includes any authorize params passed in the :authorize_params option' do
59
- instance = subject.new('abc', 'def', :token_params => {:foo => 'bar', :baz => 'zip'})
60
- expect(instance.token_params).to eq('foo' => 'bar', 'baz' => 'zip')
81
+ it "includes any authorize params passed in the :authorize_params option" do
82
+ instance = subject.new("abc", "def", :token_params => {:foo => "bar", :baz => "zip"})
83
+ expect(instance.token_params).to eq("foo" => "bar", "baz" => "zip")
84
+ end
85
+
86
+ it "includes top-level options that are marked as :authorize_options" do
87
+ instance = subject.new("abc", "def", :token_options => %i[scope foo], :scope => "bar", :foo => "baz")
88
+ expect(instance.token_params).to eq("scope" => "bar", "foo" => "baz")
61
89
  end
62
90
 
63
- it 'includes top-level options that are marked as :authorize_options' do
64
- instance = subject.new('abc', 'def', :token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz')
65
- expect(instance.token_params).to eq('scope' => 'bar', 'foo' => 'baz')
91
+ it "includes the PKCE code_verifier if enabled" do
92
+ instance = subject.new("abc", "def", :pkce => true)
93
+ # setup session
94
+ instance.authorize_params
95
+ expect(instance.token_params[:code_verifier]).to be_a(String)
66
96
  end
67
97
  end
68
98
 
69
- describe '#callback_phase' do
70
- subject { fresh_strategy }
71
- it 'calls fail with the client error received' do
72
- instance = subject.new('abc', 'def')
99
+ describe "#callback_phase" do
100
+ subject(:instance) { fresh_strategy.new("abc", "def") }
101
+
102
+ let(:params) { {"error_reason" => "user_denied", "error" => "access_denied", "state" => state} }
103
+ let(:state) { "secret" }
104
+
105
+ before do
73
106
  allow(instance).to receive(:request) do
74
- double('Request', :params => {'error_reason' => 'user_denied', 'error' => 'access_denied'})
107
+ double("Request", :params => params)
108
+ end
109
+
110
+ allow(instance).to receive(:session) do
111
+ double("Session", :delete => state)
75
112
  end
113
+ end
114
+
115
+ it "calls fail with the error received" do
116
+ expect(instance).to receive(:fail!).with("user_denied", anything)
117
+
118
+ instance.callback_phase
119
+ end
120
+
121
+ it "calls fail with the error received if state is missing and CSRF verification is disabled" do
122
+ params["state"] = nil
123
+ instance.options.provider_ignores_state = true
124
+
125
+ expect(instance).to receive(:fail!).with("user_denied", anything)
126
+
127
+ instance.callback_phase
128
+ end
129
+
130
+ it "calls fail with a CSRF error if the state is missing" do
131
+ params["state"] = nil
132
+
133
+ expect(instance).to receive(:fail!).with(:csrf_detected, anything)
134
+ instance.callback_phase
135
+ end
136
+
137
+ it "calls fail with a CSRF error if the state is invalid" do
138
+ params["state"] = "invalid"
76
139
 
77
- expect(instance).to receive(:fail!).with('user_denied', anything)
140
+ expect(instance).to receive(:fail!).with(:csrf_detected, anything)
78
141
  instance.callback_phase
79
142
  end
80
143
  end
@@ -82,17 +145,17 @@ end
82
145
 
83
146
  describe OmniAuth::Strategies::OAuth2::CallbackError do
84
147
  let(:error) { Class.new(OmniAuth::Strategies::OAuth2::CallbackError) }
85
- describe '#message' do
148
+ describe "#message" do
86
149
  subject { error }
87
- it 'includes all of the attributes' do
88
- instance = subject.new('error', 'description', 'uri')
150
+ it "includes all of the attributes" do
151
+ instance = subject.new("error", "description", "uri")
89
152
  expect(instance.message).to match(/error/)
90
153
  expect(instance.message).to match(/description/)
91
154
  expect(instance.message).to match(/uri/)
92
155
  end
93
- it 'includes all of the attributes' do
156
+ it "includes all of the attributes" do
94
157
  instance = subject.new(nil, :symbol)
95
- expect(instance.message).to eq('symbol')
158
+ expect(instance.message).to eq("symbol")
96
159
  end
97
160
  end
98
161
  end
metadata CHANGED
@@ -1,120 +1,96 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  - Erik Michaels-Ober
9
- autorequire:
9
+ - Tom Milewski
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2014-07-09 00:00:00.000000000 Z
13
+ date: 2022-06-18 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
- name: faraday
16
+ name: oauth2
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  requirements:
18
19
  - - ">="
19
20
  - !ruby/object:Gem::Version
20
- version: '0.8'
21
+ version: '1.4'
21
22
  - - "<"
22
23
  - !ruby/object:Gem::Version
23
- version: '0.10'
24
+ version: '3'
24
25
  type: :runtime
25
26
  prerelease: false
26
27
  version_requirements: !ruby/object:Gem::Requirement
27
28
  requirements:
28
29
  - - ">="
29
30
  - !ruby/object:Gem::Version
30
- version: '0.8'
31
+ version: '1.4'
31
32
  - - "<"
32
33
  - !ruby/object:Gem::Version
33
- version: '0.10'
34
- - !ruby/object:Gem::Dependency
35
- name: multi_json
36
- requirement: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.3'
41
- type: :runtime
42
- prerelease: false
43
- version_requirements: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.3'
48
- - !ruby/object:Gem::Dependency
49
- name: oauth2
50
- requirement: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.0'
55
- type: :runtime
56
- prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.0'
34
+ version: '3'
62
35
  - !ruby/object:Gem::Dependency
63
36
  name: omniauth
64
37
  requirement: !ruby/object:Gem::Requirement
65
38
  requirements:
66
39
  - - "~>"
67
40
  - !ruby/object:Gem::Version
68
- version: '1.2'
41
+ version: '2.0'
69
42
  type: :runtime
70
43
  prerelease: false
71
44
  version_requirements: !ruby/object:Gem::Requirement
72
45
  requirements:
73
46
  - - "~>"
74
47
  - !ruby/object:Gem::Version
75
- version: '1.2'
48
+ version: '2.0'
76
49
  - !ruby/object:Gem::Dependency
77
50
  name: bundler
78
51
  requirement: !ruby/object:Gem::Requirement
79
52
  requirements:
80
53
  - - "~>"
81
54
  - !ruby/object:Gem::Version
82
- version: '1.0'
55
+ version: '2.0'
83
56
  type: :development
84
57
  prerelease: false
85
58
  version_requirements: !ruby/object:Gem::Requirement
86
59
  requirements:
87
60
  - - "~>"
88
61
  - !ruby/object:Gem::Version
89
- version: '1.0'
62
+ version: '2.0'
90
63
  description: An abstract OAuth2 strategy for OmniAuth.
91
64
  email:
92
65
  - michael@intridea.com
93
66
  - sferik@gmail.com
67
+ - tmilewski@gmail.com
94
68
  executables: []
95
69
  extensions: []
96
70
  extra_rdoc_files: []
97
71
  files:
72
+ - ".github/FUNDING.yml"
73
+ - ".github/workflows/main.yml"
98
74
  - ".gitignore"
99
75
  - ".rspec"
100
76
  - ".rubocop.yml"
101
- - ".travis.yml"
77
+ - CHANGELOG.md
102
78
  - Gemfile
103
- - Guardfile
104
79
  - LICENSE.md
105
80
  - README.md
106
81
  - Rakefile
82
+ - SECURITY.md
107
83
  - lib/omniauth-oauth2.rb
108
84
  - lib/omniauth-oauth2/version.rb
109
85
  - lib/omniauth/strategies/oauth2.rb
110
86
  - omniauth-oauth2.gemspec
111
87
  - spec/helper.rb
112
88
  - spec/omniauth/strategies/oauth2_spec.rb
113
- homepage: https://github.com/intridea/omniauth-oauth2
89
+ homepage: https://github.com/omniauth/omniauth-oauth2
114
90
  licenses:
115
91
  - MIT
116
92
  metadata: {}
117
- post_install_message:
93
+ post_install_message:
118
94
  rdoc_options: []
119
95
  require_paths:
120
96
  - lib
@@ -129,9 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
105
  - !ruby/object:Gem::Version
130
106
  version: '0'
131
107
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.2.2
134
- signing_key:
108
+ rubygems_version: 3.2.32
109
+ signing_key:
135
110
  specification_version: 4
136
111
  summary: An abstract OAuth2 strategy for OmniAuth.
137
112
  test_files:
data/.travis.yml DELETED
@@ -1,22 +0,0 @@
1
- bundler_args: --without development
2
- language: ruby
3
- rvm:
4
- - 1.8.7
5
- - 1.9.2
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1.0
9
- - rbx-2
10
- - ruby-head
11
- matrix:
12
- include:
13
- - rvm: jruby-18mode
14
- env: JRUBY_OPTS="$JRUBY_OPTS --debug"
15
- - rvm: jruby-19mode
16
- env: JRUBY_OPTS="$JRUBY_OPTS --debug"
17
- - rvm: jruby-head
18
- env: JRUBY_OPTS="$JRUBY_OPTS --debug"
19
- allow_failures:
20
- - rvm: jruby-head
21
- - rvm: ruby-head
22
- fast_finish: true
data/Guardfile DELETED
@@ -1,11 +0,0 @@
1
- guard 'rspec', :version => 2 do
2
- watch(%r{^spec/.+_spec\.rb$})
3
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { "spec" }
5
- end
6
-
7
-
8
- guard 'bundler' do
9
- watch('Gemfile')
10
- watch(/^.+\.gemspec/)
11
- end