devise 1.1.rc2 → 1.1.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.
- data/CHANGELOG.rdoc +22 -2
- data/Gemfile +7 -13
- data/Gemfile.lock +118 -0
- data/README.rdoc +15 -13
- data/app/controllers/devise/unlocks_controller.rb +0 -7
- data/app/mailers/devise/mailer.rb +7 -4
- data/app/views/devise/confirmations/new.html.erb +1 -1
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/unlocks/new.html.erb +1 -1
- data/lib/devise.rb +27 -9
- data/lib/devise/controllers/helpers.rb +19 -5
- data/lib/devise/controllers/internal_helpers.rb +2 -8
- data/lib/devise/encryptors/base.rb +1 -1
- data/lib/devise/encryptors/bcrypt.rb +2 -2
- data/lib/devise/failure_app.rb +6 -2
- data/lib/devise/hooks/rememberable.rb +9 -1
- data/lib/devise/mapping.rb +15 -50
- data/lib/devise/models/authenticatable.rb +8 -0
- data/lib/devise/models/confirmable.rb +10 -6
- data/lib/devise/models/database_authenticatable.rb +9 -1
- data/lib/devise/models/recoverable.rb +6 -1
- data/lib/devise/models/rememberable.rb +36 -7
- data/lib/devise/models/token_authenticatable.rb +5 -5
- data/lib/devise/models/validatable.rb +1 -1
- data/lib/devise/path_checker.rb +7 -2
- data/lib/devise/rails.rb +6 -1
- data/lib/devise/rails/routes.rb +137 -50
- data/lib/devise/rails/warden_compat.rb +16 -2
- data/lib/devise/strategies/authenticatable.rb +12 -0
- data/lib/devise/strategies/base.rb +0 -18
- data/lib/devise/strategies/rememberable.rb +9 -1
- data/lib/devise/test_helpers.rb +2 -0
- data/lib/devise/version.rb +1 -1
- data/lib/generators/active_record/devise_generator.rb +28 -0
- data/lib/generators/{devise/devise → active_record}/templates/migration.rb +4 -0
- data/lib/generators/devise/devise_generator.rb +17 -0
- data/lib/generators/devise/{install/install_generator.rb → install_generator.rb} +1 -1
- data/lib/generators/devise/orm_helpers.rb +23 -0
- data/lib/generators/devise/{install/templates → templates}/README +0 -0
- data/lib/generators/devise/{install/templates → templates}/devise.rb +20 -13
- data/lib/generators/devise/{views/views_generator.rb → views_generator.rb} +2 -2
- data/lib/generators/mongoid/devise_generator.rb +17 -0
- data/test/controllers/helpers_test.rb +9 -0
- data/test/controllers/internal_helpers_test.rb +7 -16
- data/test/controllers/url_helpers_test.rb +11 -0
- data/test/encryptors_test.rb +1 -1
- data/test/failure_app_test.rb +18 -5
- data/test/integration/authenticatable_test.rb +76 -11
- data/test/integration/confirmable_test.rb +16 -9
- data/test/integration/lockable_test.rb +11 -13
- data/test/integration/registerable_test.rb +4 -4
- data/test/integration/rememberable_test.rb +54 -1
- data/test/mapping_test.rb +10 -45
- data/test/models/confirmable_test.rb +1 -1
- data/test/models/rememberable_test.rb +108 -0
- data/test/models/validatable_test.rb +2 -4
- data/test/models_test.rb +4 -4
- data/test/rails_app/app/active_record/admin.rb +1 -1
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
- data/test/rails_app/app/controllers/users_controller.rb +5 -1
- data/test/rails_app/app/mongoid/admin.rb +1 -1
- data/test/rails_app/config/application.rb +2 -2
- data/test/rails_app/config/environments/test.rb +2 -0
- data/test/rails_app/config/initializers/devise.rb +95 -34
- data/test/rails_app/config/routes.rb +32 -14
- data/test/routes_test.rb +34 -2
- data/test/support/integration.rb +22 -6
- data/test/test_helpers_test.rb +16 -2
- metadata +24 -27
- data/lib/devise/orm/data_mapper.rb +0 -97
- data/lib/generators/devise/devise/devise_generator.rb +0 -86
- data/lib/generators/devise_generator.rb +0 -2
- data/test/orm/data_mapper.rb +0 -10
- data/test/rails_app/app/data_mapper/admin.rb +0 -12
- data/test/rails_app/app/data_mapper/shim.rb +0 -2
- data/test/rails_app/app/data_mapper/user.rb +0 -23
data/lib/devise/failure_app.rb
CHANGED
@@ -47,7 +47,7 @@ module Devise
|
|
47
47
|
def redirect
|
48
48
|
store_location!
|
49
49
|
flash[:alert] = i18n_message unless flash[:notice]
|
50
|
-
redirect_to
|
50
|
+
redirect_to redirect_url
|
51
51
|
end
|
52
52
|
|
53
53
|
protected
|
@@ -63,8 +63,12 @@ module Devise
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
+
def redirect_url
|
67
|
+
send(:"new_#{scope}_session_path")
|
68
|
+
end
|
69
|
+
|
66
70
|
def http_auth?
|
67
|
-
!Devise.navigational_formats.include?(request.format.to_sym) || request.xhr?
|
71
|
+
!Devise.navigational_formats.include?(request.format.to_sym) || (request.xhr? && Devise.http_authenticatable_on_xhr)
|
68
72
|
end
|
69
73
|
|
70
74
|
def http_auth_body
|
@@ -9,7 +9,7 @@ module Devise
|
|
9
9
|
super
|
10
10
|
|
11
11
|
if succeeded? && resource.respond_to?(:remember_me!) && remember_me?
|
12
|
-
resource.remember_me!
|
12
|
+
resource.remember_me!(extend_remember_period?)
|
13
13
|
|
14
14
|
configuration = {
|
15
15
|
:value => resource.class.serialize_into_cookie(resource),
|
@@ -24,6 +24,14 @@ module Devise
|
|
24
24
|
|
25
25
|
protected
|
26
26
|
|
27
|
+
def succeeded?
|
28
|
+
@result == :success
|
29
|
+
end
|
30
|
+
|
31
|
+
def extend_remember_period?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
27
35
|
def remember_me?
|
28
36
|
valid_params? && Devise::TRUE_VALUES.include?(params_auth_hash[:remember_me])
|
29
37
|
end
|
data/lib/devise/mapping.rb
CHANGED
@@ -22,19 +22,9 @@ module Devise
|
|
22
22
|
# # is the modules included in the class
|
23
23
|
#
|
24
24
|
class Mapping #:nodoc:
|
25
|
-
attr_reader :singular, :plural, :path, :controllers, :path_names, :
|
25
|
+
attr_reader :singular, :plural, :path, :controllers, :path_names, :class_name
|
26
26
|
alias :name :singular
|
27
27
|
|
28
|
-
# Loop through all mappings looking for a map that matches with the requested
|
29
|
-
# path (ie /users/sign_in). If a path prefix is given, it's taken into account.
|
30
|
-
def self.find_by_path(path)
|
31
|
-
Devise.mappings.each_value do |mapping|
|
32
|
-
route = path.split("/")[mapping.segment_position]
|
33
|
-
return mapping if route && mapping.path == route.to_sym
|
34
|
-
end
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
|
38
28
|
# Receives an object and find a scope for it. If a scope cannot be found,
|
39
29
|
# raises an error. If a symbol is given, it's considered to be the scope.
|
40
30
|
def self.find_scope!(duck)
|
@@ -51,31 +41,22 @@ module Devise
|
|
51
41
|
end
|
52
42
|
|
53
43
|
def initialize(name, options) #:nodoc:
|
54
|
-
|
55
|
-
|
56
|
-
options[:path] ||= as
|
57
|
-
end
|
44
|
+
@plural = (options[:as] ? "#{options[:as]}_#{name}" : name).to_sym
|
45
|
+
@singular = (options[:singular] || @plural.to_s.singularize).to_sym
|
58
46
|
|
59
|
-
|
60
|
-
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
61
|
-
options[:singular] ||= scope
|
62
|
-
end
|
63
|
-
|
64
|
-
@plural = name.to_sym
|
65
|
-
@path = (options.delete(:path) || name).to_sym
|
66
|
-
@singular = (options.delete(:singular) || name.to_s.singularize).to_sym
|
67
|
-
|
68
|
-
@class_name = (options.delete(:class_name) || name.to_s.classify).to_s
|
47
|
+
@class_name = (options[:class_name] || name.to_s.classify).to_s
|
69
48
|
@ref = ActiveSupport::Dependencies.ref(@class_name)
|
70
49
|
|
71
|
-
@
|
50
|
+
@path = (options[:path] || name).to_s
|
51
|
+
@path_prefix = options[:path_prefix]
|
72
52
|
|
73
|
-
|
74
|
-
@controllers.
|
53
|
+
mod = options[:module] || "devise"
|
54
|
+
@controllers = Hash.new { |h,k| h[k] = "#{mod}/#{k}" }
|
55
|
+
@controllers.merge!(options[:controllers] || {})
|
75
56
|
|
76
|
-
@path_names
|
57
|
+
@path_names = Hash.new { |h,k| h[k] = k.to_s }
|
77
58
|
@path_names.merge!(:registration => "")
|
78
|
-
@path_names.merge!(options
|
59
|
+
@path_names.merge!(options[:path_names] || {})
|
79
60
|
end
|
80
61
|
|
81
62
|
# Return modules for the mapping.
|
@@ -96,30 +77,14 @@ module Devise
|
|
96
77
|
@routes ||= ROUTES.values_at(*self.modules).compact.uniq
|
97
78
|
end
|
98
79
|
|
99
|
-
# Keep a list of allowed controllers for this mapping. It's useful to ensure
|
100
|
-
# that an Admin cannot access the registrations controller unless it has
|
101
|
-
# :registerable in the model.
|
102
|
-
def allowed_controllers
|
103
|
-
@allowed_controllers ||= begin
|
104
|
-
canonical = CONTROLLERS.values_at(*self.modules).compact
|
105
|
-
@controllers.values_at(*canonical)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Return in which position in the path prefix devise should find the as mapping.
|
110
|
-
def segment_position
|
111
|
-
self.path_prefix.count("/")
|
112
|
-
end
|
113
|
-
|
114
|
-
# Returns the raw path using path_prefix and as.
|
115
|
-
def full_path
|
116
|
-
path_prefix + path.to_s
|
117
|
-
end
|
118
|
-
|
119
80
|
def authenticatable?
|
120
81
|
@authenticatable ||= self.modules.any? { |m| m.to_s =~ /authenticatable/ }
|
121
82
|
end
|
122
83
|
|
84
|
+
def fullpath
|
85
|
+
"#{@path_prefix}/#{@path}".squeeze("/")
|
86
|
+
end
|
87
|
+
|
123
88
|
# Create magic predicates for verifying what module is activated by this map.
|
124
89
|
# Example:
|
125
90
|
#
|
@@ -112,6 +112,14 @@ module Devise
|
|
112
112
|
|
113
113
|
record
|
114
114
|
end
|
115
|
+
|
116
|
+
# Generate a token by looping and ensuring does not already exist.
|
117
|
+
def generate_token(column)
|
118
|
+
loop do
|
119
|
+
token = Devise.friendly_token
|
120
|
+
break token unless find(:first, :conditions => { column => token })
|
121
|
+
end
|
122
|
+
end
|
115
123
|
end
|
116
124
|
end
|
117
125
|
end
|
@@ -45,12 +45,12 @@ module Devise
|
|
45
45
|
|
46
46
|
# Verifies whether a user is confirmed or not
|
47
47
|
def confirmed?
|
48
|
-
|
48
|
+
!!confirmed_at
|
49
49
|
end
|
50
50
|
|
51
51
|
# Send confirmation instructions by email
|
52
52
|
def send_confirmation_instructions
|
53
|
-
generate_confirmation_token if self.confirmation_token.nil?
|
53
|
+
generate_confirmation_token! if self.confirmation_token.nil?
|
54
54
|
::Devise.mailer.confirmation_instructions(self).deliver
|
55
55
|
end
|
56
56
|
|
@@ -75,15 +75,14 @@ module Devise
|
|
75
75
|
# If you don't want confirmation to be sent on create, neither a code
|
76
76
|
# to be generated, call skip_confirmation!
|
77
77
|
def skip_confirmation!
|
78
|
-
self.confirmed_at
|
79
|
-
@skip_confirmation = true
|
78
|
+
self.confirmed_at = Time.now
|
80
79
|
end
|
81
80
|
|
82
81
|
protected
|
83
82
|
|
84
83
|
# Callback to overwrite if confirmation is required or not.
|
85
84
|
def confirmation_required?
|
86
|
-
|
85
|
+
!confirmed?
|
87
86
|
end
|
88
87
|
|
89
88
|
# Checks if the confirmation for the user is within the limit time.
|
@@ -128,6 +127,10 @@ module Devise
|
|
128
127
|
self.confirmation_sent_at = Time.now.utc
|
129
128
|
end
|
130
129
|
|
130
|
+
def generate_confirmation_token!
|
131
|
+
generate_confirmation_token && save(:validate => false)
|
132
|
+
end
|
133
|
+
|
131
134
|
module ClassMethods
|
132
135
|
# Attempt to find a user by it's email. If a record is found, send new
|
133
136
|
# confirmation instructions to it. If not user is found, returns a new user
|
@@ -149,8 +152,9 @@ module Devise
|
|
149
152
|
confirmable
|
150
153
|
end
|
151
154
|
|
155
|
+
# Generate a token checking if one does not already exist in the database.
|
152
156
|
def confirmation_token
|
153
|
-
|
157
|
+
generate_token(:confirmation_token)
|
154
158
|
end
|
155
159
|
|
156
160
|
Devise::Models.config(self, :confirm_within)
|
@@ -37,7 +37,7 @@ module Devise
|
|
37
37
|
@password = new_password
|
38
38
|
|
39
39
|
if @password.present?
|
40
|
-
self.password_salt = self.class.
|
40
|
+
self.password_salt = self.class.password_salt
|
41
41
|
self.encrypted_password = password_digest(@password)
|
42
42
|
end
|
43
43
|
end
|
@@ -93,6 +93,14 @@ module Devise
|
|
93
93
|
@encryptor_class ||= ::Devise::Encryptors.const_get(encryptor.to_s.classify)
|
94
94
|
end
|
95
95
|
|
96
|
+
def password_salt
|
97
|
+
self.encryptor_class.salt(self.stretches)
|
98
|
+
end
|
99
|
+
|
100
|
+
# We assume this method already gets the sanitized values from the
|
101
|
+
# DatabaseAuthenticatable strategy. If you are using this method on
|
102
|
+
# your own, be sure to sanitize the conditions hash to only include
|
103
|
+
# the proper fields.
|
96
104
|
def find_for_database_authentication(conditions)
|
97
105
|
find_for_authentication(conditions)
|
98
106
|
end
|
@@ -35,7 +35,7 @@ module Devise
|
|
35
35
|
|
36
36
|
# Generates a new random token for reset password
|
37
37
|
def generate_reset_password_token
|
38
|
-
self.reset_password_token =
|
38
|
+
self.reset_password_token = self.class.reset_password_token
|
39
39
|
end
|
40
40
|
|
41
41
|
# Resets the reset password token with and save the record without
|
@@ -60,6 +60,11 @@ module Devise
|
|
60
60
|
recoverable
|
61
61
|
end
|
62
62
|
|
63
|
+
# Generate a token checking if one does not already exist in the database.
|
64
|
+
def reset_password_token
|
65
|
+
generate_token(:reset_password_token)
|
66
|
+
end
|
67
|
+
|
63
68
|
# Attempt to find a user by it's reset_password_token to reset it's
|
64
69
|
# password. If a user is found, reset it's password and automatically
|
65
70
|
# try saving the record. If not user is found, returns a new user
|
@@ -18,7 +18,15 @@ module Devise
|
|
18
18
|
# blocked and will have to enter his credentials again.
|
19
19
|
# This configuration is also used to calculate the expires
|
20
20
|
# time for the cookie created to remember the user.
|
21
|
-
#
|
21
|
+
# 2.weeks by default.
|
22
|
+
#
|
23
|
+
# remember_across_browsers: if true, a valid remember token can be
|
24
|
+
# re-used between multiple browsers.
|
25
|
+
# True by default.
|
26
|
+
#
|
27
|
+
# extend_remember_period: if true, extends the user's remember period
|
28
|
+
# when remembered via cookie.
|
29
|
+
# False by default.
|
22
30
|
#
|
23
31
|
# Examples:
|
24
32
|
#
|
@@ -38,10 +46,11 @@ module Devise
|
|
38
46
|
attr_accessor :remember_me
|
39
47
|
end
|
40
48
|
|
41
|
-
# Generate a new remember token and save the record without validations
|
42
|
-
|
43
|
-
|
44
|
-
self.
|
49
|
+
# Generate a new remember token and save the record without validations
|
50
|
+
# unless remember_across_browsers is true and the user already has a valid token.
|
51
|
+
def remember_me!(extend_period=false)
|
52
|
+
self.remember_token = self.class.remember_token if generate_remember_token?
|
53
|
+
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
|
45
54
|
save(:validate => false)
|
46
55
|
end
|
47
56
|
|
@@ -57,7 +66,7 @@ module Devise
|
|
57
66
|
|
58
67
|
# Remember token should be expired if expiration time not overpass now.
|
59
68
|
def remember_expired?
|
60
|
-
remember_expires_at <= Time.now.utc
|
69
|
+
remember_created_at && (remember_expires_at <= Time.now.utc)
|
61
70
|
end
|
62
71
|
|
63
72
|
# Remember token expires at created time + remember_for configuration
|
@@ -73,6 +82,20 @@ module Devise
|
|
73
82
|
self.class.cookie_domain != false
|
74
83
|
end
|
75
84
|
|
85
|
+
protected
|
86
|
+
|
87
|
+
# Generate a token unless remember_across_browsers is true and there is
|
88
|
+
# an existing remember_token or the existing remember_token has expried.
|
89
|
+
def generate_remember_token? #:nodoc:
|
90
|
+
!(self.class.remember_across_browsers && remember_token) || remember_expired?
|
91
|
+
end
|
92
|
+
|
93
|
+
# Generate a timestamp if extend_remember_period is true, if no remember_token
|
94
|
+
# exists, or if an existing remember token has expired.
|
95
|
+
def generate_remember_timestamp?(extend_period) #:nodoc:
|
96
|
+
extend_period || remember_created_at.nil? || remember_expired?
|
97
|
+
end
|
98
|
+
|
76
99
|
module ClassMethods
|
77
100
|
# Create the cookie key using the record id and remember_token
|
78
101
|
def serialize_into_cookie(record)
|
@@ -86,7 +109,13 @@ module Devise
|
|
86
109
|
record if record && !record.remember_expired?
|
87
110
|
end
|
88
111
|
|
89
|
-
|
112
|
+
# Generate a token checking if one does not already exist in the database.
|
113
|
+
def remember_token
|
114
|
+
generate_token(:remember_token)
|
115
|
+
end
|
116
|
+
|
117
|
+
Devise::Models.config(self, :remember_for, :remember_across_browsers,
|
118
|
+
:extend_remember_period, :cookie_domain)
|
90
119
|
end
|
91
120
|
end
|
92
121
|
end
|
@@ -44,16 +44,16 @@ module Devise
|
|
44
44
|
end
|
45
45
|
|
46
46
|
module ClassMethods
|
47
|
-
::Devise::Models.config(self, :token_authentication_key)
|
48
|
-
|
49
47
|
def find_for_token_authentication(conditions)
|
50
|
-
|
51
|
-
find_for_authentication(conditions)
|
48
|
+
find_for_authentication(:authentication_token => conditions[token_authentication_key])
|
52
49
|
end
|
53
50
|
|
51
|
+
# Generate a token checking if one does not already exist in the database.
|
54
52
|
def authentication_token
|
55
|
-
|
53
|
+
generate_token(:authentication_token)
|
56
54
|
end
|
55
|
+
|
56
|
+
::Devise::Models.config(self, :token_authentication_key)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -16,7 +16,7 @@ module Devise
|
|
16
16
|
|
17
17
|
base.class_eval do
|
18
18
|
validates_presence_of :email
|
19
|
-
validates_uniqueness_of :email, :scope => authentication_keys[1..-1], :allow_blank => true
|
19
|
+
validates_uniqueness_of :email, :scope => authentication_keys[1..-1], :case_sensitive => false, :allow_blank => true
|
20
20
|
validates_format_of :email, :with => email_regexp, :allow_blank => true
|
21
21
|
|
22
22
|
with_options :if => :password_required? do |v|
|
data/lib/devise/path_checker.rb
CHANGED
@@ -2,12 +2,17 @@ module Devise
|
|
2
2
|
class PathChecker
|
3
3
|
include Rails.application.routes.url_helpers
|
4
4
|
|
5
|
+
def self.default_url_options(*args)
|
6
|
+
ApplicationController.default_url_options(*args)
|
7
|
+
end
|
8
|
+
|
5
9
|
def initialize(env, scope)
|
6
|
-
@
|
10
|
+
@current_path = "/#{env["SCRIPT_NAME"]}/#{env["PATH_INFO"]}".squeeze("/")
|
11
|
+
@scope = scope
|
7
12
|
end
|
8
13
|
|
9
14
|
def signing_out?
|
10
|
-
@
|
15
|
+
@current_path == send("destroy_#{@scope}_session_path")
|
11
16
|
end
|
12
17
|
end
|
13
18
|
end
|
data/lib/devise/rails.rb
CHANGED
@@ -20,11 +20,16 @@ module Devise
|
|
20
20
|
Devise.encryptor ||= begin
|
21
21
|
warn "[WARNING] config.encryptor is not set in your config/initializers/devise.rb. " \
|
22
22
|
"Devise will then set it to :bcrypt. If you were using the previous default " \
|
23
|
-
"encryptor, please add config.encryptor = :sha1 to your configuration file."
|
23
|
+
"encryptor, please add config.encryptor = :sha1 to your configuration file." if Devise.mailer_sender
|
24
24
|
:bcrypt
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
initializer "devise.add_filters" do |app|
|
29
|
+
app.config.filter_parameters += [:password, :password_confirmation]
|
30
|
+
app.config.filter_parameters.uniq
|
31
|
+
end
|
32
|
+
|
28
33
|
unless Rails.env.production?
|
29
34
|
config.after_initialize do
|
30
35
|
actions = [:confirmation_instructions, :reset_password_instructions, :unlock_instructions]
|
data/lib/devise/rails/routes.rb
CHANGED
@@ -15,9 +15,10 @@ module ActionDispatch::Routing
|
|
15
15
|
# generate all needed routes for devise, based on what modules you have
|
16
16
|
# defined in your model.
|
17
17
|
#
|
18
|
-
# Examples
|
19
|
-
#
|
20
|
-
#
|
18
|
+
# ==== Examples
|
19
|
+
#
|
20
|
+
# Let's say you have an User model configured to use authenticatable,
|
21
|
+
# confirmable and recoverable modules. After creating this inside your routes:
|
21
22
|
#
|
22
23
|
# devise_for :users
|
23
24
|
#
|
@@ -25,20 +26,22 @@ module ActionDispatch::Routing
|
|
25
26
|
# needed routes:
|
26
27
|
#
|
27
28
|
# # Session routes for Authenticatable (default)
|
28
|
-
# new_user_session GET /users/sign_in {:controller=>"sessions", :action=>"new"}
|
29
|
-
# user_session POST /users/sign_in {:controller=>"sessions", :action=>"create"}
|
30
|
-
# destroy_user_session GET /users/sign_out {:controller=>"sessions", :action=>"destroy"}
|
29
|
+
# new_user_session GET /users/sign_in {:controller=>"devise/sessions", :action=>"new"}
|
30
|
+
# user_session POST /users/sign_in {:controller=>"devise/sessions", :action=>"create"}
|
31
|
+
# destroy_user_session GET /users/sign_out {:controller=>"devise/sessions", :action=>"destroy"}
|
31
32
|
#
|
32
33
|
# # Password routes for Recoverable, if User model has :recoverable configured
|
33
|
-
# new_user_password GET /users/password/new(.:format) {:controller=>"passwords", :action=>"new"}
|
34
|
-
# edit_user_password GET /users/password/edit(.:format) {:controller=>"passwords", :action=>"edit"}
|
35
|
-
# user_password PUT /users/password(.:format) {:controller=>"passwords", :action=>"update"}
|
36
|
-
# POST /users/password(.:format) {:controller=>"passwords", :action=>"create"}
|
34
|
+
# new_user_password GET /users/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
|
35
|
+
# edit_user_password GET /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
|
36
|
+
# user_password PUT /users/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
|
37
|
+
# POST /users/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
|
37
38
|
#
|
38
39
|
# # Confirmation routes for Confirmable, if User model has :confirmable configured
|
39
|
-
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"confirmations", :action=>"new"}
|
40
|
-
# user_confirmation GET /users/confirmation(.:format) {:controller=>"confirmations", :action=>"show"}
|
41
|
-
# POST /users/confirmation(.:format) {:controller=>"confirmations", :action=>"create"}
|
40
|
+
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
|
41
|
+
# user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
|
42
|
+
# POST /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
|
43
|
+
#
|
44
|
+
# ==== Options
|
42
45
|
#
|
43
46
|
# You can configure your routes with some options:
|
44
47
|
#
|
@@ -62,37 +65,84 @@ module ActionDispatch::Routing
|
|
62
65
|
#
|
63
66
|
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
|
64
67
|
#
|
65
|
-
# * :
|
68
|
+
# * :controllers => the controller which should be used. All routes by default points to Devise controllers.
|
69
|
+
# However, if you want them to point to custom controller, you should do:
|
66
70
|
#
|
67
|
-
# devise_for :users, :
|
71
|
+
# devise_for :users, :controllers => { :sessions => "users/sessions" }
|
68
72
|
#
|
69
|
-
#
|
70
|
-
#
|
73
|
+
# * :module => the namespace to find controlers. By default, devise will access devise/sessions,
|
74
|
+
# devise/registrations and so on. If you want to namespace all at once, use module:
|
71
75
|
#
|
72
|
-
#
|
73
|
-
# def self.default_url_options
|
74
|
-
# { :locale => I18n.locale }
|
75
|
-
# end
|
76
|
-
# end
|
76
|
+
# devise_for :users, :module => "users"
|
77
77
|
#
|
78
|
-
#
|
79
|
-
#
|
78
|
+
# Notice that whenever you use namespace in the router DSL, it automatically sets the module.
|
79
|
+
# So the following setup:
|
80
80
|
#
|
81
|
-
#
|
81
|
+
# namespace :publisher
|
82
|
+
# devise_for :account
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# Will use publisher/sessions controller instead of devise/sessions controller. You can revert
|
86
|
+
# this by providing the :module option to devise_for.
|
82
87
|
#
|
83
88
|
# * :skip => tell which controller you want to skip routes from being created:
|
84
89
|
#
|
85
90
|
# devise_for :users, :skip => :sessions
|
86
91
|
#
|
92
|
+
# ==== Scoping
|
93
|
+
#
|
94
|
+
# Following Rails 3 routes DSL, you can nest devise_for calls inside a scope:
|
95
|
+
#
|
96
|
+
# scope "/my" do
|
97
|
+
# devise_for :users
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# However, since Devise uses the request path to retrieve the current user, it has one caveats.
|
101
|
+
# If you are using a dynamic segment, as below:
|
102
|
+
#
|
103
|
+
# scope ":locale" do
|
104
|
+
# devise_for :users
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# You are required to configure default_url_options in your ApplicationController class level, so
|
108
|
+
# Devise can pick it:
|
109
|
+
#
|
110
|
+
# class ApplicationController < ActionController::Base
|
111
|
+
# def self.default_url_options
|
112
|
+
# { :locale => I18n.locale }
|
113
|
+
# end
|
114
|
+
# end
|
115
|
+
#
|
87
116
|
def devise_for(*resources)
|
88
117
|
options = resources.extract_options!
|
118
|
+
|
119
|
+
if as = options.delete(:as)
|
120
|
+
ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
|
121
|
+
options[:path] ||= as
|
122
|
+
end
|
123
|
+
|
124
|
+
if scope = options.delete(:scope)
|
125
|
+
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
126
|
+
options[:singular] ||= scope
|
127
|
+
end
|
128
|
+
|
129
|
+
options[:as] ||= @scope[:as] if @scope[:as].present?
|
130
|
+
options[:module] ||= @scope[:module] if @scope[:module].present?
|
131
|
+
options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
|
132
|
+
options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
|
133
|
+
|
89
134
|
resources.map!(&:to_sym)
|
90
135
|
|
91
136
|
resources.each do |resource|
|
92
|
-
mapping = Devise.
|
137
|
+
mapping = Devise.add_mapping(resource, options)
|
93
138
|
|
94
139
|
begin
|
95
140
|
raise_no_devise_method_error!(mapping.class_name) unless mapping.to.respond_to?(:devise)
|
141
|
+
rescue NameError => e
|
142
|
+
raise unless mapping.class_name == resource.to_s.classify
|
143
|
+
warn "[WARNING] You provided devise_for #{resource.inspect} but there is " <<
|
144
|
+
"no model #{mapping.class_name} defined in your application"
|
145
|
+
next
|
96
146
|
rescue NoMethodError => e
|
97
147
|
raise unless e.message.include?("undefined method `devise'")
|
98
148
|
raise_no_devise_method_error!(mapping.class_name)
|
@@ -101,12 +151,21 @@ module ActionDispatch::Routing
|
|
101
151
|
routes = mapping.routes
|
102
152
|
routes -= Array(options.delete(:skip)).map { |s| s.to_s.singularize.to_sym }
|
103
153
|
|
104
|
-
|
105
|
-
|
154
|
+
devise_scope mapping.name do
|
155
|
+
yield if block_given?
|
156
|
+
with_devise_exclusive_scope mapping.fullpath, mapping.name do
|
157
|
+
routes.each { |mod| send(:"devise_#{mod}", mapping, mapping.controllers) }
|
158
|
+
end
|
106
159
|
end
|
107
160
|
end
|
108
161
|
end
|
109
162
|
|
163
|
+
# Allow you to add authentication request from the router:
|
164
|
+
#
|
165
|
+
# authenticate(:user) do
|
166
|
+
# resources :post
|
167
|
+
# end
|
168
|
+
#
|
110
169
|
def authenticate(scope)
|
111
170
|
constraint = lambda do |request|
|
112
171
|
request.env["warden"].authenticate!(:scope => scope)
|
@@ -117,42 +176,70 @@ module ActionDispatch::Routing
|
|
117
176
|
end
|
118
177
|
end
|
119
178
|
|
179
|
+
# Sets the devise scope to be used in the controller. If you have custom routes,
|
180
|
+
# you are required to call this method (also aliased as :as) in order to specify
|
181
|
+
# to which controller it is targetted.
|
182
|
+
#
|
183
|
+
# as :user do
|
184
|
+
# get "sign_in", :to => "devise/sessions#new"
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# Notice you cannot have two scopes mapping to the same URL. And remember, if
|
188
|
+
# you try to access a devise controller without specifying a scope, it will
|
189
|
+
# raise ActionNotFound error.
|
190
|
+
def devise_scope(scope)
|
191
|
+
constraint = lambda do |request|
|
192
|
+
request.env["devise.mapping"] = Devise.mappings[scope]
|
193
|
+
true
|
194
|
+
end
|
195
|
+
|
196
|
+
constraints(constraint) do
|
197
|
+
yield
|
198
|
+
end
|
199
|
+
end
|
200
|
+
alias :as :devise_scope
|
201
|
+
|
120
202
|
protected
|
121
203
|
|
122
|
-
def devise_session(mapping, controllers)
|
123
|
-
scope
|
124
|
-
get
|
125
|
-
post
|
126
|
-
get
|
204
|
+
def devise_session(mapping, controllers) #:nodoc:
|
205
|
+
scope :controller => controllers[:sessions], :as => :session do
|
206
|
+
get :new, :path => mapping.path_names[:sign_in]
|
207
|
+
post :create, :path => mapping.path_names[:sign_in], :as => ""
|
208
|
+
get :destroy, :path => mapping.path_names[:sign_out]
|
127
209
|
end
|
128
210
|
end
|
129
211
|
|
130
|
-
def devise_password(mapping, controllers)
|
131
|
-
|
132
|
-
|
133
|
-
end
|
212
|
+
def devise_password(mapping, controllers) #:nodoc:
|
213
|
+
resource :password, :only => [:new, :create, :edit, :update],
|
214
|
+
:path => mapping.path_names[:password], :controller => controllers[:passwords]
|
134
215
|
end
|
135
216
|
|
136
|
-
def devise_confirmation(mapping, controllers)
|
137
|
-
|
138
|
-
|
139
|
-
end
|
217
|
+
def devise_confirmation(mapping, controllers) #:nodoc:
|
218
|
+
resource :confirmation, :only => [:new, :create, :show],
|
219
|
+
:path => mapping.path_names[:confirmation], :controller => controllers[:confirmations]
|
140
220
|
end
|
141
221
|
|
142
|
-
def devise_unlock(mapping, controllers)
|
143
|
-
|
144
|
-
resource :unlock, :only => [:new, :create, :show],
|
222
|
+
def devise_unlock(mapping, controllers) #:nodoc:
|
223
|
+
if mapping.to.unlock_strategy_enabled?(:email)
|
224
|
+
resource :unlock, :only => [:new, :create, :show],
|
225
|
+
:path => mapping.path_names[:unlock], :controller => controllers[:unlocks]
|
145
226
|
end
|
146
227
|
end
|
147
228
|
|
148
|
-
def devise_registration(mapping, controllers)
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
229
|
+
def devise_registration(mapping, controllers) #:nodoc:
|
230
|
+
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
|
231
|
+
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
|
232
|
+
end
|
233
|
+
|
234
|
+
def with_devise_exclusive_scope(new_path, new_as) #:nodoc:
|
235
|
+
old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module]
|
236
|
+
@scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil
|
237
|
+
yield
|
238
|
+
ensure
|
239
|
+
@scope[:as], @scope[:path], @scope[:module] = old_as, old_path, old_module
|
153
240
|
end
|
154
241
|
|
155
|
-
def raise_no_devise_method_error!(klass)
|
242
|
+
def raise_no_devise_method_error!(klass) #:nodoc:
|
156
243
|
raise "#{klass} does not respond to 'devise' method. This usually means you haven't " <<
|
157
244
|
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " <<
|
158
245
|
"inside 'config/initializers/devise.rb' or before your application definition in 'config/application.rb'"
|