apispree_auth 0.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.
Files changed (52) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +36 -0
  3. data/app/controllers/admin_controller_decorator.rb +7 -0
  4. data/app/controllers/admin_orders_controller_decorator.rb +15 -0
  5. data/app/controllers/admin_resource_controller_decorator.rb +3 -0
  6. data/app/controllers/checkout_controller_decorator.rb +42 -0
  7. data/app/controllers/orders_controller_decorator.rb +17 -0
  8. data/app/controllers/resource_controller_decorator.rb +25 -0
  9. data/app/controllers/spree/base_controller_decorator.rb +49 -0
  10. data/app/controllers/user_passwords_controller.rb +20 -0
  11. data/app/controllers/user_registrations_controller.rb +64 -0
  12. data/app/controllers/user_sessions_controller.rb +81 -0
  13. data/app/controllers/users_controller.rb +54 -0
  14. data/app/helpers/users_helper.rb +13 -0
  15. data/app/models/ability.rb +64 -0
  16. data/app/models/order_decorator.rb +12 -0
  17. data/app/models/spree_auth_configuration.rb +4 -0
  18. data/app/models/spree_current_order_decorator.rb +14 -0
  19. data/app/models/tokenized_permission.rb +3 -0
  20. data/app/models/user.rb +85 -0
  21. data/app/models/user_mailer.rb +13 -0
  22. data/app/views/checkout/registration.html.erb +20 -0
  23. data/app/views/layouts/admin/_login_nav.html.erb +8 -0
  24. data/app/views/shared/_flashes.html.erb +9 -0
  25. data/app/views/shared/_login.html.erb +20 -0
  26. data/app/views/shared/_login_bar.html.erb +6 -0
  27. data/app/views/shared/_user_form.html.erb +17 -0
  28. data/app/views/shared/unauthorized.html.erb +0 -0
  29. data/app/views/user_mailer/reset_password_instructions.text.erb +10 -0
  30. data/app/views/user_passwords/edit.html.erb +15 -0
  31. data/app/views/user_passwords/new.html.erb +13 -0
  32. data/app/views/user_registrations/new.html.erb +23 -0
  33. data/app/views/user_sessions/authorization_failure.html.erb +4 -0
  34. data/app/views/user_sessions/new.html.erb +13 -0
  35. data/app/views/users/edit.html.erb +11 -0
  36. data/app/views/users/show.html.erb +50 -0
  37. data/config/cucumber.yml +10 -0
  38. data/config/initializers/devise.rb +136 -0
  39. data/config/locales/en.yml +46 -0
  40. data/config/routes.rb +28 -0
  41. data/db/migrate/20101026184950_rename_columns_for_devise.rb +39 -0
  42. data/db/migrate/20101214150824_convert_user_remember_field.rb +11 -0
  43. data/db/migrate/20101217012656_create_tokenized_permissions.rb +18 -0
  44. data/db/migrate/20101219201531_tokens_for_legacy_orders.rb +12 -0
  45. data/db/sample/users.rb +53 -0
  46. data/lib/apispree_auth.rb +29 -0
  47. data/lib/spree/auth/config.rb +22 -0
  48. data/lib/spree/token_resource.rb +23 -0
  49. data/lib/spree_auth_hooks.rb +6 -0
  50. data/lib/tasks/auth.rake +8 -0
  51. data/lib/tasks/install.rake +23 -0
  52. metadata +129 -0
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2007-2010, Rails Dog LLC 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.
@@ -0,0 +1,36 @@
1
+ Overview
2
+ --------
3
+
4
+ This gem provides the so-called "core" functionality of Spree and is a requirement for any Spree application or
5
+ store. The basic data models as well as product catalog and admin functionality are all provided by this gem.
6
+
7
+
8
+ Security Warning
9
+ ----------------
10
+
11
+ *This gem provides absolutely no authentication and authorization. You are strongly encouraged to install
12
+ and use the spree-auth gem in addition to spree-core in order to restrict access to orders and other admin
13
+ functionality.*
14
+
15
+
16
+ Running Tests
17
+ -------------
18
+
19
+ You need to do a quick one-time creation of a test application and then you can use it to run the tests.
20
+
21
+ rake test_app
22
+
23
+ Then run the rspec tests
24
+
25
+ rake spec
26
+
27
+ Then run the cucumber tests
28
+
29
+ bundle exec cucumber
30
+
31
+ Misc
32
+ ----
33
+
34
+ authentication by token example
35
+
36
+ http://localhost:3000/?auth_token=oWBSN16k6dWx46TtSGcp
@@ -0,0 +1,7 @@
1
+ Admin::BaseController.class_eval do
2
+ before_filter :authorize_admin
3
+
4
+ def authorize_admin
5
+ authorize! :admin, Object
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ Admin::OrdersController.class_eval do
2
+ before_filter :check_authorization
3
+
4
+ private
5
+
6
+ def check_authorization
7
+ load_order
8
+ session[:access_token] ||= params[:token]
9
+
10
+ resource = @order || Order
11
+ action = params[:action].to_sym
12
+
13
+ authorize! action, resource, session[:access_token]
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ Admin::ResourceController.class_eval do
2
+ authorize_resource
3
+ end
@@ -0,0 +1,42 @@
1
+ CheckoutController.class_eval do
2
+ before_filter :check_authorization
3
+ before_filter :check_registration, :except => [:registration, :update_registration]
4
+
5
+ helper :users
6
+
7
+ def registration
8
+ @user = User.new
9
+ end
10
+
11
+ def update_registration
12
+ # hack - temporarily change the state to something other than cart so we can validate the order email address
13
+ current_order.state = "address"
14
+ if current_order.update_attributes(params[:order])
15
+ redirect_to checkout_path
16
+ else
17
+ @user = User.new
18
+ render 'registration'
19
+ end
20
+ end
21
+
22
+ private
23
+ def check_authorization
24
+ authorize!(:edit, current_order, session[:access_token])
25
+ end
26
+
27
+ # Introduces a registration step whenever the +registration_step+ preference is true.
28
+ def check_registration
29
+ return unless Spree::Auth::Config[:registration_step]
30
+ return if current_user or current_order.email
31
+ store_location
32
+ redirect_to checkout_registration_path
33
+ end
34
+
35
+ # Overrides the equivalent method defined in spree_core. This variation of the method will ensure that users
36
+ # are redirected to the tokenized order url unless authenticated as a registered user.
37
+ def completion_route
38
+ return order_path(@order) if current_user
39
+ token_order_path(@order, @order.token)
40
+ end
41
+
42
+ end
@@ -0,0 +1,17 @@
1
+ OrdersController.class_eval do
2
+ before_filter :check_authorization
3
+
4
+ private
5
+
6
+ def check_authorization
7
+ session[:access_token] ||= params[:token]
8
+ order = current_order || Order.find_by_number(params[:id])
9
+
10
+ if order
11
+ authorize! :edit, order, session[:access_token]
12
+ else
13
+ authorize! :create, Order
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,25 @@
1
+ # This overrides the before method provided by resource_controller so that the current_user is authorized
2
+ # for each action before proceding.
3
+ module ResourceController
4
+ module Helpers
5
+ module Internal
6
+ protected
7
+ # Calls the before block for the action, if one is present.
8
+ def before(action)
9
+
10
+ resource = case action
11
+ when :index, :new, :create
12
+ model
13
+ else object
14
+ end
15
+
16
+ if resource.respond_to? :token
17
+ authorize! action, resource, session[:access_token]
18
+ else
19
+ authorize! action, resource
20
+ end
21
+ invoke_callbacks *self.class.send(action).before
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ Spree::BaseController.class_eval do
2
+
3
+ before_filter :set_current_user
4
+
5
+ # graceful error handling for cancan authorization exceptions
6
+ rescue_from CanCan::AccessDenied do |exception|
7
+ return unauthorized
8
+ end
9
+
10
+ private
11
+
12
+ # Redirect as appropriate when an access request fails. The default action is to redirect to the login screen.
13
+ # Override this method in your controllers if you want to have special behavior in case the user is not authorized
14
+ # to access the requested action. For example, a popup window might simply close itself.
15
+ def unauthorized
16
+ respond_to do |format|
17
+ format.html do
18
+ if current_user
19
+ flash.now[:error] = I18n.t(:authorization_failure)
20
+ render 'shared/unauthorized', :layout => 'spree_application'
21
+ else
22
+ flash[:error] = I18n.t(:authorization_failure)
23
+ store_location
24
+ redirect_to login_path and return
25
+ end
26
+ end
27
+ format.xml do
28
+ request_http_basic_authentication 'Web Password'
29
+ end
30
+ format.json do
31
+ render :text => "Not Authorized \n", :status => 401
32
+ end
33
+ end
34
+ end
35
+
36
+ def store_location
37
+ # disallow return to login, logout, signup pages
38
+ disallowed_urls = [signup_url, login_url, destroy_user_session_path]
39
+ disallowed_urls.map!{|url| url[/\/\w+$/]}
40
+ unless disallowed_urls.include?(request.fullpath)
41
+ session["user_return_to"] = request.fullpath
42
+ end
43
+ end
44
+
45
+ def set_current_user
46
+ User.current = current_user
47
+ end
48
+
49
+ end
@@ -0,0 +1,20 @@
1
+ class UserPasswordsController < Devise::PasswordsController
2
+ include SpreeBase
3
+ helper :users, 'spree/base'
4
+
5
+ def new
6
+ super
7
+ end
8
+
9
+ def create
10
+ super
11
+ end
12
+
13
+ def edit
14
+ super
15
+ end
16
+
17
+ def update
18
+ super
19
+ end
20
+ end
@@ -0,0 +1,64 @@
1
+ class UserRegistrationsController < Devise::RegistrationsController
2
+ include SpreeBase
3
+ helper :users, 'spree/base'
4
+
5
+ ssl_required
6
+ after_filter :associate_user, :only => :create
7
+ before_filter :check_permissions, :only => [:edit, :update]
8
+ skip_before_filter :require_no_authentication
9
+
10
+ # GET /resource/sign_up
11
+ def new
12
+ super
13
+ end
14
+
15
+ # POST /resource/sign_up
16
+ def create
17
+ @user = build_resource(params[:user])
18
+ logger.debug(@user)
19
+ if resource.save
20
+ set_flash_message(:notice, :signed_up)
21
+ sign_in_and_redirect(:user, @user)
22
+ else
23
+ clean_up_passwords(resource)
24
+ render_with_scope(:new)
25
+ end
26
+ end
27
+
28
+ # GET /resource/edit
29
+ def edit
30
+ super
31
+ end
32
+
33
+ # PUT /resource
34
+ def update
35
+ super
36
+ end
37
+
38
+ # DELETE /resource
39
+ def destroy
40
+ super
41
+ end
42
+
43
+ # GET /resource/cancel
44
+ # Forces the session data which is usually expired after sign
45
+ # in to be expired now. This is useful if the user wants to
46
+ # cancel oauth signing in/up in the middle of the process,
47
+ # removing all OAuth session data.
48
+ def cancel
49
+ super
50
+ end
51
+
52
+ protected
53
+
54
+ def check_permissions
55
+ authorize!(:create, resource)
56
+ end
57
+
58
+ def associate_user
59
+ return unless current_user and current_order
60
+ current_order.associate_user!(current_user)
61
+ session[:guest_token] = nil
62
+ end
63
+
64
+ end
@@ -0,0 +1,81 @@
1
+ class UserSessionsController < Devise::SessionsController
2
+ include SpreeBase
3
+ helper :users, 'spree/base'
4
+
5
+ include Spree::CurrentOrder
6
+
7
+ after_filter :associate_user, :only => :create
8
+
9
+ ssl_required :new, :create, :destroy, :update
10
+ ssl_allowed :login_bar
11
+
12
+ # GET /resource/sign_in
13
+ def new
14
+ super
15
+ end
16
+ def create
17
+ authenticate_user!
18
+
19
+ if user_signed_in?
20
+ api_key = current_user.generate_api_key!
21
+ user_response = Hash.new
22
+ user_response[:user] = Hash.new
23
+ user_response[:user][:email]=current_user.email
24
+ user_response[:user][:authentication_token]=current_user.authentication_token
25
+ user_response[:user][:sign_in_count]=current_user.sign_in_count
26
+ respond_to do |format|
27
+ format.html {
28
+ flash.notice = t(:logged_in_succesfully)
29
+ redirect_back_or_default(products_path)
30
+ }
31
+ format.json {
32
+ render :json => user_response.to_json
33
+ }
34
+ end
35
+ else
36
+ flash.now[:error] = t('devise.failure.invalid')
37
+ render :new
38
+ end
39
+ end
40
+ #~ def create
41
+ #~ authenticate_user!
42
+
43
+ #~ if user_signed_in?
44
+ #~ respond_to do |format|
45
+ #~ format.html {
46
+ #~ flash[:notice] = I18n.t("logged_in_succesfully")
47
+ #~ redirect_back_or_default(products_path)
48
+ #~ }
49
+ #~ format.js {
50
+ #~ user = resource.record
51
+ #~ render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
52
+ #~ }
53
+ #~ end
54
+ #~ else
55
+ #~ flash[:error] = I18n.t("devise.failure.invalid")
56
+ #~ render :new
57
+ #~ end
58
+ #~ end
59
+
60
+ def destroy
61
+ session.clear
62
+ super
63
+ end
64
+
65
+ def nav_bar
66
+ render :partial => "shared/nav_bar"
67
+ end
68
+
69
+ private
70
+
71
+ def associate_user
72
+ return unless current_user and current_order
73
+ current_order.associate_user!(current_user)
74
+ session[:guest_token] = nil
75
+ end
76
+
77
+ def accurate_title
78
+ I18n.t(:log_in)
79
+ end
80
+
81
+ end
@@ -0,0 +1,54 @@
1
+ class UsersController < Spree::BaseController
2
+ prepend_before_filter :load_object, :only => [:show, :edit, :update]
3
+ prepend_before_filter :authorize_actions, :only => :new
4
+
5
+ def show
6
+ @orders = @user.orders.complete
7
+ end
8
+
9
+ def create
10
+ @user = User.new(params[:user])
11
+ if @user.save
12
+
13
+ if current_order
14
+ current_order.associate_user!(@user)
15
+ session[:guest_token] = nil
16
+ end
17
+
18
+ redirect_back_or_default(root_url)
19
+ else
20
+ render 'new'
21
+ end
22
+
23
+ end
24
+
25
+ def update
26
+ if @user.update_attributes(params[:user])
27
+ if params[:user][:password].present?
28
+ # this logic needed b/c devise wants to log us out after password changes
29
+ user = User.reset_password_by_token(params[:user])
30
+ sign_in(@user, :event => :authentication, :bypass => !Spree::Auth::Config[:signout_after_password_change])
31
+ end
32
+ flash.notice = I18n.t("account_updated")
33
+ redirect_to account_url
34
+ else
35
+ render 'edit'
36
+ end
37
+
38
+ end
39
+
40
+ private
41
+ def load_object
42
+ @user ||= current_user
43
+ authorize! params[:action].to_sym, @user
44
+ end
45
+
46
+ def authorize_actions
47
+ authorize! params[:action].to_sym, User
48
+ end
49
+
50
+ def accurate_title
51
+ I18n.t(:account)
52
+ end
53
+
54
+ end