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.
Files changed (61) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +234 -0
  3. data/Rakefile +85 -0
  4. data/init.rb +1 -0
  5. data/lib/authlogic-connect.rb +39 -0
  6. data/lib/authlogic_connect/access_token.rb +61 -0
  7. data/lib/authlogic_connect/authlogic_connect.rb +46 -0
  8. data/lib/authlogic_connect/callback_filter.rb +19 -0
  9. data/lib/authlogic_connect/common/session.rb +30 -0
  10. data/lib/authlogic_connect/common/state.rb +45 -0
  11. data/lib/authlogic_connect/common/user.rb +77 -0
  12. data/lib/authlogic_connect/common/variables.rb +124 -0
  13. data/lib/authlogic_connect/common.rb +10 -0
  14. data/lib/authlogic_connect/engine.rb +14 -0
  15. data/lib/authlogic_connect/ext.rb +56 -0
  16. data/lib/authlogic_connect/oauth/helper.rb +20 -0
  17. data/lib/authlogic_connect/oauth/process.rb +77 -0
  18. data/lib/authlogic_connect/oauth/session.rb +90 -0
  19. data/lib/authlogic_connect/oauth/state.rb +60 -0
  20. data/lib/authlogic_connect/oauth/tokens/aol_token.rb +2 -0
  21. data/lib/authlogic_connect/oauth/tokens/facebook_token.rb +11 -0
  22. data/lib/authlogic_connect/oauth/tokens/foursquare_token.rb +15 -0
  23. data/lib/authlogic_connect/oauth/tokens/get_satisfaction_token.rb +9 -0
  24. data/lib/authlogic_connect/oauth/tokens/github_token.rb +14 -0
  25. data/lib/authlogic_connect/oauth/tokens/google_token.rb +41 -0
  26. data/lib/authlogic_connect/oauth/tokens/linked_in_token.rb +19 -0
  27. data/lib/authlogic_connect/oauth/tokens/meetup_token.rb +12 -0
  28. data/lib/authlogic_connect/oauth/tokens/myspace_token.rb +26 -0
  29. data/lib/authlogic_connect/oauth/tokens/netflix_token.rb +10 -0
  30. data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +164 -0
  31. data/lib/authlogic_connect/oauth/tokens/ohloh_token.rb +9 -0
  32. data/lib/authlogic_connect/oauth/tokens/opensocial_token.rb +0 -0
  33. data/lib/authlogic_connect/oauth/tokens/twitter_token.rb +8 -0
  34. data/lib/authlogic_connect/oauth/tokens/vimeo_token.rb +18 -0
  35. data/lib/authlogic_connect/oauth/tokens/yahoo_token.rb +19 -0
  36. data/lib/authlogic_connect/oauth/user.rb +64 -0
  37. data/lib/authlogic_connect/oauth/variables.rb +64 -0
  38. data/lib/authlogic_connect/oauth.rb +14 -0
  39. data/lib/authlogic_connect/openid/process.rb +74 -0
  40. data/lib/authlogic_connect/openid/session.rb +56 -0
  41. data/lib/authlogic_connect/openid/state.rb +48 -0
  42. data/lib/authlogic_connect/openid/tokens/aol_token.rb +0 -0
  43. data/lib/authlogic_connect/openid/tokens/blogger_token.rb +0 -0
  44. data/lib/authlogic_connect/openid/tokens/flickr_token.rb +0 -0
  45. data/lib/authlogic_connect/openid/tokens/my_openid_token.rb +3 -0
  46. data/lib/authlogic_connect/openid/tokens/openid_token.rb +9 -0
  47. data/lib/authlogic_connect/openid/user.rb +38 -0
  48. data/lib/authlogic_connect/openid/variables.rb +19 -0
  49. data/lib/authlogic_connect/openid.rb +11 -0
  50. data/lib/authlogic_connect/rack_state.rb +19 -0
  51. data/lib/open_id_authentication.rb +127 -0
  52. data/rails/init.rb +19 -0
  53. data/test/controllers/test_users_controller.rb +21 -0
  54. data/test/libs/database.rb +47 -0
  55. data/test/libs/user.rb +7 -0
  56. data/test/libs/user_session.rb +2 -0
  57. data/test/test_helper.rb +178 -0
  58. data/test/test_oauth.rb +178 -0
  59. data/test/test_openid.rb +71 -0
  60. data/test/test_user.rb +85 -0
  61. 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,2 @@
1
+ # http://dev.aol.com/openauth_gettingstarted
2
+ # https://my.screenname.aol.com/_cqr/login/login.psp?sitedomain=dev.aol.com&authLev=1&lang=en&locale=us&siteState=OrigUrl%3Dhttp%253A%252F%252Fdev.aol.com%252Fkeys
@@ -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
@@ -0,0 +1,10 @@
1
+ class NetflixToken < OauthToken
2
+
3
+ key :user_id
4
+
5
+ settings "http://api.netflix.com",
6
+ :request_token_path => "/oauth/request_token",
7
+ :access_token_path => "/oauth/access_token",
8
+ :authorize_path => "/oauth/login"
9
+
10
+ end