af-devise 2.1.2

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 (207) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +15 -0
  3. data/CHANGELOG.rdoc +885 -0
  4. data/CONTRIBUTING.md +14 -0
  5. data/Gemfile +29 -0
  6. data/Gemfile.lock +155 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +394 -0
  9. data/Rakefile +34 -0
  10. data/app/controllers/devise/confirmations_controller.rb +43 -0
  11. data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
  12. data/app/controllers/devise/passwords_controller.rb +65 -0
  13. data/app/controllers/devise/registrations_controller.rb +119 -0
  14. data/app/controllers/devise/sessions_controller.rb +50 -0
  15. data/app/controllers/devise/unlocks_controller.rb +44 -0
  16. data/app/controllers/devise_controller.rb +184 -0
  17. data/app/helpers/devise_helper.rb +25 -0
  18. data/app/mailers/devise/mailer.rb +15 -0
  19. data/app/views/devise/_links.erb +3 -0
  20. data/app/views/devise/confirmations/new.html.erb +12 -0
  21. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  22. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  23. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  24. data/app/views/devise/passwords/edit.html.erb +16 -0
  25. data/app/views/devise/passwords/new.html.erb +12 -0
  26. data/app/views/devise/registrations/edit.html.erb +25 -0
  27. data/app/views/devise/registrations/new.html.erb +18 -0
  28. data/app/views/devise/sessions/new.html.erb +17 -0
  29. data/app/views/devise/shared/_links.erb +25 -0
  30. data/app/views/devise/unlocks/new.html.erb +12 -0
  31. data/config/locales/en.yml +59 -0
  32. data/devise.gemspec +25 -0
  33. data/gemfiles/Gemfile.rails-3.1.x +35 -0
  34. data/gemfiles/Gemfile.rails-3.1.x.lock +167 -0
  35. data/lib/devise.rb +444 -0
  36. data/lib/devise/controllers/helpers.rb +285 -0
  37. data/lib/devise/controllers/rememberable.rb +52 -0
  38. data/lib/devise/controllers/scoped_views.rb +17 -0
  39. data/lib/devise/controllers/url_helpers.rb +67 -0
  40. data/lib/devise/delegator.rb +16 -0
  41. data/lib/devise/failure_app.rb +187 -0
  42. data/lib/devise/hooks/activatable.rb +11 -0
  43. data/lib/devise/hooks/forgetable.rb +9 -0
  44. data/lib/devise/hooks/lockable.rb +7 -0
  45. data/lib/devise/hooks/rememberable.rb +6 -0
  46. data/lib/devise/hooks/timeoutable.rb +25 -0
  47. data/lib/devise/hooks/trackable.rb +9 -0
  48. data/lib/devise/mailers/helpers.rb +91 -0
  49. data/lib/devise/mapping.rb +172 -0
  50. data/lib/devise/models.rb +128 -0
  51. data/lib/devise/models/authenticatable.rb +268 -0
  52. data/lib/devise/models/confirmable.rb +270 -0
  53. data/lib/devise/models/database_authenticatable.rb +127 -0
  54. data/lib/devise/models/lockable.rb +193 -0
  55. data/lib/devise/models/omniauthable.rb +27 -0
  56. data/lib/devise/models/recoverable.rb +140 -0
  57. data/lib/devise/models/registerable.rb +25 -0
  58. data/lib/devise/models/rememberable.rb +125 -0
  59. data/lib/devise/models/timeoutable.rb +49 -0
  60. data/lib/devise/models/token_authenticatable.rb +89 -0
  61. data/lib/devise/models/trackable.rb +35 -0
  62. data/lib/devise/models/validatable.rb +66 -0
  63. data/lib/devise/modules.rb +29 -0
  64. data/lib/devise/omniauth.rb +28 -0
  65. data/lib/devise/omniauth/config.rb +45 -0
  66. data/lib/devise/omniauth/url_helpers.rb +18 -0
  67. data/lib/devise/orm/active_record.rb +3 -0
  68. data/lib/devise/orm/mongoid.rb +3 -0
  69. data/lib/devise/param_filter.rb +41 -0
  70. data/lib/devise/rails.rb +54 -0
  71. data/lib/devise/rails/routes.rb +446 -0
  72. data/lib/devise/rails/warden_compat.rb +43 -0
  73. data/lib/devise/strategies/authenticatable.rb +176 -0
  74. data/lib/devise/strategies/base.rb +20 -0
  75. data/lib/devise/strategies/database_authenticatable.rb +20 -0
  76. data/lib/devise/strategies/rememberable.rb +55 -0
  77. data/lib/devise/strategies/token_authenticatable.rb +56 -0
  78. data/lib/devise/test_helpers.rb +131 -0
  79. data/lib/devise/time_inflector.rb +14 -0
  80. data/lib/devise/version.rb +3 -0
  81. data/lib/generators/active_record/devise_generator.rb +79 -0
  82. data/lib/generators/active_record/templates/migration.rb +19 -0
  83. data/lib/generators/active_record/templates/migration_existing.rb +26 -0
  84. data/lib/generators/devise/devise_generator.rb +24 -0
  85. data/lib/generators/devise/install_generator.rb +24 -0
  86. data/lib/generators/devise/orm_helpers.rb +32 -0
  87. data/lib/generators/devise/views_generator.rb +116 -0
  88. data/lib/generators/mongoid/devise_generator.rb +57 -0
  89. data/lib/generators/templates/README +35 -0
  90. data/lib/generators/templates/devise.rb +240 -0
  91. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  92. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  93. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  94. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +15 -0
  95. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  96. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  97. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +22 -0
  98. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  99. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  100. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +15 -0
  101. data/test/controllers/custom_strategy_test.rb +62 -0
  102. data/test/controllers/helpers_test.rb +253 -0
  103. data/test/controllers/internal_helpers_test.rb +110 -0
  104. data/test/controllers/sessions_controller_test.rb +85 -0
  105. data/test/controllers/url_helpers_test.rb +59 -0
  106. data/test/delegator_test.rb +19 -0
  107. data/test/devise_test.rb +72 -0
  108. data/test/failure_app_test.rb +221 -0
  109. data/test/generators/active_record_generator_test.rb +75 -0
  110. data/test/generators/devise_generator_test.rb +39 -0
  111. data/test/generators/install_generator_test.rb +13 -0
  112. data/test/generators/mongoid_generator_test.rb +23 -0
  113. data/test/generators/views_generator_test.rb +52 -0
  114. data/test/helpers/devise_helper_test.rb +51 -0
  115. data/test/integration/authenticatable_test.rb +633 -0
  116. data/test/integration/confirmable_test.rb +298 -0
  117. data/test/integration/database_authenticatable_test.rb +82 -0
  118. data/test/integration/http_authenticatable_test.rb +97 -0
  119. data/test/integration/lockable_test.rb +242 -0
  120. data/test/integration/omniauthable_test.rb +133 -0
  121. data/test/integration/recoverable_test.rb +334 -0
  122. data/test/integration/registerable_test.rb +345 -0
  123. data/test/integration/rememberable_test.rb +158 -0
  124. data/test/integration/timeoutable_test.rb +140 -0
  125. data/test/integration/token_authenticatable_test.rb +161 -0
  126. data/test/integration/trackable_test.rb +92 -0
  127. data/test/mailers/confirmation_instructions_test.rb +102 -0
  128. data/test/mailers/reset_password_instructions_test.rb +83 -0
  129. data/test/mailers/unlock_instructions_test.rb +77 -0
  130. data/test/mapping_test.rb +127 -0
  131. data/test/models/authenticatable_test.rb +7 -0
  132. data/test/models/confirmable_test.rb +391 -0
  133. data/test/models/database_authenticatable_test.rb +196 -0
  134. data/test/models/lockable_test.rb +273 -0
  135. data/test/models/omniauthable_test.rb +7 -0
  136. data/test/models/recoverable_test.rb +205 -0
  137. data/test/models/registerable_test.rb +7 -0
  138. data/test/models/rememberable_test.rb +174 -0
  139. data/test/models/serializable_test.rb +49 -0
  140. data/test/models/timeoutable_test.rb +46 -0
  141. data/test/models/token_authenticatable_test.rb +55 -0
  142. data/test/models/trackable_test.rb +13 -0
  143. data/test/models/validatable_test.rb +117 -0
  144. data/test/models_test.rb +179 -0
  145. data/test/omniauth/config_test.rb +57 -0
  146. data/test/omniauth/url_helpers_test.rb +51 -0
  147. data/test/orm/active_record.rb +9 -0
  148. data/test/orm/mongoid.rb +13 -0
  149. data/test/rails_app/Rakefile +10 -0
  150. data/test/rails_app/app/active_record/admin.rb +6 -0
  151. data/test/rails_app/app/active_record/shim.rb +2 -0
  152. data/test/rails_app/app/active_record/user.rb +6 -0
  153. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  154. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  155. data/test/rails_app/app/controllers/application_controller.rb +8 -0
  156. data/test/rails_app/app/controllers/home_controller.rb +25 -0
  157. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  158. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  159. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  160. data/test/rails_app/app/controllers/users_controller.rb +23 -0
  161. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  162. data/test/rails_app/app/mailers/users/mailer.rb +8 -0
  163. data/test/rails_app/app/mongoid/admin.rb +29 -0
  164. data/test/rails_app/app/mongoid/shim.rb +24 -0
  165. data/test/rails_app/app/mongoid/user.rb +42 -0
  166. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  167. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  168. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  169. data/test/rails_app/app/views/home/index.html.erb +1 -0
  170. data/test/rails_app/app/views/home/join.html.erb +1 -0
  171. data/test/rails_app/app/views/home/private.html.erb +1 -0
  172. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  173. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  174. data/test/rails_app/app/views/users/index.html.erb +1 -0
  175. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  176. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  177. data/test/rails_app/config.ru +4 -0
  178. data/test/rails_app/config/application.rb +41 -0
  179. data/test/rails_app/config/boot.rb +8 -0
  180. data/test/rails_app/config/database.yml +18 -0
  181. data/test/rails_app/config/environment.rb +5 -0
  182. data/test/rails_app/config/environments/development.rb +18 -0
  183. data/test/rails_app/config/environments/production.rb +33 -0
  184. data/test/rails_app/config/environments/test.rb +33 -0
  185. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  186. data/test/rails_app/config/initializers/devise.rb +178 -0
  187. data/test/rails_app/config/initializers/inflections.rb +2 -0
  188. data/test/rails_app/config/initializers/secret_token.rb +2 -0
  189. data/test/rails_app/config/routes.rb +100 -0
  190. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +74 -0
  191. data/test/rails_app/db/schema.rb +52 -0
  192. data/test/rails_app/lib/shared_admin.rb +14 -0
  193. data/test/rails_app/lib/shared_user.rb +26 -0
  194. data/test/rails_app/public/404.html +26 -0
  195. data/test/rails_app/public/422.html +26 -0
  196. data/test/rails_app/public/500.html +26 -0
  197. data/test/rails_app/public/favicon.ico +0 -0
  198. data/test/rails_app/script/rails +10 -0
  199. data/test/routes_test.rb +248 -0
  200. data/test/support/assertions.rb +40 -0
  201. data/test/support/helpers.rb +91 -0
  202. data/test/support/integration.rb +92 -0
  203. data/test/support/locale/en.yml +4 -0
  204. data/test/support/webrat/integrations/rails.rb +24 -0
  205. data/test/test_helper.rb +27 -0
  206. data/test/test_helpers_test.rb +151 -0
  207. metadata +421 -0
@@ -0,0 +1,52 @@
1
+ module Devise
2
+ module Controllers
3
+ # A module that may be optionally included in a controller in order
4
+ # to provide remember me behavior.
5
+ module Rememberable
6
+ # Return default cookie values retrieved from session options.
7
+ def self.cookie_values
8
+ Rails.configuration.session_options.slice(:path, :domain, :secure)
9
+ end
10
+
11
+ # A small warden proxy so we can remember and forget uses from hooks.
12
+ class Proxy #:nodoc:
13
+ include Devise::Controllers::Rememberable
14
+
15
+ delegate :cookies, :env, :to => :@warden
16
+
17
+ def initialize(warden)
18
+ @warden = warden
19
+ end
20
+ end
21
+
22
+ # Remembers the given resource by setting up a cookie
23
+ def remember_me(resource)
24
+ scope = Devise::Mapping.find_scope!(resource)
25
+ resource.remember_me!(resource.extend_remember_period)
26
+ cookies.signed["remember_#{scope}_token"] = remember_cookie_values(resource)
27
+ end
28
+
29
+ # Forgets the given resource by deleting a cookie
30
+ def forget_me(resource)
31
+ scope = Devise::Mapping.find_scope!(resource)
32
+ resource.forget_me!
33
+ cookies.delete("remember_#{scope}_token", forget_cookie_values(resource))
34
+ end
35
+
36
+ protected
37
+
38
+ def forget_cookie_values(resource)
39
+ Devise::Controllers::Rememberable.cookie_values.merge!(resource.rememberable_options)
40
+ end
41
+
42
+ def remember_cookie_values(resource)
43
+ options = { :httponly => true }
44
+ options.merge!(forget_cookie_values(resource))
45
+ options.merge!(
46
+ :value => resource.class.serialize_into_cookie(resource),
47
+ :expires => resource.remember_expires_at
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
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
+ end
16
+ end
17
+ end
@@ -0,0 +1,67 @@
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 included by default to ActionController::Base.
20
+ #
21
+ # In case you want to add such helpers to another class, you can do
22
+ # that as long as this new class includes both url_helpers and
23
+ # mounted_helpers. Example:
24
+ #
25
+ # include Rails.application.routes.url_helpers
26
+ # include Rails.application.routes.mounted_helpers
27
+ #
28
+ module UrlHelpers
29
+ def self.remove_helpers!
30
+ self.instance_methods.map(&:to_s).grep(/_(url|path)$/).each do |method|
31
+ remove_method method
32
+ end
33
+ end
34
+
35
+ def self.generate_helpers!(routes=nil)
36
+ routes ||= begin
37
+ mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
38
+ Devise::URL_HELPERS.slice(*mappings)
39
+ end
40
+
41
+ routes.each do |module_name, actions|
42
+ [:path, :url].each do |path_or_url|
43
+ actions.each do |action|
44
+ action = action ? "#{action}_" : ""
45
+ method = "#{action}#{module_name}_#{path_or_url}"
46
+
47
+ class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
48
+ def #{method}(resource_or_scope, *args)
49
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
50
+ _devise_route_context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
51
+ end
52
+ URL_HELPERS
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ generate_helpers!(Devise::URL_HELPERS)
59
+
60
+ private
61
+
62
+ def _devise_route_context
63
+ @_devise_route_context ||= send(Devise.available_router_name)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,16 @@
1
+ module Devise
2
+ # Checks the scope in the given environment and returns the associated failure app.
3
+ class Delegator
4
+ def call(env)
5
+ failure_app(env).call(env)
6
+ end
7
+
8
+ def failure_app(env)
9
+ app = env["warden.options"] &&
10
+ (scope = env["warden.options"][:scope]) &&
11
+ Devise.mappings[scope.to_sym].failure_app
12
+
13
+ app || Devise::FailureApp
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,187 @@
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
+
13
+ include Rails.application.routes.url_helpers
14
+ include Rails.application.routes.mounted_helpers
15
+
16
+ delegate :flash, :to => :request
17
+
18
+ def self.call(env)
19
+ @respond ||= action(:respond)
20
+ @respond.call(env)
21
+ end
22
+
23
+ def self.default_url_options(*args)
24
+ if defined?(ApplicationController)
25
+ ApplicationController.default_url_options(*args)
26
+ else
27
+ {}
28
+ end
29
+ end
30
+
31
+ def respond
32
+ if http_auth?
33
+ http_auth
34
+ elsif warden_options[:recall]
35
+ recall
36
+ else
37
+ redirect
38
+ end
39
+ end
40
+
41
+ def http_auth
42
+ self.status = 401
43
+ self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect}) if http_auth_header?
44
+ self.content_type = request.format.to_s
45
+ self.response_body = http_auth_body
46
+ end
47
+
48
+ def recall
49
+ env["PATH_INFO"] = attempted_path
50
+ flash.now[:alert] = i18n_message(:invalid)
51
+ self.response = recall_app(warden_options[:recall]).call(env)
52
+ end
53
+
54
+ def redirect
55
+ store_location!
56
+ if flash[:timedout] && flash[:alert]
57
+ flash.keep(:timedout)
58
+ flash.keep(:alert)
59
+ else
60
+ flash[:alert] = i18n_message
61
+ end
62
+ redirect_to redirect_url
63
+ end
64
+
65
+ protected
66
+
67
+ def i18n_message(default = nil)
68
+ message = warden_message || default || :unauthenticated
69
+
70
+ if message.is_a?(Symbol)
71
+ I18n.t(:"#{scope}.#{message}", :resource_name => scope,
72
+ :scope => "devise.failure", :default => [message])
73
+ else
74
+ message.to_s
75
+ end
76
+ end
77
+
78
+ def redirect_url
79
+ if warden_message == :timeout
80
+ flash[:timedout] = true
81
+ attempted_path || scope_path
82
+ else
83
+ scope_path
84
+ end
85
+ end
86
+
87
+ def scope_path
88
+ opts = {}
89
+ route = :"new_#{scope}_session_path"
90
+ opts[:format] = request_format unless skip_format?
91
+
92
+ config = Rails.application.config
93
+ opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root))
94
+
95
+ context = send(Devise.available_router_name)
96
+
97
+ if context.respond_to?(route)
98
+ context.send(route, opts)
99
+ elsif respond_to?(:root_path)
100
+ root_path(opts)
101
+ else
102
+ "/"
103
+ end
104
+ end
105
+
106
+ def skip_format?
107
+ %w(html */*).include? request_format.to_s
108
+ end
109
+
110
+ # Choose whether we should respond in a http authentication fashion,
111
+ # including 401 and optional headers.
112
+ #
113
+ # This method allows the user to explicitly disable http authentication
114
+ # on ajax requests in case they want to redirect on failures instead of
115
+ # handling the errors on their own. This is useful in case your ajax API
116
+ # is the same as your public API and uses a format like JSON (so you
117
+ # cannot mark JSON as a navigational format).
118
+ def http_auth?
119
+ if request.xhr?
120
+ Devise.http_authenticatable_on_xhr
121
+ else
122
+ !(request_format && is_navigational_format?)
123
+ end
124
+ end
125
+
126
+ # It does not make sense to send authenticate headers in ajax requests
127
+ # or if the user disabled them.
128
+ def http_auth_header?
129
+ Devise.mappings[scope].to.http_authenticatable && !request.xhr?
130
+ end
131
+
132
+ def http_auth_body
133
+ return i18n_message unless request_format
134
+ method = "to_#{request_format}"
135
+ if method == "to_xml"
136
+ { :error => i18n_message }.to_xml(:root => "errors")
137
+ elsif {}.respond_to?(method)
138
+ { :error => i18n_message }.send(method)
139
+ else
140
+ i18n_message
141
+ end
142
+ end
143
+
144
+ def recall_app(app)
145
+ controller, action = app.split("#")
146
+ controller_name = ActiveSupport::Inflector.camelize(controller)
147
+ controller_klass = ActiveSupport::Inflector.constantize("#{controller_name}Controller")
148
+ controller_klass.action(action)
149
+ end
150
+
151
+ def warden
152
+ env['warden']
153
+ end
154
+
155
+ def warden_options
156
+ env['warden.options']
157
+ end
158
+
159
+ def warden_message
160
+ @message ||= warden.message || warden_options[:message]
161
+ end
162
+
163
+ def scope
164
+ @scope ||= warden_options[:scope] || Devise.default_scope
165
+ end
166
+
167
+ def attempted_path
168
+ warden_options[:attempted_path]
169
+ end
170
+
171
+ # Stores requested uri to redirect the user after signing in. We cannot use
172
+ # scoped session provided by warden here, since the user is not authenticated
173
+ # yet, but we still need to store the uri based on scope, so different scopes
174
+ # would never use the same uri to redirect.
175
+ def store_location!
176
+ session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
177
+ end
178
+
179
+ def is_navigational_format?
180
+ Devise.navigational_formats.include?(request_format)
181
+ end
182
+
183
+ def request_format
184
+ @request_format ||= request.format.try(:ref)
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,11 @@
1
+ # Deny user access whenever his account is not active yet. All strategies that inherits from
2
+ # Devise::Strategies::Authenticatable and uses the validate already check if the user is active_for_authentication?
3
+ # before actively signing him in. However, we need this as hook to validate the user activity
4
+ # in each request and in case the user is using other strategies beside Devise ones.
5
+ Warden::Manager.after_set_user do |record, warden, options|
6
+ if record && record.respond_to?(:active_for_authentication?) && !record.active_for_authentication?
7
+ scope = options[:scope]
8
+ warden.logout(scope)
9
+ throw :warden, :scope => scope, :message => record.inactive_message
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # Before logout hook to forget the user in the given scope, if it responds
2
+ # to forget_me! Also clear remember token to ensure the user won't be
3
+ # remembered again. Notice that we forget the user unless the record is not persisted.
4
+ # This avoids forgetting deleted users.
5
+ Warden::Manager.before_logout do |record, warden, options|
6
+ if record.respond_to?(:forget_me!)
7
+ Devise::Controllers::Rememberable::Proxy.new(warden).forget_me(record)
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # After each sign in, if resource responds to failed_attempts, sets it to 0
2
+ # This is only triggered when the user is explicitly set (with set_user)
3
+ Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
4
+ if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
5
+ record.update_attribute(:failed_attempts, 0)
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
2
+ scope = options[:scope]
3
+ if record.respond_to?(:remember_me) && record.remember_me && warden.authenticated?(scope)
4
+ Devise::Controllers::Rememberable::Proxy.new(warden).remember_me(record)
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ # Each time a record is set we check whether its session has already timed out
2
+ # or not, based on last request time. If so, the record is logged out and
3
+ # redirected to the sign in page. Also, each time the request comes and the
4
+ # record is set, we set the last request time inside its scoped session to
5
+ # verify timeout in the following request.
6
+ Warden::Manager.after_set_user do |record, warden, options|
7
+ scope = options[:scope]
8
+ env = warden.request.env
9
+
10
+ if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
11
+ last_request_at = warden.session(scope)['last_request_at']
12
+
13
+ if record.timedout?(last_request_at) && !env['devise.skip_timeout']
14
+ warden.logout(scope)
15
+ if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
16
+ record.reset_authentication_token!
17
+ end
18
+ throw :warden, :scope => scope, :message => :timeout
19
+ end
20
+
21
+ unless env['devise.skip_trackable']
22
+ warden.session(scope)['last_request_at'] = Time.now.utc
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ # After each sign in, update sign in time, sign in count and sign in IP.
2
+ # This is only triggered when the user is explicitly set (with set_user)
3
+ # and on authentication. Retrieving the user from session (:fetch) does
4
+ # not trigger it.
5
+ Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
6
+ if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && !warden.request.env['devise.skip_trackable']
7
+ record.update_tracked_fields!(warden.request)
8
+ end
9
+ end
@@ -0,0 +1,91 @@
1
+ module Devise
2
+ module Mailers
3
+ module Helpers
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Devise::Controllers::ScopedViews
8
+ attr_reader :scope_name, :resource
9
+ end
10
+
11
+ protected
12
+
13
+ # Configure default email options
14
+ def devise_mail(record, action)
15
+ initialize_from_record(record)
16
+ mail headers_for(action)
17
+ end
18
+
19
+ def initialize_from_record(record)
20
+ @scope_name = Devise::Mapping.find_scope!(record)
21
+ @resource = instance_variable_set("@#{devise_mapping.name}", record)
22
+ end
23
+
24
+ def devise_mapping
25
+ @devise_mapping ||= Devise.mappings[scope_name]
26
+ end
27
+
28
+ def headers_for(action)
29
+ headers = {
30
+ :subject => translate(devise_mapping, action),
31
+ :to => resource.email,
32
+ :from => mailer_sender(devise_mapping),
33
+ :reply_to => mailer_reply_to(devise_mapping),
34
+ :template_path => template_paths
35
+ }
36
+
37
+ if resource.respond_to?(:headers_for)
38
+ headers.merge!(resource.headers_for(action))
39
+ end
40
+
41
+ headers
42
+ end
43
+
44
+ def mailer_reply_to(mapping)
45
+ mailer_sender(mapping, :reply_to)
46
+ end
47
+
48
+ def mailer_from(mapping)
49
+ mailer_sender(mapping, :from)
50
+ end
51
+
52
+ def mailer_sender(mapping, sender = :from)
53
+ if default_params[sender].present?
54
+ default_params[sender]
55
+ elsif Devise.mailer_sender.is_a?(Proc)
56
+ Devise.mailer_sender.call(mapping.name)
57
+ else
58
+ Devise.mailer_sender
59
+ end
60
+ end
61
+
62
+ def template_paths
63
+ template_path = [self.class.mailer_name]
64
+ template_path.unshift "#{@devise_mapping.scoped_path}/mailer" if self.class.scoped_views?
65
+ template_path
66
+ end
67
+
68
+ # Setup a subject doing an I18n lookup. At first, it attemps to set a subject
69
+ # based on the current mapping:
70
+ #
71
+ # en:
72
+ # devise:
73
+ # mailer:
74
+ # confirmation_instructions:
75
+ # user_subject: '...'
76
+ #
77
+ # If one does not exist, it fallbacks to ActionMailer default:
78
+ #
79
+ # en:
80
+ # devise:
81
+ # mailer:
82
+ # confirmation_instructions:
83
+ # subject: '...'
84
+ #
85
+ def translate(mapping, key)
86
+ I18n.t(:"#{mapping.name}_subject", :scope => [:devise, :mailer, key],
87
+ :default => [:subject, key.to_s.humanize])
88
+ end
89
+ end
90
+ end
91
+ end