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,239 @@
1
+ require 'test_helper'
2
+
3
+ class LockTest < ActionDispatch::IntegrationTest
4
+
5
+ def visit_user_unlock_with_token(unlock_token)
6
+ visit user_unlock_path(unlock_token: unlock_token)
7
+ end
8
+
9
+ def send_unlock_request
10
+ user = create_user(locked: true)
11
+ ActionMailer::Base.deliveries.clear
12
+
13
+ visit new_user_session_path
14
+ click_link "Didn't receive unlock instructions?"
15
+
16
+ Devise.stubs(:friendly_token).returns("abcdef")
17
+ fill_in 'email', with: user.email
18
+ click_button 'Resend unlock instructions'
19
+ end
20
+
21
+ test 'user should be able to request a new unlock token' do
22
+ send_unlock_request
23
+
24
+ assert_template 'sessions/new'
25
+ assert_contain 'You will receive an email with instructions for how to unlock your account in a few minutes'
26
+
27
+ mail = ActionMailer::Base.deliveries.last
28
+ assert_equal 1, ActionMailer::Base.deliveries.size
29
+ assert_equal ['please-change-me@config-initializers-devise.com'], mail.from
30
+ assert_match user_unlock_path(unlock_token: 'abcdef'), mail.body.encoded
31
+ end
32
+
33
+ test 'user should receive the instructions from a custom mailer' do
34
+ User.any_instance.stubs(:devise_mailer).returns(Users::Mailer)
35
+
36
+ send_unlock_request
37
+
38
+ assert_equal ['custom@example.com'], ActionMailer::Base.deliveries.first.from
39
+ end
40
+
41
+ test 'unlocked user should not be able to request a unlock token' do
42
+ user = create_user(locked: false)
43
+ ActionMailer::Base.deliveries.clear
44
+
45
+ visit new_user_session_path
46
+ click_link "Didn't receive unlock instructions?"
47
+
48
+ fill_in 'email', with: user.email
49
+ click_button 'Resend unlock instructions'
50
+
51
+ assert_template 'unlocks/new'
52
+ assert_contain 'not locked'
53
+ assert_equal 0, ActionMailer::Base.deliveries.size
54
+ end
55
+
56
+ test 'unlocked pages should not be available if email strategy is disabled' do
57
+ visit "/admin_area/sign_in"
58
+
59
+ assert_raise Webrat::NotFoundError do
60
+ click_link "Didn't receive unlock instructions?"
61
+ end
62
+
63
+ assert_raise NameError do
64
+ visit new_admin_unlock_path
65
+ end
66
+
67
+ assert_raise ActionController::RoutingError do
68
+ visit "/admin_area/unlock/new"
69
+ end
70
+ end
71
+
72
+ test 'user with invalid unlock token should not be able to unlock an account' do
73
+ visit_user_unlock_with_token('invalid_token')
74
+
75
+ assert_response :success
76
+ assert_current_url '/users/unlock?unlock_token=invalid_token'
77
+ assert_have_selector '#error_explanation'
78
+ assert_contain /Unlock token(.*)invalid/
79
+ end
80
+
81
+ test "locked user should be able to unlock account" do
82
+ user = create_user
83
+ raw = user.lock_access!
84
+ visit_user_unlock_with_token(raw)
85
+
86
+ assert_current_url "/users/sign_in"
87
+ assert_contain 'Your account has been unlocked successfully. Please sign in to continue.'
88
+ assert_not user.reload.access_locked?
89
+ end
90
+
91
+ test "user should not send a new e-mail if already locked" do
92
+ user = create_user(locked: true)
93
+ user.failed_attempts = User.maximum_attempts + 1
94
+ user.save!
95
+
96
+ ActionMailer::Base.deliveries.clear
97
+
98
+ sign_in_as_user(password: "invalid")
99
+ assert_contain 'Your account is locked.'
100
+ assert ActionMailer::Base.deliveries.empty?
101
+ end
102
+
103
+ test 'error message is configurable by resource name' do
104
+ store_translations :en, devise: {
105
+ failure: {user: {locked: "You are locked!"}}
106
+ } do
107
+
108
+ user = create_user(locked: true)
109
+ user.failed_attempts = User.maximum_attempts + 1
110
+ user.save!
111
+
112
+ sign_in_as_user(password: "invalid")
113
+ assert_contain "You are locked!"
114
+ end
115
+ end
116
+
117
+ test "user should not be able to sign in when locked" do
118
+ store_translations :en, devise: {
119
+ failure: {user: {locked: "You are locked!"}}
120
+ } do
121
+
122
+ user = create_user(locked: true)
123
+ user.failed_attempts = User.maximum_attempts + 1
124
+ user.save!
125
+
126
+ sign_in_as_user(password: "123456")
127
+ assert_contain "You are locked!"
128
+ end
129
+ end
130
+
131
+ test 'user should be able to request a new unlock token via XML request' do
132
+ user = create_user(locked: true)
133
+ ActionMailer::Base.deliveries.clear
134
+
135
+ post user_unlock_path(format: 'xml'), user: {email: user.email}
136
+ assert_response :success
137
+ assert_equal response.body, {}.to_xml
138
+ assert_equal 1, ActionMailer::Base.deliveries.size
139
+ end
140
+
141
+ test 'unlocked user should not be able to request a unlock token via XML request' do
142
+ user = create_user(locked: false)
143
+ ActionMailer::Base.deliveries.clear
144
+
145
+ post user_unlock_path(format: 'xml'), user: {email: user.email}
146
+ assert_response :unprocessable_entity
147
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
148
+ assert_equal 0, ActionMailer::Base.deliveries.size
149
+ end
150
+
151
+ test 'user with valid unlock token should be able to unlock account via XML request' do
152
+ user = create_user()
153
+ raw = user.lock_access!
154
+ assert user.access_locked?
155
+ get user_unlock_path(format: 'xml', unlock_token: raw)
156
+ assert_response :success
157
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
158
+ end
159
+
160
+
161
+ test 'user with invalid unlock token should not be able to unlock the account via XML request' do
162
+ get user_unlock_path(format: 'xml', unlock_token: 'invalid_token')
163
+ assert_response :unprocessable_entity
164
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
165
+ end
166
+
167
+ test "when using json to ask a unlock request, should not return the user" do
168
+ user = create_user(locked: true)
169
+ post user_unlock_path(format: "json", user: {email: user.email})
170
+ assert_response :success
171
+ assert_equal response.body, {}.to_json
172
+ end
173
+
174
+ test "in paranoid mode, when trying to unlock an user that exists it should not say that it exists if it is locked" do
175
+ swap Devise, paranoid: true do
176
+ user = create_user(locked: true)
177
+
178
+ visit new_user_session_path
179
+ click_link "Didn't receive unlock instructions?"
180
+
181
+ fill_in 'email', with: user.email
182
+ click_button 'Resend unlock instructions'
183
+
184
+ assert_current_url "/users/sign_in"
185
+ assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
186
+ end
187
+ end
188
+
189
+ test "in paranoid mode, when trying to unlock an user that exists it should not say that it exists if it is not locked" do
190
+ swap Devise, paranoid: true do
191
+ user = create_user(locked: false)
192
+
193
+ visit new_user_session_path
194
+ click_link "Didn't receive unlock instructions?"
195
+
196
+ fill_in 'email', with: user.email
197
+ click_button 'Resend unlock instructions'
198
+
199
+ assert_current_url "/users/sign_in"
200
+ assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
201
+ end
202
+ end
203
+
204
+ test "in paranoid mode, when trying to unlock an user that does not exists it should not say that it does not exists" do
205
+ swap Devise, paranoid: true do
206
+ visit new_user_session_path
207
+ click_link "Didn't receive unlock instructions?"
208
+
209
+ fill_in 'email', with: "arandomemail@hotmail.com"
210
+ click_button 'Resend unlock instructions'
211
+
212
+ assert_not_contain "1 error prohibited this user from being saved:"
213
+ assert_not_contain "Email not found"
214
+ assert_current_url "/users/sign_in"
215
+
216
+ assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
217
+
218
+ end
219
+ end
220
+
221
+ test "in paranoid mode, when locking a user that exists it should not say that the user was locked" do
222
+ swap Devise, paranoid: true, maximum_attempts: 1 do
223
+ user = create_user(locked: false)
224
+
225
+ visit new_user_session_path
226
+ fill_in 'email', with: user.email
227
+ fill_in 'password', with: "abadpassword"
228
+ click_button 'Log in'
229
+
230
+ fill_in 'email', with: user.email
231
+ fill_in 'password', with: "abadpassword"
232
+ click_button 'Log in'
233
+
234
+ assert_current_url "/users/sign_in"
235
+ assert_not_contain "locked"
236
+ end
237
+ end
238
+
239
+ end
@@ -0,0 +1,133 @@
1
+ require 'test_helper'
2
+
3
+
4
+ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
5
+ FACEBOOK_INFO = {
6
+ "id" => '12345',
7
+ "link" => 'http://facebook.com/josevalim',
8
+ "email" => 'user@example.com',
9
+ "first_name" => 'Jose',
10
+ "last_name" => 'Valim',
11
+ "website" => 'http://blog.plataformatec.com.br'
12
+ }
13
+
14
+ setup do
15
+ OmniAuth.config.test_mode = true
16
+ OmniAuth.config.mock_auth[:facebook] = {
17
+ "uid" => '12345',
18
+ "provider" => 'facebook',
19
+ "user_info" => {"nickname" => 'josevalim'},
20
+ "credentials" => {"token" => 'plataformatec'},
21
+ "extra" => {"user_hash" => FACEBOOK_INFO}
22
+ }
23
+ end
24
+
25
+ teardown do
26
+ OmniAuth.config.test_mode = false
27
+ end
28
+
29
+ def stub_action!(name)
30
+ Users::OmniauthCallbacksController.class_eval do
31
+ alias_method :__old_facebook, :facebook
32
+ alias_method :facebook, name
33
+ end
34
+ yield
35
+ ensure
36
+ Users::OmniauthCallbacksController.class_eval do
37
+ alias_method :facebook, :__old_facebook
38
+ end
39
+ end
40
+
41
+ test "can access omniauth.auth in the env hash" do
42
+ visit "/users/sign_in"
43
+ click_link "Sign in with Facebook"
44
+
45
+ json = ActiveSupport::JSON.decode(response.body)
46
+
47
+ assert_equal "12345", json["uid"]
48
+ assert_equal "facebook", json["provider"]
49
+ assert_equal "josevalim", json["user_info"]["nickname"]
50
+ assert_equal FACEBOOK_INFO, json["extra"]["user_hash"]
51
+ assert_equal "plataformatec", json["credentials"]["token"]
52
+ end
53
+
54
+ test "cleans up session on sign up" do
55
+ assert_no_difference "User.count" do
56
+ visit "/users/sign_in"
57
+ click_link "Sign in with Facebook"
58
+ end
59
+
60
+ assert session["devise.facebook_data"]
61
+
62
+ assert_difference "User.count" do
63
+ visit "/users/sign_up"
64
+ fill_in "Password", with: "12345678"
65
+ fill_in "Password confirmation", with: "12345678"
66
+ click_button "Sign up"
67
+ end
68
+
69
+ assert_current_url "/"
70
+ assert_contain "You have signed up successfully."
71
+ assert_contain "Hello User user@example.com"
72
+ assert_not session["devise.facebook_data"]
73
+ end
74
+
75
+ test "cleans up session on cancel" do
76
+ assert_no_difference "User.count" do
77
+ visit "/users/sign_in"
78
+ click_link "Sign in with Facebook"
79
+ end
80
+
81
+ assert session["devise.facebook_data"]
82
+ visit "/users/cancel"
83
+ assert !session["devise.facebook_data"]
84
+ end
85
+
86
+ test "cleans up session on sign in" do
87
+ assert_no_difference "User.count" do
88
+ visit "/users/sign_in"
89
+ click_link "Sign in with Facebook"
90
+ end
91
+
92
+ assert session["devise.facebook_data"]
93
+ sign_in_as_user
94
+ assert !session["devise.facebook_data"]
95
+ end
96
+
97
+ test "sign in and send remember token if configured" do
98
+ visit "/users/sign_in"
99
+ click_link "Sign in with Facebook"
100
+ assert_nil warden.cookies["remember_user_token"]
101
+
102
+ stub_action!(:sign_in_facebook) do
103
+ create_user
104
+ visit "/users/sign_in"
105
+ click_link "Sign in with Facebook"
106
+ assert warden.authenticated?(:user)
107
+ assert warden.cookies["remember_user_token"]
108
+ end
109
+ end
110
+
111
+ test "generates a proper link when SCRIPT_NAME is set" do
112
+ header 'SCRIPT_NAME', '/q'
113
+ visit "/users/sign_in"
114
+ assert_select "a", href: "/q/users/auth/facebook"
115
+ end
116
+
117
+ test "handles callback error parameter according to the specification" do
118
+ OmniAuth.config.mock_auth[:facebook] = :access_denied
119
+ visit "/users/auth/facebook/callback?error=access_denied"
120
+ assert_current_url "/users/sign_in"
121
+ assert_contain 'Could not authenticate you from Facebook because "Access denied".'
122
+ end
123
+
124
+ test "handles other exceptions from OmniAuth" do
125
+ OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
126
+
127
+ visit "/users/sign_in"
128
+ click_link "Sign in with Facebook"
129
+
130
+ assert_current_url "/users/sign_in"
131
+ assert_contain 'Could not authenticate you from Facebook because "Invalid credentials".'
132
+ end
133
+ end
@@ -0,0 +1,334 @@
1
+ require 'test_helper'
2
+
3
+ class PasswordTest < ActionDispatch::IntegrationTest
4
+
5
+ def visit_new_password_path
6
+ visit new_user_session_path
7
+ click_link 'Forgot your password?'
8
+ end
9
+
10
+ def request_forgot_password(&block)
11
+ visit_new_password_path
12
+ assert_response :success
13
+ assert_not warden.authenticated?(:user)
14
+
15
+ fill_in 'email', with: 'user@test.com'
16
+ yield if block_given?
17
+
18
+ Devise.stubs(:friendly_token).returns("abcdef")
19
+ click_button 'Send me reset password instructions'
20
+ end
21
+
22
+ def reset_password(options={}, &block)
23
+ unless options[:visit] == false
24
+ visit edit_user_password_path(reset_password_token: options[:reset_password_token] || "abcdef")
25
+ assert_response :success
26
+ end
27
+
28
+ fill_in 'New password', with: '987654321'
29
+ fill_in 'Confirm new password', with: '987654321'
30
+ yield if block_given?
31
+ click_button 'Change my password'
32
+ end
33
+
34
+ test 'reset password with email of different case should succeed when email is in the list of case insensitive keys' do
35
+ create_user(email: 'Foo@Bar.com')
36
+
37
+ request_forgot_password do
38
+ fill_in 'email', with: 'foo@bar.com'
39
+ end
40
+
41
+ assert_current_url '/users/sign_in'
42
+ assert_contain 'You will receive an email with instructions on how to reset your password in a few minutes.'
43
+ end
44
+
45
+ test 'reset password with email should send an email from a custom mailer' do
46
+ create_user(email: 'Foo@Bar.com')
47
+
48
+ User.any_instance.stubs(:devise_mailer).returns(Users::Mailer)
49
+ request_forgot_password do
50
+ fill_in 'email', with: 'foo@bar.com'
51
+ end
52
+
53
+ mail = ActionMailer::Base.deliveries.last
54
+ assert_equal ['custom@example.com'], mail.from
55
+ assert_match edit_user_password_path(reset_password_token: 'abcdef'), mail.body.encoded
56
+ end
57
+
58
+ test 'reset password with email of different case should fail when email is NOT the list of case insensitive keys' do
59
+ swap Devise, case_insensitive_keys: [] do
60
+ create_user(email: 'Foo@Bar.com')
61
+
62
+ request_forgot_password do
63
+ fill_in 'email', with: 'foo@bar.com'
64
+ end
65
+
66
+ assert_response :success
67
+ assert_current_url '/users/password'
68
+ assert_have_selector "input[type=email][value='foo@bar.com']"
69
+ assert_contain 'not found'
70
+ end
71
+ end
72
+
73
+ test 'reset password with email with extra whitespace should succeed when email is in the list of strip whitespace keys' do
74
+ create_user(email: 'foo@bar.com')
75
+
76
+ request_forgot_password do
77
+ fill_in 'email', with: ' foo@bar.com '
78
+ end
79
+
80
+ assert_current_url '/users/sign_in'
81
+ assert_contain 'You will receive an email with instructions on how to reset your password in a few minutes.'
82
+ end
83
+
84
+ test 'reset password with email with extra whitespace should fail when email is NOT the list of strip whitespace keys' do
85
+ swap Devise, strip_whitespace_keys: [] do
86
+ create_user(email: 'foo@bar.com')
87
+
88
+ request_forgot_password do
89
+ fill_in 'email', with: ' foo@bar.com '
90
+ end
91
+
92
+ assert_response :success
93
+ assert_current_url '/users/password'
94
+ assert_have_selector "input[type=email][value=' foo@bar.com ']"
95
+ assert_contain 'not found'
96
+ end
97
+ end
98
+
99
+ test 'authenticated user should not be able to visit forgot password page' do
100
+ sign_in_as_user
101
+ assert warden.authenticated?(:user)
102
+
103
+ get new_user_password_path
104
+
105
+ assert_response :redirect
106
+ assert_redirected_to root_path
107
+ end
108
+
109
+ test 'not authenticated user should be able to request a forgot password' do
110
+ create_user
111
+ request_forgot_password
112
+
113
+ assert_current_url '/users/sign_in'
114
+ assert_contain 'You will receive an email with instructions on how to reset your password in a few minutes.'
115
+ end
116
+
117
+ test 'not authenticated user with invalid email should receive an error message' do
118
+ request_forgot_password do
119
+ fill_in 'email', with: 'invalid.test@test.com'
120
+ end
121
+
122
+ assert_response :success
123
+ assert_current_url '/users/password'
124
+ assert_have_selector "input[type=email][value='invalid.test@test.com']"
125
+ assert_contain 'not found'
126
+ end
127
+
128
+ test 'authenticated user should not be able to visit edit password page' do
129
+ sign_in_as_user
130
+ get edit_user_password_path
131
+ assert_response :redirect
132
+ assert_redirected_to root_path
133
+ assert warden.authenticated?(:user)
134
+ end
135
+
136
+ test 'not authenticated user without a reset password token should not be able to visit the page' do
137
+ get edit_user_password_path
138
+ assert_response :redirect
139
+ assert_redirected_to "/users/sign_in"
140
+ end
141
+
142
+ test 'not authenticated user with invalid reset password token should not be able to change their password' do
143
+ user = create_user
144
+ reset_password reset_password_token: 'invalid_reset_password'
145
+
146
+ assert_response :success
147
+ assert_current_url '/users/password'
148
+ assert_have_selector '#error_explanation'
149
+ assert_contain /Reset password token(.*)invalid/
150
+ assert_not user.reload.valid_password?('987654321')
151
+ end
152
+
153
+ test 'not authenticated user with valid reset password token but invalid password should not be able to change their password' do
154
+ user = create_user
155
+ request_forgot_password
156
+ reset_password do
157
+ fill_in 'Confirm new password', with: 'other_password'
158
+ end
159
+
160
+ assert_response :success
161
+ assert_current_url '/users/password'
162
+ assert_have_selector '#error_explanation'
163
+ assert_contain Devise.rails4? ?
164
+ "Password confirmation doesn't match Password" : "Password doesn't match confirmation"
165
+ assert_not user.reload.valid_password?('987654321')
166
+ end
167
+
168
+ test 'not authenticated user with valid data should be able to change their password' do
169
+ user = create_user
170
+ request_forgot_password
171
+ reset_password
172
+
173
+ assert_current_url '/'
174
+ assert_contain 'Your password has been changed successfully. You are now signed in.'
175
+ assert user.reload.valid_password?('987654321')
176
+ end
177
+
178
+ test 'after entering invalid data user should still be able to change their password' do
179
+ user = create_user
180
+ request_forgot_password
181
+
182
+ reset_password { fill_in 'Confirm new password', with: 'other_password' }
183
+ assert_response :success
184
+ assert_have_selector '#error_explanation'
185
+ assert_not user.reload.valid_password?('987654321')
186
+
187
+ reset_password visit: false
188
+ assert_contain 'Your password has been changed successfully.'
189
+ assert user.reload.valid_password?('987654321')
190
+ end
191
+
192
+ test 'sign in user automatically after changing its password' do
193
+ create_user
194
+ request_forgot_password
195
+ reset_password
196
+
197
+ assert warden.authenticated?(:user)
198
+ end
199
+
200
+ test 'does not sign in user automatically after changing its password if it\'s locked and unlock strategy is :none or :time' do
201
+ [:none, :time].each do |strategy|
202
+ swap Devise, unlock_strategy: strategy do
203
+ user = create_user(locked: true)
204
+ request_forgot_password
205
+ reset_password
206
+
207
+ assert_contain 'Your password has been changed successfully.'
208
+ assert_not_contain 'You are now signed in.'
209
+ assert_equal new_user_session_path, @request.path
210
+ assert !warden.authenticated?(:user)
211
+ end
212
+ end
213
+ end
214
+
215
+ test 'unlocks and signs in locked user automatically after changing it\'s password if unlock strategy is :email' do
216
+ swap Devise, unlock_strategy: :email do
217
+ user = create_user(locked: true)
218
+ request_forgot_password
219
+ reset_password
220
+
221
+ assert_contain 'Your password has been changed successfully.'
222
+ assert !user.reload.access_locked?
223
+ assert warden.authenticated?(:user)
224
+ end
225
+ end
226
+
227
+ test 'unlocks and signs in locked user automatically after changing it\'s password if unlock strategy is :both' do
228
+ swap Devise, unlock_strategy: :both do
229
+ user = create_user(locked: true)
230
+ request_forgot_password
231
+ reset_password
232
+
233
+ assert_contain 'Your password has been changed successfully.'
234
+ assert !user.reload.access_locked?
235
+ assert warden.authenticated?(:user)
236
+ end
237
+ end
238
+
239
+ test 'reset password request with valid E-Mail in XML format should return valid response' do
240
+ create_user
241
+ post user_password_path(format: 'xml'), user: {email: "user@test.com"}
242
+ assert_response :success
243
+ assert_equal response.body, { }.to_xml
244
+ end
245
+
246
+ test 'reset password request with invalid E-Mail in XML format should return valid response' do
247
+ create_user
248
+ post user_password_path(format: 'xml'), user: {email: "invalid.test@test.com"}
249
+ assert_response :unprocessable_entity
250
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
251
+ end
252
+
253
+ test 'reset password request with invalid E-Mail in XML format should return empty and valid response' do
254
+ swap Devise, paranoid: true do
255
+ create_user
256
+ post user_password_path(format: 'xml'), user: {email: "invalid@test.com"}
257
+ assert_response :success
258
+ assert_equal response.body, { }.to_xml
259
+ end
260
+ end
261
+
262
+ test 'change password with valid parameters in XML format should return valid response' do
263
+ create_user
264
+ request_forgot_password
265
+ put user_password_path(format: 'xml'), user: {
266
+ reset_password_token: 'abcdef', password: '987654321', password_confirmation: '987654321'
267
+ }
268
+ assert_response :success
269
+ assert warden.authenticated?(:user)
270
+ end
271
+
272
+ test 'change password with invalid token in XML format should return invalid response' do
273
+ create_user
274
+ request_forgot_password
275
+ put user_password_path(format: 'xml'), user: {reset_password_token: 'invalid.token', password: '987654321', password_confirmation: '987654321'}
276
+ assert_response :unprocessable_entity
277
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
278
+ end
279
+
280
+ test 'change password with invalid new password in XML format should return invalid response' do
281
+ user = create_user
282
+ request_forgot_password
283
+ put user_password_path(format: 'xml'), user: {reset_password_token: user.reload.reset_password_token, password: '', password_confirmation: '987654321'}
284
+ assert_response :unprocessable_entity
285
+ assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
286
+ end
287
+
288
+ test "when using json requests to ask a confirmable request, should not return the object" do
289
+ user = create_user(confirm: false)
290
+
291
+ post user_password_path(format: :json), user: { email: user.email }
292
+
293
+ assert_response :success
294
+ assert_equal response.body, "{}"
295
+ end
296
+
297
+ test "when in paranoid mode and with an invalid e-mail, asking to reset a password should display a message that does not indicates that the e-mail does not exists in the database" do
298
+ swap Devise, paranoid: true do
299
+ visit_new_password_path
300
+ fill_in "email", with: "arandomemail@test.com"
301
+ click_button 'Send me reset password instructions'
302
+
303
+ assert_not_contain "1 error prohibited this user from being saved:"
304
+ assert_not_contain "Email not found"
305
+ assert_contain "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
306
+ assert_current_url "/users/sign_in"
307
+ end
308
+ end
309
+
310
+ test "when in paranoid mode and with a valid e-mail, asking to reset password should display a message that does not indicates that the email exists in the database and redirect to the failure route" do
311
+ swap Devise, paranoid: true do
312
+ user = create_user
313
+ visit_new_password_path
314
+ fill_in 'email', with: user.email
315
+ click_button 'Send me reset password instructions'
316
+
317
+ assert_contain "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
318
+ assert_current_url "/users/sign_in"
319
+ end
320
+ end
321
+
322
+ test "after recovering a password, should set failed attempts to 0" do
323
+ user = create_user
324
+ user.update_attribute(:failed_attempts, 10)
325
+
326
+ assert_equal 10, user.failed_attempts
327
+ request_forgot_password
328
+ reset_password
329
+
330
+ assert warden.authenticated?(:user)
331
+ user.reload
332
+ assert_equal 0, user.failed_attempts
333
+ end
334
+ end