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