Ignore coverage data
[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     post "/oauth/authorize",
57          :oauth_token => token.token,
58          :allow_read_prefs => true, :allow_write_prefs => true
59     if client.callback_url
60       assert_response :redirect
61       assert_redirected_to "#{client.callback_url}?oauth_token=#{token.token}"
62     else
63       assert_response :success
64       assert_template :authorize_success
65     end
66     token.reload
67     assert_not_nil token.created_at
68     assert_not_nil token.authorized_at
69     assert_nil token.invalidated_at
70     assert_allowed token, [:allow_read_prefs]
71
72     signed_get "/oauth/access_token", :consumer => client, :token => token
73     assert_response :success
74     token.reload
75     assert_not_nil token.created_at
76     assert_not_nil token.authorized_at
77     assert_not_nil token.invalidated_at
78     token = parse_token(response)
79     assert_instance_of AccessToken, token
80     assert_not_nil token.created_at
81     assert_not_nil token.authorized_at
82     assert_nil token.invalidated_at
83     assert_allowed token, [:allow_read_prefs]
84
85     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
86     assert_response :success
87
88     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
89     assert_response :forbidden
90
91     post "/oauth/revoke", :token => token.token
92     assert_redirected_to oauth_clients_url(token.user.display_name)
93     token = OauthToken.find_by_token(token.token)
94     assert_not_nil token.invalidated_at
95
96     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
97     assert_response :unauthorized
98   end
99
100   def oauth10_refused(client)
101     token = get_request_token(client)
102
103     post "/oauth/authorize", :oauth_token => token.token
104     assert_response :success
105     assert_template :authorize_failure
106     assert_select "p", "You have denied application #{client.name} access to your account."
107     token.reload
108     assert_nil token.authorized_at
109     assert_not_nil token.invalidated_at
110
111     post "/oauth/authorize", :oauth_token => token.token
112     assert_response :success
113     assert_template :authorize_failure
114     assert_select "p", "The authorization token is not valid."
115     token.reload
116     assert_nil token.authorized_at
117     assert_not_nil token.invalidated_at
118   end
119
120   def oauth10_with_callback(client, callback_url)
121     token = get_request_token(client)
122
123     post "/oauth/authorize",
124          :oauth_token => token.token, :oauth_callback => callback_url,
125          :allow_write_api => true, :allow_read_gpx => true
126     assert_response :redirect
127     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}"
128     token.reload
129     assert_not_nil token.created_at
130     assert_not_nil token.authorized_at
131     assert_nil token.invalidated_at
132     assert_allowed token, [:allow_write_api, :allow_read_gpx]
133
134     signed_get "/oauth/access_token", :consumer => client, :token => token
135     assert_response :success
136     token.reload
137     assert_not_nil token.created_at
138     assert_not_nil token.authorized_at
139     assert_not_nil token.invalidated_at
140     token = parse_token(response)
141     assert_instance_of AccessToken, token
142     assert_not_nil token.created_at
143     assert_not_nil token.authorized_at
144     assert_nil token.invalidated_at
145     assert_allowed token, [:allow_write_api, :allow_read_gpx]
146
147     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
148     assert_response :success
149
150     signed_get "/api/0.6/user/details", :consumer => client, :token => token
151     assert_response :forbidden
152
153     post "/oauth/revoke", :token => token.token
154     assert_redirected_to oauth_clients_url(token.user.display_name)
155     token = OauthToken.find_by_token(token.token)
156     assert_not_nil token.invalidated_at
157
158     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
159     assert_response :unauthorized
160   end
161
162   def oauth10a_without_callback(client)
163     token = get_request_token(client, :oauth_callback => "oob")
164
165     post "/oauth/authorize",
166          :oauth_token => token.token,
167          :allow_read_prefs => true, :allow_write_prefs => true
168     if client.callback_url
169       assert_response :redirect
170       verifier = parse_verifier(response)
171       assert_redirected_to "http://some.web.app.org/callback?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
172     else
173       assert_response :success
174       assert_template :authorize_success
175       m = response.body.match("<p>The verification code is ([A-Za-z0-9]+).</p>")
176       assert_not_nil m
177       verifier = m[1]
178     end
179     token.reload
180     assert_not_nil token.created_at
181     assert_not_nil token.authorized_at
182     assert_nil token.invalidated_at
183     assert_allowed token, [:allow_read_prefs]
184
185     signed_get "/oauth/access_token", :consumer => client, :token => token
186     assert_response :unauthorized
187
188     signed_get "/oauth/access_token",
189                :consumer => client, :token => token, :oauth_verifier => verifier
190     assert_response :success
191     token.reload
192     assert_not_nil token.created_at
193     assert_not_nil token.authorized_at
194     assert_not_nil token.invalidated_at
195     token = parse_token(response)
196     assert_instance_of AccessToken, token
197     assert_not_nil token.created_at
198     assert_not_nil token.authorized_at
199     assert_nil token.invalidated_at
200     assert_allowed token, [:allow_read_prefs]
201
202     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
203     assert_response :success
204
205     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
206     assert_response :forbidden
207
208     post "/oauth/revoke", :token => token.token
209     assert_redirected_to oauth_clients_url(token.user.display_name)
210     token = OauthToken.find_by_token(token.token)
211     assert_not_nil token.invalidated_at
212
213     signed_get "/api/0.6/user/preferences", :consumer => client, :token => token
214     assert_response :unauthorized
215   end
216
217   def oauth10a_with_callback(client, callback_url)
218     token = get_request_token(client, :oauth_callback => callback_url)
219
220     post "/oauth/authorize",
221          :oauth_token => token.token,
222          :allow_write_api => true, :allow_read_gpx => true
223     assert_response :redirect
224     verifier = parse_verifier(response)
225     assert_redirected_to "#{callback_url}?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
226     token.reload
227     assert_not_nil token.created_at
228     assert_not_nil token.authorized_at
229     assert_nil token.invalidated_at
230     assert_allowed token, [:allow_write_api, :allow_read_gpx]
231
232     signed_get "/oauth/access_token", :consumer => client, :token => token
233     assert_response :unauthorized
234
235     signed_get "/oauth/access_token",
236                :consumer => client, :token => token, :oauth_verifier => verifier
237     assert_response :success
238     token.reload
239     assert_not_nil token.created_at
240     assert_not_nil token.authorized_at
241     assert_not_nil token.invalidated_at
242     token = parse_token(response)
243     assert_instance_of AccessToken, token
244     assert_not_nil token.created_at
245     assert_not_nil token.authorized_at
246     assert_nil token.invalidated_at
247     assert_allowed token, [:allow_write_api, :allow_read_gpx]
248
249     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
250     assert_response :success
251
252     signed_get "/api/0.6/user/details", :consumer => client, :token => token
253     assert_response :forbidden
254
255     post "/oauth/revoke", :token => token.token
256     assert_redirected_to oauth_clients_url(token.user.display_name)
257     token = OauthToken.find_by_token(token.token)
258     assert_not_nil token.invalidated_at
259
260     signed_get "/api/0.6/gpx/2", :consumer => client, :token => token
261     assert_response :unauthorized
262   end
263
264   def oauth10a_refused(client)
265     token = get_request_token(client, :oauth_callback => "oob")
266
267     post "/oauth/authorize", :oauth_token => token.token
268     assert_response :success
269     assert_template :authorize_failure
270     assert_select "p", "You have denied application #{client.name} access to your account."
271     token.reload
272     assert_nil token.authorized_at
273     assert_not_nil token.invalidated_at
274
275     post "/oauth/authorize", :oauth_token => token.token
276     assert_response :success
277     assert_template :authorize_failure
278     assert_select "p", "The authorization token is not valid."
279     token.reload
280     assert_nil token.authorized_at
281     assert_not_nil token.invalidated_at
282   end
283
284   def get_request_token(client, options = {})
285     signed_get "/oauth/request_token", options.merge(:consumer => client)
286     assert_response :success
287     token = parse_token(response)
288     assert_instance_of RequestToken, token
289     assert_not_nil token.created_at
290     assert_nil token.authorized_at
291     assert_nil token.invalidated_at
292     assert_allowed token, client.permissions
293
294     token
295   end
296
297   def signed_get(uri, options)
298     uri = URI.parse(uri)
299     uri.scheme ||= "http"
300     uri.host ||= "www.example.com"
301
302     helper = OAuth::Client::Helper.new(nil, options)
303
304     request = OAuth::RequestProxy.proxy(
305       "method" => "GET",
306       "uri" => uri,
307       "parameters" => helper.oauth_parameters
308     )
309
310     request.sign!(options)
311
312     get request.signed_uri
313   end
314
315   def parse_token(response)
316     params = CGI.parse(response.body)
317
318     token = OauthToken.find_by_token(params["oauth_token"].first)
319     assert_equal token.secret, params["oauth_token_secret"].first
320
321     token
322   end
323
324   def parse_verifier(response)
325     params = CGI.parse(URI.parse(response.location).query)
326
327     assert_not_nil params["oauth_verifier"]
328     assert params["oauth_verifier"].first.present?
329
330     params["oauth_verifier"].first
331   end
332
333   def assert_allowed(token, allowed)
334     ClientApplication.all_permissions.each do |p|
335       assert_equal allowed.include?(p), token.attributes[p.to_s]
336     end
337   end
338 end