deviseOne 1.0.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 (246) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +38 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +1117 -0
  6. data/CONTRIBUTING.md +14 -0
  7. data/Gemfile +29 -0
  8. data/Gemfile.lock +199 -0
  9. data/MIT-LICENSE +20 -0
  10. data/README.md +529 -0
  11. data/Rakefile +35 -0
  12. data/app/controllers/devise/confirmations_controller.rb +47 -0
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
  14. data/app/controllers/devise/passwords_controller.rb +71 -0
  15. data/app/controllers/devise/registrations_controller.rb +143 -0
  16. data/app/controllers/devise/sessions_controller.rb +166 -0
  17. data/app/controllers/devise/unlocks_controller.rb +46 -0
  18. data/app/controllers/devise_controller.rb +193 -0
  19. data/app/helpers/devise_helper.rb +25 -0
  20. data/app/mailers/devise/mailer.rb +20 -0
  21. data/app/views/devise/confirmations/new.html.erb +16 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise/passwords/edit.html.erb +25 -0
  26. data/app/views/devise/passwords/new.html.erb +16 -0
  27. data/app/views/devise/registrations/edit.html.erb +39 -0
  28. data/app/views/devise/registrations/new.html.erb +29 -0
  29. data/app/views/devise/sessions/new.html.erb +27 -0
  30. data/app/views/devise/shared/_links.html.erb +21 -0
  31. data/app/views/devise/unlocks/new.html.erb +16 -0
  32. data/config/locales/en.yml +70 -0
  33. data/devise.gemspec +33 -0
  34. data/devise.png +0 -0
  35. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable.lock +169 -0
  37. data/gemfiles/Gemfile.rails-4.0-stable +29 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable.lock +165 -0
  39. data/gemfiles/Gemfile.rails-4.1-stable +29 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable.lock +170 -0
  41. data/lib/devise.rb +499 -0
  42. data/lib/devise/controllers/helpers.rb +284 -0
  43. data/lib/devise/controllers/rememberable.rb +47 -0
  44. data/lib/devise/controllers/scoped_views.rb +17 -0
  45. data/lib/devise/controllers/sign_in_out.rb +102 -0
  46. data/lib/devise/controllers/store_location.rb +58 -0
  47. data/lib/devise/controllers/url_helpers.rb +69 -0
  48. data/lib/devise/delegator.rb +16 -0
  49. data/lib/devise/failure_app.rb +212 -0
  50. data/lib/devise/hooks/activatable.rb +10 -0
  51. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  52. data/lib/devise/hooks/forgetable.rb +9 -0
  53. data/lib/devise/hooks/lockable.rb +7 -0
  54. data/lib/devise/hooks/proxy.rb +21 -0
  55. data/lib/devise/hooks/rememberable.rb +7 -0
  56. data/lib/devise/hooks/timeoutable.rb +35 -0
  57. data/lib/devise/hooks/trackable.rb +9 -0
  58. data/lib/devise/mailers/helpers.rb +90 -0
  59. data/lib/devise/mapping.rb +175 -0
  60. data/lib/devise/models.rb +119 -0
  61. data/lib/devise/models/authenticatable.rb +290 -0
  62. data/lib/devise/models/confirmable.rb +305 -0
  63. data/lib/devise/models/database_authenticatable.rb +164 -0
  64. data/lib/devise/models/lockable.rb +196 -0
  65. data/lib/devise/models/omniauthable.rb +27 -0
  66. data/lib/devise/models/recoverable.rb +157 -0
  67. data/lib/devise/models/registerable.rb +25 -0
  68. data/lib/devise/models/rememberable.rb +142 -0
  69. data/lib/devise/models/timeoutable.rb +49 -0
  70. data/lib/devise/models/trackable.rb +38 -0
  71. data/lib/devise/models/validatable.rb +66 -0
  72. data/lib/devise/modules.rb +28 -0
  73. data/lib/devise/omniauth.rb +28 -0
  74. data/lib/devise/omniauth/config.rb +45 -0
  75. data/lib/devise/omniauth/url_helpers.rb +18 -0
  76. data/lib/devise/orm/active_record.rb +3 -0
  77. data/lib/devise/orm/mongoid.rb +3 -0
  78. data/lib/devise/parameter_filter.rb +40 -0
  79. data/lib/devise/parameter_sanitizer.rb +99 -0
  80. data/lib/devise/rails.rb +56 -0
  81. data/lib/devise/rails/routes.rb +495 -0
  82. data/lib/devise/rails/warden_compat.rb +22 -0
  83. data/lib/devise/strategies/authenticatable.rb +173 -0
  84. data/lib/devise/strategies/base.rb +20 -0
  85. data/lib/devise/strategies/database_authenticatable.rb +24 -0
  86. data/lib/devise/strategies/rememberable.rb +59 -0
  87. data/lib/devise/test_helpers.rb +132 -0
  88. data/lib/devise/time_inflector.rb +14 -0
  89. data/lib/devise/token_generator.rb +70 -0
  90. data/lib/devise/version.rb +3 -0
  91. data/lib/generators/active_record/devise_generator.rb +91 -0
  92. data/lib/generators/active_record/templates/migration.rb +18 -0
  93. data/lib/generators/active_record/templates/migration_existing.rb +25 -0
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +26 -0
  96. data/lib/generators/devise/install_generator.rb +29 -0
  97. data/lib/generators/devise/orm_helpers.rb +51 -0
  98. data/lib/generators/devise/views_generator.rb +135 -0
  99. data/lib/generators/mongoid/devise_generator.rb +55 -0
  100. data/lib/generators/templates/README +35 -0
  101. data/lib/generators/templates/controllers/README +14 -0
  102. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  103. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  104. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  105. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  106. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  107. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  108. data/lib/generators/templates/devise.rb +263 -0
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  110. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  111. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  112. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +16 -0
  113. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  114. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  115. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +27 -0
  116. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  117. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  118. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +16 -0
  119. data/script/cached-bundle +49 -0
  120. data/script/s3-put +71 -0
  121. data/test/controllers/custom_registrations_controller_test.rb +35 -0
  122. data/test/controllers/custom_strategy_test.rb +62 -0
  123. data/test/controllers/helpers_test.rb +316 -0
  124. data/test/controllers/internal_helpers_test.rb +129 -0
  125. data/test/controllers/load_hooks_controller_test.rb +19 -0
  126. data/test/controllers/passwords_controller_test.rb +31 -0
  127. data/test/controllers/sessions_controller_test.rb +102 -0
  128. data/test/controllers/url_helpers_test.rb +65 -0
  129. data/test/delegator_test.rb +19 -0
  130. data/test/devise_test.rb +107 -0
  131. data/test/failure_app_test.rb +275 -0
  132. data/test/generators/active_record_generator_test.rb +109 -0
  133. data/test/generators/controllers_generator_test.rb +48 -0
  134. data/test/generators/devise_generator_test.rb +39 -0
  135. data/test/generators/install_generator_test.rb +13 -0
  136. data/test/generators/mongoid_generator_test.rb +23 -0
  137. data/test/generators/views_generator_test.rb +96 -0
  138. data/test/helpers/devise_helper_test.rb +49 -0
  139. data/test/integration/authenticatable_test.rb +731 -0
  140. data/test/integration/confirmable_test.rb +324 -0
  141. data/test/integration/database_authenticatable_test.rb +94 -0
  142. data/test/integration/http_authenticatable_test.rb +105 -0
  143. data/test/integration/lockable_test.rb +239 -0
  144. data/test/integration/omniauthable_test.rb +133 -0
  145. data/test/integration/recoverable_test.rb +334 -0
  146. data/test/integration/registerable_test.rb +361 -0
  147. data/test/integration/rememberable_test.rb +176 -0
  148. data/test/integration/timeoutable_test.rb +189 -0
  149. data/test/integration/trackable_test.rb +92 -0
  150. data/test/mailers/confirmation_instructions_test.rb +115 -0
  151. data/test/mailers/reset_password_instructions_test.rb +96 -0
  152. data/test/mailers/unlock_instructions_test.rb +91 -0
  153. data/test/mapping_test.rb +128 -0
  154. data/test/models/authenticatable_test.rb +23 -0
  155. data/test/models/confirmable_test.rb +461 -0
  156. data/test/models/database_authenticatable_test.rb +249 -0
  157. data/test/models/lockable_test.rb +328 -0
  158. data/test/models/omniauthable_test.rb +7 -0
  159. data/test/models/recoverable_test.rb +205 -0
  160. data/test/models/registerable_test.rb +7 -0
  161. data/test/models/rememberable_test.rb +198 -0
  162. data/test/models/serializable_test.rb +49 -0
  163. data/test/models/timeoutable_test.rb +51 -0
  164. data/test/models/trackable_test.rb +41 -0
  165. data/test/models/validatable_test.rb +127 -0
  166. data/test/models_test.rb +144 -0
  167. data/test/omniauth/config_test.rb +57 -0
  168. data/test/omniauth/url_helpers_test.rb +54 -0
  169. data/test/orm/active_record.rb +10 -0
  170. data/test/orm/mongoid.rb +13 -0
  171. data/test/parameter_sanitizer_test.rb +81 -0
  172. data/test/rails_app/Rakefile +6 -0
  173. data/test/rails_app/app/active_record/admin.rb +6 -0
  174. data/test/rails_app/app/active_record/shim.rb +2 -0
  175. data/test/rails_app/app/active_record/user.rb +6 -0
  176. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  177. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  178. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  179. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  180. data/test/rails_app/app/controllers/application_controller.rb +12 -0
  181. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  182. data/test/rails_app/app/controllers/custom/registrations_controller.rb +21 -0
  183. data/test/rails_app/app/controllers/home_controller.rb +25 -0
  184. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  185. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  186. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  187. data/test/rails_app/app/controllers/users_controller.rb +31 -0
  188. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  189. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  190. data/test/rails_app/app/mailers/users/mailer.rb +3 -0
  191. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  192. data/test/rails_app/app/mongoid/admin.rb +29 -0
  193. data/test/rails_app/app/mongoid/shim.rb +23 -0
  194. data/test/rails_app/app/mongoid/user.rb +39 -0
  195. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  196. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  197. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  198. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  199. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  200. data/test/rails_app/app/views/home/index.html.erb +1 -0
  201. data/test/rails_app/app/views/home/join.html.erb +1 -0
  202. data/test/rails_app/app/views/home/private.html.erb +1 -0
  203. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  204. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  205. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  206. data/test/rails_app/app/views/users/index.html.erb +1 -0
  207. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  208. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  209. data/test/rails_app/bin/bundle +3 -0
  210. data/test/rails_app/bin/rails +4 -0
  211. data/test/rails_app/bin/rake +4 -0
  212. data/test/rails_app/config.ru +4 -0
  213. data/test/rails_app/config/application.rb +40 -0
  214. data/test/rails_app/config/boot.rb +14 -0
  215. data/test/rails_app/config/database.yml +18 -0
  216. data/test/rails_app/config/environment.rb +5 -0
  217. data/test/rails_app/config/environments/development.rb +30 -0
  218. data/test/rails_app/config/environments/production.rb +80 -0
  219. data/test/rails_app/config/environments/test.rb +36 -0
  220. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  221. data/test/rails_app/config/initializers/devise.rb +180 -0
  222. data/test/rails_app/config/initializers/inflections.rb +2 -0
  223. data/test/rails_app/config/initializers/secret_token.rb +8 -0
  224. data/test/rails_app/config/initializers/session_store.rb +1 -0
  225. data/test/rails_app/config/routes.rb +122 -0
  226. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +71 -0
  227. data/test/rails_app/db/schema.rb +55 -0
  228. data/test/rails_app/lib/shared_admin.rb +17 -0
  229. data/test/rails_app/lib/shared_user.rb +29 -0
  230. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  231. data/test/rails_app/public/404.html +26 -0
  232. data/test/rails_app/public/422.html +26 -0
  233. data/test/rails_app/public/500.html +26 -0
  234. data/test/rails_app/public/favicon.ico +0 -0
  235. data/test/routes_test.rb +264 -0
  236. data/test/support/action_controller/record_identifier.rb +10 -0
  237. data/test/support/assertions.rb +39 -0
  238. data/test/support/helpers.rb +73 -0
  239. data/test/support/integration.rb +92 -0
  240. data/test/support/locale/en.yml +8 -0
  241. data/test/support/mongoid.yml +6 -0
  242. data/test/support/webrat/integrations/rails.rb +24 -0
  243. data/test/test_helper.rb +34 -0
  244. data/test/test_helpers_test.rb +163 -0
  245. data/test/test_models.rb +33 -0
  246. metadata +531 -0
@@ -0,0 +1,22 @@
1
+ module Warden::Mixins::Common
2
+ def request
3
+ @request ||= ActionDispatch::Request.new(env)
4
+ end
5
+
6
+ # Deprecate: Remove this check once we move to Rails 4 only.
7
+ NULL_STORE =
8
+ defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
9
+ ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
10
+
11
+ def reset_session!
12
+ # Calling reset_session on NULL_STORE causes it fail.
13
+ # This is a bug that needs to be fixed in Rails.
14
+ unless NULL_STORE && request.session.is_a?(NULL_STORE)
15
+ request.reset_session
16
+ end
17
+ end
18
+
19
+ def cookies
20
+ request.cookie_jar
21
+ end
22
+ end
@@ -0,0 +1,173 @@
1
+ require 'devise/strategies/base'
2
+
3
+ module Devise
4
+ module Strategies
5
+ # This strategy should be used as basis for authentication strategies. It retrieves
6
+ # parameters both from params or from http authorization headers. See database_authenticatable
7
+ # for an example.
8
+ class Authenticatable < Base
9
+ attr_accessor :authentication_hash, :authentication_type, :password
10
+
11
+ def store?
12
+ super && !mapping.to.skip_session_storage.include?(authentication_type)
13
+ end
14
+
15
+ def valid?
16
+ valid_for_params_auth? || valid_for_http_auth?
17
+ end
18
+
19
+ # Override and set to false for things like OmniAuth that technically
20
+ # run through Authentication (user_set) very often, which would normally
21
+ # reset CSRF data in the session
22
+ def clean_up_csrf?
23
+ true
24
+ end
25
+
26
+ private
27
+
28
+ # Receives a resource and check if it is valid by calling valid_for_authentication?
29
+ # An optional block that will be triggered while validating can be optionally
30
+ # given as parameter. Check Devise::Models::Authenticable.valid_for_authentication?
31
+ # for more information.
32
+ #
33
+ # In case the resource can't be validated, it will fail with the given
34
+ # unauthenticated_message.
35
+ def validate(resource, &block)
36
+ result = resource && resource.valid_for_authentication?(&block)
37
+
38
+ if result
39
+ true
40
+ else
41
+ if resource
42
+ fail!(resource.unauthenticated_message)
43
+ end
44
+ false
45
+ end
46
+ end
47
+
48
+ # Get values from params and set in the resource.
49
+ def remember_me(resource)
50
+ resource.remember_me = remember_me? if resource.respond_to?(:remember_me=)
51
+ end
52
+
53
+ # Should this resource be marked to be remembered?
54
+ def remember_me?
55
+ valid_params? && Devise::TRUE_VALUES.include?(params_auth_hash[:remember_me])
56
+ end
57
+
58
+ # Check if this is a valid strategy for http authentication by:
59
+ #
60
+ # * Validating if the model allows params authentication;
61
+ # * If any of the authorization headers were sent;
62
+ # * If all authentication keys are present;
63
+ #
64
+ def valid_for_http_auth?
65
+ http_authenticatable? && request.authorization && with_authentication_hash(:http_auth, http_auth_hash)
66
+ end
67
+
68
+ # Check if this is a valid strategy for params authentication by:
69
+ #
70
+ # * Validating if the model allows params authentication;
71
+ # * If the request hits the sessions controller through POST;
72
+ # * If the params[scope] returns a hash with credentials;
73
+ # * If all authentication keys are present;
74
+ #
75
+ def valid_for_params_auth?
76
+ params_authenticatable? && valid_params_request? &&
77
+ valid_params? && with_authentication_hash(:params_auth, params_auth_hash)
78
+ end
79
+
80
+ # Check if the model accepts this strategy as http authenticatable.
81
+ def http_authenticatable?
82
+ mapping.to.http_authenticatable?(authenticatable_name)
83
+ end
84
+
85
+ # Check if the model accepts this strategy as params authenticatable.
86
+ def params_authenticatable?
87
+ mapping.to.params_authenticatable?(authenticatable_name)
88
+ end
89
+
90
+ # Extract the appropriate subhash for authentication from params.
91
+ def params_auth_hash
92
+ params[scope]
93
+ end
94
+
95
+ # Extract a hash with attributes:values from the http params.
96
+ def http_auth_hash
97
+ keys = [http_authentication_key, :password]
98
+ Hash[*keys.zip(decode_credentials).flatten]
99
+ end
100
+
101
+ # By default, a request is valid if the controller set the proper env variable.
102
+ def valid_params_request?
103
+ !!env["devise.allow_params_authentication"]
104
+ end
105
+
106
+ # If the request is valid, finally check if params_auth_hash returns a hash.
107
+ def valid_params?
108
+ params_auth_hash.is_a?(Hash)
109
+ end
110
+
111
+ # Check if password is present.
112
+ def valid_password?
113
+ password.present?
114
+ end
115
+
116
+ # Helper to decode credentials from HTTP.
117
+ def decode_credentials
118
+ return [] unless request.authorization && request.authorization =~ /^Basic (.*)/m
119
+ Base64.decode64($1).split(/:/, 2)
120
+ end
121
+
122
+ # Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
123
+ def with_authentication_hash(auth_type, auth_values)
124
+ self.authentication_hash, self.authentication_type = {}, auth_type
125
+ self.password = auth_values[:password]
126
+
127
+ parse_authentication_key_values(auth_values, authentication_keys) &&
128
+ parse_authentication_key_values(request_values, request_keys)
129
+ end
130
+
131
+ def authentication_keys
132
+ @authentication_keys ||= mapping.to.authentication_keys
133
+ end
134
+
135
+ def http_authentication_key
136
+ @http_authentication_key ||= mapping.to.http_authentication_key || case authentication_keys
137
+ when Array then authentication_keys.first
138
+ when Hash then authentication_keys.keys.first
139
+ end
140
+ end
141
+
142
+ def request_keys
143
+ @request_keys ||= mapping.to.request_keys
144
+ end
145
+
146
+ def request_values
147
+ keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
148
+ values = keys.map { |k| self.request.send(k) }
149
+ Hash[keys.zip(values)]
150
+ end
151
+
152
+ def parse_authentication_key_values(hash, keys)
153
+ keys.each do |key, enforce|
154
+ value = hash[key].presence
155
+ if value
156
+ self.authentication_hash[key] = value
157
+ else
158
+ return false unless enforce == false
159
+ end
160
+ end
161
+ true
162
+ end
163
+
164
+ # Holds the authenticatable name for this class. Devise::Strategies::DatabaseAuthenticatable
165
+ # becomes simply :database.
166
+ def authenticatable_name
167
+ @authenticatable_name ||=
168
+ ActiveSupport::Inflector.underscore(self.class.name.split("::").last).
169
+ sub("_authenticatable", "").to_sym
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,20 @@
1
+ module Devise
2
+ module Strategies
3
+ # Base strategy for Devise. Responsible for verifying correct scope and mapping.
4
+ class Base < ::Warden::Strategies::Base
5
+ # Whenever CSRF cannot be verified, we turn off any kind of storage
6
+ def store?
7
+ !env["devise.skip_storage"]
8
+ end
9
+
10
+ # Checks if a valid scope was given for devise and find mapping based on this scope.
11
+ def mapping
12
+ @mapping ||= begin
13
+ mapping = Devise.mappings[scope]
14
+ raise "Could not find mapping for #{scope}" unless mapping
15
+ mapping
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ require 'devise/strategies/authenticatable'
2
+
3
+ module Devise
4
+ module Strategies
5
+ # Default strategy for signing in a user, based on their email and password in the database.
6
+ class DatabaseAuthenticatable < Authenticatable
7
+ def authenticate!
8
+ resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
9
+ encrypted = false
10
+
11
+ if validate(resource){ encrypted = true; resource.valid_password?(password) }
12
+ remember_me(resource)
13
+ resource.after_database_authentication
14
+ success!(resource)
15
+ end
16
+
17
+ mapping.to.new.password = password if !encrypted && Devise.paranoid
18
+ fail(:not_found_in_database) unless resource
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ Warden::Strategies.add(:database_authenticatable, Devise::Strategies::DatabaseAuthenticatable)
@@ -0,0 +1,59 @@
1
+ require 'devise/strategies/authenticatable'
2
+
3
+ module Devise
4
+ module Strategies
5
+ # Remember the user through the remember token. This strategy is responsible
6
+ # to verify whether there is a cookie with the remember token, and to
7
+ # recreate the user from this cookie if it exists. Must be called *before*
8
+ # authenticatable.
9
+ class Rememberable < Authenticatable
10
+ # A valid strategy for rememberable needs a remember token in the cookies.
11
+ def valid?
12
+ @remember_cookie = nil
13
+ remember_cookie.present?
14
+ end
15
+
16
+ # To authenticate a user we deserialize the cookie and attempt finding
17
+ # the record in the database. If the attempt fails, we pass to another
18
+ # strategy handle the authentication.
19
+ def authenticate!
20
+ resource = mapping.to.serialize_from_cookie(*remember_cookie)
21
+
22
+ unless resource
23
+ cookies.delete(remember_key)
24
+ return pass
25
+ end
26
+
27
+ if validate(resource)
28
+ remember_me(resource)
29
+ extend_remember_me_period(resource)
30
+ resource.after_remembered
31
+ success!(resource)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def extend_remember_me_period(resource)
38
+ if resource.respond_to?(:extend_remember_period=)
39
+ resource.extend_remember_period = mapping.to.extend_remember_period
40
+ end
41
+ end
42
+
43
+ def remember_me?
44
+ true
45
+ end
46
+
47
+ def remember_key
48
+ mapping.to.rememberable_options.fetch(:key, "remember_#{scope}_token")
49
+ end
50
+
51
+ def remember_cookie
52
+ @remember_cookie ||= cookies.signed[remember_key]
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+
59
+ Warden::Strategies.add(:rememberable, Devise::Strategies::Rememberable)
@@ -0,0 +1,132 @@
1
+ module Devise
2
+ # Devise::TestHelpers provides a facility to test controllers in isolation
3
+ # when using ActionController::TestCase allowing you to quickly sign_in or
4
+ # sign_out a user. Do not use Devise::TestHelpers in integration tests.
5
+ #
6
+ # Notice you should not test Warden specific behavior (like Warden callbacks)
7
+ # using Devise::TestHelpers since it is a stub of the actual behavior. Such
8
+ # callbacks should be tested in your integration suite instead.
9
+ module TestHelpers
10
+ def self.included(base)
11
+ base.class_eval do
12
+ setup :setup_controller_for_warden, :warden if respond_to?(:setup)
13
+ end
14
+ end
15
+
16
+ # Override process to consider warden.
17
+ def process(*)
18
+ # Make sure we always return @response, a la ActionController::TestCase::Behaviour#process, even if warden interrupts
19
+ _catch_warden { super } || @response
20
+ end
21
+
22
+ # We need to setup the environment variables and the response in the controller.
23
+ def setup_controller_for_warden #:nodoc:
24
+ @request.env['action_controller.instance'] = @controller
25
+ end
26
+
27
+ # Quick access to Warden::Proxy.
28
+ def warden #:nodoc:
29
+ @warden ||= begin
30
+ manager = Warden::Manager.new(nil) do |config|
31
+ config.merge! Devise.warden_config
32
+ end
33
+ @request.env['warden'] = Warden::Proxy.new(@request.env, manager)
34
+ end
35
+ end
36
+
37
+ # sign_in a given resource by storing its keys in the session.
38
+ # This method bypass any warden authentication callback.
39
+ #
40
+ # Examples:
41
+ #
42
+ # sign_in :user, @user # sign_in(scope, resource)
43
+ # sign_in @user # sign_in(resource)
44
+ #
45
+ def sign_in(resource_or_scope, resource=nil)
46
+ scope ||= Devise::Mapping.find_scope!(resource_or_scope)
47
+ resource ||= resource_or_scope
48
+ warden.instance_variable_get(:@users).delete(scope)
49
+ warden.session_serializer.store(resource, scope)
50
+ end
51
+
52
+ # Sign out a given resource or scope by calling logout on Warden.
53
+ # This method bypass any warden logout callback.
54
+ #
55
+ # Examples:
56
+ #
57
+ # sign_out :user # sign_out(scope)
58
+ # sign_out @user # sign_out(resource)
59
+ #
60
+ def sign_out(resource_or_scope)
61
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
62
+ @controller.instance_variable_set(:"@current_#{scope}", nil)
63
+ user = warden.instance_variable_get(:@users).delete(scope)
64
+ warden.session_serializer.delete(scope, user)
65
+ end
66
+
67
+ protected
68
+
69
+ # Catch warden continuations and handle like the middleware would.
70
+ # Returns nil when interrupted, otherwise the normal result of the block.
71
+ def _catch_warden(&block)
72
+ result = catch(:warden, &block)
73
+
74
+ env = @controller.request.env
75
+
76
+ result ||= {}
77
+
78
+ # Set the response. In production, the rack result is returned
79
+ # from Warden::Manager#call, which the following is modelled on.
80
+ case result
81
+ when Array
82
+ if result.first == 401 && intercept_401?(env) # does this happen during testing?
83
+ _process_unauthenticated(env)
84
+ else
85
+ result
86
+ end
87
+ when Hash
88
+ _process_unauthenticated(env, result)
89
+ else
90
+ result
91
+ end
92
+ end
93
+
94
+ def _process_unauthenticated(env, options = {})
95
+ options[:action] ||= :unauthenticated
96
+ proxy = env['warden']
97
+ result = options[:result] || proxy.result
98
+
99
+ ret = case result
100
+ when :redirect
101
+ body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
102
+ [proxy.status, proxy.headers, [body]]
103
+ when :custom
104
+ proxy.custom_response
105
+ else
106
+ env["PATH_INFO"] = "/#{options[:action]}"
107
+ env["warden.options"] = options
108
+ Warden::Manager._run_callbacks(:before_failure, env, options)
109
+
110
+ status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
111
+ @controller.response.headers.merge!(headers)
112
+ @controller.send :render, status: status, text: response.body,
113
+ content_type: headers["Content-Type"], location: headers["Location"]
114
+ nil # causes process return @response
115
+ end
116
+
117
+ # ensure that the controller response is set up. In production, this is
118
+ # not necessary since warden returns the results to rack. However, at
119
+ # testing time, we want the response to be available to the testing
120
+ # framework to verify what would be returned to rack.
121
+ if ret.is_a?(Array)
122
+ # ensure the controller response is set to our response.
123
+ @controller.response ||= @response
124
+ @response.status = ret.first
125
+ @response.headers = ret.second
126
+ @response.body = ret.third
127
+ end
128
+
129
+ ret
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,14 @@
1
+ require "active_support/core_ext/module/delegation"
2
+
3
+ module Devise
4
+ class TimeInflector
5
+ include ActionView::Helpers::DateHelper
6
+
7
+ class << self
8
+ attr_reader :instance
9
+ delegate :time_ago_in_words, to: :instance
10
+ end
11
+
12
+ @instance = new
13
+ end
14
+ end