devise 1.1.3 → 1.2.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.
- data/.gitignore +10 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.rdoc +94 -0
- data/Gemfile +24 -13
- data/Gemfile.lock +119 -75
- data/MIT-LICENSE +1 -1
- data/README.rdoc +144 -101
- data/Rakefile +3 -24
- data/app/controllers/devise/confirmations_controller.rb +1 -1
- data/app/controllers/devise/omniauth_callbacks_controller.rb +26 -0
- data/app/controllers/devise/passwords_controller.rb +1 -1
- data/app/controllers/devise/registrations_controller.rb +60 -7
- data/app/controllers/devise/sessions_controller.rb +6 -4
- data/app/controllers/devise/unlocks_controller.rb +1 -1
- data/app/helpers/devise_helper.rb +10 -2
- data/app/mailers/devise/mailer.rb +27 -10
- data/app/views/devise/confirmations/new.html.erb +1 -1
- data/app/views/devise/passwords/edit.html.erb +2 -2
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/edit.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/views/devise/shared/_links.erb +6 -0
- data/app/views/devise/unlocks/new.html.erb +1 -1
- data/config/locales/en.yml +11 -2
- data/devise.gemspec +25 -0
- data/lib/devise/controllers/helpers.rb +119 -116
- data/lib/devise/controllers/internal_helpers.rb +29 -8
- data/lib/devise/controllers/rememberable.rb +52 -0
- data/lib/devise/controllers/scoped_views.rb +4 -6
- data/lib/devise/controllers/url_helpers.rb +3 -5
- data/lib/devise/encryptors/authlogic_sha512.rb +1 -1
- data/lib/devise/encryptors/base.rb +1 -1
- data/lib/devise/encryptors/restful_authentication_sha1.rb +4 -4
- data/lib/devise/failure_app.rb +46 -10
- data/lib/devise/hooks/activatable.rb +2 -2
- data/lib/devise/hooks/forgetable.rb +1 -3
- data/lib/devise/hooks/rememberable.rb +5 -42
- data/lib/devise/hooks/timeoutable.rb +1 -1
- data/lib/devise/mapping.rb +18 -7
- data/lib/devise/models/authenticatable.rb +73 -31
- data/lib/devise/models/confirmable.rb +16 -20
- data/lib/devise/models/database_authenticatable.rb +27 -37
- data/lib/devise/models/encryptable.rb +72 -0
- data/lib/devise/models/lockable.rb +27 -21
- data/lib/devise/models/omniauthable.rb +23 -0
- data/lib/devise/models/recoverable.rb +13 -3
- data/lib/devise/models/registerable.rb +13 -0
- data/lib/devise/models/rememberable.rb +39 -34
- data/lib/devise/models/timeoutable.rb +20 -3
- data/lib/devise/models/token_authenticatable.rb +22 -10
- data/lib/devise/models/validatable.rb +16 -4
- data/lib/devise/models.rb +4 -16
- data/lib/devise/modules.rb +15 -8
- data/lib/devise/omniauth/config.rb +18 -0
- data/lib/devise/omniauth/url_helpers.rb +33 -0
- data/lib/devise/omniauth.rb +32 -0
- data/lib/devise/orm/active_record.rb +2 -0
- data/lib/devise/orm/mongoid.rb +4 -2
- data/lib/devise/rails/routes.rb +67 -20
- data/lib/devise/rails/warden_compat.rb +101 -15
- data/lib/devise/rails.rb +33 -44
- data/lib/devise/schema.rb +16 -16
- data/lib/devise/strategies/authenticatable.rb +48 -7
- data/lib/devise/strategies/database_authenticatable.rb +1 -1
- data/lib/devise/strategies/rememberable.rb +6 -5
- data/lib/devise/strategies/token_authenticatable.rb +6 -2
- data/lib/devise/test_helpers.rb +13 -3
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +162 -50
- data/lib/generators/active_record/devise_generator.rb +2 -2
- data/lib/generators/active_record/templates/migration.rb +2 -0
- data/lib/generators/devise/devise_generator.rb +3 -1
- data/lib/generators/devise/orm_helpers.rb +1 -1
- data/lib/generators/devise/views_generator.rb +8 -45
- data/lib/generators/mongoid/devise_generator.rb +2 -2
- data/lib/generators/templates/devise.rb +82 -39
- data/test/controllers/helpers_test.rb +78 -72
- data/test/controllers/internal_helpers_test.rb +29 -8
- data/test/controllers/url_helpers_test.rb +2 -1
- data/test/devise_test.rb +10 -0
- data/test/failure_app_test.rb +86 -22
- data/test/generators/active_record_generator_test.rb +24 -0
- data/test/generators/devise_generator_test.rb +33 -0
- data/test/generators/install_generator_test.rb +13 -0
- data/test/generators/mongoid_generator_test.rb +22 -0
- data/test/generators/views_generator_test.rb +35 -0
- data/test/indifferent_hash.rb +33 -0
- data/test/integration/authenticatable_test.rb +165 -62
- data/test/integration/database_authenticatable_test.rb +22 -0
- data/test/integration/http_authenticatable_test.rb +12 -2
- data/test/integration/omniauthable_test.rb +138 -0
- data/test/integration/recoverable_test.rb +39 -20
- data/test/integration/registerable_test.rb +60 -4
- data/test/integration/rememberable_test.rb +72 -29
- data/test/integration/timeoutable_test.rb +10 -1
- data/test/integration/token_authenticatable_test.rb +55 -6
- data/test/mailers/confirmation_instructions_test.rb +4 -0
- data/test/mailers/reset_password_instructions_test.rb +4 -0
- data/test/mailers/unlock_instructions_test.rb +4 -0
- data/test/mapping_test.rb +37 -3
- data/test/models/confirmable_test.rb +32 -15
- data/test/models/database_authenticatable_test.rb +14 -71
- data/test/models/encryptable_test.rb +65 -0
- data/test/models/lockable_test.rb +48 -11
- data/test/models/recoverable_test.rb +28 -2
- data/test/models/rememberable_test.rb +186 -125
- data/test/models/token_authenticatable_test.rb +19 -1
- data/test/models_test.rb +12 -5
- data/test/omniauth/url_helpers_test.rb +54 -0
- data/test/orm/mongoid.rb +3 -2
- data/test/rails_app/Rakefile +10 -0
- data/test/rails_app/app/active_record/admin.rb +4 -1
- data/test/rails_app/app/active_record/user.rb +5 -4
- data/test/rails_app/app/controllers/{sessions_controller.rb → admins/sessions_controller.rb} +1 -1
- data/test/rails_app/app/controllers/application_controller.rb +0 -1
- data/test/rails_app/app/controllers/home_controller.rb +9 -0
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
- data/test/rails_app/app/mongoid/admin.rb +4 -1
- data/test/rails_app/app/mongoid/shim.rb +16 -3
- data/test/rails_app/app/mongoid/user.rb +5 -5
- data/test/rails_app/app/views/admins/index.html.erb +1 -0
- data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
- data/test/rails_app/app/views/home/index.html.erb +1 -0
- data/test/rails_app/app/views/home/private.html.erb +1 -0
- data/test/rails_app/app/views/layouts/application.html.erb +24 -0
- data/test/rails_app/app/views/users/index.html.erb +1 -0
- data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
- data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
- data/test/rails_app/config/application.rb +5 -0
- data/test/rails_app/config/boot.rb +2 -2
- data/test/rails_app/config/database.yml +18 -0
- data/test/rails_app/config/initializers/devise.rb +71 -31
- data/test/rails_app/config/routes.rb +14 -6
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +21 -17
- data/test/rails_app/db/schema.rb +17 -51
- data/test/rails_app/lib/shared_admin.rb +9 -0
- data/test/rails_app/lib/shared_user.rb +23 -0
- data/test/rails_app/public/404.html +26 -0
- data/test/rails_app/public/422.html +26 -0
- data/test/rails_app/public/500.html +26 -0
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_app/script/rails +10 -0
- data/test/routes_test.rb +42 -9
- data/test/schema_test.rb +33 -0
- data/test/support/integration.rb +4 -4
- data/test/support/locale/en.yml +4 -0
- data/test/support/webrat/integrations/rails.rb +11 -19
- data/test/test_helper.rb +8 -2
- data/test/test_helpers_test.rb +64 -2
- metadata +106 -30
- data/TODO +0 -3
- data/lib/devise/encryptors/bcrypt.rb +0 -19
- data/lib/generators/devise_install_generator.rb +0 -4
- data/lib/generators/devise_views_generator.rb +0 -4
- data/test/support/test_silencer.rb +0 -5
|
@@ -9,7 +9,7 @@ module Devise
|
|
|
9
9
|
attr_accessor :authentication_hash, :password
|
|
10
10
|
|
|
11
11
|
def valid?
|
|
12
|
-
|
|
12
|
+
valid_for_params_auth? || valid_for_http_auth?
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
private
|
|
@@ -19,13 +19,27 @@ module Devise
|
|
|
19
19
|
result = resource && resource.valid_for_authentication?(&block)
|
|
20
20
|
|
|
21
21
|
case result
|
|
22
|
-
when
|
|
22
|
+
when String, Symbol
|
|
23
23
|
fail!(result)
|
|
24
|
+
false
|
|
25
|
+
when TrueClass
|
|
26
|
+
decorate(resource)
|
|
27
|
+
true
|
|
24
28
|
else
|
|
25
29
|
result
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
|
|
33
|
+
# Get values from params and set in the resource.
|
|
34
|
+
def decorate(resource)
|
|
35
|
+
resource.remember_me = remember_me? if resource.respond_to?(:remember_me=)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Should this resource be marked to be remembered?
|
|
39
|
+
def remember_me?
|
|
40
|
+
valid_params? && Devise::TRUE_VALUES.include?(params_auth_hash[:remember_me])
|
|
41
|
+
end
|
|
42
|
+
|
|
29
43
|
# Check if this is strategy is valid for http authentication by:
|
|
30
44
|
#
|
|
31
45
|
# * Validating if the model allows params authentication;
|
|
@@ -96,15 +110,17 @@ module Devise
|
|
|
96
110
|
|
|
97
111
|
# Helper to decode credentials from HTTP.
|
|
98
112
|
def decode_credentials
|
|
99
|
-
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/
|
|
113
|
+
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/m
|
|
100
114
|
ActiveSupport::Base64.decode64($1).split(/:/, 2)
|
|
101
115
|
end
|
|
102
116
|
|
|
103
117
|
# Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
|
|
104
|
-
def with_authentication_hash(
|
|
105
|
-
self.authentication_hash =
|
|
106
|
-
self.password =
|
|
107
|
-
|
|
118
|
+
def with_authentication_hash(auth_values)
|
|
119
|
+
self.authentication_hash = {}
|
|
120
|
+
self.password = auth_values[:password]
|
|
121
|
+
|
|
122
|
+
parse_authentication_key_values(auth_values, authentication_keys) &&
|
|
123
|
+
parse_authentication_key_values(request_values, request_keys)
|
|
108
124
|
end
|
|
109
125
|
|
|
110
126
|
# Holds the authentication keys.
|
|
@@ -112,6 +128,31 @@ module Devise
|
|
|
112
128
|
@authentication_keys ||= mapping.to.authentication_keys
|
|
113
129
|
end
|
|
114
130
|
|
|
131
|
+
# Holds request keys.
|
|
132
|
+
def request_keys
|
|
133
|
+
@request_keys ||= mapping.to.request_keys
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns values from the request object.
|
|
137
|
+
def request_values
|
|
138
|
+
keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
|
|
139
|
+
values = keys.map { |k| self.request.send(k) }
|
|
140
|
+
Hash[keys.zip(values)]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Parse authentication keys considering if they should be enforced or not.
|
|
144
|
+
def parse_authentication_key_values(hash, keys)
|
|
145
|
+
keys.each do |key, enforce|
|
|
146
|
+
value = hash[key].presence
|
|
147
|
+
if value
|
|
148
|
+
self.authentication_hash[key] = value
|
|
149
|
+
else
|
|
150
|
+
return false unless enforce == false
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
true
|
|
154
|
+
end
|
|
155
|
+
|
|
115
156
|
# Holds the authenticatable name for this class. Devise::Strategies::DatabaseAuthenticatable
|
|
116
157
|
# becomes simply :database.
|
|
117
158
|
def authenticatable_name
|
|
@@ -20,7 +20,7 @@ module Devise
|
|
|
20
20
|
|
|
21
21
|
if validate(resource)
|
|
22
22
|
success!(resource)
|
|
23
|
-
|
|
23
|
+
elsif !halted?
|
|
24
24
|
cookies.delete(remember_key)
|
|
25
25
|
pass
|
|
26
26
|
end
|
|
@@ -28,6 +28,11 @@ module Devise
|
|
|
28
28
|
|
|
29
29
|
private
|
|
30
30
|
|
|
31
|
+
def decorate(resource)
|
|
32
|
+
super
|
|
33
|
+
resource.extend_remember_period = mapping.to.extend_remember_period if resource.respond_to?(:extend_remember_period=)
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
def remember_me?
|
|
32
37
|
true
|
|
33
38
|
end
|
|
@@ -36,10 +41,6 @@ module Devise
|
|
|
36
41
|
"remember_#{scope}_token"
|
|
37
42
|
end
|
|
38
43
|
|
|
39
|
-
def extend_remember_period?
|
|
40
|
-
mapping.to.extend_remember_period
|
|
41
|
-
end
|
|
42
|
-
|
|
43
44
|
# Accessor for remember cookie
|
|
44
45
|
def remember_cookie
|
|
45
46
|
@remember_cookie ||= cookies.signed[remember_key]
|
|
@@ -10,13 +10,17 @@ module Devise
|
|
|
10
10
|
# For HTTP, you can pass the token as username and blank password. Since some clients may require
|
|
11
11
|
# a password, you can pass "X" as password and it will simply be ignored.
|
|
12
12
|
class TokenAuthenticatable < Authenticatable
|
|
13
|
+
def store?
|
|
14
|
+
!mapping.to.stateless_token
|
|
15
|
+
end
|
|
16
|
+
|
|
13
17
|
def authenticate!
|
|
14
18
|
resource = mapping.to.find_for_token_authentication(authentication_hash)
|
|
15
19
|
|
|
16
20
|
if validate(resource)
|
|
17
21
|
resource.after_token_authentication
|
|
18
22
|
success!(resource)
|
|
19
|
-
|
|
23
|
+
elsif !halted?
|
|
20
24
|
fail(:invalid_token)
|
|
21
25
|
end
|
|
22
26
|
end
|
|
@@ -28,7 +32,7 @@ module Devise
|
|
|
28
32
|
true
|
|
29
33
|
end
|
|
30
34
|
|
|
31
|
-
# Do not use remember_me
|
|
35
|
+
# Do not use remember_me behavior with token.
|
|
32
36
|
def remember_me?
|
|
33
37
|
false
|
|
34
38
|
end
|
data/lib/devise/test_helpers.rb
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
module Devise
|
|
2
|
+
# Devise::TestHelpers provides a facility to test controllers in isolation
|
|
3
|
+
# when using ActionController::TestCase allowing you to quickly sign_in or
|
|
4
|
+
# sign_out a user. Do not use Devise::TestHelpers in integration tests.
|
|
5
|
+
#
|
|
6
|
+
# Notice you should not test Warden specific behavior (like Warden callbacks)
|
|
7
|
+
# using Devise::TestHelpers since it is a stub of the actual behavior. Such
|
|
8
|
+
# callbacks should be tested in your integration suite instead.
|
|
2
9
|
module TestHelpers
|
|
3
10
|
def self.included(base)
|
|
4
11
|
base.class_eval do
|
|
@@ -37,9 +44,9 @@ module Devise
|
|
|
37
44
|
env = @controller.request.env
|
|
38
45
|
env["PATH_INFO"] = "/#{result[:action]}"
|
|
39
46
|
env["warden.options"] = result
|
|
40
|
-
Warden::Manager.
|
|
47
|
+
Warden::Manager._run_callbacks(:before_failure, env, result)
|
|
41
48
|
|
|
42
|
-
status, headers, body = Devise
|
|
49
|
+
status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
|
|
43
50
|
@controller.send :render, :status => status, :text => body,
|
|
44
51
|
:content_type => headers["Content-Type"], :location => headers["Location"]
|
|
45
52
|
|
|
@@ -61,6 +68,7 @@ module Devise
|
|
|
61
68
|
end
|
|
62
69
|
|
|
63
70
|
# sign_in a given resource by storing its keys in the session.
|
|
71
|
+
# This method bypass any warden authentication callback.
|
|
64
72
|
#
|
|
65
73
|
# Examples:
|
|
66
74
|
#
|
|
@@ -74,6 +82,7 @@ module Devise
|
|
|
74
82
|
end
|
|
75
83
|
|
|
76
84
|
# Sign out a given resource or scope by calling logout on Warden.
|
|
85
|
+
# This method bypass any warden logout callback.
|
|
77
86
|
#
|
|
78
87
|
# Examples:
|
|
79
88
|
#
|
|
@@ -83,7 +92,8 @@ module Devise
|
|
|
83
92
|
def sign_out(resource_or_scope)
|
|
84
93
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
85
94
|
@controller.instance_variable_set(:"@current_#{scope}", nil)
|
|
86
|
-
warden.
|
|
95
|
+
user = warden.instance_variable_get(:@users).delete(scope)
|
|
96
|
+
warden.session_serializer.delete(scope, user)
|
|
87
97
|
end
|
|
88
98
|
|
|
89
99
|
end
|
data/lib/devise/version.rb
CHANGED
data/lib/devise.rb
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
require 'rails'
|
|
1
2
|
require 'active_support/core_ext/numeric/time'
|
|
2
3
|
require 'active_support/dependencies'
|
|
4
|
+
require 'orm_adapter'
|
|
5
|
+
require 'set'
|
|
3
6
|
|
|
4
7
|
module Devise
|
|
5
8
|
autoload :FailureApp, 'devise/failure_app'
|
|
9
|
+
autoload :OmniAuth, 'devise/omniauth'
|
|
6
10
|
autoload :PathChecker, 'devise/path_checker'
|
|
7
11
|
autoload :Schema, 'devise/schema'
|
|
8
12
|
autoload :TestHelpers, 'devise/test_helpers'
|
|
@@ -10,13 +14,13 @@ module Devise
|
|
|
10
14
|
module Controllers
|
|
11
15
|
autoload :Helpers, 'devise/controllers/helpers'
|
|
12
16
|
autoload :InternalHelpers, 'devise/controllers/internal_helpers'
|
|
17
|
+
autoload :Rememberable, 'devise/controllers/rememberable'
|
|
13
18
|
autoload :ScopedViews, 'devise/controllers/scoped_views'
|
|
14
19
|
autoload :UrlHelpers, 'devise/controllers/url_helpers'
|
|
15
20
|
end
|
|
16
21
|
|
|
17
22
|
module Encryptors
|
|
18
23
|
autoload :Base, 'devise/encryptors/base'
|
|
19
|
-
autoload :Bcrypt, 'devise/encryptors/bcrypt'
|
|
20
24
|
autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512'
|
|
21
25
|
autoload :ClearanceSha1, 'devise/encryptors/clearance_sha1'
|
|
22
26
|
autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1'
|
|
@@ -30,11 +34,12 @@ module Devise
|
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
# Constants which holds devise configuration for extensions. Those should
|
|
33
|
-
# not be modified by the "end user".
|
|
37
|
+
# not be modified by the "end user" (this is why they are constants).
|
|
34
38
|
ALL = []
|
|
35
39
|
CONTROLLERS = ActiveSupport::OrderedHash.new
|
|
36
40
|
ROUTES = ActiveSupport::OrderedHash.new
|
|
37
41
|
STRATEGIES = ActiveSupport::OrderedHash.new
|
|
42
|
+
URL_HELPERS = ActiveSupport::OrderedHash.new
|
|
38
43
|
|
|
39
44
|
# True values used to check params
|
|
40
45
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
|
@@ -45,31 +50,35 @@ module Devise
|
|
|
45
50
|
:sha512 => 128,
|
|
46
51
|
:clearance_sha1 => 40,
|
|
47
52
|
:restful_authentication_sha1 => 40,
|
|
48
|
-
:authlogic_sha512 => 128
|
|
49
|
-
:bcrypt => 60
|
|
53
|
+
:authlogic_sha512 => 128
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
# Custom domain for cookies. Not set by default
|
|
53
|
-
mattr_accessor :
|
|
54
|
-
@@
|
|
55
|
-
|
|
56
|
-
# Used to encrypt password. Please generate one with rake secret.
|
|
57
|
-
mattr_accessor :pepper
|
|
58
|
-
@@pepper = nil
|
|
57
|
+
mattr_accessor :cookie_options
|
|
58
|
+
@@cookie_options = {}
|
|
59
59
|
|
|
60
60
|
# The number of times to encrypt password.
|
|
61
61
|
mattr_accessor :stretches
|
|
62
62
|
@@stretches = 10
|
|
63
63
|
|
|
64
|
-
# Keys used when authenticating
|
|
64
|
+
# Keys used when authenticating a user.
|
|
65
65
|
mattr_accessor :authentication_keys
|
|
66
66
|
@@authentication_keys = [ :email ]
|
|
67
67
|
|
|
68
|
+
# Request keys used when authenticating a user.
|
|
69
|
+
mattr_accessor :request_keys
|
|
70
|
+
@@request_keys = []
|
|
71
|
+
|
|
72
|
+
# Keys that should be case-insensitive.
|
|
73
|
+
# False by default for backwards compatibility.
|
|
74
|
+
mattr_accessor :case_insensitive_keys
|
|
75
|
+
@@case_insensitive_keys = false
|
|
76
|
+
|
|
68
77
|
# If http authentication is enabled by default.
|
|
69
78
|
mattr_accessor :http_authenticatable
|
|
70
|
-
@@http_authenticatable =
|
|
79
|
+
@@http_authenticatable = false
|
|
71
80
|
|
|
72
|
-
# If http
|
|
81
|
+
# If http headers should be returned for ajax requests. True by default.
|
|
73
82
|
mattr_accessor :http_authenticatable_on_xhr
|
|
74
83
|
@@http_authenticatable_on_xhr = true
|
|
75
84
|
|
|
@@ -83,7 +92,7 @@ module Devise
|
|
|
83
92
|
|
|
84
93
|
# Email regex used to validate email formats. Adapted from authlogic.
|
|
85
94
|
mattr_accessor :email_regexp
|
|
86
|
-
@@email_regexp =
|
|
95
|
+
@@email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
|
|
87
96
|
|
|
88
97
|
# Range validation for password length
|
|
89
98
|
mattr_accessor :password_length
|
|
@@ -101,22 +110,31 @@ module Devise
|
|
|
101
110
|
mattr_accessor :extend_remember_period
|
|
102
111
|
@@extend_remember_period = false
|
|
103
112
|
|
|
113
|
+
# If true, uses salt as remember token and does not create it in the database.
|
|
114
|
+
# By default is false for backwards compatibility.
|
|
115
|
+
mattr_accessor :use_salt_as_remember_token
|
|
116
|
+
@@use_salt_as_remember_token = false
|
|
117
|
+
|
|
104
118
|
# Time interval you can access your account before confirming your account.
|
|
105
119
|
mattr_accessor :confirm_within
|
|
106
120
|
@@confirm_within = 0.days
|
|
107
121
|
|
|
122
|
+
# Defines which key will be used when confirming an account
|
|
123
|
+
mattr_accessor :confirmation_keys
|
|
124
|
+
@@confirmation_keys = [ :email ]
|
|
125
|
+
|
|
108
126
|
# Time interval to timeout the user session without activity.
|
|
109
127
|
mattr_accessor :timeout_in
|
|
110
128
|
@@timeout_in = 30.minutes
|
|
111
129
|
|
|
130
|
+
# Used to encrypt password. Please generate one with rake secret.
|
|
131
|
+
mattr_accessor :pepper
|
|
132
|
+
@@pepper = nil
|
|
133
|
+
|
|
112
134
|
# Used to define the password encryption algorithm.
|
|
113
135
|
mattr_accessor :encryptor
|
|
114
136
|
@@encryptor = nil
|
|
115
137
|
|
|
116
|
-
# Store scopes mappings.
|
|
117
|
-
mattr_accessor :mappings
|
|
118
|
-
@@mappings = ActiveSupport::OrderedHash.new
|
|
119
|
-
|
|
120
138
|
# Tells if devise should apply the schema in ORMs where devise declaration
|
|
121
139
|
# and schema belongs to the same class (as Datamapper and Mongoid).
|
|
122
140
|
mattr_accessor :apply_schema
|
|
@@ -132,6 +150,10 @@ module Devise
|
|
|
132
150
|
mattr_accessor :lock_strategy
|
|
133
151
|
@@lock_strategy = :failed_attempts
|
|
134
152
|
|
|
153
|
+
# Defines which key will be used when locking and unlocking an account
|
|
154
|
+
mattr_accessor :unlock_keys
|
|
155
|
+
@@unlock_keys = [ :email ]
|
|
156
|
+
|
|
135
157
|
# Defines which strategy can be used to unlock an account.
|
|
136
158
|
# Values: :email, :time, :both
|
|
137
159
|
mattr_accessor :unlock_strategy
|
|
@@ -145,6 +167,10 @@ module Devise
|
|
|
145
167
|
mattr_accessor :unlock_in
|
|
146
168
|
@@unlock_in = 1.hour
|
|
147
169
|
|
|
170
|
+
# Defines which key will be used when recovering the password for an account
|
|
171
|
+
mattr_accessor :reset_password_keys
|
|
172
|
+
@@reset_password_keys = [ :email ]
|
|
173
|
+
|
|
148
174
|
# The default scope which is used by warden.
|
|
149
175
|
mattr_accessor :default_scope
|
|
150
176
|
@@default_scope = nil
|
|
@@ -157,59 +183,98 @@ module Devise
|
|
|
157
183
|
mattr_accessor :token_authentication_key
|
|
158
184
|
@@token_authentication_key = :auth_token
|
|
159
185
|
|
|
186
|
+
# If true, authentication through token does not store user in session
|
|
187
|
+
mattr_accessor :stateless_token
|
|
188
|
+
@@stateless_token = false
|
|
189
|
+
|
|
160
190
|
# Which formats should be treated as navigational.
|
|
191
|
+
# We need both :"*/*" and "*/*" to work on different Rails versions.
|
|
161
192
|
mattr_accessor :navigational_formats
|
|
162
|
-
@@navigational_formats = [:html]
|
|
193
|
+
@@navigational_formats = [:"*/*", "*/*", :html]
|
|
194
|
+
|
|
195
|
+
# When set to true, signing out a user signs out all other scopes.
|
|
196
|
+
mattr_accessor :sign_out_all_scopes
|
|
197
|
+
@@sign_out_all_scopes = true
|
|
198
|
+
|
|
199
|
+
# The default method used while signing out
|
|
200
|
+
mattr_accessor :sign_out_via
|
|
201
|
+
@@sign_out_via = :get
|
|
202
|
+
|
|
203
|
+
# PRIVATE CONFIGURATION
|
|
204
|
+
|
|
205
|
+
# Store scopes mappings.
|
|
206
|
+
mattr_reader :mappings
|
|
207
|
+
@@mappings = ActiveSupport::OrderedHash.new
|
|
208
|
+
|
|
209
|
+
# Omniauth configurations.
|
|
210
|
+
mattr_reader :omniauth_configs
|
|
211
|
+
@@omniauth_configs = ActiveSupport::OrderedHash.new
|
|
212
|
+
|
|
213
|
+
# Define a set of modules that are called when a mapping is added.
|
|
214
|
+
mattr_reader :helpers
|
|
215
|
+
@@helpers = Set.new
|
|
216
|
+
@@helpers << Devise::Controllers::Helpers
|
|
163
217
|
|
|
164
218
|
# Private methods to interface with Warden.
|
|
165
219
|
mattr_accessor :warden_config
|
|
166
220
|
@@warden_config = nil
|
|
167
221
|
@@warden_config_block = nil
|
|
168
222
|
|
|
169
|
-
# When set to true, signing out an user signs out all other scopes.
|
|
170
|
-
mattr_accessor :sign_out_all_scopes
|
|
171
|
-
@@sign_out_all_scopes = false
|
|
172
|
-
|
|
173
|
-
def self.use_default_scope=(*)
|
|
174
|
-
ActiveSupport::Deprecation.warn "config.use_default_scope is deprecated and removed from Devise. " <<
|
|
175
|
-
"If you are using non conventional routes in Devise, all you need to do is to pass the devise " <<
|
|
176
|
-
"scope in the router DSL:\n\n as :user do\n get \"sign_in\", :to => \"devise/sessions\"\n end\n\n" <<
|
|
177
|
-
"The method :as is also aliased to :devise_scope. Choose the one you prefer.", caller
|
|
178
|
-
end
|
|
179
|
-
|
|
180
223
|
# Default way to setup Devise. Run rails generate devise_install to create
|
|
181
224
|
# a fresh initializer with all configuration values.
|
|
182
225
|
def self.setup
|
|
183
226
|
yield self
|
|
184
227
|
end
|
|
185
228
|
|
|
229
|
+
def self.ref(arg)
|
|
230
|
+
if defined?(ActiveSupport::Dependencies::ClassCache)
|
|
231
|
+
ActiveSupport::Dependencies::Reference.store(arg)
|
|
232
|
+
else
|
|
233
|
+
ActiveSupport::Dependencies.ref(arg)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def self.omniauth_providers
|
|
238
|
+
omniauth_configs.keys
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def self.cookie_domain=(value)
|
|
242
|
+
ActiveSupport::Deprecation.warn "Devise.cookie_domain=(value) is deprecated. "
|
|
243
|
+
"Please use Devise.cookie_options = { :domain => value } instead."
|
|
244
|
+
self.cookie_options[:domain] = value
|
|
245
|
+
end
|
|
246
|
+
|
|
186
247
|
# Get the mailer class from the mailer reference object.
|
|
187
248
|
def self.mailer
|
|
188
|
-
|
|
249
|
+
if defined?(ActiveSupport::Dependencies::ClassCache)
|
|
250
|
+
@@mailer_ref.get "Devise::Mailer"
|
|
251
|
+
else
|
|
252
|
+
@@mailer_ref.get
|
|
253
|
+
end
|
|
189
254
|
end
|
|
190
255
|
|
|
191
256
|
# Set the mailer reference object to access the mailer.
|
|
192
257
|
def self.mailer=(class_name)
|
|
193
|
-
@@mailer_ref =
|
|
258
|
+
@@mailer_ref = ref(class_name)
|
|
194
259
|
end
|
|
195
260
|
self.mailer = "Devise::Mailer"
|
|
196
261
|
|
|
197
262
|
# Small method that adds a mapping to Devise.
|
|
198
263
|
def self.add_mapping(resource, options)
|
|
199
264
|
mapping = Devise::Mapping.new(resource, options)
|
|
200
|
-
|
|
201
|
-
|
|
265
|
+
@@mappings[mapping.name] = mapping
|
|
266
|
+
@@default_scope ||= mapping.name
|
|
267
|
+
@@helpers.each { |h| h.define_helpers(mapping) }
|
|
202
268
|
mapping
|
|
203
269
|
end
|
|
204
270
|
|
|
205
|
-
# Make Devise aware of an 3rd party Devise-module. For convenience.
|
|
271
|
+
# Make Devise aware of an 3rd party Devise-module (like invitable). For convenience.
|
|
206
272
|
#
|
|
207
273
|
# == Options:
|
|
208
274
|
#
|
|
209
275
|
# +model+ - String representing the load path to a custom *model* for this module (to autoload.)
|
|
210
276
|
# +controller+ - Symbol representing the name of an exisiting or custom *controller* for this module.
|
|
211
277
|
# +route+ - Symbol representing the named *route* helper for this module.
|
|
212
|
-
# +flash+ - Symbol representing the *flash messages* used by this helper.
|
|
213
278
|
# +strategy+ - Symbol representing if this module got a custom *strategy*.
|
|
214
279
|
#
|
|
215
280
|
# All values, except :model, accept also a boolean and will have the same name as the given module
|
|
@@ -225,26 +290,36 @@ module Devise
|
|
|
225
290
|
ALL << module_name
|
|
226
291
|
options.assert_valid_keys(:strategy, :model, :controller, :route)
|
|
227
292
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
:controller => CONTROLLERS
|
|
232
|
-
}
|
|
293
|
+
if strategy = options[:strategy]
|
|
294
|
+
STRATEGIES[module_name] = (strategy == true ? module_name : strategy)
|
|
295
|
+
end
|
|
233
296
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
297
|
+
if controller = options[:controller]
|
|
298
|
+
CONTROLLERS[module_name] = (controller == true ? module_name : controller)
|
|
299
|
+
end
|
|
237
300
|
|
|
238
|
-
|
|
239
|
-
|
|
301
|
+
if route = options[:route]
|
|
302
|
+
case route
|
|
303
|
+
when TrueClass
|
|
304
|
+
key, value = module_name, []
|
|
305
|
+
when Symbol
|
|
306
|
+
key, value = route, []
|
|
307
|
+
when Hash
|
|
308
|
+
key, value = route.keys.first, route.values.flatten
|
|
240
309
|
else
|
|
241
|
-
|
|
310
|
+
raise ArgumentError, ":route should be true, a Symbol or a Hash"
|
|
242
311
|
end
|
|
312
|
+
|
|
313
|
+
URL_HELPERS[key] ||= []
|
|
314
|
+
URL_HELPERS[key].concat(value)
|
|
315
|
+
URL_HELPERS[key].uniq!
|
|
316
|
+
|
|
317
|
+
ROUTES[module_name] = key
|
|
243
318
|
end
|
|
244
319
|
|
|
245
320
|
if options[:model]
|
|
246
|
-
|
|
247
|
-
Devise::Models.send(:autoload, module_name.to_s.camelize.to_sym,
|
|
321
|
+
path = (options[:model] == true ? "devise/models/#{module_name}" : options[:model])
|
|
322
|
+
Devise::Models.send(:autoload, module_name.to_s.camelize.to_sym, path)
|
|
248
323
|
end
|
|
249
324
|
|
|
250
325
|
Devise::Mapping.add_module module_name
|
|
@@ -265,12 +340,39 @@ module Devise
|
|
|
265
340
|
@@warden_config_block = block
|
|
266
341
|
end
|
|
267
342
|
|
|
343
|
+
# Specify an omniauth provider.
|
|
344
|
+
#
|
|
345
|
+
# config.omniauth :github, APP_ID, APP_SECRET
|
|
346
|
+
#
|
|
347
|
+
def self.omniauth(provider, *args)
|
|
348
|
+
@@helpers << Devise::OmniAuth::UrlHelpers
|
|
349
|
+
@@omniauth_configs[provider] = Devise::OmniAuth::Config.new(provider, args)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# Include helpers in the given scope to AC and AV.
|
|
353
|
+
def self.include_helpers(scope)
|
|
354
|
+
ActiveSupport.on_load(:action_controller) do
|
|
355
|
+
include scope::Helpers if defined?(scope::Helpers)
|
|
356
|
+
include scope::UrlHelpers
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
ActiveSupport.on_load(:action_view) do
|
|
360
|
+
include scope::UrlHelpers
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# Returns true if Rails version is bigger than 3.0.x
|
|
365
|
+
def self.rack_session?
|
|
366
|
+
Rails::VERSION::STRING[0,3] != "3.0"
|
|
367
|
+
end
|
|
368
|
+
|
|
268
369
|
# A method used internally to setup warden manager from the Rails initialize
|
|
269
370
|
# block.
|
|
270
371
|
def self.configure_warden! #:nodoc:
|
|
271
372
|
@@warden_configured ||= begin
|
|
272
373
|
warden_config.failure_app = Devise::FailureApp
|
|
273
374
|
warden_config.default_scope = Devise.default_scope
|
|
375
|
+
warden_config.intercept_401 = false
|
|
274
376
|
|
|
275
377
|
Devise.mappings.each_value do |mapping|
|
|
276
378
|
warden_config.scope_defaults mapping.name, :strategies => mapping.strategies
|
|
@@ -283,7 +385,17 @@ module Devise
|
|
|
283
385
|
|
|
284
386
|
# Generate a friendly string randomically to be used as token.
|
|
285
387
|
def self.friendly_token
|
|
286
|
-
ActiveSupport::SecureRandom.base64(15).tr('+/=', '
|
|
388
|
+
ActiveSupport::SecureRandom.base64(15).tr('+/=', 'xyz')
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# constant-time comparison algorithm to prevent timing attacks
|
|
392
|
+
def self.secure_compare(a, b)
|
|
393
|
+
return false if a.blank? || b.blank? || a.bytesize != b.bytesize
|
|
394
|
+
l = a.unpack "C#{a.bytesize}"
|
|
395
|
+
|
|
396
|
+
res = 0
|
|
397
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
|
398
|
+
res == 0
|
|
287
399
|
end
|
|
288
400
|
end
|
|
289
401
|
|
|
@@ -10,7 +10,7 @@ module ActiveRecord
|
|
|
10
10
|
source_root File.expand_path("../templates", __FILE__)
|
|
11
11
|
|
|
12
12
|
def generate_model
|
|
13
|
-
invoke "active_record:model", [name], :migration => false unless model_exists?
|
|
13
|
+
invoke "active_record:model", [name], :migration => false unless model_exists? && behavior == :invoke
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def copy_devise_migration
|
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def inject_devise_content
|
|
21
|
-
inject_into_class
|
|
21
|
+
inject_into_class(model_path, class_name, model_contents + <<CONTENT) if model_exists?
|
|
22
22
|
# Setup accessible (or protected) attributes for your model
|
|
23
23
|
attr_accessible :email, :password, :password_confirmation, :remember_me
|
|
24
24
|
CONTENT
|
|
@@ -6,6 +6,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
|
|
6
6
|
t.rememberable
|
|
7
7
|
t.trackable
|
|
8
8
|
|
|
9
|
+
# t.encryptable
|
|
9
10
|
# t.confirmable
|
|
10
11
|
# t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
|
|
11
12
|
# t.token_authenticatable
|
|
@@ -21,6 +22,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
|
|
21
22
|
add_index :<%= table_name %>, :reset_password_token, :unique => true
|
|
22
23
|
# add_index :<%= table_name %>, :confirmation_token, :unique => true
|
|
23
24
|
# add_index :<%= table_name %>, :unlock_token, :unique => true
|
|
25
|
+
# add_index :<%= table_name %>, :authentication_token, :unique => true
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def self.down
|
|
@@ -10,7 +10,9 @@ module Devise
|
|
|
10
10
|
hook_for :orm
|
|
11
11
|
|
|
12
12
|
def add_devise_routes
|
|
13
|
-
|
|
13
|
+
devise_route = "devise_for :#{plural_name}"
|
|
14
|
+
devise_route += %Q(, :class_name => "#{class_name}") if class_name.include?("::")
|
|
15
|
+
route devise_route
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
18
|
end
|
|
@@ -4,7 +4,7 @@ module Devise
|
|
|
4
4
|
def model_contents
|
|
5
5
|
<<-CONTENT
|
|
6
6
|
# Include default devise modules. Others available are:
|
|
7
|
-
# :token_authenticatable, :confirmable, :lockable and :
|
|
7
|
+
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
|
|
8
8
|
devise :database_authenticatable, :registerable,
|
|
9
9
|
:recoverable, :rememberable, :trackable, :validatable
|
|
10
10
|
|