Repository: omniauth/omniauth-oauth2
Branch: master
Commit: 1481c33b3ffd
Files: 17
Total size: 23.1 KB
Directory structure:
gitextract_b905nxjk/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .rspec
├── .rubocop.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.md
├── README.md
├── Rakefile
├── SECURITY.md
├── lib/
│ ├── omniauth/
│ │ └── strategies/
│ │ └── oauth2.rb
│ ├── omniauth-oauth2/
│ │ └── version.rb
│ └── omniauth-oauth2.rb
├── omniauth-oauth2.gemspec
└── spec/
├── helper.rb
└── omniauth/
└── strategies/
└── oauth2_spec.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
github: bobbymcwho
tidelift: rubygems/omniauth-oauth2
================================================
FILE: .github/workflows/main.yml
================================================
name: Ruby
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
ruby: ['3.0', 3.1, 3.2, 3.3, 3.4, head, debug, truffleruby, truffleruby-head, jruby, jruby-head]
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Set JRUBY_OPTS environment variable
run: echo "JRUBY_OPTS=--debug" >> "$GITHUB_ENV"
if: ${{ startsWith(matrix.ruby, 'jruby') }}
- name: Run tests
run: bundle exec rake
- uses: actions/upload-artifact@v4
if: ${{ matrix.os == 'ubuntu-latest' && matrix.ruby == '3.0' }}
with:
name: coverage
path: coverage/
retention-days: 1
coveralls:
needs: test
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/download-artifact@v4
with:
name: coverage
path: coverage/
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2
================================================
FILE: .gitignore
================================================
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
*.swp
================================================
FILE: .rspec
================================================
--colour
--format=progress
================================================
FILE: .rubocop.yml
================================================
AllCops:
NewCops: enable
Gemspec/RequiredRubyVersion:
Enabled: false
Layout/AccessModifierIndentation:
EnforcedStyle: outdent
Layout/LineLength:
AllowURI: true
Enabled: false
Layout/SpaceInsideHashLiteralBraces:
EnforcedStyle: no_space
Lint/MissingSuper:
Enabled: false
Metrics/AbcSize:
Max: 18
Metrics/BlockLength:
Exclude:
- spec/omniauth/strategies/oauth2_spec.rb
Metrics/BlockNesting:
Max: 2
Metrics/ClassLength:
Max: 110
Metrics/MethodLength:
CountComments: false
Max: 10
Metrics/ParameterLists:
Max: 4
CountKeywordArgs: true
Naming/FileName:
Exclude:
- lib/omniauth-oauth2.rb
Style/CollectionMethods:
PreferredMethods:
map: 'collect'
reduce: 'inject'
find: 'detect'
find_all: 'select'
Style/Documentation:
Enabled: false
Style/DoubleNegation:
Enabled: false
Style/ExpandPathArguments:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Style/HashSyntax:
EnforcedStyle: hash_rockets
Style/StderrPuts:
Enabled: false
Style/StringLiterals:
EnforcedStyle: double_quotes
Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
================================================
FILE: CHANGELOG.md
================================================
## [v1.9.0](https://github.com/omniauth/omniauth-oauth2/releases/tag/v1.9.0)
- Prevent timing attacks [#174](https://github.com/omniauth/omniauth-oauth2/pull/174)
- Rescue OAuth2 timeouts [#169](https://github.com/omniauth/omniauth-oauth2/pull/169)
## [v1.8.0](https://github.com/omniauth/omniauth-oauth2/releases/tag/v1.8.0)
- Relaxes allowed versions of the oauth2 gem. [#146](https://github.com/omniauth/omniauth-oauth2/pull/146)
- Requires omniauth `~> 2.0` [#152](https://github.com/omniauth/omniauth-oauth2/pull/152)
Please see https://github.com/omniauth/omniauth-oauth2/releases for changelog prior to 1.8.0
================================================
FILE: Gemfile
================================================
source "https://rubygems.org"
gem "rake", "~> 13.0"
group :test do
gem "addressable", "~> 2.3.8", :platforms => %i[jruby ruby_18]
gem 'coveralls_reborn', '~> 0.19.0', require: false
gem "json", :platforms => %i[jruby ruby_18 ruby_19]
gem "mime-types", "~> 1.25", :platforms => %i[jruby ruby_18]
gem "rack-test"
gem "rest-client", "~> 1.8.0", :platforms => %i[jruby ruby_18]
gem "rspec", "~> 3.2"
gem "rubocop", ">= 0.51", :platforms => %i[ruby_19 ruby_20 ruby_21 ruby_22 ruby_23 ruby_24]
gem 'simplecov-lcov'
gem 'tins', '~> 1.13', :platforms => %i[jruby_18 jruby_19 ruby_19]
gem "webmock", "~> 3.0"
end
# Specify your gem's dependencies in omniauth-oauth2.gemspec
gemspec
================================================
FILE: LICENSE.md
================================================
Copyright (C) 2014 Michael Bleigh, Erik Michaels-Ober 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.
================================================
FILE: README.md
================================================
# OmniAuth OAuth2
[][gem]
[][codeclimate]
[][coveralls]
[](https://hakiri.io/github/omniauth/omniauth-oauth2/master)
[gem]: https://rubygems.org/gems/omniauth-oauth2
[codeclimate]: https://codeclimate.com/github/intridea/omniauth-oauth2
[coveralls]: https://coveralls.io/r/intridea/omniauth-oauth2
This gem contains a generic OAuth2 strategy for OmniAuth. It is meant to serve
as a building block strategy for other strategies and not to be used
independently (since it has no inherent way to gather uid and user info).
## Creating an OAuth2 Strategy
To create an OmniAuth OAuth2 strategy using this gem, you can simply subclass
it and add a few extra methods like so:
```ruby
require 'omniauth-oauth2'
module OmniAuth
module Strategies
class SomeSite < OmniAuth::Strategies::OAuth2
# Give your strategy a name.
option :name, "some_site"
# This is where you pass the options you would pass when
# initializing your consumer from the OAuth gem.
option :client_options, {:site => "https://api.somesite.com"}
# You may specify that your strategy should use PKCE by setting
# the pkce option to true: https://tools.ietf.org/html/rfc7636
option :pkce, true
# These are called after authentication has succeeded. If
# possible, you should try to set the UID without making
# additional calls (if the user id is returned with the token
# or as a URI parameter). This may not be possible with all
# providers.
uid{ raw_info['id'] }
info do
{
:name => raw_info['name'],
:email => raw_info['email']
}
end
extra do
{
'raw_info' => raw_info
}
end
def raw_info
@raw_info ||= access_token.get('/me').parsed
end
end
end
end
```
That's pretty much it!
## OmniAuth-OAuth2 for Enterprise
Available as part of the Tidelift Subscription.
The maintainers of OmniAuth-OAuth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.](https://tidelift.com/subscription/pkg/rubygems-omniauth-oauth2?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise)
## Supported Ruby Versions
OmniAuth is tested under 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, truffleruby, and JRuby.
================================================
FILE: Rakefile
================================================
#!/usr/bin/env rake
require "bundler/gem_tasks"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new
task :test => :spec
begin
require "rubocop/rake_task"
RuboCop::RakeTask.new
rescue LoadError
task :rubocop do
$stderr.puts "RuboCop is disabled"
end
end
task :default => %i[spec rubocop]
================================================
FILE: SECURITY.md
================================================
# 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 |
| ------- | ------------------ |
| 1.7.x | :white_check_mark: |
| <= 1.6.x | :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.
================================================
FILE: lib/omniauth/strategies/oauth2.rb
================================================
require "oauth2"
require "omniauth"
require "securerandom"
require "socket" # for SocketError
require "timeout" # for Timeout::Error
module OmniAuth
module Strategies
# Authentication strategy for connecting with APIs constructed using
# the [OAuth 2.0 Specification](http://tools.ietf.org/html/draft-ietf-oauth-v2-10).
# You must generally register your application with the provider and
# utilize an application id and secret in order to authenticate using
# OAuth 2.0.
class OAuth2
include OmniAuth::Strategy
def self.inherited(subclass)
OmniAuth::Strategy.included(subclass)
end
args %i[client_id client_secret]
option :client_id, nil
option :client_secret, nil
option :client_options, {}
option :authorize_params, {}
option :authorize_options, %i[scope state]
option :token_params, {}
option :token_options, []
option :auth_token_params, {}
option :provider_ignores_state, false
option :pkce, false
option :pkce_verifier, nil
option :pkce_options, {
:code_challenge => proc { |verifier|
Base64.urlsafe_encode64(
Digest::SHA2.digest(verifier),
:padding => false,
)
},
:code_challenge_method => "S256",
}
attr_accessor :access_token
def client
::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
end
credentials do
hash = {"token" => access_token.token}
hash["refresh_token"] = access_token.refresh_token if access_token.expires? && access_token.refresh_token
hash["expires_at"] = access_token.expires_at if access_token.expires?
hash["expires"] = access_token.expires?
hash
end
def request_phase
redirect client.auth_code.authorize_url({:redirect_uri => callback_url}.merge(authorize_params))
end
def authorize_params # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
options.authorize_params[:state] = SecureRandom.hex(24)
if OmniAuth.config.test_mode
@env ||= {}
@env["rack.session"] ||= {}
end
params = options.authorize_params
.merge(options_for("authorize"))
.merge(pkce_authorize_params)
session["omniauth.pkce.verifier"] = options.pkce_verifier if options.pkce
session["omniauth.state"] = params[:state]
params
end
def token_params
options.token_params.merge(options_for("token")).merge(pkce_token_params)
end
def callback_phase # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
error = request.params["error_reason"] || request.params["error"]
if !options.provider_ignores_state && (request.params["state"].to_s.empty? || !secure_compare(request.params["state"], session.delete("omniauth.state")))
fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected"))
elsif error
fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"]))
else
self.access_token = build_access_token
self.access_token = access_token.refresh! if access_token.expired?
super
end
rescue ::OAuth2::Error, CallbackError => e
fail!(:invalid_credentials, e)
rescue ::Timeout::Error, ::Errno::ETIMEDOUT, ::OAuth2::TimeoutError, ::OAuth2::ConnectionError => e
fail!(:timeout, e)
rescue ::SocketError => e
fail!(:failed_to_connect, e)
end
protected
def pkce_authorize_params
return {} unless options.pkce
options.pkce_verifier = SecureRandom.hex(64)
# NOTE: see https://tools.ietf.org/html/rfc7636#appendix-A
{
:code_challenge => options.pkce_options[:code_challenge]
.call(options.pkce_verifier),
:code_challenge_method => options.pkce_options[:code_challenge_method],
}
end
def pkce_token_params
return {} unless options.pkce
{:code_verifier => session.delete("omniauth.pkce.verifier")}
end
def build_access_token
verifier = request.params["code"]
client.auth_code.get_token(verifier, {:redirect_uri => callback_url}.merge(token_params.to_hash(:symbolize_keys => true)), deep_symbolize(options.auth_token_params))
end
def deep_symbolize(options)
options.each_with_object({}) do |(key, value), hash|
hash[key.to_sym] = value.is_a?(Hash) ? deep_symbolize(value) : value
end
end
def options_for(option)
hash = {}
options.send(:"#{option}_options").select { |key| options[key] }.each do |key|
hash[key.to_sym] = if options[key].respond_to?(:call)
options[key].call(env)
else
options[key]
end
end
hash
end
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(string_a, string_b)
return false unless string_a.bytesize == string_b.bytesize
l = string_a.unpack "C#{string_a.bytesize}"
res = 0
string_b.each_byte { |byte| res |= byte ^ l.shift }
res.zero?
end
# An error that is indicated in the OAuth 2.0 callback.
# This could be a `redirect_uri_mismatch` or other
class CallbackError < StandardError
attr_accessor :error, :error_reason, :error_uri
def initialize(error, error_reason = nil, error_uri = nil)
self.error = error
self.error_reason = error_reason
self.error_uri = error_uri
end
def message
[error, error_reason, error_uri].compact.join(" | ")
end
end
end
end
end
OmniAuth.config.add_camelization "oauth2", "OAuth2"
================================================
FILE: lib/omniauth-oauth2/version.rb
================================================
module OmniAuth
module OAuth2
VERSION = "1.9.0".freeze
end
end
================================================
FILE: lib/omniauth-oauth2.rb
================================================
require "omniauth-oauth2/version"
require "omniauth/strategies/oauth2"
================================================
FILE: omniauth-oauth2.gemspec
================================================
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "omniauth-oauth2/version"
Gem::Specification.new do |gem|
gem.add_dependency "oauth2", [">= 2.0.2", "< 3"]
gem.add_dependency "omniauth", "~> 2.0"
gem.add_development_dependency "bundler", "~> 4.0"
gem.authors = ["Michael Bleigh", "Erik Michaels-Ober", "Tom Milewski"]
gem.email = ["michael@intridea.com", "sferik@gmail.com", "tmilewski@gmail.com"]
gem.description = "An abstract OAuth2 strategy for OmniAuth."
gem.summary = gem.description
gem.homepage = "https://github.com/omniauth/omniauth-oauth2"
gem.licenses = %w[MIT]
gem.executables = `git ls-files -- bin/*`.split("\n").collect { |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.name = "omniauth-oauth2"
gem.require_paths = %w[lib]
gem.version = OmniAuth::OAuth2::VERSION
end
================================================
FILE: spec/helper.rb
================================================
$LOAD_PATH.unshift File.expand_path("..", __FILE__)
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
if RUBY_VERSION >= "1.9"
require "simplecov"
require "simplecov-lcov"
require "coveralls"
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter,
Coveralls::SimpleCov::Formatter
]
SimpleCov.start do
minimum_coverage(78.48)
end
end
require "rspec"
require "rack/test"
require "webmock/rspec"
require "omniauth"
require "omniauth-oauth2"
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect
end
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
config.include Rack::Test::Methods
config.include WebMock::API
end
================================================
FILE: spec/omniauth/strategies/oauth2_spec.rb
================================================
require "helper"
describe OmniAuth::Strategies::OAuth2 do
def app
lambda do |_env|
[200, {}, ["Hello."]]
end
end
let(:fresh_strategy) { Class.new(OmniAuth::Strategies::OAuth2) }
before do
OmniAuth.config.test_mode = true
end
after do
OmniAuth.config.test_mode = false
end
describe "Subclassing Behavior" do
subject { fresh_strategy }
it "performs the OmniAuth::Strategy included hook" do
expect(OmniAuth.strategies).to include(OmniAuth::Strategies::OAuth2)
expect(OmniAuth.strategies).to include(subject)
end
end
describe "#client" do
subject { fresh_strategy }
it "is initialized with symbolized client_options" do
instance = subject.new(app, :client_options => {"authorize_url" => "https://example.com"})
expect(instance.client.options[:authorize_url]).to eq("https://example.com")
end
it "sets ssl options as connection options" do
instance = subject.new(app, :client_options => {"ssl" => {"ca_path" => "foo"}})
expect(instance.client.options[:connection_opts][:ssl]).to eq(:ca_path => "foo")
end
end
describe "#authorize_params" do
subject { fresh_strategy }
it "includes any authorize params passed in the :authorize_params option" do
instance = subject.new("abc", "def", :authorize_params => {:foo => "bar", :baz => "zip"})
expect(instance.authorize_params["foo"]).to eq("bar")
expect(instance.authorize_params["baz"]).to eq("zip")
end
it "includes top-level options that are marked as :authorize_options" do
instance = subject.new("abc", "def", :authorize_options => %i[scope foo state], :scope => "bar", :foo => "baz")
expect(instance.authorize_params["scope"]).to eq("bar")
expect(instance.authorize_params["foo"]).to eq("baz")
expect(instance.authorize_params["state"]).not_to be_empty
end
it "includes random state in the authorize params" do
instance = subject.new("abc", "def")
expect(instance.authorize_params.keys).to eq(["state"])
expect(instance.session["omniauth.state"]).not_to be_empty
end
it "includes custom state in the authorize params" do
instance = subject.new("abc", "def", :state => proc { "qux" })
expect(instance.authorize_params.keys).to eq(["state"])
expect(instance.session["omniauth.state"]).to eq("qux")
end
it "includes PKCE parameters if enabled" do
instance = subject.new("abc", "def", :pkce => true)
expect(instance.authorize_params[:code_challenge]).to be_a(String)
expect(instance.authorize_params[:code_challenge_method]).to eq("S256")
expect(instance.session["omniauth.pkce.verifier"]).to be_a(String)
end
end
describe "#token_params" do
subject { fresh_strategy }
it "includes any authorize params passed in the :authorize_params option" do
instance = subject.new("abc", "def", :token_params => {:foo => "bar", :baz => "zip"})
expect(instance.token_params).to eq("foo" => "bar", "baz" => "zip")
end
it "includes top-level options that are marked as :authorize_options" do
instance = subject.new("abc", "def", :token_options => %i[scope foo], :scope => "bar", :foo => "baz")
expect(instance.token_params).to eq("scope" => "bar", "foo" => "baz")
end
it "includes the PKCE code_verifier if enabled" do
instance = subject.new("abc", "def", :pkce => true)
# setup session
instance.authorize_params
expect(instance.token_params[:code_verifier]).to be_a(String)
end
end
describe "#callback_phase" do
subject(:instance) { fresh_strategy.new("abc", "def") }
let(:params) { {"error_reason" => "user_denied", "error" => "access_denied", "state" => state} }
let(:state) { "secret" }
before do
allow(instance).to receive(:request) do
double("Request", :params => params)
end
allow(instance).to receive(:session) do
double("Session", :delete => state)
end
end
it "calls fail with the error received" do
expect(instance).to receive(:fail!).with("user_denied", anything)
instance.callback_phase
end
it "calls fail with the error received if state is missing and CSRF verification is disabled" do
params["state"] = nil
instance.options.provider_ignores_state = true
expect(instance).to receive(:fail!).with("user_denied", anything)
instance.callback_phase
end
it "calls fail with a CSRF error if the state is missing" do
params["state"] = nil
expect(instance).to receive(:fail!).with(:csrf_detected, anything)
instance.callback_phase
end
it "calls fail with a CSRF error if the state is invalid" do
params["state"] = "invalid"
expect(instance).to receive(:fail!).with(:csrf_detected, anything)
instance.callback_phase
end
describe 'exception handlings' do
let(:params) do
{"code" => "code", "state" => state}
end
before do
allow_any_instance_of(OmniAuth::Strategies::OAuth2).to receive(:build_access_token).and_raise(exception)
end
{
:invalid_credentials => [OAuth2::Error, OmniAuth::Strategies::OAuth2::CallbackError],
:timeout => [Timeout::Error, Errno::ETIMEDOUT, OAuth2::TimeoutError, OAuth2::ConnectionError],
:failed_to_connect => [SocketError]
}.each do |error_type, exceptions|
exceptions.each do |klass|
context "when #{klass}" do
let(:exception) { klass.new 'error' }
it do
expect(instance).to receive(:fail!).with(error_type, exception)
instance.callback_phase
end
end
end
end
end
end
describe "#secure_compare" do
subject { fresh_strategy }
it "returns true when the two inputs are the same and false otherwise" do
instance = subject.new("abc", "def")
expect(instance.send(:secure_compare, "a", "a")).to be true
expect(instance.send(:secure_compare, "b", "a")).to be false
end
end
end
describe OmniAuth::Strategies::OAuth2::CallbackError do
let(:error) { Class.new(OmniAuth::Strategies::OAuth2::CallbackError) }
describe "#message" do
subject { error }
it "includes all of the attributes" do
instance = subject.new("error", "description", "uri")
expect(instance.message).to match(/error/)
expect(instance.message).to match(/description/)
expect(instance.message).to match(/uri/)
end
it "includes all of the attributes" do
instance = subject.new(nil, :symbol)
expect(instance.message).to eq("symbol")
end
end
end
gitextract_b905nxjk/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .rspec
├── .rubocop.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.md
├── README.md
├── Rakefile
├── SECURITY.md
├── lib/
│ ├── omniauth/
│ │ └── strategies/
│ │ └── oauth2.rb
│ ├── omniauth-oauth2/
│ │ └── version.rb
│ └── omniauth-oauth2.rb
├── omniauth-oauth2.gemspec
└── spec/
├── helper.rb
└── omniauth/
└── strategies/
└── oauth2_spec.rb
SYMBOL INDEX (21 symbols across 3 files)
FILE: lib/omniauth-oauth2/version.rb
type OmniAuth (line 1) | module OmniAuth
type OAuth2 (line 2) | module OAuth2
FILE: lib/omniauth/strategies/oauth2.rb
type OmniAuth (line 7) | module OmniAuth
type Strategies (line 8) | module Strategies
class OAuth2 (line 14) | class OAuth2
method inherited (line 17) | def self.inherited(subclass)
method client (line 46) | def client
method request_phase (line 58) | def request_phase
method authorize_params (line 62) | def authorize_params # rubocop:disable Metrics/AbcSize, Metrics/Me...
method token_params (line 80) | def token_params
method callback_phase (line 84) | def callback_phase # rubocop:disable Metrics/AbcSize, Metrics/Cycl...
method pkce_authorize_params (line 105) | def pkce_authorize_params
method pkce_token_params (line 118) | def pkce_token_params
method build_access_token (line 124) | def build_access_token
method deep_symbolize (line 129) | def deep_symbolize(options)
method options_for (line 135) | def options_for(option)
method secure_compare (line 148) | def secure_compare(string_a, string_b)
class CallbackError (line 160) | class CallbackError < StandardError
method initialize (line 163) | def initialize(error, error_reason = nil, error_uri = nil)
method message (line 169) | def message
FILE: spec/omniauth/strategies/oauth2_spec.rb
function app (line 4) | def app
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (26K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 54,
"preview": "github: bobbymcwho\ntidelift: rubygems/omniauth-oauth2\n"
},
{
"path": ".github/workflows/main.yml",
"chars": 1202,
"preview": "name: Ruby\n\non:\n push:\n branches: [ master ]\n pull_request:\n branches: [ master ]\n\njobs:\n test:\n runs-on: ${"
},
{
"path": ".gitignore",
"chars": 160,
"preview": "*.gem\n*.rbc\n.bundle\n.config\n.yardoc\nGemfile.lock\nInstalledFiles\n_yardoc\ncoverage\ndoc/\nlib/bundler/man\npkg\nrdoc\nspec/repo"
},
{
"path": ".rspec",
"chars": 27,
"preview": "--colour\n--format=progress\n"
},
{
"path": ".rubocop.yml",
"chars": 1297,
"preview": "AllCops:\n NewCops: enable\n\nGemspec/RequiredRubyVersion:\n Enabled: false\n\nLayout/AccessModifierIndentation:\n EnforcedS"
},
{
"path": "CHANGELOG.md",
"chars": 619,
"preview": "## [v1.9.0](https://github.com/omniauth/omniauth-oauth2/releases/tag/v1.9.0)\n- Prevent timing attacks [#174](https://git"
},
{
"path": "Gemfile",
"chars": 698,
"preview": "source \"https://rubygems.org\"\n\ngem \"rake\", \"~> 13.0\"\n\ngroup :test do\n gem \"addressable\", \"~> 2.3.8\", :platforms => %i[j"
},
{
"path": "LICENSE.md",
"chars": 1097,
"preview": "Copyright (C) 2014 Michael Bleigh, Erik Michaels-Ober and Intridea, Inc.\n\nPermission is hereby granted, free of charge, "
},
{
"path": "README.md",
"chars": 2811,
"preview": "# OmniAuth OAuth2\n\n[][gem]\n[\n$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)\nrequire \"omniauth-oau"
},
{
"path": "spec/helper.rb",
"chars": 832,
"preview": "$LOAD_PATH.unshift File.expand_path(\"..\", __FILE__)\n$LOAD_PATH.unshift File.expand_path(\"../../lib\", __FILE__)\n\nif RUBY_"
},
{
"path": "spec/omniauth/strategies/oauth2_spec.rb",
"chars": 6685,
"preview": "require \"helper\"\n\ndescribe OmniAuth::Strategies::OAuth2 do\n def app\n lambda do |_env|\n [200, {}, [\"Hello.\"]]\n "
}
]
About this extraction
This page contains the full source code of the omniauth/omniauth-oauth2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (23.1 KB), approximately 6.6k tokens, and a symbol index with 21 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.