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