jspooner-authlogic-connect 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.markdown +234 -0
- data/Rakefile +85 -0
- data/init.rb +1 -0
- data/lib/authlogic-connect.rb +39 -0
- data/lib/authlogic_connect/access_token.rb +61 -0
- data/lib/authlogic_connect/authlogic_connect.rb +46 -0
- data/lib/authlogic_connect/callback_filter.rb +19 -0
- data/lib/authlogic_connect/common/session.rb +30 -0
- data/lib/authlogic_connect/common/state.rb +45 -0
- data/lib/authlogic_connect/common/user.rb +77 -0
- data/lib/authlogic_connect/common/variables.rb +124 -0
- data/lib/authlogic_connect/common.rb +10 -0
- data/lib/authlogic_connect/engine.rb +14 -0
- data/lib/authlogic_connect/ext.rb +56 -0
- data/lib/authlogic_connect/oauth/helper.rb +20 -0
- data/lib/authlogic_connect/oauth/process.rb +77 -0
- data/lib/authlogic_connect/oauth/session.rb +90 -0
- data/lib/authlogic_connect/oauth/state.rb +60 -0
- data/lib/authlogic_connect/oauth/tokens/aol_token.rb +2 -0
- data/lib/authlogic_connect/oauth/tokens/facebook_token.rb +11 -0
- data/lib/authlogic_connect/oauth/tokens/foursquare_token.rb +15 -0
- data/lib/authlogic_connect/oauth/tokens/get_satisfaction_token.rb +9 -0
- data/lib/authlogic_connect/oauth/tokens/github_token.rb +14 -0
- data/lib/authlogic_connect/oauth/tokens/google_token.rb +41 -0
- data/lib/authlogic_connect/oauth/tokens/linked_in_token.rb +19 -0
- data/lib/authlogic_connect/oauth/tokens/meetup_token.rb +12 -0
- data/lib/authlogic_connect/oauth/tokens/myspace_token.rb +26 -0
- data/lib/authlogic_connect/oauth/tokens/netflix_token.rb +10 -0
- data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +164 -0
- data/lib/authlogic_connect/oauth/tokens/ohloh_token.rb +9 -0
- data/lib/authlogic_connect/oauth/tokens/opensocial_token.rb +0 -0
- data/lib/authlogic_connect/oauth/tokens/twitter_token.rb +8 -0
- data/lib/authlogic_connect/oauth/tokens/vimeo_token.rb +18 -0
- data/lib/authlogic_connect/oauth/tokens/yahoo_token.rb +19 -0
- data/lib/authlogic_connect/oauth/user.rb +64 -0
- data/lib/authlogic_connect/oauth/variables.rb +64 -0
- data/lib/authlogic_connect/oauth.rb +14 -0
- data/lib/authlogic_connect/openid/process.rb +74 -0
- data/lib/authlogic_connect/openid/session.rb +56 -0
- data/lib/authlogic_connect/openid/state.rb +48 -0
- data/lib/authlogic_connect/openid/tokens/aol_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/blogger_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/flickr_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/my_openid_token.rb +3 -0
- data/lib/authlogic_connect/openid/tokens/openid_token.rb +9 -0
- data/lib/authlogic_connect/openid/user.rb +38 -0
- data/lib/authlogic_connect/openid/variables.rb +19 -0
- data/lib/authlogic_connect/openid.rb +11 -0
- data/lib/authlogic_connect/rack_state.rb +19 -0
- data/lib/open_id_authentication.rb +127 -0
- data/rails/init.rb +19 -0
- data/test/controllers/test_users_controller.rb +21 -0
- data/test/libs/database.rb +47 -0
- data/test/libs/user.rb +7 -0
- data/test/libs/user_session.rb +2 -0
- data/test/test_helper.rb +178 -0
- data/test/test_oauth.rb +178 -0
- data/test/test_openid.rb +71 -0
- data/test/test_user.rb +85 -0
- metadata +243 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
module AuthlogicConnect::Common::Variables
|
2
|
+
include AuthlogicConnect::Common::State
|
3
|
+
|
4
|
+
attr_reader :processing_authentication
|
5
|
+
|
6
|
+
def auth_class
|
7
|
+
is_auth_session? ? self.class : session_class
|
8
|
+
end
|
9
|
+
|
10
|
+
def auth_controller
|
11
|
+
is_auth_session? ? controller : session_class.controller
|
12
|
+
end
|
13
|
+
|
14
|
+
def auth_params
|
15
|
+
return nil unless auth_controller?
|
16
|
+
auth_controller.params.symbolize_keys!
|
17
|
+
auth_controller.params.keys.each do |key|
|
18
|
+
auth_controller.params[key.to_s] = auth_controller.params.delete(key) if key.to_s =~ /^OpenID/
|
19
|
+
end
|
20
|
+
auth_controller.params
|
21
|
+
end
|
22
|
+
|
23
|
+
def auth_session
|
24
|
+
return nil unless auth_controller?
|
25
|
+
auth_controller.session.symbolize_keys!
|
26
|
+
auth_controller.session.keys.each do |key|
|
27
|
+
auth_controller.session[key.to_s] = auth_controller.session.delete(key) if key.to_s =~ /^OpenID/
|
28
|
+
end
|
29
|
+
auth_controller.session
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth_callback_url(options = {})
|
33
|
+
auth_controller.url_for({:controller => auth_controller.controller_name, :action => auth_controller.action_name}.merge(options))
|
34
|
+
end
|
35
|
+
|
36
|
+
# if we've said it's a "user" (registration), or a "session" (login)
|
37
|
+
def auth_type
|
38
|
+
from_session_or_params(:authentication_type)
|
39
|
+
end
|
40
|
+
|
41
|
+
# auth_params and auth_session attributes are all String!
|
42
|
+
def from_session_or_params(attribute)
|
43
|
+
return nil unless auth_controller?
|
44
|
+
key = attribute.is_a?(Symbol) ? attribute : attribute.to_sym
|
45
|
+
result = auth_params[key] if (auth_params && auth_params[key])
|
46
|
+
result = auth_session[key] if (result.nil? || result.blank?)
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_session_key(key, value)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_session_key(key)
|
55
|
+
keys = key.is_a?(Symbol) ? [key, key.to_s] : [key, key.to_sym]
|
56
|
+
keys.each {|k| auth_session.delete(k)}
|
57
|
+
end
|
58
|
+
|
59
|
+
# wraps the call to "save" (in yield).
|
60
|
+
# reason being, we need to somehow not allow oauth/openid validations to run
|
61
|
+
# when we don't have a block. We can't know that using class methods, so we create
|
62
|
+
# this property "processing_authentication", which is used in the validation method.
|
63
|
+
# it's value is set to "block_given", which is the value of block_given?
|
64
|
+
def authenticate_via_protocol(block_given = false, options = {}, &block)
|
65
|
+
@processing_authentication = auth_controller? && block_given
|
66
|
+
saved = yield start_authentication?
|
67
|
+
@processing_authentication = false
|
68
|
+
saved
|
69
|
+
end
|
70
|
+
|
71
|
+
# returns boolean
|
72
|
+
def authentication_protocol(with, phase)
|
73
|
+
returning(send("#{phase.to_s}_#{with.to_s}?")) do |ready|
|
74
|
+
send("#{phase.to_s}_#{with.to_s}") if ready
|
75
|
+
end if send("using_#{with.to_s}?")
|
76
|
+
end
|
77
|
+
|
78
|
+
# it only reaches this point once it has returned, or you
|
79
|
+
# have manually skipped the redirect and save was called directly.
|
80
|
+
def cleanup_authentication_session(options = {}, &block)
|
81
|
+
unless (options.has_key?(:keep_session) && options[:keep_session])
|
82
|
+
%w(oauth openid).each do |type|
|
83
|
+
send("cleanup_#{type.to_s}_session")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def log(*methods)
|
89
|
+
methods.each do |method|
|
90
|
+
puts "#{method.to_s}: #{send(method).inspect}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_state
|
95
|
+
log(:correct_request_class?)
|
96
|
+
log(:using_oauth?, :start_oauth?, :complete_oauth?)
|
97
|
+
log(:oauth_request?, :oauth_response?, :stored_oauth_token_and_secret?)
|
98
|
+
log(:using_openid?, :start_openid?, :complete_openid?, :openid_request?, :openid_response?)
|
99
|
+
log(:authenticating_with_openid?)
|
100
|
+
log(:stored_oauth_token_and_secret)
|
101
|
+
end
|
102
|
+
|
103
|
+
# because we may need to store 6+ session variables, all with pretty lengthy names,
|
104
|
+
# might as well just tinify them.
|
105
|
+
# just an idea
|
106
|
+
def optimized_session_key(key)
|
107
|
+
@optimized_session_keys ||= {
|
108
|
+
:auth_request_class => :authcl,
|
109
|
+
:authentication_method => :authme,
|
110
|
+
:authentication_type => :authty,
|
111
|
+
:oauth_provider => :authpr,
|
112
|
+
:auth_callback_method => :authcb,
|
113
|
+
:oauth_request_token => :authtk,
|
114
|
+
:oauth_request_token_secret => :authsc,
|
115
|
+
:auth_attributes => :authat
|
116
|
+
}
|
117
|
+
@optimized_session_keys[key]
|
118
|
+
end
|
119
|
+
|
120
|
+
def auto_register?
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module AuthlogicConnect::Common
|
2
|
+
end
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/common/state"
|
5
|
+
require File.dirname(__FILE__) + "/common/variables"
|
6
|
+
require File.dirname(__FILE__) + "/common/user"
|
7
|
+
require File.dirname(__FILE__) + "/common/session"
|
8
|
+
|
9
|
+
ActiveRecord::Base.send(:include, AuthlogicConnect::Common::User)
|
10
|
+
Authlogic::Session::Base.send(:include, AuthlogicConnect::Common::Session)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module AuthlogicConnect
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
|
4
|
+
initializer "authlogic_connect.authentication_hook" do |app|
|
5
|
+
app.middleware.use AuthlogicConnect::CallbackFilter
|
6
|
+
app.middleware.use OpenIdAuthentication
|
7
|
+
end
|
8
|
+
|
9
|
+
initializer "authlogic_connect.finalize", :after => "authlogic_connect.authentication_hook" do |app|
|
10
|
+
OpenID::Util.logger = Rails.logger
|
11
|
+
ActionController::Base.send :include, OpenIdAuthentication
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# these are extensions I've found useful for this project
|
2
|
+
class String
|
3
|
+
# normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
|
4
|
+
def normalize_identifier
|
5
|
+
# clean up whitespace
|
6
|
+
identifier = self.dup.strip
|
7
|
+
|
8
|
+
# if an XRI has a prefix, strip it.
|
9
|
+
identifier.gsub!(/xri:\/\//i, '')
|
10
|
+
|
11
|
+
# dodge XRIs -- TODO: validate, don't just skip.
|
12
|
+
unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
|
13
|
+
# does it begin with http? if not, add it.
|
14
|
+
identifier = "http://#{identifier}" unless identifier =~ /^http/i
|
15
|
+
|
16
|
+
# strip any fragments
|
17
|
+
identifier.gsub!(/\#(.*)$/, '')
|
18
|
+
|
19
|
+
begin
|
20
|
+
uri = URI.parse(identifier)
|
21
|
+
uri.scheme = uri.scheme.downcase # URI should do this
|
22
|
+
identifier = uri.normalize.to_s
|
23
|
+
rescue URI::InvalidURIError
|
24
|
+
raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return identifier
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
def recursively_symbolize_keys!
|
34
|
+
self.symbolize_keys!
|
35
|
+
self.values.each do |v|
|
36
|
+
if v.is_a? Hash
|
37
|
+
v.recursively_symbolize_keys!
|
38
|
+
elsif v.is_a? Array
|
39
|
+
v.recursively_symbolize_keys!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Array
|
47
|
+
def recursively_symbolize_keys!
|
48
|
+
self.each do |item|
|
49
|
+
if item.is_a? Hash
|
50
|
+
item.recursively_symbolize_keys!
|
51
|
+
elsif item.is_a? Array
|
52
|
+
item.recursively_symbolize_keys!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module AuthlogicConnect::Oauth::Helper
|
2
|
+
|
3
|
+
# options include "name"
|
4
|
+
def oauth_register_hidden_input
|
5
|
+
oauth_input(:type => "user")
|
6
|
+
end
|
7
|
+
|
8
|
+
def oauth_login_hidden_input
|
9
|
+
oauth_input(:type => "session")
|
10
|
+
end
|
11
|
+
|
12
|
+
def oauth_input(options = {})
|
13
|
+
tag(:input, {:type => "hidden", :name => "authentication_type", :value => options[:type]})
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
module AuthlogicConnect::Oauth::FormHelper
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module AuthlogicConnect::Oauth::Process
|
2
|
+
|
3
|
+
include AuthlogicConnect::Oauth::Variables
|
4
|
+
|
5
|
+
# Step 2: after save is called, it runs this method for validation
|
6
|
+
def validate_by_oauth
|
7
|
+
if processing_authentication
|
8
|
+
authentication_protocol(:oauth, :start) || authentication_protocol(:oauth, :complete)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Step 3: if new_oauth_request?, redirect to oauth provider
|
13
|
+
def start_oauth
|
14
|
+
save_oauth_session
|
15
|
+
authorize_url = token_class.authorize_url(auth_callback_url) do |request_token|
|
16
|
+
request_token.display = "popup"
|
17
|
+
save_auth_session_token(request_token) # only for oauth version 1
|
18
|
+
end
|
19
|
+
puts "4 AAAAAAAAAA ----------------- authorize_url #{authorize_url}"
|
20
|
+
auth_controller.redirect_to authorize_url
|
21
|
+
end
|
22
|
+
|
23
|
+
# Step 4: on callback, run this method
|
24
|
+
def complete_oauth
|
25
|
+
# implemented in User and Session Oauth modules
|
26
|
+
unless new_oauth_request? # shouldn't be validating if it's redirecting...
|
27
|
+
restore_attributes
|
28
|
+
complete_oauth_transaction
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
# Step 3a: save our passed-parameters into the session,
|
35
|
+
# so we can retrieve them after the redirect calls back
|
36
|
+
def save_oauth_session
|
37
|
+
# Store the class which is redirecting, so we can ensure other classes
|
38
|
+
# don't get confused and attempt to use the response
|
39
|
+
auth_session[:auth_request_class] = self.class.name
|
40
|
+
|
41
|
+
auth_session[:authentication_type] = auth_params[:authentication_type]
|
42
|
+
auth_session[:oauth_provider] = auth_params[:oauth_provider]
|
43
|
+
auth_session[:auth_method] = "oauth"
|
44
|
+
|
45
|
+
# Tell our rack callback filter what method the current request is using
|
46
|
+
auth_session[:auth_callback_method] = auth_controller.request.method
|
47
|
+
end
|
48
|
+
|
49
|
+
# Step 3b (if version 1.0 of oauth)
|
50
|
+
def save_auth_session_token(request)
|
51
|
+
# store token and secret
|
52
|
+
auth_session[:oauth_request_token] = request.token
|
53
|
+
auth_session[:oauth_request_token_secret] = request.secret
|
54
|
+
end
|
55
|
+
|
56
|
+
def restore_attributes
|
57
|
+
end
|
58
|
+
|
59
|
+
# Step last, after the response
|
60
|
+
# having lots of trouble testing logging and out multiple times,
|
61
|
+
# so there needs to be a solid way to know when a user has messed up loggin in.
|
62
|
+
def cleanup_oauth_session
|
63
|
+
[:auth_request_class,
|
64
|
+
:authentication_type,
|
65
|
+
:auth_method,
|
66
|
+
:auth_attributes,
|
67
|
+
:oauth_provider,
|
68
|
+
:auth_callback_method,
|
69
|
+
:oauth_request_token,
|
70
|
+
:oauth_request_token_secret,
|
71
|
+
:_key,
|
72
|
+
:_token,
|
73
|
+
:_secret,
|
74
|
+
].each {|key| remove_session_key(key)}
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module AuthlogicConnect::Oauth
|
2
|
+
# This module is responsible for adding oauth
|
3
|
+
# to the Authlogic::Session::Base class.
|
4
|
+
module Session
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
include InstanceMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
include Process
|
13
|
+
|
14
|
+
def self.included(klass)
|
15
|
+
klass.class_eval do
|
16
|
+
validate :validate_by_oauth, :if => :authenticating_with_oauth?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Hooks into credentials so that you can pass a user who has already has an oauth access token.
|
21
|
+
def credentials=(value)
|
22
|
+
super
|
23
|
+
values = value.is_a?(Array) ? value : [value]
|
24
|
+
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
|
25
|
+
self.record = hash[:priority_record] if !hash.nil? && hash.key?(:priority_record)
|
26
|
+
end
|
27
|
+
|
28
|
+
def record=(record)
|
29
|
+
@record = record
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def complete_oauth_transaction
|
35
|
+
if @record
|
36
|
+
self.attempted_record = record
|
37
|
+
else
|
38
|
+
# this generated token is always the same for a user!
|
39
|
+
# this is searching with User.find ...
|
40
|
+
# attempted_record is part of AuthLogic
|
41
|
+
hash = oauth_token_and_secret
|
42
|
+
puts "////////////////////////// OAUTH"
|
43
|
+
puts "////////////////////////// OAUTH #{hash}"
|
44
|
+
puts "////////////////////////// OAUTH.inspect #{hash.inspect}"
|
45
|
+
puts "////////////////////////// hash[:key] #{hash[:key]}"
|
46
|
+
puts "////////////////////////// hash[:token] #{hash[:token]}"
|
47
|
+
token = token_class.find_by_key_or_token(hash[:key], hash[:token], :include => [:user]) # some weird error if I leave out the include)
|
48
|
+
if token
|
49
|
+
self.attempted_record = token.user
|
50
|
+
elsif auto_register?
|
51
|
+
self.attempted_record = klass.new
|
52
|
+
self.attempted_record.access_tokens << token_class.new(hash)
|
53
|
+
|
54
|
+
puts "////////////// FACEBOOK TOKEN??? #{self.attempted_record.get_token(:facebook)}"
|
55
|
+
puts "////////////// FACEBOOK TOKEN??? #{self.attempted_record.get_token(:facebook).inspect}"
|
56
|
+
# If it's a facebook token lets look up the users email address
|
57
|
+
if self.attempted_record.has_token?(:facebook)
|
58
|
+
self.attempted_record.active_token = self.attempted_record.get_token(:facebook)
|
59
|
+
facebook = JSON.parse(self.attempted_record.active_token.get("/me"))
|
60
|
+
puts "////////////// FACEBOOK DETAILS #{facebook.inspect}"
|
61
|
+
puts "////////////// FACEBOOK EMAIL #{facebook[:email]}"
|
62
|
+
if facebook[:email]
|
63
|
+
existing_user = klass.find_by_email(facebook[:email])
|
64
|
+
puts "////////////// FACEBOOK DETAILS YES YES YES YES #{existing_user} #{existing_user.inspect}"
|
65
|
+
if existing_user
|
66
|
+
# It would be nice to place this app specific code somewhere else
|
67
|
+
self.attempted_record = existing_user
|
68
|
+
self.attempted_record.access_tokens << token_class.new(hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
self.attempted_record.first_name = facebook[:first_name] if !facebook[:first_name].nil? and !self.attempted_record.first_name.nil?
|
72
|
+
self.attempted_record.last_name = facebook[:last_name] if !facebook[:last_name].nil? and !self.attempted_record.last_name.nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
self.attempted_record.save
|
77
|
+
else
|
78
|
+
auth_session[:_key] = hash[:key]
|
79
|
+
auth_session[:_token] = hash[:token]
|
80
|
+
auth_session[:_secret] = hash[:secret]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if !attempted_record
|
85
|
+
errors.add(:user, "Could not find user in our database, have you registered with your oauth account?")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# all these methods must return true or false
|
2
|
+
module AuthlogicConnect::Oauth::State
|
3
|
+
|
4
|
+
# 1. to call
|
5
|
+
# checks that we just passed parameters to it,
|
6
|
+
# and that the parameters say 'authentication_method' == 'oauth'
|
7
|
+
def oauth_request?
|
8
|
+
auth_params? && oauth_provider?
|
9
|
+
end
|
10
|
+
|
11
|
+
# 2. from call
|
12
|
+
# checks that the correct session variables are there
|
13
|
+
def oauth_response?
|
14
|
+
!oauth_response.nil? && auth_session? && auth_session[:auth_request_class] == self.class.name && auth_session[:auth_method] == "oauth"
|
15
|
+
end
|
16
|
+
|
17
|
+
def oauth_complete?
|
18
|
+
oauth_response? || stored_oauth_token_and_secret?
|
19
|
+
end
|
20
|
+
|
21
|
+
# 3. either to or from call
|
22
|
+
def using_oauth?
|
23
|
+
oauth_request? || oauth_response? || stored_oauth_token_and_secret?
|
24
|
+
end
|
25
|
+
|
26
|
+
def new_oauth_request?
|
27
|
+
return false if stored_oauth_token_and_secret?
|
28
|
+
return oauth_response.blank?
|
29
|
+
end
|
30
|
+
|
31
|
+
def oauth_provider?
|
32
|
+
!oauth_provider.blank?
|
33
|
+
end
|
34
|
+
|
35
|
+
# main method we call on validation
|
36
|
+
def authenticating_with_oauth?
|
37
|
+
correct_request_class? && using_oauth?
|
38
|
+
end
|
39
|
+
|
40
|
+
def allow_oauth_redirect?
|
41
|
+
authenticating_with_oauth? && !oauth_complete?
|
42
|
+
end
|
43
|
+
|
44
|
+
def start_oauth?
|
45
|
+
authenticating_with_oauth? && !oauth_complete?
|
46
|
+
end
|
47
|
+
|
48
|
+
def complete_oauth?
|
49
|
+
using_oauth? && !new_oauth_request?
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_password_with_oauth?
|
53
|
+
!using_oauth? && require_password?
|
54
|
+
end
|
55
|
+
|
56
|
+
def stored_oauth_token_and_secret?
|
57
|
+
!is_auth_session? && auth_params? && auth_params.has_key?(:_key) && auth_params.has_key?(:_token) && auth_params.has_key?(:_secret)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# http://www.facebook.com/developers/apps.php
|
2
|
+
# http://developers.facebook.com/setup/
|
3
|
+
class FacebookToken < OauthToken
|
4
|
+
|
5
|
+
version 2.0
|
6
|
+
|
7
|
+
settings "https://graph.facebook.com",
|
8
|
+
:authorize_url => "https://graph.facebook.com/oauth/authorize",
|
9
|
+
:scope => "email, offline_access"
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class FoursquareToken < OauthToken
|
2
|
+
|
3
|
+
key do |access_token|
|
4
|
+
body = JSON.parse(access_token.get("/user.json").body)
|
5
|
+
user_id = body['user']['id'].to_s
|
6
|
+
end
|
7
|
+
|
8
|
+
settings "http://api.foursquare.com/:api_version",
|
9
|
+
:request_token_url => "http://foursquare.com/oauth/request_token",
|
10
|
+
:access_token_url => "http://foursquare.com/oauth/access_token",
|
11
|
+
:authorize_url => "http://foursquare.com/oauth/authorize",
|
12
|
+
:api_versions => {1 => "v1", 2 => "v2"},
|
13
|
+
:api_version => 1
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# http://getsatisfaction.com/developers/oauth
|
2
|
+
class GetSatisfactionToken < OauthToken
|
3
|
+
|
4
|
+
settings "http://getsatisfaction.com",
|
5
|
+
:request_token_path => "/api/request_token",
|
6
|
+
:authorize_url => "/api/authorize",
|
7
|
+
:access_token_path => "/api/access_token"
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class GithubToken < OauthToken
|
2
|
+
|
3
|
+
version 2
|
4
|
+
|
5
|
+
key do |access_token|
|
6
|
+
user = JSON.parse(access_token.get("/api/v2/json/user/show"))
|
7
|
+
user["id"]
|
8
|
+
end
|
9
|
+
|
10
|
+
settings "https://github.com",
|
11
|
+
:authorize_path => "/login/oauth/authorize",
|
12
|
+
:access_token_path => "/login/oauth/access_token"
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# http://code.google.com/apis/accounts/docs/OAuth_ref.html
|
2
|
+
# http://code.google.com/apis/accounts/docs/OpenID.html#settingup
|
3
|
+
# http://code.google.com/apis/accounts/docs/OAuth.html
|
4
|
+
# http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
|
5
|
+
# http://www.manu-j.com/blog/add-google-oauth-ruby-on-rails-sites/214/
|
6
|
+
# http://googlecodesamples.com/oauth_playground/
|
7
|
+
# Scopes:
|
8
|
+
# Analytics https://www.google.com/analytics/feeds/
|
9
|
+
# Google Base http://www.google.com/base/feeds/
|
10
|
+
# Book Search http://www.google.com/books/feeds/
|
11
|
+
# Blogger http://www.blogger.com/feeds/
|
12
|
+
# Calendar http://www.google.com/calendar/feeds/
|
13
|
+
# Contacts http://www.google.com/m8/feeds/
|
14
|
+
# Documents List http://docs.google.com/feeds/
|
15
|
+
# Finance http://finance.google.com/finance/feeds/
|
16
|
+
# GMail https://mail.google.com/mail/feed/atom
|
17
|
+
# Health https://www.google.com/health/feeds/
|
18
|
+
# H9 https://www.google.com/h9/feeds/
|
19
|
+
# Maps http://maps.google.com/maps/feeds/
|
20
|
+
# OpenSocial http://www-opensocial.googleusercontent.com/api/people/
|
21
|
+
# orkut http://www.orkut.com/social/rest
|
22
|
+
# Picasa Web http://picasaweb.google.com/data/
|
23
|
+
# Sidewiki http://www.google.com/sidewiki/feeds/
|
24
|
+
# Sites http://sites.google.com/feeds/
|
25
|
+
# Spreadsheets http://spreadsheets.google.com/feeds/
|
26
|
+
# Webmaster Tools http://www.google.com/webmasters/tools/feeds/
|
27
|
+
# YouTube http://gdata.youtube.com
|
28
|
+
class GoogleToken < OauthToken
|
29
|
+
|
30
|
+
settings "https://www.google.com",
|
31
|
+
:request_token_path => "/accounts/OAuthGetRequestToken",
|
32
|
+
:authorize_path => "/accounts/OAuthAuthorizeToken",
|
33
|
+
:access_token_path => "/accounts/OAuthGetAccessToken",
|
34
|
+
:scope => "https://www.googleapis.com/auth/userinfo#email"
|
35
|
+
|
36
|
+
key do |access_token|
|
37
|
+
body = JSON.parse(access_token.get("https://www.googleapis.com/userinfo/email?alt=json").body)
|
38
|
+
email = body["data"]["email"]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# http://developer.linkedin.com/docs/DOC-1008
|
2
|
+
# https://www.linkedin.com/secure/developer
|
3
|
+
# http://github.com/pengwynn/linkedin/tree/master/lib/linked_in/
|
4
|
+
class LinkedInToken < OauthToken
|
5
|
+
|
6
|
+
key do |access_token|
|
7
|
+
body = access_token.get("https://api.linkedin.com/v1/people/~:(id)").body
|
8
|
+
id = body.gsub("<id>([^><]+)</id>", "\\1") # so we don't need to also import nokogiri
|
9
|
+
id
|
10
|
+
end
|
11
|
+
|
12
|
+
settings "https://api.linkedin.com",
|
13
|
+
:request_token_path => "/uas/oauth/requestToken",
|
14
|
+
:access_token_path => "/uas/oauth/accessToken",
|
15
|
+
:authorize_path => "/uas/oauth/authorize",
|
16
|
+
:http_method => "get",
|
17
|
+
:scheme => :query_string
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# http://www.meetup.com/meetup_api/docs/#oauth
|
2
|
+
# protected resources: http://api.meetup.com
|
3
|
+
class MeetupToken < OauthToken
|
4
|
+
|
5
|
+
key :user_id
|
6
|
+
|
7
|
+
settings "http://www.meetup.com/"
|
8
|
+
:request_token_path => "/oauth/request",
|
9
|
+
:authorize_path => "/authorize",
|
10
|
+
:access_token_path => "/oauth/access"
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# http://wiki.developer.myspace.com/index.php?title=Category:MySpaceID
|
2
|
+
# http://developerwiki.myspace.com/index.php?title=OAuth_REST_API_Usage_-_Authentication_Process
|
3
|
+
# http://developerwiki.myspace.com/index.php?title=How_to_Set_Up_a_New_Application_for_OpenID
|
4
|
+
# http://developer.myspace.com/Modules/Apps/Pages/ApplyDevSandbox.aspx
|
5
|
+
# after you've signed up:
|
6
|
+
# http://developer.myspace.com/modules/apps/pages/createappaccount.aspx
|
7
|
+
# "Create a MySpaceID App"
|
8
|
+
# http://developer.myspace.com/modules/apps/pages/editapp.aspx?appid=188312&mode=create
|
9
|
+
# http://developer.myspace.com/Modules/APIs/Pages/OAuthTool.aspx
|
10
|
+
# http://developer.myspace.com/Community/forums/p/3626/15947.aspx
|
11
|
+
class MyspaceToken < OauthToken
|
12
|
+
|
13
|
+
# http://wiki.developer.myspace.com/index.php?title=Portable_Contacts_REST_Resources
|
14
|
+
key do |access_token|
|
15
|
+
body = JSON.parse(access_token.get("/v2/people/@me/@self?format=json").body)
|
16
|
+
id = body["entry"]["id"]
|
17
|
+
end
|
18
|
+
|
19
|
+
settings "http://api.myspace.com",
|
20
|
+
:request_token_path => "/request_token",
|
21
|
+
:authorize_path => "/authorize",
|
22
|
+
:access_token_path => "/access_token",
|
23
|
+
:http_method => "get",
|
24
|
+
:scheme => :query_string
|
25
|
+
|
26
|
+
end
|