Merged updates from trunk into stable branch
[feedcatcher.git] / vendor / rails / actionpack / test / controller / request_forgery_protection_test.rb
1 require 'abstract_unit'
2 require 'digest/sha1'
3
4 ActionController::Routing::Routes.draw do |map|
5 map.connect ':controller/:action/:id'
6 end
7
8 # common controller actions
9 module RequestForgeryProtectionActions
10 def index
11 render :inline => "<%= form_tag('/') {} %>"
12 end
13
14 def show_button
15 render :inline => "<%= button_to('New', '/') {} %>"
16 end
17
18 def remote_form
19 render :inline => "<% form_remote_tag(:url => '/') {} %>"
20 end
21
22 def unsafe
23 render :text => 'pwn'
24 end
25
26 def rescue_action(e) raise e end
27 end
28
29 # sample controllers
30 class RequestForgeryProtectionController < ActionController::Base
31 include RequestForgeryProtectionActions
32 protect_from_forgery :only => :index
33 end
34
35 class FreeCookieController < RequestForgeryProtectionController
36 self.allow_forgery_protection = false
37
38 def index
39 render :inline => "<%= form_tag('/') {} %>"
40 end
41
42 def show_button
43 render :inline => "<%= button_to('New', '/') {} %>"
44 end
45 end
46
47 # common test methods
48
49 module RequestForgeryProtectionTests
50 def teardown
51 ActionController::Base.request_forgery_protection_token = nil
52 end
53
54
55 def test_should_render_form_with_token_tag
56 get :index
57 assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
58 end
59
60 def test_should_render_button_to_with_token_tag
61 get :show_button
62 assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
63 end
64
65 def test_should_render_remote_form_with_only_one_token_parameter
66 get :remote_form
67 assert_equal 1, @response.body.scan(@token).size
68 end
69
70 def test_should_allow_get
71 get :index
72 assert_response :success
73 end
74
75 def test_should_allow_post_without_token_on_unsafe_action
76 post :unsafe
77 assert_response :success
78 end
79
80 def test_should_not_allow_html_post_without_token
81 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
82 assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
83 end
84
85 def test_should_not_allow_html_put_without_token
86 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
87 assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
88 end
89
90 def test_should_not_allow_html_delete_without_token
91 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
92 assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
93 end
94
95 def test_should_allow_api_formatted_post_without_token
96 assert_nothing_raised do
97 post :index, :format => 'xml'
98 end
99 end
100
101 def test_should_not_allow_api_formatted_put_without_token
102 assert_nothing_raised do
103 put :index, :format => 'xml'
104 end
105 end
106
107 def test_should_allow_api_formatted_delete_without_token
108 assert_nothing_raised do
109 delete :index, :format => 'xml'
110 end
111 end
112
113 def test_should_not_allow_api_formatted_post_sent_as_url_encoded_form_without_token
114 assert_raise(ActionController::InvalidAuthenticityToken) do
115 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
116 post :index, :format => 'xml'
117 end
118 end
119
120 def test_should_not_allow_api_formatted_put_sent_as_url_encoded_form_without_token
121 assert_raise(ActionController::InvalidAuthenticityToken) do
122 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
123 put :index, :format => 'xml'
124 end
125 end
126
127 def test_should_not_allow_api_formatted_delete_sent_as_url_encoded_form_without_token
128 assert_raise(ActionController::InvalidAuthenticityToken) do
129 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
130 delete :index, :format => 'xml'
131 end
132 end
133
134 def test_should_not_allow_api_formatted_post_sent_as_multipart_form_without_token
135 assert_raise(ActionController::InvalidAuthenticityToken) do
136 @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
137 post :index, :format => 'xml'
138 end
139 end
140
141 def test_should_not_allow_api_formatted_put_sent_as_multipart_form_without_token
142 assert_raise(ActionController::InvalidAuthenticityToken) do
143 @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
144 put :index, :format => 'xml'
145 end
146 end
147
148 def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_token
149 assert_raise(ActionController::InvalidAuthenticityToken) do
150 @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
151 delete :index, :format => 'xml'
152 end
153 end
154
155 def test_should_allow_xhr_post_without_token
156 assert_nothing_raised { xhr :post, :index }
157 end
158 def test_should_not_allow_xhr_post_with_html_without_token
159 @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
160 assert_raise(ActionController::InvalidAuthenticityToken) { xhr :post, :index }
161 end
162
163 def test_should_allow_xhr_put_without_token
164 assert_nothing_raised { xhr :put, :index }
165 end
166
167 def test_should_allow_xhr_delete_without_token
168 assert_nothing_raised { xhr :delete, :index }
169 end
170
171 def test_should_allow_post_with_token
172 post :index, :authenticity_token => @token
173 assert_response :success
174 end
175
176 def test_should_allow_put_with_token
177 put :index, :authenticity_token => @token
178 assert_response :success
179 end
180
181 def test_should_allow_delete_with_token
182 delete :index, :authenticity_token => @token
183 assert_response :success
184 end
185
186 def test_should_allow_post_with_xml
187 @request.env['CONTENT_TYPE'] = Mime::XML.to_s
188 post :index, :format => 'xml'
189 assert_response :success
190 end
191
192 def test_should_allow_put_with_xml
193 @request.env['CONTENT_TYPE'] = Mime::XML.to_s
194 put :index, :format => 'xml'
195 assert_response :success
196 end
197
198 def test_should_allow_delete_with_xml
199 @request.env['CONTENT_TYPE'] = Mime::XML.to_s
200 delete :index, :format => 'xml'
201 assert_response :success
202 end
203 end
204
205 # OK let's get our test on
206
207 class RequestForgeryProtectionControllerTest < ActionController::TestCase
208 include RequestForgeryProtectionTests
209 def setup
210 @controller = RequestForgeryProtectionController.new
211 @request = ActionController::TestRequest.new
212 @request.format = :html
213 @response = ActionController::TestResponse.new
214 @token = "cf50faa3fe97702ca1ae"
215
216 ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
217 ActionController::Base.request_forgery_protection_token = :authenticity_token
218 end
219 end
220
221 class FreeCookieControllerTest < ActionController::TestCase
222 def setup
223 @controller = FreeCookieController.new
224 @request = ActionController::TestRequest.new
225 @response = ActionController::TestResponse.new
226 @token = "cf50faa3fe97702ca1ae"
227
228 ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
229 end
230
231 def test_should_not_render_form_with_token_tag
232 get :index
233 assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
234 end
235
236 def test_should_not_render_button_to_with_token_tag
237 get :show_button
238 assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
239 end
240
241 def test_should_allow_all_methods_without_token
242 [:post, :put, :delete].each do |method|
243 assert_nothing_raised { send(method, :index)}
244 end
245 end
246 end