devise-jdguyot 1.2.rc

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 (185) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG.rdoc +532 -0
  3. data/Gemfile +29 -0
  4. data/Gemfile.lock +152 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +353 -0
  7. data/Rakefile +36 -0
  8. data/TODO +4 -0
  9. data/app/controllers/devise/confirmations_controller.rb +33 -0
  10. data/app/controllers/devise/omniauth_callbacks_controller.rb +26 -0
  11. data/app/controllers/devise/passwords_controller.rb +41 -0
  12. data/app/controllers/devise/registrations_controller.rb +110 -0
  13. data/app/controllers/devise/sessions_controller.rb +25 -0
  14. data/app/controllers/devise/unlocks_controller.rb +34 -0
  15. data/app/helpers/devise_helper.rb +19 -0
  16. data/app/mailers/devise/mailer.rb +88 -0
  17. data/app/views/devise/confirmations/new.html.erb +12 -0
  18. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  19. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  20. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  21. data/app/views/devise/passwords/edit.html.erb +16 -0
  22. data/app/views/devise/passwords/new.html.erb +12 -0
  23. data/app/views/devise/registrations/edit.html.erb +25 -0
  24. data/app/views/devise/registrations/new.html.erb +18 -0
  25. data/app/views/devise/sessions/new.html.erb +17 -0
  26. data/app/views/devise/shared/_links.erb +25 -0
  27. data/app/views/devise/unlocks/new.html.erb +12 -0
  28. data/config/locales/en.yml +46 -0
  29. data/devise.gemspec +25 -0
  30. data/lib/devise/controllers/helpers.rb +227 -0
  31. data/lib/devise/controllers/internal_helpers.rb +119 -0
  32. data/lib/devise/controllers/scoped_views.rb +33 -0
  33. data/lib/devise/controllers/url_helpers.rb +39 -0
  34. data/lib/devise/encryptors/authlogic_sha512.rb +19 -0
  35. data/lib/devise/encryptors/base.rb +20 -0
  36. data/lib/devise/encryptors/clearance_sha1.rb +17 -0
  37. data/lib/devise/encryptors/restful_authentication_sha1.rb +22 -0
  38. data/lib/devise/encryptors/sha1.rb +25 -0
  39. data/lib/devise/encryptors/sha512.rb +25 -0
  40. data/lib/devise/failure_app.rb +132 -0
  41. data/lib/devise/hooks/activatable.rb +11 -0
  42. data/lib/devise/hooks/forgetable.rb +12 -0
  43. data/lib/devise/hooks/rememberable.rb +48 -0
  44. data/lib/devise/hooks/timeoutable.rb +22 -0
  45. data/lib/devise/hooks/trackable.rb +9 -0
  46. data/lib/devise/mapping.rb +110 -0
  47. data/lib/devise/models/authenticatable.rb +146 -0
  48. data/lib/devise/models/confirmable.rb +160 -0
  49. data/lib/devise/models/database_authenticatable.rb +100 -0
  50. data/lib/devise/models/encryptable.rb +72 -0
  51. data/lib/devise/models/lockable.rb +169 -0
  52. data/lib/devise/models/omniauthable.rb +23 -0
  53. data/lib/devise/models/recoverable.rb +123 -0
  54. data/lib/devise/models/registerable.rb +21 -0
  55. data/lib/devise/models/rememberable.rb +130 -0
  56. data/lib/devise/models/timeoutable.rb +43 -0
  57. data/lib/devise/models/token_authenticatable.rb +72 -0
  58. data/lib/devise/models/trackable.rb +30 -0
  59. data/lib/devise/models/validatable.rb +65 -0
  60. data/lib/devise/models.rb +68 -0
  61. data/lib/devise/modules.rb +30 -0
  62. data/lib/devise/omniauth/config.rb +30 -0
  63. data/lib/devise/omniauth/test_helpers.rb +57 -0
  64. data/lib/devise/omniauth/url_helpers.rb +29 -0
  65. data/lib/devise/omniauth.rb +47 -0
  66. data/lib/devise/orm/active_record.rb +38 -0
  67. data/lib/devise/orm/mongoid.rb +31 -0
  68. data/lib/devise/path_checker.rb +18 -0
  69. data/lib/devise/rails/routes.rb +292 -0
  70. data/lib/devise/rails/warden_compat.rb +125 -0
  71. data/lib/devise/rails.rb +50 -0
  72. data/lib/devise/schema.rb +97 -0
  73. data/lib/devise/strategies/authenticatable.rb +150 -0
  74. data/lib/devise/strategies/base.rb +15 -0
  75. data/lib/devise/strategies/database_authenticatable.rb +21 -0
  76. data/lib/devise/strategies/rememberable.rb +51 -0
  77. data/lib/devise/strategies/token_authenticatable.rb +53 -0
  78. data/lib/devise/test_helpers.rb +100 -0
  79. data/lib/devise/version.rb +3 -0
  80. data/lib/devise.rb +381 -0
  81. data/lib/generators/active_record/devise_generator.rb +28 -0
  82. data/lib/generators/active_record/templates/migration.rb +31 -0
  83. data/lib/generators/devise/devise_generator.rb +17 -0
  84. data/lib/generators/devise/install_generator.rb +24 -0
  85. data/lib/generators/devise/orm_helpers.rb +23 -0
  86. data/lib/generators/devise/views_generator.rb +106 -0
  87. data/lib/generators/mongoid/devise_generator.rb +17 -0
  88. data/lib/generators/templates/README +25 -0
  89. data/lib/generators/templates/devise.rb +186 -0
  90. data/test/controllers/helpers_test.rb +237 -0
  91. data/test/controllers/internal_helpers_test.rb +72 -0
  92. data/test/controllers/url_helpers_test.rb +59 -0
  93. data/test/devise_test.rb +65 -0
  94. data/test/encryptors_test.rb +30 -0
  95. data/test/failure_app_test.rb +187 -0
  96. data/test/generators/active_record_generator_test.rb +24 -0
  97. data/test/generators/install_generator_test.rb +13 -0
  98. data/test/generators/mongoid_generator_test.rb +22 -0
  99. data/test/generators/views_generator_test.rb +35 -0
  100. data/test/indifferent_hash.rb +33 -0
  101. data/test/integration/authenticatable_test.rb +447 -0
  102. data/test/integration/confirmable_test.rb +104 -0
  103. data/test/integration/database_authenticatable_test.rb +60 -0
  104. data/test/integration/http_authenticatable_test.rb +74 -0
  105. data/test/integration/lockable_test.rb +109 -0
  106. data/test/integration/omniauthable_test.rb +107 -0
  107. data/test/integration/recoverable_test.rb +160 -0
  108. data/test/integration/registerable_test.rb +179 -0
  109. data/test/integration/rememberable_test.rb +180 -0
  110. data/test/integration/timeoutable_test.rb +89 -0
  111. data/test/integration/token_authenticatable_test.rb +99 -0
  112. data/test/integration/trackable_test.rb +64 -0
  113. data/test/mailers/confirmation_instructions_test.rb +84 -0
  114. data/test/mailers/reset_password_instructions_test.rb +72 -0
  115. data/test/mailers/unlock_instructions_test.rb +66 -0
  116. data/test/mapping_test.rb +119 -0
  117. data/test/models/confirmable_test.rb +221 -0
  118. data/test/models/database_authenticatable_test.rb +98 -0
  119. data/test/models/encryptable_test.rb +65 -0
  120. data/test/models/lockable_test.rb +204 -0
  121. data/test/models/recoverable_test.rb +190 -0
  122. data/test/models/rememberable_test.rb +279 -0
  123. data/test/models/timeoutable_test.rb +28 -0
  124. data/test/models/token_authenticatable_test.rb +37 -0
  125. data/test/models/trackable_test.rb +5 -0
  126. data/test/models/validatable_test.rb +99 -0
  127. data/test/models_test.rb +84 -0
  128. data/test/omniauth/url_helpers_test.rb +47 -0
  129. data/test/orm/active_record.rb +9 -0
  130. data/test/orm/mongoid.rb +11 -0
  131. data/test/rails_app/Rakefile +10 -0
  132. data/test/rails_app/app/active_record/admin.rb +6 -0
  133. data/test/rails_app/app/active_record/shim.rb +2 -0
  134. data/test/rails_app/app/active_record/user.rb +8 -0
  135. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  136. data/test/rails_app/app/controllers/admins_controller.rb +6 -0
  137. data/test/rails_app/app/controllers/application_controller.rb +8 -0
  138. data/test/rails_app/app/controllers/home_controller.rb +16 -0
  139. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  140. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  141. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +7 -0
  142. data/test/rails_app/app/controllers/users_controller.rb +18 -0
  143. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  144. data/test/rails_app/app/mongoid/admin.rb +9 -0
  145. data/test/rails_app/app/mongoid/shim.rb +29 -0
  146. data/test/rails_app/app/mongoid/user.rb +10 -0
  147. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  148. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  149. data/test/rails_app/app/views/home/index.html.erb +1 -0
  150. data/test/rails_app/app/views/home/private.html.erb +1 -0
  151. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  152. data/test/rails_app/app/views/users/index.html.erb +1 -0
  153. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  154. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  155. data/test/rails_app/config/application.rb +40 -0
  156. data/test/rails_app/config/boot.rb +13 -0
  157. data/test/rails_app/config/database.yml +18 -0
  158. data/test/rails_app/config/environment.rb +5 -0
  159. data/test/rails_app/config/environments/development.rb +19 -0
  160. data/test/rails_app/config/environments/production.rb +33 -0
  161. data/test/rails_app/config/environments/test.rb +33 -0
  162. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  163. data/test/rails_app/config/initializers/devise.rb +176 -0
  164. data/test/rails_app/config/initializers/inflections.rb +2 -0
  165. data/test/rails_app/config/initializers/secret_token.rb +2 -0
  166. data/test/rails_app/config/routes.rb +55 -0
  167. data/test/rails_app/config.ru +4 -0
  168. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +31 -0
  169. data/test/rails_app/db/schema.rb +52 -0
  170. data/test/rails_app/lib/shared_admin.rb +9 -0
  171. data/test/rails_app/lib/shared_user.rb +23 -0
  172. data/test/rails_app/public/404.html +26 -0
  173. data/test/rails_app/public/422.html +26 -0
  174. data/test/rails_app/public/500.html +26 -0
  175. data/test/rails_app/public/favicon.ico +0 -0
  176. data/test/rails_app/script/rails +10 -0
  177. data/test/routes_test.rb +179 -0
  178. data/test/support/assertions.rb +24 -0
  179. data/test/support/helpers.rb +60 -0
  180. data/test/support/integration.rb +88 -0
  181. data/test/support/locale/en.yml +4 -0
  182. data/test/support/webrat/integrations/rails.rb +24 -0
  183. data/test/test_helper.rb +29 -0
  184. data/test/test_helpers_test.rb +118 -0
  185. metadata +388 -0
@@ -0,0 +1,227 @@
1
+ module Devise
2
+ module Controllers
3
+ # Those helpers are convenience methods added to ApplicationController.
4
+ module Helpers
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper_method :warden, :signed_in?, :devise_controller?, :anybody_signed_in?
9
+ end
10
+
11
+ # Define authentication filters and accessor helpers based on mappings.
12
+ # These filters should be used inside the controllers as before_filters,
13
+ # so you can control the scope of the user who should be signed in to
14
+ # access that specific controller/action.
15
+ # Example:
16
+ #
17
+ # Roles:
18
+ # User
19
+ # Admin
20
+ #
21
+ # Generated methods:
22
+ # authenticate_user! # Signs user in or redirect
23
+ # authenticate_admin! # Signs admin in or redirect
24
+ # user_signed_in? # Checks whether there is an user signed in or not
25
+ # admin_signed_in? # Checks whether there is an admin signed in or not
26
+ # current_user # Current signed in user
27
+ # current_admin # Current signed in admin
28
+ # user_session # Session data available only to the user scope
29
+ # admin_session # Session data available only to the admin scope
30
+ #
31
+ # Use:
32
+ # before_filter :authenticate_user! # Tell devise to use :user map
33
+ # before_filter :authenticate_admin! # Tell devise to use :admin map
34
+ #
35
+ def self.define_helpers(mapping) #:nodoc:
36
+ mapping = mapping.name
37
+
38
+ class_eval <<-METHODS, __FILE__, __LINE__ + 1
39
+ def authenticate_#{mapping}!(force = false)
40
+ warden.authenticate!(:scope => :#{mapping}) if !devise_controller? || force
41
+ end
42
+
43
+ def #{mapping}_signed_in?
44
+ !!current_#{mapping}
45
+ end
46
+
47
+ def current_#{mapping}
48
+ @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
49
+ end
50
+
51
+ def #{mapping}_session
52
+ current_#{mapping} && warden.session(:#{mapping})
53
+ end
54
+ METHODS
55
+
56
+ ActiveSupport.on_load(:action_controller) do
57
+ helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
58
+ end
59
+ end
60
+
61
+ # The main accessor for the warden proxy instance
62
+ def warden
63
+ request.env['warden']
64
+ end
65
+
66
+ # Return true if it's a devise_controller. false to all controllers unless
67
+ # the controllers defined inside devise. Useful if you want to apply a before
68
+ # filter to all controllers, except the ones in devise:
69
+ #
70
+ # before_filter :my_filter, :unless => { |c| c.devise_controller? }
71
+ def devise_controller?
72
+ false
73
+ end
74
+
75
+ # Return true if the given scope is signed in session. If no scope given, return
76
+ # true if any scope is signed in. Does not run authentication hooks.
77
+ def signed_in?(scope=nil)
78
+ [ scope || Devise.mappings.keys ].flatten.any? do |scope|
79
+ warden.authenticate?(:scope => scope)
80
+ end
81
+ end
82
+
83
+ def anybody_signed_in?
84
+ ActiveSupport::Deprecation.warn "Devise#anybody_signed_in? is deprecated. "
85
+ "Please use Devise#signed_in?(nil) instead."
86
+ signed_in?
87
+ end
88
+
89
+ # Sign in an user that already was authenticated. This helper is useful for logging
90
+ # users in after sign up.
91
+ #
92
+ # All options given to sign_in is passed forward to the set_user method in warden.
93
+ # The only exception is the :bypass option, which bypass warden callbacks and stores
94
+ # the user straight in session. This option is useful in cases the user is already
95
+ # signed in, but we want to refresh the credentials in session.
96
+ #
97
+ # Examples:
98
+ #
99
+ # sign_in :user, @user # sign_in(scope, resource)
100
+ # sign_in @user # sign_in(resource)
101
+ # sign_in @user, :event => :authentication # sign_in(resource, options)
102
+ # sign_in @user, :bypass => true # sign_in(resource, options)
103
+ #
104
+ def sign_in(resource_or_scope, *args)
105
+ options = args.extract_options!
106
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
107
+ resource = args.last || resource_or_scope
108
+
109
+ expire_session_data_after_sign_in!
110
+
111
+ if options[:bypass]
112
+ warden.session_serializer.store(resource, scope)
113
+ elsif warden.user(scope) == resource && !options.delete(:force)
114
+ # Do nothing. User already signed in and we are not forcing it.
115
+ else
116
+ warden.set_user(resource, options.merge!(:scope => scope))
117
+ end
118
+ end
119
+
120
+ # Sign out a given user or scope. This helper is useful for signing out an user
121
+ # after deleting accounts.
122
+ #
123
+ # Examples:
124
+ #
125
+ # sign_out :user # sign_out(scope)
126
+ # sign_out @user # sign_out(resource)
127
+ #
128
+ def sign_out(resource_or_scope=nil)
129
+ return sign_out_all_scopes unless resource_or_scope
130
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
131
+ warden.user(scope) # Without loading user here, before_logout hook is not called
132
+ warden.raw_session.inspect # Without this inspect here. The session does not clear.
133
+ warden.logout(scope)
134
+ end
135
+
136
+ # Sign out all active users or scopes. This helper is useful for signing out all roles
137
+ # in one click. This signs out ALL scopes in warden.
138
+ def sign_out_all_scopes
139
+ warden.raw_session.inspect
140
+ warden.logout
141
+ end
142
+
143
+ # Returns and delete the url stored in the session for the given scope. Useful
144
+ # for giving redirect backs after sign up:
145
+ #
146
+ # Example:
147
+ #
148
+ # redirect_to stored_location_for(:user) || root_path
149
+ #
150
+ def stored_location_for(resource_or_scope)
151
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
152
+ session.delete("#{scope}_return_to")
153
+ end
154
+
155
+ # The default url to be used after signing in. This is used by all Devise
156
+ # controllers and you can overwrite it in your ApplicationController to
157
+ # provide a custom hook for a custom resource.
158
+ #
159
+ # By default, it first tries to find a resource_root_path, otherwise it
160
+ # uses the root path. For a user scope, you can define the default url in
161
+ # the following way:
162
+ #
163
+ # map.user_root '/users', :controller => 'users' # creates user_root_path
164
+ #
165
+ # map.namespace :user do |user|
166
+ # user.root :controller => 'users' # creates user_root_path
167
+ # end
168
+ #
169
+ #
170
+ # If the resource root path is not defined, root_path is used. However,
171
+ # if this default is not enough, you can customize it, for example:
172
+ #
173
+ # def after_sign_in_path_for(resource)
174
+ # if resource.is_a?(User) && resource.can_publish?
175
+ # publisher_url
176
+ # else
177
+ # super
178
+ # end
179
+ # end
180
+ #
181
+ def after_sign_in_path_for(resource_or_scope)
182
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
183
+ home_path = "#{scope}_root_path"
184
+ respond_to?(home_path, true) ? send(home_path) : root_path
185
+ end
186
+
187
+ # Method used by sessions controller to sign out an user. You can overwrite
188
+ # it in your ApplicationController to provide a custom hook for a custom
189
+ # scope. Notice that differently from +after_sign_in_path_for+ this method
190
+ # receives a symbol with the scope, and not the resource.
191
+ #
192
+ # By default is the root_path.
193
+ def after_sign_out_path_for(resource_or_scope)
194
+ root_path
195
+ end
196
+
197
+ # Sign in an user and tries to redirect first to the stored location and
198
+ # then to the url specified by after_sign_in_path_for. It accepts the same
199
+ # parameters as the sign_in method.
200
+ def sign_in_and_redirect(resource_or_scope, *args)
201
+ options = args.extract_options!
202
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
203
+ resource = args.last || resource_or_scope
204
+ sign_in(scope, resource, options)
205
+ redirect_to redirect_location(scope, resource)
206
+ end
207
+
208
+ def redirect_location(scope, resource) #:nodoc:
209
+ stored_location_for(scope) || after_sign_in_path_for(resource)
210
+ end
211
+
212
+ # Sign out an user and tries to redirect to the url specified by
213
+ # after_sign_out_path_for.
214
+ def sign_out_and_redirect(resource_or_scope)
215
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
216
+ Devise.sign_out_all_scopes ? sign_out : sign_out(scope)
217
+ redirect_to after_sign_out_path_for(scope)
218
+ end
219
+
220
+ # A hook called to expire session data after sign up/in. All keys
221
+ # stored under "devise." namespace are removed after sign in.
222
+ def expire_session_data_after_sign_in!
223
+ session.keys.grep(/^devise\./).each { |k| session.delete(k) }
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,119 @@
1
+ module Devise
2
+ module Controllers
3
+ # Those helpers are used only inside Devise controllers and should not be
4
+ # included in ApplicationController since they all depend on the url being
5
+ # accessed.
6
+ module InternalHelpers #:nodoc:
7
+ extend ActiveSupport::Concern
8
+ include Devise::Controllers::ScopedViews
9
+
10
+ included do
11
+ helper DeviseHelper
12
+
13
+ helpers = %w(resource scope_name resource_name signed_in_resource
14
+ resource_class devise_mapping devise_controller?)
15
+ hide_action *helpers
16
+ helper_method *helpers
17
+
18
+ prepend_before_filter :is_devise_resource?
19
+ respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
20
+ end
21
+
22
+ # Gets the actual resource stored in the instance variable
23
+ def resource
24
+ instance_variable_get(:"@#{resource_name}")
25
+ end
26
+
27
+ # Proxy to devise map name
28
+ def resource_name
29
+ devise_mapping.name
30
+ end
31
+ alias :scope_name :resource_name
32
+
33
+ # Proxy to devise map class
34
+ def resource_class
35
+ devise_mapping.to
36
+ end
37
+
38
+ # Returns a signed in resource from session (if one exists)
39
+ def signed_in_resource
40
+ warden.authenticate(:scope => resource_name)
41
+ end
42
+
43
+ # Attempt to find the mapped route for devise based on request path
44
+ def devise_mapping
45
+ @devise_mapping ||= request.env["devise.mapping"]
46
+ end
47
+
48
+ # Overwrites devise_controller? to return true
49
+ def devise_controller?
50
+ true
51
+ end
52
+
53
+ protected
54
+
55
+ # Checks whether it's a devise mapped resource or not.
56
+ def is_devise_resource? #:nodoc:
57
+ unknown_action!("Could not find devise mapping for path #{request.fullpath.inspect}") unless devise_mapping
58
+ end
59
+
60
+ # Check whether it's navigational format, such as :html or :iphone, or not.
61
+ def is_navigational_format?
62
+ Devise.navigational_formats.include?(request.format.to_sym)
63
+ end
64
+
65
+ def unknown_action!(msg)
66
+ logger.debug "[Devise] #{msg}" if logger
67
+ raise ActionController::UnknownAction, msg
68
+ end
69
+
70
+ # Sets the resource creating an instance variable
71
+ def resource=(new_resource)
72
+ instance_variable_set(:"@#{resource_name}", new_resource)
73
+ end
74
+
75
+ # Build a devise resource.
76
+ def build_resource(hash=nil)
77
+ hash ||= params[resource_name] || {}
78
+ self.resource = resource_class.new(hash)
79
+ end
80
+
81
+ # Helper for use in before_filters where no authentication is required.
82
+ #
83
+ # Example:
84
+ # before_filter :require_no_authentication, :only => :new
85
+ def require_no_authentication
86
+ if warden.authenticated?(resource_name)
87
+ resource = warden.user(resource_name)
88
+ redirect_to after_sign_in_path_for(resource)
89
+ end
90
+ end
91
+
92
+ # Sets the flash message with :key, using I18n. By default you are able
93
+ # to setup your messages using specific resource scope, and if no one is
94
+ # found we look to default scope.
95
+ # Example (i18n locale file):
96
+ #
97
+ # en:
98
+ # devise:
99
+ # passwords:
100
+ # #default_scope_messages - only if resource_scope is not found
101
+ # user:
102
+ # #resource_scope_messages
103
+ #
104
+ # Please refer to README or en.yml locale file to check what messages are
105
+ # available.
106
+ def set_flash_message(key, kind, options={}) #:nodoc:
107
+ options[:scope] = "devise.#{controller_name}"
108
+ options[:default] = Array(options[:default]).unshift(kind.to_sym)
109
+ options[:resource_name] = resource_name
110
+ message = I18n.t("#{resource_name}.#{kind}", options)
111
+ flash[key] = message if message.present?
112
+ end
113
+
114
+ def clean_up_passwords(object) #:nodoc:
115
+ object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,33 @@
1
+ module Devise
2
+ module Controllers
3
+ module ScopedViews
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def scoped_views?
8
+ defined?(@scoped_views) ? @scoped_views : Devise.scoped_views
9
+ end
10
+
11
+ def scoped_views=(value)
12
+ @scoped_views = value
13
+ end
14
+ end
15
+
16
+ protected
17
+
18
+ # Render a view for the specified scope. Turned off by default.
19
+ # Accepts just :controller as option.
20
+ def render_with_scope(action, path=self.controller_path)
21
+ if self.class.scoped_views?
22
+ begin
23
+ render :template => "#{devise_mapping.scoped_path}/#{path.split("/").last}/#{action}"
24
+ rescue ActionView::MissingTemplate
25
+ render :template => "#{path}/#{action}"
26
+ end
27
+ else
28
+ render :template => "#{path}/#{action}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ module Devise
2
+ module Controllers
3
+ # Create url helpers to be used with resource/scope configuration. Acts as
4
+ # proxies to the generated routes created by devise.
5
+ # Resource param can be a string or symbol, a class, or an instance object.
6
+ # Example using a :user resource:
7
+ #
8
+ # new_session_path(:user) => new_user_session_path
9
+ # session_path(:user) => user_session_path
10
+ # destroy_session_path(:user) => destroy_user_session_path
11
+ #
12
+ # new_password_path(:user) => new_user_password_path
13
+ # password_path(:user) => user_password_path
14
+ # edit_password_path(:user) => edit_user_password_path
15
+ #
16
+ # new_confirmation_path(:user) => new_user_confirmation_path
17
+ # confirmation_path(:user) => user_confirmation_path
18
+ #
19
+ # Those helpers are added to your ApplicationController.
20
+ module UrlHelpers
21
+
22
+ Devise::URL_HELPERS.each do |module_name, actions|
23
+ [:path, :url].each do |path_or_url|
24
+ actions.each do |action|
25
+ action = action ? "#{action}_" : ""
26
+
27
+ class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
28
+ def #{action}#{module_name}_#{path_or_url}(resource_or_scope, *args)
29
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
30
+ send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
31
+ end
32
+ URL_HELPERS
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ require "digest/sha2"
2
+
3
+ module Devise
4
+ module Encryptors
5
+ # = AuthlogicSha512
6
+ # Simulates Authlogic's default encryption mechanism.
7
+ # Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to simulate
8
+ # the default behavior.
9
+ class AuthlogicSha512 < Base
10
+ # Gererates a default password digest based on salt, pepper and the
11
+ # incoming password.
12
+ def self.digest(password, stretches, salt, pepper)
13
+ digest = [password, salt].flatten.join('')
14
+ stretches.times { digest = Digest::SHA512.hexdigest(digest) }
15
+ digest
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Devise
2
+ # Implements a way of adding different encryptions.
3
+ # The class should implement a self.digest method that taks the following params:
4
+ # - password
5
+ # - stretches: the number of times the encryption will be applied
6
+ # - salt: the password salt as defined by devise
7
+ # - pepper: Devise config option
8
+ #
9
+ module Encryptors
10
+ class Base
11
+ def self.digest
12
+ raise NotImplemented
13
+ end
14
+
15
+ def self.salt(stretches)
16
+ Devise.friendly_token[0,20]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require "digest/sha1"
2
+
3
+ module Devise
4
+ module Encryptors
5
+ # = ClearanceSha1
6
+ # Simulates Clearance's default encryption mechanism.
7
+ # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
8
+ # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES
9
+ class ClearanceSha1 < Base
10
+ # Gererates a default password digest based on salt, pepper and the
11
+ # incoming password.
12
+ def self.digest(password, stretches, salt, pepper)
13
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require "digest/sha1"
2
+
3
+ module Devise
4
+ module Encryptors
5
+ # = RestfulAuthenticationSha1
6
+ # Simulates Restful Authentication's default encryption mechanism.
7
+ # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
8
+ # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in
9
+ # the initializer to simulate the default behavior.
10
+ class RestfulAuthenticationSha1 < Base
11
+
12
+ # Gererates a default password digest based on salt, pepper and the
13
+ # incoming password.
14
+ def self.digest(password, stretches, salt, pepper)
15
+ digest = pepper
16
+ stretches.times { digest = Digest::SHA1.hexdigest([digest, salt, password, pepper].flatten.join('--')) }
17
+ digest
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require "digest/sha1"
2
+
3
+ module Devise
4
+ module Encryptors
5
+ # = Sha1
6
+ # Uses the Sha1 hash algorithm to encrypt passwords.
7
+ class Sha1 < Base
8
+ # Gererates a default password digest based on stretches, salt, pepper and the
9
+ # incoming password.
10
+ def self.digest(password, stretches, salt, pepper)
11
+ digest = pepper
12
+ stretches.times { digest = self.secure_digest(salt, digest, password, pepper) }
13
+ digest
14
+ end
15
+
16
+ private
17
+
18
+ # Generate a SHA1 digest joining args. Generated token is something like
19
+ # --arg1--arg2--arg3--argN--
20
+ def self.secure_digest(*tokens)
21
+ ::Digest::SHA1.hexdigest('--' << tokens.flatten.join('--') << '--')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require "digest/sha2"
2
+
3
+ module Devise
4
+ module Encryptors
5
+ # = Sha512
6
+ # Uses the Sha512 hash algorithm to encrypt passwords.
7
+ class Sha512 < Base
8
+ # Gererates a default password digest based on salt, pepper and the
9
+ # incoming password.
10
+ def self.digest(password, stretches, salt, pepper)
11
+ digest = pepper
12
+ stretches.times { digest = self.secure_digest(salt, digest, password, pepper) }
13
+ digest
14
+ end
15
+
16
+ private
17
+
18
+ # Generate a Sha512 digest joining args. Generated token is something like
19
+ # --arg1--arg2--arg3--argN--
20
+ def self.secure_digest(*tokens)
21
+ ::Digest::SHA512.hexdigest('--' << tokens.flatten.join('--') << '--')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,132 @@
1
+ require "action_controller/metal"
2
+
3
+ module Devise
4
+ # Failure application that will be called every time :warden is thrown from
5
+ # any strategy or hook. Responsible for redirect the user to the sign in
6
+ # page based on current scope and mapping. If no scope is given, redirect
7
+ # to the default_url.
8
+ class FailureApp < ActionController::Metal
9
+ include ActionController::RackDelegation
10
+ include ActionController::UrlFor
11
+ include ActionController::Redirecting
12
+ include Rails.application.routes.url_helpers
13
+
14
+ delegate :flash, :to => :request
15
+
16
+ def self.call(env)
17
+ action(:respond).call(env)
18
+ end
19
+
20
+ def self.default_url_options(*args)
21
+ ApplicationController.default_url_options(*args)
22
+ end
23
+
24
+ def respond
25
+ if http_auth?
26
+ http_auth
27
+ elsif warden_options[:recall]
28
+ recall
29
+ else
30
+ redirect
31
+ end
32
+ end
33
+
34
+ def http_auth
35
+ self.status = 401
36
+ self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect}) if http_auth_header?
37
+ self.content_type = request.format.to_s
38
+ self.response_body = http_auth_body
39
+ end
40
+
41
+ def recall
42
+ env["PATH_INFO"] = attempted_path
43
+ flash.now[:alert] = i18n_message(:invalid)
44
+ self.response = recall_app(warden_options[:recall]).call(env)
45
+ end
46
+
47
+ def redirect
48
+ store_location!
49
+ flash[:alert] = i18n_message
50
+ redirect_to redirect_url
51
+ end
52
+
53
+ protected
54
+
55
+ def i18n_message(default = nil)
56
+ message = warden.message || warden_options[:message] || default || :unauthenticated
57
+
58
+ if message.is_a?(Symbol)
59
+ I18n.t(:"#{scope}.#{message}", :resource_name => scope,
60
+ :scope => "devise.failure", :default => [message, message.to_s])
61
+ else
62
+ message.to_s
63
+ end
64
+ end
65
+
66
+ def redirect_url
67
+ request_format = request.format.to_sym
68
+ if request_format == :html
69
+ send(:"new_#{scope}_session_path")
70
+ else
71
+ send(:"new_#{scope}_session_path", :format => request_format)
72
+ end
73
+ end
74
+
75
+ # Choose whether we should respond in a http authentication fashion,
76
+ # including 401 and optional headers.
77
+ #
78
+ # This method allows the user to explicitly disable http authentication
79
+ # on ajax requests in case they want to redirect on failures instead of
80
+ # handling the errors on their own. This is useful in case your ajax API
81
+ # is the same as your public API and uses a format like JSON (so you
82
+ # cannot mark JSON as a navigational format).
83
+ def http_auth?
84
+ if request.xhr?
85
+ Devise.http_authenticatable_on_xhr
86
+ else
87
+ !(request.format && Devise.navigational_formats.include?(request.format.to_sym))
88
+ end
89
+ end
90
+
91
+ # It does not make sense to send authenticate headers in ajax requests
92
+ # or if the user disabled them.
93
+ def http_auth_header?
94
+ Devise.mappings[scope].to.http_authenticatable && !request.xhr?
95
+ end
96
+
97
+ def http_auth_body
98
+ return i18n_message unless request.format
99
+ method = "to_#{request.format.to_sym}"
100
+ {}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message
101
+ end
102
+
103
+ def recall_app(app)
104
+ controller, action = app.split("#")
105
+ "#{controller.camelize}Controller".constantize.action(action)
106
+ end
107
+
108
+ def warden
109
+ env['warden']
110
+ end
111
+
112
+ def warden_options
113
+ env['warden.options']
114
+ end
115
+
116
+ def scope
117
+ @scope ||= warden_options[:scope] || Devise.default_scope
118
+ end
119
+
120
+ def attempted_path
121
+ warden_options[:attempted_path]
122
+ end
123
+
124
+ # Stores requested uri to redirect the user after signing in. We cannot use
125
+ # scoped session provided by warden here, since the user is not authenticated
126
+ # yet, but we still need to store the uri based on scope, so different scopes
127
+ # would never use the same uri to redirect.
128
+ def store_location!
129
+ session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
130
+ end
131
+ end
132
+ end