1
0
Fork 0
mirror of https://github.com/omniauth/omniauth.git synced 2022-11-09 12:31:49 -05:00

Merge branch 'master' of github.com:intridea/omniauth

Conflicts:
	.gitignore
This commit is contained in:
Ping Yu 2010-10-18 16:44:46 -05:00
commit 087c3f8b3c
37 changed files with 424 additions and 481 deletions

4
.gitignore vendored
View file

@ -29,3 +29,7 @@ oa-live
.bundle
.project
.loadpath
.yardoc
doc
Gemfile.lock

View file

@ -22,10 +22,12 @@ OmniAuth currently supports the following external providers:
* Foursquare
* LinkedIn
* GitHub
* Identi.ca (credit: [dcu](http://github.com/dcu))
* Gowalla (credit: [kvnsmth](http://github.com/kvnsmth))
* OpenID
* Google Apps (via OpenID)
* CAS (Central Authentication Service)
* LDAP
* CAS (Central Authentication Service) (credit: [jamesarosen](http://github.com/jamesarosen))
* LDAP (credit: **Ping Yu**)
## Usage
@ -34,10 +36,10 @@ OmniAuth is a collection of Rack middleware. To use a single strategy, you simpl
require 'oa-oauth'
use OmniAuth::Strategies::Twitter, 'CONSUMER_KEY', 'CONSUMER_SECRET'
Now to initiate authentication you merely need to redirect the user to `/auth/twitter` via a link or other means. Once the user has authenticated to Twitter, they will be redirected to `/auth/twitter/callback`. You should build an endpoint that handles this URL, at which point you will will have access to the authentication information through the `rack.auth` parameter of the Rack environment. For example, in Sinatra you would do something like this:
Now to initiate authentication you merely need to redirect the user to `/auth/twitter` via a link or other means. Once the user has authenticated to Twitter, they will be redirected to `/auth/twitter/callback`. You should build an endpoint that handles this URL, at which point you will will have access to the authentication information through the `omniauth.auth` parameter of the Rack environment. For example, in Sinatra you would do something like this:
get '/auth/twitter/callback' do
auth_hash = request.env['rack.auth']
auth_hash = request.env['omniauth.auth']
end
The hash in question will look something like this:

View file

@ -1,8 +1,14 @@
require 'rubygems'
require 'rake'
require 'term/ansicolor'
include Term::ANSIColor
begin
require 'term/ansicolor'
include Term::ANSIColor
rescue LoadError
def cyan; '' end
def blue; '' end
def clear; '' end
end
OMNIAUTH_GEMS = %w(oa-basic oa-core oa-oauth oa-openid oa-enterprise omniauth)
@ -60,6 +66,15 @@ namespace :dependencies do
end
end
task :release => ['release:tag', 'gems:publish', 'doc:pages:publish']
namespace :release do
task :tag do
system("git tag v#{version}")
system('git push origin --tags')
end
end
namespace :gems do
desc 'Build all gems'
@ -70,7 +85,7 @@ namespace :gems do
end
desc 'Push all gems to Gemcutter'
task :release do
task :push do
each_gem('is releasing to Gemcutter...') do
system('rake gem:publish')
end
@ -119,3 +134,33 @@ namespace :version do
end
task :default => :spec
begin
YARD_OPTS = ['-m', 'markdown', '-M', 'maruku']
require 'yard'
YARD::Rake::YardocTask.new(:doc) do |t|
t.files = OMNIAUTH_GEMS.inject([]){|a,g| a = a + ["#{g}/lib/**/*.rb"]; a} + ['README.markdown']
t.options = YARD_OPTS
end
namespace :doc do
YARD::Rake::YardocTask.new(:pages) do |t|
t.files = OMNIAUTH_GEMS.inject([]){|a,g| a = a + ["#{g}/lib/**/*.rb"]; a} + ['README.markdown']
t.options = YARD_OPTS + ['-o', '../omniauth.doc']
end
namespace :pages do
desc 'Generate and publish YARD docs to GitHub pages.'
task :publish => ['doc:pages'] do
Dir.chdir(File.dirname(__FILE__) + '/../omniauth.doc') do
system("git add .")
system("git add -u")
system("git commit -m 'Generating docs for version #{version}.'")
system("git push origin gh-pages")
end
end
end
end
rescue LoadError
puts "You need to install YARD."
end

View file

@ -1 +1 @@
0.1.1
0.1.4

View file

@ -1,50 +0,0 @@
PATH
remote: .
specs:
oa-basic (0.1.1)
multi_json (~> 0.0.2)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
rest-client (~> 1.6.0)
PATH
remote: /Users/mbleigh/gems/omniauth/oa-core
specs:
oa-core (0.1.1)
rack (~> 1.1)
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
json (1.4.3)
mg (0.0.8)
rake
mime-types (1.16)
multi_json (0.0.4)
nokogiri (1.4.3.1)
rack (1.2.1)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rest-client (1.6.0)
mime-types (>= 1.16)
rspec (1.3.0)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-basic!
oa-core!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
webmock (~> 1.3.4)

View file

@ -35,13 +35,13 @@ module OmniAuth
def perform
@response = perform_authentication(endpoint)
request.POST['auth'] = auth_hash
@env['omniauth.auth'] = auth_hash
@env['REQUEST_METHOD'] = 'GET'
@env['PATH_INFO'] = "#{OmniAuth.config.path_prefix}/#{name}/callback"
@app.call(@env)
rescue RestClient::Request::Unauthorized
fail!(:invalid_credentials)
call_app!
rescue RestClient::Request::Unauthorized => e
fail!(:invalid_credentials, e)
end
def perform_authentication(uri, headers = request_headers)

View file

@ -1,35 +0,0 @@
PATH
remote: .
specs:
oa-core (0.1.1)
rack (~> 1.1)
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
json (1.4.3)
mg (0.0.8)
rake
rack (1.2.1)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rspec (1.3.0)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-core!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
webmock (~> 1.3.4)

View file

@ -7,6 +7,14 @@ module OmniAuth
super(&block)
end
def on_failure(&block)
OmniAuth.config.on_failure = block
end
def configure(&block)
OmniAuth.configure(&block)
end
def provider(klass, *args, &block)
if klass.is_a?(Class)
middleware = klass

View file

@ -3,35 +3,35 @@ require 'singleton'
require 'omniauth/form'
module OmniAuth
autoload :Builder, 'omniauth/builder'
autoload :Strategy, 'omniauth/strategy'
autoload :Test, 'omniauth/test'
module Strategies
autoload :Password, 'omniauth/strategies/password'
end
class Configuration
include Singleton
@@defaults = {
:path_prefix => '/auth',
:on_failure => Proc.new do |env, message_key|
new_path = "#{OmniAuth.config.path_prefix}/failure?message=#{message_key}"
[302, {'Location' => "#{new_path}"}, []]
[302, {'Location' => "#{new_path}", 'Content-Type'=> 'text/html'}, []]
end,
:form_css => Form::DEFAULT_CSS
}
def self.defaults
@@defaults
end
def initialize
@@defaults.each_pair{|k,v| self.send("#{k}=",v)}
end
def on_failure(&block)
if block_given?
@on_failure = block
@ -39,19 +39,19 @@ module OmniAuth
@on_failure
end
end
attr_writer :on_failure
attr_accessor :path_prefix, :form_css
end
def self.config
Configuration.instance
end
def self.configure
yield config
end
module Utils
CAMELIZE_SPECIAL = {
'oauth' => 'OAuth',
@ -60,31 +60,31 @@ module OmniAuth
'open_id' => 'OpenID',
'github' => 'GitHub'
}
module_function
def form_css
"<style type='text/css'>#{OmniAuth.config.form_css}</style>"
end
def deep_merge(hash, other_hash)
target = hash.dup
other_hash.keys.each do |key|
if other_hash[key].is_a? ::Hash and 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 CAMELIZE_SPECIAL[word.to_s] if CAMELIZE_SPECIAL[word.to_s]
if first_letter_in_uppercase
word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
else

View file

@ -19,8 +19,8 @@ module OmniAuth
return fail!(:password_mismatch) if request[:password_confirmation] && request[:password_confirmation] != '' && request[:password] != request[:password_confirmation]
env['REQUEST_METHOD'] = 'GET'
env['PATH_INFO'] = request.path + '/callback'
request['auth'] = auth_hash(encrypt(request[:identifier], request[:password]))
@app.call(env)
env['omniauth.auth'] = auth_hash(encrypt(request[:identifier], request[:password]))
call_app!
end
def auth_hash(crypted_password)
@ -33,7 +33,7 @@ module OmniAuth
end
def callback_phase
@app.call(env)
call_app!
end
def encrypt(identifier, password)

View file

@ -29,7 +29,7 @@ module OmniAuth
if respond_to?(:other_phase)
other_phase
else
@app.call(env)
call_app!
end
end
end
@ -39,8 +39,15 @@ module OmniAuth
end
def callback_phase
env['rack.auth'] = auth_hash
@app.call(env)
@env['omniauth.auth'] = auth_hash
call_app!
end
def call_app!
@env['rack.auth'] = env['omniauth.auth'] if env.key?('omniauth.auth')
@env['rack.auth.error'] = env['omniauth.error'] if env.key?('omniauth.error')
@app.call(@env)
end
def auth_hash
@ -77,7 +84,8 @@ module OmniAuth
def user_info; {} end
def fail!(message_key)
def fail!(message_key, exception = nil)
self.env['omniauth.error'] = exception
OmniAuth.config.on_failure.call(self.env, message_key.to_sym)
end
end

View file

@ -6,19 +6,19 @@ module OmniAuth
def sets_an_auth_hash
it 'should set an auth hash' do
last_request['auth'].should be_kind_of(Hash)
last_request.env['omniauth.auth'].should be_kind_of(Hash)
end
end
def sets_provider_to(provider)
it "should set the provider to #{provider}" do
(last_request['auth'] || {})['provider'].should == provider
(last_request.env['omniauth.auth'] || {})['provider'].should == provider
end
end
def sets_uid_to(uid)
it "should set the UID to #{uid}" do
(last_request['auth'] || {})['uid'].should == uid
(last_request.env['omniauth.auth'] || {})['uid'].should == uid
end
end

View file

@ -5,8 +5,9 @@ module OmniAuth
module Test
# Support for testing OmniAuth strategies. Usage:
# Support for testing OmniAuth strategies.
#
# @example Usage
# class MyStrategyTest < Test::Unit::TestCase
# include OmniAuth::Test::StrategyTestCase
# def strategy

View file

@ -29,7 +29,7 @@ describe OmniAuth::Strategies::Password, :type => :strategy do
sets_an_auth_hash
sets_provider_to 'password'
it 'should set the UID to an opaque identifier' do
uid = last_request['auth']['uid']
uid = last_request.env['omniauth.auth']['uid']
uid.should_not be_nil
uid.should_not =~ /jerome/
uid.should_not =~ /my password/

View file

@ -1,48 +0,0 @@
PATH
remote: /Users/mbleigh/gems/omniauth/oa-core
specs:
oa-core (0.1.1)
rack (~> 1.1)
PATH
remote: .
specs:
oa-enterprise (0.1.1)
net-ldap (~> 0.1.1)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
rubyntlm (~> 0.1.1)
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
json (1.4.3)
mg (0.0.8)
rake
net-ldap (0.1.1)
nokogiri (1.4.3.1)
rack (1.1.0)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rspec (1.3.0)
rubyntlm (0.1.1)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-core!
oa-enterprise!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
webmock (~> 1.3.4)

View file

@ -11,12 +11,12 @@ module OmniAuth
# @param [Hash] params configuration options
# @option params [String, nil] :cas_server the CAS server root URL; probably something like
# 'http://cas.mycompany.com' or 'http://cas.mycompany.com/cas'; optional.
# `http://cas.mycompany.com` or `http://cas.mycompany.com/cas`; optional.
# @option params [String, nil] :cas_login_url (:cas_server + '/login') the URL to which to
# redirect for logins; options if <tt>:cas_server</tt> is specified,
# redirect for logins; options if `:cas_server` is specified,
# required otherwise.
# @option params [String, nil] :cas_service_validate_url (:cas_server + '/serviceValidate') the
# URL to use for validating service tickets; optional if <tt>:cas_server</tt> is
# URL to use for validating service tickets; optional if `:cas_server` is
# specified, requred otherwise.
def initialize(params)
parse_params params
@ -26,8 +26,7 @@ module OmniAuth
#
# @param [String] service the service (a.k.a. return-to) URL
#
# @return [String] a URL like
# "http://cas.mycompany.com/login?service=..."
# @return [String] a URL like `http://cas.mycompany.com/login?service=...`
def login_url(service)
append_service @login_url, service
end
@ -37,8 +36,7 @@ module OmniAuth
# @param [String] service the service (a.k.a. return-to) URL
# @param [String] ticket the ticket to validate
#
# @return [String] a URL like
# "http://cas.mycompany.com/serviceValidate?service=...&ticket=..."
# @return [String] a URL like `http://cas.mycompany.com/serviceValidate?service=...&ticket=...`
def service_validate_url(service, ticket)
url = append_service @service_validate_url, service
url << '&ticket=' << Rack::Utils.escape(ticket)

View file

@ -31,7 +31,7 @@ module OmniAuth
private
# turns an <cas:authenticationSuccess> node into a Hash;
# turns an `<cas:authenticationSuccess>` node into a Hash;
# returns nil if given nil
def parse_user_info(node)
return nil if node.nil?
@ -45,8 +45,8 @@ module OmniAuth
end
end
# finds an <cas:authenticationSuccess> node in
# a <cas:serviceResponse> body if present; returns nil
# finds an `<cas:authenticationSuccess>` node in
# a `<cas:serviceResponse>` body if present; returns nil
# if the passed body is nil or if there is no such node.
def find_authentication_success(body)
return nil if body.nil? || body == ''
@ -62,7 +62,7 @@ module OmniAuth
end
end
# retrieves the <cas:serviceResponse> XML from the CAS server
# retrieves the `<cas:serviceResponse>` XML from the CAS server
def get_service_response_body
result = ''
http = Net::HTTP.new(@uri.host, @uri.port)

View file

@ -45,14 +45,12 @@ module OmniAuth
@adaptor.bind(:bind_dn => request.POST['username'], :password => request.POST['password'])
@ldap_user_info = @adaptor.search(:filter => Net::LDAP::Filter.eq(@adaptor.uid, request.POST['username']),:limit => 1)
@user_info = self.class.map_user(@@config, @ldap_user_info)
request.POST['auth'] = auth_hash
@env['REQUEST_METHOD'] = 'GET'
@env['PATH_INFO'] = "#{OmniAuth.config.path_prefix}/#{name}/callback"
@app.call(@env)
call_app!
rescue Exception => e
puts e.message
fail!(:invalid_credentials)
fail!(:invalid_credentials, e)
end
end

View file

@ -1,55 +0,0 @@
PATH
remote: /Users/mbleigh/gems/omniauth/oa-core
specs:
oa-core (0.1.1)
rack (~> 1.1)
PATH
remote: .
specs:
oa-oauth (0.1.1)
multi_json (~> 0.0.2)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
oauth (~> 0.4.0)
oauth2 (~> 0.0.10)
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
faraday (0.4.6)
addressable (>= 2.1.1)
rack (>= 1.0.1)
json (1.4.3)
mg (0.0.8)
rake
multi_json (0.0.4)
nokogiri (1.4.3.1)
oauth (0.4.3)
oauth2 (0.0.13)
faraday (~> 0.4.1)
multi_json (>= 0.0.4)
rack (1.2.1)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rspec (1.3.0)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-core!
oa-oauth!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
webmock (~> 1.3.4)

View file

@ -11,5 +11,7 @@ module OmniAuth
autoload :GitHub, 'omniauth/strategies/github'
autoload :ThirtySevenSignals, 'omniauth/strategies/thirty_seven_signals'
autoload :Foursquare, 'omniauth/strategies/foursquare'
autoload :Gowalla, 'omniauth/strategies/gowalla'
autoload :Identica, 'omniauth/strategies/identica'
end
end

View file

@ -3,18 +3,16 @@ require 'multi_json'
module OmniAuth
module Strategies
#
# Authenticate to Facebook utilizing OAuth 2.0 and retrieve
# basic user information.
#
# Usage:
#
# use OmniAuth::Strategies::Facebook, 'app_id', 'app_secret'
#
# Options:
#
# <tt>:scope</tt> :: Extended permissions such as <tt>email</tt> and <tt>offline_access</tt> (which are the defaults).
# @example Basic Usage
# use OmniAuth::Strategies::Facebook, 'app_id', 'app_secret'
class Facebook < OAuth2
# @param [Rack Application] app standard middleware application parameter
# @param [String] app_id the application id as [registered on Facebook](http://www.facebook.com/developers/)
# @param [String] app_secret the application secret as registered on Facebook
# @option options [String] :scope ('email,offline_access') comma-separated extended permissions such as `email` and `manage_pages`
def initialize(app, app_id, app_secret, options = {})
options[:site] = 'https://graph.facebook.com/'
super(app, :facebook, app_id, app_secret, options)
@ -24,9 +22,9 @@ module OmniAuth
@data ||= MultiJson.decode(@access_token.get('/me'))
end
def request_phase(options = {})
def request_phase
options[:scope] ||= "email,offline_access"
super(options)
super
end
def user_info

View file

@ -3,7 +3,13 @@ require 'multi_json'
module OmniAuth
module Strategies
# OAuth 2.0 based authentication with GitHub. In order to
# sign up for an application, you need to [register an application](http://github.com/account/applications/new)
# and provide the proper credentials to this middleware.
class GitHub < OAuth2
# @param [Rack Application] app standard middleware application argument
# @param [String] app_id the application ID for your client
# @param [String] app_secret the application secret
def initialize(app, app_id, app_secret, options = {})
options[:site] = 'https://github.com/'
options[:authorize_path] = '/login/oauth/authorize'
@ -11,6 +17,8 @@ module OmniAuth
super(app, :github, app_id, app_secret, options)
end
protected
def user_data
@data ||= MultiJson.decode(@access_token.get('/api/v2/json/user/show'))['user']
end

View file

@ -0,0 +1,61 @@
require 'omniauth/oauth'
require 'multi_json'
module OmniAuth
module Strategies
#
# Authenticate to Gowalla utilizing OAuth 2.0 and retrieve
# basic user information.
#
# @example Basic Usage
# use OmniAuth::Strategies::Gowalla, 'API Key', 'Secret Key'
class Gowalla < OAuth2
# @param [Rack Application] app standard middleware application parameter
# @param [String] api_key the application id as [registered on Gowalla](http://gowalla.com/api/keys)
# @param [String] secret_key the application secret as [registered on Gowalla](http://gowalla.com/api/keys)
# @option options ['read','read-write'] :scope ('read') the scope of your authorization request; must be `read` or `read-write`
def initialize(app, api_key, secret_key, options = {})
options[:site] = 'https://api.gowalla.com/api/oauth'
options[:authorize_url] = 'https://gowalla.com/api/oauth/new'
options[:access_token_url] = 'https://api.gowalla.com/api/oauth/token'
super(app, :gowalla, api_key, secret_key, options)
end
protected
def user_data
@data ||= MultiJson.decode(@access_token.get("/users/me.json"))
end
def request_phase
options[:scope] ||= "read"
super
end
def user_info
{
'name' => "#{user_data['first_name']} #{user_data['last_name']}",
'nickname' => user_data["username"],
'first_name' => user_data["first_name"],
'last_name' => user_data["last_name"],
'location' => user_data["hometown"],
'description' => user_data["bio"],
'image' => user_data["image_url"],
'phone' => nil,
'urls' => {
'Gowalla' => "http://www.gowalla.com#{user_data['url']}",
'Website' => user_data["website"]
}
}
end
def auth_hash
OmniAuth::Utils.deep_merge(super, {
'uid' => user_data["url"].split('/').last,
'user_info' => user_info,
'extra' => {'user_hash' => user_data}
})
end
end
end
end

View file

@ -0,0 +1,49 @@
require 'omniauth/oauth'
require 'multi_json'
module OmniAuth
module Strategies
#
# Authenticate to Identica via OAuth and retrieve basic
# user information.
#
# Usage:
#
# use OmniAuth::Strategies::Identica, 'consumerkey', 'consumersecret'
#
class Identica < OmniAuth::Strategies::OAuth
def initialize(app, consumer_key, consumer_secret)
super(app, :identica, consumer_key, consumer_secret,
:site => 'http://identi.ca',
:request_token_path => "/api/oauth/request_token",
:access_token_path => "/api/oauth/access_token",
:authorize_path => "/api/oauth/authorize")
end
def auth_hash
OmniAuth::Utils.deep_merge(super, {
'uid' => @access_token.params[:user_id],
'user_info' => user_info,
'extra' => {'user_hash' => user_hash}
})
end
def user_info
user_hash = self.user_hash
{
'nickname' => user_hash['screen_name'],
'name' => user_hash['name'],
'location' => user_hash['location'],
'image' => user_hash['profile_image_url'],
'description' => user_hash['description'],
'urls' => {'Website' => user_hash['url']}
}
end
def user_hash
@user_hash ||= MultiJson.decode(@access_token.get('/api/account/verify_credentials.json').body)
end
end
end
end

View file

@ -23,12 +23,9 @@ module OmniAuth
def callback_phase
request_token = ::OAuth::RequestToken.new(consumer, session[:oauth][name.to_sym].delete(:request_token), session[:oauth][name.to_sym].delete(:request_secret))
@access_token = request_token.get_access_token(:oauth_verifier => request.params['oauth_verifier'])
request['auth'] = self.auth_hash
@app.call(self.env)
rescue ::OAuth::Unauthorized
fail!(:invalid_credentials)
super
rescue ::OAuth::Unauthorized => e
fail!(:invalid_credentials, e)
end
def auth_hash

View file

@ -5,29 +5,60 @@ require 'omniauth/oauth'
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
# The options passed in to the strategy.
attr_accessor :options
# The `OAuth2::Client` for this strategy.
attr_accessor :client
# 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
end
# Initialize a new OAuth 2.0 authentication provider.
# @param [Rack Application] app standard middleware application argument
# @param [String] name the name for this provider to be used in its URL, e.g. `/auth/name`
# @param [String] client_id the client/application ID of this provider
# @param [String] client_secret the client/application secret of this provider
# @param [Hash] options that will be passed through to the OAuth2::Client (see [oauth2 docs](http://rubydoc.info/gems/oauth2))
def initialize(app, name, client_id, client_secret, options = {})
super(app, name)
@options = options
@client = ::OAuth2::Client.new(client_id, client_secret, options)
self.options = options
self.client = ::OAuth2::Client.new(client_id, client_secret, options)
end
protected
attr_accessor :client
def request_phase(options = {})
def request_phase
redirect client.web_server.authorize_url({:redirect_uri => callback_url}.merge(options))
end
def callback_phase
if request.params['error']
raise CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri'])
end
verifier = request.params['code']
@access_token = client.web_server.get_access_token(verifier, :redirect_uri => callback_url)
super
rescue ::OAuth2::HTTPError => e
fail!(:invalid_credentials)
rescue ::OAuth2::HTTPError, ::OAuth2::AccessDenied, CallbackError => e
fail!(:invalid_credentials, e)
end
def auth_hash

View file

@ -14,7 +14,8 @@ module OmniAuth
class Twitter < OmniAuth::Strategies::OAuth
def initialize(app, consumer_key, consumer_secret)
super(app, :twitter, consumer_key, consumer_secret,
:site => 'https://api.twitter.com')
:site => 'https://api.twitter.com',
:authorize_path => '/oauth/authenticate')
end
def auth_hash

View file

@ -0,0 +1,13 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe OmniAuth::Strategies::Gowalla do
it 'should subclass OAuth2' do
OmniAuth::Strategies::Gowalla.should < OmniAuth::Strategies::OAuth2
end
it 'should initialize with just api key and secret key' do
lambda{OmniAuth::Strategies::Gowalla.new({},'api_key','secret_key')}.should_not raise_error
end
end

View file

@ -0,0 +1,13 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe 'OmniAuth::Strategies::Identica' do
it 'should subclass Identica' do
OmniAuth::Strategies::Identica.should < OmniAuth::Strategies::OAuth
end
it 'should initialize with just consumer key and secret' do
lambda{OmniAuth::Strategies::Identica.new({},'abc','def')}.should_not raise_error
end
end

View file

@ -8,7 +8,7 @@ describe "OmniAuth::Strategies::OAuth" do
use OmniAuth::Builder do
provider :oauth, 'example.org', 'abc', 'def', :site => 'https://api.example.org'
end
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, [Rack::Request.new(env).params.key?('auth').to_s]] }
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
}.to_app
end
@ -43,8 +43,8 @@ describe "OmniAuth::Strategies::OAuth" do
end
it 'should exchange the request token for an access token' do
last_request['auth']['provider'].should == 'example.org'
last_request['auth']['extra']['access_token'].should be_kind_of(OAuth::AccessToken)
last_request.env['omniauth.auth']['provider'].should == 'example.org'
last_request.env['omniauth.auth']['extra']['access_token'].should be_kind_of(OAuth::AccessToken)
end
it 'should call through to the master app' do

View file

@ -1,51 +0,0 @@
PATH
remote: /Users/mbleigh/gems/omniauth/oa-core
specs:
oa-core (0.1.1)
rack (~> 1.1)
PATH
remote: .
specs:
oa-openid (0.1.1)
oa-core (= 0.1.1)
rack-openid (~> 1.1.1)
ruby-openid-apps-discovery
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
json (1.4.3)
mg (0.0.8)
rake
rack (1.2.1)
rack-openid (1.1.1)
rack (>= 0.4)
ruby-openid (>= 2.0.3)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rspec (1.3.0)
ruby-openid (2.1.8)
ruby-openid-apps-discovery (1.2.0)
ruby-openid (>= 2.1.7)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-core!
oa-openid!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
ruby-openid-apps-discovery
webmock (~> 1.3.4)

View file

@ -1,37 +0,0 @@
= OmniAuth::OpenID
OpenID strategies for the OmniAuth gem.
== Installation
To get just OpenID functionality:
gem install oa-openid
For the full auth suite:
gem install omniauth
== Stand-Alone Example
Use the strategy as a middleware in your application:
require 'omniauth/openid'
require 'openid/store/filesystem'
use OmniAuth::Strategies::OpenID, OpenID::Store::Filesystem.new('/tmp')
Then simply direct users to '/auth/open_id' to prompt them for their OpenID identifier. You may also pre-set the identifier by passing an <tt>identifier</tt> parameter to the URL (Example: <tt>/auth/open_id?identifier=google.com</tt>).
== OmniAuth Builder
If OpenID is one of several authentication strategies, use the OmniAuth Builder:
require 'omniauth/openid'
require 'omniauth/basic' # for Campfire
require 'openid/store/filesystem'
use OmniAuth::Builder do
provider :open_id, OpenID::Store::Filesystem.new('/tmp')
provider :campfire
end

View file

@ -1,6 +1,57 @@
require 'omniauth/core'
module OmniAuth
# OmniAuth::OpenID provides strategies for authenticating to providers
# using the OpenID standard.
#
# # Installation
#
# To get just OpenID functionality:
#
# gem install oa-openid
#
# For the full auth suite:
#
# gem install omniauth
#
# # Stand-Alone Example
#
# Use the strategy as a middleware in your application:
#
# require 'omniauth/openid'
# require 'openid/store/filesystem'
#
# use Rack::Session::Cookie
# use OmniAuth::Strategies::OpenID, OpenID::Store::Filesystem.new('/tmp')
#
# Then simply direct users to '/auth/open_id' to prompt them for their OpenID identifier. You may also pre-set the identifier by passing an <tt>identifier</tt> parameter to the URL (Example: <tt>/auth/open_id?openid_url=yahoo.com</tt>).
#
# A list of all OpenID stores is available at http://github.com/openid/ruby-openid/tree/master/lib/openid/store/
#
# # OmniAuth Builder
#
# If OpenID is one of several authentication strategies, use the OmniAuth Builder:
#
# require 'omniauth/openid'
# require 'omniauth/basic' # for Campfire
# require 'openid/store/filesystem'
#
# use OmniAuth::Builder do
# provider :open_id, OpenID::Store::Filesystem.new('/tmp')
# provider :campfire
# end
#
# # Configured Identifiers
#
# You may pre-configure an OpenID identifier. For example, to use Google's main OpenID endpoint:
#
# use OmniAuth::Builder do
# provider :open_id, nil, :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id'
# end
#
# Note the use of nil, which will trigger ruby-openid's default Memory Store.
module OpenID; end
module Strategies
autoload :OpenID, 'omniauth/strategies/open_id'
autoload :GoogleApps, 'omniauth/strategies/google_apps'

View file

@ -0,0 +1,32 @@
require 'openid/consumer'
require 'gapps_openid'
module OpenID
# Because gapps_openid changes the discovery order
# (looking first for Google Apps, then anything else),
# we need to monkeypatch it to make it play nicely
# with others.
def self.discover(uri)
discovered = self.default_discover(uri)
if discovered.last.empty?
info = discover_google_apps(uri)
return info if info
end
return discovered
rescue OpenID::DiscoveryFailure => e
info = discover_google_apps(uri)
if info.nil?
raise e
else
return info
end
end
def self.discover_google_apps(uri)
discovery = GoogleDiscovery.new
discovery.perform_discovery(uri)
end
end

View file

@ -8,6 +8,13 @@ module OmniAuth
super(app, store, options)
end
def get_identifier
OmniAuth::Form.build('Google Apps Authentication') do
label_field('Google Apps Domain', 'domain')
input_field('url', 'domain')
end.to_response
end
def identifier
options[:domain] || request['domain']
end

View file

@ -1,5 +1,5 @@
require 'rack/openid'
require 'gapps_openid'
require 'omniauth/openid/gapps'
require 'omniauth/openid'
module OmniAuth
@ -24,7 +24,7 @@ module OmniAuth
}
def initialize(app, store = nil, options = {})
super(app, options[:name] || :open_id)
super(app, options.delete(:name) || :open_id)
@options = options
@options[:required] ||= [AX[:email], AX[:first_name], AX[:last_name], 'email', 'fullname']
@options[:optional] ||= [AX[:nickname], AX[:city], AX[:state], AX[:website], AX[:image], 'postcode', 'nickname']
@ -47,7 +47,7 @@ module OmniAuth
end
def identifier
request[IDENTIFIER_URL_PARAMETER]
options[:identifier] || request[IDENTIFIER_URL_PARAMETER]
end
def request_phase
@ -74,22 +74,20 @@ module OmniAuth
def callback_phase
env['REQUEST_METHOD'] = 'GET'
openid = Rack::OpenID.new(lambda{|env| [200,{},[]]}, @store)
openid.call(env)
resp = env.delete('rack.openid.response')
if resp && resp.status == :success
request['auth'] = auth_hash(resp)
@app.call(env)
@openid_response = env.delete('rack.openid.response')
if @openid_response && @openid_response.status == :success
super
else
fail!(:invalid_credentials)
end
end
def auth_hash(response)
def auth_hash
OmniAuth::Utils.deep_merge(super(), {
'uid' => response.display_identifier,
'user_info' => user_info(response)
'uid' => @openid_response.display_identifier,
'user_info' => user_info(@openid_response)
})
end

View file

@ -1,106 +0,0 @@
PATH
remote: /Users/mbleigh/gems/omniauth/oa-basic
specs:
oa-basic (0.1.1)
multi_json (~> 0.0.2)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
rest-client (~> 1.6.0)
PATH
remote: /Users/mbleigh/gems/omniauth/oa-core
specs:
oa-core (0.1.1)
rack (~> 1.1)
PATH
remote: /Users/mbleigh/gems/omniauth/oa-enterprise
specs:
oa-enterprise (0.1.1)
net-ldap (~> 0.1.1)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
rubyntlm (~> 0.1.1)
PATH
remote: /Users/mbleigh/gems/omniauth/oa-oauth
specs:
oa-oauth (0.1.1)
multi_json (~> 0.0.2)
nokogiri (~> 1.4.2)
oa-core (= 0.1.1)
oauth (~> 0.4.0)
oauth2 (~> 0.0.10)
PATH
remote: /Users/mbleigh/gems/omniauth/oa-openid
specs:
oa-openid (0.1.1)
oa-core (= 0.1.1)
rack-openid (~> 1.1.1)
ruby-openid-apps-discovery
PATH
remote: .
specs:
omniauth (0.1.1)
oa-basic (= 0.1.1)
oa-core (= 0.1.1)
oa-enterprise (= 0.1.1)
oa-oauth (= 0.1.1)
oa-openid (= 0.1.1)
GEM
remote: http://rubygems.org/
specs:
addressable (2.2.0)
crack (0.1.8)
faraday (0.4.6)
addressable (>= 2.1.1)
rack (>= 1.0.1)
json (1.4.3)
mg (0.0.8)
rake
mime-types (1.16)
multi_json (0.0.4)
net-ldap (0.1.1)
nokogiri (1.4.3.1)
oauth (0.4.3)
oauth2 (0.0.13)
faraday (~> 0.4.1)
multi_json (>= 0.0.4)
rack (1.2.1)
rack-openid (1.1.1)
rack (>= 0.4)
ruby-openid (>= 2.0.3)
rack-test (0.5.4)
rack (>= 1.0)
rake (0.8.7)
rest-client (1.6.0)
mime-types (>= 1.16)
rspec (1.3.0)
ruby-openid (2.1.8)
ruby-openid-apps-discovery (1.2.0)
ruby-openid (>= 2.1.7)
rubyntlm (0.1.1)
webmock (1.3.4)
addressable (>= 2.1.1)
crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
json (~> 1.4.3)
mg (~> 0.0.8)
oa-basic!
oa-core!
oa-enterprise!
oa-oauth!
oa-openid!
omniauth!
rack
rack-test (~> 0.5.4)
rake
rspec (~> 1.3.0)
webmock (~> 1.3.4)