foreverman-authlogic-connect 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) 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.rb +10 -0
  10. data/lib/authlogic_connect/common/session.rb +30 -0
  11. data/lib/authlogic_connect/common/state.rb +45 -0
  12. data/lib/authlogic_connect/common/user.rb +77 -0
  13. data/lib/authlogic_connect/common/variables.rb +124 -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.rb +14 -0
  17. data/lib/authlogic_connect/oauth/helper.rb +20 -0
  18. data/lib/authlogic_connect/oauth/process.rb +75 -0
  19. data/lib/authlogic_connect/oauth/session.rb +62 -0
  20. data/lib/authlogic_connect/oauth/state.rb +60 -0
  21. data/lib/authlogic_connect/oauth/tokens/aol_token.rb +2 -0
  22. data/lib/authlogic_connect/oauth/tokens/facebook_token.rb +11 -0
  23. data/lib/authlogic_connect/oauth/tokens/foursquare_token.rb +15 -0
  24. data/lib/authlogic_connect/oauth/tokens/get_satisfaction_token.rb +9 -0
  25. data/lib/authlogic_connect/oauth/tokens/github_token.rb +14 -0
  26. data/lib/authlogic_connect/oauth/tokens/google_token.rb +41 -0
  27. data/lib/authlogic_connect/oauth/tokens/linked_in_token.rb +19 -0
  28. data/lib/authlogic_connect/oauth/tokens/meetup_token.rb +12 -0
  29. data/lib/authlogic_connect/oauth/tokens/myspace_token.rb +26 -0
  30. data/lib/authlogic_connect/oauth/tokens/netflix_token.rb +10 -0
  31. data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +164 -0
  32. data/lib/authlogic_connect/oauth/tokens/ohloh_token.rb +9 -0
  33. data/lib/authlogic_connect/oauth/tokens/opensocial_token.rb +0 -0
  34. data/lib/authlogic_connect/oauth/tokens/twitter_token.rb +8 -0
  35. data/lib/authlogic_connect/oauth/tokens/vimeo_token.rb +18 -0
  36. data/lib/authlogic_connect/oauth/tokens/yahoo_token.rb +19 -0
  37. data/lib/authlogic_connect/oauth/user.rb +64 -0
  38. data/lib/authlogic_connect/oauth/variables.rb +64 -0
  39. data/lib/authlogic_connect/openid.rb +11 -0
  40. data/lib/authlogic_connect/openid/process.rb +74 -0
  41. data/lib/authlogic_connect/openid/session.rb +56 -0
  42. data/lib/authlogic_connect/openid/state.rb +48 -0
  43. data/lib/authlogic_connect/openid/tokens/aol_token.rb +0 -0
  44. data/lib/authlogic_connect/openid/tokens/blogger_token.rb +0 -0
  45. data/lib/authlogic_connect/openid/tokens/flickr_token.rb +0 -0
  46. data/lib/authlogic_connect/openid/tokens/my_openid_token.rb +3 -0
  47. data/lib/authlogic_connect/openid/tokens/openid_token.rb +9 -0
  48. data/lib/authlogic_connect/openid/user.rb +38 -0
  49. data/lib/authlogic_connect/openid/variables.rb +19 -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/database.yml +3 -0
  55. data/test/libs/database.rb +47 -0
  56. data/test/libs/user.rb +7 -0
  57. data/test/libs/user_session.rb +2 -0
  58. data/test/test_helper.rb +178 -0
  59. data/test/test_oauth.rb +178 -0
  60. data/test/test_openid.rb +71 -0
  61. data/test/test_user.rb +85 -0
  62. 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,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
@@ -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