rack-oauth 0.1.2 → 0.1.3

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/lib/rack-oauth.rb CHANGED
@@ -30,6 +30,17 @@ module Rack #:nodoc:
30
30
  # Helper methods intended to be included in your Rails controller or
31
31
  # in your Sinatra helpers block
32
32
  module Methods
33
+
34
+ # This is *the* method you want to call.
35
+ #
36
+ # After you're authorized and redirected back to your #redirect_to path,
37
+ # you should be able to call get_access_token to get and hold onto
38
+ # the access token for the user you've been authorized as.
39
+ #
40
+ # You can use the token to make GET/POST/etc requests
41
+ def get_access_token name = nil
42
+ oauth(name).get_access_token(oauth_request_env)
43
+ end
33
44
 
34
45
  # [Internal] this method returns the Rack 'env' for the current request.
35
46
  #
@@ -53,32 +64,6 @@ module Rack #:nodoc:
53
64
  oauth
54
65
  end
55
66
 
56
- # Makes a request using the stored access token for the current session.
57
- #
58
- # Without a user logged in to an OAuth provider in the current session, this won't work.
59
- #
60
- # This is *not* the method to use to fire off requests for saved access tokens.
61
- def oauth_request *args
62
- oauth.request oauth_request_env, *args
63
- end
64
-
65
- def oauth_request_with_access_token token, *args
66
- oauth.request_with_access_token token, *args
67
- end
68
-
69
- # Get the access token object for the currently authorized session
70
- def oauth_access_token name = nil
71
- oauth(name).get_access_token(oauth_request_env)
72
- end
73
-
74
- # If Rack::OAuth#get_access_token is nil given the #oauth_request_env available
75
- # (inotherwords, it's nil in our user's current session), then we didn't
76
- # log in. If we have an access token for this particular session, then
77
- # we are logged in.
78
- def logged_in? name = nil
79
- !! oauth_access_token(name)
80
- end
81
-
82
67
  # Returns the path to rediret to for logging in via OAuth
83
68
  def oauth_login_path name = nil
84
69
  oauth(name).login_path
@@ -117,32 +102,9 @@ module Rack #:nodoc:
117
102
  :login_path => '/oauth_login',
118
103
  :callback_path => '/oauth_callback',
119
104
  :redirect_to => '/oauth_complete',
120
- :rack_session => 'rack.session',
121
- :json_parser => lambda {|json_string| require 'json'; JSON.parse(json_string); },
122
- :access_token_getter => lambda {|key, oauth| oauth.get_access_token_via_instance_variable(key) },
123
- :access_token_setter => lambda {|key, token, oauth| oauth.set_access_token_via_instance_variable(key, token) }
105
+ :rack_session => 'rack.session'
124
106
  }
125
107
 
126
- # A proc that accepts an argument for the KEY we're using to get an access token
127
- # that should return the actual access token object.
128
- #
129
- # A second parameter is passed to your block with the Rack::OAuth instance
130
- #
131
- # This allows you to override how access tokens are persisted
132
- attr_accessor :access_token_getter
133
- alias get access_token_getter
134
- alias get= access_token_getter=
135
-
136
- # A proc that accepts an argument for the KEY we're using to set an access token
137
- # and a second argument with the actual access token object.
138
- #
139
- # A third parameter is passed to your block with the Rack::OAuth instance
140
- #
141
- # This allows you to override how access tokens are persisted
142
- attr_accessor :access_token_setter
143
- alias set access_token_setter
144
- alias set= access_token_setter=
145
-
146
108
  # the URL that should initiate OAuth and redirect to the OAuth provider's login page
147
109
  def login_path
148
110
  ::File.join *[@login_path.to_s, name_unless_default].compact
@@ -182,9 +144,6 @@ module Rack #:nodoc:
182
144
  alias site consumer_site
183
145
  alias site= consumer_site=
184
146
 
185
- # a Proc that accepts a JSON string and returns a Ruby object. Defaults to using the 'json' gem, if available.
186
- attr_accessor :json_parser
187
-
188
147
  # an arbitrary name for this instance of Rack::OAuth
189
148
  def name
190
149
  @name.to_s
@@ -204,96 +163,76 @@ module Rack #:nodoc:
204
163
  end
205
164
 
206
165
  def call env
166
+ # put this instance of Rack::OAuth in the env
167
+ # so it's accessible from the application
207
168
  env['rack.oauth'] ||= {}
208
169
  env['rack.oauth'][name] = self
209
170
 
210
171
  case env['PATH_INFO']
211
- when login_path; do_login env
212
- when callback_path; do_callback env
213
- else; @app.call env
172
+
173
+ # find out where to redirect to authorize for this oauth provider
174
+ # and redirect there. when the authorization is finished,
175
+ # the provider will redirect back to our application's callback path
176
+ when login_path
177
+ do_login(env)
178
+
179
+ # the oauth provider has redirected back to us! we should have a
180
+ # verifier now that we can use, in combination with out token and
181
+ # secret, to get an access token for this user
182
+ when callback_path
183
+ do_callback(env)
184
+
185
+ else
186
+ @app.call(env)
214
187
  end
215
188
  end
216
189
 
217
190
  def do_login env
218
-
219
191
  if Rack::OAuth.test_mode?
220
- session(env)[:token] = "Token"
221
- session(env)[:secret] = "Secret"
222
- set_access_token env, "AccessToken"
192
+ set_access_token env, OpenStruct.new(:params => { 'I am a' => 'fake token' })
223
193
  return [ 302, { 'Content-Type' => 'text/html', 'Location' => redirect_to }, [] ]
224
194
  end
225
195
 
196
+ # get request token and hold onto the token/secret (which we need later to get the access token)
226
197
  request = consumer.get_request_token :oauth_callback => ::File.join("http://#{ env['HTTP_HOST'] }", callback_path)
227
198
  session(env)[:token] = request.token
228
199
  session(env)[:secret] = request.secret
200
+
201
+ # redirect to the oauth provider's authorize url to authorize the user
229
202
  [ 302, { 'Content-Type' => 'text/html', 'Location' => request.authorize_url }, [] ]
230
203
  end
231
204
 
232
205
  def do_callback env
233
- session(env)[:verifier] = Rack::Request.new(env).params['oauth_verifier']
206
+ # get access token and persist it in the session in a way that we can get it back out later
234
207
  request = ::OAuth::RequestToken.new consumer, session(env)[:token], session(env)[:secret]
235
- access = request.get_access_token :oauth_verifier => session(env)[:verifier]
208
+ set_access_token env, request.get_access_token(:oauth_verifier => Rack::Request.new(env).params['oauth_verifier'])
236
209
 
237
- # hold onto the access token
238
- set_access_token env, access
210
+ # clear out the session variables (won't need these anymore)
211
+ session(env).delete(:token)
212
+ session(env).delete(:secret)
239
213
 
214
+ # we have an access token now ... redirect back to the user's application
240
215
  [ 302, { 'Content-Type' => 'text/html', 'Location' => redirect_to }, [] ]
241
216
  end
242
217
 
243
- # Default implementation of access_token_getter
244
- #
245
- # Keeps tokens in an instance variable
246
- def get_access_token_via_instance_variable key
247
- @tokens[key] if @tokens
248
- end
249
-
250
- # Default implementation of access_token_setter
251
- #
252
- # Keeps tokens in an instance variable
253
- def set_access_token_via_instance_variable key, token
254
- @tokens ||= {}
255
- @tokens[key] = token
256
- end
257
-
258
- # Returns the key to use (for this particular session) to get or set an
259
- # access token for this Rack env
260
- #
261
- # TODO this will very likely change as we want to be able to get or set
262
- # access tokens using useful data like a user's name in the future
263
- def key_for_env env
264
- val = session(env)[:token] + session(env)[:secret] if session(env)[:token] and session(env)[:secret]
265
- session(env)[:token] + session(env)[:secret] if session(env)[:token] and session(env)[:secret]
218
+ # Stores the access token in this env's session in a way that we can get it back out via #get_access_token(env)
219
+ def set_access_token env, token
220
+ session(env)[:access_token_params] = token.params
266
221
  end
267
222
 
268
- # Gets an Access Token by key using access_token_getter (for this specific ENV)
223
+ # See #set_access_token
269
224
  def get_access_token env
270
- access_token_getter.call key_for_env(env), self
271
- end
272
-
273
- # Sets an Access Token by key and value using access_token_setter (for this specific ENV)
274
- def set_access_token env, token
275
- access_token_setter.call key_for_env(env), token, self
225
+ params = session(env)[:access_token_params]
226
+ ::OAuth::AccessToken.from_hash consumer, params if params
276
227
  end
277
228
 
278
229
  # Usage:
279
230
  #
280
- # request '/account/verify_credentials.json'
281
- # request 'GET', '/account/verify_credentials.json'
282
- # request :post, '/statuses/update.json', :status => params[:tweet]
231
+ # request @token, '/account/verify_credentials.json'
232
+ # request @token, 'GET', '/account/verify_credentials.json'
233
+ # request @token, :post, '/statuses/update.json', :status => params[:tweet]
283
234
  #
284
- def request env, method, path = nil, *args
285
- if method.to_s.start_with?('/')
286
- path = method
287
- method = :get
288
- end
289
-
290
- return Rack::OAuth.mock_response_for(method, path) if Rack::OAuth.test_mode?
291
-
292
- consumer.request method.to_s.downcase.to_sym, path, get_access_token(env), *args
293
- end
294
-
295
- # Same as #request but you can manually pass your own request token
296
- def request_with_access_token token, method, path = nil, *args
235
+ def request token, method, path = nil, *args
297
236
  if method.to_s.start_with?('/')
298
237
  path = method
299
238
  method = :get
@@ -1,30 +1,26 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
+ require 'fakeweb'
4
+ FakeWeb.allow_net_connect = false
5
+ FakeWeb.register_uri :get, 'http://twitter.com/account/verify_credentials.json', :body => %{{"friends_count":190,"utc_offset":-28800,"profile_sidebar_border_color":"829D5E","status":{"in_reply_to_screen_name":null,"text":"Come on people, don't you realize that smoking isn't cool anymore? Try a healthier stimulant. Maybe one that doesn't irritate my sinuses?","in_reply_to_user_id":null,"in_reply_to_status_id":null,"source":"web","truncated":false,"favorited":false,"id":5177704516,"created_at":"Mon Oct 26 17:15:10 +0000 2009"},"notifications":false,"statuses_count":1689,"time_zone":"Pacific Time (US & Canada)","verified":false,"profile_text_color":"3E4415","profile_image_url":"http://a3.twimg.com/profile_images/54765389/remi-rock-on_bak_normal.png","profile_background_image_url":"http://s.twimg.com/a/1256577591/images/themes/theme5/bg.gif","location":"Phoenix, AZ","following":false,"favourites_count":0,"profile_link_color":"D02B55","screen_name":"THE_REAL_SHAQ","geo_enabled":false,"profile_background_tile":false,"protected":false,"profile_background_color":"352726","name":"THE_REAL_SHAQ","followers_count":255,"url":"http://remi.org","id":11043342,"created_at":"Tue Dec 11 09:13:43 +0000 2007","profile_sidebar_fill_color":"99CC33","description":"Beer goes in, Code comes out"}}
6
+
3
7
  require 'json'
4
8
  require 'sinatra/base'
5
9
  class SampleSinatraApp < Sinatra::Base
6
10
 
7
- # this is hardcore optional ... if you want to override where ALL tokens are persisted, you can do this ...
8
-
9
- def self.get_token key, oauth
10
- @tokens[key] if @tokens
11
- end
12
- def self.set_token key, token, oauth
13
- @tokens ||= {}
14
- @tokens[key] = token
15
- end
16
-
17
11
  use Rack::Session::Cookie
18
12
  use Rack::OAuth, :site => 'http://twitter.com',
19
13
  :key => '4JjFmhjfZyQ6rdbiql5A',
20
- :secret => 'rv4ZaCgvxVPVjxHIDbMxTGFbIMxUa4KkIdPqL7HmaQo',
21
- :get => method(:get_token),
22
- :set => method(:set_token)
14
+ :secret => 'rv4ZaCgvxVPVjxHIDbMxTGFbIMxUa4KkIdPqL7HmaQo'
23
15
 
24
16
  enable :raise_errors
25
17
 
26
18
  helpers do
27
19
  include Rack::OAuth::Methods
20
+
21
+ def logged_in?
22
+ get_access_token.present?
23
+ end
28
24
  end
29
25
 
30
26
  get '/' do
@@ -36,13 +32,12 @@ class SampleSinatraApp < Sinatra::Base
36
32
  end
37
33
 
38
34
  get '/oauth_complete' do
39
- info = JSON.parse oauth_request('/account/verify_credentials.json')
35
+ info = JSON.parse get_access_token.get('/account/verify_credentials.json').body
40
36
  name = info['screen_name']
41
- $access_tokens[name] = oauth_access_token
42
37
  end
43
38
 
44
39
  get '/get_user_info' do
45
- info = JSON.parse oauth_request('/account/verify_credentials.json')
40
+ info = JSON.parse get_access_token.get('/account/verify_credentials.json').body
46
41
  end
47
42
  end
48
43
 
@@ -78,28 +73,4 @@ describe SampleSinatraApp do
78
73
  request('/').body.should include('Hello World')
79
74
  end
80
75
 
81
- it 'should be able to specify a mock response for an arbitrary authorized response' do
82
- request('/oauth_login') # login
83
-
84
- # if we don't mock the request, it should blow up
85
- lambda { request('/get_user_info') }.should raise_error
86
-
87
- Rack::OAuth.mock_request '/account/verify_credentials.json', example_json
88
-
89
- request('/get_user_info').body.should include('remitaylor')
90
- end
91
-
92
- it 'should be able to persist access token by some arbitrary value like twitter screen_name' do
93
- $access_tokens ||= {}
94
- request('/oauth_login').status.should == 302
95
-
96
- # token should be nil
97
- $access_tokens['remitaylor'].should be_nil
98
-
99
- request('/oauth_complete')
100
-
101
- # token should not be nil because the oauth_complete goes and gets and persists it
102
- $access_tokens['remitaylor'].should_not be_nil
103
- end
104
-
105
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - remi
@@ -11,8 +11,27 @@ cert_chain: []
11
11
 
12
12
  date: 2009-11-02 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: oauth
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
16
35
  description: Rack Middleware for OAuth Authorization
17
36
  email: remi@remitaylor.com
18
37
  executables: []
@@ -97,6 +116,9 @@ files:
97
116
  - examples/rails-example/tmp/webrat-1257210581.html
98
117
  - examples/rails-example/tmp/webrat-1257210600.html
99
118
  - examples/rails-example/tmp/webrat-1257210608.html
119
+ - examples/rails-example/tmp/webrat-1257219890.html
120
+ - examples/rails-example/tmp/webrat-1257219947.html
121
+ - examples/rails-example/tmp/webrat-1257219957.html
100
122
  - examples/sinatra-twitter.rb
101
123
  - examples/sinatra-twitter.ru
102
124
  - lib/rack-oauth.rb