From 2f13ab6adfaee2ce15680196676a7fd095ccfc51 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 29 Oct 2015 16:47:08 +1100 Subject: [PATCH] Fixing customer info security for orders and fulfillments report --- .../orders_and_fulfillments_report.rb | 5 +- .../orders_and_fulfillments_report_spec.rb | 97 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index 06e00cf77a..2221b79080 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -42,7 +42,10 @@ module OpenFoodNetwork line_items = permissions.visible_line_items.merge(Spree::LineItem.where(order_id: orders)) line_items = line_items.supplied_by_any(params[:supplier_id_in]) if params[:supplier_id_in].present? - line_items_with_hidden_details = line_items.where('"spree_line_items"."id" NOT IN (?)', permissions.editable_line_items) + # If empty array is passed in, the where clause will return all line_items, which is bad + line_items_with_hidden_details = + permissions.editable_line_items.empty? ? line_items : line_items.where('"spree_line_items"."id" NOT IN (?)', permissions.editable_line_items) + line_items.select{ |li| line_items_with_hidden_details.include? li }.each do |line_item| # TODO We should really be hiding customer code here too, but until we # have an actual association between order and customer, it's a bit tricky diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb new file mode 100644 index 0000000000..55c8bd1197 --- /dev/null +++ b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb @@ -0,0 +1,97 @@ +require 'spec_helper' + +include AuthenticationWorkflow + +module OpenFoodNetwork + describe OrdersAndFulfillmentsReport do + describe "fetching orders" do + let(:d1) { create(:distributor_enterprise) } + let(:oc1) { create(:simple_order_cycle) } + let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) } + let(:li1) { build(:line_item) } + + before { o1.line_items << li1 } + + context "as a site admin" do + let(:user) { create(:admin_user) } + subject { PackingReport.new user } + + it "fetches completed orders" do + o2 = create(:order) + o2.line_items << build(:line_item) + subject.table_items.should == [li1] + end + + it "does not show cancelled orders" do + o2 = create(:order, state: "canceled", completed_at: 1.day.ago) + o2.line_items << build(:line_item) + subject.table_items.should == [li1] + end + end + + context "as a manager of a supplier" do + let!(:user) { create(:user) } + subject { OrdersAndFulfillmentsReport.new user } + + let(:s1) { create(:supplier_enterprise) } + + before do + s1.enterprise_roles.create!(user: user) + end + + context "that has granted P-OC to the distributor" do + let(:o2) { create(:order, distributor: d1, completed_at: 1.day.ago, bill_address: create(:address), ship_address: create(:address)) } + let(:li2) { build(:line_item, product: create(:simple_product, supplier: s1)) } + + before do + o2.line_items << li2 + create(:enterprise_relationship, parent: s1, child: d1, permissions_list: [:add_to_order_cycle]) + end + + it "shows line items supplied by my producers, with names hidden" do + subject.table_items.should == [li2] + subject.table_items.first.order.bill_address.firstname.should == "HIDDEN" + end + end + + context "that has not granted P-OC to the distributor" do + let(:o2) { create(:order, distributor: d1, completed_at: 1.day.ago, bill_address: create(:address), ship_address: create(:address)) } + let(:li2) { build(:line_item, product: create(:simple_product, supplier: s1)) } + + before do + o2.line_items << li2 + end + + it "shows line items supplied by my producers, with names hidden" do + subject.table_items.should == [] + end + end + end + + context "as a manager of a distributor" do + let!(:user) { create(:user) } + subject { OrdersAndFulfillmentsReport.new user } + + before do + d1.enterprise_roles.create!(user: user) + end + + it "only shows line items distributed by enterprises managed by the current user" do + d2 = create(:distributor_enterprise) + d2.enterprise_roles.create!(user: create(:user)) + o2 = create(:order, distributor: d2, completed_at: 1.day.ago) + o2.line_items << build(:line_item) + subject.table_items.should == [li1] + end + + it "only shows the selected order cycle" do + oc2 = create(:simple_order_cycle) + o2 = create(:order, distributor: d1, order_cycle: oc2) + o2.line_items << build(:line_item) + subject.stub(:params).and_return(order_cycle_id_in: oc1.id) + subject.table_items.should == [li1] + end + end + end + end +end