Refactor the oauth integration test to avoid using user fixtures.
[rails.git] / test / integration / oauth_test.rb
1 require "test_helper"
2
3 class OAuthTest < ActionDispatch::IntegrationTest
4   include OAuth::Helper
5
6   def setup
7     stub_hostip_requests
8   end
9
10   def test_oauth10_web_app
11     client = create(:client_application, :callback_url => "http://some.web.app.example.org/callback", :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
12
13     post_via_redirect "/login", :username => client.user.email, :password => "test"
14     assert_response :success
15
16     oauth10_without_callback(client)
17     oauth10_with_callback(client, "http://another.web.app.example.org/callback")
18     oauth10_refused(client)
19   end
20
21   def test_oauth10_desktop_app
22     client = create(:client_application, :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
23
24     post_via_redirect "/login", :username => client.user.email, :password => "test"
25     assert_response :success
26
27     oauth10_without_callback(client)
28     oauth10_refused(client)
29   end
30
31   def test_oauth10a_web_app
32     client = create(:client_application, :callback_url => "http://some.web.app.example.org/callback", :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
33
34     post_via_redirect "/login", :username => client.user.email, :password => "test"
35     assert_response :success
36
37     oauth10a_without_callback(client)
38     oauth10a_with_callback(client, "http://another.web.app.example.org/callback")
39     oauth10a_refused(client)
40   end
41
42   def test_oauth10a_desktop_app
43     client = create(:client_application, :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
44
45     post_via_redirect "/login", :username => client.user.email, :password => "test"
46     assert_response :success
47
48     oauth10a_without_callback(client)
49     oauth10a_refused(client)
50   end
51
52   private
53
54   def oauth10_without_callback(client)
55     token = get_request_token(client)
56
57     get "/oauth/authorize", :oauth_token => token.token
58     assert_response :success
59     assert_template :authorize
60
61     post "/oauth/authorize",
62          :oauth_token => token.token,
63          :allow_read_prefs => true, :allow_write_prefs => true
64     if client.callback_url
65       assert_response :redirect
66       assert_redirected_to "#{client.callback_url}?oauth_token=#{token.token}"
67     else
68       assert_response :success
69       assert_template :authorize_success
70     end
71     token.reload
72     assert_not_nil token.created_at
73     assert_not_nil token.authorized_at
74     assert_nil token.invalidated_at
75     assert_allowed token, [:allow_read_prefs]
76
77     signed_get "/oauth/access_token", :consumer => client, :token => token
78     assert_response :success
79     token.reload
80     assert_not_nil token.created_at
81     assert_not_nil token.authorized_at
82     assert_not_nil token.invalidated_at
83     token = parse_token(response)
84     assert_instance_of AccessToken, token
85     assert_not_nil token.created_at
86     assert_not_nil token.authorized_at
87     assert_nil token.invalidated_at
88     assert_allowed token, [:allow_read_prefs]
89
90     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
91     assert_response :success
92
93     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
94     assert_response :forbidden
95
96     post "/oauth/revoke", :token => token.token
97     assert_redirected_to oauth_clients_url(token.user.display_name)
98     token = OauthToken.find_by(:token => token.token)
99     assert_not_nil token.invalidated_at
100
101     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
102     assert_response :unauthorized
103   end
104
105   def oauth10_refused(client)
106     token = get_request_token(client)
107
108     get "/oauth/authorize", :oauth_token => token.token
109     assert_response :success
110     assert_template :authorize
111
112     post "/oauth/authorize", :oauth_token => token.token
113     assert_response :success
114     assert_template :authorize_failure
115     assert_select "p", "You have denied application #{client.name} access to your account."
116     token.reload
117     assert_nil token.authorized_at
118     assert_not_nil token.invalidated_at
119
120     get "/oauth/authorize", :oauth_token => token.token
121     assert_response :success
122     assert_template :authorize_failure
123     assert_select "p", "The authorization token is not valid."
124     token.reload
125     assert_nil token.authorized_at
126     assert_not_nil token.invalidated_at
127
128     post "/oauth/authorize", :oauth_token => token.token
129     assert_response :success
130     assert_template :authorize_failure
131     assert_select "p", "The authorization token is not valid."
132     token.reload
133     assert_nil token.authorized_at
134     assert_not_nil token.invalidated_at
135   end
136
137   def oauth10_with_callback(client, callback_url)
138     token = get_request_token(client)
139
140     get "/oauth/authorize", :oauth_token => token.token
141     assert_response :success
142     assert_template :authorize
143
144     post "/oauth/authorize",
145          :oauth_token => token.token, :oauth_callback => callback_url,
146          :allow_write_api => true, :allow_read_gpx => true
147     assert_response :redirect
148     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}"
149     token.reload
150     assert_not_nil token.created_at
151     assert_not_nil token.authorized_at
152     assert_nil token.invalidated_at
153     assert_allowed token, [:allow_write_api, :allow_read_gpx]
154
155     signed_get "/oauth/access_token", :consumer => client, :token => token
156     assert_response :success
157     token.reload
158     assert_not_nil token.created_at
159     assert_not_nil token.authorized_at
160     assert_not_nil token.invalidated_at
161     token = parse_token(response)
162     assert_instance_of AccessToken, token
163     assert_not_nil token.created_at
164     assert_not_nil token.authorized_at
165     assert_nil token.invalidated_at
166     assert_allowed token, [:allow_write_api, :allow_read_gpx]
167
168     trace = create(:trace, :user => client.user)
169     signed_get "/api/0.6/gpx/#{trace.id}", :consumer => client, :token => token
170     assert_response :success
171
172     signed_get "/api/0.6/user/details", :consumer => client, :token => token
173     assert_response :forbidden
174
175     post "/oauth/revoke", :token => token.token
176     assert_redirected_to oauth_clients_url(token.user.display_name)
177     token = OauthToken.find_by(:token => token.token)
178     assert_not_nil token.invalidated_at
179
180     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
181     assert_response :unauthorized
182   end
183
184   def oauth10a_without_callback(client)
185     token = get_request_token(client, :oauth_callback => "oob")
186
187     get "/oauth/authorize", :oauth_token => token.token
188     assert_response :success
189     assert_template :authorize
190
191     post "/oauth/authorize",
192          :oauth_token => token.token,
193          :allow_read_prefs => true, :allow_write_prefs => true
194     if client.callback_url
195       assert_response :redirect
196       verifier = parse_verifier(response)
197       assert_redirected_to "http://some.web.app.example.org/callback?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
198     else
199       assert_response :success
200       assert_template :authorize_success
201       m = response.body.match("<p>The verification code is ([A-Za-z0-9]+).</p>")
202       assert_not_nil m
203       verifier = m[1]
204     end
205     token.reload
206     assert_not_nil token.created_at
207     assert_not_nil token.authorized_at
208     assert_nil token.invalidated_at
209     assert_allowed token, [:allow_read_prefs]
210
211     signed_get "/oauth/access_token", :consumer => client, :token => token
212     assert_response :unauthorized
213
214     signed_get "/oauth/access_token",
215                :consumer => client, :token => token, :oauth_verifier => verifier
216     assert_response :success
217     token.reload
218     assert_not_nil token.created_at
219     assert_not_nil token.authorized_at
220     assert_not_nil token.invalidated_at
221     token = parse_token(response)
222     assert_instance_of AccessToken, token
223     assert_not_nil token.created_at
224     assert_not_nil token.authorized_at
225     assert_nil token.invalidated_at
226     assert_allowed token, [:allow_read_prefs]
227
228     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
229     assert_response :success
230
231     trace = create(:trace, :user => client.user)
232     signed_get "/api/0.6/gpx/#{trace.id}", :consumer => client, :token => token
233     assert_response :forbidden
234
235     post "/oauth/revoke", :token => token.token
236     assert_redirected_to oauth_clients_url(token.user.display_name)
237     token = OauthToken.find_by(:token => token.token)
238     assert_not_nil token.invalidated_at
239
240     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
241     assert_response :unauthorized
242   end
243
244   def oauth10a_with_callback(client, callback_url)
245     token = get_request_token(client, :oauth_callback => callback_url)
246
247     get "/oauth/authorize", :oauth_token => token.token
248     assert_response :success
249     assert_template :authorize
250
251     post "/oauth/authorize",
252          :oauth_token => token.token,
253          :allow_write_api => true, :allow_read_gpx => true
254     assert_response :redirect
255     verifier = parse_verifier(response)
256     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
257     token.reload
258     assert_not_nil token.created_at
259     assert_not_nil token.authorized_at
260     assert_nil token.invalidated_at
261     assert_allowed token, [:allow_write_api, :allow_read_gpx]
262
263     signed_get "/oauth/access_token", :consumer => client, :token => token
264     assert_response :unauthorized
265
266     signed_get "/oauth/access_token",
267                :consumer => client, :token => token, :oauth_verifier => verifier
268     assert_response :success
269     token.reload
270     assert_not_nil token.created_at
271     assert_not_nil token.authorized_at
272     assert_not_nil token.invalidated_at
273     token = parse_token(response)
274     assert_instance_of AccessToken, token
275     assert_not_nil token.created_at
276     assert_not_nil token.authorized_at
277     assert_nil token.invalidated_at
278     assert_allowed token, [:allow_write_api, :allow_read_gpx]
279
280     trace = create(:trace, :user => client.user)
281     signed_get "/api/0.6/gpx/#{trace.id}", :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