spree_auth_devise 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spree_auth_devise might be problematic. Click here for more details.

Files changed (67) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +39 -0
  3. data/app/assets/javascripts/admin/spree_auth.js +1 -0
  4. data/app/assets/javascripts/store/spree_auth.js +1 -0
  5. data/app/assets/stylesheets/admin/spree_auth.css +3 -0
  6. data/app/assets/stylesheets/store/spree_auth.css +3 -0
  7. data/app/controllers/spree/admin/admin_controller_decorator.rb +7 -0
  8. data/app/controllers/spree/admin/admin_orders_controller_decorator.rb +14 -0
  9. data/app/controllers/spree/admin/admin_resource_controller_decorator.rb +3 -0
  10. data/app/controllers/spree/admin/admin_users_controller_decorator.rb +21 -0
  11. data/app/controllers/spree/admin/users_controller.rb +77 -0
  12. data/app/controllers/spree/base_controller_decorator.rb +18 -0
  13. data/app/controllers/spree/checkout_controller_decorator.rb +47 -0
  14. data/app/controllers/spree/orders_controller_decorator.rb +15 -0
  15. data/app/controllers/spree/products_controller_decorator.rb +13 -0
  16. data/app/controllers/spree/user_passwords_controller.rb +32 -0
  17. data/app/controllers/spree/user_registrations_controller.rb +63 -0
  18. data/app/controllers/spree/user_sessions_controller.rb +58 -0
  19. data/app/controllers/spree/users_controller.rb +50 -0
  20. data/app/helpers/spree/admin/users_helper.rb +10 -0
  21. data/app/helpers/spree/users_helper.rb +15 -0
  22. data/app/mailers/spree/user_mailer.rb +8 -0
  23. data/app/models/spree/auth_configuration.rb +6 -0
  24. data/app/models/spree/current_order_decorator.rb +12 -0
  25. data/app/models/spree/user.rb +83 -0
  26. data/app/overrides/admin_tab.rb +6 -0
  27. data/app/overrides/auth_admin_login_navigation_bar.rb +5 -0
  28. data/app/overrides/auth_admin_user_roles.rb +6 -0
  29. data/app/overrides/auth_shared_login_bar.rb +7 -0
  30. data/app/overrides/auth_user_login_form.rb +6 -0
  31. data/app/views/spree/admin/users/_form.html.erb +19 -0
  32. data/app/views/spree/admin/users/_roles.html.erb +12 -0
  33. data/app/views/spree/admin/users/edit.html.erb +14 -0
  34. data/app/views/spree/admin/users/index.html.erb +48 -0
  35. data/app/views/spree/admin/users/new.html.erb +14 -0
  36. data/app/views/spree/admin/users/show.html.erb +21 -0
  37. data/app/views/spree/layouts/admin/_login_nav.html.erb +8 -0
  38. data/app/views/spree/shared/_flashes.html.erb +9 -0
  39. data/app/views/spree/shared/_login.html.erb +20 -0
  40. data/app/views/spree/shared/_login_bar.html.erb +6 -0
  41. data/app/views/spree/shared/_user_form.html.erb +17 -0
  42. data/app/views/spree/user_mailer/reset_password_instructions.text.erb +10 -0
  43. data/app/views/spree/user_passwords/edit.html.erb +15 -0
  44. data/app/views/spree/user_passwords/new.html.erb +15 -0
  45. data/app/views/spree/user_registrations/new.html.erb +22 -0
  46. data/app/views/spree/user_sessions/authorization_failure.html.erb +4 -0
  47. data/app/views/spree/user_sessions/new.html.erb +13 -0
  48. data/app/views/spree/users/edit.html.erb +11 -0
  49. data/app/views/spree/users/show.html.erb +43 -0
  50. data/config/initializers/devise.rb +142 -0
  51. data/config/initializers/spree.rb +1 -0
  52. data/config/locales/en.yml +46 -0
  53. data/config/routes.rb +31 -0
  54. data/db/default/users.rb +76 -0
  55. data/db/migrate/20101026184949_create_users.rb +29 -0
  56. data/db/migrate/20101026184950_rename_columns_for_devise.rb +37 -0
  57. data/db/migrate/20101214150824_convert_user_remember_field.rb +11 -0
  58. data/db/migrate/20120203010234_add_reset_password_sent_at_to_spree_users.rb +8 -0
  59. data/db/migrate/20120605211305_make_users_email_index_unique.rb +9 -0
  60. data/db/seeds.rb +5 -0
  61. data/lib/spree/auth/devise.rb +13 -0
  62. data/lib/spree/auth/engine.rb +22 -0
  63. data/lib/spree/auth.rb +1 -0
  64. data/lib/spree/authentication_helpers.rb +26 -0
  65. data/lib/spree_auth_devise.rb +2 -0
  66. data/lib/tasks/auth.rake +9 -0
  67. metadata +160 -0
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2007-2012, Spree Commerce, Inc. and other contributors
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Spree Auth (Devise)
2
+
3
+ Provides authentication services for Spree, using the Devise gem.
4
+
5
+ ## Installation
6
+
7
+ At one stage in the past, this used to be the auth component for Spree. If that's the feature that you're now finding lacking from Spree, that's easy fixed.
8
+
9
+ Just add this line to your Gemfile:
10
+
11
+ gem "spree_auth_devise", :git => "git://github.com/spree/spree_auth_devise"
12
+
13
+ Then run `bundle install`. Authentication will then work exactly as it did in previous versions of Spree.
14
+
15
+ If you're installing this in a new Spree 1.2+ application, you'll need to install and run the migrations with
16
+
17
+ bundle exec rake spree_auth:install:migrations
18
+ bundle exec rake db:migrate
19
+
20
+ and then, run `bundle exec rake spree_auth:admin:create` in order to set up the admin user for the application.
21
+
22
+ If you're updating a Spree 1.1 application, run these to migrate the database:
23
+
24
+ rake railties:install:migrations
25
+ rake db:migrate
26
+
27
+
28
+ ## Testing
29
+
30
+ You need to do a quick one-time creation of a test application and then you can use it to run the tests.
31
+
32
+ bundle exec rake test_app
33
+
34
+ Then run the rspec tests
35
+
36
+ bundle exec rake spec
37
+
38
+ If everything doesn't pass on your machine (using Ruby (1.8.7 or 1.9.3) and (MySQL or PostgreSQL or SQLite3)) then we would consider that a bug. Please file a bug report on the issues page for this project with your test output
39
+ and we will investigate it.
@@ -0,0 +1 @@
1
+ //= require admin/spree_core
@@ -0,0 +1 @@
1
+ //= require store/spree_core
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require admin/spree_core
3
+ */
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require store/spree_core
3
+ */
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../../base_controller_decorator', __FILE__)
2
+ Spree::Admin::BaseController.class_eval do
3
+ protected
4
+ def model_class
5
+ "Spree::#{controller_name.classify}".constantize
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ Spree::Admin::OrdersController.class_eval do
2
+ before_filter :check_authorization
3
+
4
+ private
5
+ def check_authorization
6
+ load_order
7
+ session[:access_token] ||= params[:token]
8
+
9
+ resource = @order || Spree::Order.new
10
+ action = params[:action].to_sym
11
+
12
+ authorize! action, resource, session[:access_token]
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ Spree::Admin::ResourceController.class_eval do
2
+ rescue_from CanCan::AccessDenied, :with => :unauthorized
3
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../../base_controller_decorator', __FILE__)
2
+ Spree::Admin::UsersController.class_eval do
3
+ rescue_from Spree::User::DestroyWithOrdersError, :with => :user_destroy_with_orders_error
4
+
5
+ update.after :sign_in_if_change_own_password
6
+
7
+ before_filter :load_roles, :only => [:edit, :new, :update, :create]
8
+
9
+ private
10
+
11
+ def sign_in_if_change_own_password
12
+ if spree_current_user == @user && @user.password.present?
13
+ sign_in(@user, :event => :authentication, :bypass => true)
14
+ end
15
+ end
16
+
17
+ def load_roles
18
+ @roles = Spree::Role.scoped
19
+ end
20
+ end
21
+
@@ -0,0 +1,77 @@
1
+ module Spree
2
+ module Admin
3
+ class UsersController < ResourceController
4
+
5
+ # http://spreecommerce.com/blog/2010/11/02/json-hijacking-vulnerability/
6
+ before_filter :check_json_authenticity, :only => :index
7
+ before_filter :load_roles, :only => [:edit, :new, :update, :create, :generate_api_key, :clear_api_key]
8
+
9
+ def index
10
+ respond_with(@collection) do |format|
11
+ format.html
12
+ format.json { render :json => json_data }
13
+ end
14
+ end
15
+
16
+ def generate_api_key
17
+ if @user.generate_spree_api_key!
18
+ flash.notice = t('key_generated', :scope => 'spree.api')
19
+ end
20
+ redirect_to edit_admin_user_path(@user)
21
+ end
22
+
23
+ def clear_api_key
24
+ if @user.clear_spree_api_key!
25
+ flash.notice = t('key_cleared', :scope => 'spree.api')
26
+ end
27
+ redirect_to edit_admin_user_path(@user)
28
+ end
29
+
30
+
31
+ protected
32
+
33
+ def collection
34
+ return @collection if @collection.present?
35
+ unless request.xhr?
36
+ @search = Spree::User.registered.ransack(params[:q])
37
+ @collection = @search.result.page(params[:page]).per(Spree::Config[:admin_products_per_page])
38
+ else
39
+ #disabling proper nested include here due to rails 3.1 bug
40
+ #@collection = User.includes(:bill_address => [:state, :country], :ship_address => [:state, :country]).
41
+ @collection = Spree::User.includes(:bill_address, :ship_address).
42
+ where("spree_users.email #{LIKE} :search
43
+ OR (spree_addresses.firstname #{LIKE} :search AND spree_addresses.id = spree_users.bill_address_id)
44
+ OR (spree_addresses.lastname #{LIKE} :search AND spree_addresses.id = spree_users.bill_address_id)
45
+ OR (spree_addresses.firstname #{LIKE} :search AND spree_addresses.id = spree_users.ship_address_id)
46
+ OR (spree_addresses.lastname #{LIKE} :search AND spree_addresses.id = spree_users.ship_address_id)",
47
+ { :search => "#{params[:q].strip}%" }).
48
+ limit(params[:limit] || 100)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # handling raise from Spree::Admin::ResourceController#destroy
55
+ def user_destroy_with_orders_error
56
+ invoke_callbacks(:destroy, :fails)
57
+ render :status => :forbidden, :text => t(:error_user_destroy_with_orders)
58
+ end
59
+
60
+ # Allow different formats of json data to suit different ajax calls
61
+ def json_data
62
+ json_format = params[:json_format] or 'default'
63
+ case json_format
64
+ when 'basic'
65
+ collection.map { |u| { 'id' => u.id, 'name' => u.email } }.to_json
66
+ else
67
+ address_fields = [:firstname, :lastname, :address1, :address2, :city, :zipcode, :phone, :state_name, :state_id, :country_id]
68
+ includes = { :only => address_fields , :include => { :state => { :only => :name }, :country => { :only => :name } } }
69
+
70
+ collection.to_json(:only => [:id, :email], :include =>
71
+ { :bill_address => includes, :ship_address => includes })
72
+ end
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ Spree::BaseController.class_eval do
2
+ def spree_login_path
3
+ spree.login_path
4
+ end
5
+
6
+ def spree_signup_path
7
+ spree.signup_path
8
+ end
9
+
10
+ def spree_logout_path
11
+ spree.destroy_user_session_path
12
+ end
13
+
14
+ def spree_current_user
15
+ current_user
16
+ end
17
+ end
18
+
@@ -0,0 +1,47 @@
1
+ Spree::CheckoutController.class_eval do
2
+ before_filter :check_authorization
3
+ before_filter :check_registration, :except => [:registration, :update_registration]
4
+
5
+ helper 'spree/users'
6
+
7
+ def registration
8
+ @user = Spree::User.new
9
+ end
10
+
11
+ def update_registration
12
+ fire_event("spree.user.signup", :order => current_order)
13
+ # hack - temporarily change the state to something other than cart so we can validate the order email address
14
+ current_order.state = 'address'
15
+ if current_order.update_attributes(params[:order])
16
+ redirect_to checkout_path
17
+ else
18
+ @user = Spree::User.new
19
+ render 'registration'
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def skip_state_validation?
26
+ %w(registration update_registration).include?(params[:action])
27
+ end
28
+
29
+ def check_authorization
30
+ authorize!(:edit, current_order, session[:access_token])
31
+ end
32
+
33
+ # Introduces a registration step whenever the +registration_step+ preference is true.
34
+ def check_registration
35
+ return unless Spree::Auth::Config[:registration_step]
36
+ return if spree_current_user or current_order.email
37
+ store_location
38
+ redirect_to spree.checkout_registration_path
39
+ end
40
+
41
+ # Overrides the equivalent method defined in Spree::Core. This variation of the method will ensure that users
42
+ # are redirected to the tokenized order url unless authenticated as a registered user.
43
+ def completion_route
44
+ return order_path(@order) if spree_current_user
45
+ spree.token_order_path(@order, @order.token)
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ Spree::OrdersController.class_eval do
2
+ before_filter :check_authorization
3
+
4
+ private
5
+ def check_authorization
6
+ session[:access_token] ||= params[:token]
7
+ order = Spree::Order.find_by_number(params[:id]) || current_order
8
+
9
+ if order
10
+ authorize! :edit, order, session[:access_token]
11
+ else
12
+ authorize! :create, Spree::Order.new
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ Spree::ProductsController.class_eval do
2
+ rescue_from CanCan::AccessDenied, :with => :render_404
3
+
4
+ private
5
+ def load_product
6
+ @product = Spree::Product.find_by_permalink!(params[:id])
7
+ if !@product.deleted? && (@product.available_on.nil? || @product.available_on.future?)
8
+ # Allow admins to view any yet to be available products
9
+ raise CanCan::AccessDenied unless spree_current_user && spree_current_user.has_spree_role?(:admin)
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,32 @@
1
+ class Spree::UserPasswordsController < Devise::PasswordsController
2
+ include SslRequirement
3
+ helper 'spree/users', 'spree/base'
4
+
5
+ if defined?(Spree::Dash)
6
+ helper 'spree/analytics'
7
+ end
8
+
9
+ include Spree::Core::ControllerHelpers
10
+
11
+ ssl_required
12
+
13
+ # Temporary Override until next Devise release (i.e after v1.3.4)
14
+ # line:
15
+ # respond_with resource, :location => new_session_path(resource_name)
16
+ # is generating bad url /session/new.user
17
+ #
18
+ # overridden to:
19
+ # respond_with resource, :location => login_path
20
+ #
21
+ def create
22
+ self.resource = resource_class.send_reset_password_instructions(params[resource_name])
23
+
24
+ if resource.errors.empty?
25
+ set_flash_message(:notice, :send_instructions) if is_navigational_format?
26
+ respond_with resource, :location => spree.login_path
27
+ else
28
+ respond_with_navigational(resource) { render :new }
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,63 @@
1
+ class Spree::UserRegistrationsController < Devise::RegistrationsController
2
+ include SslRequirement
3
+ helper 'spree/users', 'spree/base'
4
+
5
+ if defined?(Spree::Dash)
6
+ helper 'spree/analytics'
7
+ end
8
+
9
+ include Spree::Core::ControllerHelpers
10
+ ssl_required
11
+ before_filter :check_permissions, :only => [:edit, :update]
12
+ skip_before_filter :require_no_authentication
13
+
14
+ # GET /resource/sign_up
15
+ def new
16
+ super
17
+ end
18
+
19
+ # POST /resource/sign_up
20
+ def create
21
+ @user = build_resource(params[:user])
22
+ if resource.save
23
+ set_flash_message(:notice, :signed_up)
24
+ sign_in(:user, @user)
25
+ session[:spree_user_signup] = true
26
+ associate_user
27
+ sign_in_and_redirect(:user, @user)
28
+ else
29
+ clean_up_passwords(resource)
30
+ render :new
31
+ end
32
+ end
33
+
34
+ # GET /resource/edit
35
+ def edit
36
+ super
37
+ end
38
+
39
+ # PUT /resource
40
+ def update
41
+ super
42
+ end
43
+
44
+ # DELETE /resource
45
+ def destroy
46
+ super
47
+ end
48
+
49
+ # GET /resource/cancel
50
+ # Forces the session data which is usually expired after sign
51
+ # in to be expired now. This is useful if the user wants to
52
+ # cancel oauth signing in/up in the middle of the process,
53
+ # removing all OAuth session data.
54
+ def cancel
55
+ super
56
+ end
57
+
58
+ protected
59
+ def check_permissions
60
+ authorize!(:create, resource)
61
+ end
62
+
63
+ end
@@ -0,0 +1,58 @@
1
+ class Spree::UserSessionsController < Devise::SessionsController
2
+ include SslRequirement
3
+ helper 'spree/users', 'spree/base'
4
+ if defined?(Spree::Dash)
5
+ helper 'spree/analytics'
6
+ end
7
+
8
+ include Spree::Core::CurrentOrder
9
+ include Spree::Core::ControllerHelpers
10
+
11
+ ssl_required :new, :create, :destroy, :update
12
+ ssl_allowed :login_bar
13
+
14
+ # GET /resource/sign_in
15
+ def new
16
+ super
17
+ end
18
+
19
+ def create
20
+ authenticate_user!
21
+
22
+ if user_signed_in?
23
+ respond_to do |format|
24
+ format.html {
25
+ flash.notice = t(:logged_in_succesfully)
26
+ redirect_back_or_default(root_path)
27
+ }
28
+ format.js {
29
+ user = resource.record
30
+ render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
31
+ }
32
+ end
33
+ else
34
+ flash.now[:error] = t('devise.failure.invalid')
35
+ render :new
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ cookies.clear
41
+ session.clear
42
+ super
43
+ end
44
+
45
+ def nav_bar
46
+ render :partial => 'spree/shared/nav_bar'
47
+ end
48
+
49
+ private
50
+ def accurate_title
51
+ t(:login)
52
+ end
53
+
54
+ def redirect_back_or_default(default)
55
+ redirect_to(session["user_return_to"] || default)
56
+ session["user_return_to"] = nil
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ class Spree::UsersController < Spree::BaseController
2
+ ssl_required
3
+ prepend_before_filter :load_object, :only => [:show, :edit, :update]
4
+ prepend_before_filter :authorize_actions, :only => :new
5
+
6
+ def show
7
+ @orders = @user.orders.complete
8
+ end
9
+
10
+ def create
11
+ @user = Spree::User.new(params[:user])
12
+ if @user.save
13
+
14
+ if current_order
15
+ session[:guest_token] = nil
16
+ end
17
+
18
+ redirect_back_or_default(root_url)
19
+ else
20
+ render :new
21
+ end
22
+ end
23
+
24
+ def update
25
+ if @user.update_attributes(params[:user])
26
+ if params[:user][:password].present?
27
+ # this logic needed b/c devise wants to log us out after password changes
28
+ user = Spree::User.reset_password_by_token(params[:user])
29
+ sign_in(@user, :event => :authentication, :bypass => !Spree::Auth::Config[:signout_after_password_change])
30
+ end
31
+ redirect_to spree.account_url, :notice => t(:account_updated)
32
+ else
33
+ render :edit
34
+ end
35
+ end
36
+
37
+ private
38
+ def load_object
39
+ @user ||= spree_current_user
40
+ authorize! params[:action].to_sym, @user
41
+ end
42
+
43
+ def authorize_actions
44
+ authorize! params[:action].to_sym, Spree::User.new
45
+ end
46
+
47
+ def accurate_title
48
+ t(:my_account)
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ module Spree
2
+ module Admin
3
+ module UsersHelper
4
+ def list_roles(user)
5
+ # while testing spree-core itself user model does not have method roles
6
+ user.respond_to?(:spree_roles) ? user.spree_roles.collect { |role| role.name }.join(", ") : []
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module UsersHelper
3
+ def password_style(user)
4
+ ActiveSupport::Deprecation.warn '[SPREE] Password style has be depreciated due to the removal of OpenID from the Auth Gem. '
5
+ 'Please install the spree_social gem to regain this functionality and more.'
6
+ ''
7
+ end
8
+
9
+ def openid_style(user)
10
+ ActiveSupport::Deprecation.warn '[SPREE] Password style has be depreciated due to the removal of OpenID from the Auth Gem. '
11
+ 'Please install the spree_social gem to regain this functionality and more.'
12
+ 'display:none'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ class Spree::UserMailer < ActionMailer::Base
2
+ def reset_password_instructions(user)
3
+ @edit_password_reset_url = spree.edit_user_password_url(:reset_password_token => user.reset_password_token)
4
+
5
+ mail(:to => user.email,
6
+ :subject => Spree::Config[:site_name] + ' ' + I18n.t(:password_reset_instructions))
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class AuthConfiguration < Preferences::Configuration
3
+ preference :registration_step, :boolean, :default => true
4
+ preference :signout_after_password_change, :boolean, :default => true
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ Spree::Core::CurrentOrder.module_eval do
2
+ # Associate the new order with the currently authenticated user before saving
3
+ def before_save_new_order
4
+ @current_order.user ||= try_spree_current_user
5
+ end
6
+
7
+ def after_save_new_order
8
+ # make sure the user has permission to access the order (if they are a guest)
9
+ return if spree_current_user
10
+ session[:access_token] = @current_order.token
11
+ end
12
+ end
@@ -0,0 +1,83 @@
1
+ module Spree
2
+ class User < ActiveRecord::Base
3
+ include Core::UserBanners
4
+
5
+ devise :database_authenticatable, :token_authenticatable, :registerable, :recoverable,
6
+ :rememberable, :trackable, :validatable, :encryptable, :encryptor => 'authlogic_sha512'
7
+
8
+ has_many :orders
9
+ belongs_to :ship_address, :foreign_key => 'ship_address_id', :class_name => 'Spree::Address'
10
+ belongs_to :bill_address, :foreign_key => 'bill_address_id', :class_name => 'Spree::Address'
11
+
12
+ before_save :check_admin
13
+ before_validation :set_login
14
+ before_destroy :check_completed_orders
15
+
16
+ # Setup accessible (or protected) attributes for your model
17
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :persistence_token, :login, :spree_role_ids
18
+
19
+ users_table_name = User.table_name
20
+ roles_table_name = Role.table_name
21
+
22
+ scope :admin, lambda { includes(:spree_roles).where("#{roles_table_name}.name" => "admin") }
23
+ scope :registered, where("#{users_table_name}.email NOT LIKE ?", "%@example.net")
24
+
25
+ class DestroyWithOrdersError < StandardError; end
26
+
27
+ # Creates an anonymous user. An anonymous user is basically an auto-generated +User+ account that is created for the customer
28
+ # behind the scenes and its completely transparently to the customer. All +Orders+ must have a +User+ so this is necessary
29
+ # when adding to the "cart" (which is really an order) and before the customer has a chance to provide an email or to register.
30
+ def self.anonymous!
31
+ token = User.generate_token(:persistence_token)
32
+ User.create(:email => "#{token}@example.net", :password => token, :password_confirmation => token, :persistence_token => token)
33
+ end
34
+
35
+ def self.admin_created?
36
+ User.admin.count > 0
37
+ end
38
+
39
+ def anonymous?
40
+ email =~ /@example.net$/ ? true : false
41
+ end
42
+
43
+ def send_reset_password_instructions
44
+ generate_reset_password_token!
45
+ UserMailer.reset_password_instructions(self).deliver
46
+ end
47
+
48
+ protected
49
+ def password_required?
50
+ !persisted? || password.present? || password_confirmation.present?
51
+ end
52
+
53
+ private
54
+
55
+ def check_completed_orders
56
+ raise DestroyWithOrdersError if orders.complete.present?
57
+ end
58
+
59
+ def check_admin
60
+ return if self.class.admin_created?
61
+ admin_role = Role.find_or_create_by_name 'admin'
62
+ self.spree_roles << admin_role
63
+ end
64
+
65
+ def set_login
66
+ # for now force login to be same as email, eventually we will make this configurable, etc.
67
+ self.login ||= self.email if self.email
68
+ end
69
+
70
+ # Generate a friendly string randomically to be used as token.
71
+ def self.friendly_token
72
+ SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
73
+ end
74
+
75
+ # Generate a token by looping and ensuring does not already exist.
76
+ def self.generate_token(column)
77
+ loop do
78
+ token = friendly_token
79
+ break token unless find(:first, :conditions => { column => token })
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(:virtual_path => "spree/layouts/admin",
2
+ :name => "user_admin_tabs",
3
+ :insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
4
+ :text => "<%= tab(:users, :url => spree.admin_users_path) %>",
5
+ :disabled => false)
6
+
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/layouts/admin",
2
+ :name => "auth_admin_login_navigation_bar",
3
+ :replace => "[data-hook='admin_login_navigation_bar'], #admin_login_navigation_bar[data-hook]",
4
+ :partial => "spree/layouts/admin/login_nav",
5
+ :original => '0a5476d4d5db90ec8dd200ebaa0109a6a54ec6bc' )