devise 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (80) hide show
  1. data/CHANGELOG.rdoc +21 -2
  2. data/README.rdoc +40 -54
  3. data/Rakefile +1 -1
  4. data/TODO +1 -3
  5. data/app/controllers/confirmations_controller.rb +9 -20
  6. data/app/controllers/passwords_controller.rb +9 -20
  7. data/app/controllers/sessions_controller.rb +9 -9
  8. data/app/controllers/unlocks_controller.rb +22 -0
  9. data/app/models/devise_mailer.rb +6 -1
  10. data/app/views/confirmations/new.html.erb +1 -5
  11. data/app/views/devise_mailer/unlock_instructions.html.erb +7 -0
  12. data/app/views/passwords/edit.html.erb +1 -5
  13. data/app/views/passwords/new.html.erb +1 -5
  14. data/app/views/sessions/new.html.erb +1 -7
  15. data/app/views/shared/_devise_links.erb +15 -0
  16. data/app/views/unlocks/new.html.erb +12 -0
  17. data/generators/devise/templates/migration.rb +2 -0
  18. data/generators/devise/templates/model.rb +4 -1
  19. data/generators/devise_install/templates/devise.rb +20 -10
  20. data/lib/devise.rb +62 -18
  21. data/lib/devise/controllers/common.rb +24 -0
  22. data/lib/devise/controllers/helpers.rb +160 -80
  23. data/lib/devise/controllers/internal_helpers.rb +120 -0
  24. data/lib/devise/controllers/url_helpers.rb +2 -10
  25. data/lib/devise/encryptors/bcrypt.rb +2 -2
  26. data/lib/devise/hooks/activatable.rb +1 -4
  27. data/lib/devise/hooks/rememberable.rb +30 -0
  28. data/lib/devise/hooks/timeoutable.rb +4 -2
  29. data/lib/devise/locales/en.yml +9 -2
  30. data/lib/devise/mapping.rb +15 -11
  31. data/lib/devise/models.rb +16 -35
  32. data/lib/devise/models/activatable.rb +1 -1
  33. data/lib/devise/models/authenticatable.rb +1 -9
  34. data/lib/devise/models/confirmable.rb +6 -2
  35. data/lib/devise/models/lockable.rb +142 -0
  36. data/lib/devise/models/rememberable.rb +19 -2
  37. data/lib/devise/models/timeoutable.rb +1 -2
  38. data/lib/devise/orm/active_record.rb +2 -0
  39. data/lib/devise/orm/data_mapper.rb +1 -1
  40. data/lib/devise/orm/mongo_mapper.rb +12 -1
  41. data/lib/devise/rails/routes.rb +5 -1
  42. data/lib/devise/rails/warden_compat.rb +13 -13
  43. data/lib/devise/schema.rb +7 -0
  44. data/lib/devise/strategies/authenticatable.rb +1 -3
  45. data/lib/devise/strategies/base.rb +1 -1
  46. data/lib/devise/strategies/rememberable.rb +37 -0
  47. data/lib/devise/test_helpers.rb +1 -1
  48. data/lib/devise/version.rb +1 -1
  49. data/test/controllers/helpers_test.rb +155 -33
  50. data/test/controllers/internal_helpers_test.rb +55 -0
  51. data/test/devise_test.rb +24 -3
  52. data/test/encryptors_test.rb +3 -1
  53. data/test/integration/lockable_test.rb +83 -0
  54. data/test/integration/rememberable_test.rb +1 -1
  55. data/test/mailers/unlock_instructions_test.rb +62 -0
  56. data/test/models/authenticatable_test.rb +0 -23
  57. data/test/models/lockable_test.rb +202 -0
  58. data/test/models/timeoutable_test.rb +7 -7
  59. data/test/models/validatable_test.rb +2 -2
  60. data/test/models_test.rb +9 -76
  61. data/test/orm/active_record.rb +1 -0
  62. data/test/orm/mongo_mapper.rb +0 -1
  63. data/test/rails_app/app/active_record/admin.rb +1 -1
  64. data/test/rails_app/app/active_record/user.rb +2 -1
  65. data/test/rails_app/app/mongo_mapper/admin.rb +1 -1
  66. data/test/rails_app/app/mongo_mapper/user.rb +2 -1
  67. data/test/rails_app/config/initializers/devise.rb +13 -10
  68. data/test/rails_app/config/routes.rb +5 -3
  69. data/test/routes_test.rb +5 -0
  70. data/test/support/integration_tests_helper.rb +1 -0
  71. metadata +16 -12
  72. data/lib/devise/controllers/filters.rb +0 -186
  73. data/lib/devise/models/cookie_serializer.rb +0 -21
  74. data/lib/devise/models/session_serializer.rb +0 -19
  75. data/lib/devise/serializers/base.rb +0 -23
  76. data/lib/devise/serializers/cookie.rb +0 -43
  77. data/lib/devise/serializers/session.rb +0 -22
  78. data/test/controllers/filters_test.rb +0 -177
  79. data/test/rails_app/app/active_record/account.rb +0 -7
  80. data/test/rails_app/app/mongo_mapper/account.rb +0 -9
@@ -9,8 +9,4 @@
9
9
  <p><%= f.submit "Send me reset password instructions" %></p>
10
10
  <% end %>
11
11
 
12
- <%= link_to "Sign in", new_session_path(resource_name) %><br />
13
-
14
- <%- if devise_mapping.confirmable? %>
15
- <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
16
- <% end -%>
12
+ <%= render :partial => "shared/devise_links" %>
@@ -16,10 +16,4 @@
16
16
  <% end -%>
17
17
  <% end%>
18
18
 
19
- <%- if devise_mapping.recoverable? %>
20
- <%= link_to "Forgot password?", new_password_path(resource_name) %><br />
21
- <% end -%>
22
-
23
- <%- if devise_mapping.confirmable? %>
24
- <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
25
- <% end -%>
19
+ <%= render :partial => "shared/devise_links" %>
@@ -0,0 +1,15 @@
1
+ <%- if controller_name != 'sessions' %>
2
+ <%= link_to t('devise.sessions.link'), new_session_path(resource_name) %><br />
3
+ <% end -%>
4
+
5
+ <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
6
+ <%= link_to t('devise.passwords.link'), new_password_path(resource_name) %><br />
7
+ <% end -%>
8
+
9
+ <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
10
+ <%= link_to t('devise.confirmations.link'), new_confirmation_path(resource_name) %><br />
11
+ <% end -%>
12
+
13
+ <%- if devise_mapping.lockable? && controller_name != 'unlocks' %>
14
+ <%= link_to t('devise.unlocks.link'), new_unlock_path(resource_name) %><br />
15
+ <% end -%>
@@ -0,0 +1,12 @@
1
+ <h2>Resend unlock instructions</h2>
2
+
3
+ <% form_for resource_name, resource, :url => unlock_path(resource_name) do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <p><%= f.label :email %></p>
7
+ <p><%= f.text_field :email %></p>
8
+
9
+ <p><%= f.submit "Resend unlock instructions" %></p>
10
+ <% end %>
11
+
12
+ <%= render :partial => "shared/devise_links" %>
@@ -6,6 +6,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
6
6
  t.recoverable
7
7
  t.rememberable
8
8
  t.trackable
9
+ # t.lockable
9
10
 
10
11
  t.timestamps
11
12
  end
@@ -13,6 +14,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
13
14
  add_index :<%= table_name %>, :email, :unique => true
14
15
  add_index :<%= table_name %>, :confirmation_token, :unique => true
15
16
  add_index :<%= table_name %>, :reset_password_token, :unique => true
17
+ # add_index :<%= table_name %>, :unlock_token, :unique => true
16
18
  end
17
19
 
18
20
  def self.down
@@ -1,5 +1,8 @@
1
1
  class <%= class_name %> < ActiveRecord::Base
2
- devise :all
2
+ # Include default devise modules.
3
+ # Others available are :lockable, :timeoutable and :activatable.
4
+ devise :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
5
+
3
6
  # Setup accessible (or protected) attributes for your model
4
7
  attr_accessible :email, :password, :password_confirmation
5
8
  end
@@ -1,18 +1,10 @@
1
1
  # Use this hook to configure devise mailer, warden hooks and so forth. The first
2
2
  # four configuration values can also be set straight in your models.
3
3
  Devise.setup do |config|
4
- # Configure Devise modules used by default. You should always set this value
5
- # because if Devise adds a new strategy, it won't be added to your application
6
- # by default, unless you configure it here.
7
- #
8
- # Remember that Devise includes other modules on its own (like :activatable
9
- # and :timeoutable) which are not included here and also plugins. So be sure
10
- # to check the docs for a complete set.
11
- config.all = [:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable]
12
-
13
4
  # Configure the e-mail address which will be shown in DeviseMailer.
14
5
  config.mailer_sender = "please-change-me@config-initializers-devise.com"
15
6
 
7
+ # ==> Configuration for :authenticatable
16
8
  # Invoke `rake secret` and use the printed value to setup a pepper to generate
17
9
  # the encrypted password. By default no pepper is used.
18
10
  # config.pepper = "rake secret output"
@@ -34,18 +26,36 @@ Devise.setup do |config|
34
26
  # session. If you need permissions, you should implement that in a before filter.
35
27
  # config.authentication_keys = [ :email ]
36
28
 
29
+ # ==> Configuration for :confirmable
37
30
  # The time you want give to your user to confirm his account. During this time
38
31
  # he will be able to access your application without confirming. Default is nil.
39
32
  # config.confirm_within = 2.days
40
33
 
34
+ # ==> Configuration for :rememberable
41
35
  # The time the user will be remembered without asking for credentials again.
42
36
  # config.remember_for = 2.weeks
43
37
 
38
+ # ==> Configuration for :timeoutable
44
39
  # The time you want to timeout the user session without activity. After this
45
40
  # time the user will be asked for credentials again.
46
41
  # config.timeout_in = 10.minutes
47
42
 
48
- # Load and configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper.
43
+ # ==> Configuration for :lockable
44
+ # Number of authentication tries before locking an account.
45
+ # config.maximum_attempts = 20
46
+
47
+ # Defines which strategy will be used to unlock an account.
48
+ # :email = Sends an unlock link to the user email
49
+ # :time = Reanables login after a certain ammount of time (see :unlock_in below)
50
+ # :both = enables both strategies
51
+ # config.unlock_strategy = :both
52
+
53
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
54
+ # config.unlock_in = 1.hour
55
+
56
+ # ==> General configuration
57
+ # Load and configure the ORM. Supports :active_record (default), :mongo_mapper
58
+ # (requires mongo_ext installed) and :data_mapper (experimental).
49
59
  # require 'devise/orm/mongo_mapper'
50
60
  # config.orm = :mongo_mapper
51
61
 
@@ -1,12 +1,12 @@
1
1
  module Devise
2
2
  autoload :FailureApp, 'devise/failure_app'
3
- autoload :Mapping, 'devise/mapping'
4
3
  autoload :Schema, 'devise/schema'
5
4
  autoload :TestHelpers, 'devise/test_helpers'
6
5
 
7
6
  module Controllers
8
- autoload :Filters, 'devise/controllers/filters'
7
+ autoload :Common, 'devise/controllers/common'
9
8
  autoload :Helpers, 'devise/controllers/helpers'
9
+ autoload :InternalHelpers, 'devise/controllers/internal_helpers'
10
10
  autoload :UrlHelpers, 'devise/controllers/url_helpers'
11
11
  end
12
12
 
@@ -26,22 +26,22 @@ module Devise
26
26
  autoload :MongoMapper, 'devise/orm/mongo_mapper'
27
27
  end
28
28
 
29
- ALL = [:authenticatable, :activatable, :confirmable, :recoverable, :rememberable,
30
- :timeoutable, :trackable, :validatable]
29
+ ALL = [:authenticatable, :activatable, :confirmable, :recoverable,
30
+ :rememberable, :validatable, :trackable, :timeoutable, :lockable]
31
31
 
32
32
  # Maps controller names to devise modules
33
33
  CONTROLLERS = {
34
34
  :sessions => [:authenticatable],
35
35
  :passwords => [:recoverable],
36
- :confirmations => [:confirmable]
36
+ :confirmations => [:confirmable],
37
+ :unlocks => [:lockable]
37
38
  }
38
39
 
39
- STRATEGIES = [:authenticatable]
40
- SERIALIZERS = [:session, :cookie]
40
+ STRATEGIES = [:rememberable, :authenticatable]
41
41
  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
42
42
 
43
43
  # Maps the messages types that are used in flash message.
44
- FLASH_MESSAGES = [ :unauthenticated, :unconfirmed, :invalid, :timeout, :inactive ]
44
+ FLASH_MESSAGES = [ :unauthenticated, :unconfirmed, :invalid, :timeout, :inactive, :locked ]
45
45
 
46
46
  # Declare encryptors length which are used in migrations.
47
47
  ENCRYPTORS_LENGTH = {
@@ -86,15 +86,15 @@ module Devise
86
86
 
87
87
  # Store scopes mappings.
88
88
  mattr_accessor :mappings
89
- @@mappings = {}
89
+ @@mappings = ActiveSupport::OrderedHash.new
90
90
 
91
91
  # Stores the chosen ORM.
92
92
  mattr_accessor :orm
93
93
  @@orm = :active_record
94
94
 
95
- # Configure default options used in :all.
95
+ # TODO Remove
96
96
  mattr_accessor :all
97
- @@all = Devise::ALL.dup
97
+ @@all = []
98
98
 
99
99
  # Tells if devise should apply the schema in ORMs where devise declaration
100
100
  # and schema belongs to the same class (as Datamapper and MongoMapper).
@@ -106,6 +106,19 @@ module Devise
106
106
  mattr_accessor :scoped_views
107
107
  @@scoped_views = false
108
108
 
109
+ # Number of authentication tries before locking an account
110
+ mattr_accessor :maximum_attempts
111
+ @@maximum_attempts = 20
112
+
113
+ # Defines which strategy can be used to unlock an account.
114
+ # Values: :email, :time, :both
115
+ mattr_accessor :unlock_strategy
116
+ @@unlock_strategy = :both
117
+
118
+ # Time interval to unlock the account if :time is defined as unlock_strategy.
119
+ mattr_accessor :unlock_in
120
+ @@unlock_in = 1.hour
121
+
109
122
  # Tell when to use the default scope, if one cannot be found from routes.
110
123
  mattr_accessor :use_default_scope
111
124
  @@use_default_scope
@@ -149,10 +162,8 @@ module Devise
149
162
  # block.
150
163
  def configure_warden(config) #:nodoc:
151
164
  config.default_strategies *Devise::STRATEGIES
152
- config.default_serializers *Devise::SERIALIZERS
153
165
  config.failure_app = Devise::FailureApp
154
166
  config.silence_missing_strategies!
155
- config.silence_missing_serializers!
156
167
  config.default_scope = Devise.default_scope
157
168
 
158
169
  # If the user provided a warden hook, call it now.
@@ -168,6 +179,42 @@ module Devise
168
179
  def friendly_token
169
180
  ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
170
181
  end
182
+
183
+ # Make Devise aware of an 3rd party Devise-module. For convenience.
184
+ #
185
+ # == Options:
186
+ #
187
+ # +strategy+ - Boolean value representing if this module got a custom *strategy*.
188
+ # Default is +false+. Note: Devise will auto-detect this in such case if this is true.
189
+ # +model+ - String representing a load path to a custom *model* for this module (to autoload).
190
+ # Default is +nil+ (i.e. +false+).
191
+ # +controller+ - Symbol representing a name of an exisiting or custom *controller* for this module.
192
+ # Default is +nil+ (i.e. +false+).
193
+ #
194
+ # == Examples:
195
+ #
196
+ # Devise.add_module(:party_module)
197
+ # Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
198
+ # Devise.add_module(:party_module, :model => 'party_module/model')
199
+ #
200
+ def add_module(module_name, options = {})
201
+ Devise::ALL.unshift module_name unless Devise::ALL.include?(module_name)
202
+ Devise::STRATEGIES.unshift module_name if options[:strategy] && !Devise::STRATEGIES.include?(module_name)
203
+
204
+ if options[:controller]
205
+ controller = options[:controller].to_sym
206
+ Devise::CONTROLLERS[controller] ||= []
207
+ Devise::CONTROLLERS[controller].unshift module_name unless Devise::CONTROLLERS[controller].include?(module_name)
208
+ end
209
+
210
+ if options[:model]
211
+ Devise::Models.module_eval do
212
+ autoload :"#{module_name.to_s.classify}", options[:model]
213
+ end
214
+ end
215
+
216
+ Devise::Mapping.register module_name
217
+ end
171
218
  end
172
219
  end
173
220
 
@@ -178,8 +225,5 @@ rescue
178
225
  require 'warden'
179
226
  end
180
227
 
181
- # Clear some Warden default configuration which will be overwritten
182
- Warden::Strategies.clear!
183
- Warden::Serializers.clear!
184
-
185
- require 'devise/rails'
228
+ require 'devise/mapping'
229
+ require 'devise/rails'
@@ -0,0 +1,24 @@
1
+ module Devise
2
+ module Controllers
3
+ # Common actions shared between Devise controllers
4
+ module Common #:nodoc:
5
+ # GET /resource/controller/new
6
+ def new
7
+ build_resource
8
+ render_with_scope :new
9
+ end
10
+
11
+ # POST /resource/controller
12
+ def create
13
+ self.resource = resource_class.send(send_instructions_with, params[resource_name])
14
+
15
+ if resource.errors.empty?
16
+ set_flash_message :notice, :send_instructions
17
+ redirect_to new_session_path(resource_name)
18
+ else
19
+ render_with_scope :new
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,118 +1,198 @@
1
1
  module Devise
2
2
  module Controllers
3
- # Those helpers are used only inside Devise controllers and should not be
4
- # included in ApplicationController since they all depend on the url being
5
- # accessed.
3
+ # Those helpers are convenience methods added to ApplicationController.
6
4
  module Helpers
7
5
 
8
6
  def self.included(base)
9
7
  base.class_eval do
10
- unloadable
8
+ helper_method :warden, :signed_in?, :devise_controller?,
9
+ *Devise.mappings.keys.map { |m| [:"current_#{m}", :"#{m}_signed_in?"] }.flatten
11
10
 
12
- helper_method :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller?
13
- hide_action :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller?
14
-
15
- skip_before_filter *Devise.mappings.keys.map { |m| :"authenticate_#{m}!" }
16
- before_filter :is_devise_resource?
11
+ # Use devise default_url_options. We have to declare it here to overwrite
12
+ # default definitions.
13
+ def default_url_options(options=nil)
14
+ Devise::Mapping.default_url_options
15
+ end
17
16
  end
18
17
  end
19
18
 
20
- # Gets the actual resource stored in the instance variable
21
- def resource
22
- instance_variable_get(:"@#{resource_name}")
19
+ # The main accessor for the warden proxy instance
20
+ def warden
21
+ request.env['warden']
23
22
  end
24
23
 
25
- # Proxy to devise map name
26
- def resource_name
27
- devise_mapping.name
24
+ # Return true if it's a devise_controller. false to all controllers unless
25
+ # the controllers defined inside devise. Useful if you want to apply a before
26
+ # filter to all controller, except the ones in devise:
27
+ #
28
+ # before_filter :my_filter, :unless => { |c| c.devise_controller? }
29
+ def devise_controller?
30
+ false
28
31
  end
29
- alias :scope_name :resource_name
30
32
 
31
- # Proxy to devise map class
32
- def resource_class
33
- devise_mapping.to
33
+ # Attempts to authenticate the given scope by running authentication hooks,
34
+ # but does not redirect in case of failures.
35
+ def authenticate(scope)
36
+ warden.authenticate(:scope => scope)
34
37
  end
35
38
 
36
- # Attempt to find the mapped route for devise based on request path
37
- def devise_mapping
38
- @devise_mapping ||= begin
39
- mapping = Devise::Mapping.find_by_path(request.path)
40
- mapping ||= Devise.mappings[Devise.default_scope] if Devise.use_default_scope
41
- mapping
42
- end
39
+ # Attempts to authenticate the given scope by running authentication hooks,
40
+ # redirecting in case of failures.
41
+ def authenticate!(scope)
42
+ warden.authenticate!(:scope => scope)
43
43
  end
44
44
 
45
- # Overwrites devise_controller? to return true
46
- def devise_controller?
47
- true
45
+ # Check if the given scope is signed in session, without running
46
+ # authentication hooks.
47
+ def signed_in?(scope)
48
+ warden.authenticate?(:scope => scope)
48
49
  end
49
50
 
50
- protected
51
+ # Sign in an user that already was authenticated. This helper is useful for logging
52
+ # users in after sign up.
53
+ #
54
+ # Examples:
55
+ #
56
+ # sign_in :user, @user # sign_in(scope, resource)
57
+ # sign_in @user # sign_in(resource)
58
+ #
59
+ def sign_in(resource_or_scope, resource=nil)
60
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
61
+ resource ||= resource_or_scope
62
+ warden.set_user(resource, :scope => scope)
63
+ end
51
64
 
52
- # Checks whether it's a devise mapped resource or not.
53
- def is_devise_resource? #:nodoc:
54
- raise ActionController::UnknownAction unless devise_mapping && devise_mapping.allows?(controller_name)
65
+ # Sign out a given user or scope. This helper is useful for signing out an user
66
+ # after deleting accounts.
67
+ #
68
+ # Examples:
69
+ #
70
+ # sign_out :user # sign_out(scope)
71
+ # sign_out @user # sign_out(resource)
72
+ #
73
+ def sign_out(resource_or_scope)
74
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
75
+ warden.user(scope) # Without loading user here, before_logout hook is not called
76
+ warden.raw_session.inspect # Without this inspect here. The session does not clear.
77
+ warden.logout(scope)
55
78
  end
56
79
 
57
- # Sets the resource creating an instance variable
58
- def resource=(new_resource)
59
- instance_variable_set(:"@#{resource_name}", new_resource)
80
+ # Returns and delete the url stored in the session for the given scope. Useful
81
+ # for giving redirect backs after sign up:
82
+ #
83
+ # Example:
84
+ #
85
+ # redirect_to stored_location_for(:user) || root_path
86
+ #
87
+ def stored_location_for(resource_or_scope)
88
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
89
+ session.delete(:"#{scope}.return_to")
60
90
  end
61
91
 
62
- # Build a devise resource without setting password and password confirmation fields.
63
- def build_resource
64
- self.resource ||= begin
65
- attributes = params[resource_name].try(:except, :password, :password_confirmation)
66
- resource_class.new(attributes || {})
67
- end
92
+ # The default url to be used after signing in. This is used by all Devise
93
+ # controllers and you can overwrite it in your ApplicationController to
94
+ # provide a custom hook for a custom resource.
95
+ #
96
+ # By default, it first tries to find a resource_root_path, otherwise it
97
+ # uses the root path. For a user scope, you can define the default url in
98
+ # the following way:
99
+ #
100
+ # map.user_root '/users', :controller => 'users' # creates user_root_path
101
+ #
102
+ # map.resources :users do |users|
103
+ # users.root # creates user_root_path
104
+ # end
105
+ #
106
+ #
107
+ # If none of these are defined, root_path is used. However, if this default
108
+ # is not enough, you can customize it, for example:
109
+ #
110
+ # def after_sign_in_path_for(resource)
111
+ # if resource.is_a?(User) && resource.can_publish?
112
+ # publisher_url
113
+ # else
114
+ # super
115
+ # end
116
+ # end
117
+ #
118
+ def after_sign_in_path_for(resource_or_scope)
119
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
120
+ home_path = :"#{scope}_root_path"
121
+ respond_to?(home_path, true) ? send(home_path) : root_path
68
122
  end
69
123
 
70
- # Helper for use in before_filters where no authentication is required.
124
+ # Method used by sessions controller to sign out an user. You can overwrite
125
+ # it in your ApplicationController to provide a custom hook for a custom
126
+ # scope. Notice that differently from +after_sign_in_path_for+ this method
127
+ # receives a symbol with the scope, and not the resource.
71
128
  #
72
- # Example:
73
- # before_filter :require_no_authentication, :only => :new
74
- def require_no_authentication
75
- redirect_to after_sign_in_path_for(resource_name) if warden.authenticated?(resource_name)
129
+ # By default is the root_path.
130
+ def after_sign_out_path_for(resource_or_scope)
131
+ root_path
76
132
  end
77
133
 
78
- # Sets the flash message with :key, using I18n. By default you are able
79
- # to setup your messages using specific resource scope, and if no one is
80
- # found we look to default scope.
81
- # Example (i18n locale file):
82
- #
83
- # en:
84
- # devise:
85
- # passwords:
86
- # #default_scope_messages - only if resource_scope is not found
87
- # user:
88
- # #resource_scope_messages
89
- #
90
- # Please refer to README or en.yml locale file to check what messages are
91
- # available.
92
- def set_flash_message(key, kind, now=false)
93
- flash_hash = now ? flash.now : flash
94
- flash_hash[key] = I18n.t(:"#{resource_name}.#{kind}",
95
- :scope => [:devise, controller_name.to_sym], :default => kind)
134
+ # Sign in an user and tries to redirect first to the stored location and
135
+ # then to the url specified by after_sign_in_path_for.
136
+ #
137
+ # If just a symbol is given, consider that the user was already signed in
138
+ # through other means and just perform the redirection.
139
+ def sign_in_and_redirect(resource_or_scope, resource=nil, skip=false)
140
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
141
+ resource ||= resource_or_scope
142
+ sign_in(scope, resource) unless skip
143
+ redirect_to stored_location_for(scope) || after_sign_in_path_for(resource)
96
144
  end
97
145
 
98
- # Shortcut to set flash.now message. Same rules applied from set_flash_message
99
- def set_now_flash_message(key, kind)
100
- set_flash_message(key, kind, true)
146
+ # Sign out an user and tries to redirect to the url specified by
147
+ # after_sign_out_path_for.
148
+ def sign_out_and_redirect(resource_or_scope)
149
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
150
+ sign_out(scope)
151
+ redirect_to after_sign_out_path_for(scope)
101
152
  end
102
153
 
103
- # Render a view for the specified scope. Turned off by default.
104
- # Accepts just :controller as option.
105
- def render_with_scope(action, options={})
106
- controller_name = options.delete(:controller) || self.controller_name
107
- if Devise.scoped_views
108
- begin
109
- render :template => "#{controller_name}/#{devise_mapping.as}/#{action}"
110
- rescue ActionView::MissingTemplate
111
- render action, :controller => controller_name
154
+ # Define authentication filters and accessor helpers based on mappings.
155
+ # These filters should be used inside the controllers as before_filters,
156
+ # so you can control the scope of the user who should be signed in to
157
+ # access that specific controller/action.
158
+ # Example:
159
+ #
160
+ # Maps:
161
+ # User => :authenticatable
162
+ # Admin => :authenticatable
163
+ #
164
+ # Generated methods:
165
+ # authenticate_user! # Signs user in or redirect
166
+ # authenticate_admin! # Signs admin in or redirect
167
+ # user_signed_in? # Checks whether there is an user signed in or not
168
+ # admin_signed_in? # Checks whether there is an admin signed in or not
169
+ # current_user # Current signed in user
170
+ # current_admin # Currend signed in admin
171
+ # user_session # Session data available only to the user scope
172
+ # admin_session # Session data available only to the admin scope
173
+ #
174
+ # Use:
175
+ # before_filter :authenticate_user! # Tell devise to use :user map
176
+ # before_filter :authenticate_admin! # Tell devise to use :admin map
177
+ #
178
+ Devise.mappings.each_key do |mapping|
179
+ class_eval <<-METHODS, __FILE__, __LINE__
180
+ def authenticate_#{mapping}!
181
+ warden.authenticate!(:scope => :#{mapping})
112
182
  end
113
- else
114
- render action, :controller => controller_name
115
- end
183
+
184
+ def #{mapping}_signed_in?
185
+ warden.authenticate?(:scope => :#{mapping})
186
+ end
187
+
188
+ def current_#{mapping}
189
+ @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
190
+ end
191
+
192
+ def #{mapping}_session
193
+ current_#{mapping} && warden.session(:#{mapping})
194
+ end
195
+ METHODS
116
196
  end
117
197
 
118
198
  end