Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Associate guest order with current_user once authentication completed…

…. Moved current_order and auth_user stuff into their own modules.
  • Loading branch information...
commit b3119a524f51d139b57ccca76a51ceed069c8305 1 parent df50cb7
@schof schof authored
View
12 auth/app/controllers/devise/sessions_controller_decorator.rb
@@ -0,0 +1,12 @@
+Devise::SessionsController.class_eval do
+ after_filter :associate_user, :only => :create
+
+ include Spree::CurrentOrder
+ include Spree::AuthUser
+
+ def associate_user
+ return unless current_user and current_order
+ current_order.associate_user!(current_user) if can? :edit, current_order
+ session[:guest_token] = nil
+ end
+end
View
14 auth/app/controllers/spree/base_controller_decorator.rb
@@ -1,5 +1,7 @@
Spree::BaseController.class_eval do
+ include Spree::AuthUser
+
# graceful error handling for cancan authorization exceptions
rescue_from CanCan::AccessDenied, :with => :access_denied
@@ -25,16 +27,4 @@ def access_denied
end
end
- # Returns the currently authenticated user or the user associated with the guest_token stored in the session
- # when available. This assists in providing authorization to guest users who may wish to create a new user
- # account at some point during the checkout (and thus, we cannot just log them in using the session token)
- def auth_user
- current_user || User.find_by_authentication_token(session[:guest_token])
- end
-
- # Overrides the default method used by Cancan so that we can use the guest_token in addition to current_user.
- def current_ability
- @current_ability ||= ::Ability.new(auth_user)
- end
-
end
View
7 auth/app/models/order_decorator.rb
@@ -1,4 +1,11 @@
Order.class_eval do
+ # Associates the specified user with the order and destroys any previous association with guest user if
+ # necessary.
+ def associate_user!(user)
+ self.user = user
+ save!
+ end
+
def token
user.token if user.guest?
end
View
20 auth/lib/spree/auth_user.rb
@@ -0,0 +1,20 @@
+module Spree
+ module AuthUser
+
+ # Gives controllers the ability to learn the +auth_user+ as opposed to limiting them to just the standard
+ # +current_user.+ The +auth_user+ method will return the user corresponding to the +guest_token+ if present,
+ # otherwise it will return the +current_user.+ This allows us to check authorization against a guest user
+ # without requiring that user to be signed in via warden/devise. This means the guest can later sign up for
+ # an acccount (or log in to an existing account.)
+ def auth_user
+ return current_user unless session[:guest_token]
+ User.find_by_authentication_token(session[:guest_token])
+ end
+
+ # Overrides the default method used by Cancan so that we can use the guest_token in addition to current_user.
+ def current_ability
+ @current_ability ||= ::Ability.new(auth_user)
+ end
+
+ end
+end
View
1  auth/lib/spree_auth.rb
@@ -1,4 +1,5 @@
require 'spree_core'
+require 'spree/auth_user'
require 'devise'
require 'devise/orm/active_record'
require 'cancan'
View
24 auth/spec/controllers/resource_controller_spec.rb
@@ -1,24 +0,0 @@
-require 'spec_helper'
-
-class Foo
-end
-
-class FooController < ResourceController::Base
-end
-
-describe FooController do
- # context "#populate" do
- # before { Order.stub(:create).and_return mock_model(Order, :token => "foo") }
- # it "should store a guest token (for new guest order)" do
- # controller.should_receive(:current_user).and_return(nil)
- # post :populate, {}, {}
- # session[:guest_token].should_not be_nil
- # end
- # it "should not store a guest token (for new registered user order)" do
- # controller.should_receive(:current_user).and_return mock_model(User)
- # post :populate, {}, {}
- # session[:guest_token].should be_nil
- # end
- # end
-
-end
View
39 auth/spec/controllers/sessions_controller_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe Devise::SessionsController do
+ before(:each) do
+ # apparently this is needed to test devise with rspec
+ controller.request.env["devise.mapping"] = Devise.mappings[:user]
+ end
+
+ context "#create" do
+ context "when current_order is associated with a guest user" do
+ let(:user) { mock_model User, :has_role? => false }
+ let(:order) { mock_model Order, :guest? => true, :user => user }
+
+ before do
+ controller.stub :authorize! => true
+ controller.stub_chain :warden, :authenticated? => true
+ controller.stub :current_order => order
+ controller.stub :current_user => user
+ end
+
+ it "should associate the order with the newly authenticated user" do
+ controller.stub :authorize! => true
+ controller.stub_chain :warden, :authenticated? => true
+ controller.stub :current_order => order
+
+ order.should_receive(:associate_user!).with user
+ post :create, {}, { :order_id => 1 }
+ end
+
+ it "should destroy the session token for guest_user" do
+ order.stub :associate_user!
+ post :create, {}, { :order_id => 1, :guest_token => "foo" }
+ session[:guest_token].should be_nil
+ end
+
+ end
+ end
+
+end
View
7 auth/spec/controllers/spree/base_controller_spec.rb
@@ -9,6 +9,7 @@
before { controller.stub :current_user => user }
it "should return the authenticated user" do
+ User.stub(:find_by_authentication_token).with(nil).and_return mock_model(User)
controller.auth_user.should == user
end
@@ -19,19 +20,19 @@
it "should return nil if there is no guest_token" do
User.stub :find_by_access_token => nil
- session[:guest_user] = nil
+ session[:guest_token] = nil
controller.auth_user.should be_nil
end
it "should return the user matching the token" do
User.stub :find_by_authentication_token => user
- session[:guest_user] = "foo"
+ session[:guest_token] = "foo"
controller.auth_user.should == user
end
it "should return nil if there is no database record associated with the guest_token" do
User.stub :find_by_access_token => nil
- session[:guest_user] = "foo"
+ session[:guest_token] = "foo"
controller.auth_user.should be_nil
end
end
View
21 auth/spec/models/order_spec.rb
@@ -14,4 +14,25 @@
order.token.should be_nil
end
end
+ context "#associate_user!" do
+ let(:user) { mock_model User, :guest? => false }
+ before { order.stub(:save! => true) }
+
+ it "should associate the order with the specified user" do
+ order.associate_user! user
+ order.user.should == user
+ end
+
+ it "should destroy any previous association with a guest user" do
+ guest_user = mock_model User
+ order.user = guest_user
+ order.associate_user! user
+ order.user.should_not == guest_user
+ end
+
+ it "should change the guest flag to false" do
+ order.associate_user! user
+ order.guest?.should be_false
+ end
+ end
end
View
12 core/app/controllers/spree/base_controller.rb
@@ -10,6 +10,7 @@ class Spree::BaseController < ActionController::Base
protect_from_forgery # See ActionController::RequestForgeryProtection for details
include SslRequirement
+ include Spree::CurrentOrder
def admin_created?
User.first(:include => :roles, :conditions => ["roles.name = 'admin'"])
@@ -40,18 +41,9 @@ def title
protected
- # The current incomplete order from the session for use in cart and during checkout
- def current_order(create_order_if_necessary = false)
- return @current_order if @current_order
- @current_order ||= Order.find_by_id(session[:order_id], :include => :adjustments)
- if create_order_if_necessary and (@current_order.nil? or @current_order.complete?)
- @current_order = Order.create
- end
- session[:order_id] = @current_order ? @current_order.id : nil
- @current_order
- end
helper_method :current_order
+
def default_title
Spree::Config[:site_name]
end
View
14 core/lib/spree/current_order.rb
@@ -0,0 +1,14 @@
+module Spree
+ module CurrentOrder
+ # The current incomplete order from the session for use in cart and during checkout
+ def current_order(create_order_if_necessary = false)
+ return @current_order if @current_order
+ @current_order ||= Order.find_by_id(session[:order_id], :include => :adjustments)
+ if create_order_if_necessary and (@current_order.nil? or @current_order.complete?)
+ @current_order = Order.create
+ end
+ session[:order_id] = @current_order ? @current_order.id : nil
+ @current_order
+ end
+ end
+end
View
1  core/lib/spree_core.rb
@@ -51,6 +51,7 @@
require 'store_helpers'
require 'spree/file_utilz'
require 'spree/calculated_adjustments'
+require 'spree/current_order'
module Spree
def self.version
Please sign in to comment.
Something went wrong with that request. Please try again.