rack-twitter-auth 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +54 -0
- data/Rakefile +67 -0
- data/VERSION +1 -0
- data/examples/rails-example/README +243 -0
- data/examples/rails-example/Rakefile +10 -0
- data/examples/rails-example/app/controllers/application_controller.rb +18 -0
- data/examples/rails-example/app/controllers/welcome_controller.rb +23 -0
- data/examples/rails-example/app/helpers/application_helper.rb +3 -0
- data/examples/rails-example/app/helpers/welcome_helper.rb +2 -0
- data/examples/rails-example/app/views/welcome/index.html.erb +2 -0
- data/examples/rails-example/config/boot.rb +110 -0
- data/examples/rails-example/config/database.yml +22 -0
- data/examples/rails-example/config/environment.rb +16 -0
- data/examples/rails-example/config/environments/development.rb +17 -0
- data/examples/rails-example/config/environments/production.rb +28 -0
- data/examples/rails-example/config/environments/test.rb +33 -0
- data/examples/rails-example/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/rails-example/config/initializers/inflections.rb +10 -0
- data/examples/rails-example/config/initializers/mime_types.rb +5 -0
- data/examples/rails-example/config/initializers/new_rails_defaults.rb +21 -0
- data/examples/rails-example/config/initializers/session_store.rb +15 -0
- data/examples/rails-example/config/locales/en.yml +5 -0
- data/examples/rails-example/config/routes.rb +6 -0
- data/examples/rails-example/db/development.sqlite3 +1 -0
- data/examples/rails-example/db/seeds.rb +7 -0
- data/examples/rails-example/db/test.sqlite3 +1 -0
- data/examples/rails-example/doc/README_FOR_APP +2 -0
- data/examples/rails-example/lib/tasks/rspec.rake +182 -0
- data/examples/rails-example/log/development.log +241 -0
- data/examples/rails-example/log/production.log +0 -0
- data/examples/rails-example/log/server.log +0 -0
- data/examples/rails-example/log/test.log +1750 -0
- data/examples/rails-example/public/404.html +30 -0
- data/examples/rails-example/public/422.html +30 -0
- data/examples/rails-example/public/500.html +30 -0
- data/examples/rails-example/public/favicon.ico +0 -0
- data/examples/rails-example/public/images/rails.png +0 -0
- data/examples/rails-example/public/javascripts/application.js +2 -0
- data/examples/rails-example/public/javascripts/controls.js +963 -0
- data/examples/rails-example/public/javascripts/dragdrop.js +973 -0
- data/examples/rails-example/public/javascripts/effects.js +1128 -0
- data/examples/rails-example/public/javascripts/prototype.js +4320 -0
- data/examples/rails-example/public/robots.txt +5 -0
- data/examples/rails-example/script/about +4 -0
- data/examples/rails-example/script/autospec +6 -0
- data/examples/rails-example/script/console +3 -0
- data/examples/rails-example/script/dbconsole +3 -0
- data/examples/rails-example/script/destroy +3 -0
- data/examples/rails-example/script/generate +3 -0
- data/examples/rails-example/script/performance/benchmarker +3 -0
- data/examples/rails-example/script/performance/profiler +3 -0
- data/examples/rails-example/script/plugin +3 -0
- data/examples/rails-example/script/runner +3 -0
- data/examples/rails-example/script/server +3 -0
- data/examples/rails-example/script/spec +10 -0
- data/examples/rails-example/script/spec_server +9 -0
- data/examples/rails-example/spec/integration/login_spec.rb +17 -0
- data/examples/rails-example/spec/rcov.opts +2 -0
- data/examples/rails-example/spec/spec.opts +4 -0
- data/examples/rails-example/spec/spec_helper.rb +16 -0
- data/examples/rails-example/tmp/webrat-1257205170.html +202 -0
- data/examples/rails-example/tmp/webrat-1257205276.html +31 -0
- data/examples/rails-example/tmp/webrat-1257205315.html +211 -0
- data/examples/rails-example/tmp/webrat-1257205333.html +31 -0
- data/examples/rails-example/tmp/webrat-1257205380.html +211 -0
- data/examples/rails-example/tmp/webrat-1257205757.html +211 -0
- data/examples/rails-example/tmp/webrat-1257210107.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210160.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210488.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210501.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210545.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210564.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210581.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210600.html +32 -0
- data/examples/rails-example/tmp/webrat-1257210608.html +32 -0
- data/examples/rails-example/tmp/webrat-1257219890.html +211 -0
- data/examples/rails-example/tmp/webrat-1257219947.html +213 -0
- data/examples/rails-example/tmp/webrat-1257219957.html +213 -0
- data/examples/sinatra-twitter.rb +30 -0
- data/examples/sinatra-twitter.ru +2 -0
- data/lib/rack-oauth.rb +289 -0
- data/lib/rack/oauth.rb +1 -0
- data/spec/data/unauthorized_request_token.yml +56 -0
- data/spec/rack_oauth_middleware_spec.rb +156 -0
- data/spec/sample_sinatra_app_spec.rb +91 -0
- data/spec/spec_helper.rb +24 -0
- metadata +183 -0
data/lib/rack-oauth.rb
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rack'
|
3
|
+
require 'oauth'
|
4
|
+
|
5
|
+
# For some reason, getting the location our of a HeaderHash doesn't always work!
|
6
|
+
#
|
7
|
+
# sometimes you can see the header key/value in the HeaderHash, but you can't get it out!
|
8
|
+
class Rack::Utils::HeaderHash
|
9
|
+
def [] key
|
10
|
+
if not has_key?(key)
|
11
|
+
hash = to_hash
|
12
|
+
hash.keys.each do |hash_key|
|
13
|
+
if hash_key.downcase == key.downcase
|
14
|
+
return hash[hash_key]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Rack #:nodoc:
|
23
|
+
|
24
|
+
# Rack Middleware for integrating OAuth into your application
|
25
|
+
#
|
26
|
+
# Note: this *requires* that a Rack::Session middleware be enabled
|
27
|
+
#
|
28
|
+
class OAuth
|
29
|
+
|
30
|
+
# Helper methods intended to be included in your Rails controller or
|
31
|
+
# in your Sinatra helpers block
|
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_instance(name).get_access_token(oauth_request_env)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Same as #get_access_token but it clears the access token out of the session.
|
46
|
+
def get_access_token! name = nil
|
47
|
+
oauth_instance(name).get_access_token!(oauth_request_env)
|
48
|
+
end
|
49
|
+
|
50
|
+
# [Internal] this method returns the Rack 'env' for the current request.
|
51
|
+
#
|
52
|
+
# This looks for #env or #request.env by default. If these don't return
|
53
|
+
# something, then we raise an exception and you should override this method
|
54
|
+
# so it returns the Rack env that we need.
|
55
|
+
def oauth_request_env
|
56
|
+
if respond_to?(:env)
|
57
|
+
env
|
58
|
+
elsif respond_to?(:request) and request.respond_to?(:env)
|
59
|
+
request.env
|
60
|
+
else
|
61
|
+
raise "Couldn't find 'env' ... please override #oauth_request_env"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the instance of Rack::OAuth given a name (defaults to the default Rack::OAuth name)
|
66
|
+
def oauth_instance name = nil
|
67
|
+
oauth = Rack::OAuth.get(oauth_request_env, nil)
|
68
|
+
raise "Couldn't find Rack::OAuth instance with name #{ name }" unless oauth
|
69
|
+
oauth
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the path to rediret to for logging in via OAuth
|
73
|
+
def oauth_login_path name = nil
|
74
|
+
oauth_instance(name).login_path
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
class << self
|
80
|
+
|
81
|
+
# The name we use for Rack::OAuth instances when a name is not given.
|
82
|
+
#
|
83
|
+
# This is 'default' by default
|
84
|
+
attr_accessor :default_instance_name
|
85
|
+
|
86
|
+
# Set this equal to true to enable 'test mode'
|
87
|
+
attr_accessor :test_mode_enabled
|
88
|
+
def enable_test_mode() self.test_mode_enabled = true end
|
89
|
+
def disable_test_mode() self.test_mode_enabled = false end
|
90
|
+
def test_mode?() test_mode_enabled == true end
|
91
|
+
end
|
92
|
+
|
93
|
+
@default_instance_name = 'default'
|
94
|
+
|
95
|
+
# Returns all of the Rack::OAuth instances found in this Rack 'env' Hash
|
96
|
+
def self.all env
|
97
|
+
env['rack.oauth']
|
98
|
+
end
|
99
|
+
|
100
|
+
# Simple helper to get an instance of Rack::OAuth by name found in this Rack 'env' Hash
|
101
|
+
def self.get env, name = nil
|
102
|
+
name = Rack::OAuth.default_instance_name if name.nil?
|
103
|
+
all(env)[name.to_s]
|
104
|
+
end
|
105
|
+
|
106
|
+
DEFAULT_OPTIONS = {
|
107
|
+
:login_path => '/oauth_login',
|
108
|
+
:callback_path => '/oauth_callback',
|
109
|
+
:redirect_to => '/oauth_complete',
|
110
|
+
:rack_session => 'rack.session'
|
111
|
+
}
|
112
|
+
|
113
|
+
# the URL that should initiate OAuth and redirect to the OAuth provider's login page
|
114
|
+
def login_path
|
115
|
+
::File.join *[@login_path.to_s, name_unless_default].compact
|
116
|
+
end
|
117
|
+
attr_writer :login_path
|
118
|
+
alias login login_path
|
119
|
+
alias login= login_path=
|
120
|
+
|
121
|
+
# the URL that the OAuth provider should callback to after OAuth login is complete
|
122
|
+
def callback_path
|
123
|
+
::File.join *[@callback_path.to_s, name_unless_default].compact
|
124
|
+
end
|
125
|
+
attr_writer :callback_path
|
126
|
+
alias callback callback_path
|
127
|
+
alias callback= callback_path=
|
128
|
+
|
129
|
+
# the URL that Rack::OAuth should redirect to after the OAuth has been completed (part of your app)
|
130
|
+
attr_accessor :redirect_to
|
131
|
+
alias redirect redirect_to
|
132
|
+
alias redirect= redirect_to=
|
133
|
+
|
134
|
+
# the name of the Rack env variable used for the session
|
135
|
+
attr_accessor :rack_session
|
136
|
+
|
137
|
+
# [required] Your OAuth consumer key
|
138
|
+
attr_accessor :consumer_key
|
139
|
+
alias key consumer_key
|
140
|
+
alias key= consumer_key=
|
141
|
+
|
142
|
+
# [required] Your OAuth consumer secret
|
143
|
+
attr_accessor :consumer_secret
|
144
|
+
alias secret consumer_secret
|
145
|
+
alias secret= consumer_secret=
|
146
|
+
|
147
|
+
# [required] The site you want to request OAuth for, eg. 'http://twitter.com'
|
148
|
+
attr_accessor :consumer_site
|
149
|
+
alias site consumer_site
|
150
|
+
alias site= consumer_site=
|
151
|
+
|
152
|
+
# for using "Sign in w/twitter"
|
153
|
+
attr_accessor :authentication
|
154
|
+
|
155
|
+
# an arbitrary name for this instance of Rack::OAuth
|
156
|
+
def name
|
157
|
+
@name.to_s
|
158
|
+
end
|
159
|
+
attr_writer :name
|
160
|
+
|
161
|
+
def initialize app, *args
|
162
|
+
@app = app
|
163
|
+
|
164
|
+
options = args.pop
|
165
|
+
@name = args.first || Rack::OAuth.default_instance_name
|
166
|
+
|
167
|
+
DEFAULT_OPTIONS.each {|name, value| send "#{name}=", value }
|
168
|
+
options.each {|name, value| send "#{name}=", value } if options
|
169
|
+
|
170
|
+
raise_validation_exception unless valid?
|
171
|
+
end
|
172
|
+
|
173
|
+
def call env
|
174
|
+
# put this instance of Rack::OAuth in the env
|
175
|
+
# so it's accessible from the application
|
176
|
+
env['rack.oauth'] ||= {}
|
177
|
+
env['rack.oauth'][name] = self
|
178
|
+
|
179
|
+
case env['PATH_INFO']
|
180
|
+
|
181
|
+
# find out where to redirect to authorize for this oauth provider
|
182
|
+
# and redirect there. when the authorization is finished,
|
183
|
+
# the provider will redirect back to our application's callback path
|
184
|
+
when login_path
|
185
|
+
do_login(env)
|
186
|
+
|
187
|
+
# the oauth provider has redirected back to us! we should have a
|
188
|
+
# verifier now that we can use, in combination with out token and
|
189
|
+
# secret, to get an access token for this user
|
190
|
+
when callback_path
|
191
|
+
do_callback(env)
|
192
|
+
|
193
|
+
else
|
194
|
+
@app.call(env)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def do_login env
|
199
|
+
if Rack::OAuth.test_mode?
|
200
|
+
set_access_token env, OpenStruct.new(:params => { 'I am a' => 'fake token' })
|
201
|
+
return [ 302, { 'Content-Type' => 'text/html', 'Location' => redirect_to }, [] ]
|
202
|
+
end
|
203
|
+
|
204
|
+
# get request token and hold onto the token/secret (which we need later to get the access token)
|
205
|
+
request = consumer.get_request_token :oauth_callback => ::File.join("http://#{ env['HTTP_HOST'] }", callback_path)
|
206
|
+
session(env)[:token] = request.token
|
207
|
+
session(env)[:secret] = request.secret
|
208
|
+
|
209
|
+
# redirect to the oauth provider's authorize url to authorize the user
|
210
|
+
path = request.authorize_url
|
211
|
+
path.gsub!('authorize', 'authenticate') if @authentication
|
212
|
+
[ 302, { 'Content-Type' => 'text/html', 'Location' => path }, [] ]
|
213
|
+
end
|
214
|
+
|
215
|
+
def do_callback env
|
216
|
+
# get access token and persist it in the session in a way that we can get it back out later
|
217
|
+
request = ::OAuth::RequestToken.new consumer, session(env)[:token], session(env)[:secret]
|
218
|
+
set_access_token env, request.get_access_token(:oauth_verifier => Rack::Request.new(env).params['oauth_verifier'])
|
219
|
+
|
220
|
+
# clear out the session variables (won't need these anymore)
|
221
|
+
session(env).delete(:token)
|
222
|
+
session(env).delete(:secret)
|
223
|
+
|
224
|
+
# we have an access token now ... redirect back to the user's application
|
225
|
+
[ 302, { 'Content-Type' => 'text/html', 'Location' => redirect_to }, [] ]
|
226
|
+
end
|
227
|
+
|
228
|
+
# Stores the access token in this env's session in a way that we can get it back out via #get_access_token(env)
|
229
|
+
def set_access_token env, token
|
230
|
+
session(env)[:access_token_params] = token.params
|
231
|
+
end
|
232
|
+
|
233
|
+
# See #set_access_token
|
234
|
+
def get_access_token env
|
235
|
+
params = session(env)[:access_token_params]
|
236
|
+
::OAuth::AccessToken.from_hash consumer, params if params
|
237
|
+
end
|
238
|
+
|
239
|
+
# Same as #get_access_token but it clears the access token info out of the session
|
240
|
+
def get_access_token! env
|
241
|
+
params = session(env).delete(:access_token_params)
|
242
|
+
::OAuth::AccessToken.from_hash consumer, params if params
|
243
|
+
end
|
244
|
+
|
245
|
+
def verified? env
|
246
|
+
[ :token, :secret, :verifier ].all? { |required_session_key| session(env)[required_session_key] }
|
247
|
+
end
|
248
|
+
|
249
|
+
def consumer
|
250
|
+
@consumer ||= ::OAuth::Consumer.new consumer_key, consumer_secret, :site => consumer_site
|
251
|
+
end
|
252
|
+
|
253
|
+
def valid?
|
254
|
+
@errors = []
|
255
|
+
@errors << ":consumer_key option is required" unless consumer_key
|
256
|
+
@errors << ":consumer_secret option is required" unless consumer_secret
|
257
|
+
@errors << ":consumer_site option is required" unless consumer_site
|
258
|
+
@errors.empty?
|
259
|
+
end
|
260
|
+
|
261
|
+
def raise_validation_exception
|
262
|
+
raise @errors.join(', ')
|
263
|
+
end
|
264
|
+
|
265
|
+
# Returns a hash of session variables, specific to this instance of Rack::OAuth and the end-user
|
266
|
+
#
|
267
|
+
# All user-specific variables are stored in the session.
|
268
|
+
#
|
269
|
+
# The variables we currently keep track of are:
|
270
|
+
# - token
|
271
|
+
# - secret
|
272
|
+
# - verifier
|
273
|
+
#
|
274
|
+
# With all three of these, we can make arbitrary requests to our OAuth provider for this user.
|
275
|
+
def session env
|
276
|
+
raise "Rack env['rack.session'] is nil ... has a Rack::Session middleware be enabled? " +
|
277
|
+
"use :rack_session for custom key" if env[rack_session].nil?
|
278
|
+
env[rack_session]['rack.oauth'] ||= {}
|
279
|
+
env[rack_session]['rack.oauth'][name] ||= {}
|
280
|
+
end
|
281
|
+
|
282
|
+
# Returns the #name of this Rack::OAuth unless the name is 'default', in which case it returns nil
|
283
|
+
def name_unless_default
|
284
|
+
name == Rack::OAuth.default_instance_name ? nil : name
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
data/lib/rack/oauth.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rack-oauth'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:OAuth::RequestToken
|
2
|
+
consumer: !ruby/object:OAuth::Consumer
|
3
|
+
http: !ruby/object:Net::HTTP
|
4
|
+
address: twitter.com
|
5
|
+
close_on_empty_response: false
|
6
|
+
curr_http_version: "1.1"
|
7
|
+
debug_output:
|
8
|
+
newimpl: true
|
9
|
+
open_timeout:
|
10
|
+
port: 80
|
11
|
+
read_timeout: 60
|
12
|
+
seems_1_0_server: false
|
13
|
+
socket:
|
14
|
+
ssl_context: !ruby/object:OpenSSL::SSL::SSLContext
|
15
|
+
ca_file: /etc/ssl/certs/ca-certificates.crt
|
16
|
+
ca_path:
|
17
|
+
cert:
|
18
|
+
cert_store:
|
19
|
+
client_ca:
|
20
|
+
client_cert_cb:
|
21
|
+
extra_chain_cert:
|
22
|
+
key:
|
23
|
+
options:
|
24
|
+
session_get_cb:
|
25
|
+
session_id_context:
|
26
|
+
session_new_cb:
|
27
|
+
session_remove_cb:
|
28
|
+
timeout:
|
29
|
+
tmp_dh_callback:
|
30
|
+
verify_callback:
|
31
|
+
verify_depth: 5
|
32
|
+
verify_mode: 1
|
33
|
+
started: false
|
34
|
+
use_ssl: false
|
35
|
+
http_method: :post
|
36
|
+
key: 4JjFmhjfZyQ6rdbiql5A
|
37
|
+
options:
|
38
|
+
:http_method: :post
|
39
|
+
:scheme: :header
|
40
|
+
:oauth_version: "1.0"
|
41
|
+
:proxy:
|
42
|
+
:request_token_path: /oauth/request_token
|
43
|
+
:authorize_path: AUTH_PATH
|
44
|
+
:site: http://twitter.com
|
45
|
+
:signature_method: HMAC-SHA1
|
46
|
+
:access_token_path: /oauth/access_token
|
47
|
+
secret: rv4ZaCgvxVPVjxHIDbMxTGFbIMxUa4KkIdPqL7HmaQo
|
48
|
+
params:
|
49
|
+
oauth_callback_confirmed: "true"
|
50
|
+
oauth_token_secret: XnS8UEe2l4iKAYqPBFhQ0wfI0s3i2nLE1RjnC1CbA
|
51
|
+
:oauth_callback_confirmed: "true"
|
52
|
+
:oauth_token_secret: XnS8UEe2l4iKAYqPBFhQ0wfI0s3i2nLE1RjnC1CbA
|
53
|
+
oauth_token: 6dhuchM6Wzh9PpNv0KGB0h3AxzHLZ2Vy9erSJsOAv4
|
54
|
+
:oauth_token: 6dhuchM6Wzh9PpNv0KGB0h3AxzHLZ2Vy9erSJsOAv4
|
55
|
+
secret: XnS8UEe2l4iKAYqPBFhQ0wfI0s3i2nLE1RjnC1CbA
|
56
|
+
token: 6dhuchM6Wzh9PpNv0KGB0h3AxzHLZ2Vy9erSJsOAv4
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
# This is just testing to make sure that the basics of the middleware
|
4
|
+
# all work. This does NOT actually test any of the OAuth functionality.
|
5
|
+
describe Rack::OAuth, 'basic middlware usage' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@app = lambda {|env| [200, {}, ["Hello World"]] }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should have a name' do
|
12
|
+
oauth = Rack::OAuth.new @app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
13
|
+
oauth.name.should == 'foo'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'name should default to "default"' do
|
17
|
+
oauth = Rack::OAuth.new @app, :site => 'a', :key => 'b', :secret => 'c'
|
18
|
+
oauth.name.should == 'default'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be able to access an instance of Rack::OAuth by name from within Rack application' do
|
22
|
+
app = lambda {|env| [200, {}, [ env['rack.oauth'].keys.inspect ]] }
|
23
|
+
|
24
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
25
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('foo')
|
26
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should_not include('bar')
|
27
|
+
|
28
|
+
oauth = Rack::OAuth.new oauth, :bar, :site => 'a', :key => 'b', :secret => 'c'
|
29
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('foo')
|
30
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('bar')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be *really* easy to access the default instance of Rack::OAuth by name from within Rack application' do
|
34
|
+
app = lambda {|env| [200, {}, [ Rack::OAuth.get(env).inspect ]] }
|
35
|
+
|
36
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
37
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should == 'nil'
|
38
|
+
|
39
|
+
oauth = Rack::OAuth.new app, :site => 'a', :key => 'b', :secret => 'c'
|
40
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should_not == 'nil'
|
41
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('#<Rack::OAuth')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be easy to access an instance of Rack::OAuth by name from within Rack application' do
|
45
|
+
app = lambda {|env| [200, {}, [ Rack::OAuth.get(env, :bar).inspect ]] }
|
46
|
+
|
47
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
48
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should == 'nil'
|
49
|
+
|
50
|
+
oauth = Rack::OAuth.new oauth, :bar, :site => 'a', :key => 'b', :secret => 'c'
|
51
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should_not == 'nil'
|
52
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('#<Rack::OAuth')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should be easy to access to all instances of Rack::OAuth for a Rack application' do
|
56
|
+
app = lambda {|env| [200, {}, [ Rack::OAuth.all(env).length ]] }
|
57
|
+
|
58
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
59
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should == '1'
|
60
|
+
|
61
|
+
oauth = Rack::OAuth.new oauth, :bar, :site => 'a', :key => 'b', :secret => 'c'
|
62
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should == '2'
|
63
|
+
|
64
|
+
## double check it's working as expected ...
|
65
|
+
|
66
|
+
app = lambda {|env| [200, {}, [ Rack::OAuth.all(env).keys ]] }
|
67
|
+
|
68
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
69
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('foo')
|
70
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should_not include('bar')
|
71
|
+
|
72
|
+
oauth = Rack::OAuth.new oauth, :bar, :site => 'a', :key => 'b', :secret => 'c'
|
73
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('foo')
|
74
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include('bar')
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should be able to get the login path for an instance (so we can easily redirect from the app)' do
|
78
|
+
pending
|
79
|
+
oauth = Rack::OAuth.new app, :foo, :site => 'a', :key => 'b', :secret => 'c'
|
80
|
+
oauth.login_path
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# path getters should join the name of the Rack::OAuth. setters shouldn't include the name.
|
85
|
+
it 'login path should be namespaced to the name of the Rack::OAuth instance' do
|
86
|
+
app = lambda {|env| [200, {}, ["Hello World"]] }
|
87
|
+
|
88
|
+
# the default name doesn't have its name appended. we assume 'default' for this.
|
89
|
+
Rack::OAuth.new(app, :site => 'a', :key => 'b', :secret => 'c').login_path.should == '/oauth_login'
|
90
|
+
|
91
|
+
Rack::OAuth.new(app, :foo, :site => 'a', :key => 'b', :secret => 'c').login_path.should == '/oauth_login/foo'
|
92
|
+
|
93
|
+
oauth = Rack::OAuth.new(app, :bar, :site => 'a', :key => 'b', :secret => 'c', :login_path => '/twitter_login')
|
94
|
+
oauth.login_path.should == '/twitter_login/bar'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'callback path should be namespaced to the name of the Rack::OAuth instance' do
|
98
|
+
app = lambda {|env| [200, {}, ["Hello World"]] }
|
99
|
+
|
100
|
+
# the default name doesn't have its name appended. we assume 'default' for this.
|
101
|
+
Rack::OAuth.new(app, :site => 'a', :key => 'b', :secret => 'c').callback_path.should == '/oauth_callback'
|
102
|
+
|
103
|
+
Rack::OAuth.new(app, :foo, :site => 'a', :key => 'b', :secret => 'c').callback_path.should == '/oauth_callback/foo'
|
104
|
+
|
105
|
+
oauth = Rack::OAuth.new(app, :bar, :site => 'a', :key => 'b', :secret => 'c', :callback_path => '/twitter_callback')
|
106
|
+
oauth.callback_path.should == '/twitter_callback/bar'
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'redirect_to should NOT be namespaced to the name of the Rack::OAuth instance' do
|
110
|
+
app = lambda {|env| [200, {}, ["Hello World"]] }
|
111
|
+
|
112
|
+
# the default name doesn't have its name appended. we assume 'default' for this.
|
113
|
+
Rack::OAuth.new(app, :site => 'a', :key => 'b', :secret => 'c').redirect_to.should == '/oauth_complete'
|
114
|
+
|
115
|
+
Rack::OAuth.new(app, :foo, :site => 'a', :key => 'b', :secret => 'c').redirect_to.should == '/oauth_complete'
|
116
|
+
|
117
|
+
oauth = Rack::OAuth.new(app, :bar, :site => 'a', :key => 'b', :secret => 'c', :redirect_to => '/twitter_login_complete')
|
118
|
+
oauth.redirect_to.should == '/twitter_login_complete'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'session variables should all be namespaced to the name of the Rack::OAuth instance'
|
122
|
+
|
123
|
+
it 'should explodify with a helpful message if 2 Rack::OAuths are instantiated with the same name (?)'
|
124
|
+
|
125
|
+
describe 'Mocked requests / responses and whatnot' do
|
126
|
+
|
127
|
+
it 'the Rack::OAuth#consumer should persist through requests (confirm this is true because we need it to be true for mocking purposes)' do
|
128
|
+
app = lambda {|env| [200, {}, [ Rack::OAuth.get(env).consumer.object_id.to_s ]] }
|
129
|
+
oauth = Rack::OAuth.new app, :site => 'a', :key => 'b', :secret => 'c'
|
130
|
+
|
131
|
+
consumer_id = oauth.consumer.object_id
|
132
|
+
|
133
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include(consumer_id.to_s)
|
134
|
+
oauth.consumer.object_id.should == consumer_id
|
135
|
+
|
136
|
+
# do another request to make sure it stays the same
|
137
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/').body.should include(consumer_id.to_s)
|
138
|
+
oauth.consumer.object_id.should == consumer_id
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should redirect to the authorize_url of the OAuth::RequestToken returned by consumer.get_request_token' do
|
142
|
+
app = lambda {|env| [200, {}, ["Hello World"]] }
|
143
|
+
oauth = Rack::OAuth.new app, :site => 'a', :key => 'b', :secret => 'c'
|
144
|
+
|
145
|
+
oauth.consumer.should_receive(:get_request_token).with(:oauth_callback => 'http://foo.com/oauth_callback').
|
146
|
+
and_return(mock_request_token(:authorize_path => '/silly_path'))
|
147
|
+
|
148
|
+
RackBox.request(Rack::Session::Cookie.new(oauth), '/oauth_login', 'HTTP_HOST' => 'foo.com').
|
149
|
+
headers['Location'].should =~ /^http:\/\/twitter\.com\/silly_path\?oauth_token=/
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should get an access token that can be used to make arbitrary requests if the callback_path is hit with the right variables given'
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|