diff --git a/test/controllers/active_storage/direct_uploads_controller_test.rb b/test/controllers/active_storage/direct_uploads_controller_test.rb index f614f2e..7765839 100644 --- a/test/controllers/active_storage/direct_uploads_controller_test.rb +++ b/test/controllers/active_storage/direct_uploads_controller_test.rb @@ -34,10 +34,46 @@ class ActiveStorage::DirectUploadsControllerTest < ActionDispatch::IntegrationTe assert_response :success end + test "disk update requires authentication" do + put direct_upload_url_for("hello"), params: "hello", headers: { "Content-Type" => "text/plain" } + + assert_redirected_to new_session_url + end + + test "disk update stores bytes for an authenticated session without a CSRF token" do + sign_in :david + url = direct_upload_url_for("hello") + + # Forgery protection is off in test by default; turn it on so this proves the + # signed-token service PUT stays CSRF-exempt even when the concern re-arms it. + with_forgery_protection do + put url, params: "hello", headers: { "Content-Type" => "text/plain" } + end + + assert_response :no_content + end + private def blob_params content = "hello" { filename: "hello.txt", byte_size: content.bytesize, content_type: "text/plain", \ checksum: Digest::MD5.base64digest(content) } end + + def direct_upload_url_for(content) + blob = ActiveStorage::Blob.create_before_direct_upload! \ + filename: "hello.txt", byte_size: content.bytesize, \ + checksum: Digest::MD5.base64digest(content), content_type: "text/plain" + ActiveStorage::Current.set(url_options: { host: "once.campfire.test", protocol: "http" }) do + blob.service_url_for_direct_upload + end + end + + def with_forgery_protection + original = ActionController::Base.allow_forgery_protection + ActionController::Base.allow_forgery_protection = true + yield + ensure + ActionController::Base.allow_forgery_protection = original + end end