af-devise 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
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