diff --git a/config/initializers/active_storage.rb b/config/initializers/active_storage.rb index 586c292a16..de3bb4eafe 100644 --- a/config/initializers/active_storage.rb +++ b/config/initializers/active_storage.rb @@ -52,7 +52,7 @@ module ActiveStorageDirectUploadsControllerExtensions included do include Authentication include Authorization - skip_forgery_protection if: :authenticate_by_bearer_token + skip_forgery_protection if: -> { authenticate_by_bearer_token || (resume_session && request.format.json?) } end end diff --git a/test/controllers/active_storage/direct_uploads_controller_test.rb b/test/controllers/active_storage/direct_uploads_controller_test.rb index f52d343210..2fbcb6d8b7 100644 --- a/test/controllers/active_storage/direct_uploads_controller_test.rb +++ b/test/controllers/active_storage/direct_uploads_controller_test.rb @@ -34,6 +34,40 @@ class ActiveStorage::DirectUploadsControllerTest < ActionDispatch::IntegrationTe assert_includes response.parsed_body.keys, "direct_upload" end + test "create with session token" do + sign_in_as :david + + post rails_direct_uploads_path, + params: @blob_params, + as: :json + + assert_response :success + assert_includes response.parsed_body.keys, "direct_upload" + end + + test "create with session token skips forgery protection" do + sign_in_as :david + + with_forgery_protection do + post rails_direct_uploads_path, + params: @blob_params, + as: :json + + assert_response :success + assert_includes response.parsed_body.keys, "direct_upload" + end + end + + test "create with session token in another account is forbidden" do + sign_in_as :david + + post rails_direct_uploads_path(script_name: "/#{ActiveRecord::FixtureSet.identify("initech")}"), + params: @blob_params, + as: :json + + assert_response :forbidden + end + test "create with read-only access token" do post rails_direct_uploads_path, params: @blob_params, @@ -83,4 +117,12 @@ class ActiveStorage::DirectUploadsControllerTest < ActionDispatch::IntegrationTe def bearer_token_header(token) { "Authorization" => "Bearer #{token}" } 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