Fix User controlled method execution

Add white list for the fire endpoint to limit which action can be taken.
Add specs for fire endpoint
This commit is contained in:
Gaetan Craig-Riou
2025-02-18 14:42:26 +11:00
parent e386640b57
commit 0ae855047d
2 changed files with 60 additions and 1 deletions

View File

@@ -69,7 +69,7 @@ module Spree
@order.send_cancellation_email = params[:send_cancellation_email] != "false"
@order.restock_items = params.fetch(:restock_items, "true") == "true"
if @order.public_send(event.to_s)
if allowed_events.include?(event) && @order.public_send(event.to_s)
AmendBackorderJob.perform_later(@order) if @order.completed?
flash[:success] = Spree.t(:order_updated)
else
@@ -198,6 +198,10 @@ module Spree
ocs.closed +
ocs.undated
end
def allowed_events
%w{cancel resume}
end
end
end
end

View File

@@ -294,4 +294,59 @@ RSpec.describe Spree::Admin::OrdersController, type: :controller do
end
end
end
describe "#fire" do
let(:order) { create(:completed_order_with_totals) }
before do
controller_login_as_admin
allow(Spree::Order).to receive_message_chain(:includes, :find_by!).and_return(order)
@request.env['HTTP_REFERER'] = spree.edit_admin_order_path(order)
end
%w{cancel resume}.each do |event|
it "calls allowed event #{event}" do
expect(order).to receive(:public_send).with(event)
spree_get :fire, { id: order, e: event }
expect(response).to redirect_to spree.edit_admin_order_path(order)
end
end
it "returns a success flash message" do
spree_get :fire, { id: order, e: "cancel" }
expect(flash[:success]).to eq "Order Updated"
end
it "amends back order" do
expect(AmendBackorderJob).to receive(:perform_later)
spree_get :fire, { id: order, e: "cancel" }
end
context "with a non allowed event" do
it "returns an error" do
expect(order).not_to receive(:public_send).with("state")
spree_get :fire, { id: order, e: "state" }
expect(flash[:error]).to eq "Can not perform this operation"
expect(response).to redirect_to spree.edit_admin_order_path(order)
end
end
context "when a GatewayError is raised" do
it "returns an error flash message" do
allow(order).to receive(:public_send).and_raise(Spree::Core::GatewayError, "Some error")
spree_get :fire, { id: order, e: "cancel" }
expect(flash[:error]).to eq "Some error"
expect(response).to redirect_to spree.edit_admin_order_path(order)
end
end
end
end