devise 1.0.10 → 1.1.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.
Files changed (176) hide show
  1. data/CHANGELOG.rdoc +62 -10
  2. data/Gemfile +23 -0
  3. data/Gemfile.lock +118 -0
  4. data/README.rdoc +116 -77
  5. data/Rakefile +4 -2
  6. data/TODO +3 -2
  7. data/app/controllers/{confirmations_controller.rb → devise/confirmations_controller.rb} +1 -1
  8. data/app/controllers/{passwords_controller.rb → devise/passwords_controller.rb} +1 -1
  9. data/app/controllers/{registrations_controller.rb → devise/registrations_controller.rb} +12 -8
  10. data/app/controllers/devise/sessions_controller.rb +23 -0
  11. data/app/controllers/{unlocks_controller.rb → devise/unlocks_controller.rb} +1 -8
  12. data/app/helpers/devise_helper.rb +17 -0
  13. data/app/mailers/devise/mailer.rb +71 -0
  14. data/app/views/devise/confirmations/new.html.erb +12 -0
  15. data/app/views/devise/passwords/edit.html.erb +16 -0
  16. data/app/views/devise/passwords/new.html.erb +12 -0
  17. data/app/views/devise/registrations/edit.html.erb +25 -0
  18. data/app/views/devise/registrations/new.html.erb +18 -0
  19. data/app/views/devise/sessions/new.html.erb +17 -0
  20. data/app/views/devise/shared/_links.erb +19 -0
  21. data/app/views/devise/unlocks/new.html.erb +12 -0
  22. data/{lib/devise → config}/locales/en.yml +16 -12
  23. data/lib/devise/controllers/helpers.rb +57 -52
  24. data/lib/devise/controllers/internal_helpers.rb +19 -50
  25. data/lib/devise/controllers/scoped_views.rb +35 -0
  26. data/lib/devise/controllers/url_helpers.rb +1 -1
  27. data/lib/devise/encryptors/authlogic_sha512.rb +0 -2
  28. data/lib/devise/encryptors/base.rb +1 -1
  29. data/lib/devise/encryptors/bcrypt.rb +2 -4
  30. data/lib/devise/encryptors/clearance_sha1.rb +0 -2
  31. data/lib/devise/encryptors/sha1.rb +6 -8
  32. data/lib/devise/encryptors/sha512.rb +6 -8
  33. data/lib/devise/failure_app.rb +76 -39
  34. data/lib/devise/hooks/activatable.rb +6 -10
  35. data/lib/devise/hooks/forgetable.rb +11 -0
  36. data/lib/devise/hooks/rememberable.rb +40 -30
  37. data/lib/devise/hooks/timeoutable.rb +7 -3
  38. data/lib/devise/hooks/trackable.rb +5 -14
  39. data/lib/devise/mapping.rb +35 -62
  40. data/lib/devise/models/authenticatable.rb +126 -0
  41. data/lib/devise/models/confirmable.rb +19 -22
  42. data/lib/devise/models/database_authenticatable.rb +26 -60
  43. data/lib/devise/models/lockable.rb +43 -28
  44. data/lib/devise/models/recoverable.rb +11 -10
  45. data/lib/devise/models/rememberable.rb +56 -26
  46. data/lib/devise/models/timeoutable.rb +1 -3
  47. data/lib/devise/models/token_authenticatable.rb +14 -43
  48. data/lib/devise/models/trackable.rb +14 -0
  49. data/lib/devise/models/validatable.rb +16 -2
  50. data/lib/devise/models.rb +16 -53
  51. data/lib/devise/modules.rb +23 -0
  52. data/lib/devise/orm/active_record.rb +10 -15
  53. data/lib/devise/orm/mongoid.rb +29 -0
  54. data/lib/devise/path_checker.rb +18 -0
  55. data/lib/devise/rails/routes.rb +232 -117
  56. data/lib/devise/rails/warden_compat.rb +18 -39
  57. data/lib/devise/rails.rb +64 -9
  58. data/lib/devise/schema.rb +47 -23
  59. data/lib/devise/strategies/authenticatable.rb +123 -0
  60. data/lib/devise/strategies/base.rb +2 -3
  61. data/lib/devise/strategies/database_authenticatable.rb +7 -22
  62. data/lib/devise/strategies/rememberable.rb +21 -7
  63. data/lib/devise/strategies/token_authenticatable.rb +31 -19
  64. data/lib/devise/test_helpers.rb +6 -6
  65. data/lib/devise/version.rb +1 -1
  66. data/lib/devise.rb +174 -157
  67. data/lib/generators/active_record/devise_generator.rb +28 -0
  68. data/{generators/devise → lib/generators/active_record}/templates/migration.rb +9 -3
  69. data/lib/generators/devise/devise_generator.rb +17 -0
  70. data/lib/generators/devise/install_generator.rb +24 -0
  71. data/lib/generators/devise/orm_helpers.rb +23 -0
  72. data/{generators/devise_install → lib/generators/devise}/templates/README +9 -7
  73. data/lib/generators/devise/templates/devise.rb +142 -0
  74. data/lib/generators/devise/views_generator.rb +63 -0
  75. data/lib/generators/devise_install_generator.rb +4 -0
  76. data/lib/generators/devise_views_generator.rb +4 -0
  77. data/lib/generators/mongoid/devise_generator.rb +17 -0
  78. data/test/controllers/helpers_test.rb +48 -19
  79. data/test/controllers/internal_helpers_test.rb +12 -16
  80. data/test/controllers/url_helpers_test.rb +21 -10
  81. data/test/devise_test.rb +16 -25
  82. data/test/encryptors_test.rb +2 -3
  83. data/test/failure_app_test.rb +106 -27
  84. data/test/integration/authenticatable_test.rb +138 -126
  85. data/test/integration/confirmable_test.rb +22 -15
  86. data/test/integration/database_authenticatable_test.rb +38 -0
  87. data/test/integration/http_authenticatable_test.rb +9 -12
  88. data/test/integration/lockable_test.rb +22 -15
  89. data/test/integration/recoverable_test.rb +6 -6
  90. data/test/integration/registerable_test.rb +42 -33
  91. data/test/integration/rememberable_test.rb +84 -22
  92. data/test/integration/timeoutable_test.rb +16 -4
  93. data/test/integration/token_authenticatable_test.rb +45 -12
  94. data/test/integration/trackable_test.rb +1 -1
  95. data/test/mailers/confirmation_instructions_test.rb +11 -17
  96. data/test/mailers/reset_password_instructions_test.rb +7 -7
  97. data/test/mailers/unlock_instructions_test.rb +7 -7
  98. data/test/mapping_test.rb +22 -95
  99. data/test/models/confirmable_test.rb +12 -19
  100. data/test/models/{authenticatable_test.rb → database_authenticatable_test.rb} +24 -56
  101. data/test/models/lockable_test.rb +32 -46
  102. data/test/models/recoverable_test.rb +7 -7
  103. data/test/models/rememberable_test.rb +118 -35
  104. data/test/models/timeoutable_test.rb +1 -1
  105. data/test/models/token_authenticatable_test.rb +5 -19
  106. data/test/models/trackable_test.rb +1 -1
  107. data/test/models/validatable_test.rb +20 -27
  108. data/test/models_test.rb +12 -5
  109. data/test/orm/active_record.rb +1 -23
  110. data/test/orm/mongoid.rb +10 -0
  111. data/test/rails_app/app/active_record/admin.rb +1 -5
  112. data/test/rails_app/app/active_record/shim.rb +2 -0
  113. data/test/rails_app/app/active_record/user.rb +3 -3
  114. data/test/rails_app/app/controllers/application_controller.rb +2 -5
  115. data/test/rails_app/app/controllers/home_controller.rb +3 -0
  116. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  117. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  118. data/test/rails_app/app/controllers/sessions_controller.rb +6 -0
  119. data/test/rails_app/app/controllers/users_controller.rb +7 -5
  120. data/test/rails_app/app/mongoid/admin.rb +6 -0
  121. data/test/rails_app/app/mongoid/shim.rb +16 -0
  122. data/test/rails_app/app/mongoid/user.rb +10 -0
  123. data/test/rails_app/config/application.rb +35 -0
  124. data/test/rails_app/config/boot.rb +10 -107
  125. data/test/rails_app/config/environment.rb +4 -41
  126. data/test/rails_app/config/environments/development.rb +15 -13
  127. data/test/rails_app/config/environments/production.rb +25 -20
  128. data/test/rails_app/config/environments/test.rb +33 -28
  129. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  130. data/test/rails_app/config/initializers/devise.rb +95 -38
  131. data/test/rails_app/config/initializers/secret_token.rb +2 -0
  132. data/test/rails_app/config/routes.rb +47 -25
  133. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +27 -0
  134. data/test/rails_app/db/schema.rb +86 -0
  135. data/test/routes_test.rb +62 -47
  136. data/test/support/{assertions_helper.rb → assertions.rb} +2 -15
  137. data/test/support/{tests_helper.rb → helpers.rb} +18 -3
  138. data/test/support/{integration_tests_helper.rb → integration.rb} +24 -7
  139. data/test/support/webrat/integrations/rails.rb +32 -0
  140. data/test/test_helper.rb +11 -11
  141. data/test/test_helpers_test.rb +30 -15
  142. metadata +105 -64
  143. data/app/controllers/sessions_controller.rb +0 -42
  144. data/app/models/devise_mailer.rb +0 -68
  145. data/app/views/confirmations/new.html.erb +0 -12
  146. data/app/views/passwords/edit.html.erb +0 -16
  147. data/app/views/passwords/new.html.erb +0 -12
  148. data/app/views/registrations/edit.html.erb +0 -25
  149. data/app/views/registrations/new.html.erb +0 -17
  150. data/app/views/sessions/new.html.erb +0 -17
  151. data/app/views/shared/_devise_links.erb +0 -19
  152. data/app/views/unlocks/new.html.erb +0 -12
  153. data/generators/devise/USAGE +0 -5
  154. data/generators/devise/devise_generator.rb +0 -15
  155. data/generators/devise/lib/route_devise.rb +0 -32
  156. data/generators/devise/templates/model.rb +0 -9
  157. data/generators/devise_install/USAGE +0 -3
  158. data/generators/devise_install/devise_install_generator.rb +0 -15
  159. data/generators/devise_install/templates/devise.rb +0 -105
  160. data/generators/devise_views/USAGE +0 -3
  161. data/generators/devise_views/devise_views_generator.rb +0 -21
  162. data/lib/devise/models/activatable.rb +0 -16
  163. data/lib/devise/models/http_authenticatable.rb +0 -23
  164. data/lib/devise/orm/data_mapper.rb +0 -83
  165. data/lib/devise/orm/mongo_mapper.rb +0 -52
  166. data/lib/devise/strategies/http_authenticatable.rb +0 -59
  167. data/rails/init.rb +0 -2
  168. data/test/integration/rack_middleware_test.rb +0 -47
  169. data/test/orm/mongo_mapper.rb +0 -20
  170. data/test/rails_app/app/mongo_mapper/admin.rb +0 -13
  171. data/test/rails_app/app/mongo_mapper/user.rb +0 -14
  172. data/test/rails_app/config/initializers/new_rails_defaults.rb +0 -24
  173. data/test/rails_app/config/initializers/session_store.rb +0 -15
  174. /data/app/views/{devise_mailer → devise/mailer}/confirmation_instructions.html.erb +0 -0
  175. /data/app/views/{devise_mailer → devise/mailer}/reset_password_instructions.html.erb +0 -0
  176. /data/app/views/{devise_mailer → devise/mailer}/unlock_instructions.html.erb +0 -0
data/lib/devise.rb CHANGED
@@ -1,12 +1,16 @@
1
+ require 'active_support/core_ext/numeric/time'
2
+ require 'active_support/dependencies'
3
+
1
4
  module Devise
2
5
  autoload :FailureApp, 'devise/failure_app'
3
- autoload :Models, 'devise/models'
6
+ autoload :PathChecker, 'devise/path_checker'
4
7
  autoload :Schema, 'devise/schema'
5
8
  autoload :TestHelpers, 'devise/test_helpers'
6
9
 
7
10
  module Controllers
8
11
  autoload :Helpers, 'devise/controllers/helpers'
9
12
  autoload :InternalHelpers, 'devise/controllers/internal_helpers'
13
+ autoload :ScopedViews, 'devise/controllers/scoped_views'
10
14
  autoload :UrlHelpers, 'devise/controllers/url_helpers'
11
15
  end
12
16
 
@@ -20,45 +24,21 @@ module Devise
20
24
  autoload :Sha1, 'devise/encryptors/sha1'
21
25
  end
22
26
 
23
- module Orm
24
- autoload :ActiveRecord, 'devise/orm/active_record'
25
- autoload :DataMapper, 'devise/orm/data_mapper'
26
- autoload :MongoMapper, 'devise/orm/mongo_mapper'
27
+ module Strategies
28
+ autoload :Base, 'devise/strategies/base'
29
+ autoload :Authenticatable, 'devise/strategies/authenticatable'
27
30
  end
28
31
 
29
- ALL = []
30
-
31
- # Authentication ones first
32
- ALL.push :database_authenticatable, :http_authenticatable, :token_authenticatable, :rememberable
33
-
34
- # Misc after
35
- ALL.push :recoverable, :registerable, :validatable
36
-
37
- # The ones which can sign out after
38
- ALL.push :activatable, :confirmable, :lockable, :timeoutable
39
-
40
- # Stats for last, so we make sure the user is really signed in
41
- ALL.push :trackable
42
-
43
- # Maps controller names to devise modules.
44
- CONTROLLERS = {
45
- :sessions => [:database_authenticatable, :token_authenticatable],
46
- :passwords => [:recoverable],
47
- :confirmations => [:confirmable],
48
- :registrations => [:registerable],
49
- :unlocks => [:lockable]
50
- }
51
-
52
- # Routes for generating url helpers.
53
- ROUTES = [:session, :password, :confirmation, :registration, :unlock]
54
-
55
- STRATEGIES = [:rememberable, :http_authenticatable, :token_authenticatable, :database_authenticatable]
32
+ # Constants which holds devise configuration for extensions. Those should
33
+ # not be modified by the "end user".
34
+ ALL = []
35
+ CONTROLLERS = ActiveSupport::OrderedHash.new
36
+ ROUTES = ActiveSupport::OrderedHash.new
37
+ STRATEGIES = ActiveSupport::OrderedHash.new
56
38
 
39
+ # True values used to check params
57
40
  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
58
41
 
59
- # Maps the messages types that are used in flash message.
60
- FLASH_MESSAGES = [:unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked]
61
-
62
42
  # Declare encryptors length which are used in migrations.
63
43
  ENCRYPTORS_LENGTH = {
64
44
  :sha1 => 40,
@@ -69,8 +49,9 @@ module Devise
69
49
  :bcrypt => 60
70
50
  }
71
51
 
72
- # Email regex used to validate email formats. Adapted from authlogic.
73
- EMAIL_REGEX = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
52
+ # Custom domain for cookies. Not set by default
53
+ mattr_accessor :cookie_domain
54
+ @@cookie_domain = false
74
55
 
75
56
  # Used to encrypt password. Please generate one with rake secret.
76
57
  mattr_accessor :pepper
@@ -84,10 +65,42 @@ module Devise
84
65
  mattr_accessor :authentication_keys
85
66
  @@authentication_keys = [ :email ]
86
67
 
87
- # Time interval where the remember me token is valid.
68
+ # If http authentication is enabled by default.
69
+ mattr_accessor :http_authenticatable
70
+ @@http_authenticatable = true
71
+
72
+ # If http authentication is used for ajax requests. True by default.
73
+ mattr_accessor :http_authenticatable_on_xhr
74
+ @@http_authenticatable_on_xhr = true
75
+
76
+ # If params authenticatable is enabled by default.
77
+ mattr_accessor :params_authenticatable
78
+ @@params_authenticatable = true
79
+
80
+ # The realm used in Http Basic Authentication.
81
+ mattr_accessor :http_authentication_realm
82
+ @@http_authentication_realm = "Application"
83
+
84
+ # Email regex used to validate email formats. Adapted from authlogic.
85
+ mattr_accessor :email_regexp
86
+ @@email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
87
+
88
+ # Range validation for password length
89
+ mattr_accessor :password_length
90
+ @@password_length = 6..20
91
+
92
+ # The time the user will be remembered without asking for credentials again.
88
93
  mattr_accessor :remember_for
89
94
  @@remember_for = 2.weeks
90
95
 
96
+ # If true, a valid remember token can be re-used between multiple browsers.
97
+ mattr_accessor :remember_across_browsers
98
+ @@remember_across_browsers = true
99
+
100
+ # If true, extends the user's remember period when remembered via cookie.
101
+ mattr_accessor :extend_remember_period
102
+ @@extend_remember_period = false
103
+
91
104
  # Time interval you can access your account before confirming your account.
92
105
  mattr_accessor :confirm_within
93
106
  @@confirm_within = 0.days
@@ -98,22 +111,14 @@ module Devise
98
111
 
99
112
  # Used to define the password encryption algorithm.
100
113
  mattr_accessor :encryptor
101
- @@encryptor = :sha1
114
+ @@encryptor = nil
102
115
 
103
116
  # Store scopes mappings.
104
117
  mattr_accessor :mappings
105
118
  @@mappings = ActiveSupport::OrderedHash.new
106
119
 
107
- # Stores the chosen ORM.
108
- mattr_accessor :orm
109
- @@orm = :active_record
110
-
111
- # TODO Remove
112
- mattr_accessor :all
113
- @@all = []
114
-
115
120
  # Tells if devise should apply the schema in ORMs where devise declaration
116
- # and schema belongs to the same class (as Datamapper and MongoMapper).
121
+ # and schema belongs to the same class (as Datamapper and Mongoid).
117
122
  mattr_accessor :apply_schema
118
123
  @@apply_schema = true
119
124
 
@@ -122,23 +127,24 @@ module Devise
122
127
  mattr_accessor :scoped_views
123
128
  @@scoped_views = false
124
129
 
125
- # Number of authentication tries before locking an account
126
- mattr_accessor :maximum_attempts
127
- @@maximum_attempts = 20
130
+ # Defines which strategy can be used to lock an account.
131
+ # Values: :failed_attempts, :none
132
+ mattr_accessor :lock_strategy
133
+ @@lock_strategy = :failed_attempts
128
134
 
129
135
  # Defines which strategy can be used to unlock an account.
130
136
  # Values: :email, :time, :both
131
137
  mattr_accessor :unlock_strategy
132
138
  @@unlock_strategy = :both
133
139
 
140
+ # Number of authentication tries before locking an account
141
+ mattr_accessor :maximum_attempts
142
+ @@maximum_attempts = 20
143
+
134
144
  # Time interval to unlock the account if :time is defined as unlock_strategy.
135
145
  mattr_accessor :unlock_in
136
146
  @@unlock_in = 1.hour
137
147
 
138
- # Tell when to use the default scope, if one cannot be found from routes.
139
- mattr_accessor :use_default_scope
140
- @@use_default_scope = false
141
-
142
148
  # The default scope which is used by warden.
143
149
  mattr_accessor :default_scope
144
150
  @@default_scope = nil
@@ -147,131 +153,142 @@ module Devise
147
153
  mattr_accessor :mailer_sender
148
154
  @@mailer_sender = nil
149
155
 
150
- # Content Type of Devise e-mails.
151
- mattr_accessor :mailer_content_type
152
- @@mailer_content_type = 'text/html'
153
-
154
156
  # Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
155
157
  mattr_accessor :token_authentication_key
156
158
  @@token_authentication_key = :auth_token
157
159
 
158
- # The realm used in Http Basic Authentication
159
- mattr_accessor :http_authentication_realm
160
- @@http_authentication_realm = "Application"
160
+ # Which formats should be treated as navigational.
161
+ mattr_accessor :navigational_formats
162
+ @@navigational_formats = [:html]
161
163
 
162
- class << self
163
- # Default way to setup Devise. Run script/generate devise_install to create
164
- # a fresh initializer with all configuration values.
165
- def setup
166
- yield self
167
- end
164
+ # Private methods to interface with Warden.
165
+ mattr_accessor :warden_config
166
+ @@warden_config = nil
167
+ @@warden_config_block = nil
168
168
 
169
- # Sets warden configuration using a block that will be invoked on warden
170
- # initialization.
171
- #
172
- # Devise.initialize do |config|
173
- # config.confirm_within = 2.days
174
- #
175
- # config.warden do |manager|
176
- # # Configure warden to use other strategies, like oauth.
177
- # manager.oauth(:twitter)
178
- # end
179
- # end
180
- def warden(&block)
181
- @warden_config = block
182
- end
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
183
172
 
184
- # Configure default url options to be used within Devise and ActionController.
185
- def default_url_options(&block)
186
- who = Devise::Mapping.respond_to?(:singleton_class) ?
187
- Devise::Mapping.singleton_class : Devise::Mapping.metaclass
188
- who.send :define_method, :default_url_options, &block
189
- end
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
190
179
 
191
- # A method used internally to setup warden manager from the Rails initialize
192
- # block.
193
- def configure_warden(config) #:nodoc:
194
- config.default_strategies *Devise::STRATEGIES
195
- config.failure_app = Devise::FailureApp
196
- config.silence_missing_strategies!
197
- config.default_scope = Devise.default_scope
180
+ # Default way to setup Devise. Run rails generate devise_install to create
181
+ # a fresh initializer with all configuration values.
182
+ def self.setup
183
+ yield self
184
+ end
198
185
 
199
- # If the user provided a warden hook, call it now.
200
- @warden_config.try :call, config
201
- end
186
+ # Get the mailer class from the mailer reference object.
187
+ def self.mailer
188
+ @@mailer_ref.get
189
+ end
202
190
 
203
- # The class of the configured ORM
204
- def orm_class
205
- Devise::Orm.const_get(@@orm.to_s.camelize.to_sym)
206
- end
191
+ # Set the mailer reference object to access the mailer.
192
+ def self.mailer=(class_name)
193
+ @@mailer_ref = ActiveSupport::Dependencies.ref(class_name)
194
+ end
195
+ self.mailer = "Devise::Mailer"
196
+
197
+ # Small method that adds a mapping to Devise.
198
+ def self.add_mapping(resource, options)
199
+ mapping = Devise::Mapping.new(resource, options)
200
+ self.mappings[mapping.name] = mapping
201
+ self.default_scope ||= mapping.name
202
+ mapping
203
+ end
207
204
 
208
- # Generate a friendly string randomically to be used as token.
209
- def friendly_token
210
- ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
205
+ # Make Devise aware of an 3rd party Devise-module. For convenience.
206
+ #
207
+ # == Options:
208
+ #
209
+ # +model+ - String representing the load path to a custom *model* for this module (to autoload.)
210
+ # +controller+ - Symbol representing the name of an exisiting or custom *controller* for this module.
211
+ # +route+ - Symbol representing the named *route* helper for this module.
212
+ # +flash+ - Symbol representing the *flash messages* used by this helper.
213
+ # +strategy+ - Symbol representing if this module got a custom *strategy*.
214
+ #
215
+ # All values, except :model, accept also a boolean and will have the same name as the given module
216
+ # name.
217
+ #
218
+ # == Examples:
219
+ #
220
+ # Devise.add_module(:party_module)
221
+ # Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
222
+ # Devise.add_module(:party_module, :model => 'party_module/model')
223
+ #
224
+ def self.add_module(module_name, options = {})
225
+ ALL << module_name
226
+ options.assert_valid_keys(:strategy, :model, :controller, :route)
227
+
228
+ config = {
229
+ :strategy => STRATEGIES,
230
+ :route => ROUTES,
231
+ :controller => CONTROLLERS
232
+ }
233
+
234
+ config.each do |key, value|
235
+ next unless options[key]
236
+ name = (options[key] == true ? module_name : options[key])
237
+
238
+ if value.is_a?(Hash)
239
+ value[module_name] = name
240
+ else
241
+ value << name unless value.include?(name)
242
+ end
211
243
  end
212
244
 
213
- # constant-time comparison algorithm to prevent timing attacks
214
- def secure_compare(a, b)
215
- return false unless a.present? && b.present?
216
- return false unless a.bytesize == b.bytesize
217
- l = a.unpack "C#{a.bytesize}"
218
-
219
- res = 0
220
- b.each_byte { |byte| res |= byte ^ l.shift }
221
- res == 0
245
+ if options[:model]
246
+ model_path = (options[:model] == true ? "devise/models/#{module_name}" : options[:model])
247
+ Devise::Models.send(:autoload, module_name.to_s.camelize.to_sym, model_path)
222
248
  end
223
249
 
224
- # Make Devise aware of an 3rd party Devise-module. For convenience.
225
- #
226
- # == Options:
227
- #
228
- # +strategy+ - Boolean value representing if this module got a custom *strategy*.
229
- # Default is +false+. Note: Devise will auto-detect this in such case if this is true.
230
- # +model+ - String representing a load path to a custom *model* for this module (to autoload).
231
- # Default is +nil+ (i.e. +false+).
232
- # +controller+ - Symbol representing a name of an exisiting or custom *controller* for this module.
233
- # Default is +nil+ (i.e. +false+).
234
- # +route+ - Symbol representing the name of a *route* related to this module which a set of
235
- # route view helpers should be created for.
236
- # Default is +nil+ (i.e. +false+).
237
- #
238
- # == Examples:
239
- #
240
- # Devise.add_module(:party_module)
241
- # Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
242
- # Devise.add_module(:party_module, :model => 'party_module/model')
243
- #
244
- def add_module(module_name, options = {})
245
- Devise::ALL << module_name unless Devise::ALL.include?(module_name)
246
- Devise::STRATEGIES.unshift module_name if options[:strategy] && !Devise::STRATEGIES.include?(module_name)
247
-
248
- if options[:controller]
249
- controller = options[:controller].to_sym
250
- Devise::CONTROLLERS[controller] ||= []
251
- Devise::CONTROLLERS[controller].unshift module_name unless Devise::CONTROLLERS[controller].include?(module_name)
252
- end
250
+ Devise::Mapping.add_module module_name
251
+ end
253
252
 
254
- if options[:route]
255
- Devise::ROUTES.unshift options[:route] unless Devise::ROUTES.include?(options[:route])
256
- end
253
+ # Sets warden configuration using a block that will be invoked on warden
254
+ # initialization.
255
+ #
256
+ # Devise.initialize do |config|
257
+ # config.confirm_within = 2.days
258
+ #
259
+ # config.warden do |manager|
260
+ # # Configure warden to use other strategies, like oauth.
261
+ # manager.oauth(:twitter)
262
+ # end
263
+ # end
264
+ def self.warden(&block)
265
+ @@warden_config_block = block
266
+ end
257
267
 
258
- if options[:model]
259
- Devise::Models.module_eval do
260
- autoload :"#{module_name.to_s.classify}", options[:model]
261
- end
268
+ # A method used internally to setup warden manager from the Rails initialize
269
+ # block.
270
+ def self.configure_warden! #:nodoc:
271
+ @@warden_configured ||= begin
272
+ warden_config.failure_app = Devise::FailureApp
273
+ warden_config.default_scope = Devise.default_scope
274
+
275
+ Devise.mappings.each_value do |mapping|
276
+ warden_config.scope_defaults mapping.name, :strategies => mapping.strategies
262
277
  end
263
278
 
264
- Devise::Mapping.register module_name
279
+ @@warden_config_block.try :call, Devise.warden_config
280
+ true
265
281
  end
266
282
  end
267
- end
268
283
 
269
- begin
270
- require 'warden'
271
- rescue
272
- gem 'warden'
273
- require 'warden'
284
+ # Generate a friendly string randomically to be used as token.
285
+ def self.friendly_token
286
+ ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
287
+ end
274
288
  end
275
289
 
290
+ require 'warden'
276
291
  require 'devise/mapping'
292
+ require 'devise/models'
293
+ require 'devise/modules'
277
294
  require 'devise/rails'
@@ -0,0 +1,28 @@
1
+ require 'rails/generators/active_record'
2
+ require 'generators/devise/orm_helpers'
3
+
4
+ module ActiveRecord
5
+ module Generators
6
+ class DeviseGenerator < ActiveRecord::Generators::Base
7
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
8
+
9
+ include Devise::Generators::OrmHelpers
10
+ source_root File.expand_path("../templates", __FILE__)
11
+
12
+ def generate_model
13
+ invoke "active_record:model", [name], :migration => false unless model_exists?
14
+ end
15
+
16
+ def copy_devise_migration
17
+ migration_template "migration.rb", "db/migrate/devise_create_#{table_name}"
18
+ end
19
+
20
+ def inject_devise_content
21
+ inject_into_class model_path, class_name, model_contents + <<-CONTENT
22
+ # Setup accessible (or protected) attributes for your model
23
+ attr_accessible :email, :password, :password_confirmation, :remember_me
24
+ CONTENT
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,18 +2,24 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
2
2
  def self.up
3
3
  create_table(:<%= table_name %>) do |t|
4
4
  t.database_authenticatable :null => false
5
- t.confirmable
6
5
  t.recoverable
7
6
  t.rememberable
8
7
  t.trackable
9
- # t.lockable
8
+
9
+ # t.confirmable
10
+ # t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
11
+ # t.token_authenticatable
12
+
13
+ <% for attribute in attributes -%>
14
+ t.<%= attribute.type %> :<%= attribute.name %>
15
+ <% end -%>
10
16
 
11
17
  t.timestamps
12
18
  end
13
19
 
14
20
  add_index :<%= table_name %>, :email, :unique => true
15
- add_index :<%= table_name %>, :confirmation_token, :unique => true
16
21
  add_index :<%= table_name %>, :reset_password_token, :unique => true
22
+ # add_index :<%= table_name %>, :confirmation_token, :unique => true
17
23
  # add_index :<%= table_name %>, :unlock_token, :unique => true
18
24
  end
19
25
 
@@ -0,0 +1,17 @@
1
+ module Devise
2
+ module Generators
3
+ class DeviseGenerator < Rails::Generators::NamedBase
4
+ namespace "devise"
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+ desc "Generates a model with the given NAME (if one does not exist) with devise " <<
8
+ "configuration plus a migration file and devise routes."
9
+
10
+ hook_for :orm
11
+
12
+ def add_devise_routes
13
+ route "devise_for :#{table_name}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ require 'active_support/secure_random'
2
+
3
+ module Devise
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ desc "Creates a Devise initializer and copy locale files to your application."
9
+ class_option :orm
10
+
11
+ def copy_initializer
12
+ template "devise.rb", "config/initializers/devise.rb"
13
+ end
14
+
15
+ def copy_locale
16
+ copy_file "../../../../config/locales/en.yml", "config/locales/devise.en.yml"
17
+ end
18
+
19
+ def show_readme
20
+ readme "README"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Devise
2
+ module Generators
3
+ module OrmHelpers
4
+ def model_contents
5
+ <<-CONTENT
6
+ # Include default devise modules. Others available are:
7
+ # :token_authenticatable, :confirmable, :lockable and :timeoutable
8
+ devise :database_authenticatable, :registerable,
9
+ :recoverable, :rememberable, :trackable, :validatable
10
+
11
+ CONTENT
12
+ end
13
+
14
+ def model_exists?
15
+ File.exists?(File.join(destination_root, model_path))
16
+ end
17
+
18
+ def model_path
19
+ @model_path ||= File.join("app", "models", "#{file_path}.rb")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,4 @@
1
+
1
2
  ===============================================================================
2
3
 
3
4
  Some setup you must do manually if you haven't yet:
@@ -7,17 +8,18 @@ Some setup you must do manually if you haven't yet:
7
8
 
8
9
  config.action_mailer.default_url_options = { :host => 'localhost:3000' }
9
10
 
10
- This is a required Rails configuration. In production is must be the
11
+ This is a required Rails configuration. In production it must be the
11
12
  actual host of your application
12
13
 
13
- 2. Ensure you have defined root_url to *something* in your config/routes.rb:
14
+ 2. Ensure you have defined root_url to *something* in your config/routes.rb.
15
+ For example:
14
16
 
15
- map.root :controller => 'home'
17
+ root :to => "home#index"
16
18
 
17
- 3. Ensure you have a default layout in app/views/layouts and it shows
18
- flash messages. For example:
19
+ 3. Ensure you have flash messages in app/views/layouts/application.html.erb.
20
+ For example:
19
21
 
20
- <p class="notice"><%= flash[:notice] %></p>
21
- <p class="alert"><%= flash[:alert] %></p>
22
+ <p class="notice"><%= notice %></p>
23
+ <p class="alert"><%= alert %></p>
22
24
 
23
25
  ===============================================================================