mongoid-devise 1.0.1
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/CHANGELOG.rdoc +333 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +260 -0
- data/Rakefile +53 -0
- data/TODO +2 -0
- data/app/controllers/confirmations_controller.rb +33 -0
- data/app/controllers/passwords_controller.rb +42 -0
- data/app/controllers/registrations_controller.rb +55 -0
- data/app/controllers/sessions_controller.rb +45 -0
- data/app/controllers/unlocks_controller.rb +33 -0
- data/app/models/devise_mailer.rb +68 -0
- data/app/views/confirmations/new.html.erb +12 -0
- data/app/views/devise_mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/devise_mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/devise_mailer/unlock_instructions.html.erb +7 -0
- data/app/views/passwords/edit.html.erb +16 -0
- data/app/views/passwords/new.html.erb +12 -0
- data/app/views/registrations/edit.html.erb +25 -0
- data/app/views/registrations/new.html.erb +17 -0
- data/app/views/sessions/new.html.erb +17 -0
- data/app/views/shared/_devise_links.erb +19 -0
- data/app/views/unlocks/new.html.erb +12 -0
- data/generators/devise/USAGE +5 -0
- data/generators/devise/devise_generator.rb +15 -0
- data/generators/devise/lib/route_devise.rb +32 -0
- data/generators/devise/templates/migration.rb +23 -0
- data/generators/devise/templates/model.rb +9 -0
- data/generators/devise_install/USAGE +3 -0
- data/generators/devise_install/devise_install_generator.rb +15 -0
- data/generators/devise_install/templates/README +18 -0
- data/generators/devise_install/templates/devise.rb +102 -0
- data/generators/devise_views/USAGE +3 -0
- data/generators/devise_views/devise_views_generator.rb +21 -0
- data/init.rb +2 -0
- data/lib/devise.rb +253 -0
- data/lib/devise/controllers/helpers.rb +200 -0
- data/lib/devise/controllers/internal_helpers.rb +129 -0
- data/lib/devise/controllers/url_helpers.rb +41 -0
- data/lib/devise/encryptors/authlogic_sha512.rb +21 -0
- data/lib/devise/encryptors/base.rb +20 -0
- data/lib/devise/encryptors/bcrypt.rb +21 -0
- data/lib/devise/encryptors/clearance_sha1.rb +19 -0
- data/lib/devise/encryptors/restful_authentication_sha1.rb +22 -0
- data/lib/devise/encryptors/sha1.rb +27 -0
- data/lib/devise/encryptors/sha512.rb +27 -0
- data/lib/devise/failure_app.rb +65 -0
- data/lib/devise/hooks/activatable.rb +15 -0
- data/lib/devise/hooks/rememberable.rb +30 -0
- data/lib/devise/hooks/timeoutable.rb +18 -0
- data/lib/devise/hooks/trackable.rb +18 -0
- data/lib/devise/locales/en.yml +35 -0
- data/lib/devise/mapping.rb +131 -0
- data/lib/devise/models.rb +112 -0
- data/lib/devise/models/activatable.rb +16 -0
- data/lib/devise/models/authenticatable.rb +146 -0
- data/lib/devise/models/confirmable.rb +172 -0
- data/lib/devise/models/http_authenticatable.rb +21 -0
- data/lib/devise/models/lockable.rb +160 -0
- data/lib/devise/models/recoverable.rb +80 -0
- data/lib/devise/models/registerable.rb +8 -0
- data/lib/devise/models/rememberable.rb +94 -0
- data/lib/devise/models/timeoutable.rb +28 -0
- data/lib/devise/models/token_authenticatable.rb +89 -0
- data/lib/devise/models/trackable.rb +16 -0
- data/lib/devise/models/validatable.rb +48 -0
- data/lib/devise/orm/active_record.rb +41 -0
- data/lib/devise/orm/data_mapper.rb +83 -0
- data/lib/devise/orm/mongo_mapper.rb +51 -0
- data/lib/devise/orm/mongoid.rb +60 -0
- data/lib/devise/rails.rb +14 -0
- data/lib/devise/rails/routes.rb +125 -0
- data/lib/devise/rails/warden_compat.rb +25 -0
- data/lib/devise/schema.rb +65 -0
- data/lib/devise/strategies/authenticatable.rb +36 -0
- data/lib/devise/strategies/base.rb +16 -0
- data/lib/devise/strategies/http_authenticatable.rb +49 -0
- data/lib/devise/strategies/rememberable.rb +37 -0
- data/lib/devise/strategies/token_authenticatable.rb +37 -0
- data/lib/devise/test_helpers.rb +86 -0
- data/lib/devise/version.rb +3 -0
- data/test/controllers/helpers_test.rb +177 -0
- data/test/controllers/internal_helpers_test.rb +55 -0
- data/test/controllers/url_helpers_test.rb +47 -0
- data/test/devise_test.rb +69 -0
- data/test/encryptors_test.rb +31 -0
- data/test/failure_app_test.rb +44 -0
- data/test/integration/authenticatable_test.rb +271 -0
- data/test/integration/confirmable_test.rb +97 -0
- data/test/integration/http_authenticatable_test.rb +44 -0
- data/test/integration/lockable_test.rb +83 -0
- data/test/integration/recoverable_test.rb +141 -0
- data/test/integration/registerable_test.rb +130 -0
- data/test/integration/rememberable_test.rb +63 -0
- data/test/integration/timeoutable_test.rb +68 -0
- data/test/integration/token_authenticatable_test.rb +55 -0
- data/test/integration/trackable_test.rb +64 -0
- data/test/mailers/confirmation_instructions_test.rb +80 -0
- data/test/mailers/reset_password_instructions_test.rb +68 -0
- data/test/mailers/unlock_instructions_test.rb +62 -0
- data/test/mapping_test.rb +153 -0
- data/test/models/authenticatable_test.rb +180 -0
- data/test/models/confirmable_test.rb +228 -0
- data/test/models/lockable_test.rb +202 -0
- data/test/models/recoverable_test.rb +138 -0
- data/test/models/rememberable_test.rb +135 -0
- data/test/models/timeoutable_test.rb +28 -0
- data/test/models/token_authenticatable_test.rb +51 -0
- data/test/models/trackable_test.rb +5 -0
- data/test/models/validatable_test.rb +106 -0
- data/test/models_test.rb +56 -0
- data/test/orm/active_record.rb +31 -0
- data/test/orm/mongo_mapper.rb +20 -0
- data/test/orm/mongoid.rb +22 -0
- data/test/rails_app/app/active_record/admin.rb +7 -0
- data/test/rails_app/app/active_record/user.rb +7 -0
- data/test/rails_app/app/controllers/admins_controller.rb +6 -0
- data/test/rails_app/app/controllers/application_controller.rb +10 -0
- data/test/rails_app/app/controllers/home_controller.rb +4 -0
- data/test/rails_app/app/controllers/users_controller.rb +16 -0
- data/test/rails_app/app/helpers/application_helper.rb +3 -0
- data/test/rails_app/app/mongo_mapper/admin.rb +9 -0
- data/test/rails_app/app/mongo_mapper/user.rb +8 -0
- data/test/rails_app/app/mongoid/admin.rb +9 -0
- data/test/rails_app/app/mongoid/user.rb +8 -0
- data/test/rails_app/config/boot.rb +110 -0
- data/test/rails_app/config/environment.rb +42 -0
- data/test/rails_app/config/environments/development.rb +17 -0
- data/test/rails_app/config/environments/production.rb +28 -0
- data/test/rails_app/config/environments/test.rb +28 -0
- data/test/rails_app/config/initializers/devise.rb +79 -0
- data/test/rails_app/config/initializers/inflections.rb +2 -0
- data/test/rails_app/config/initializers/new_rails_defaults.rb +24 -0
- data/test/rails_app/config/initializers/session_store.rb +15 -0
- data/test/rails_app/config/routes.rb +21 -0
- data/test/routes_test.rb +110 -0
- data/test/support/assertions_helper.rb +37 -0
- data/test/support/integration_tests_helper.rb +71 -0
- data/test/support/test_silencer.rb +5 -0
- data/test/support/tests_helper.rb +39 -0
- data/test/test_helper.rb +21 -0
- data/test/test_helpers_test.rb +57 -0
- metadata +216 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Models
|
|
3
|
+
|
|
4
|
+
# Recoverable takes care of reseting the user password and send reset instructions
|
|
5
|
+
# Examples:
|
|
6
|
+
#
|
|
7
|
+
# # resets the user password and save the record, true if valid passwords are given, otherwise false
|
|
8
|
+
# User.find(1).reset_password!('password123', 'password123')
|
|
9
|
+
#
|
|
10
|
+
# # only resets the user password, without saving the record
|
|
11
|
+
# user = User.find(1)
|
|
12
|
+
# user.reset_password('password123', 'password123')
|
|
13
|
+
#
|
|
14
|
+
# # creates a new token and send it with instructions about how to reset the password
|
|
15
|
+
# User.find(1).send_reset_password_instructions
|
|
16
|
+
module Recoverable
|
|
17
|
+
def self.included(base)
|
|
18
|
+
base.class_eval do
|
|
19
|
+
extend ClassMethods
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Update password saving the record and clearing token. Returns true if
|
|
24
|
+
# the passwords are valid and the record was saved, false otherwise.
|
|
25
|
+
def reset_password!(new_password, new_password_confirmation)
|
|
26
|
+
self.password = new_password
|
|
27
|
+
self.password_confirmation = new_password_confirmation
|
|
28
|
+
clear_reset_password_token if valid?
|
|
29
|
+
save
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Resets reset password token and send reset password instructions by email
|
|
33
|
+
def send_reset_password_instructions
|
|
34
|
+
generate_reset_password_token!
|
|
35
|
+
::DeviseMailer.deliver_reset_password_instructions(self)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
# Generates a new random token for reset password
|
|
41
|
+
def generate_reset_password_token
|
|
42
|
+
self.reset_password_token = Devise.friendly_token
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Resets the reset password token with and save the record without
|
|
46
|
+
# validating
|
|
47
|
+
def generate_reset_password_token!
|
|
48
|
+
generate_reset_password_token && save(false)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Removes reset_password token
|
|
52
|
+
def clear_reset_password_token
|
|
53
|
+
self.reset_password_token = nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
module ClassMethods
|
|
57
|
+
# Attempt to find a user by it's email. If a record is found, send new
|
|
58
|
+
# password instructions to it. If not user is found, returns a new user
|
|
59
|
+
# with an email not found error.
|
|
60
|
+
# Attributes must contain the user email
|
|
61
|
+
def send_reset_password_instructions(attributes={})
|
|
62
|
+
recoverable = find_or_initialize_with_error_by(:email, attributes[:email], :not_found)
|
|
63
|
+
recoverable.send_reset_password_instructions unless recoverable.new_record?
|
|
64
|
+
recoverable
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Attempt to find a user by it's reset_password_token to reset it's
|
|
68
|
+
# password. If a user is found, reset it's password and automatically
|
|
69
|
+
# try saving the record. If not user is found, returns a new user
|
|
70
|
+
# containing an error in reset_password_token attribute.
|
|
71
|
+
# Attributes must contain reset_password_token, password and confirmation
|
|
72
|
+
def reset_password!(attributes={})
|
|
73
|
+
recoverable = find_or_initialize_with_error_by(:reset_password_token, attributes[:reset_password_token])
|
|
74
|
+
recoverable.reset_password!(attributes[:password], attributes[:password_confirmation]) unless recoverable.new_record?
|
|
75
|
+
recoverable
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'devise/strategies/rememberable'
|
|
2
|
+
require 'devise/hooks/rememberable'
|
|
3
|
+
|
|
4
|
+
module Devise
|
|
5
|
+
module Models
|
|
6
|
+
# Rememberable manages generating and clearing token for remember the user
|
|
7
|
+
# from a saved cookie. Rememberable also has utility methods for dealing
|
|
8
|
+
# with serializing the user into the cookie and back from the cookie, trying
|
|
9
|
+
# to lookup the record based on the saved information.
|
|
10
|
+
# You probably wouldn't use rememberable methods directly, they are used
|
|
11
|
+
# mostly internally for handling the remember token.
|
|
12
|
+
#
|
|
13
|
+
# Configuration:
|
|
14
|
+
#
|
|
15
|
+
# remember_for: the time you want the user will be remembered without
|
|
16
|
+
# asking for credentials. After this time the user will be
|
|
17
|
+
# blocked and will have to enter his credentials again.
|
|
18
|
+
# This configuration is also used to calculate the expires
|
|
19
|
+
# time for the cookie created to remember the user.
|
|
20
|
+
# By default remember_for is 2.weeks.
|
|
21
|
+
#
|
|
22
|
+
# Examples:
|
|
23
|
+
#
|
|
24
|
+
# User.find(1).remember_me! # regenerating the token
|
|
25
|
+
# User.find(1).forget_me! # clearing the token
|
|
26
|
+
#
|
|
27
|
+
# # generating info to put into cookies
|
|
28
|
+
# User.serialize_into_cookie(user)
|
|
29
|
+
#
|
|
30
|
+
# # lookup the user based on the incoming cookie information
|
|
31
|
+
# User.serialize_from_cookie(cookie_string)
|
|
32
|
+
module Rememberable
|
|
33
|
+
|
|
34
|
+
def self.included(base)
|
|
35
|
+
base.class_eval do
|
|
36
|
+
extend ClassMethods
|
|
37
|
+
|
|
38
|
+
# Remember me option available in after_authentication hook.
|
|
39
|
+
attr_accessor :remember_me
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Generate a new remember token and save the record without validations.
|
|
44
|
+
def remember_me!
|
|
45
|
+
self.remember_token = Devise.friendly_token
|
|
46
|
+
self.remember_created_at = Time.now.utc
|
|
47
|
+
|
|
48
|
+
save(false)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Removes the remember token only if it exists, and save the record
|
|
52
|
+
# without validations.
|
|
53
|
+
def forget_me!
|
|
54
|
+
if remember_token
|
|
55
|
+
self.remember_token = nil
|
|
56
|
+
self.remember_created_at = nil
|
|
57
|
+
save(false)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Checks whether the incoming token matches or not with the record token.
|
|
62
|
+
def valid_remember_token?(token)
|
|
63
|
+
remember_token && !remember_expired? && remember_token == token
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Remember token should be expired if expiration time not overpass now.
|
|
67
|
+
def remember_expired?
|
|
68
|
+
remember_expires_at <= Time.now.utc
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Remember token expires at created time + remember_for configuration
|
|
72
|
+
def remember_expires_at
|
|
73
|
+
# TODO: with MongoId need transform by remember_created_at.utc
|
|
74
|
+
remember_created_at + self.class.remember_for
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
module ClassMethods
|
|
78
|
+
# Create the cookie key using the record id and remember_token
|
|
79
|
+
def serialize_into_cookie(record)
|
|
80
|
+
"#{record.id}::#{record.remember_token}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Recreate the user based on the stored cookie
|
|
84
|
+
def serialize_from_cookie(cookie)
|
|
85
|
+
record_id, record_token = cookie.split('::')
|
|
86
|
+
record = find(:first, :conditions => { :id => record_id }) if record_id
|
|
87
|
+
record if record.try(:valid_remember_token?, record_token)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
Devise::Models.config(self, :remember_for)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'devise/hooks/timeoutable'
|
|
2
|
+
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
|
+
# Timeoutable takes care of veryfing whether a user session has already
|
|
6
|
+
# expired or not. When a session expires after the configured time, the user
|
|
7
|
+
# will be asked for credentials again, it means, he/she will be redirected
|
|
8
|
+
# to the sign in page.
|
|
9
|
+
#
|
|
10
|
+
# Configuration:
|
|
11
|
+
#
|
|
12
|
+
# timeout_in: the time you want to timeout the user session without activity.
|
|
13
|
+
module Timeoutable
|
|
14
|
+
def self.included(base)
|
|
15
|
+
base.extend ClassMethods
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks whether the user session has expired based on configured time.
|
|
19
|
+
def timedout?(last_access)
|
|
20
|
+
last_access && last_access <= self.class.timeout_in.ago
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
module ClassMethods
|
|
24
|
+
Devise::Models.config(self, :timeout_in)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'devise/strategies/token_authenticatable'
|
|
2
|
+
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
|
+
# Token Authenticatable Module, responsible for generate authentication token and validating
|
|
6
|
+
# authenticity of a user while signing in using an authentication token (say follows an URL).
|
|
7
|
+
#
|
|
8
|
+
# == Configuration:
|
|
9
|
+
#
|
|
10
|
+
# You can overwrite configuration values by setting in globally in Devise (+Devise.setup+),
|
|
11
|
+
# using devise method, or overwriting the respective instance method.
|
|
12
|
+
#
|
|
13
|
+
# +token_authentication_key+ - Defines name of the authentication token params key. E.g. /users/sign_in?some_key=...
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# User.authenticate_with_token(:auth_token => '123456789') # returns authenticated user or nil
|
|
18
|
+
# User.find(1).valid_authentication_token?('rI1t6PKQ8yP7VetgwdybB') # returns true/false
|
|
19
|
+
#
|
|
20
|
+
module TokenAuthenticatable
|
|
21
|
+
def self.included(base)
|
|
22
|
+
base.class_eval do
|
|
23
|
+
extend ClassMethods
|
|
24
|
+
before_save :ensure_authentication_token
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Generate new authentication token (a.k.a. "single access token").
|
|
29
|
+
def reset_authentication_token
|
|
30
|
+
self.authentication_token = self.class.authentication_token
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Generate new authentication token and save the record.
|
|
34
|
+
def reset_authentication_token!
|
|
35
|
+
reset_authentication_token
|
|
36
|
+
self.save
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Generate authentication token unless already exists.
|
|
40
|
+
def ensure_authentication_token
|
|
41
|
+
self.reset_authentication_token if self.authentication_token.blank?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Generate authentication token unless already exists and save the record.
|
|
45
|
+
def ensure_authentication_token!
|
|
46
|
+
self.reset_authentication_token! if self.authentication_token.blank?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Verifies whether an +incoming_authentication_token+ (i.e. from single access URL)
|
|
50
|
+
# is the user authentication token.
|
|
51
|
+
def valid_authentication_token?(incoming_auth_token)
|
|
52
|
+
incoming_auth_token.present? && incoming_auth_token == self.authentication_token
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
module ClassMethods
|
|
56
|
+
::Devise::Models.config(self, :token_authentication_key)
|
|
57
|
+
|
|
58
|
+
# Authenticate a user based on authentication token.
|
|
59
|
+
def authenticate_with_token(attributes)
|
|
60
|
+
token = attributes[self.token_authentication_key]
|
|
61
|
+
resource = self.find_for_token_authentication(token)
|
|
62
|
+
resource if resource.try(:valid_authentication_token?, token)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def authentication_token
|
|
66
|
+
::Devise.friendly_token
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
protected
|
|
70
|
+
|
|
71
|
+
# Find first record based on conditions given (ie by the sign in form).
|
|
72
|
+
# Overwrite to add customized conditions, create a join, or maybe use a
|
|
73
|
+
# namedscope to filter records while authenticating.
|
|
74
|
+
#
|
|
75
|
+
# == Example:
|
|
76
|
+
#
|
|
77
|
+
# def self.find_for_token_authentication(token, conditions = {})
|
|
78
|
+
# conditions = {:active => true}
|
|
79
|
+
# self.find_by_authentication_token(token, :conditions => conditions)
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
def find_for_token_authentication(token)
|
|
83
|
+
self.find(:first, :conditions => { :authentication_token => token})
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'devise/hooks/trackable'
|
|
2
|
+
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
|
+
# Track information about your user sign in. It tracks the following columns:
|
|
6
|
+
#
|
|
7
|
+
# * sign_in_count - Increased every time a sign in is made (by form, openid, oauth)
|
|
8
|
+
# * current_sign_in_at - A tiemstamp updated when the user signs in
|
|
9
|
+
# * last_sign_in_at - Holds the timestamp of the previous sign in
|
|
10
|
+
# * current_sign_in_ip - The remote ip updated when the user sign in
|
|
11
|
+
# * last_sign_in_at - Holds the remote ip of the previous sign in
|
|
12
|
+
#
|
|
13
|
+
module Trackable
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Models
|
|
3
|
+
|
|
4
|
+
# Validatable creates all needed validations for a user email and password.
|
|
5
|
+
# It's optional, given you may want to create the validations by yourself.
|
|
6
|
+
# Automatically validate if the email is present, unique and it's format is
|
|
7
|
+
# valid. Also tests presence of password, confirmation and length
|
|
8
|
+
module Validatable
|
|
9
|
+
# All validations used by this module.
|
|
10
|
+
VALIDATIONS = [ :validates_presence_of, :validates_uniqueness_of, :validates_format_of,
|
|
11
|
+
:validates_confirmation_of, :validates_length_of ].freeze
|
|
12
|
+
|
|
13
|
+
def self.included(base)
|
|
14
|
+
assert_validations_api!(base)
|
|
15
|
+
|
|
16
|
+
base.class_eval do
|
|
17
|
+
validates_presence_of :email
|
|
18
|
+
validates_uniqueness_of :email, :scope => authentication_keys[1..-1], :allow_blank => true
|
|
19
|
+
validates_format_of :email, :with => EMAIL_REGEX, :allow_blank => true
|
|
20
|
+
|
|
21
|
+
with_options :if => :password_required? do |v|
|
|
22
|
+
v.validates_presence_of :password
|
|
23
|
+
v.validates_confirmation_of :password
|
|
24
|
+
v.validates_length_of :password, :within => 6..20, :allow_blank => true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.assert_validations_api!(base) #:nodoc:
|
|
30
|
+
unavailable_validations = VALIDATIONS.select { |v| !base.respond_to?(v) }
|
|
31
|
+
|
|
32
|
+
unless unavailable_validations.empty?
|
|
33
|
+
raise "Could not use :validatable module since #{base} does not respond " <<
|
|
34
|
+
"to the following methods: #{unavailable_validations.to_sentence}."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
# Checks whether a password is needed or not. For validations only.
|
|
41
|
+
# Passwords are always required if it's a new record, or if the password
|
|
42
|
+
# or confirmation are being set somewhere.
|
|
43
|
+
def password_required?
|
|
44
|
+
new_record? || !password.nil? || !password_confirmation.nil?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
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.trackable
|
|
11
|
+
# t.lockable
|
|
12
|
+
# t.timestamps
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# However this method does not add indexes. If you need them, here is the declaration:
|
|
16
|
+
#
|
|
17
|
+
# add_index "accounts", ["email"], :name => "email", :unique => true
|
|
18
|
+
# add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true
|
|
19
|
+
# add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true
|
|
20
|
+
#
|
|
21
|
+
module ActiveRecord
|
|
22
|
+
# Required ORM hook. Just yield the given block in ActiveRecord.
|
|
23
|
+
def self.included_modules_hook(klass)
|
|
24
|
+
yield
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
include Devise::Schema
|
|
28
|
+
|
|
29
|
+
# Tell how to apply schema methods.
|
|
30
|
+
def apply_schema(name, type, options={})
|
|
31
|
+
column name, type.to_s.downcase.to_sym, options
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if defined?(ActiveRecord)
|
|
38
|
+
ActiveRecord::Base.extend Devise::Models
|
|
39
|
+
ActiveRecord::ConnectionAdapters::Table.send :include, Devise::Orm::ActiveRecord
|
|
40
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Orm::ActiveRecord
|
|
41
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Orm
|
|
3
|
+
module DataMapper
|
|
4
|
+
module InstanceMethods
|
|
5
|
+
def save(flag=nil)
|
|
6
|
+
if flag == false
|
|
7
|
+
save!
|
|
8
|
+
else
|
|
9
|
+
super()
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.included_modules_hook(klass)
|
|
15
|
+
klass.send :extend, self
|
|
16
|
+
klass.send :include, InstanceMethods
|
|
17
|
+
|
|
18
|
+
yield
|
|
19
|
+
|
|
20
|
+
klass.devise_modules.each do |mod|
|
|
21
|
+
klass.send(mod) if klass.respond_to?(mod)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
include Devise::Schema
|
|
26
|
+
|
|
27
|
+
SCHEMA_OPTIONS = {
|
|
28
|
+
:null => :nullable,
|
|
29
|
+
:limit => :length
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Hooks for confirmable
|
|
33
|
+
def before_create(*args)
|
|
34
|
+
wrap_hook(:before, *args)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def after_create(*args)
|
|
38
|
+
wrap_hook(:after, *args)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def wrap_hook(action, *args)
|
|
42
|
+
options = args.extract_options!
|
|
43
|
+
|
|
44
|
+
args.each do |callback|
|
|
45
|
+
send action, :create, callback
|
|
46
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
|
47
|
+
def #{callback}
|
|
48
|
+
super if #{options[:if] || true}
|
|
49
|
+
end
|
|
50
|
+
METHOD
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Add ActiveRecord like finder
|
|
55
|
+
def find(*args)
|
|
56
|
+
options = args.extract_options!
|
|
57
|
+
case args.first
|
|
58
|
+
when :first
|
|
59
|
+
first(options)
|
|
60
|
+
when :all
|
|
61
|
+
all(options)
|
|
62
|
+
else
|
|
63
|
+
get(*args)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Tell how to apply schema methods. This automatically maps :limit to
|
|
68
|
+
# :length and :null to :nullable.
|
|
69
|
+
def apply_schema(name, type, options={})
|
|
70
|
+
return unless Devise.apply_schema
|
|
71
|
+
|
|
72
|
+
SCHEMA_OPTIONS.each do |old_key, new_key|
|
|
73
|
+
next unless options.key?(old_key)
|
|
74
|
+
options[new_key] = options.delete(old_key)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
property name, type, options
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
DataMapper::Model.send(:include, Devise::Models)
|