mirror of
https://github.com/omniauth/omniauth.git
synced 2022-11-09 12:31:49 -05:00
Adds lots of stuff. Facebook is broken, beware.
This commit is contained in:
parent
349cfc3e44
commit
f9dc9ea282
31 changed files with 250 additions and 28 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,3 +24,4 @@ rdoc
|
|||
pkg
|
||||
|
||||
## PROJECT::SPECIFIC
|
||||
*.gem
|
4
Rakefile
4
Rakefile
|
@ -4,7 +4,7 @@ require 'term/ansicolor'
|
|||
|
||||
include Term::ANSIColor
|
||||
|
||||
OMNIAUTH_GEMS = %w(oa-core oa-basic oa-oauth oa-openid)
|
||||
OMNIAUTH_GEMS = %w(oa-core oa-basic oa-oauth oa-openid oa-facebook)
|
||||
|
||||
desc 'Run specs for all of the gems.'
|
||||
task :spec do
|
||||
|
@ -15,4 +15,6 @@ task :spec do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
|
0
oa-basic/CHANGELOG.rdoc
Normal file
0
oa-basic/CHANGELOG.rdoc
Normal file
0
oa-basic/LICENSE.rdoc
Normal file
0
oa-basic/LICENSE.rdoc
Normal file
0
oa-basic/README.rdoc
Normal file
0
oa-basic/README.rdoc
Normal file
|
@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|||
gem.summary = %Q{HTTP Basic strategies for OmniAuth.}
|
||||
gem.description = %Q{HTTP Basic strategies for OmniAuth.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omni_auth"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
|
0
oa-core/CHANGELOG.rdoc
Normal file
0
oa-core/CHANGELOG.rdoc
Normal file
0
oa-core/LICENSE.rdoc
Normal file
0
oa-core/LICENSE.rdoc
Normal file
0
oa-core/README.rdoc
Normal file
0
oa-core/README.rdoc
Normal file
|
@ -12,17 +12,21 @@ module OmniAuth
|
|||
end
|
||||
|
||||
def call(env)
|
||||
dup._call(env)
|
||||
dup.call!(env)
|
||||
end
|
||||
|
||||
def _call(env)
|
||||
def call!(env)
|
||||
@env = env
|
||||
if request.path == "#{OmniAuth.config.path_prefix}/#{name}"
|
||||
request_phase
|
||||
elsif request.path == "#{OmniAuth.config.path_prefix}/#{name}/callback"
|
||||
callback_phase
|
||||
else
|
||||
@app.call(env)
|
||||
if respond_to?(:other_phase)
|
||||
other_phase
|
||||
else
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,7 +35,8 @@ module OmniAuth
|
|||
end
|
||||
|
||||
def callback_phase
|
||||
raise NotImplementedError
|
||||
request['auth'] = auth_hash
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def auth_hash
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Gem::Specification.new do |gem|
|
||||
gem.name = "oa-basic"
|
||||
gem.name = "oa-core"
|
||||
gem.version = File.open(File.dirname(__FILE__) + '/VERSION', 'r').read.strip
|
||||
gem.summary = %Q{HTTP Basic strategies for OmniAuth.}
|
||||
gem.description = %Q{HTTP Basic strategies for OmniAuth.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omni_auth"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
|
0
oa-facebook/CHANGELOG.rdoc
Normal file
0
oa-facebook/CHANGELOG.rdoc
Normal file
0
oa-facebook/LICENSE.rdoc
Normal file
0
oa-facebook/LICENSE.rdoc
Normal file
0
oa-facebook/README.rdoc
Normal file
0
oa-facebook/README.rdoc
Normal file
13
oa-facebook/Rakefile
Normal file
13
oa-facebook/Rakefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
require 'rubygems'
|
||||
require 'rake'
|
||||
|
||||
require 'mg'
|
||||
MG.new('oa-facebook.gemspec')
|
||||
|
||||
require 'spec/rake/spectask'
|
||||
Spec::Rake::SpecTask.new(:spec) do |spec|
|
||||
spec.libs << '../oa-core/lib' << 'lib' << 'spec'
|
||||
spec.spec_files = FileList['spec/**/*_spec.rb']
|
||||
end
|
||||
|
||||
task :default => :spec
|
1
oa-facebook/VERSION
Normal file
1
oa-facebook/VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
0.0.1
|
3
oa-facebook/lib/omniauth/facebook.rb
Normal file
3
oa-facebook/lib/omniauth/facebook.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'omniauth/core'
|
||||
require 'omniauth/strategies/facebook'
|
||||
require 'mini_fb'
|
128
oa-facebook/lib/omniauth/strategies/facebook.rb
Normal file
128
oa-facebook/lib/omniauth/strategies/facebook.rb
Normal file
|
@ -0,0 +1,128 @@
|
|||
module OmniAuth
|
||||
module Strategies
|
||||
# An Authentication strategy that utilizes Facebook Connect.
|
||||
class Facebook
|
||||
include OmniAuth::Strategy
|
||||
EXTENDED_PERMISSIONS = %w(publish_stream read_stream email read_mailbox offline_access create_event rsvp_event sms status_update video_upload create_note share_item)
|
||||
|
||||
# Initialize the middleware. Requires a Facebook API key and secret
|
||||
# and takes the following options:
|
||||
#
|
||||
# <tt>:permissions</tt> :: An array of Facebook extended permissions, defaults to <tt>%w(email offline_access)</tt>. Use <tt>:all</tt> to include all extended permissions.
|
||||
# <tt>:scripts</tt> :: A boolean value for whether or not to automatically inject the Facebook Javascripts and XD Receiver into your application. Defaults to <tt>true</tt>.
|
||||
#
|
||||
def initialize(app, api_key, api_secret, options = {})
|
||||
super app, :facebook
|
||||
|
||||
options[:permissions] = EXTENDED_PERMISSIONS if options[:permissions] == :all
|
||||
@options = {
|
||||
:permissions => %w(email offline_access),
|
||||
:scripts => true
|
||||
}.merge(options)
|
||||
|
||||
@api_key = api_key
|
||||
@api_secret = api_secret
|
||||
|
||||
self.extend PageInjections if @options[:scripts]
|
||||
end
|
||||
|
||||
def auth_hash
|
||||
OmniAuth.deep_merge(super, {
|
||||
'provider' => 'facebook',
|
||||
'uid' => request.cookies["#{@api_key}_user"],
|
||||
'credentials' => {
|
||||
'key' => request.cookies["#{@api_key}_session_key"],
|
||||
'secret' => request.cookies["#{@api_key}_ss"],
|
||||
'expires' => (Time.at(request.cookies["#{@api_key}_expires"].to_i) if request.cookies["#{@api_key}_expires"].to_i > 0)
|
||||
},
|
||||
'user_info' => user_info(session_key, user_id)
|
||||
})
|
||||
end
|
||||
|
||||
def user_info
|
||||
hash = MiniFB.call(@api_key, @api_secret, "Users.getInfo", 'uids' => request[:auth][:user_id], 'fields' => [:name, :first_name, :last_name, :username, :pic_square, :current_location])[0]
|
||||
{
|
||||
'name' => user[:name],
|
||||
'first_name' => user[:first_name],
|
||||
'last_name' => user[:last_name],
|
||||
'nickname' => user[:username],
|
||||
'image' => user[:pic_square],
|
||||
'location' => user[:locale]
|
||||
}
|
||||
end
|
||||
|
||||
def call(env)
|
||||
dup = self.dup
|
||||
dup.extend PageInjections if @options[:scripts]
|
||||
dup.call!(env)
|
||||
end
|
||||
|
||||
module PageInjections
|
||||
def call!(env)
|
||||
super
|
||||
@base_url = (request.scheme.downcase == 'https' ? 'https://ssl.connect.facebook.com' : 'http://static.ak.connect.facebook.com')
|
||||
case request.path
|
||||
when "/#{OmniAuth.config.path_prefix}/facebook/xd_receiver.html"
|
||||
xd_receiver
|
||||
else
|
||||
inject_facebook
|
||||
end
|
||||
end
|
||||
|
||||
def xd_receiver #:nodoc:
|
||||
xd = <<-HTML
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
<head>
|
||||
<title>Cross-Domain Receiver Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="#{@base_url}/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
Rack::Response.new(xd).finish
|
||||
end
|
||||
|
||||
def inject_facebook #:nodoc:
|
||||
status, headers, responses = @app.call(@env)
|
||||
responses = Array(responses) unless responses.respond_to?(:each)
|
||||
|
||||
if headers["Content-Type"] =~ %r{(text/html)|(application/xhtml+xml)}
|
||||
resp = []
|
||||
responses.each do |r|
|
||||
r.sub! /(<html[^\/>]*)>/i, '\1 xmlns:fb=\"http://www.facebook.com/2008/fbml\">'
|
||||
r.sub! /(<body[^\/>]*)>/i, '\1><script src="' + @base_url + '/js/api_lib/v0.4/FeatureLoader.js.php/en_US" type="text/javascript"></script>'
|
||||
r.sub! /<\/body>/i, <<-HTML
|
||||
<script type="text/javascript">
|
||||
FB.init("#{@api_key}", "/auth/facebook/xd_receiver.html");
|
||||
OmniAuth = {
|
||||
Facebook: {
|
||||
loginSuccess:function() {
|
||||
FB.Connect.showPermissionDialog("#{Array(@options[:permissions]).join(',')}", function(perms) {
|
||||
if (perms) {
|
||||
window.location.href = '/#{OmniAuth.config.path_prefix}/facebook/callback';
|
||||
} else {
|
||||
window.location.href = '/#{OmniAuth.config.path_prefix}/facebook/callback?permissions=denied';
|
||||
}
|
||||
});
|
||||
},
|
||||
loginFailure:function() {
|
||||
window.location.href = '/#{OmniAuth.config.path_prefix}/failure?message=user_declined';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script></body>
|
||||
HTML
|
||||
resp << r
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Response.new(resp || responses, status, headers).finish
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
oa-facebook/oa-facebook.gemspec
Normal file
21
oa-facebook/oa-facebook.gemspec
Normal file
|
@ -0,0 +1,21 @@
|
|||
version = File.open(File.dirname(__FILE__) + '/VERSION', 'r').read.strip
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.name = "oa-facebook"
|
||||
gem.version = File.open(File.dirname(__FILE__) + '/VERSION', 'r').read.strip
|
||||
gem.summary = %Q{Facebook strategies for OmniAuth.}
|
||||
gem.description = %Q{Facebook strategies for OmniAuth.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
||||
gem.add_dependency 'oa-core', "~> #{version.gsub(/\d$/,'0')}"
|
||||
gem.add_dependency 'fb_mini'
|
||||
|
||||
gem.add_development_dependency "rspec", ">= 1.2.9"
|
||||
gem.add_development_dependency "webmock"
|
||||
gem.add_development_dependency "rack-test"
|
||||
gem.add_development_dependency "mg"
|
||||
end
|
0
oa-facebook/spec/spec_helper.rb
Normal file
0
oa-facebook/spec/spec_helper.rb
Normal file
|
@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|||
gem.summary = %Q{OAuth strategies for OmniAuth.}
|
||||
gem.description = %Q{OAuth strategies for OmniAuth.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omni_auth"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
|
0
oa-openid/CHANGELOG.rdoc
Normal file
0
oa-openid/CHANGELOG.rdoc
Normal file
0
oa-openid/LICENSE.rdoc
Normal file
0
oa-openid/LICENSE.rdoc
Normal file
0
oa-openid/README.rdoc
Normal file
0
oa-openid/README.rdoc
Normal file
7
oa-openid/lib/omniauth/strategies/google.rb
Normal file
7
oa-openid/lib/omniauth/strategies/google.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
module OmniAuth
|
||||
module Strategies
|
||||
class Google < OmniAuth::Stratgies::OpenID
|
||||
def identifier; 'https://www.google.com/accounts/o8/id' end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,27 +5,55 @@ module OmniAuth
|
|||
class OpenID
|
||||
include OmniAuth::Strategy
|
||||
|
||||
AX = {
|
||||
:email => 'http://axschema.org/contact/email',
|
||||
:name => 'http://axschema.org/namePerson',
|
||||
:nickname => 'http://axschema.org/namePerson/friendly',
|
||||
:first_name => 'http://axschema.org/namePerson/first',
|
||||
:last_name => 'http://axschema.org/namePerson/last',
|
||||
:city => 'http://axschema.org/contact/city/home',
|
||||
:state => 'http://axschema.org/contact/state/home',
|
||||
:website => 'http://axschema.org/contact/web/default',
|
||||
:image => 'http://axschema.org/media/image/aspect11'
|
||||
}
|
||||
|
||||
def initialize(app, store = nil, options = {})
|
||||
super(app, :open_id)
|
||||
super(app, options[:name] || :open_id)
|
||||
@options = options
|
||||
@options[:required] ||= %w(email fullname)
|
||||
@options[:optional] ||= %w(nickname dob gender postcode country language timezone)
|
||||
@options[:required] ||= [AX[:email], AX[:name], 'email', 'fullname']
|
||||
@options[:optional] ||= [AX[:first_name], AX[:last_name], AX[:nickname], AX[:city], AX[:state], AX[:website], AX[:image], 'postcode', 'nickname']
|
||||
@store = store
|
||||
end
|
||||
|
||||
def dummy_app
|
||||
lambda{|env| [401, {"WWW-Authenticate" => Rack::OpenID.build_header(
|
||||
:identifier => request[:identifier],
|
||||
:return_to => request.url + '/callback',
|
||||
:identifier => identifier,
|
||||
:return_to => callback_url,
|
||||
:required => @options[:required],
|
||||
:optional => @options[:optional]
|
||||
)}, []]}
|
||||
end
|
||||
|
||||
def callback_url
|
||||
uri = URI.parse(request.url)
|
||||
uri.path += '/callback'
|
||||
uri.to_s
|
||||
end
|
||||
|
||||
def identifier
|
||||
request[:identifier]
|
||||
end
|
||||
|
||||
def request_phase
|
||||
return fail!(:missing_information) unless request[:identifier]
|
||||
return fail!(:missing_information) unless identifier
|
||||
openid = Rack::OpenID.new(dummy_app, @store)
|
||||
openid.call(env)
|
||||
response = openid.call(env)
|
||||
case env['rack.openid.response']
|
||||
when Rack::OpenID::MissingResponse, Rack::OpenID::TimeoutResponse
|
||||
fail :connection_failed
|
||||
else
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
def callback_phase
|
||||
|
@ -45,19 +73,36 @@ module OmniAuth
|
|||
def auth_hash(response)
|
||||
OmniAuth::Utils.deep_merge(super(), {
|
||||
'uid' => response.display_identifier,
|
||||
'user_info' => user_info(response.display_identifier, ::OpenID::SReg::Response.from_success_response(response))
|
||||
'user_info' => user_info(response)
|
||||
})
|
||||
end
|
||||
|
||||
def user_info(identifier, sreg)
|
||||
def user_info(response)
|
||||
sreg_user_info(response).merge(ax_user_info(response))
|
||||
end
|
||||
|
||||
def sreg_user_info(response)
|
||||
sreg = ::OpenID::SReg::Response.from_success_response(response)
|
||||
return {} unless sreg
|
||||
{
|
||||
'email' => sreg['email'],
|
||||
'name' => sreg['fullname'],
|
||||
'location' => sreg['postcode'],
|
||||
'nickname' => sreg['nickname'],
|
||||
'urls' => {'Profile' => identifier}
|
||||
'nickname' => sreg['nickname']
|
||||
}.reject{|k,v| v.nil? || v == ''}
|
||||
end
|
||||
|
||||
def ax_user_info(response)
|
||||
ax = ::OpenID::AX::FetchResponse.from_success_response(response)
|
||||
return {} unless ax
|
||||
{
|
||||
'email' => ax[AX[:email]],
|
||||
'name' => ax[AX[:name]],
|
||||
'location' => ("#{ax[AX[:city]]}, #{ax[AX[:state]]}" if Array(ax[AX[:city]]).any? && Array(ax[AX[:state]]).any?),
|
||||
'nickname' => ax[AX[:nickname]],
|
||||
'urls' => ({'Website' => Array(ax[AX[:website]]).first} if Array(ax[AX[:website]]).any?)
|
||||
}.inject({}){|h,(k,v)| h[k] = Array(v).first; h}.reject{|k,v| v.nil? || v == ''}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|||
gem.summary = %Q{OpenID strategies for OmniAuth.}
|
||||
gem.description = %Q{OpenID strategies for OmniAuth.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omni_auth"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
|
0
omniauth/CHANGELOG.rdoc
Normal file
0
omniauth/CHANGELOG.rdoc
Normal file
0
omniauth/LICENSE.rdoc
Normal file
0
omniauth/LICENSE.rdoc
Normal file
|
@ -1,9 +1,5 @@
|
|||
require 'omniauth/core'
|
||||
|
||||
%w(password oauth basic openid).each do |s|
|
||||
begin
|
||||
require "omniauth/#{s}"
|
||||
rescue LoadError
|
||||
puts "Unable to find the files for oa-#{s}, ignored it."
|
||||
end
|
||||
%w(password oauth basic openid facebook).each do |s|
|
||||
require "omniauth/#{s}"
|
||||
end
|
|
@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|||
gem.summary = %Q{Rack middleware for standardized multi-provider authentication.}
|
||||
gem.description = %Q{OmniAuth is an authentication framework that that separates the concept of authentiation from the concept of identity, providing simple hooks for any application to have one or multiple authentication providers for a user.}
|
||||
gem.email = "michael@intridea.com"
|
||||
gem.homepage = "http://github.com/intridea/omni_auth"
|
||||
gem.homepage = "http://github.com/intridea/omniauth"
|
||||
gem.authors = ["Michael Bleigh"]
|
||||
|
||||
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE.rdoc CHANGELOG.rdoc)
|
||||
|
|
Loading…
Reference in a new issue