omniauth 1.8.1 → 2.1.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: d44b113518272f233522832707ca3d6212dca359
4
- data.tar.gz: 558b3aad56d54629e5ae18ca72944008ca4d4a1e
2
+ SHA256:
3
+ metadata.gz: df50309ac3b4098a460e7a52f233798a3246cffdfeb2c6f6f60d373b8af8af2c
4
+ data.tar.gz: bf5c53ceadb04c431b88aa17dfe6a11b46475b38bc9d4fa74865e1eb21d27772
5
5
  SHA512:
6
- metadata.gz: fc2cdd4f9decc4537dd2fdda21b9a18d005a29cff9e18f6db923571bde2c9f85d68483230c395a82983438bd16cec2754576625ed2ecb599dce3d1b752832523
7
- data.tar.gz: 0beb474c0fea700dfb8032a71fdf6062d952466a31ddb496433b4935405902cf0cd2cd0b18888700ccc838e0577822bdb300a97ff3d22385deb605c252d57946
6
+ metadata.gz: dfd0bb2add456a51a393e672cba45d310f6ab7d2b5aa37c058a7242b8b0dc9b644877596c0a47c9e1c462d1e593516d1474379f103cae0988cced76c37260d4a
7
+ data.tar.gz: 6a0c4302b25339ca10e304ef1fb968e5dd36cb5e6d686499c1b9d5185f9165fef864f54603f385076bf81160980ca532285a00ebdf23de82f3a1bacf95655856
@@ -0,0 +1,2 @@
1
+ github: bobbymcwho
2
+ tidelift: rubygems/omniauth
@@ -0,0 +1,89 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-18.04
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ os: [ubuntu, macos]
23
+ ruby: [2.5, 2.6, 2.7, '3.0', 3.1, head, debug, truffleruby, truffleruby-head]
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby }}
30
+ bundler-cache: true
31
+ - name: Install dependencies
32
+ run: bundle install
33
+ - name: Run tests
34
+ run: bundle exec rake
35
+ test-jruby:
36
+ runs-on: ubuntu-18.04
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ os: [ubuntu, macos]
41
+ jruby: [jruby] # TODO: Add back jruby-head once we figure out why there's a bundler mismatch
42
+ steps:
43
+ - uses: actions/checkout@v2
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.jruby }}
48
+ bundler-cache: true
49
+ - name: Install dependencies
50
+ env:
51
+ JRUBY_OPTS: --debug
52
+ run: bundle install
53
+ - name: Run tests
54
+ env:
55
+ JRUBY_OPTS: --debug
56
+ run: bundle exec rake
57
+ frozen-string-compat:
58
+ runs-on: ubuntu-18.04
59
+ steps:
60
+ - uses: actions/checkout@v2
61
+ - name: Set up Ruby
62
+ uses: ruby/setup-ruby@v1
63
+ with:
64
+ ruby-version: 2.6
65
+ bundler-cache: true
66
+ - name: Install dependencies
67
+ run: bundle install
68
+ - name: Run tests
69
+ env:
70
+ RUBYOPT: "--enable-frozen-string-literal"
71
+ run: bundle exec rake
72
+ coveralls:
73
+ runs-on: ubuntu-18.04
74
+ steps:
75
+ - uses: actions/checkout@v2
76
+ - name: Set up Ruby
77
+ uses: ruby/setup-ruby@v1
78
+ with:
79
+ ruby-version: 2.6
80
+ bundler-cache: true
81
+ - name: Install dependencies
82
+ run: bundle install
83
+ - name: Run tests
84
+ run: bundle exec rake
85
+ - name: Coveralls GitHub Action
86
+ uses: coverallsapp/github-action@v1.1.2
87
+ with:
88
+ github-token: ${{ secrets.github_token }}
89
+ path-to-lcov: './coverage/lcov/omniauth.lcov'
data/.gitignore CHANGED
@@ -10,3 +10,5 @@ doc/*
10
10
  log/*
11
11
  measurement/*
12
12
  pkg/*
13
+ .DS_Store
14
+ .tool-versions
data/.rubocop.yml CHANGED
@@ -1,6 +1,12 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.2
3
+
1
4
  Layout/AccessModifierIndentation:
2
5
  EnforcedStyle: outdent
3
6
 
7
+ Layout/AlignHash:
8
+ Enabled: false
9
+
4
10
  Layout/DotPosition:
5
11
  EnforcedStyle: trailing
6
12
 
@@ -50,6 +56,9 @@ Style/EachWithObject:
50
56
  Style/Encoding:
51
57
  Enabled: false
52
58
 
59
+ Style/ExpandPathArguments:
60
+ Enabled: false
61
+
53
62
  Style/HashSyntax:
54
63
  EnforcedStyle: hash_rockets
55
64
 
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'jruby-openssl', '~> 0.9.19', :platforms => :jruby
3
+ gem 'jruby-openssl', '~> 0.10.5', platforms: :jruby
4
4
  gem 'rake', '>= 12.0'
5
5
  gem 'yard', '>= 0.9.11'
6
6
 
@@ -12,16 +12,17 @@ group :development do
12
12
  end
13
13
 
14
14
  group :test do
15
- gem 'coveralls', :require => false
16
- gem 'hashie', '>= 3.4.6', '< 3.6.0', :platforms => [:jruby_18]
17
- gem 'json', '~> 2.0.3', :platforms => %i[jruby_18 jruby_19 ruby_19]
18
- gem 'mime-types', '~> 3.1', :platforms => [:jruby_18]
19
- gem 'rack', '>= 1.6.2', :platforms => %i[jruby_18 jruby_19 ruby_19 ruby_20 ruby_21]
15
+ gem 'coveralls_reborn', '~> 0.19.0', require: false
16
+ gem 'hashie', '>= 3.4.6', '~> 4.0.0', platforms: [:jruby_18]
17
+ gem 'json', '~> 2.3.0', platforms: %i[jruby_18 jruby_19 ruby_19]
18
+ gem 'mime-types', '~> 3.1', platforms: [:jruby_18]
20
19
  gem 'rack-test'
21
- gem 'rest-client', '~> 2.0.0', :platforms => [:jruby_18]
22
- gem 'rspec', '~> 3.5.0'
23
- gem 'rubocop', '>= 0.47', :platforms => %i[ruby_20 ruby_21 ruby_22 ruby_23 ruby_24]
24
- gem 'tins', '~> 1.13.0', :platforms => %i[jruby_18 jruby_19 ruby_19]
20
+ gem 'rest-client', '~> 2.0.0', platforms: [:jruby_18]
21
+ gem 'rspec', '~> 3.5'
22
+ gem 'rack-freeze'
23
+ gem 'rubocop', '>= 0.58.2', '< 0.69.0', platforms: %i[ruby_20 ruby_21 ruby_22 ruby_23 ruby_24]
24
+ gem 'simplecov-lcov'
25
+ gem 'tins', '~> 1.13', platforms: %i[jruby_18 jruby_19 ruby_19]
25
26
  end
26
27
 
27
28
  gemspec
data/README.md CHANGED
@@ -2,17 +2,16 @@
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/omniauth.svg)][gem]
4
4
  [![Build Status](http://img.shields.io/travis/omniauth/omniauth.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/omniauth/omniauth.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/omniauth/omniauth.svg)][codeclimate]
5
+ [![Code Climate](https://api.codeclimate.com/v1/badges/ffd33970723587806744/maintainability)][codeclimate]
7
6
  [![Coverage Status](http://img.shields.io/coveralls/omniauth/omniauth.svg)][coveralls]
8
- [![Security](https://hakiri.io/github/omniauth/omniauth/master.svg)](https://hakiri.io/github/omniauth/omniauth/master)
9
7
 
10
8
  [gem]: https://rubygems.org/gems/omniauth
11
9
  [travis]: http://travis-ci.org/omniauth/omniauth
12
- [gemnasium]: https://gemnasium.com/omniauth/omniauth
13
10
  [codeclimate]: https://codeclimate.com/github/omniauth/omniauth
14
11
  [coveralls]: https://coveralls.io/r/omniauth/omniauth
15
12
 
13
+ This is the documentation for our latest release [v2.1.0](https://github.com/omniauth/omniauth/releases/tag/v2.1.0).
14
+
16
15
  ## An Introduction
17
16
  OmniAuth is a library that standardizes multi-provider authentication for
18
17
  web applications. It was created to be powerful, flexible, and do as
@@ -34,8 +33,8 @@ development and easily swap in other strategies later.
34
33
  ## Getting Started
35
34
  Each OmniAuth strategy is a Rack Middleware. That means that you can use
36
35
  it the same way that you use any other Rack middleware. For example, to
37
- use the built-in Developer strategy in a Sinatra application I might do
38
- this:
36
+ use the built-in Developer strategy in a Sinatra application you might
37
+ do this:
39
38
 
40
39
  ```ruby
41
40
  require 'sinatra'
@@ -47,7 +46,7 @@ class MyApplication < Sinatra::Base
47
46
  end
48
47
  ```
49
48
 
50
- Because OmniAuth is built for *multi-provider* authentication, I may
49
+ Because OmniAuth is built for *multi-provider* authentication, you may
51
50
  want to leave room to run multiple strategies. For this, the built-in
52
51
  `OmniAuth::Builder` class gives you an easy way to specify multiple
53
52
  strategies. Note that there is **no difference** between the following
@@ -84,33 +83,9 @@ environment of a request to `/auth/:provider/callback`. This hash
84
83
  contains as much information about the user as OmniAuth was able to
85
84
  glean from the utilized strategy. You should set up an endpoint in your
86
85
  application that matches to the callback URL and then performs whatever
87
- steps are necessary for your application. For example, in a Rails app I
88
- would add a line in my `routes.rb` file like this:
89
-
90
- ```ruby
91
- get '/auth/:provider/callback', to: 'sessions#create'
92
- ```
93
-
94
- And I might then have a `SessionsController` with code that looks
95
- something like this:
96
-
97
- ```ruby
98
- class SessionsController < ApplicationController
99
- def create
100
- @user = User.find_or_create_from_auth_hash(auth_hash)
101
- self.current_user = @user
102
- redirect_to '/'
103
- end
104
-
105
- protected
106
-
107
- def auth_hash
108
- request.env['omniauth.auth']
109
- end
110
- end
111
- ```
86
+ steps are necessary for your application.
112
87
 
113
- The `omniauth.auth` key in the environment hash gives me my
88
+ The `omniauth.auth` key in the environment hash provides an
114
89
  Authentication Hash which will contain information about the just
115
90
  authenticated user including a unique id, the strategy they just used
116
91
  for authentication, and personal details such as name and email address
@@ -122,33 +97,67 @@ environment information on the callback request. It is entirely up to
122
97
  you how you want to implement the particulars of your application's
123
98
  authentication flow.
124
99
 
125
- ## Configuring The `origin` Param
126
- The `origin` url parameter is typically used to inform where a user came from and where, should you choose to use it, they'd want to return to.
127
100
 
128
- There are three possible options:
101
+ ## Rails (without Devise)
102
+ To get started, add the following gems
129
103
 
130
- Default Flow:
104
+ **Gemfile**:
131
105
  ```ruby
132
- # /auth/twitter/?origin=[URL]
133
- # No change
134
- # If blank, `omniauth.origin` is set to HTTP_REFERER
106
+ gem 'omniauth'
107
+ gem "omniauth-rails_csrf_protection"
135
108
  ```
136
109
 
137
- Renaming Origin Param:
110
+ Then insert OmniAuth as a middleware
111
+
112
+ **config/initializers/omniauth.rb**:
138
113
  ```ruby
139
- # /auth/twitter/?return_to=[URL]
140
- # If blank, `omniauth.origin` is set to HTTP_REFERER
141
- provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'
114
+ Rails.application.config.middleware.use OmniAuth::Builder do
115
+ provider :developer if Rails.env.development?
116
+ end
142
117
  ```
143
118
 
144
- Disabling Origin Param:
119
+ Additional providers can be added here in the future. Next we wire it
120
+ all up using routes, a controller and a login view.
121
+
122
+ **config/routes.rb**:
123
+
145
124
  ```ruby
146
- # /auth/twitter
147
- # Origin handled externally, if need be. `omniauth.origin` is not set
148
- provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: false
125
+ get 'auth/:provider/callback', to: 'sessions#create'
126
+ get '/login', to: 'sessions#new'
149
127
  ```
150
128
 
151
- ## Integrating OmniAuth Into Your Rails API
129
+ **app/controllers/sessions_controller.rb**:
130
+ ```ruby
131
+ class SessionsController < ApplicationController
132
+ def new
133
+ render :new
134
+ end
135
+
136
+ def create
137
+ user_info = request.env['omniauth.auth']
138
+ raise user_info # Your own session management should be placed here.
139
+ end
140
+ end
141
+ ```
142
+
143
+ **app/views/sessions/new.html.erb**:
144
+ ```erb
145
+ <%= form_tag('/auth/developer', method: 'post', data: {turbo: false}) do %>
146
+ <button type='submit'>Login with Developer</button>
147
+ <% end %>
148
+ ```
149
+
150
+ Now if you visit `/login` and click the Login button, you should see the
151
+ OmniAuth developer login screen. After submitting it, you are returned to your
152
+ application at `Sessions#create`. The raise should now display all the Omniauth
153
+ details you have available to integrate it into your own user management.
154
+
155
+ If you want out of the box usermanagement, you should consider using Omniauth
156
+ through Devise. Please visit the [Devise Github page](https://github.com/heartcombo/devise#omniauth)
157
+ for more information.
158
+
159
+
160
+ ## Rails API
152
161
  The following middleware are (by default) included for session management in
153
162
  Rails applications. When using OmniAuth with a Rails API, you'll need to add
154
163
  one of these required middleware back in:
@@ -163,7 +172,7 @@ a `session_store.rb` initializer, add `use ActionDispatch::Session::CookieStore`
163
172
  and have sessions functioning as normal.
164
173
 
165
174
  To be clear: sessions may work, but your session options will be ignored
166
- (i.e the session key will default to `_session_id`). Instead of the
175
+ (i.e. the session key will default to `_session_id`). Instead of the
167
176
  initializer, you'll have to set the relevant options somewhere
168
177
  before your middleware is built (like `application.rb`) and pass them to your
169
178
  preferred middleware, like this:
@@ -187,14 +196,51 @@ to `STDOUT` but you can configure this using `OmniAuth.config.logger`:
187
196
  OmniAuth.config.logger = Rails.logger
188
197
  ```
189
198
 
199
+ ## Origin Param
200
+ The `origin` url parameter is typically used to inform where a user came from
201
+ and where, should you choose to use it, they'd want to return to.
202
+ Omniauth supports the following settings which can be configured on a provider level:
203
+
204
+ **Default**:
205
+ ```ruby
206
+ provider :twitter, ENV['KEY'], ENV['SECRET']
207
+ POST /auth/twitter/?origin=[URL]
208
+ # If the `origin` parameter is blank, `omniauth.origin` is set to HTTP_REFERER
209
+ ```
210
+
211
+ **Using a differently named origin parameter**:
212
+ ```ruby
213
+ provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'
214
+ POST /auth/twitter/?return_to=[URL]
215
+ # If the `return_to` parameter is blank, `omniauth.origin` is set to HTTP_REFERER
216
+ ```
217
+
218
+ **Disabled**:
219
+ ```ruby
220
+ provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: false
221
+ POST /auth/twitter
222
+ # This means the origin should be handled by your own application.
223
+ # Note that `omniauth.origin` will always be blank.
224
+ ```
225
+
190
226
  ## Resources
191
227
  The [OmniAuth Wiki](https://github.com/omniauth/omniauth/wiki) has
192
228
  actively maintained in-depth documentation for OmniAuth. It should be
193
229
  your first stop if you are wondering about a more in-depth look at
194
230
  OmniAuth, how it works, and how to use it.
195
231
 
232
+ ## OmniAuth for Enterprise
233
+
234
+ Available as part of the Tidelift Subscription.
235
+
236
+ The maintainers of OmniAuth and thousands of other packages are working with
237
+ Tidelift to deliver commercial support and maintenance for the open source
238
+ packages you use to build your applications. Save time, reduce risk, and
239
+ improve code health, while paying the maintainers of the exact packages you use.
240
+ [Learn more.](https://tidelift.com/subscription/pkg/rubygems-omniauth?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
241
+
196
242
  ## Supported Ruby Versions
197
- OmniAuth is tested under 2.1.10, 2.2.6, 2.3.3, 2.4.0, 2.5.0, and JRuby.
243
+ OmniAuth is tested under 2.5, 2.6, 2.7, truffleruby, and JRuby.
198
244
 
199
245
  ## Versioning
200
246
  This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
data/Rakefile CHANGED
@@ -30,6 +30,7 @@ namespace :perf do
30
30
  def call_app(path = ENV['GET_PATH'] || '/')
31
31
  result = @app.get(path)
32
32
  raise "Did not succeed #{result.body}" unless result.status == 200
33
+
33
34
  result
34
35
  end
35
36
  end
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
+ | 2.0.x | :white_check_mark: |
11
+ | <= 1.9.1 | :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.
@@ -20,9 +20,7 @@ module OmniAuth
20
20
  end
21
21
 
22
22
  def regular_writer(key, value)
23
- if key.to_s == 'info' && value.is_a?(::Hash) && !value.is_a?(InfoHash)
24
- value = InfoHash.new(value)
25
- end
23
+ value = InfoHash.new(value) if key.to_s == 'info' && value.is_a?(::Hash) && !value.is_a?(InfoHash)
26
24
  super
27
25
  end
28
26
 
@@ -36,6 +34,7 @@ module OmniAuth
36
34
  return "#{first_name} #{last_name}".strip if first_name? || last_name?
37
35
  return nickname if nickname?
38
36
  return email if email?
37
+
39
38
  nil
40
39
  end
41
40
 
@@ -0,0 +1,32 @@
1
+ require 'rack-protection'
2
+
3
+ module OmniAuth
4
+ class AuthenticityError < StandardError; end
5
+ class AuthenticityTokenProtection < Rack::Protection::AuthenticityToken
6
+ def initialize(options = {})
7
+ @options = default_options.merge(options)
8
+ end
9
+
10
+ def self.call(env)
11
+ new.call!(env)
12
+ end
13
+
14
+ def call!(env)
15
+ return if accepts?(env)
16
+
17
+ instrument env
18
+ react env
19
+ end
20
+
21
+ alias_method :call, :call!
22
+
23
+ private
24
+
25
+ def deny(_env)
26
+ OmniAuth.logger.send(:warn, "Attack prevented by #{self.class}")
27
+ raise AuthenticityError.new(options[:message])
28
+ end
29
+
30
+ alias default_reaction deny
31
+ end
32
+ end
@@ -1,24 +1,5 @@
1
1
  module OmniAuth
2
2
  class Builder < ::Rack::Builder
3
- def initialize(app, &block)
4
- @options = nil
5
- if rack14? || rack2?
6
- super
7
- else
8
- @app = app
9
- super(&block)
10
- @ins << @app
11
- end
12
- end
13
-
14
- def rack14?
15
- Rack.release.start_with?('1.') && (Rack.release.split('.')[1].to_i >= 4)
16
- end
17
-
18
- def rack2?
19
- Rack.release.start_with? '2.'
20
- end
21
-
22
3
  def on_failure(&block)
23
4
  OmniAuth.config.on_failure = block
24
5
  end
@@ -40,23 +21,23 @@ module OmniAuth
40
21
  end
41
22
 
42
23
  def options(options = false)
43
- return @options || {} if options == false
24
+ return @options ||= {} if options == false
25
+
44
26
  @options = options
45
27
  end
46
28
 
47
- def provider(klass, *args, &block)
29
+ def provider(klass, *args, **opts, &block)
48
30
  if klass.is_a?(Class)
49
31
  middleware = klass
50
32
  else
51
33
  begin
52
- middleware = OmniAuth::Strategies.const_get(OmniAuth::Utils.camelize(klass.to_s).to_s)
34
+ middleware = OmniAuth::Strategies.const_get(OmniAuth::Utils.camelize(klass.to_s).to_s, false)
53
35
  rescue NameError
54
36
  raise(LoadError.new("Could not find matching strategy for #{klass.inspect}. You may need to install an additional gem (such as omniauth-#{klass})."))
55
37
  end
56
38
  end
57
39
 
58
- args.last.is_a?(Hash) ? args.push(options.merge(args.pop)) : args.push(options)
59
- use middleware, *args, &block
40
+ use middleware, *args, **options.merge(opts), &block
60
41
  end
61
42
 
62
43
  def call(env)
@@ -27,17 +27,28 @@ module OmniAuth
27
27
 
28
28
  def redirect_to_failure
29
29
  message_key = env['omniauth.error.type']
30
- new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}#{origin_query_param}#{strategy_name_query_param}"
30
+
31
+ new_path = "#{env['SCRIPT_NAME']}#{strategy_path_prefix}/failure?message=#{Rack::Utils.escape(message_key)}#{origin_query_param}#{strategy_name_query_param}"
31
32
  Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
32
33
  end
33
34
 
35
+ def strategy_path_prefix
36
+ if env['omniauth.error.strategy']
37
+ env['omniauth.error.strategy'].path_prefix
38
+ else
39
+ OmniAuth.config.path_prefix
40
+ end
41
+ end
42
+
34
43
  def strategy_name_query_param
35
44
  return '' unless env['omniauth.error.strategy']
45
+
36
46
  "&strategy=#{env['omniauth.error.strategy'].name}"
37
47
  end
38
48
 
39
49
  def origin_query_param
40
50
  return '' unless env['omniauth.origin']
51
+
41
52
  "&origin=#{Rack::Utils.escape(env['omniauth.origin'])}"
42
53
  end
43
54
  end
data/lib/omniauth/form.rb CHANGED
@@ -9,7 +9,7 @@ module OmniAuth
9
9
  options[:header_info] ||= ''
10
10
  self.options = options
11
11
 
12
- @html = ''
12
+ @html = +'' # unary + string allows it to be mutable if strings are frozen
13
13
  @with_custom_button = false
14
14
  @footer = nil
15
15
  header(options[:title], options[:header_info])
@@ -82,6 +82,7 @@ module OmniAuth
82
82
 
83
83
  def footer
84
84
  return self if @footer
85
+
85
86
  @html << "\n<button type='submit'>Connect</button>" unless @with_custom_button
86
87
  @html << <<-HTML
87
88
  </form>
@@ -140,6 +140,7 @@ module OmniAuth
140
140
 
141
141
  self.class.args.each do |arg|
142
142
  break if args.empty?
143
+
143
144
  options[arg] = args.shift
144
145
  end
145
146
 
@@ -180,16 +181,47 @@ module OmniAuth
180
181
  end
181
182
 
182
183
  @env = env
184
+
185
+ warn_if_using_get_on_request_path
186
+
183
187
  @env['omniauth.strategy'] = self if on_auth_path?
184
188
 
185
189
  return mock_call!(env) if OmniAuth.config.test_mode
186
- return options_call if on_auth_path? && options_request?
187
- return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
188
- return callback_call if on_callback_path?
189
- return other_phase if respond_to?(:other_phase)
190
+
191
+ begin
192
+ return options_call if on_auth_path? && options_request?
193
+ return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
194
+ return callback_call if on_callback_path?
195
+ return other_phase if respond_to?(:other_phase)
196
+ rescue StandardError => e
197
+ raise e if env.delete('omniauth.error.app')
198
+
199
+ return fail!(e.message, e)
200
+ end
201
+
190
202
  @app.call(env)
191
203
  end
192
204
 
205
+ def warn_if_using_get_on_request_path
206
+ return unless on_request_path?
207
+ return unless OmniAuth.config.allowed_request_methods.include?(:get)
208
+ return if OmniAuth.config.silence_get_warning
209
+
210
+ log :warn, <<-WARN
211
+ You are using GET as an allowed request method for OmniAuth. This may leave
212
+ you open to CSRF attacks. As of v2.0.0, OmniAuth by default allows only POST
213
+ to its own routes. You should review the following resources to guide your
214
+ mitigation:
215
+ https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
216
+ https://github.com/omniauth/omniauth/issues/960
217
+ https://nvd.nist.gov/vuln/detail/CVE-2015-9284
218
+ https://github.com/omniauth/omniauth/pull/809
219
+
220
+ You can ignore this warning by setting:
221
+ OmniAuth.config.silence_get_warning = true
222
+ WARN
223
+ end
224
+
193
225
  # Responds to an OPTIONS request.
194
226
  def options_call
195
227
  OmniAuth.config.before_options_phase.call(env) if OmniAuth.config.before_options_phase
@@ -200,17 +232,19 @@ module OmniAuth
200
232
  # Performs the steps necessary to run the request phase of a strategy.
201
233
  def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
202
234
  setup_phase
203
- log :info, 'Request phase initiated.'
235
+ log :debug, 'Request phase initiated.'
204
236
 
205
237
  # store query params from the request url, extracted in the callback_phase
206
238
  session['omniauth.params'] = request.GET
239
+
240
+ OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
207
241
  OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
208
242
 
209
243
  if options.form.respond_to?(:call)
210
- log :info, 'Rendering form from supplied Rack endpoint.'
244
+ log :debug, 'Rendering form from supplied Rack endpoint.'
211
245
  options.form.call(env)
212
246
  elsif options.form
213
- log :info, 'Rendering form from underlying application.'
247
+ log :debug, 'Rendering form from underlying application.'
214
248
  call_app!
215
249
  elsif !options.origin_param
216
250
  request_phase
@@ -223,12 +257,14 @@ module OmniAuth
223
257
 
224
258
  request_phase
225
259
  end
260
+ rescue OmniAuth::AuthenticityError => e
261
+ fail!(:authenticity_error, e)
226
262
  end
227
263
 
228
264
  # Performs the steps necessary to run the callback phase of a strategy.
229
265
  def callback_call
230
266
  setup_phase
231
- log :info, 'Callback phase initiated.'
267
+ log :debug, 'Callback phase initiated.'
232
268
  @env['omniauth.origin'] = session.delete('omniauth.origin')
233
269
  @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
234
270
  @env['omniauth.params'] = session.delete('omniauth.params') || {}
@@ -266,8 +302,15 @@ module OmniAuth
266
302
  # in the event that OmniAuth has been configured to be
267
303
  # in test mode.
268
304
  def mock_call!(*)
269
- return mock_request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
270
- return mock_callback_call if on_callback_path?
305
+ begin
306
+ return mock_request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
307
+ return mock_callback_call if on_callback_path?
308
+ rescue StandardError => e
309
+ raise e if env.delete('omniauth.error.app')
310
+
311
+ return fail!(e.message, e)
312
+ end
313
+
271
314
  call_app!
272
315
  end
273
316
 
@@ -275,7 +318,10 @@ module OmniAuth
275
318
  setup_phase
276
319
 
277
320
  session['omniauth.params'] = request.GET
321
+
322
+ OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
278
323
  OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
324
+
279
325
  if options.origin_param
280
326
  if request.params[options.origin_param]
281
327
  session['omniauth.origin'] = request.params[options.origin_param]
@@ -309,10 +355,10 @@ module OmniAuth
309
355
  # underlying application. This will default to `/auth/:provider/setup`.
310
356
  def setup_phase
311
357
  if options[:setup].respond_to?(:call)
312
- log :info, 'Setup endpoint detected, running now.'
358
+ log :debug, 'Setup endpoint detected, running now.'
313
359
  options[:setup].call(env)
314
360
  elsif options[:setup]
315
- log :info, 'Calling through to underlying application for setup.'
361
+ log :debug, 'Calling through to underlying application for setup.'
316
362
  setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
317
363
  call_app!(setup_env)
318
364
  end
@@ -342,11 +388,13 @@ module OmniAuth
342
388
  end
343
389
 
344
390
  def auth_hash
345
- hash = AuthHash.new(:provider => name, :uid => uid)
346
- hash.info = info unless skip_info?
347
- hash.credentials = credentials if credentials
348
- hash.extra = extra if extra
349
- hash
391
+ credentials_data = credentials
392
+ extra_data = extra
393
+ AuthHash.new(:provider => name, :uid => uid).tap do |auth|
394
+ auth.info = info unless skip_info?
395
+ auth.credentials = credentials_data if credentials_data
396
+ auth.extra = extra_data if extra_data
397
+ end
350
398
  end
351
399
 
352
400
  # Determines whether or not user info should be retrieved. This
@@ -361,6 +409,7 @@ module OmniAuth
361
409
  def skip_info?
362
410
  return false unless options.skip_info?
363
411
  return true unless options.skip_info.respond_to?(:call)
412
+
364
413
  options.skip_info.call(uid)
365
414
  end
366
415
 
@@ -377,6 +426,7 @@ module OmniAuth
377
426
  if options[kind].respond_to?(:call)
378
427
  result = options[kind].call(env)
379
428
  return nil unless result.is_a?(String)
429
+
380
430
  result
381
431
  else
382
432
  options[kind]
@@ -384,7 +434,12 @@ module OmniAuth
384
434
  end
385
435
 
386
436
  def request_path
387
- @request_path ||= options[:request_path].is_a?(String) ? options[:request_path] : "#{path_prefix}/#{name}"
437
+ @request_path ||=
438
+ if options[:request_path].is_a?(String)
439
+ options[:request_path]
440
+ else
441
+ "#{script_name}#{path_prefix}/#{name}"
442
+ end
388
443
  end
389
444
 
390
445
  def callback_path
@@ -392,7 +447,7 @@ module OmniAuth
392
447
  path = options[:callback_path] if options[:callback_path].is_a?(String)
393
448
  path ||= current_path if options[:callback_path].respond_to?(:call) && options[:callback_path].call(env)
394
449
  path ||= custom_path(:request_path)
395
- path ||= "#{path_prefix}/#{name}/callback"
450
+ path ||= "#{script_name}#{path_prefix}/#{name}/callback"
396
451
  path
397
452
  end
398
453
  end
@@ -401,10 +456,10 @@ module OmniAuth
401
456
  options[:setup_path] || "#{path_prefix}/#{name}/setup"
402
457
  end
403
458
 
404
- CURRENT_PATH_REGEX = %r{/$}
459
+ CURRENT_PATH_REGEX = %r{/$}.freeze
405
460
  EMPTY_STRING = ''.freeze
406
461
  def current_path
407
- @current_path ||= request.path_info.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
462
+ @current_path ||= request.path.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
408
463
  end
409
464
 
410
465
  def query_string
@@ -413,6 +468,9 @@ module OmniAuth
413
468
 
414
469
  def call_app!(env = @env)
415
470
  @app.call(env)
471
+ rescue StandardError => e
472
+ env['omniauth.error.app'] = true
473
+ raise e
416
474
  end
417
475
 
418
476
  def full_host
@@ -436,7 +494,7 @@ module OmniAuth
436
494
  end
437
495
 
438
496
  def callback_url
439
- full_host + script_name + callback_path + query_string
497
+ full_host + callback_path + query_string
440
498
  end
441
499
 
442
500
  def script_name
@@ -486,16 +544,15 @@ module OmniAuth
486
544
  OmniAuth.config.on_failure.call(env)
487
545
  end
488
546
 
489
- def dup
490
- super.tap do
491
- @options = @options.dup
492
- end
493
- end
494
-
495
547
  class Options < OmniAuth::KeyStore; end
496
548
 
497
549
  protected
498
550
 
551
+ def initialize_copy(*args)
552
+ super
553
+ @options = @options.dup
554
+ end
555
+
499
556
  def merge_stack(stack)
500
557
  stack.inject({}) do |a, e|
501
558
  a.merge!(e)
@@ -1,3 +1,3 @@
1
1
  module OmniAuth
2
- VERSION = '1.8.1'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
data/lib/omniauth.rb CHANGED
@@ -15,6 +15,7 @@ module OmniAuth
15
15
  autoload :Form, 'omniauth/form'
16
16
  autoload :AuthHash, 'omniauth/auth_hash'
17
17
  autoload :FailureEndpoint, 'omniauth/failure_endpoint'
18
+ autoload :AuthenticityTokenProtection, 'omniauth/authenticity_token_protection'
18
19
 
19
20
  def self.strategies
20
21
  @strategies ||= []
@@ -29,20 +30,22 @@ module OmniAuth
29
30
  logger
30
31
  end
31
32
 
32
- def self.defaults
33
+ def self.defaults # rubocop:disable MethodLength
33
34
  @defaults ||= {
34
35
  :camelizations => {},
35
36
  :path_prefix => '/auth',
36
37
  :on_failure => OmniAuth::FailureEndpoint,
37
38
  :failure_raise_out_environments => ['development'],
39
+ :request_validation_phase => OmniAuth::AuthenticityTokenProtection,
38
40
  :before_request_phase => nil,
39
41
  :before_callback_phase => nil,
40
42
  :before_options_phase => nil,
41
43
  :form_css => Form::DEFAULT_CSS,
42
44
  :test_mode => false,
43
45
  :logger => default_logger,
44
- :allowed_request_methods => %i[get post],
45
- :mock_auth => {:default => AuthHash.new('provider' => 'default', 'uid' => '1234', 'info' => {'name' => 'Example User'})}
46
+ :allowed_request_methods => %i[post],
47
+ :mock_auth => {:default => AuthHash.new('provider' => 'default', 'uid' => '1234', 'info' => {'name' => 'Example User'})},
48
+ :silence_get_warning => false
46
49
  }
47
50
  end
48
51
 
@@ -74,6 +77,14 @@ module OmniAuth
74
77
  end
75
78
  end
76
79
 
80
+ def request_validation_phase(&block)
81
+ if block_given?
82
+ @request_validation_phase = block
83
+ else
84
+ @request_validation_phase
85
+ end
86
+ end
87
+
77
88
  def before_request_phase(&block)
78
89
  if block_given?
79
90
  @before_request_phase = block
@@ -111,8 +122,9 @@ module OmniAuth
111
122
  camelizations[name.to_s] = camelized.to_s
112
123
  end
113
124
 
114
- attr_writer :on_failure, :before_callback_phase, :before_options_phase, :before_request_phase
115
- attr_accessor :failure_raise_out_environments, :path_prefix, :allowed_request_methods, :form_css, :test_mode, :mock_auth, :full_host, :camelizations, :logger
125
+ attr_writer :on_failure, :before_callback_phase, :before_options_phase, :before_request_phase, :request_validation_phase
126
+ attr_accessor :failure_raise_out_environments, :path_prefix, :allowed_request_methods, :form_css,
127
+ :test_mode, :mock_auth, :full_host, :camelizations, :logger, :silence_get_warning
116
128
  end
117
129
 
118
130
  def self.config
@@ -132,7 +144,7 @@ module OmniAuth
132
144
  end
133
145
 
134
146
  module Utils
135
- module_function
147
+ module_function # rubocop:disable Layout/IndentationWidth
136
148
 
137
149
  def form_css
138
150
  "<style type='text/css'>#{OmniAuth.config.form_css}</style>"
@@ -159,7 +171,7 @@ module OmniAuth
159
171
  if first_letter_in_uppercase
160
172
  word.to_s.gsub(%r{/(.?)}) { '::' + Regexp.last_match[1].upcase }.gsub(/(^|_)(.)/) { Regexp.last_match[2].upcase }
161
173
  else
162
- word.first + camelize(word)[1..-1]
174
+ camelize(word).tap { |w| w[0] = w[0].downcase }
163
175
  end
164
176
  end
165
177
  end
data/omniauth.gemspec CHANGED
@@ -5,9 +5,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'omniauth/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.add_dependency 'hashie', ['>= 3.4.6', '< 3.6.0']
9
- spec.add_dependency 'rack', ['>= 1.6.2', '< 3']
10
- spec.add_development_dependency 'bundler', '~> 1.14'
8
+ spec.add_dependency 'hashie', ['>= 3.4.6']
9
+ spec.add_dependency 'rack', '>= 2.2.3'
10
+ spec.add_development_dependency 'bundler', '~> 2.0'
11
+ spec.add_dependency 'rack-protection'
11
12
  spec.add_development_dependency 'rake', '~> 12.0'
12
13
  spec.authors = ['Michael Bleigh', 'Erik Michaels-Ober', 'Tom Milewski']
13
14
  spec.description = 'A generalized Rack framework for multiple-provider authentication.'
@@ -18,7 +19,7 @@ Gem::Specification.new do |spec|
18
19
  spec.name = 'omniauth'
19
20
  spec.require_paths = %w[lib]
20
21
  spec.required_rubygems_version = '>= 1.3.5'
21
- spec.required_ruby_version = '>= 2.1.9'
22
+ spec.required_ruby_version = '>= 2.2'
22
23
  spec.summary = spec.description
23
24
  spec.version = OmniAuth::VERSION
24
25
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  - Erik Michaels-Ober
9
9
  - Tom Milewski
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-12-28 00:00:00.000000000 Z
13
+ date: 2022-04-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hashie
@@ -19,9 +19,6 @@ dependencies:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
21
  version: 3.4.6
22
- - - "<"
23
- - !ruby/object:Gem::Version
24
- version: 3.6.0
25
22
  type: :runtime
26
23
  prerelease: false
27
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,43 +26,48 @@ dependencies:
29
26
  - - ">="
30
27
  - !ruby/object:Gem::Version
31
28
  version: 3.4.6
32
- - - "<"
33
- - !ruby/object:Gem::Version
34
- version: 3.6.0
35
29
  - !ruby/object:Gem::Dependency
36
30
  name: rack
37
31
  requirement: !ruby/object:Gem::Requirement
38
32
  requirements:
39
33
  - - ">="
40
34
  - !ruby/object:Gem::Version
41
- version: 1.6.2
42
- - - "<"
43
- - !ruby/object:Gem::Version
44
- version: '3'
35
+ version: 2.2.3
45
36
  type: :runtime
46
37
  prerelease: false
47
38
  version_requirements: !ruby/object:Gem::Requirement
48
39
  requirements:
49
40
  - - ">="
50
41
  - !ruby/object:Gem::Version
51
- version: 1.6.2
52
- - - "<"
53
- - !ruby/object:Gem::Version
54
- version: '3'
42
+ version: 2.2.3
55
43
  - !ruby/object:Gem::Dependency
56
44
  name: bundler
57
45
  requirement: !ruby/object:Gem::Requirement
58
46
  requirements:
59
47
  - - "~>"
60
48
  - !ruby/object:Gem::Version
61
- version: '1.14'
49
+ version: '2.0'
62
50
  type: :development
63
51
  prerelease: false
64
52
  version_requirements: !ruby/object:Gem::Requirement
65
53
  requirements:
66
54
  - - "~>"
67
55
  - !ruby/object:Gem::Version
68
- version: '1.14'
56
+ version: '2.0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: rack-protection
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
69
71
  - !ruby/object:Gem::Dependency
70
72
  name: rake
71
73
  requirement: !ruby/object:Gem::Requirement
@@ -89,18 +91,21 @@ executables: []
89
91
  extensions: []
90
92
  extra_rdoc_files: []
91
93
  files:
94
+ - ".github/FUNDING.yml"
92
95
  - ".github/ISSUE_TEMPLATE.md"
96
+ - ".github/workflows/main.yml"
93
97
  - ".gitignore"
94
98
  - ".rspec"
95
99
  - ".rubocop.yml"
96
- - ".travis.yml"
97
100
  - ".yardopts"
98
101
  - Gemfile
99
102
  - LICENSE.md
100
103
  - README.md
101
104
  - Rakefile
105
+ - SECURITY.md
102
106
  - lib/omniauth.rb
103
107
  - lib/omniauth/auth_hash.rb
108
+ - lib/omniauth/authenticity_token_protection.rb
104
109
  - lib/omniauth/builder.rb
105
110
  - lib/omniauth/failure_endpoint.rb
106
111
  - lib/omniauth/form.css
@@ -118,7 +123,7 @@ homepage: https://github.com/omniauth/omniauth
118
123
  licenses:
119
124
  - MIT
120
125
  metadata: {}
121
- post_install_message:
126
+ post_install_message:
122
127
  rdoc_options: []
123
128
  require_paths:
124
129
  - lib
@@ -126,16 +131,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
131
  requirements:
127
132
  - - ">="
128
133
  - !ruby/object:Gem::Version
129
- version: 2.1.9
134
+ version: '2.2'
130
135
  required_rubygems_version: !ruby/object:Gem::Requirement
131
136
  requirements:
132
137
  - - ">="
133
138
  - !ruby/object:Gem::Version
134
139
  version: 1.3.5
135
140
  requirements: []
136
- rubyforge_project:
137
- rubygems_version: 2.6.11
138
- signing_key:
141
+ rubygems_version: 3.2.32
142
+ signing_key:
139
143
  specification_version: 4
140
144
  summary: A generalized Rack framework for multiple-provider authentication.
141
145
  test_files: []
data/.travis.yml DELETED
@@ -1,24 +0,0 @@
1
- bundler_args: --without development
2
- before_install:
3
- - gem update --system
4
- - gem update bundler
5
- cache: bundler
6
- env:
7
- global:
8
- - JRUBY_OPTS="$JRUBY_OPTS --debug"
9
- language: ruby
10
- rvm:
11
- - jruby-9000
12
- - 2.1.10 # EOL Soon
13
- - 2.2.6
14
- - 2.3.3
15
- - 2.4.0
16
- - 2.5.0
17
- - jruby-head
18
- - ruby-head
19
- matrix:
20
- allow_failures:
21
- - rvm: jruby-head
22
- - rvm: ruby-head
23
- fast_finish: true
24
- sudo: false