Skip to content

Commit

Permalink
Adds lots of stuff. Facebook is broken, beware.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Bleigh committed Apr 10, 2010
1 parent 349cfc3 commit f9dc9ea
Show file tree
Hide file tree
Showing 31 changed files with 250 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ rdoc
pkg

## PROJECT::SPECIFIC
*.gem
4 changes: 3 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -15,4 +15,6 @@ task :spec do
end
end
end

task :default => :spec

Empty file added oa-basic/CHANGELOG.rdoc
Empty file.
Empty file added oa-basic/LICENSE.rdoc
Empty file.
Empty file added oa-basic/README.rdoc
Empty file.
2 changes: 1 addition & 1 deletion oa-basic/oa-basic.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Empty file added oa-core/CHANGELOG.rdoc
Empty file.
Empty file added oa-core/LICENSE.rdoc
Empty file.
Empty file added oa-core/README.rdoc
Empty file.
13 changes: 9 additions & 4 deletions oa-core/lib/omniauth/strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ def initialize(app, name, *args)
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

Expand All @@ -31,7 +35,8 @@ def request_phase
end

def callback_phase
raise NotImplementedError
request['auth'] = auth_hash
@app.call(env)
end

def auth_hash
Expand Down
4 changes: 2 additions & 2 deletions oa-core/oa-core.gemspec
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
Empty file added oa-facebook/CHANGELOG.rdoc
Empty file.
Empty file added oa-facebook/LICENSE.rdoc
Empty file.
Empty file added oa-facebook/README.rdoc
Empty file.
13 changes: 13 additions & 0 deletions oa-facebook/Rakefile
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions oa-facebook/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
3 changes: 3 additions & 0 deletions oa-facebook/lib/omniauth/facebook.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'omniauth/core'
require 'omniauth/strategies/facebook'
require 'mini_fb'
128 changes: 128 additions & 0 deletions oa-facebook/lib/omniauth/strategies/facebook.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions oa-facebook/oa-facebook.gemspec
Original file line number Diff line number Diff line change
@@ -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
Empty file added oa-facebook/spec/spec_helper.rb
Empty file.
2 changes: 1 addition & 1 deletion oa-oauth/oa-oauth.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Empty file added oa-openid/CHANGELOG.rdoc
Empty file.
Empty file added oa-openid/LICENSE.rdoc
Empty file.
Empty file added oa-openid/README.rdoc
Empty file.
7 changes: 7 additions & 0 deletions oa-openid/lib/omniauth/strategies/google.rb
Original file line number Diff line number Diff line change
@@ -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
67 changes: 56 additions & 11 deletions oa-openid/lib/omniauth/strategies/open_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,55 @@ module Strategies
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
Expand All @@ -45,19 +73,36 @@ def callback_phase
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
2 changes: 1 addition & 1 deletion oa-openid/oa-openid.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Empty file added omniauth/CHANGELOG.rdoc
Empty file.
Empty file added omniauth/LICENSE.rdoc
Empty file.
Loading

0 comments on commit f9dc9ea

Please sign in to comment.