rack-twitter-auth 0.1.5
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/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
|