foreverman-authlogic-connect 0.0.1
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.rb +10 -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/engine.rb +14 -0
- data/lib/authlogic_connect/ext.rb +56 -0
- data/lib/authlogic_connect/oauth.rb +14 -0
- data/lib/authlogic_connect/oauth/helper.rb +20 -0
- data/lib/authlogic_connect/oauth/process.rb +75 -0
- data/lib/authlogic_connect/oauth/session.rb +62 -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/openid.rb +11 -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/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/database.yml +3 -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 +244 -0
@@ -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,75 @@
|
|
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
|
+
save_auth_session_token(request_token) # only for oauth version 1
|
17
|
+
end
|
18
|
+
auth_controller.redirect_to authorize_url
|
19
|
+
end
|
20
|
+
|
21
|
+
# Step 4: on callback, run this method
|
22
|
+
def complete_oauth
|
23
|
+
# implemented in User and Session Oauth modules
|
24
|
+
unless new_oauth_request? # shouldn't be validating if it's redirecting...
|
25
|
+
restore_attributes
|
26
|
+
complete_oauth_transaction
|
27
|
+
return true
|
28
|
+
end
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
|
32
|
+
# Step 3a: save our passed-parameters into the session,
|
33
|
+
# so we can retrieve them after the redirect calls back
|
34
|
+
def save_oauth_session
|
35
|
+
# Store the class which is redirecting, so we can ensure other classes
|
36
|
+
# don't get confused and attempt to use the response
|
37
|
+
auth_session[:auth_request_class] = self.class.name
|
38
|
+
|
39
|
+
auth_session[:authentication_type] = auth_params[:authentication_type]
|
40
|
+
auth_session[:oauth_provider] = auth_params[:oauth_provider]
|
41
|
+
auth_session[:auth_method] = "oauth"
|
42
|
+
|
43
|
+
# Tell our rack callback filter what method the current request is using
|
44
|
+
auth_session[:auth_callback_method] = auth_controller.request.method
|
45
|
+
end
|
46
|
+
|
47
|
+
# Step 3b (if version 1.0 of oauth)
|
48
|
+
def save_auth_session_token(request)
|
49
|
+
# store token and secret
|
50
|
+
auth_session[:oauth_request_token] = request.token
|
51
|
+
auth_session[:oauth_request_token_secret] = request.secret
|
52
|
+
end
|
53
|
+
|
54
|
+
def restore_attributes
|
55
|
+
end
|
56
|
+
|
57
|
+
# Step last, after the response
|
58
|
+
# having lots of trouble testing logging and out multiple times,
|
59
|
+
# so there needs to be a solid way to know when a user has messed up loggin in.
|
60
|
+
def cleanup_oauth_session
|
61
|
+
[:auth_request_class,
|
62
|
+
:authentication_type,
|
63
|
+
:auth_method,
|
64
|
+
:auth_attributes,
|
65
|
+
:oauth_provider,
|
66
|
+
:auth_callback_method,
|
67
|
+
:oauth_request_token,
|
68
|
+
:oauth_request_token_secret,
|
69
|
+
:_key,
|
70
|
+
:_token,
|
71
|
+
:_secret,
|
72
|
+
].each {|key| remove_session_key(key)}
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,62 @@
|
|
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
|
+
token = token_class.find_by_key_or_token(hash[:key], hash[:token], :include => [:user]) # some weird error if I leave out the include)
|
43
|
+
if token
|
44
|
+
self.attempted_record = token.user
|
45
|
+
elsif auto_register?
|
46
|
+
self.attempted_record = klass.new
|
47
|
+
self.attempted_record.access_tokens << token_class.new(hash)
|
48
|
+
self.attempted_record.save
|
49
|
+
else
|
50
|
+
auth_session[:_key] = hash[:key]
|
51
|
+
auth_session[:_token] = hash[:token]
|
52
|
+
auth_session[:_secret] = hash[:secret]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if !attempted_record
|
57
|
+
errors.add(:user, "Could not find user in our database, have you registered with your oauth account?")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
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
|
@@ -0,0 +1,164 @@
|
|
1
|
+
class OauthToken < AccessToken
|
2
|
+
|
3
|
+
def client
|
4
|
+
unless @client
|
5
|
+
if oauth_version == 1.0
|
6
|
+
@client = OAuth::AccessToken.new(self.consumer, self.token, self.secret)
|
7
|
+
else
|
8
|
+
@client = OAuth2::AccessToken.new(self.consumer, self.token)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
@client
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear
|
16
|
+
@client = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def oauth_version
|
20
|
+
self.class.oauth_version
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(path, headers = {})
|
24
|
+
client.get(path, headers)
|
25
|
+
end
|
26
|
+
|
27
|
+
def post(path, body = "", headers = {})
|
28
|
+
client.post(path, body, headers)
|
29
|
+
end
|
30
|
+
|
31
|
+
def head(path, headers = {})
|
32
|
+
client.head(path, headers)
|
33
|
+
end
|
34
|
+
|
35
|
+
def put(path, body = "", headers = {})
|
36
|
+
client.put(path, body, headers)
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(path, headers = {})
|
40
|
+
client.delete(path, headers)
|
41
|
+
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
|
45
|
+
# oauth version, 1.0 or 2.0
|
46
|
+
def version(value)
|
47
|
+
@oauth_version = value
|
48
|
+
end
|
49
|
+
|
50
|
+
def oauth_version
|
51
|
+
@oauth_version ||= 1.0
|
52
|
+
end
|
53
|
+
|
54
|
+
# unique key that we will use from the AccessToken response
|
55
|
+
# to identify the user by.
|
56
|
+
# in Twitter, its "user_id". Twitter has "screen_name", but that's
|
57
|
+
# more subject to change than user_id. Pick whatever is least likely to change
|
58
|
+
def key(value = nil, &block)
|
59
|
+
if block_given?
|
60
|
+
@oauth_key = block
|
61
|
+
else
|
62
|
+
@oauth_key = value.is_a?(Symbol) ? value : value.to_sym
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def oauth_key
|
67
|
+
@oauth_key
|
68
|
+
end
|
69
|
+
|
70
|
+
def config
|
71
|
+
super.merge(credentials[:options] || {})
|
72
|
+
end
|
73
|
+
|
74
|
+
def consumer
|
75
|
+
if oauth_version == 1.0
|
76
|
+
OAuth::Consumer.new(credentials[:key], credentials[:secret], config)
|
77
|
+
else
|
78
|
+
OAuth2::Client.new(credentials[:key], credentials[:secret], config)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# if we're lucky we can find it by the token.
|
83
|
+
def find_by_key_or_token(key, token, options = {})
|
84
|
+
result = self.find_by_key(key, options) unless key.nil?
|
85
|
+
unless result
|
86
|
+
if !token.blank? && self.respond_to?(:find_by_token)
|
87
|
+
result = self.find_by_token(token, options)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
result
|
91
|
+
end
|
92
|
+
|
93
|
+
# this is a wrapper around oauth 1 and 2.
|
94
|
+
# it looks obscure, but from the api point of view
|
95
|
+
# you won't have to worry about it's implementation.
|
96
|
+
# in oauth 1.0, key = oauth_token, secret = oauth_secret
|
97
|
+
# in oauth 2.0, key = code, secret = access_token
|
98
|
+
def get_token_and_secret(options = {})
|
99
|
+
oauth_verifier = options[:oauth_verifier]
|
100
|
+
redirect_uri = options[:redirect_uri]
|
101
|
+
token = options[:token]
|
102
|
+
secret = options[:secret]
|
103
|
+
consumer = self.consumer # cached
|
104
|
+
|
105
|
+
if oauth_version == 1.0
|
106
|
+
access = request_token(token, secret).get_access_token(:oauth_verifier => oauth_verifier)
|
107
|
+
result = {:token => access.token, :secret => access.secret, :key => nil}
|
108
|
+
if self.oauth_key
|
109
|
+
if oauth_key.is_a?(Proc)
|
110
|
+
result[:key] = oauth_key.call(access)
|
111
|
+
else
|
112
|
+
result[:key] = access.params[self.oauth_key] || access.params[self.oauth_key.to_s] # try both
|
113
|
+
end
|
114
|
+
else
|
115
|
+
puts "Access Token: #{access.inspect}"
|
116
|
+
raise "please set an oauth key for #{service_name.to_s}"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
access = consumer.web_server.get_access_token(secret, :redirect_uri => redirect_uri)
|
120
|
+
result = {:token => access.token, :secret => secret, :key => nil}
|
121
|
+
end
|
122
|
+
|
123
|
+
result
|
124
|
+
end
|
125
|
+
|
126
|
+
# this is a cleaner method so we can access the authorize_url
|
127
|
+
# from oauth 1 or 2
|
128
|
+
def authorize_url(callback_url, &block)
|
129
|
+
consumer = self.consumer # cached
|
130
|
+
|
131
|
+
if oauth_version == 1.0
|
132
|
+
request = get_request_token(callback_url, consumer)
|
133
|
+
yield request if block_given?
|
134
|
+
return request.authorize_url
|
135
|
+
else
|
136
|
+
options = {:redirect_uri => callback_url}
|
137
|
+
|
138
|
+
unless consumer.nil? || consumer.options.empty? || consumer.options[:scope].nil?
|
139
|
+
options[:scope] = consumer.options[:scope]
|
140
|
+
else
|
141
|
+
options[:scope] = self.config[:scope] unless self.config[:scope].blank?
|
142
|
+
end
|
143
|
+
return consumer.web_server.authorize_url(options)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def request_token(token, secret)
|
148
|
+
OAuth::RequestToken.new(consumer, token, secret)
|
149
|
+
end
|
150
|
+
|
151
|
+
# if you pass a hash as the second parameter to consumer.get_request_token,
|
152
|
+
# ruby oauth will think this is a form and all sorts of bad things happen
|
153
|
+
def get_request_token(callback_url, consumer = nil)
|
154
|
+
options = {:scope => config[:scope]} if config[:scope]
|
155
|
+
consumer ||= self.consumer
|
156
|
+
consumer.get_request_token({:oauth_callback => callback_url}, options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def get_access_token(oauth_verifier)
|
160
|
+
request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|