From 1dcffa790d4847e53d9e64045c5f30fa9307a055 Mon Sep 17 00:00:00 2001 From: stveep Date: Sun, 23 Oct 2016 08:20:45 +0100 Subject: [PATCH] Add JWT encoding to state param --- Gemfile | 5 +++-- Gemfile.lock | 1 + app/controllers/admin/enterprises_controller.rb | 4 +++- app/helpers/admin/stripe_helper.rb | 12 +++++++++++- spec/helpers/admin/stripe_helper_spec.rb | 10 ++++++++-- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index ade5fa6951..aae6e31e35 100644 --- a/Gemfile +++ b/Gemfile @@ -14,8 +14,6 @@ gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6-adjustment-stat gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable' gem 'spree_auth_devise', github: 'openfoodfoundation/spree_auth_devise', branch: 'spree-upgrade-intermediate' -gem 'oauth2', '~> 1.2.0' # Used for Stripe Connect - # Our branch contains two changes # - Pass customer email and phone number to PayPal (merged to upstream master) # - Change type of password from string to password to hide it in the form @@ -23,6 +21,9 @@ gem 'spree_paypal_express', :github => "openfoodfoundation/better_spree_paypal_e #gem 'spree_paypal_express', :github => "spree-contrib/better_spree_paypal_express", :branch => "1-3-stable" gem 'stripe', '~>1.51.0' +gem 'oauth2', '~> 1.2.0' # Used for Stripe Connect +gem 'jwt', '~> 1.5' + gem 'delayed_job_active_record' gem 'daemons' diff --git a/Gemfile.lock b/Gemfile.lock index 822e0e400c..00e57d42c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -752,6 +752,7 @@ DEPENDENCIES jquery-migrate-rails jquery-rails json_spec + jwt (~> 1.5) knapsack letter_opener momentjs-rails diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index e795645261..045a67a24b 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -120,7 +120,9 @@ module Admin def stripe_connect_callback if params["code"] - state = JSON.parse(params["state"].gsub("=>",":")) + state = jwt_decode(params["state"]) + redirect_to unauthorized unless state.keys.include? "enterprise_id" + # Get the Enterprise @enterprise = Enterprise.find_by_permalink(state["enterprise_id"]) diff --git a/app/helpers/admin/stripe_helper.rb b/app/helpers/admin/stripe_helper.rb index a2eef84662..09f8fefdd1 100644 --- a/app/helpers/admin/stripe_helper.rb +++ b/app/helpers/admin/stripe_helper.rb @@ -29,8 +29,9 @@ module Admin def authorize_stripe(enterprise_id, options={}) options = options.merge({enterprise_id: enterprise_id}) + jwt = jwt_encode options # State param will be passed back after auth - StripeHelper.client.auth_code.authorize_url(state: options) + StripeHelper.client.auth_code.authorize_url(state: jwt) end def deauthorize_stripe(account_id) @@ -52,5 +53,14 @@ module Admin event_json = JSON.parse(request.body.read) JSON.parse(Stripe::Event.retrieve(event_json["id"])) end + + private + def jwt_encode payload + JWT.encode(payload, Openfoodnetwork::Application.config.secret_token) + end + + def jwt_decode token + JWT.decode(token, Openfoodnetwork::Application.config.secret_token)[0] # only returns the original payload + end end end diff --git a/spec/helpers/admin/stripe_helper_spec.rb b/spec/helpers/admin/stripe_helper_spec.rb index a401f8ff46..a2d4cfce9f 100644 --- a/spec/helpers/admin/stripe_helper_spec.rb +++ b/spec/helpers/admin/stripe_helper_spec.rb @@ -10,8 +10,10 @@ describe Admin::StripeHelper do helper.get_stripe_token("abc") end - it "calls the Stripe API for authorization, passing the enterprise in the state param" do - expect(Admin::StripeHelper.client.auth_code).to receive(:authorize_url).with({state: {enterprise_id: "enterprise-permalink"}}) + it "calls the Stripe API for authorization, passing appropriate JWT in the state param" do + expect(Admin::StripeHelper.client.auth_code).to receive(:authorize_url).with({ + state: JWT.encode({enterprise_id: "enterprise-permalink"}, Openfoodnetwork::Application.config.secret_token) + }) helper.authorize_stripe("enterprise-permalink") end @@ -42,5 +44,9 @@ describe Admin::StripeHelper do deauthorize_stripe(stripe_account.id) end + it "encodes and decodes JWT" do + jwt_decode(jwt_encode({test: "string"})).should eq({"test" => "string"}) + end + end end