pax_global_header 0000666 0000000 0000000 00000000064 15067257603 0014525 g ustar 00root root 0000000 0000000 52 comment=20ac5e05a39d58d18aca6419599f7176208f985d
omniauth-omniauth-586c401/ 0000775 0000000 0000000 00000000000 15067257603 0015447 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/.github/ 0000775 0000000 0000000 00000000000 15067257603 0017007 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/.github/FUNDING.yml 0000664 0000000 0000000 00000000057 15067257603 0020626 0 ustar 00root root 0000000 0000000 github: bobbymcwho
tidelift: rubygems/omniauth
omniauth-omniauth-586c401/.github/ISSUE_TEMPLATE.md 0000664 0000000 0000000 00000000460 15067257603 0021514 0 ustar 00root root 0000000 0000000 Please complete all sections.
### Configuration
- Provider Gem: `omniauth-*`
- Ruby Version: ``
- Framework: ``
- Platform: ``
### Expected Behavior
Tell us what should happen.
### Actual Behavior
Tell us what happens instead.
### Steps to Reproduce
Please list all steps to reproduce the issue.
omniauth-omniauth-586c401/.github/dependabot.yml 0000664 0000000 0000000 00000001116 15067257603 0021636 0 ustar 00root root 0000000 0000000 # To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: bundler
directory: '/'
schedule:
interval: weekly
open-pull-requests-limit: 99
- package-ecosystem: github-actions
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 99
omniauth-omniauth-586c401/.github/workflows/ 0000775 0000000 0000000 00000000000 15067257603 0021044 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/.github/workflows/jruby.yml 0000664 0000000 0000000 00000001064 15067257603 0022723 0 ustar 00root root 0000000 0000000 name: JRuby
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
jruby: [jruby, jruby-head]
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.jruby }}
bundler-cache: true
env:
JRUBY_OPTS: --debug
- name: Run tests
env:
JRUBY_OPTS: --debug
run: bundle exec rake
omniauth-omniauth-586c401/.github/workflows/main.yml 0000664 0000000 0000000 00000003322 15067257603 0022513 0 ustar 00root root 0000000 0000000 # This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
name: Ruby
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
ruby: [2.5, 2.6, 2.7, '3.0', 3.1, 3.2, 3.3, 3.4, head, debug]
exclude:
- os: macos
ruby: 2.5
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run tests
run: bundle exec rake
frozen-string-compat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
bundler-cache: true
- name: Run tests
env:
RUBYOPT: "--enable-frozen-string-literal"
run: bundle exec rake
coveralls:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
bundler-cache: true
- name: Run tests
run: bundle exec rake
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.github_token }}
path-to-lcov: './coverage/lcov/omniauth.lcov'
omniauth-omniauth-586c401/.github/workflows/truffle_ruby.yml 0000664 0000000 0000000 00000000766 15067257603 0024310 0 ustar 00root root 0000000 0000000 name: TruffleRuby
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
ruby: [truffleruby, truffleruby-head]
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run tests
run: bundle exec rake
omniauth-omniauth-586c401/.gitignore 0000664 0000000 0000000 00000000200 15067257603 0017427 0 ustar 00root root 0000000 0000000 *.gem
*~
.bundle
.rvmrc
.yardoc
Gemfile.lock
Gemfile.*.lock
coverage/*
doc/*
log/*
measurement/*
pkg/*
.DS_Store
.tool-versions
omniauth-omniauth-586c401/.rspec 0000664 0000000 0000000 00000000027 15067257603 0016563 0 ustar 00root root 0000000 0000000 --color
--order random
omniauth-omniauth-586c401/.rubocop.yml 0000664 0000000 0000000 00000001773 15067257603 0017731 0 ustar 00root root 0000000 0000000 AllCops:
TargetRubyVersion: 2.2
Layout/AccessModifierIndentation:
EnforcedStyle: outdent
Layout/AlignHash:
Enabled: false
Layout/DotPosition:
EnforcedStyle: trailing
Layout/SpaceInsideHashLiteralBraces:
EnforcedStyle: no_space
Lint/HandleExceptions:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/BlockNesting:
Max: 2
Metrics/LineLength:
AllowURI: true
Enabled: false
Metrics/MethodLength:
CountComments: false
Max: 15
Metrics/ParameterLists:
Max: 4
CountKeywordArgs: true
Metrics/AbcSize:
Enabled: false
Style/CollectionMethods:
PreferredMethods:
map: 'collect'
reduce: 'inject'
find: 'detect'
find_all: 'select'
Style/Documentation:
Enabled: false
Style/DoubleNegation:
Enabled: false
Style/EachWithObject:
Enabled: false
Style/Encoding:
Enabled: false
Style/ExpandPathArguments:
Enabled: false
Style/HashSyntax:
EnforcedStyle: hash_rockets
Style/Lambda:
Enabled: false
Style/RaiseArgs:
EnforcedStyle: compact
omniauth-omniauth-586c401/.yardopts 0000664 0000000 0000000 00000000070 15067257603 0017312 0 ustar 00root root 0000000 0000000 --markup markdown
--markup-provider maruku
-
LICENSE.md
omniauth-omniauth-586c401/Gemfile 0000664 0000000 0000000 00000000754 15067257603 0016750 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gem 'jruby-openssl', '~> 0.10.5', platforms: :jruby
gem 'rake', '>= 12.0'
gem 'yard', '>= 0.9.11'
group :development do
gem 'benchmark-ips'
gem 'kramdown'
gem 'memory_profiler'
gem 'pry'
end
group :test do
gem 'cgi'
gem 'coveralls_reborn', '~> 0.19.0', require: false
gem 'rack-test'
gem 'rspec', '~> 3.5'
gem 'rack-freeze'
gem 'rubocop', '>= 0.58.2', '< 0.69.0', platforms: %i[ruby_22 ruby_23 ruby_24]
gem 'simplecov-lcov'
end
gemspec
omniauth-omniauth-586c401/LICENSE.md 0000664 0000000 0000000 00000002072 15067257603 0017054 0 ustar 00root root 0000000 0000000 Copyright (c) 2010-2017 Michael Bleigh and Intridea, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
omniauth-omniauth-586c401/README.md 0000664 0000000 0000000 00000026122 15067257603 0016731 0 ustar 00root root 0000000 0000000 # OmniAuth: Standardized Multi-Provider Authentication
[][gem]
[][githubactions]
[][githubactionstruffle]
[][githubactionsjruby]
[][codeclimate]
[][coveralls]
[gem]: https://rubygems.org/gems/omniauth
[githubactions]: https://github.com/omniauth/omniauth/actions/workflows/main.yml
[githubactionstruffle]: https://github.com/omniauth/omniauth/actions/workflows/truffle_ruby.yml
[githubactionsjruby]: https://github.com/omniauth/omniauth/actions/workflows/jruby.yml
[codeclimate]: https://codeclimate.com/github/omniauth/omniauth
[coveralls]: https://coveralls.io/r/omniauth/omniauth
This is the documentation for the in-development branch of OmniAuth.
You can find the documentation for the latest stable release [here](https://github.com/omniauth/omniauth/tree/v2.1.4)
## An Introduction
OmniAuth is a library that standardizes multi-provider authentication for
web applications. It was created to be powerful, flexible, and do as
little as possible. Any developer can create **strategies** for OmniAuth
that can authenticate users via disparate systems. OmniAuth strategies
have been created for everything from Facebook to LDAP.
In order to use OmniAuth in your applications, you will need to leverage
one or more strategies. These strategies are generally released
individually as RubyGems, and you can see a [community maintained list](https://github.com/omniauth/omniauth/wiki/List-of-Strategies)
on the wiki for this project.
One strategy, called `Developer`, is included with OmniAuth and provides
a completely insecure, non-production-usable strategy that directly
prompts a user for authentication information and then passes it
straight through. You can use it as a placeholder when you start
development and easily swap in other strategies later.
## Getting Started
Each OmniAuth strategy is a Rack Middleware. That means that you can use
it the same way that you use any other Rack middleware. For example, to
use the built-in Developer strategy in a Sinatra application you might
do this:
```ruby
require 'sinatra'
require 'omniauth'
class MyApplication < Sinatra::Base
use Rack::Session::Cookie
use OmniAuth::Strategies::Developer
end
```
Because OmniAuth is built for *multi-provider* authentication, you may
want to leave room to run multiple strategies. For this, the built-in
`OmniAuth::Builder` class gives you an easy way to specify multiple
strategies. Note that there is **no difference** between the following
code and using each strategy individually as middleware. This is an
example that you might put into a Rails initializer at
`config/initializers/omniauth.rb`:
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer unless Rails.env.production?
provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end
```
You should look to the documentation for each provider you use for
specific initialization requirements.
## Integrating OmniAuth Into Your Application
OmniAuth is an extremely low-touch library. It is designed to be a
black box that you can send your application's users into when you need
authentication and then get information back. OmniAuth was intentionally
built not to automatically associate with a User model or make
assumptions about how many authentication methods you might want to use
or what you might want to do with the data once a user has
authenticated. This makes OmniAuth incredibly flexible. To use OmniAuth,
you need only to redirect users to `/auth/:provider`, where `:provider`
is the name of the strategy (for example, `developer` or `twitter`).
From there, OmniAuth will take over and take the user through the
necessary steps to authenticate them with the chosen strategy.
Once the user has authenticated, what do you do next? OmniAuth simply
sets a special hash called the Authentication Hash on the Rack
environment of a request to `/auth/:provider/callback`. This hash
contains as much information about the user as OmniAuth was able to
glean from the utilized strategy. You should set up an endpoint in your
application that matches to the callback URL and then performs whatever
steps are necessary for your application.
The `omniauth.auth` key in the environment hash provides an
Authentication Hash which will contain information about the just
authenticated user including a unique id, the strategy they just used
for authentication, and personal details such as name and email address
as available. For an in-depth description of what the authentication
hash might contain, see the [Auth Hash Schema wiki page](https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema).
Note that OmniAuth does not perform any actions beyond setting some
environment information on the callback request. It is entirely up to
you how you want to implement the particulars of your application's
authentication flow.
## rack_csrf
`omniauth` is not OOTB-compatible with [rack_csrf](https://github.com/baldowl/rack_csrf). In order to do so, the following code needs to be added to the application bootstrapping code:
```ruby
OmniAuth::AuthenticityTokenProtection.default_options(key: "csrf.token", authenticity_param: "_csrf")
```
## Rails (without Devise)
To get started, add the following gems
**Gemfile**:
```ruby
gem 'omniauth'
gem "omniauth-rails_csrf_protection"
```
Then insert OmniAuth as a middleware
**config/initializers/omniauth.rb**:
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer if Rails.env.development?
end
```
Additional providers can be added here in the future. Next we wire it
all up using routes, a controller and a login view.
**config/routes.rb**:
```ruby
get 'auth/:provider/callback', to: 'sessions#create'
get '/login', to: 'sessions#new'
```
**app/controllers/sessions_controller.rb**:
```ruby
class SessionsController < ApplicationController
def new
render :new
end
def create
user_info = request.env['omniauth.auth']
raise user_info # Your own session management should be placed here.
end
end
```
**app/views/sessions/new.html.erb**:
```erb
<%= form_tag('/auth/developer', method: 'post', data: {turbo: false}) do %>
<% end %>
```
Now if you visit `/login` and click the Login button, you should see the
OmniAuth developer login screen. After submitting it, you are returned to your
application at `Sessions#create`. The raise should now display all the Omniauth
details you have available to integrate it into your own user management.
If you want out of the box usermanagement, you should consider using Omniauth
through Devise. Please visit the [Devise Github page](https://github.com/heartcombo/devise#omniauth)
for more information.
## Rails API
The following middleware are (by default) included for session management in
Rails applications. When using OmniAuth with a Rails API, you'll need to add
one of these required middleware back in:
- `ActionDispatch::Session::CacheStore`
- `ActionDispatch::Session::CookieStore`
- `ActionDispatch::Session::MemCacheStore`
The trick to adding these back in is that, by default, they are passed
`session_options` when added (including the session key), so you can't just add
a `session_store.rb` initializer, add `use ActionDispatch::Session::CookieStore`
and have sessions functioning as normal.
To be clear: sessions may work, but your session options will be ignored
(i.e. the session key will default to `_session_id`). Instead of the
initializer, you'll have to set the relevant options somewhere
before your middleware is built (like `application.rb`) and pass them to your
preferred middleware, like this:
**application.rb:**
```ruby
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies # Required for all session management
config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
```
(Thanks @mltsy)
## Logging
OmniAuth supports a configurable logger. By default, OmniAuth will log
to `STDOUT` but you can configure this using `OmniAuth.config.logger`:
```ruby
# Rails application example
OmniAuth.config.logger = Rails.logger
```
## Origin Param
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.
Omniauth supports the following settings which can be configured on a provider level:
**Default**:
```ruby
provider :twitter, ENV['KEY'], ENV['SECRET']
POST /auth/twitter/?origin=[URL]
# If the `origin` parameter is blank, `omniauth.origin` is set to HTTP_REFERER
```
**Using a differently named origin parameter**:
```ruby
provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'
POST /auth/twitter/?return_to=[URL]
# If the `return_to` parameter is blank, `omniauth.origin` is set to HTTP_REFERER
```
**Disabled**:
```ruby
provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: false
POST /auth/twitter
# This means the origin should be handled by your own application.
# Note that `omniauth.origin` will always be blank.
```
## Resources
The [OmniAuth Wiki](https://github.com/omniauth/omniauth/wiki) has
actively maintained in-depth documentation for OmniAuth. It should be
your first stop if you are wondering about a more in-depth look at
OmniAuth, how it works, and how to use it.
## OmniAuth for Enterprise
Available as part of the Tidelift Subscription.
The maintainers of OmniAuth 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?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
## Supported Ruby Versions
OmniAuth is tested under 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, truffleruby, and JRuby.
## Versioning
This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
of this scheme should be reported as bugs. Specifically, if a minor or patch
version is released that breaks backward compatibility, that version should be
immediately yanked and/or a new version should be immediately released that
restores compatibility. Breaking changes to the public API will only be
introduced with new major versions. As a result of this policy, you can (and
should) specify a dependency on this gem using the [Pessimistic Version
Constraint][pvc] with two digits of precision. For example:
spec.add_dependency 'omniauth', '~> 1.0'
[semver]: http://semver.org/
[pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
## License
Copyright (c) 2010-2017 Michael Bleigh and Intridea, Inc. See [LICENSE][] for
details.
[license]: LICENSE.md
omniauth-omniauth-586c401/Rakefile 0000664 0000000 0000000 00000002167 15067257603 0017122 0 ustar 00root root 0000000 0000000 require 'bundler'
Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :test => :spec
begin
require 'rubocop/rake_task'
RuboCop::RakeTask.new
rescue LoadError
task :rubocop do
warn 'RuboCop is disabled'
end
end
task :default => %i[spec rubocop]
namespace :perf do
task :setup do
require 'omniauth'
require 'rack/test'
app = Rack::Builder.new do |b|
b.use Rack::Session::Cookie, :secret => 'abc123'
b.use OmniAuth::Strategies::Developer
b.run lambda { |_env| [200, {}, ['Not Found']] }
end.to_app
@app = Rack::MockRequest.new(app)
def call_app(path = ENV['GET_PATH'] || '/')
result = @app.get(path)
raise "Did not succeed #{result.body}" unless result.status == 200
result
end
end
task :ips => :setup do
require 'benchmark/ips'
Benchmark.ips do |x|
x.report('ips') { call_app }
end
end
task :mem => :setup do
require 'memory_profiler'
num = Integer(ENV['CNT'] || 1)
report = MemoryProfiler.report do
num.times { call_app }
end
report.pretty_print
end
end
omniauth-omniauth-586c401/SECURITY.md 0000664 0000000 0000000 00000001021 15067257603 0017232 0 ustar 00root root 0000000 0000000 # Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 2.1.x | :white_check_mark: |
| 2.0.x | :white_check_mark: |
| <= 1.9.1 | :x: |
## Security contact information
To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
omniauth-omniauth-586c401/lib/ 0000775 0000000 0000000 00000000000 15067257603 0016215 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/lib/omniauth.rb 0000664 0000000 0000000 00000012230 15067257603 0020364 0 ustar 00root root 0000000 0000000 # TODO: Fixed in https://github.com/rack/rack/pull/1610 for Rack 3
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
require 'delegate'
end
require 'rack'
require 'singleton'
require 'logger'
module OmniAuth
class Error < StandardError; end
module Strategies
autoload :Developer, 'omniauth/strategies/developer'
end
autoload :Builder, 'omniauth/builder'
autoload :Strategy, 'omniauth/strategy'
autoload :Test, 'omniauth/test'
autoload :Form, 'omniauth/form'
autoload :AuthHash, 'omniauth/auth_hash'
autoload :FailureEndpoint, 'omniauth/failure_endpoint'
autoload :AuthenticityTokenProtection, 'omniauth/authenticity_token_protection'
def self.strategies
@strategies ||= []
end
class Configuration
include Singleton
def self.default_logger
logger = Logger.new(STDOUT)
logger.progname = 'omniauth'
logger
end
def self.defaults # rubocop:disable MethodLength
@defaults ||= {
:camelizations => {},
:path_prefix => '/auth',
:on_failure => OmniAuth::FailureEndpoint,
:failure_raise_out_environments => ['development'],
:request_validation_phase => OmniAuth::AuthenticityTokenProtection,
:before_request_phase => nil,
:after_request_phase => nil,
:before_callback_phase => nil,
:before_options_phase => nil,
:form_css => Form::DEFAULT_CSS,
:test_mode => false,
:logger => default_logger,
:allowed_request_methods => %i[post],
:mock_auth => {:default => AuthHash.new('provider' => 'default', 'uid' => '1234', 'info' => {'name' => 'Example User'})},
:silence_get_warning => false
}
end
def initialize
self.class.defaults.each_pair { |k, v| send("#{k}=", v) }
end
def on_failure(&block)
if block_given?
@on_failure = block
else
@on_failure
end
end
def before_callback_phase(&block)
if block_given?
@before_callback_phase = block
else
@before_callback_phase
end
end
def before_options_phase(&block)
if block_given?
@before_options_phase = block
else
@before_options_phase
end
end
def request_validation_phase(&block)
if block_given?
@request_validation_phase = block
else
@request_validation_phase
end
end
def before_request_phase(&block)
if block_given?
@before_request_phase = block
else
@before_request_phase
end
end
def after_request_phase(&block)
if block_given?
@after_request_phase = block
else
@after_request_phase
end
end
def add_mock(provider, original = {})
# Create key-stringified new hash from given auth hash
mock = {}
original.each_pair do |key, val|
mock[key.to_s] = if val.is_a? Hash
Hash[val.each_pair { |k, v| [k.to_s, v] }]
else
val
end
end
# Merge with the default mock and ensure provider is correct.
mock = mock_auth[:default].dup.merge(mock)
mock['provider'] = provider.to_s
# Add it to the mocks.
mock_auth[provider.to_sym] = mock
end
# This is a convenience method to be used by strategy authors
# so that they can add special cases to the camelization utility
# method that allows OmniAuth::Builder to work.
#
# @param name [String] The underscored name, e.g. `oauth`
# @param camelized [String] The properly camelized name, e.g. 'OAuth'
def add_camelization(name, camelized)
camelizations[name.to_s] = camelized.to_s
end
attr_writer :on_failure, :before_callback_phase, :before_options_phase, :before_request_phase, :after_request_phase, :request_validation_phase
attr_accessor :failure_raise_out_environments, :path_prefix, :allowed_request_methods, :form_css,
:test_mode, :mock_auth, :full_host, :camelizations, :logger, :silence_get_warning
end
def self.config
Configuration.instance
end
def self.configure
yield config
end
def self.logger
config.logger
end
def self.mock_auth_for(provider)
config.mock_auth[provider.to_sym] || config.mock_auth[:default]
end
module Utils
module_function # rubocop:disable Layout/IndentationWidth
def form_css
""
end
def deep_merge(hash, other_hash)
target = hash.dup
other_hash.each_key do |key|
if other_hash[key].is_a?(::Hash) && hash[key].is_a?(::Hash)
target[key] = deep_merge(target[key], other_hash[key])
next
end
target[key] = other_hash[key]
end
target
end
def camelize(word, first_letter_in_uppercase = true)
return OmniAuth.config.camelizations[word.to_s] if OmniAuth.config.camelizations[word.to_s]
if first_letter_in_uppercase
word.to_s.gsub(%r{/(.?)}) { '::' + Regexp.last_match[1].upcase }.gsub(/(^|_)(.)/) { Regexp.last_match[2].upcase }
else
camelize(word).tap { |w| w[0] = w[0].downcase }
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/ 0000775 0000000 0000000 00000000000 15067257603 0020041 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/lib/omniauth/auth_hash.rb 0000664 0000000 0000000 00000002435 15067257603 0022336 0 ustar 00root root 0000000 0000000 require 'omniauth/key_store'
module OmniAuth
# The AuthHash is a normalized schema returned by all OmniAuth
# strategies. It maps as much user information as the provider
# is able to provide into the InfoHash (stored as the `'info'`
# key).
class AuthHash < OmniAuth::KeyStore
def self.subkey_class
Hashie::Mash
end
# Tells you if this is considered to be a valid
# OmniAuth AuthHash. The requirements for that
# are that it has a provider name, a uid, and a
# valid info hash. See InfoHash#valid? for
# more details there.
def valid?
uid? && provider? && info? && info.valid?
end
def regular_writer(key, value)
value = InfoHash.new(value) if key.to_s == 'info' && value.is_a?(::Hash) && !value.is_a?(InfoHash)
super
end
class InfoHash < OmniAuth::KeyStore
def self.subkey_class
Hashie::Mash
end
def name
return self[:name] if self[:name]
return "#{first_name} #{last_name}".strip if first_name? || last_name?
return nickname if nickname?
return email if email?
nil
end
def name?
!!name
end
alias valid? name?
def to_hash
hash = super
hash['name'] ||= name
hash
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/authenticity_token_protection.rb 0000664 0000000 0000000 00000001200 15067257603 0026537 0 ustar 00root root 0000000 0000000 require 'rack-protection'
module OmniAuth
class AuthenticityError < StandardError; end
class AuthenticityTokenProtection < Rack::Protection::AuthenticityToken
def initialize(options = {})
@options = default_options.merge(options)
end
def self.call(env)
new.call!(env)
end
def call!(env)
return if accepts?(env)
instrument env
react env
end
alias_method :call, :call!
private
def deny(_env)
OmniAuth.logger.send(:warn, "Attack prevented by #{self.class}")
raise AuthenticityError.new(options[:message])
end
alias default_reaction deny
end
end
omniauth-omniauth-586c401/lib/omniauth/builder.rb 0000664 0000000 0000000 00000002362 15067257603 0022017 0 ustar 00root root 0000000 0000000 module OmniAuth
class Builder < ::Rack::Builder
def on_failure(&block)
OmniAuth.config.on_failure = block
end
def before_options_phase(&block)
OmniAuth.config.before_options_phase = block
end
def before_request_phase(&block)
OmniAuth.config.before_request_phase = block
end
def after_request_phase(&block)
OmniAuth.config.after_request_phase = block
end
def before_callback_phase(&block)
OmniAuth.config.before_callback_phase = block
end
def configure(&block)
OmniAuth.configure(&block)
end
def options(options = false)
return @options ||= {} if options == false
@options = options
end
def provider(klass, *args, **opts, &block)
if klass.is_a?(Class)
middleware = klass
else
begin
middleware = OmniAuth::Strategies.const_get(OmniAuth::Utils.camelize(klass.to_s).to_s, false)
rescue NameError
raise(LoadError.new("Could not find matching strategy for #{klass.inspect}. You may need to install an additional gem (such as omniauth-#{klass})."))
end
end
use middleware, *args, **options.merge(opts), &block
end
def call(env)
to_app.call(env)
end
end
end
omniauth-omniauth-586c401/lib/omniauth/failure_endpoint.rb 0000664 0000000 0000000 00000003037 15067257603 0023720 0 ustar 00root root 0000000 0000000 module OmniAuth
# This simple Rack endpoint that serves as the default
# 'failure' mechanism for OmniAuth. If a strategy fails for
# any reason this endpoint will be invoked. The default behavior
# is to redirect to `/auth/failure` except in the case of
# a development `RACK_ENV`, in which case an exception will
# be raised.
class FailureEndpoint
attr_reader :env
def self.call(env)
new(env).call
end
def initialize(env)
@env = env
end
def call
raise_out! if OmniAuth.config.failure_raise_out_environments.include?(ENV['RACK_ENV'].to_s)
redirect_to_failure
end
def raise_out!
raise(env['omniauth.error'] || OmniAuth::Error.new(env['omniauth.error.type']))
end
def redirect_to_failure
message_key = env['omniauth.error.type']
new_path = "#{env['SCRIPT_NAME']}#{strategy_path_prefix}/failure?message=#{Rack::Utils.escape(message_key)}#{origin_query_param}#{strategy_name_query_param}"
Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
end
def strategy_path_prefix
if env['omniauth.error.strategy']
env['omniauth.error.strategy'].path_prefix
else
OmniAuth.config.path_prefix
end
end
def strategy_name_query_param
return '' unless env['omniauth.error.strategy']
"&strategy=#{env['omniauth.error.strategy'].name}"
end
def origin_query_param
return '' unless env['omniauth.origin']
"&origin=#{Rack::Utils.escape(env['omniauth.origin'])}"
end
end
end
omniauth-omniauth-586c401/lib/omniauth/form.css 0000664 0000000 0000000 00000003067 15067257603 0021524 0 ustar 00root root 0000000 0000000 body {
background: #ccc;
font-family: "Lucida Grande", "Lucida Sans", Helvetica, Arial, sans-serif;
}
h1 {
text-align: center;
margin: 30px auto 0px;
font-size: 18px;
padding: 10px 10px 15px;
background: #555;
color: white;
width: 320px;
border: 10px solid #444;
border-bottom: 0;
-moz-border-radius-topleft: 10px;
-moz-border-radius-topright: 10px;
-webkit-border-top-left-radius: 10px;
-webkit-border-top-right-radius: 10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
h1, form {
-moz-box-shadow: 2px 2px 7px rgba(0,0,0,0.3);
-webkit-box-shadow: 2px 2px 7px rgba(0,0,0,0.3);
}
form {
background: white;
border: 10px solid #eee;
border-top: 0;
padding: 20px;
margin: 0px auto 40px;
width: 300px;
-moz-border-radius-bottomleft: 10px;
-moz-border-radius-bottomright: 10px;
-webkit-border-bottom-left-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
input {
font-size: 18px;
padding: 4px 8px;
display: block;
margin-bottom: 10px;
width: 280px;
}
input#identifier, input#openid_url {
background: url(https://openid.net/images/login-bg.gif) no-repeat;
background-position: 0 50%;
padding-left: 18px;
}
button {
font-size: 22px;
padding: 4px 8px;
display: block;
margin: 20px auto 0;
}
fieldset {
border: 1px solid #ccc;
border-left: 0;
border-right: 0;
padding: 10px 0;
}
fieldset input {
width: 260px;
font-size: 16px;
}
omniauth-omniauth-586c401/lib/omniauth/form.rb 0000664 0000000 0000000 00000005067 15067257603 0021341 0 ustar 00root root 0000000 0000000 module OmniAuth
class Form
DEFAULT_CSS = File.read(File.expand_path('../form.css', __FILE__))
attr_accessor :options
def initialize(options = {})
options[:title] ||= 'Authentication Info Required'
options[:header_info] ||= ''
options[:method] ||= 'post'
self.options = options
@html = +'' # unary + string allows it to be mutable if strings are frozen
@with_custom_button = false
@footer = nil
header(options[:title], options[:header_info])
end
def self.build(options = {}, &block)
form = OmniAuth::Form.new(options)
if block.arity > 0
yield form
else
form.instance_eval(&block)
end
form
end
def label_field(text, target)
@html << "\n"
self
end
def input_field(type, name)
@html << "\n"
self
end
def text_field(label, name)
label_field(label, name)
input_field('text', name)
self
end
def password_field(label, name)
label_field(label, name)
input_field('password', name)
self
end
def button(text)
@with_custom_button = true
@html << "\n"
end
def html(html)
@html << html
end
def fieldset(legend, options = {}, &block)
@html << "\n
HTML
@footer = true
self
end
def to_html
footer
@html
end
def to_response
footer
Rack::Response.new(@html, 200, 'content-type' => 'text/html').finish
end
protected
def css
"\n"
end
end
end
omniauth-omniauth-586c401/lib/omniauth/key_store.rb 0000664 0000000 0000000 00000001140 15067257603 0022366 0 ustar 00root root 0000000 0000000 require 'hashie/mash'
module OmniAuth
# Generic helper hash that allows method access on deeply nested keys.
class KeyStore < ::Hashie::Mash
# Disables warnings on Hashie 3.5.0+ for overwritten keys
def self.override_logging
require 'hashie/version'
return unless Gem::Version.new(Hashie::VERSION) >= Gem::Version.new('3.5.0')
if respond_to?(:disable_warnings)
disable_warnings
else
define_method(:log_built_in_message) { |*| }
private :log_built_in_message
end
end
# Disable on loading of the class
override_logging
end
end
omniauth-omniauth-586c401/lib/omniauth/strategies/ 0000775 0000000 0000000 00000000000 15067257603 0022213 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/lib/omniauth/strategies/developer.rb 0000664 0000000 0000000 00000003263 15067257603 0024531 0 ustar 00root root 0000000 0000000 module OmniAuth
module Strategies
# The Developer strategy is a very simple strategy that can be used as a
# placeholder in your application until a different authentication strategy
# is swapped in. It has zero security and should *never* be used in a
# production setting.
#
# ## Usage
#
# To use the Developer strategy, all you need to do is put it in like any
# other strategy:
#
# @example Basic Usage
#
# use OmniAuth::Builder do
# provider :developer
# end
#
# @example Custom Fields
#
# use OmniAuth::Builder do
# provider :developer,
# :fields => [:first_name, :last_name],
# :uid_field => :last_name
# end
#
# This will create a strategy that, when the user visits `/auth/developer`
# they will be presented a form that prompts for (by default) their name
# and email address. The auth hash will be populated with these fields and
# the `uid` will simply be set to the provided email.
class Developer
include OmniAuth::Strategy
option :fields, %i[name email]
option :uid_field, :email
def request_phase
form = OmniAuth::Form.new(:title => 'User Info', :url => callback_path, :method => 'get')
options.fields.each do |field|
form.text_field field.to_s.capitalize.tr('_', ' '), field.to_s
end
form.button 'Sign In'
form.to_response
end
uid do
request.params[options.uid_field.to_s]
end
info do
options.fields.inject({}) do |hash, field|
hash[field] = request.params[field.to_s]
hash
end
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/strategy.rb 0000664 0000000 0000000 00000043772 15067257603 0022245 0 ustar 00root root 0000000 0000000 require 'omniauth/key_store'
module OmniAuth
class NoSessionError < StandardError; end
# The Strategy is the base unit of OmniAuth's ability to
# wrangle multiple providers. Each strategy provided by
# OmniAuth includes this mixin to gain the default functionality
# necessary to be compatible with the OmniAuth library.
module Strategy # rubocop:disable ModuleLength
def self.included(base)
OmniAuth.strategies << base
base.extend ClassMethods
base.class_eval do
option :setup, false
option :skip_info, false
option :origin_param, 'origin'
end
end
module ClassMethods
# Returns an inherited set of default options set at the class-level
# for each strategy.
def default_options
# existing = superclass.default_options if superclass.respond_to?(:default_options)
existing = superclass.respond_to?(:default_options) ? superclass.default_options : {}
@default_options ||= OmniAuth::Strategy::Options.new(existing)
end
# This allows for more declarative subclassing of strategies by allowing
# default options to be set using a simple configure call.
#
# @param options [Hash] If supplied, these will be the default options (deep-merged into the superclass's default options).
# @yield [Options] The options Mash that allows you to set your defaults as you'd like.
#
# @example Using a yield to configure the default options.
#
# class MyStrategy
# include OmniAuth::Strategy
#
# configure do |c|
# c.foo = 'bar'
# end
# end
#
# @example Using a hash to configure the default options.
#
# class MyStrategy
# include OmniAuth::Strategy
# configure foo: 'bar'
# end
def configure(options = nil)
if block_given?
yield default_options
else
default_options.deep_merge!(options)
end
end
# Directly declare a default option for your class. This is a useful from
# a documentation perspective as it provides a simple line-by-line analysis
# of the kinds of options your strategy provides by default.
#
# @param name [Symbol] The key of the default option in your configuration hash.
# @param value [Object] The value your object defaults to. Nil if not provided.
#
# @example
#
# class MyStrategy
# include OmniAuth::Strategy
#
# option :foo, 'bar'
# option
# end
def option(name, value = nil)
default_options[name] = value
end
# Sets (and retrieves) option key names for initializer arguments to be
# recorded as. This takes care of 90% of the use cases for overriding
# the initializer in OmniAuth Strategies.
def args(args = nil)
if args
@args = Array(args)
return
end
existing = superclass.respond_to?(:args) ? superclass.args : []
(instance_variable_defined?(:@args) && @args) || existing
end
%w[uid info extra credentials].each do |fetcher|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
attr_reader :#{fetcher}_proc
private :#{fetcher}_proc
def #{fetcher}(&block)
return #{fetcher}_proc unless block_given?
@#{fetcher}_proc = block
end
def #{fetcher}_stack(context)
compile_stack(self.ancestors, :#{fetcher}, context)
end
RUBY
end
def compile_stack(ancestors, method, context)
stack = ancestors.inject([]) do |a, ancestor|
a << context.instance_eval(&ancestor.send(method)) if ancestor.respond_to?(method) && ancestor.send(method)
a
end
stack.reverse!
end
end
attr_reader :app, :env, :options, :response
# Initializes the strategy by passing in the Rack endpoint,
# the unique URL segment name for this strategy, and any
# additional arguments. An `options` hash is automatically
# created from the last argument if it is a hash.
#
# @param app [Rack application] The application on which this middleware is applied.
#
# @overload new(app, options = {})
# If nothing but a hash is supplied, initialized with the supplied options
# overriding the strategy's default options via a deep merge.
# @overload new(app, *args, options = {})
# If the strategy has supplied custom arguments that it accepts, they may
# will be passed through and set to the appropriate values.
#
# @yield [Options] Yields options to block for further configuration.
def initialize(app, *args, &block) # rubocop:disable UnusedMethodArgument
@app = app
@env = nil
@options = self.class.default_options.dup
options.deep_merge!(args.pop) if args.last.is_a?(Hash)
options[:name] ||= self.class.to_s.split('::').last.downcase
self.class.args.each do |arg|
break if args.empty?
options[arg] = args.shift
end
# Make sure that all of the args have been dealt with, otherwise error out.
raise(ArgumentError.new("Received wrong number of arguments. #{args.inspect}")) unless args.empty?
yield options if block_given?
end
def inspect
"#<#{self.class}>"
end
# Direct access to the OmniAuth logger, automatically prefixed
# with this strategy's name.
#
# @example
# log :warn, "This is a warning."
def log(level, message)
OmniAuth.logger.send(level, "(#{name}) #{message}")
end
# Duplicates this instance and runs #call! on it.
# @param [Hash] The Rack environment.
def call(env)
dup.call!(env)
end
# The logic for dispatching any additional actions that need
# to be taken. For instance, calling the request phase if
# the request path is recognized.
#
# @param env [Hash] The Rack environment.
def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
unless env['rack.session']
error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
raise(error)
end
@env = env
warn_if_using_get_on_request_path
@env['omniauth.strategy'] = self if on_auth_path?
return mock_call!(env) if OmniAuth.config.test_mode
begin
return options_call if on_auth_path? && options_request?
return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
return callback_call if on_callback_path?
return other_phase if respond_to?(:other_phase)
rescue StandardError => e
raise e if env.delete('omniauth.error.app')
return fail!(e.message, e)
end
@app.call(env)
end
def warn_if_using_get_on_request_path
return unless on_request_path?
return unless OmniAuth.config.allowed_request_methods.include?(:get)
return if OmniAuth.config.silence_get_warning
log :warn, <<-WARN
You are using GET as an allowed request method for OmniAuth. This may leave
you open to CSRF attacks. As of v2.0.0, OmniAuth by default allows only POST
to its own routes. You should review the following resources to guide your
mitigation:
https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
https://github.com/omniauth/omniauth/issues/960
https://nvd.nist.gov/vuln/detail/CVE-2015-9284
https://github.com/omniauth/omniauth/pull/809
You can ignore this warning by setting:
OmniAuth.config.silence_get_warning = true
WARN
end
# Responds to an OPTIONS request.
def options_call
OmniAuth.config.before_options_phase.call(env) if OmniAuth.config.before_options_phase
verbs = OmniAuth.config.allowed_request_methods.collect(&:to_s).collect(&:upcase).join(', ')
[200, {'Allow' => verbs}, []]
end
# Performs the steps necessary to run the request phase of a strategy.
def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
setup_phase
log :debug, 'Request phase initiated.'
# store query params from the request url, extracted in the callback_phase
session['omniauth.params'] = request.GET
OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
result = if options.form.respond_to?(:call)
log :debug, 'Rendering form from supplied Rack endpoint.'
options.form.call(env)
elsif options.form
log :debug, 'Rendering form from underlying application.'
call_app!
elsif !options.origin_param
request_phase
else
if request.params[options.origin_param]
env['rack.session']['omniauth.origin'] = request.params[options.origin_param]
elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
end
request_phase
end
OmniAuth.config.after_request_phase.call(env) if OmniAuth.config.after_request_phase
result
rescue OmniAuth::AuthenticityError => e
fail!(:authenticity_error, e)
end
# Performs the steps necessary to run the callback phase of a strategy.
def callback_call
setup_phase
log :debug, 'Callback phase initiated.'
@env['omniauth.origin'] = session.delete('omniauth.origin')
@env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
@env['omniauth.params'] = session.delete('omniauth.params') || {}
OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
callback_phase
end
# Returns true if the environment recognizes either the
# request or callback path.
def on_auth_path?
on_request_path? || on_callback_path?
end
def on_request_path?
if options[:request_path].respond_to?(:call)
options[:request_path].call(env)
else
on_path?(request_path)
end
end
def on_callback_path?
on_path?(callback_path)
end
def on_path?(path)
current_path.casecmp(path).zero?
end
def options_request?
request.request_method == 'OPTIONS'
end
# This is called in lieu of the normal request process
# in the event that OmniAuth has been configured to be
# in test mode.
def mock_call!(*)
begin
return mock_request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
return mock_callback_call if on_callback_path?
rescue StandardError => e
raise e if env.delete('omniauth.error.app')
return fail!(e.message, e)
end
call_app!
end
def mock_request_call
setup_phase
session['omniauth.params'] = request.GET
OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
if options.origin_param
if request.params[options.origin_param]
session['omniauth.origin'] = request.params[options.origin_param]
elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
session['omniauth.origin'] = env['HTTP_REFERER']
end
end
result = redirect(callback_url)
OmniAuth.config.after_request_phase.call(env) if OmniAuth.config.after_request_phase
result
end
def mock_callback_call
setup_phase
origin = session.delete('omniauth.origin')
@env['omniauth.origin'] ||= origin
@env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
@env['omniauth.params'] = session.delete('omniauth.params') || {}
mocked_auth = OmniAuth.mock_auth_for(name.to_s)
if mocked_auth.is_a?(Symbol)
fail!(mocked_auth)
else
@env['omniauth.auth'] = mocked_auth
OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
call_app!
end
end
# The setup phase looks for the `:setup` option to exist and,
# if it is, will call either the Rack endpoint supplied to the
# `:setup` option or it will call out to the setup path of the
# underlying application. This will default to `/auth/:provider/setup`.
def setup_phase
if options[:setup].respond_to?(:call)
log :debug, 'Setup endpoint detected, running now.'
options[:setup].call(env)
elsif options[:setup]
log :debug, 'Calling through to underlying application for setup.'
setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
call_app!(setup_env)
end
end
# @abstract This method is called when the user is on the request path. You should
# perform any information gathering you need to be able to authenticate
# the user in this phase.
def request_phase
raise(NotImplementedError)
end
def uid
self.class.uid_stack(self).last
end
def info
merge_stack(self.class.info_stack(self))
end
def credentials
merge_stack(self.class.credentials_stack(self))
end
def extra
merge_stack(self.class.extra_stack(self))
end
def auth_hash
credentials_data = credentials
extra_data = extra
AuthHash.new(:provider => name, :uid => uid).tap do |auth|
auth.info = info unless skip_info?
auth.credentials = credentials_data if credentials_data
auth.extra = extra_data if extra_data
end
end
# Determines whether or not user info should be retrieved. This
# allows some strategies to save a call to an external API service
# for existing users. You can use it either by setting the `:skip_info`
# to true or by setting `:skip_info` to a Proc that takes a uid and
# evaluates to true when you would like to skip info.
#
# @example
#
# use MyStrategy, :skip_info => lambda{|uid| User.find_by_uid(uid)}
def skip_info?
return false unless options.skip_info?
return true unless options.skip_info.respond_to?(:call)
options.skip_info.call(uid)
end
def callback_phase
env['omniauth.auth'] = auth_hash
call_app!
end
def path_prefix
options[:path_prefix] || OmniAuth.config.path_prefix
end
def custom_path(kind)
if options[kind].respond_to?(:call)
result = options[kind].call(env)
return nil unless result.is_a?(String)
result
else
options[kind]
end
end
def request_path
@request_path ||=
if options[:request_path].is_a?(String)
options[:request_path]
else
"#{script_name}#{path_prefix}/#{name}"
end
end
def callback_path
@callback_path ||= begin
path = options[:callback_path] if options[:callback_path].is_a?(String)
path ||= current_path if options[:callback_path].respond_to?(:call) && options[:callback_path].call(env)
path ||= custom_path(:request_path)
path ||= "#{script_name}#{path_prefix}/#{name}/callback"
path
end
end
def setup_path
options[:setup_path] || "#{path_prefix}/#{name}/setup"
end
CURRENT_PATH_REGEX = %r{/$}.freeze
EMPTY_STRING = ''.freeze
def current_path
@current_path ||= request.path.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
end
def query_string
request.query_string.empty? ? '' : "?#{request.query_string}"
end
def call_app!(env = @env)
@app.call(env)
rescue StandardError => e
env['omniauth.error.app'] = true
raise e
end
def full_host
case OmniAuth.config.full_host
when String
OmniAuth.config.full_host
when Proc
OmniAuth.config.full_host.call(env)
else
# in Rack 1.3.x, request.url explodes if scheme is nil
if request.scheme && URI.parse(request.url).absolute?
uri = URI.parse(request.url.gsub(/\?.*$/, ''))
uri.path = ''
# sometimes the url is actually showing http inside rails because the
# other layers (like nginx) have handled the ssl termination.
uri.scheme = 'https' if ssl? # rubocop:disable BlockNesting
uri.to_s
else ''
end
end
end
def callback_url
full_host + callback_path + query_string
end
def script_name
return '' if @env.nil?
@env['SCRIPT_NAME'] || ''
end
def session
@env['rack.session']
end
def request
@request ||= Rack::Request.new(@env)
end
def name
options[:name]
end
def redirect(uri)
r = Rack::Response.new
if options[:iframe]
r.write("")
else
r.write("Redirecting to #{uri}...")
r.redirect(uri)
end
r.finish
end
def user_info
{}
end
def fail!(message_key, exception = nil)
env['omniauth.error'] = exception
env['omniauth.error.type'] = message_key.to_sym
env['omniauth.error.strategy'] = self
if exception
log :error, "Authentication failure! #{message_key}: #{exception.class}, #{exception.message}"
else
log :error, "Authentication failure! #{message_key} encountered."
end
OmniAuth.config.on_failure.call(env)
end
class Options < OmniAuth::KeyStore; end
protected
def initialize_copy(*args)
super
@options = @options.dup
end
def merge_stack(stack)
stack.inject({}) do |a, e|
a.merge!(e)
a
end
end
def ssl?
request.env['HTTPS'] == 'on' ||
request.env['HTTP_X_FORWARDED_SSL'] == 'on' ||
request.env['HTTP_X_FORWARDED_SCHEME'] == 'https' ||
(request.env['HTTP_X_FORWARDED_PROTO'] && request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0] == 'https') ||
request.env['rack.url_scheme'] == 'https'
end
end
end
omniauth-omniauth-586c401/lib/omniauth/test.rb 0000664 0000000 0000000 00000000426 15067257603 0021347 0 ustar 00root root 0000000 0000000 module OmniAuth
# Support for testing OmniAuth strategies.
module Test
autoload :PhonySession, 'omniauth/test/phony_session'
autoload :StrategyMacros, 'omniauth/test/strategy_macros'
autoload :StrategyTestCase, 'omniauth/test/strategy_test_case'
end
end
omniauth-omniauth-586c401/lib/omniauth/test/ 0000775 0000000 0000000 00000000000 15067257603 0021020 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/lib/omniauth/test/phony_session.rb 0000664 0000000 0000000 00000000414 15067257603 0024244 0 ustar 00root root 0000000 0000000 module OmniAuth
module Test
class PhonySession
def initialize(app)
@app = app
end
def call(env)
@session ||= (env['rack.session'] || {})
env['rack.session'] = @session
@app.call(env)
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/test/strategy_macros.rb 0000664 0000000 0000000 00000001432 15067257603 0024553 0 ustar 00root root 0000000 0000000 module OmniAuth
module Test
module StrategyMacros
def sets_an_auth_hash
it 'sets an auth hash' do
expect(last_request.env['omniauth.auth']).to be_kind_of(Hash)
end
end
def sets_provider_to(provider)
it "sets the provider to #{provider}" do
expect((last_request.env['omniauth.auth'] || {})['provider']).to eq provider
end
end
def sets_uid_to(uid)
it "sets the UID to #{uid}" do
expect((last_request.env['omniauth.auth'] || {})['uid']).to eq uid
end
end
def sets_user_info_to(user_info)
it "sets the user_info to #{user_info}" do
expect((last_request.env['omniauth.auth'] || {})['user_info']).to eq user_info
end
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/test/strategy_test_case.rb 0000664 0000000 0000000 00000002201 15067257603 0025234 0 ustar 00root root 0000000 0000000 require 'rack'
require 'omniauth/test'
module OmniAuth
module Test
# Support for testing OmniAuth strategies.
#
# @example Usage
# class MyStrategyTest < Test::Unit::TestCase
# include OmniAuth::Test::StrategyTestCase
# def strategy
# # return the parameters to a Rack::Builder map call:
# [MyStrategy, :some, :configuration, :options => 'here']
# end
# setup do
# post '/auth/my_strategy/callback', :user => { 'name' => 'Dylan', 'id' => '445' }
# end
# end
module StrategyTestCase
def app
strat = strategy
resp = app_response
Rack::Builder.new do
use(OmniAuth::Test::PhonySession)
use(*strat)
run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [resp || env.key?('omniauth.auth').to_s]] }
end.to_app
end
def app_response
nil
end
def session
last_request.env['rack.session']
end
def strategy
error = NotImplementedError.new('Including specs must define #strategy')
raise(error)
end
end
end
end
omniauth-omniauth-586c401/lib/omniauth/version.rb 0000664 0000000 0000000 00000000057 15067257603 0022055 0 ustar 00root root 0000000 0000000 module OmniAuth
VERSION = '2.1.4'.freeze
end
omniauth-omniauth-586c401/omniauth.gemspec 0000664 0000000 0000000 00000002144 15067257603 0020641 0 ustar 00root root 0000000 0000000 # coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'omniauth/version'
Gem::Specification.new do |spec|
spec.add_dependency 'hashie', ['>= 3.4.6']
spec.add_dependency 'rack', '>= 2.2.3'
spec.add_development_dependency 'bundler', '~> 2.0'
spec.add_dependency 'rack-protection'
spec.add_dependency 'logger'
spec.add_development_dependency 'rake', '~> 12.0'
spec.authors = ['Michael Bleigh', 'Erik Michaels-Ober', 'Tom Milewski']
spec.description = 'A generalized Rack framework for multiple-provider authentication.'
spec.email = ['michael@intridea.com', 'sferik@gmail.com', 'tmilewski@gmail.com']
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('spec/') }
spec.homepage = 'https://github.com/omniauth/omniauth'
spec.licenses = %w[MIT]
spec.name = 'omniauth'
spec.require_paths = %w[lib]
spec.required_rubygems_version = '>= 1.3.5'
spec.required_ruby_version = '>= 2.2'
spec.summary = spec.description
spec.version = OmniAuth::VERSION
end
omniauth-omniauth-586c401/spec/ 0000775 0000000 0000000 00000000000 15067257603 0016401 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/spec/helper.rb 0000664 0000000 0000000 00000003055 15067257603 0020210 0 ustar 00root root 0000000 0000000 require 'simplecov'
require 'coveralls'
require 'simplecov-lcov'
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter,
Coveralls::SimpleCov::Formatter
]
SimpleCov.start do
add_filter ['/spec/', '/vendor/', 'strategy_macros.rb']
minimum_coverage(92.5)
maximum_coverage_drop(0.05)
end
require 'rspec'
require 'rack/test'
require 'rack/freeze'
require 'omniauth'
require 'omniauth/test'
OmniAuth.config.logger = Logger.new('/dev/null')
OmniAuth.config.request_validation_phase = nil
RSpec.configure do |config|
config.include Rack::Test::Methods
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
class ExampleStrategy
include OmniAuth::Strategy
attr_reader :last_env
option :name, 'test'
def call(env)
options[:dup] ? super : call!(env)
end
def initialize(*args, &block)
super
@fail = nil
end
def request_phase
options[:mutate_on_request].call(options) if options[:mutate_on_request]
@fail = fail!(options[:failure], options[:failure_exception]) if options[:failure]
@last_env = env
return @fail if @fail
raise('Request Phase')
end
def callback_phase
options[:mutate_on_callback].call(options) if options[:mutate_on_callback]
@fail = fail!(options[:failure], options[:failure_exception]) if options[:failure]
@last_env = env
return @fail if @fail
raise('Callback Phase')
end
end
omniauth-omniauth-586c401/spec/omniauth/ 0000775 0000000 0000000 00000000000 15067257603 0020225 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/spec/omniauth/auth_hash_spec.rb 0000664 0000000 0000000 00000010405 15067257603 0023530 0 ustar 00root root 0000000 0000000 require 'helper'
describe OmniAuth::AuthHash do
subject { OmniAuth::AuthHash.new }
it 'converts a supplied info key into an InfoHash object' do
subject.info = {:first_name => 'Awesome'}
expect(subject.info).to be_kind_of(OmniAuth::AuthHash::InfoHash)
expect(subject.info.first_name).to eq('Awesome')
end
it 'does not try to parse `string` as InfoHash' do
subject.weird_field = {:info => 'string'}
expect(subject.weird_field.info).to eq 'string'
end
it 'has a subkey_class' do
expect(OmniAuth::AuthHash.subkey_class).to eq Hashie::Mash
end
describe '#valid?' do
subject { OmniAuth::AuthHash.new(:uid => '123', :provider => 'example', :info => {:name => 'Steven'}) }
it 'is valid with the right parameters' do
expect(subject).to be_valid
end
it 'requires a uid' do
subject.uid = nil
expect(subject).not_to be_valid
end
it 'requires a provider' do
subject.provider = nil
expect(subject).not_to be_valid
end
it 'requires a name in the user info hash' do
subject.info.name = nil
expect(subject).not_to be_valid
end
end
describe '#name' do
subject do
OmniAuth::AuthHash.new(:info => {
:name => 'Phillip J. Fry',
:first_name => 'Phillip',
:last_name => 'Fry',
:nickname => 'meatbag',
:email => 'fry@planetexpress.com'
})
end
it 'defaults to the name key' do
expect(subject.info.name).to eq('Phillip J. Fry')
end
it 'falls back to go to first_name last_name concatenation' do
subject.info.name = nil
expect(subject.info.name).to eq('Phillip Fry')
end
it 'displays only a first or last name if only that is available' do
subject.info.name = nil
subject.info.first_name = nil
expect(subject.info.name).to eq('Fry')
end
it 'displays the nickname if no name, first, or last is available' do
subject.info.name = nil
%w[first_name last_name].each { |k| subject.info[k] = nil }
expect(subject.info.name).to eq('meatbag')
end
it 'displays the email if no name, first, last, or nick is available' do
subject.info.name = nil
%w[first_name last_name nickname].each { |k| subject.info[k] = nil }
expect(subject.info.name).to eq('fry@planetexpress.com')
end
end
describe '#to_hash' do
subject { OmniAuth::AuthHash.new(:uid => '123', :provider => 'test', :name => 'Example User') }
let(:hash) { subject.to_hash }
it 'is a plain old hash' do
expect(hash.class).to eq(::Hash)
end
it 'has string keys' do
expect(hash.keys).to be_include('uid')
end
it 'converts an info hash as well' do
subject.info = {:first_name => 'Example', :last_name => 'User'}
expect(subject.info.class).to eq(OmniAuth::AuthHash::InfoHash)
expect(subject.to_hash['info'].class).to eq(::Hash)
end
it 'supplies the calculated name in the converted hash' do
subject.info = {:first_name => 'Examplar', :last_name => 'User'}
expect(hash['info']['name']).to eq('Examplar User')
end
it "does not pollute the URL hash with 'name' etc" do
subject.info = {'urls' => {'Homepage' => 'http://homepage.com'}}
expect(subject.to_hash['info']['urls']).to eq('Homepage' => 'http://homepage.com')
end
end
describe OmniAuth::AuthHash::InfoHash do
describe '#valid?' do
it 'is valid if there is a name' do
expect(OmniAuth::AuthHash::InfoHash.new(:name => 'Awesome')).to be_valid
end
end
it 'has a subkey_class' do
expect(OmniAuth::AuthHash::InfoHash.subkey_class).to eq Hashie::Mash
end
require 'hashie/version'
if Gem::Version.new(Hashie::VERSION) >= Gem::Version.new('3.5.1')
context 'with Hashie 3.5.1+' do
around(:each) do |example|
original_logger = Hashie.logger
example.run
Hashie.logger = original_logger
end
it 'does not log anything in Hashie 3.5.1+' do
logger = double('Logger')
expect(logger).not_to receive(:warn)
Hashie.logger = logger
subject.name = 'test'
end
end
end
end
end
omniauth-omniauth-586c401/spec/omniauth/builder_spec.rb 0000664 0000000 0000000 00000007662 15067257603 0023225 0 ustar 00root root 0000000 0000000 require 'helper'
describe OmniAuth::Builder do
describe '#provider' do
it 'translates a symbol to a constant' do
expect(OmniAuth::Strategies).to receive(:const_get).with('MyStrategy', false).and_return(Class.new)
OmniAuth::Builder.new(nil) do
provider :my_strategy
end
end
it 'accepts a class' do
class ExampleClass; end
expect do
OmniAuth::Builder.new(nil) do
provider ::ExampleClass
end
end.not_to raise_error
end
it "raises a helpful LoadError message if it can't find the class" do
expect do
OmniAuth::Builder.new(nil) do
provider :lorax
end
end.to raise_error(LoadError, 'Could not find matching strategy for :lorax. You may need to install an additional gem (such as omniauth-lorax).')
end
it "doesn't translate a symbol to a top-level constant" do
class MyStrategy; end
expect do
OmniAuth::Builder.new(nil) do
provider :my_strategy
end
end.to raise_error(LoadError, 'Could not find matching strategy for :my_strategy. You may need to install an additional gem (such as omniauth-my_strategy).')
end
end
describe '#options' do
it 'merges provided options in' do
k = Class.new
b = OmniAuth::Builder.new(nil)
expect(b).to receive(:use).with(k, :foo => 'bar', :baz => 'tik')
b.options :foo => 'bar'
b.provider k, :baz => 'tik'
end
it 'adds an argument if no options are provided' do
k = Class.new
b = OmniAuth::Builder.new(nil)
expect(b).to receive(:use).with(k, :foo => 'bar')
b.options :foo => 'bar'
b.provider k
end
end
describe '#on_failure' do
it 'passes the block to the config' do
prok = proc {}
with_config_reset(:on_failure) do
OmniAuth::Builder.new(nil).on_failure(&prok)
expect(OmniAuth.config.on_failure).to eq(prok)
end
end
end
describe '#before_options_phase' do
it 'passes the block to the config' do
prok = proc {}
with_config_reset(:before_options_phase) do
OmniAuth::Builder.new(nil).before_options_phase(&prok)
expect(OmniAuth.config.before_options_phase).to eq(prok)
end
end
end
describe '#before_request_phase' do
it 'passes the block to the config' do
prok = proc {}
with_config_reset(:before_request_phase) do
OmniAuth::Builder.new(nil).before_request_phase(&prok)
expect(OmniAuth.config.before_request_phase).to eq(prok)
end
end
end
describe '#after_request_phase' do
it 'passes the block to the config' do
prok = proc {}
with_config_reset(:after_request_phase) do
OmniAuth::Builder.new(nil).after_request_phase(&prok)
expect(OmniAuth.config.after_request_phase).to eq(prok)
end
end
end
describe '#before_callback_phase' do
it 'passes the block to the config' do
prok = proc {}
with_config_reset(:before_callback_phase) do
OmniAuth::Builder.new(nil).before_callback_phase(&prok)
expect(OmniAuth.config.before_callback_phase).to eq(prok)
end
end
end
describe '#configure' do
it 'passes the block to the config' do
prok = proc {}
allow(OmniAuth).to receive(:configure).and_call_original
OmniAuth::Builder.new(nil).configure(&prok)
expect(OmniAuth).to have_received(:configure) do |&block|
expect(block).to eq(prok)
end
end
end
describe '#call' do
it 'passes env to to_app.call' do
app = lambda { |env| [200, {}, env['CUSTOM_ENV_VALUE']] }
builder = OmniAuth::Builder.new(app)
env = {'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/some/path', 'CUSTOM_ENV_VALUE' => 'VALUE'}
expect(builder.call(env)).to eq([200, {}, 'VALUE'])
end
end
def with_config_reset(option)
old_config = OmniAuth.config.send(option)
yield
OmniAuth.config.send("#{option}=", old_config)
end
end
omniauth-omniauth-586c401/spec/omniauth/failure_endpoint_spec.rb 0000664 0000000 0000000 00000004471 15067257603 0025121 0 ustar 00root root 0000000 0000000 require 'helper'
describe OmniAuth::FailureEndpoint do
subject { OmniAuth::FailureEndpoint }
context 'raise-out environment' do
before do
@rack_env = ENV['RACK_ENV']
ENV['RACK_ENV'] = 'test'
@default = OmniAuth.config.failure_raise_out_environments
OmniAuth.config.failure_raise_out_environments = ['test']
end
it 'raises out the error' do
expect do
subject.call('omniauth.error' => StandardError.new('Blah'))
end.to raise_error(StandardError, 'Blah')
end
it 'raises out an OmniAuth::Error if no omniauth.error is set' do
expect { subject.call('omniauth.error.type' => 'example') }.to raise_error(OmniAuth::Error, 'example')
end
after do
ENV['RACK_ENV'] = @rack_env
OmniAuth.config.failure_raise_out_environments = @default
end
end
context 'non-raise-out environment' do
let(:env) do
{'omniauth.error.type' => 'invalid_request', 'omniauth.error.strategy' => ExampleStrategy.new({})}
end
it 'is a redirect' do
status, = *subject.call(env)
expect(status).to eq(302)
end
it 'includes the SCRIPT_NAME' do
_, head, = *subject.call(env.merge('SCRIPT_NAME' => '/random'))
expect(head['Location']).to eq('/random/auth/failure?message=invalid_request&strategy=test')
end
it 'respects the globally configured path prefix' do
allow(OmniAuth.config).to receive(:path_prefix).and_return('/boo')
_, head, = *subject.call(env)
expect(head['Location']).to eq('/boo/failure?message=invalid_request&strategy=test')
end
it 'respects the custom path prefix configured on the strategy' do
env['omniauth.error.strategy'] = ExampleStrategy.new({}, path_prefix: "/some/custom/path")
_, head, = *subject.call(env)
expect(head['Location']).to eq('/some/custom/path/failure?message=invalid_request&strategy=test')
end
it 'includes the origin (escaped) if one is provided' do
env['omniauth.origin'] = '/origin-example'
_, head, = *subject.call(env)
expect(head['Location']).to be_include('&origin=%2Forigin-example')
end
it 'escapes the message key' do
_, head = *subject.call(env.merge('omniauth.error.type' => 'Connection refused!'))
expect(head['Location']).to be_include('message=Connection+refused%21')
end
end
end
omniauth-omniauth-586c401/spec/omniauth/form_spec.rb 0000664 0000000 0000000 00000004057 15067257603 0022535 0 ustar 00root root 0000000 0000000 require 'helper'
describe OmniAuth::Form do
describe '.build' do
it 'yields the instance when called with a block and argument' do
OmniAuth::Form.build { |f| expect(f).to be_kind_of(OmniAuth::Form) }
end
it 'evaluates in the instance when called with a block and no argument' do
f = OmniAuth::Form.build { @html = '
')
end
end
describe '#initialize' do
it 'sets the form action to the passed :url option' do
expect(OmniAuth::Form.new(:url => '/awesome').to_html).to be_include("action='/awesome'")
end
it 'sets an H1 tag from the passed :title option' do
expect(OmniAuth::Form.new(:title => 'Something Cool').to_html).to be_include('
Something Cool
')
end
it 'sets the default form method to post' do
expect(OmniAuth::Form.new.to_html).to be_include("method='post'")
end
it 'sets the form method to the passed :method option' do
expect(OmniAuth::Form.new(:method => 'get').to_html).to be_include("method='get'")
end
end
describe '#password_field' do
it 'adds a labeled input field' do
form = OmniAuth::Form.new.password_field('pass', 'password')
form_html = form.to_html
expect(form_html).to include('')
expect(form_html).to include('')
end
end
describe '#html' do
it 'appends to the html body' do
form = OmniAuth::Form.build { @html = +'' }
form.html('')
expect(form.instance_variable_get(:@html)).to eq ''
end
end
describe 'fieldset' do
it 'creates a fieldset with options' do
form = OmniAuth::Form.new
options = {:style => 'color: red', :id => 'fieldSetId'}
expected = ""
form.fieldset('legendary', options) {}
expect(form.to_html).to include expected
end
end
end
omniauth-omniauth-586c401/spec/omniauth/key_store_spec.rb 0000664 0000000 0000000 00000004001 15067257603 0023563 0 ustar 00root root 0000000 0000000 require 'helper'
RSpec.describe OmniAuth::KeyStore do
let(:logger) { double('Logger') }
around(:each) do |example|
patched = monkey_patch_logger
example.run
remove_logger(patched)
end
context 'on Hashie < 3.5.0' do
let(:version) { '3.4.0' }
it 'does not log anything to the console' do
stub_const('Hashie::VERSION', version)
OmniAuth::KeyStore.override_logging
expect(logger).not_to receive(:info)
OmniAuth::KeyStore.new(:id => 1234)
end
end
context 'on Hashie 3.5.0 and 3.5.1' do
let(:version) { '3.5.0' }
it 'does not log anything to the console' do
stub_const('Hashie::VERSION', version)
allow(OmniAuth::KeyStore).to receive(:respond_to?).with(:disable_warnings).and_return(false)
OmniAuth::KeyStore.override_logging
expect(logger).not_to receive(:info)
OmniAuth::KeyStore.new(:id => 1234)
end
end
context 'on Hashie 3.5.2+' do
let(:version) { '3.5.2' }
around(:each) do |example|
patching = monkey_patch_unreleased_interface
example.run
remove_monkey_patch(patching)
end
it 'does not log anything to the console' do
stub_const('Hashie::VERSION', version)
OmniAuth::KeyStore.override_logging
expect(logger).not_to receive(:info)
OmniAuth::KeyStore.new(:id => 1234)
end
end
def monkey_patch_unreleased_interface
return false if OmniAuth::KeyStore.class.respond_to?(:disable_warnings, true)
OmniAuth::KeyStore.define_singleton_method(:disable_warnings) {}
OmniAuth::KeyStore.define_singleton_method(:log_built_in_message) { |*| }
true
end
def monkey_patch_logger
return unless Hashie.respond_to?(:logger)
original_logger = Hashie.logger
Hashie.logger = logger
original_logger
end
def remove_logger(logger)
return unless logger
Hashie.logger = logger
end
def remove_monkey_patch(perform)
return unless perform
OmniAuth::KeyStore.singleton_class.__send__(:remove_method, :disable_warnings)
end
end
omniauth-omniauth-586c401/spec/omniauth/strategies/ 0000775 0000000 0000000 00000000000 15067257603 0022377 5 ustar 00root root 0000000 0000000 omniauth-omniauth-586c401/spec/omniauth/strategies/developer_spec.rb 0000664 0000000 0000000 00000004125 15067257603 0025725 0 ustar 00root root 0000000 0000000 require 'helper'
describe OmniAuth::Strategies::Developer do
let(:app) do
Rack::Builder.new do |b|
b.use Rack::Session::Cookie, :secret => 'abc123'
b.use OmniAuth::Strategies::Developer
b.run lambda { |_env| [200, {}, ['Not Found']] }
end.to_app
end
context 'request phase' do
before(:each) { post '/auth/developer' }
it 'displays a form' do
expect(last_response.status).to eq(200)
expect(last_response.body).to be_include('