devise 0.4.3 → 0.5.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 +10 -0
- data/README.rdoc +17 -1
- data/TODO +1 -3
- data/app/controllers/confirmations_controller.rb +1 -1
- data/app/controllers/passwords_controller.rb +1 -1
- data/generators/devise/templates/migration.rb +1 -1
- data/generators/devise_install/templates/devise.rb +10 -0
- data/lib/devise.rb +33 -4
- data/lib/devise/encryptors/authlogic_sha512.rb +28 -0
- data/lib/devise/encryptors/clearance_sha1.rb +26 -0
- data/lib/devise/encryptors/restful_authentication_sha1.rb +29 -0
- data/lib/devise/encryptors/sha1.rb +34 -0
- data/lib/devise/encryptors/sha512.rb +34 -0
- data/lib/devise/hooks/confirmable.rb +2 -2
- data/lib/devise/hooks/rememberable.rb +8 -6
- data/lib/devise/mapping.rb +7 -8
- data/lib/devise/middlewares/rememberable.rb +35 -0
- data/lib/devise/models.rb +3 -0
- data/lib/devise/models/authenticatable.rb +6 -16
- data/lib/devise/models/rememberable.rb +1 -1
- data/lib/devise/orm/active_record.rb +37 -0
- data/lib/devise/orm/mongo_mapper.rb +23 -0
- data/lib/devise/rails.rb +4 -4
- data/lib/devise/rails/routes.rb +8 -2
- data/lib/devise/rails/warden_compat.rb +7 -4
- data/lib/devise/schema.rb +43 -0
- data/lib/devise/version.rb +1 -1
- data/test/devise_test.rb +1 -1
- data/test/encryptors_test.rb +28 -0
- data/test/integration/rememberable_test.rb +1 -3
- data/test/mapping_test.rb +8 -0
- data/test/models/authenticatable_test.rb +18 -6
- data/test/rails_app/config/routes.rb +3 -1
- data/test/routes_test.rb +5 -2
- metadata +12 -4
- data/lib/devise/migrations.rb +0 -51
- data/lib/devise/strategies/rememberable.rb +0 -35
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.5.0
|
2
|
+
|
3
|
+
* bug fix
|
4
|
+
* Fixed a bug where remember me module was not working properly
|
5
|
+
|
6
|
+
* enhancements
|
7
|
+
* Moved encryption strategy into the Encryptors module to allow several algorithms (by github.com/mhfs)
|
8
|
+
* Implemented encryptors for Clearance, Authlogic and Restful-Authentication (by github.com/mhfs)
|
9
|
+
* Added support for MongoMapper (by github.com/shingara)
|
10
|
+
|
1
11
|
== 0.4.3
|
2
12
|
|
3
13
|
* bug fix
|
data/README.rdoc
CHANGED
@@ -27,7 +27,7 @@ All gems are on gemcutter, so you need to add gemcutter to your sources if you h
|
|
27
27
|
|
28
28
|
sudo gem sources -a http://gemcutter.org/
|
29
29
|
|
30
|
-
Install warden gem if you don't have it installed (requires 0.5.
|
30
|
+
Install warden gem if you don't have it installed (requires 0.5.2 or higher):
|
31
31
|
|
32
32
|
sudo gem install warden
|
33
33
|
|
@@ -228,10 +228,26 @@ Devise mailer uses the same pattern to create subject messages:
|
|
228
228
|
|
229
229
|
Take a look at our locale file to check all available messages.
|
230
230
|
|
231
|
+
== Migrating from other solutions
|
232
|
+
|
233
|
+
Devise implements encryption strategies for Clearance, Authlogic and Restful-Authentication. To make use of it set the desired encryptor in the encryptor initializer config option. You might also need to rename your encrypted password and salt columns to match Devises's one (encrypted_password and password_salt).
|
234
|
+
|
235
|
+
== Other ORMs
|
236
|
+
|
237
|
+
Devise was made to work from scratch with ActiveRecord. However it currently supports MongoMapper as well.
|
238
|
+
To use it, just set Devise.orm or configure it in the initialization file (which is created with devise_install).
|
239
|
+
|
231
240
|
== TODO
|
232
241
|
|
233
242
|
Please refer to TODO file.
|
234
243
|
|
244
|
+
== Contributors
|
245
|
+
|
246
|
+
* José Valim (http://github.com/josevalim)
|
247
|
+
* Carlos Antônio da Silva (http://github.com/carlosantoniodasilva)
|
248
|
+
* Marcelo Silveira (http://github.com/mhfs)
|
249
|
+
* Cyril Mougel (http://github.com/shingara)
|
250
|
+
|
235
251
|
== Bugs and Feedback
|
236
252
|
|
237
253
|
If you discover any bugs or want to drop a line, feel free to create an issue on
|
data/TODO
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
+
* Allow authentication keys to be configured, so things like username and subdomain can be used
|
1
2
|
* Devise::Timeoutable
|
2
3
|
* Devise::TestHelper
|
3
4
|
* Use request_ip in session cookies
|
4
5
|
* Devise::BruteForceProtection
|
5
6
|
* Devise::MagicColumns
|
6
|
-
* Improve Generators to pass modules as arguments
|
7
|
-
* Different cryptography providers
|
8
|
-
* Devise::Invitable
|
@@ -18,7 +18,7 @@ class ConfirmationsController < ApplicationController
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
# GET /resource/confirmation?
|
21
|
+
# GET /resource/confirmation?confirmation_token=abcdef
|
22
22
|
def show
|
23
23
|
self.resource = resource_class.confirm!(:confirmation_token => params[:confirmation_token])
|
24
24
|
|
@@ -20,7 +20,7 @@ class PasswordsController < ApplicationController
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
# GET /resource/password/edit?
|
23
|
+
# GET /resource/password/edit?reset_password_token=abcdef
|
24
24
|
def edit
|
25
25
|
self.resource = resource_class.new
|
26
26
|
resource.reset_password_token = params[:reset_password_token]
|
@@ -8,6 +8,13 @@ Devise.setup do |config|
|
|
8
8
|
# Configure how many times you want the password is reencrypted. Default is 10.
|
9
9
|
# config.stretches = 10
|
10
10
|
|
11
|
+
# Define which will be the encryption algorithm. Supported algorithms are :sha1
|
12
|
+
# (default) and :sha512. Devise also supports encryptors from others authentication
|
13
|
+
# frameworks as :clearance_sha1, :authlogic_sha512 (then you should set stretches
|
14
|
+
# above to 20 for default behavior) and :restful_authentication_sha1 (then you
|
15
|
+
# should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
16
|
+
# config.encryptor = :sha1
|
17
|
+
|
11
18
|
# The time you want give to your user to confirm his account. During this time
|
12
19
|
# he will be able to access your application without confirming. Default is nil.
|
13
20
|
# config.confirm_within = 2.days
|
@@ -18,6 +25,9 @@ Devise.setup do |config|
|
|
18
25
|
# Configure the e-mail address which will be shown in DeviseMailer.
|
19
26
|
# config.mailer_sender = "foo.bar@yourapp.com"
|
20
27
|
|
28
|
+
# Configure the ORM. Supports :active_record and :mongo_mapper
|
29
|
+
# config.orm = :active_record
|
30
|
+
|
21
31
|
# If you want to use other strategies, that are not (yet) supported by Devise,
|
22
32
|
# you can configure them inside the config.warden block. The example below
|
23
33
|
# allows you to setup OAuth, using http://github.com/roman/warden_oauth
|
data/lib/devise.rb
CHANGED
@@ -8,7 +8,7 @@ module Devise
|
|
8
8
|
:confirmations => :confirmable
|
9
9
|
}.freeze
|
10
10
|
|
11
|
-
STRATEGIES = [:
|
11
|
+
STRATEGIES = [:authenticatable].freeze
|
12
12
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
13
13
|
|
14
14
|
# Maps the messages types that comes from warden to a flash type.
|
@@ -18,26 +18,50 @@ module Devise
|
|
18
18
|
:unconfirmed => :failure
|
19
19
|
}
|
20
20
|
|
21
|
+
# Declare encryptors length which are used in migrations.
|
22
|
+
ENCRYPTORS_LENGTH = {
|
23
|
+
:sha1 => 40,
|
24
|
+
:sha512 => 128,
|
25
|
+
:clearance_sha1 => 40,
|
26
|
+
:restful_authentication_sha1 => 40,
|
27
|
+
:authlogic_sha512 => 128
|
28
|
+
}
|
29
|
+
|
21
30
|
# Used to encrypt password. Please generate one with rake secret
|
22
31
|
mattr_accessor :pepper
|
23
32
|
@@pepper = nil
|
24
|
-
|
33
|
+
|
25
34
|
# The number of times to encrypt password.
|
26
35
|
mattr_accessor :stretches
|
27
36
|
@@stretches = 10
|
28
|
-
|
37
|
+
|
29
38
|
# Time interval where the remember me token is valid.
|
30
39
|
mattr_accessor :remember_for
|
31
40
|
@@remember_for = 2.weeks
|
32
|
-
|
41
|
+
|
33
42
|
# Time interval you can access your account before confirming your account.
|
34
43
|
mattr_accessor :confirm_within
|
35
44
|
@@confirm_within = 0.days
|
36
45
|
|
46
|
+
# Used to define the password encryption algorithm.
|
47
|
+
def self.encryptor=(value)
|
48
|
+
@@encryptor = if value.is_a?(Symbol)
|
49
|
+
::Devise::Encryptors.const_get(value.to_s.classify)
|
50
|
+
else
|
51
|
+
value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
mattr_reader :encryptor
|
55
|
+
@@encryptor = ::Devise::Encryptors::Sha1
|
56
|
+
|
37
57
|
# Store scopes mappings.
|
38
58
|
mattr_accessor :mappings
|
39
59
|
@@mappings = {}
|
40
60
|
|
61
|
+
# Stores the chosen ORM.
|
62
|
+
mattr_accessor :orm
|
63
|
+
@@orm = :active_record
|
64
|
+
|
41
65
|
class << self
|
42
66
|
# Default way to setup Devise. Run script/generate devise_install to create
|
43
67
|
# a fresh initializer with all configuration values.
|
@@ -86,6 +110,11 @@ module Devise
|
|
86
110
|
# If the user provided a warden hook, call it now.
|
87
111
|
@warden_config.try :call, manager
|
88
112
|
end
|
113
|
+
|
114
|
+
# The class of the configured ORM
|
115
|
+
def orm_class
|
116
|
+
Devise::Orm.const_get(@@orm.to_s.camelize.to_sym)
|
117
|
+
end
|
89
118
|
end
|
90
119
|
end
|
91
120
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "digest/sha2"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
# Implements a way of adding different encryptions.
|
5
|
+
# The class should implement a self.digest method that taks the following params:
|
6
|
+
# - password
|
7
|
+
# - stretches: the number of times the encryption will be applied
|
8
|
+
# - salt: the password salt as defined by devise
|
9
|
+
# - pepper: Devise config option
|
10
|
+
#
|
11
|
+
module Encryptors
|
12
|
+
# = AuthlogicSha512
|
13
|
+
# Simulates Authlogic's default encryption mechanism.
|
14
|
+
# Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to silumate
|
15
|
+
# the default behavior.
|
16
|
+
class AuthlogicSha512
|
17
|
+
|
18
|
+
# Gererates a default password digest based on salt, pepper and the
|
19
|
+
# incoming password.
|
20
|
+
def self.digest(password, stretches, salt, pepper)
|
21
|
+
digest = [password, salt].flatten.join('')
|
22
|
+
stretches.times { digest = Digest::SHA512.hexdigest(digest) }
|
23
|
+
digest
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
# Implements a way of adding different encryptions.
|
5
|
+
# The class should implement a self.digest method that taks the following params:
|
6
|
+
# - password
|
7
|
+
# - stretches: the number of times the encryption will be applied
|
8
|
+
# - salt: the password salt as defined by devise
|
9
|
+
# - pepper: Devise config option
|
10
|
+
#
|
11
|
+
module Encryptors
|
12
|
+
# = ClearanceSha1
|
13
|
+
# Simulates Clearance's default encryption mechanism.
|
14
|
+
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
|
15
|
+
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES
|
16
|
+
class ClearanceSha1
|
17
|
+
|
18
|
+
# Gererates a default password digest based on salt, pepper and the
|
19
|
+
# incoming password.
|
20
|
+
def self.digest(password, stretches, salt, pepper)
|
21
|
+
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
# Implements a way of adding different encryptions.
|
5
|
+
# The class should implement a self.digest method that taks the following params:
|
6
|
+
# - password
|
7
|
+
# - stretches: the number of times the encryption will be applied
|
8
|
+
# - salt: the password salt as defined by devise
|
9
|
+
# - pepper: Devise config option
|
10
|
+
#
|
11
|
+
module Encryptors
|
12
|
+
# = RestfulAuthenticationSha1
|
13
|
+
# Simulates Restful Authentication's default encryption mechanism.
|
14
|
+
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
|
15
|
+
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in
|
16
|
+
# the initializer to silumate the default behavior.
|
17
|
+
class RestfulAuthenticationSha1
|
18
|
+
|
19
|
+
# Gererates a default password digest based on salt, pepper and the
|
20
|
+
# incoming password.
|
21
|
+
def self.digest(password, stretches, salt, pepper)
|
22
|
+
digest = pepper
|
23
|
+
stretches.times { digest = Digest::SHA1.hexdigest([digest, salt, password, pepper].flatten.join('--')) }
|
24
|
+
digest
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
# Implements a way of adding different encryptions.
|
5
|
+
# The class should implement a self.digest method that taks the following params:
|
6
|
+
# - password
|
7
|
+
# - stretches: the number of times the encryption will be applied
|
8
|
+
# - salt: the password salt as defined by devise
|
9
|
+
# - pepper: Devise config option
|
10
|
+
#
|
11
|
+
module Encryptors
|
12
|
+
# = Sha1
|
13
|
+
# Uses the Sha1 hash algorithm to encrypt passwords.
|
14
|
+
class Sha1
|
15
|
+
|
16
|
+
# Gererates a default password digest based on stretches, salt, pepper and the
|
17
|
+
# incoming password.
|
18
|
+
def self.digest(password, stretches, salt, pepper)
|
19
|
+
digest = pepper
|
20
|
+
stretches.times { digest = self.secure_digest(salt, digest, password, pepper) }
|
21
|
+
digest
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Generate a SHA1 digest joining args. Generated token is something like
|
27
|
+
# --arg1--arg2--arg3--argN--
|
28
|
+
def self.secure_digest(*tokens)
|
29
|
+
::Digest::SHA1.hexdigest('--' << tokens.flatten.join('--') << '--')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "digest/sha2"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
# Implements a way of adding different encryptions.
|
5
|
+
# The class should implement a self.digest method that taks the following params:
|
6
|
+
# - password
|
7
|
+
# - stretches: the number of times the encryption will be applied
|
8
|
+
# - salt: the password salt as defined by devise
|
9
|
+
# - pepper: Devise config option
|
10
|
+
#
|
11
|
+
module Encryptors
|
12
|
+
# = Sha512
|
13
|
+
# Uses the Sha512 hash algorithm to encrypt passwords.
|
14
|
+
class Sha512
|
15
|
+
|
16
|
+
# Gererates a default password digest based on salt, pepper and the
|
17
|
+
# incoming password.
|
18
|
+
def self.digest(password, stretches, salt, pepper)
|
19
|
+
digest = pepper
|
20
|
+
stretches.times { digest = self.secure_digest(salt, digest, password, pepper) }
|
21
|
+
digest
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Generate a Sha512 digest joining args. Generated token is something like
|
27
|
+
# --arg1--arg2--arg3--argN--
|
28
|
+
def self.secure_digest(*tokens)
|
29
|
+
::Digest::SHA512.hexdigest('--' << tokens.flatten.join('--') << '--')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
# This is done by checking the time frame the user is able to sign in without
|
3
3
|
# confirming it's account. If the user has not confirmed it's account during
|
4
4
|
# this time frame, he/she will not able to sign in anymore.
|
5
|
-
Warden::Manager.after_set_user do |record,
|
5
|
+
Warden::Manager.after_set_user do |record, warden, options|
|
6
6
|
if record && record.respond_to?(:active?) && !record.active?
|
7
7
|
scope = options[:scope]
|
8
|
-
|
8
|
+
warden.logout(scope)
|
9
9
|
throw :warden, :scope => scope, :params => { :unconfirmed => true }
|
10
10
|
end
|
11
11
|
end
|
@@ -3,15 +3,17 @@
|
|
3
3
|
# that specific user and adds a cookie with this user info to sign in this user
|
4
4
|
# automatically without asking for credentials. Refer to rememberable strategy
|
5
5
|
# for more info.
|
6
|
-
Warden::Manager.after_authentication do |record,
|
6
|
+
Warden::Manager.after_authentication do |record, warden, options|
|
7
7
|
scope = options[:scope]
|
8
|
-
remember_me =
|
8
|
+
remember_me = warden.params[scope].try(:fetch, :remember_me, nil)
|
9
9
|
|
10
10
|
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
11
11
|
record.remember_me!
|
12
|
-
|
12
|
+
|
13
|
+
warden.response.set_cookie "remember_#{scope}_token", {
|
13
14
|
:value => record.class.serialize_into_cookie(record),
|
14
|
-
:expires => record.remember_expires_at
|
15
|
+
:expires => record.remember_expires_at,
|
16
|
+
:path => "/"
|
15
17
|
}
|
16
18
|
end
|
17
19
|
end
|
@@ -19,9 +21,9 @@ end
|
|
19
21
|
# Before logout hook to forget the user in the given scope, only if rememberable
|
20
22
|
# is activated for this scope. Also clear remember token to ensure the user
|
21
23
|
# won't be remembered again.
|
22
|
-
Warden::Manager.before_logout do |record,
|
24
|
+
Warden::Manager.before_logout do |record, warden, scope|
|
23
25
|
if record.respond_to?(:forget_me!)
|
24
26
|
record.forget_me!
|
25
|
-
|
27
|
+
warden.response.delete_cookie "remember_#{scope}_token"
|
26
28
|
end
|
27
29
|
end
|
data/lib/devise/mapping.rb
CHANGED
@@ -22,7 +22,7 @@ module Devise
|
|
22
22
|
# # is the modules included in the class
|
23
23
|
#
|
24
24
|
class Mapping #:nodoc:
|
25
|
-
attr_reader :name, :as, :path_names, :path_prefix
|
25
|
+
attr_reader :name, :as, :path_names, :path_prefix, :route_options
|
26
26
|
|
27
27
|
# Loop through all mappings looking for a map that matches with the requested
|
28
28
|
# path (ie /users/sign_in). If a path prefix is given, it's taken into account.
|
@@ -40,14 +40,13 @@ module Devise
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def initialize(name, options) #:nodoc:
|
43
|
-
options.
|
44
|
-
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@path_names = options[:path_names] || {}
|
49
|
-
@path_prefix = options[:path_prefix] || ""
|
43
|
+
@as = (options.delete(:as) || name).to_sym
|
44
|
+
@klass = (options.delete(:class_name) || name.to_s.classify).to_s
|
45
|
+
@name = (options.delete(:singular) || name.to_s.singularize).to_sym
|
46
|
+
@path_names = options.delete(:path_names) || {}
|
47
|
+
@path_prefix = options.delete(:path_prefix) || ""
|
50
48
|
@path_prefix << "/" unless @path_prefix[-1] == ?/
|
49
|
+
@route_options = options || {}
|
51
50
|
|
52
51
|
setup_path_names
|
53
52
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Devise
|
2
|
+
module Middlewares
|
3
|
+
class Rememberable
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
auth = env['warden']
|
10
|
+
scopes = select_cookies(auth.request)
|
11
|
+
scopes.each do |scope, token|
|
12
|
+
mapping = Devise.mappings[scope]
|
13
|
+
next unless mapping && mapping.for.include?(:rememberable)
|
14
|
+
user = mapping.to.serialize_from_cookie(token)
|
15
|
+
auth.set_user(user, :scope => scope) if user
|
16
|
+
end
|
17
|
+
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def select_cookies(request)
|
24
|
+
scopes = {}
|
25
|
+
matching = /remember_(#{Devise.mappings.keys.join("|")})_token/
|
26
|
+
request.cookies.each do |key, value|
|
27
|
+
if key.to_s =~ matching
|
28
|
+
scopes[$1.to_sym] = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
scopes
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/devise/models.rb
CHANGED
@@ -92,6 +92,9 @@ module Devise
|
|
92
92
|
|
93
93
|
# Convert new keys to methods which overwrites Devise defaults
|
94
94
|
options.each { |key, value| send(:"#{key}=", value) }
|
95
|
+
|
96
|
+
# Call specific hooks for each ORM
|
97
|
+
Devise.orm_class.included_modules_hook(self, devise_modules)
|
95
98
|
end
|
96
99
|
|
97
100
|
# Stores all modules included inside the model, so we are able to verify
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'digest/sha1'
|
2
1
|
require 'devise/strategies/authenticatable'
|
3
2
|
|
4
3
|
module Devise
|
@@ -49,22 +48,12 @@ module Devise
|
|
49
48
|
end
|
50
49
|
|
51
50
|
protected
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
digest = pepper
|
57
|
-
stretches.times { digest = secure_digest(password_salt, digest, password_to_digest, pepper) }
|
58
|
-
digest
|
59
|
-
end
|
60
|
-
|
61
|
-
# Generate a SHA1 digest joining args. Generated token is something like
|
62
|
-
#
|
63
|
-
# --arg1--arg2--arg3--argN--
|
64
|
-
def secure_digest(*tokens)
|
65
|
-
::Digest::SHA1.hexdigest('--' << tokens.flatten.join('--') << '--')
|
51
|
+
|
52
|
+
# Digests the password using the configured encryptor
|
53
|
+
def password_digest(password)
|
54
|
+
encryptor.digest(password, stretches, password_salt, pepper)
|
66
55
|
end
|
67
|
-
|
56
|
+
|
68
57
|
# Generate a friendly string randomically to be used as token.
|
69
58
|
def friendly_token
|
70
59
|
ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
|
@@ -92,6 +81,7 @@ module Devise
|
|
92
81
|
|
93
82
|
Devise::Models.config(self, :pepper)
|
94
83
|
Devise::Models.config(self, :stretches)
|
84
|
+
Devise::Models.config(self, :encryptor)
|
95
85
|
end
|
96
86
|
end
|
97
87
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Devise
|
2
|
+
module Orm
|
3
|
+
# This module contains some helpers and handle schema (migrations):
|
4
|
+
#
|
5
|
+
# create_table :accounts do |t|
|
6
|
+
# t.authenticatable
|
7
|
+
# t.confirmable
|
8
|
+
# t.recoverable
|
9
|
+
# t.rememberable
|
10
|
+
# t.timestamps
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# However this method does not add indexes. If you need them, here is the declaration:
|
14
|
+
#
|
15
|
+
# add_index "accounts", ["email"], :name => "email", :unique => true
|
16
|
+
# add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true
|
17
|
+
# add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true
|
18
|
+
#
|
19
|
+
module ActiveRecord
|
20
|
+
# Required ORM hook. By default, do nothing on ActiveRecord.
|
21
|
+
def self.included_modules_hook(klass, modules)
|
22
|
+
end
|
23
|
+
|
24
|
+
include Devise::Schema
|
25
|
+
|
26
|
+
# Tell how to apply schema methods.
|
27
|
+
def apply_schema(name, type, options={})
|
28
|
+
column name, type.to_s.downcase.to_sym, options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if defined?(ActiveRecord)
|
35
|
+
ActiveRecord::Base.extend Devise::Models
|
36
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Orm::ActiveRecord
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Devise
|
2
|
+
module Orm
|
3
|
+
module MongoMapper
|
4
|
+
# Include attributes modules and set the proper ones.
|
5
|
+
def self.included_modules_hook(klass, modules)
|
6
|
+
klass.send :extend, self
|
7
|
+
|
8
|
+
modules.each do |mod|
|
9
|
+
klass.send(mod)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
include Devise::Schema
|
14
|
+
|
15
|
+
# Tell how to apply schema methods.
|
16
|
+
def apply_schema(name, type, options={})
|
17
|
+
key name, type, options
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
MongoMapper::Document::ClassMethods.send(:include, Devise::Models)
|
data/lib/devise/rails.rb
CHANGED
@@ -2,10 +2,7 @@ require 'devise/rails/routes'
|
|
2
2
|
require 'devise/rails/warden_compat'
|
3
3
|
|
4
4
|
Rails.configuration.after_initialize do
|
5
|
-
|
6
|
-
ActiveRecord::Base.extend Devise::Models
|
7
|
-
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Migrations
|
8
|
-
end
|
5
|
+
require "devise/orm/#{Devise.orm}"
|
9
6
|
|
10
7
|
# Adds Warden Manager to Rails middleware stack, configuring default devise
|
11
8
|
# strategy and also the failure app.
|
@@ -13,5 +10,8 @@ Rails.configuration.after_initialize do
|
|
13
10
|
Devise.configure_warden_manager(manager)
|
14
11
|
end
|
15
12
|
|
13
|
+
# If using a rememberable module, include the middleware that log users.
|
14
|
+
Rails.configuration.middleware.use Devise::Middlewares::Rememberable
|
15
|
+
|
16
16
|
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
|
17
17
|
end
|
data/lib/devise/rails/routes.rb
CHANGED
@@ -64,6 +64,10 @@ module ActionController::Routing
|
|
64
64
|
#
|
65
65
|
# map.devise_for :users, :path_prefix => "/:locale"
|
66
66
|
#
|
67
|
+
# Any other options will be passed to route definition. If you need conditions for your routes, just map:
|
68
|
+
#
|
69
|
+
# map.devise_for :users, :conditions => { :subdomain => /.+/ }
|
70
|
+
#
|
67
71
|
# If you are using a dynamic prefix, like :locale above, you need to configure default_url_options through Devise. You can do that in config/initializers/devise.rb or setting a Devise.default_url_options:
|
68
72
|
#
|
69
73
|
# Devise.default_url_options do
|
@@ -75,10 +79,12 @@ module ActionController::Routing
|
|
75
79
|
|
76
80
|
resources.map!(&:to_sym)
|
77
81
|
resources.each do |resource|
|
78
|
-
mapping = Devise::Mapping.new(resource, options)
|
82
|
+
mapping = Devise::Mapping.new(resource, options.dup)
|
79
83
|
Devise.mappings[mapping.name] = mapping
|
80
84
|
|
81
|
-
|
85
|
+
route_options = mapping.route_options.merge(:path_prefix => mapping.raw_path, :name_prefix => "#{mapping.name}_")
|
86
|
+
|
87
|
+
with_options(route_options) do |routes|
|
82
88
|
mapping.for.each do |strategy|
|
83
89
|
send(strategy, routes, mapping) if self.respond_to?(strategy, true)
|
84
90
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# Taken from RailsWarden, thanks to Hassox. http://github.com/hassox/rails_warden
|
2
2
|
module Warden::Mixins::Common
|
3
|
-
# Gets the rails request object by default if it's available
|
4
3
|
def request
|
5
4
|
return @request if @request
|
6
5
|
if env['action_controller.rescue.request']
|
@@ -19,8 +18,12 @@ module Warden::Mixins::Common
|
|
19
18
|
raw_session.clear
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def response
|
22
|
+
return @response if @response
|
23
|
+
if env['action_controller.rescue.response']
|
24
|
+
@response = env['action_controller.rescue.response']
|
25
|
+
else
|
26
|
+
Rack::Response.new(env)
|
27
|
+
end
|
25
28
|
end
|
26
29
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Devise
|
2
|
+
# Holds devise schema information. To use it, just include its methods
|
3
|
+
# and overwrite the apply_schema method.
|
4
|
+
module Schema
|
5
|
+
|
6
|
+
# Creates email, encrypted_password and password_salt.
|
7
|
+
#
|
8
|
+
# == Options
|
9
|
+
# * :null when true, allow columns to be null
|
10
|
+
# * :encryptor The encryptor going to be used, necessary for setting the proper encrypter password length
|
11
|
+
def authenticatable(options={})
|
12
|
+
null = options[:null] || false
|
13
|
+
encryptor = options[:encryptor] || :sha1
|
14
|
+
|
15
|
+
apply_schema :email, String, :null => null, :limit => 100
|
16
|
+
apply_schema :encrypted_password, String, :null => null, :limit => Devise::ENCRYPTORS_LENGTH[encryptor]
|
17
|
+
apply_schema :password_salt, String, :null => null, :limit => 20
|
18
|
+
end
|
19
|
+
|
20
|
+
# Creates confirmation_token, confirmed_at and confirmation_sent_at.
|
21
|
+
def confirmable
|
22
|
+
apply_schema :confirmation_token, String, :limit => 20
|
23
|
+
apply_schema :confirmed_at, DateTime
|
24
|
+
apply_schema :confirmation_sent_at, DateTime
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates reset_password_token.
|
28
|
+
def recoverable
|
29
|
+
apply_schema :reset_password_token, String, :limit => 20
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates remember_token and remember_created_at.
|
33
|
+
def rememberable
|
34
|
+
apply_schema :remember_token, String, :limit => 20
|
35
|
+
apply_schema :remember_created_at, DateTime
|
36
|
+
end
|
37
|
+
|
38
|
+
# Overwrite with specific modification to create your own schema.
|
39
|
+
def apply_schema(name, tupe, options={})
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/devise/version.rb
CHANGED
data/test/devise_test.rb
CHANGED
@@ -50,7 +50,7 @@ class DeviseTest < ActiveSupport::TestCase
|
|
50
50
|
Devise.configure_warden_manager(manager)
|
51
51
|
|
52
52
|
assert_equal Devise::Failure, manager.failure_app
|
53
|
-
assert_equal [:
|
53
|
+
assert_equal [:authenticatable], manager.default_strategies
|
54
54
|
assert manager.silence_missing_strategies
|
55
55
|
end
|
56
56
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Encryptors < ActiveSupport::TestCase
|
2
|
+
|
3
|
+
test 'should match a password created by authlogic' do
|
4
|
+
authlogic = "b623c3bc9c775b0eb8edb218a382453396fec4146422853e66ecc4b6bc32d7162ee42074dcb5f180a770dc38b5df15812f09bbf497a4a1b95fe5e7d2b8eb7eb4"
|
5
|
+
encryptor = Devise::Encryptors::AuthlogicSha512.digest('123mudar', 20, 'usZK_z_EAaF61Gwkw-ed', '')
|
6
|
+
assert_equal authlogic, encryptor
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'should match a password created by restful_authentication' do
|
10
|
+
restful_authentication = "93110f71309ce91366375ea44e2a6f5cc73fa8d4"
|
11
|
+
encryptor = Devise::Encryptors::RestfulAuthenticationSha1.digest('123mudar', 10, '48901d2b247a54088acb7f8ea3e695e50fe6791b', 'fee9a51ec0a28d11be380ca6dee6b4b760c1a3bf')
|
12
|
+
assert_equal restful_authentication, encryptor
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'should match a password created by clearance' do
|
16
|
+
clearance = "0f40bbae18ddefd7066276c3ef209d40729b0378"
|
17
|
+
encryptor = Devise::Encryptors::ClearanceSha1.digest('123mudar', nil, '65c58472c207c829f28c68619d3e3aefed18ab3f', nil)
|
18
|
+
assert_equal clearance, encryptor
|
19
|
+
end
|
20
|
+
|
21
|
+
Devise::ENCRYPTORS_LENGTH.each do |key, value|
|
22
|
+
test "should have length #{value} for #{key.inspect}" do
|
23
|
+
swap Devise, :encryptor => key do
|
24
|
+
assert_equal value, Devise.encryptor.digest('a', 2, 'b', 'c').size
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -6,19 +6,17 @@ class RememberMeTest < ActionController::IntegrationTest
|
|
6
6
|
Devise.remember_for = 1
|
7
7
|
user = create_user
|
8
8
|
user.remember_me!
|
9
|
-
cookies['
|
9
|
+
cookies['remember_user_token'] = User.serialize_into_cookie(user) + add_to_token
|
10
10
|
user
|
11
11
|
end
|
12
12
|
|
13
13
|
test 'do not remember the user if he has not checked remember me option' do
|
14
14
|
user = sign_in_as_user
|
15
|
-
|
16
15
|
assert_nil user.reload.remember_token
|
17
16
|
end
|
18
17
|
|
19
18
|
test 'generate remember token after sign in' do
|
20
19
|
user = sign_in_as_user :remember_me => true
|
21
|
-
|
22
20
|
assert_not_nil user.reload.remember_token
|
23
21
|
end
|
24
22
|
|
data/test/mapping_test.rb
CHANGED
@@ -85,6 +85,14 @@ class MappingTest < ActiveSupport::TestCase
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
test 'should have default route options' do
|
89
|
+
assert_equal({}, Devise.mappings[:user].route_options)
|
90
|
+
end
|
91
|
+
|
92
|
+
test 'should allow passing route options to devise routes' do
|
93
|
+
assert_equal({ :requirements => { :extra => 'value' } }, Devise.mappings[:manager].route_options)
|
94
|
+
end
|
95
|
+
|
88
96
|
test 'magic predicates' do
|
89
97
|
mapping = Devise.mappings[:user]
|
90
98
|
assert mapping.authenticatable?
|
@@ -3,10 +3,8 @@ require 'digest/sha1'
|
|
3
3
|
|
4
4
|
class AuthenticatableTest < ActiveSupport::TestCase
|
5
5
|
|
6
|
-
def encrypt_password(user, pepper=
|
7
|
-
|
8
|
-
user.password = '123456'
|
9
|
-
::Digest::SHA1.hexdigest("--#{user.password_salt}--#{pepper}--123456--#{pepper}--")
|
6
|
+
def encrypt_password(user, pepper=User.pepper, stretches=User.stretches, encryptor = ::Devise::Encryptors::Sha1)
|
7
|
+
encryptor.digest('123456', stretches, user.password_salt, pepper)
|
10
8
|
end
|
11
9
|
|
12
10
|
test 'should respond to password and password confirmation' do
|
@@ -59,7 +57,7 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|
59
57
|
assert_not_equal encrypted_password, user.encrypted_password
|
60
58
|
end
|
61
59
|
|
62
|
-
test 'should
|
60
|
+
test 'should fallback to Sha1 as default encryption' do
|
63
61
|
user = new_user
|
64
62
|
assert_equal encrypt_password(user), user.encrypted_password
|
65
63
|
end
|
@@ -69,12 +67,15 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|
69
67
|
Devise.pepper = ''
|
70
68
|
user = new_user
|
71
69
|
assert_equal encrypt_password(user), user.encrypted_password
|
70
|
+
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
72
71
|
Devise.pepper = 'new_pepper'
|
73
72
|
user = new_user
|
74
73
|
assert_equal encrypt_password(user, 'new_pepper'), user.encrypted_password
|
74
|
+
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
75
75
|
Devise.pepper = '123456'
|
76
76
|
user = new_user
|
77
77
|
assert_equal encrypt_password(user, '123456'), user.encrypted_password
|
78
|
+
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
78
79
|
ensure
|
79
80
|
Devise.pepper = nil
|
80
81
|
end
|
@@ -85,11 +86,22 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|
85
86
|
default_stretches = Devise.stretches
|
86
87
|
Devise.stretches = 1
|
87
88
|
user = new_user
|
88
|
-
assert_equal encrypt_password(user, nil,
|
89
|
+
assert_equal encrypt_password(user, nil, 1), user.encrypted_password
|
90
|
+
assert_not_equal encrypt_password(user, nil, 2), user.encrypted_password
|
89
91
|
ensure
|
90
92
|
Devise.stretches = default_stretches
|
91
93
|
end
|
92
94
|
end
|
95
|
+
|
96
|
+
test 'should respect encryptor configuration' do
|
97
|
+
begin
|
98
|
+
Devise.encryptor = ::Devise::Encryptors::Sha512
|
99
|
+
user = create_user
|
100
|
+
assert_equal user.encrypted_password, encrypt_password(user, User.pepper, User.stretches, ::Devise::Encryptors::Sha512)
|
101
|
+
ensure
|
102
|
+
Devise.encryptor = ::Devise::Encryptors::Sha1
|
103
|
+
end
|
104
|
+
end
|
93
105
|
|
94
106
|
test 'should test for a valid password' do
|
95
107
|
user = create_user
|
@@ -4,7 +4,9 @@ ActionController::Routing::Routes.draw do |map|
|
|
4
4
|
map.devise_for :account, :path_names => {
|
5
5
|
:sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification'
|
6
6
|
}
|
7
|
-
map.devise_for :organizers, :singular => 'manager',
|
7
|
+
map.devise_for :organizers, :singular => 'manager',
|
8
|
+
:path_prefix => '/:locale',
|
9
|
+
:requirements => { :extra => 'value' }
|
8
10
|
|
9
11
|
map.resources :users, :only => :index
|
10
12
|
map.resources :admins, :only => :index
|
data/test/routes_test.rb
CHANGED
@@ -69,11 +69,14 @@ class MapRoutingTest < ActionController::TestCase
|
|
69
69
|
end
|
70
70
|
|
71
71
|
test 'map organizer with custom singular name' do
|
72
|
-
assert_recognizes({:controller => 'passwords', :action => 'new', :locale => "en"}, '/en/organizers/password/new')
|
72
|
+
assert_recognizes({:controller => 'passwords', :action => 'new', :locale => "en", :extra => 'value'}, '/en/organizers/password/new')
|
73
73
|
end
|
74
74
|
|
75
75
|
test 'map organizer with path prefix' do
|
76
|
-
assert_recognizes({:controller => 'sessions', :action => 'new', :locale => "en"}, '/en/organizers/sign_in')
|
76
|
+
assert_recognizes({:controller => 'sessions', :action => 'new', :locale => "en", :extra => 'value'}, '/en/organizers/sign_in')
|
77
77
|
end
|
78
78
|
|
79
|
+
test 'map organizer with additional route options' do
|
80
|
+
assert_recognizes({:controller => 'passwords', :action => 'new', :locale => "en", :extra => 'value'}, '/en/organizers/password/new')
|
81
|
+
end
|
79
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jos\xC3\xA9 Valim"
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-11-
|
13
|
+
date: 2009-11-13 00:00:00 -02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -63,24 +63,31 @@ files:
|
|
63
63
|
- lib/devise/controllers/filters.rb
|
64
64
|
- lib/devise/controllers/helpers.rb
|
65
65
|
- lib/devise/controllers/url_helpers.rb
|
66
|
+
- lib/devise/encryptors/authlogic_sha512.rb
|
67
|
+
- lib/devise/encryptors/clearance_sha1.rb
|
68
|
+
- lib/devise/encryptors/restful_authentication_sha1.rb
|
69
|
+
- lib/devise/encryptors/sha1.rb
|
70
|
+
- lib/devise/encryptors/sha512.rb
|
66
71
|
- lib/devise/failure.rb
|
67
72
|
- lib/devise/hooks/confirmable.rb
|
68
73
|
- lib/devise/hooks/rememberable.rb
|
69
74
|
- lib/devise/locales/en.yml
|
70
75
|
- lib/devise/mapping.rb
|
71
|
-
- lib/devise/
|
76
|
+
- lib/devise/middlewares/rememberable.rb
|
72
77
|
- lib/devise/models.rb
|
73
78
|
- lib/devise/models/authenticatable.rb
|
74
79
|
- lib/devise/models/confirmable.rb
|
75
80
|
- lib/devise/models/recoverable.rb
|
76
81
|
- lib/devise/models/rememberable.rb
|
77
82
|
- lib/devise/models/validatable.rb
|
83
|
+
- lib/devise/orm/active_record.rb
|
84
|
+
- lib/devise/orm/mongo_mapper.rb
|
78
85
|
- lib/devise/rails.rb
|
79
86
|
- lib/devise/rails/routes.rb
|
80
87
|
- lib/devise/rails/warden_compat.rb
|
88
|
+
- lib/devise/schema.rb
|
81
89
|
- lib/devise/strategies/authenticatable.rb
|
82
90
|
- lib/devise/strategies/base.rb
|
83
|
-
- lib/devise/strategies/rememberable.rb
|
84
91
|
- lib/devise/version.rb
|
85
92
|
- lib/devise/warden.rb
|
86
93
|
has_rdoc: true
|
@@ -116,6 +123,7 @@ test_files:
|
|
116
123
|
- test/controllers/helpers_test.rb
|
117
124
|
- test/controllers/url_helpers_test.rb
|
118
125
|
- test/devise_test.rb
|
126
|
+
- test/encryptors_test.rb
|
119
127
|
- test/failure_test.rb
|
120
128
|
- test/integration/authenticatable_test.rb
|
121
129
|
- test/integration/confirmable_test.rb
|
data/lib/devise/migrations.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
module Devise
|
2
|
-
# Helpers to migration:
|
3
|
-
#
|
4
|
-
# create_table :accounts do |t|
|
5
|
-
# t.authenticatable
|
6
|
-
# t.confirmable
|
7
|
-
# t.recoverable
|
8
|
-
# t.rememberable
|
9
|
-
# t.timestamps
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# However this method does not add indexes. If you need them, here is the declaration:
|
13
|
-
#
|
14
|
-
# add_index "accounts", ["email"], :name => "email", :unique => true
|
15
|
-
# add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true
|
16
|
-
# add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true
|
17
|
-
#
|
18
|
-
module Migrations
|
19
|
-
|
20
|
-
# Creates email, encrypted_password and password_salt.
|
21
|
-
#
|
22
|
-
def authenticatable(options={})
|
23
|
-
null = options[:null] || false
|
24
|
-
string :email, :limit => 100, :null => null
|
25
|
-
string :encrypted_password, :limit => 40, :null => null
|
26
|
-
string :password_salt, :limit => 20, :null => null
|
27
|
-
end
|
28
|
-
|
29
|
-
# Creates confirmation_token, confirmed_at and confirmation_sent_at.
|
30
|
-
#
|
31
|
-
def confirmable
|
32
|
-
string :confirmation_token, :limit => 20
|
33
|
-
datetime :confirmed_at
|
34
|
-
datetime :confirmation_sent_at
|
35
|
-
end
|
36
|
-
|
37
|
-
# Creates reset_password_token.
|
38
|
-
#
|
39
|
-
def recoverable
|
40
|
-
string :reset_password_token, :limit => 20
|
41
|
-
end
|
42
|
-
|
43
|
-
# Creates remember_token and remember_created_at.
|
44
|
-
#
|
45
|
-
def rememberable
|
46
|
-
string :remember_token, :limit => 20
|
47
|
-
datetime :remember_created_at
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Devise
|
2
|
-
module Strategies
|
3
|
-
# Remember the user through the remember token. This strategy is responsible
|
4
|
-
# to verify whether there is a cookie with the remember token, and to
|
5
|
-
# recreate the user from this cookie if it exists. Must be called *before*
|
6
|
-
# authenticatable.
|
7
|
-
class Rememberable < Devise::Strategies::Base
|
8
|
-
|
9
|
-
# A valid strategy for rememberable needs a remember token in the cookies.
|
10
|
-
def valid?
|
11
|
-
super && remember_me_cookie.present?
|
12
|
-
end
|
13
|
-
|
14
|
-
# To authenticate a user we deserialize the cookie and attempt finding
|
15
|
-
# the record in the database. If the attempt fails, we pass to another
|
16
|
-
# strategy handle the authentication.
|
17
|
-
def authenticate!
|
18
|
-
if resource = mapping.to.serialize_from_cookie(remember_me_cookie)
|
19
|
-
success!(resource)
|
20
|
-
else
|
21
|
-
pass
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
# Accessor for remember cookie
|
28
|
-
def remember_me_cookie
|
29
|
-
cookies['remember_token']
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
Warden::Strategies.add(:rememberable, Devise::Strategies::Rememberable)
|