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.
Files changed (142) hide show
  1. data/CHANGELOG.rdoc +333 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +260 -0
  4. data/Rakefile +53 -0
  5. data/TODO +2 -0
  6. data/app/controllers/confirmations_controller.rb +33 -0
  7. data/app/controllers/passwords_controller.rb +42 -0
  8. data/app/controllers/registrations_controller.rb +55 -0
  9. data/app/controllers/sessions_controller.rb +45 -0
  10. data/app/controllers/unlocks_controller.rb +33 -0
  11. data/app/models/devise_mailer.rb +68 -0
  12. data/app/views/confirmations/new.html.erb +12 -0
  13. data/app/views/devise_mailer/confirmation_instructions.html.erb +5 -0
  14. data/app/views/devise_mailer/reset_password_instructions.html.erb +8 -0
  15. data/app/views/devise_mailer/unlock_instructions.html.erb +7 -0
  16. data/app/views/passwords/edit.html.erb +16 -0
  17. data/app/views/passwords/new.html.erb +12 -0
  18. data/app/views/registrations/edit.html.erb +25 -0
  19. data/app/views/registrations/new.html.erb +17 -0
  20. data/app/views/sessions/new.html.erb +17 -0
  21. data/app/views/shared/_devise_links.erb +19 -0
  22. data/app/views/unlocks/new.html.erb +12 -0
  23. data/generators/devise/USAGE +5 -0
  24. data/generators/devise/devise_generator.rb +15 -0
  25. data/generators/devise/lib/route_devise.rb +32 -0
  26. data/generators/devise/templates/migration.rb +23 -0
  27. data/generators/devise/templates/model.rb +9 -0
  28. data/generators/devise_install/USAGE +3 -0
  29. data/generators/devise_install/devise_install_generator.rb +15 -0
  30. data/generators/devise_install/templates/README +18 -0
  31. data/generators/devise_install/templates/devise.rb +102 -0
  32. data/generators/devise_views/USAGE +3 -0
  33. data/generators/devise_views/devise_views_generator.rb +21 -0
  34. data/init.rb +2 -0
  35. data/lib/devise.rb +253 -0
  36. data/lib/devise/controllers/helpers.rb +200 -0
  37. data/lib/devise/controllers/internal_helpers.rb +129 -0
  38. data/lib/devise/controllers/url_helpers.rb +41 -0
  39. data/lib/devise/encryptors/authlogic_sha512.rb +21 -0
  40. data/lib/devise/encryptors/base.rb +20 -0
  41. data/lib/devise/encryptors/bcrypt.rb +21 -0
  42. data/lib/devise/encryptors/clearance_sha1.rb +19 -0
  43. data/lib/devise/encryptors/restful_authentication_sha1.rb +22 -0
  44. data/lib/devise/encryptors/sha1.rb +27 -0
  45. data/lib/devise/encryptors/sha512.rb +27 -0
  46. data/lib/devise/failure_app.rb +65 -0
  47. data/lib/devise/hooks/activatable.rb +15 -0
  48. data/lib/devise/hooks/rememberable.rb +30 -0
  49. data/lib/devise/hooks/timeoutable.rb +18 -0
  50. data/lib/devise/hooks/trackable.rb +18 -0
  51. data/lib/devise/locales/en.yml +35 -0
  52. data/lib/devise/mapping.rb +131 -0
  53. data/lib/devise/models.rb +112 -0
  54. data/lib/devise/models/activatable.rb +16 -0
  55. data/lib/devise/models/authenticatable.rb +146 -0
  56. data/lib/devise/models/confirmable.rb +172 -0
  57. data/lib/devise/models/http_authenticatable.rb +21 -0
  58. data/lib/devise/models/lockable.rb +160 -0
  59. data/lib/devise/models/recoverable.rb +80 -0
  60. data/lib/devise/models/registerable.rb +8 -0
  61. data/lib/devise/models/rememberable.rb +94 -0
  62. data/lib/devise/models/timeoutable.rb +28 -0
  63. data/lib/devise/models/token_authenticatable.rb +89 -0
  64. data/lib/devise/models/trackable.rb +16 -0
  65. data/lib/devise/models/validatable.rb +48 -0
  66. data/lib/devise/orm/active_record.rb +41 -0
  67. data/lib/devise/orm/data_mapper.rb +83 -0
  68. data/lib/devise/orm/mongo_mapper.rb +51 -0
  69. data/lib/devise/orm/mongoid.rb +60 -0
  70. data/lib/devise/rails.rb +14 -0
  71. data/lib/devise/rails/routes.rb +125 -0
  72. data/lib/devise/rails/warden_compat.rb +25 -0
  73. data/lib/devise/schema.rb +65 -0
  74. data/lib/devise/strategies/authenticatable.rb +36 -0
  75. data/lib/devise/strategies/base.rb +16 -0
  76. data/lib/devise/strategies/http_authenticatable.rb +49 -0
  77. data/lib/devise/strategies/rememberable.rb +37 -0
  78. data/lib/devise/strategies/token_authenticatable.rb +37 -0
  79. data/lib/devise/test_helpers.rb +86 -0
  80. data/lib/devise/version.rb +3 -0
  81. data/test/controllers/helpers_test.rb +177 -0
  82. data/test/controllers/internal_helpers_test.rb +55 -0
  83. data/test/controllers/url_helpers_test.rb +47 -0
  84. data/test/devise_test.rb +69 -0
  85. data/test/encryptors_test.rb +31 -0
  86. data/test/failure_app_test.rb +44 -0
  87. data/test/integration/authenticatable_test.rb +271 -0
  88. data/test/integration/confirmable_test.rb +97 -0
  89. data/test/integration/http_authenticatable_test.rb +44 -0
  90. data/test/integration/lockable_test.rb +83 -0
  91. data/test/integration/recoverable_test.rb +141 -0
  92. data/test/integration/registerable_test.rb +130 -0
  93. data/test/integration/rememberable_test.rb +63 -0
  94. data/test/integration/timeoutable_test.rb +68 -0
  95. data/test/integration/token_authenticatable_test.rb +55 -0
  96. data/test/integration/trackable_test.rb +64 -0
  97. data/test/mailers/confirmation_instructions_test.rb +80 -0
  98. data/test/mailers/reset_password_instructions_test.rb +68 -0
  99. data/test/mailers/unlock_instructions_test.rb +62 -0
  100. data/test/mapping_test.rb +153 -0
  101. data/test/models/authenticatable_test.rb +180 -0
  102. data/test/models/confirmable_test.rb +228 -0
  103. data/test/models/lockable_test.rb +202 -0
  104. data/test/models/recoverable_test.rb +138 -0
  105. data/test/models/rememberable_test.rb +135 -0
  106. data/test/models/timeoutable_test.rb +28 -0
  107. data/test/models/token_authenticatable_test.rb +51 -0
  108. data/test/models/trackable_test.rb +5 -0
  109. data/test/models/validatable_test.rb +106 -0
  110. data/test/models_test.rb +56 -0
  111. data/test/orm/active_record.rb +31 -0
  112. data/test/orm/mongo_mapper.rb +20 -0
  113. data/test/orm/mongoid.rb +22 -0
  114. data/test/rails_app/app/active_record/admin.rb +7 -0
  115. data/test/rails_app/app/active_record/user.rb +7 -0
  116. data/test/rails_app/app/controllers/admins_controller.rb +6 -0
  117. data/test/rails_app/app/controllers/application_controller.rb +10 -0
  118. data/test/rails_app/app/controllers/home_controller.rb +4 -0
  119. data/test/rails_app/app/controllers/users_controller.rb +16 -0
  120. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  121. data/test/rails_app/app/mongo_mapper/admin.rb +9 -0
  122. data/test/rails_app/app/mongo_mapper/user.rb +8 -0
  123. data/test/rails_app/app/mongoid/admin.rb +9 -0
  124. data/test/rails_app/app/mongoid/user.rb +8 -0
  125. data/test/rails_app/config/boot.rb +110 -0
  126. data/test/rails_app/config/environment.rb +42 -0
  127. data/test/rails_app/config/environments/development.rb +17 -0
  128. data/test/rails_app/config/environments/production.rb +28 -0
  129. data/test/rails_app/config/environments/test.rb +28 -0
  130. data/test/rails_app/config/initializers/devise.rb +79 -0
  131. data/test/rails_app/config/initializers/inflections.rb +2 -0
  132. data/test/rails_app/config/initializers/new_rails_defaults.rb +24 -0
  133. data/test/rails_app/config/initializers/session_store.rb +15 -0
  134. data/test/rails_app/config/routes.rb +21 -0
  135. data/test/routes_test.rb +110 -0
  136. data/test/support/assertions_helper.rb +37 -0
  137. data/test/support/integration_tests_helper.rb +71 -0
  138. data/test/support/test_silencer.rb +5 -0
  139. data/test/support/tests_helper.rb +39 -0
  140. data/test/test_helper.rb +21 -0
  141. data/test/test_helpers_test.rb +57 -0
  142. 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,8 @@
1
+ module Devise
2
+ module Models
3
+ # Registerable is responsible for everything related to registering a new
4
+ # resource (ie user sign up).
5
+ module Registerable
6
+ end
7
+ end
8
+ 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)