Work around upcoming minitest insanity
[rails.git] / test / integration / oauth_test.rb
1 require "test_helper"
2
3 class OAuthTest < ActionDispatch::IntegrationTest
4   fixtures :users, :client_applications, :gpx_files
5   set_fixture_class :gpx_files => Trace
6
7   include OAuth::Helper
8
9   def setup
10     stub_hostip_requests
11   end
12
13   def test_oauth10_web_app
14     client = client_applications(:oauth_web_app)
15
16     post_via_redirect "/login", :username => client.user.email, :password => "test"
17     assert_response :success
18
19     oauth10_without_callback(client)
20     oauth10_with_callback(client, "http://another.web.app.org/callback")
21     oauth10_refused(client)
22   end
23
24   def test_oauth10_desktop_app
25     client = client_applications(:oauth_desktop_app)
26
27     post_via_redirect "/login", :username => client.user.email, :password => "test"
28     assert_response :success
29
30     oauth10_without_callback(client)
31     oauth10_refused(client)
32   end
33
34   def test_oauth10a_web_app
35     client = client_applications(:oauth_web_app)
36
37     post_via_redirect "/login", :username => client.user.email, :password => "test"
38     assert_response :success
39
40     oauth10a_without_callback(client)
41     oauth10a_with_callback(client, "http://another.web.app.org/callback")
42     oauth10a_refused(client)
43   end
44
45   def test_oauth10a_desktop_app
46     client = client_applications(:oauth_desktop_app)
47
48     post_via_redirect "/login", :username => client.user.email, :password => "test"
49     assert_response :success
50
51     oauth10a_without_callback(client)
52     oauth10a_refused(client)
53   end
54
55   private
56
57   def oauth10_without_callback(client)
58     token = get_request_token(client)
59
60     get "/oauth/authorize", :oauth_token => token.token
61     assert_response :success
62     assert_template :authorize
63
64     post "/oauth/authorize",
65          :oauth_token => token.token,
66          :allow_read_prefs => true, :allow_write_prefs => true
67     if client.callback_url
68       assert_response :redirect
69       assert_redirected_to "#{client.callback_url}?oauth_token=#{token.token}"
70     else
71       assert_response :success
72       assert_template :authorize_success
73     end
74     token.reload
75     assert_not_nil token.created_at
76     assert_not_nil token.authorized_at
77     assert_nil token.invalidated_at
78     assert_allowed token, [:allow_read_prefs]
79
80     signed_get "/oauth/access_token", :consumer => client, :token => token
81     assert_response :success
82     token.reload
83     assert_not_nil token.created_at
84     assert_not_nil token.authorized_at
85     assert_not_nil token.invalidated_at
86     token = parse_token(response)
87     assert_instance_of AccessToken, token
88     assert_not_nil token.created_at
89     assert_not_nil token.authorized_at
90     assert_nil token.invalidated_at
91     assert_allowed token, [:allow_read_prefs]
92
93     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
94     assert_response :success
95
96     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
97     assert_response :forbidden
98
99     post "/oauth/revoke", :token => token.token
100     assert_redirected_to oauth_clients_url(token.user.display_name)
101     token = OauthToken.find_by(:token => token.token)
102     assert_not_nil token.invalidated_at
103
104     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
105     assert_response :unauthorized
106   end
107
108   def oauth10_refused(client)
109     token = get_request_token(client)
110
111     get "/oauth/authorize", :oauth_token => token.token
112     assert_response :success
113     assert_template :authorize
114
115     post "/oauth/authorize", :oauth_token => token.token
116     assert_response :success
117     assert_template :authorize_failure
118     assert_select "p", "You have denied application #{client.name} access to your account."
119     token.reload
120     assert_nil token.authorized_at
121     assert_not_nil token.invalidated_at
122
123     get "/oauth/authorize", :oauth_token => token.token
124     assert_response :success
125     assert_template :authorize_failure
126     assert_select "p", "The authorization token is not valid."
127     token.reload
128     assert_nil token.authorized_at
129     assert_not_nil token.invalidated_at
130
131     post "/oauth/authorize", :oauth_token => token.token
132     assert_response :success
133     assert_template :authorize_failure
134     assert_select "p", "The authorization token is not valid."
135     token.reload
136     assert_nil token.authorized_at
137     assert_not_nil token.invalidated_at
138   end
139
140   def oauth10_with_callback(client, callback_url)
141     token = get_request_token(client)
142
143     get "/oauth/authorize", :oauth_token => token.token
144     assert_response :success
145     assert_template :authorize
146
147     post "/oauth/authorize",
148          :oauth_token => token.token, :oauth_callback => callback_url,
149          :allow_write_api => true, :allow_read_gpx => true
150     assert_response :redirect
151     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}"
152     token.reload
153     assert_not_nil token.created_at
154     assert_not_nil token.authorized_at
155     assert_nil token.invalidated_at
156     assert_allowed token, [:allow_write_api, :allow_read_gpx]
157
158     signed_get "/oauth/access_token", :consumer => client, :token => token
159     assert_response :success
160     token.reload
161     assert_not_nil token.created_at
162     assert_not_nil token.authorized_at
163     assert_not_nil token.invalidated_at
164     token = parse_token(response)
165     assert_instance_of AccessToken, token
166     assert_not_nil token.created_at
167     assert_not_nil token.authorized_at
168     assert_nil token.invalidated_at
169     assert_allowed token, [:allow_write_api, :allow_read_gpx]
170
171     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
172     assert_response :success
173
174     signed_get "/api/0.6/user/details", :consumer => client, :token => token
175     assert_response :forbidden
176
177     post "/oauth/revoke", :token => token.token
178     assert_redirected_to oauth_clients_url(token.user.display_name)
179     token = OauthToken.find_by(:token => token.token)
180     assert_not_nil token.invalidated_at
181
182     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
183     assert_response :unauthorized
184   end
185
186   def oauth10a_without_callback(client)
187     token = get_request_token(client, :oauth_callback => "oob")
188
189     get "/oauth/authorize", :oauth_token => token.token
190     assert_response :success
191     assert_template :authorize
192
193     post "/oauth/authorize",
194          :oauth_token => token.token,
195          :allow_read_prefs => true, :allow_write_prefs => true
196     if client.callback_url
197       assert_response :redirect
198       verifier = parse_verifier(response)
199       assert_redirected_to "http://some.web.app.org/callback?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
200     else
201       assert_response :success
202       assert_template :authorize_success
203       m = response.body.match("<p>The verification code is ([A-Za-z0-9]+).</p>")
204       assert_not_nil m
205       verifier = m[1]
206     end
207     token.reload
208     assert_not_nil token.created_at
209     assert_not_nil token.authorized_at
210     assert_nil token.invalidated_at
211     assert_allowed token, [:allow_read_prefs]
212
213     signed_get "/oauth/access_token", :consumer => client, :token => token
214     assert_response :unauthorized
215
216     signed_get "/oauth/access_token",
217                :consumer => client, :token => token, :oauth_verifier => verifier
218     assert_response :success
219     token.reload
220     assert_not_nil token.created_at
221     assert_not_nil token.authorized_at
222     assert_not_nil token.invalidated_at
223     token = parse_token(response)
224     assert_instance_of AccessToken, token
225     assert_not_nil token.created_at
226     assert_not_nil token.authorized_at
227     assert_nil token.invalidated_at
228     assert_allowed token, [:allow_read_prefs]
229
230     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
231     assert_response :success
232
233     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
234     assert_response :forbidden
235
236     post "/oauth/revoke", :token => token.token
237     assert_redirected_to oauth_clients_url(token.user.display_name)
238     token = OauthToken.find_by(:token => token.token)
239     assert_not_nil token.invalidated_at
240
241     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
242     assert_response :unauthorized
243   end
244
245   def oauth10a_with_callback(client, callback_url)
246     token = get_request_token(client, :oauth_callback => callback_url)
247
248     get "/oauth/authorize", :oauth_token => token.token
249     assert_response :success
250     assert_template :authorize
251
252     post "/oauth/authorize",
253          :oauth_token => token.token,
254          :allow_write_api => true, :allow_read_gpx => true
255     assert_response :redirect
256     verifier = parse_verifier(response)
257     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
258     token.reload
259     assert_not_nil token.created_at
260     assert_not_nil token.authorized_at
261     assert_nil token.invalidated_at
262     assert_allowed token, [:allow_write_api, :allow_read_gpx]
263
264     signed_get "/oauth/access_token", :consumer => client, :token => token
265     assert_response :unauthorized
266
267     signed_get "/oauth/access_token",
268                :consumer => client, :token => token, :oauth_verifier => verifier
269     assert_response :success
270     token.reload
271     assert_not_nil token.created_at
272     assert_not_nil token.authorized_at
273     assert_not_nil token.invalidated_at
274     token = parse_token(response)
275     assert_instance_of AccessToken, token
276     assert_not_nil token.created_at
277     assert_not_nil token.authorized_at
278     assert_nil token.invalidated_at
279     assert_allowed token, [:allow_write_api, :allow_read_gpx]
280
281     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
282     assert_response :success
283
284     signed_get "/api/0.6/user/details", :consumer => client, :token => token
285     assert_response :forbidden
286
287     post "/oauth/revoke", :token => token.token
288     assert_redirected_to oauth_clients_url(token.user.display_name)
289     token = OauthToken.find_by(:token => token.token)
290     assert_not_nil token.invalidated_at
291
292     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
293     assert_response :unauthorized
294   end
295
296   def oauth10a_refused(client)
297     token = get_request_token(client, :oauth_callback => "oob")
298
299     get "/oauth/authorize", :oauth_token => token.token
300     assert_response :success
301     assert_template :authorize
302
303     post "/oauth/authorize", :oauth_token => token.token
304     assert_response :success
305     assert_template :authorize_failure
306     assert_select "p", "You have denied application #{client.name} access to your account."
307     token.reload
308     assert_nil token.authorized_at
309     assert_not_nil token.invalidated_at
310
311     get "/oauth/authorize", :oauth_token => token.token
312     assert_response :success
313     assert_template :authorize_failure
314     assert_select "p", "The authorization token is not valid."
315     token.reload
316     assert_nil token.authorized_at
317     assert_not_nil token.invalidated_at
318
319     post "/oauth/authorize", :oauth_token => token.token
320     assert_response :success
321     assert_template :authorize_failure
322     assert_select "p", "The authorization token is not valid."
323     token.reload
324     assert_nil token.authorized_at
325     assert_not_nil token.invalidated_at
326   end
327
328   def get_request_token(client, options = {})
329     signed_get "/oauth/request_token", options.merge(:consumer => client)
330     assert_response :success
331     token = parse_token(response)
332     assert_instance_of RequestToken, token
333     assert_not_nil token.created_at
334     assert_nil token.authorized_at
335     assert_nil token.invalidated_at
336     assert_equal_allowing_nil options[:oauth_callback], token.callback_url
337     assert_allowed token, client.permissions
338
339     token
340   end
341
342   def signed_get(uri, options)
343     uri = URI.parse(uri)
344     uri.scheme ||= "http"
345     uri.host ||= "www.example.com"
346
347     helper = OAuth::Client::Helper.new(nil, options)
348
349     request = OAuth::RequestProxy.proxy(
350       "method" => "GET",
351       "uri" => uri,
352       "parameters" => helper.oauth_parameters
353     )
354
355     request.sign!(options)
356
357     get request.signed_uri
358   end
359
360   def parse_token(response)
361     params = CGI.parse(response.body)
362
363     token = OauthToken.find_by(:token => params["oauth_token"].first)
364     assert_equal token.secret, params["oauth_token_secret"].first
365
366     token
367   end
368
369   def parse_verifier(response)
370     params = CGI.parse(URI.parse(response.location).query)
371
372     assert_not_nil params["oauth_verifier"]
373     assert params["oauth_verifier"].first.present?
374
375     params["oauth_verifier"].first
376   end
377
378   def assert_allowed(token, allowed)
379     ClientApplication.all_permissions.each do |p|
380       assert_equal allowed.include?(p), token.attributes[p.to_s]
381     end
382   end
383 end