From e35b39c7cfbbe6750acb7b152ed7b85bac3790c1 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 5 Jun 2015 12:43:49 +1000 Subject: [PATCH] Handle invalid referer URLs Rescues URI::InvalidURIError of URL(request.referer). --- .../admin/enterprises_controller.rb | 5 +++- app/controllers/application_controller.rb | 5 +++- .../admin/products_controller_decorator.rb | 4 +++- lib/open_food_network/referer_parser.rb | 17 ++++++++++++++ .../open_food_network/referer_parser_spec.rb | 23 +++++++++++++++++++ 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 lib/open_food_network/referer_parser.rb create mode 100644 spec/lib/open_food_network/referer_parser_spec.rb diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index a0b55ad3c8..e50779c3ff 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -1,3 +1,5 @@ +require 'open_food_network/referer_parser' + module Admin class EnterprisesController < ResourceController before_filter :load_enterprise_set, :only => :index @@ -199,7 +201,8 @@ module Admin # Overriding method on Spree's resource controller def location_after_save - refered_from_edit = URI(request.referer).path == main_app.edit_admin_enterprise_path(@enterprise) + referer_path = OpenFoodNetwork::RefererParser::path(request.referer) + refered_from_edit = referer_path == main_app.edit_admin_enterprise_path(@enterprise) if params[:enterprise].key?(:producer_properties_attributes) && !refered_from_edit main_app.admin_enterprises_path else diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 53763ad274..aaa7d0bb06 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,5 @@ +require 'open_food_network/referer_parser' + class ApplicationController < ActionController::Base protect_from_forgery @@ -9,7 +11,8 @@ class ApplicationController < ActionController::Base end def set_checkout_redirect - if request.referer and referer_path = URI(request.referer).path + referer_path = OpenFoodNetwork::RefererParser::path(request.referer) + if referer_path session["spree_user_return_to"] = [main_app.checkout_path].include?(referer_path) ? referer_path : root_path end end diff --git a/app/controllers/spree/admin/products_controller_decorator.rb b/app/controllers/spree/admin/products_controller_decorator.rb index 1591586f76..5b1bb347a1 100644 --- a/app/controllers/spree/admin/products_controller_decorator.rb +++ b/app/controllers/spree/admin/products_controller_decorator.rb @@ -1,4 +1,5 @@ require 'open_food_network/spree_api_key_loader' +require 'open_food_network/referer_parser' Spree::Admin::ProductsController.class_eval do include OpenFoodNetwork::SpreeApiKeyLoader @@ -53,7 +54,8 @@ Spree::Admin::ProductsController.class_eval do protected def location_after_save - if URI(request.referer).path == '/admin/products/bulk_edit' + referer_path = OpenFoodNetwork::RefererParser::path(request.referer) + if referer_path == '/admin/products/bulk_edit' bulk_edit_admin_products_url else location_after_save_original diff --git a/lib/open_food_network/referer_parser.rb b/lib/open_food_network/referer_parser.rb new file mode 100644 index 0000000000..b90ef21829 --- /dev/null +++ b/lib/open_food_network/referer_parser.rb @@ -0,0 +1,17 @@ +module OpenFoodNetwork + class RefererParser + def self.path(referer) + parse_uri(referer).andand.path if referer + end + + def self.parse_uri(string) + begin + # TODO: make this operation obsolete by fixing URLs generated by AngularJS + string.sub!('##', '#') + URI(string) + rescue URI::InvalidURIError + nil + end + end + end +end diff --git a/spec/lib/open_food_network/referer_parser_spec.rb b/spec/lib/open_food_network/referer_parser_spec.rb new file mode 100644 index 0000000000..13cde6099e --- /dev/null +++ b/spec/lib/open_food_network/referer_parser_spec.rb @@ -0,0 +1,23 @@ +require 'open_food_network/referer_parser' +require 'spec_helper' + +module OpenFoodNetwork + describe RefererParser do + + it "handles requests without referer" do + RefererParser.path(nil).should be_nil + end + + it "handles requests with referer" do + RefererParser.path('http://example.org/').should eq('/') + end + + it "handles requests with invalid referer" do + RefererParser.path('this is not a URI').should be_nil + end + + it "handles requests with known issue of referer" do + RefererParser.path('http://example.org/##invalid-fragment').should eq('/') + end + end +end