Compare commits

...

381 Commits

Author SHA1 Message Date
José Valim
65947b6696 Release v3.2.2 2013-11-25 12:00:21 +01:00
Vasiliy Ermolovich
0028dc6a4f Merge pull request #2751 from fgo/patch-1
Fix spelling in README [ci skip]
2013-11-22 00:57:03 -08:00
Francis Go
f438209669 Fix spelling in README 2013-11-22 19:55:16 +11:00
José Valim
c85ecbb9ac Merge pull request #2750 from louman/master
Timeoutable - fixes missing caller
2013-11-21 08:38:12 -08:00
Marcus Mansur
b16899f7bf fixes timeoutable specs to cover sign_out_all_scopes false 2013-11-21 14:02:45 -02:00
Marcus Mansur
bd83483ba6 fixes missing caller 2013-11-21 13:26:34 -02:00
José Valim
0514e60bc4 Merge pull request #2749 from csexton/master
Keep the query string and path in store_location_for
2013-11-20 13:13:12 -08:00
Christopher Sexton
7afc096fa4 Keep the query string and path in store_location_for
Persist the URI's query when saving to the session.

Fixes #2742
2013-11-20 15:47:20 -05:00
Vasiliy Ermolovich
bb2ff3553b require rails generator base class in devise generators
closes #2743
2013-11-15 15:56:09 +03:00
José Valim
1390945e5c Improve default omniauth sample 2013-11-14 09:09:05 +01:00
José Valim
f36efc0cc9 Ensure multiple leading / are also removed, thanks @homakov 2013-11-13 15:01:23 +01:00
José Valim
3b598ec235 Release v3.2.1 2013-11-13 14:15:13 +01:00
José Valim
95ec62ea76 Ensure encryption on authentication 2013-11-13 13:45:34 +01:00
José Valim
9a412c139f Update CHANGELOG 2013-11-13 13:32:59 +01:00
José Valim
0582467032 Ensure we only store paths in store_location_for (thanks to @homakov for the tip) 2013-11-13 13:30:24 +01:00
José Valim
221be6d6ef Update bundled rails app 2013-11-13 13:29:25 +01:00
José Valim
ed86361b92 Merge pull request #2728 from edelpero/master
Adds yield around resource on devise controllers
2013-11-08 23:22:53 -08:00
José Valim
e303de9756 Merge pull request #2729 from matthewrudy/store-location-helper
Add store_location_for helper
2013-11-08 23:22:39 -08:00
Matthew Rudy Jacobs
268e486dbb Add store_location_for helper
This is used as a complement to `stored_location_for`.

Example:

Before authorizing with Omniauth;

  store_location_for(:user, dashboard_path)
  redirect_to user_omniauth_authorize_path(:facebook)

In our Omniauth callback

  sign_in(user)
  redirect_to stored_location_for(:user) || root_path
2013-11-09 00:59:00 +00:00
Ezequiel Delpero
989071144e Adds yield around resource on devise controllers
If you want to add a new behavior to your devise
controllers but you don't want to override devise's
default workflow, just pass a block around resource.

This would give you for example, the ability to
trigger background jobs after user signs in.
2013-11-08 20:43:08 -03:00
Rafael Mendonça França
25726becdd Merge pull request #2731 from plataformatec/lm-password-digest
Bring `password_digest` back.
2013-11-08 10:28:11 -08:00
Lucas Mazza
bf5bcd52cb Bring password_digest back.
This method is part of the protected API and is used by custom
encryption engines (like `devise-encryptable`) to hook the custom
encryption logic in the models.

Fixes #2730
2013-11-08 16:22:31 -02:00
José Valim
e26ea51fe5 Improve error message for wrongly nested omniauth callback 2013-11-07 14:30:32 +01:00
José Valim
c840fc419f Update Rails 3.2 lock too 2013-11-06 21:50:04 +01:00
José Valim
9d872709c0 Release Devise 3.2.0 2013-11-06 21:39:16 +01:00
José Valim
27bcefcf54 Ensure timeoutable hook respects Devise.sign_out_all_scopes configuration
Closes #2606
2013-11-06 21:07:38 +01:00
José Valim
4f1bf8f3f9 Split out sign_in/out functionality so it can be reused in hooks 2013-11-06 20:55:26 +01:00
José Valim
d49f0a1184 Update CHANGELOG 2013-11-06 20:34:57 +01:00
José Valim
a7624c8f51 Merge pull request #2227 from AlexanderZaytsev/master
Use mapping.fullpath in omniauth callbacks
2013-11-06 11:32:21 -08:00
andrew morton
52a3768451 A GET to sign in shouldn't extend the session. 2013-11-06 20:20:22 +01:00
José Valim
f5f7e97d8b Merge pull request #2718 from ssendev/flashing_formats
Separate redirects and flash messages in navigational_formats and flashing_formats
2013-11-06 00:10:23 -08:00
José Valim
13117f01be Merge pull request #2562 from devolute/master
passes headers through test helpers' response
2013-11-05 23:59:11 -08:00
Kaworu
fe1fb1f7a2 Don't use config option for flashing_formats 2013-11-01 22:25:15 +01:00
Kaworu
c87809a0f5 Separate redirects and flash messages in navigational_formats and flashing_formats 2013-11-01 21:47:40 +01:00
José Valim
9eb0768cb9 Add Rails 4 related todo 2013-10-31 14:40:44 +01:00
José Valim
e445039716 Merge pull request #2717 from memberful/2716-splat-sanitize-params
Splat the arguments to strong_parameters#permit, fixes #2716
2013-10-31 14:40:28 +01:00
José Valim
69d28f9b0e Add config.last_attempt_warning to default config 2013-10-26 11:56:31 +02:00
José Valim
5cb575bd48 Merge pull request #2705 from 13k/master
Fix configuration option name in CHANGELOG.
2013-10-24 14:43:37 -07:00
Kiyoshi '13k' Murata
88de877f8b Fix configuration option name in CHANGELOG.
[ci skip]
2013-10-24 19:37:47 -02:00
José Valim
5a363f5fcb Merge pull request #2703 from bbenezech/master
Add options for FailureApp's i18n_message. Similar #1633
2013-10-24 09:10:19 -07:00
Benoit Bénézech
04e47687b2 remove respond_to in favor of an implementation that returns options 2013-10-24 17:29:53 +02:00
Benoit Bénézech
d5514bf916 Add options for FailureApp's i18n_message. Similar #1633 2013-10-24 16:49:13 +02:00
José Valim
93649e21d0 Merge pull request #2700 from obiwanchinobi/task/document-after-db-auth-hook
Add documentation to the 'after_database_authentication' method.
2013-10-23 23:35:47 -07:00
Dave Tong
8bef8b87f1 Add documentation to the 'after_database_authentication' method. 2013-10-24 08:25:00 +11:00
José Valim
fb530110c7 Merge pull request #2697 from Lightpower/feature/last_attempt_message
Show last attempt message for last attempt, not for one-before-last one
2013-10-22 01:33:37 -07:00
Vitaly Bezkrovny
bb810cfb8f * show message for last attempt, not for one-before-last one;
* update test to check the message :invalid, :last_attempt, :locked
2013-10-22 00:43:56 +03:00
José Valim
a8069be4c8 Improve devise_for docs to be make routes integration more explicit 2013-10-21 13:28:20 +02:00
Jay Hayes
2296d14803 Add entry to changelog
[#2691]
[ci skip]

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>

Conflicts:
	CHANGELOG.md
2013-10-21 13:21:43 +02:00
Jay Hayes
21583cbf95 Update code comment to keep it up to date
[#2691]
[ci skip]
2013-10-21 13:21:11 +02:00
Jay Hayes
4861436298 Prevent mutation of orig values during case and wspace sanitizations 2013-10-21 13:21:05 +02:00
Vasiliy Ermolovich
844d467ab9 Update CHANGELOG [ci skip] 2013-10-20 17:55:51 +03:00
Vasiliy Ermolovich
520e2845ae Merge pull request #2689 from Lightpower/master
* typo
2013-10-16 14:53:38 -07:00
Vitaly Bezkrovny
aba19c1ca4 * typo 2013-10-16 23:57:11 +03:00
José Valim
986f52df2b Merge pull request #2687 from Lightpower/master
Warning of the last attempt password entering
2013-10-16 01:33:41 -07:00
Vitaly Bezkrovny
e20e446cf4 + last_attempt
+ @@last_attempt_warning

+ last_attempt? method;
* send :last_attempt key if it is the last attempt

+ test for last attempt

* update test to make two asserts

* update message
2013-10-15 01:53:56 +03:00
José Valim
e947a9cbec Merge pull request #2674 from jessy/master
Fix #2673 email templates generated with the good @token
2013-10-08 02:28:30 -07:00
Jessy Bernal
fa06b33dd3 Fix #2673 email templates generated with the good @token 2013-10-08 11:25:04 +02:00
José Valim
31971e69e6 Merge pull request #2669 from plataformatec/pr-2598-fixed
Fixed version of PR #2598
2013-10-06 04:22:45 -07:00
Vasiliy Ermolovich
fa16afd90a add CHANGELOG entry 2013-10-06 14:19:19 +03:00
Vasiliy Ermolovich
0d6493a9a5 proper hash comparing in Devise.bcrypt test 2013-10-06 14:19:08 +03:00
Aaron Patterson
5300bdabc8 add a class method so you can encrypt passwords from fixtures 2013-10-06 13:53:12 +03:00
José Valim
93f59dd63a Update CHANGELOG.md 2013-10-04 20:04:23 +02:00
José Valim
9281ac3958 Merge pull request #2663 from scaryzet/fix_expire_session_data_after_sign_in
Fix expire_session_data_after_sign_in!
2013-10-03 08:40:04 -07:00
Vasiliy Ermolovich
52300c033d Merge pull request #2662 from plataformatec/issue-2659
do not define mailer if ActionMailer is not defined
2013-10-03 08:17:18 -07:00
Vasiliy Ermolovich
036715facc do not define mailer if ActionMailer is not defined
closes #2659
2013-10-03 17:39:04 +03:00
Ivan Zhidkov
2351d0215a Fix expire_session_data_after_sign_in! 2013-10-03 18:34:39 +04:00
José Valim
eaad61b2da Make it clear a restart is required when setting the secret key 2013-10-01 17:12:08 +02:00
José Valim
c323065b57 Merge pull request #2634 from gregates/bug/confirmation_workflow
Tweaks confirmation flow for signed_in users
2013-09-16 07:17:46 -07:00
Greg Gates
989d7192fa Tweaks confirmation flow for signed_in users
For #2627

When allow_unconfirmed_access_for > 0, users may
be already signed in at the time they confirm
their account. Consequently, the default
confirmation should be compatible with this
possibility. Additionally, they should not be
redirected to the sign in form after confirmation
in this case. So I've changed
ConfirmationsController#after_confirmation_path_for
to send the user to the root path when signed in,
or the sign in form otherwise.
2013-09-16 10:12:15 -04:00
Vasiliy Ermolovich
acefa2f761 Merge pull request #2631 from vipulnsward/cleanup_tests
Cleanup tests for unused variables
2013-09-14 14:53:23 -07:00
Vipul A M
ae6a37f796 Cleanup tests for unused variables 2013-09-15 01:52:53 +05:30
Vasiliy Ermolovich
d75fd56f15 remove unused reset_password_token method
closes #2621
2013-09-14 12:30:23 +03:00
Vasiliy Ermolovich
4216c34538 fix markdown in CHANGELOG [ci skip]
closes #2626
2013-09-13 22:29:34 +03:00
José Valim
b24d178b21 Merge pull request #2628 from ricardohsd/master
Update wiki link on README.md
2013-09-13 04:53:58 -07:00
Ricardo Henrique
fc5522a8ed Update wiki link on README.md 2013-09-13 08:47:27 -03:00
Rafael Mendonça França
041fcf9080 Merge pull request #2608 from benmanns/patch-1
Update link to new contributors page
2013-09-04 11:46:07 -07:00
Benjamin Manns
f45d874ed9 Update link to new contributors page [ci skip] 2013-09-04 14:43:45 -04:00
Carlos Antonio da Silva
47d9f1b959 Fix changelog [ci skip] 2013-09-03 08:47:57 -03:00
José Valim
9464416c3e Bring back test removed by accident 2013-09-02 19:25:05 -03:00
José Valim
6b3b0c5e8c Remove deprecated token lookups 2013-09-02 19:23:15 -03:00
José Valim
dff7891b97 Get rid of token authentication 2013-09-02 19:15:47 -03:00
José Valim
07f0ee75ee Link to update gist on CHANGELOG for 3.0 update 2013-09-02 19:04:51 -03:00
José Valim
08edcc10fe Release 3.1.0 2013-09-02 19:02:48 -03:00
José Valim
2d919fba32 Merge pull request #2582 from tod-uma/master
Allowed updating of attributes without a password if password_required? resolves to false.
2013-09-02 14:46:08 -07:00
José Valim
843168d5c7 Merge pull request #2605 from sekrett/master
Handle nil failed_attempts
2013-09-02 04:44:48 -07:00
Alexander Zubkov
095572b6fd Add nulls to migration generator 2013-09-02 15:00:12 +04:00
Alexander Zubkov
b9112d4308 Handle nil failed_attempts 2013-09-02 14:48:19 +04:00
Vasiliy Ermolovich
23c5517009 add test for fc251c306c 2013-08-31 15:25:49 +03:00
José Valim
32e60fade5 Merge pull request #2604 from gregates/revise_locale_messages
Fixes incorrect flash message on confirmation
2013-08-31 02:49:02 -07:00
Greg Gates
fc251c306c Fixes incorrect flash message on confirmation
The :confirmed default message in devise.en.yml
used to say "You are now signed in." This is no
longer the default behavior in v3.1.0.

This commit renames that message to
:confirmed_and_signed_in and changes the :confirmed
message to be appropriate for the default post-
confirmation location (which is now the new session
page). The new :confirmed message reads:

"Your account was successfully confirmed. Please
sign in."
2013-08-30 17:16:56 -04:00
Rafael Mendonça França
f6a74e90e5 Merge pull request #2603 from rwz/patch-1
Consistent single quotes in devise.rb generator
2013-08-30 09:28:43 -07:00
Pavel Pravosud
91f2bce08e Consistent single quotes in devise.rb generator 2013-08-30 22:21:12 +07:00
Rafael Mendonça França
5e81210400 Merge pull request #2601 from theodorton/patch-1
Typo
2013-08-30 07:39:27 -07:00
Theodor Tonum
4b7fcac23a Typo 2013-08-30 16:38:34 +02:00
José Valim
213ed81641 Update CHANGELOG.md 2013-08-27 07:05:54 -03:00
José Valim
3232d14b20 token authenticatable mentions 2013-08-21 17:33:38 +02:00
José Valim
949c9e5ded Remove gem version from README (because it doesn't work when branched) 2013-08-21 17:30:01 +02:00
Tod Detre
66c829eef4 created update_resource method to allow subclass overwritting 2013-08-21 11:04:32 -04:00
Tod Detre
6a22e88dfa Allowed updating of attributes without a password if password_required? resolves to false 2013-08-20 16:36:35 -04:00
José Valim
605924a921 Add a test related to remember token generation 2013-08-19 20:48:36 +02:00
José Valim
72c3472fe1 Generate remember token 2013-08-19 20:33:21 +02:00
José Valim
ea870e0636 Credit where credit is due [ci skip] 2013-08-18 10:46:00 +02:00
José Valim
3f00d735a4 Mention the security announcement [ci skip] 2013-08-18 10:17:51 +02:00
José Valim
1437ae2ce3 Release v3.1.0.rc2 2013-08-18 10:13:53 +02:00
Andri Möll
052cbef205 Don't confirm email after password reset.
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2013-08-18 10:13:35 +02:00
José Valim
b1754074e5 Only raise on missing secret key after a route is defined 2013-08-18 09:55:05 +02:00
José Valim
e8b70bb04d Include registration on docs 2013-08-17 09:19:28 +02:00
José Valim
58cbd91512 Do not do double redirect on after confirmation path 2013-08-13 18:55:50 +02:00
Carlos Antonio da Silva
177ed8a356 Bump up lock dependencies 2013-08-13 13:43:40 -03:00
Carlos Antonio da Silva
a5e63d7a28 Update Gemfile.lock with new Devise version
Also bump master with latest mongoid
2013-08-13 13:43:21 -03:00
José Valim
5ecbbdf260 Update version.rb 2013-08-13 18:22:19 +02:00
José Valim
efe34219a9 Fix the build on Rails 3.2 2013-08-12 15:36:41 +02:00
José Valim
bc0cab8d60 Update README.md
Remove unnecessary maintainers list
2013-08-12 15:25:44 +02:00
José Valim
7e855eddef Credit where credit is due 2013-08-11 22:30:19 +02:00
José Valim
8541c465d7 Convert CHANGELOG to markdown 2013-08-11 22:20:59 +02:00
José Valim
4e318b5167 Simplify parameter sanitization proposal 2013-08-11 22:20:59 +02:00
Alex Peattie
5e7caffc9e Extend params sanitizer, to make it easier to add/remove permitted params
- Move the default permitted parameters into ParameterSanitizer::PermittedParameters
- Add devise_permitted_parameters helper
- devise_permitted_parameters.add to add permitted parameters
- devise_permitted_parameters.remove to remove Devise's defaults
- devise_permitted_parameters.for to access the parameters for a given action
- Update 'Strong Parameters' section of README

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2013-08-11 22:20:59 +02:00
José Valim
87edf0fbcf Merge pull request #2564 from glebm/doc-confirmable-fix
fix doc typo
2013-08-09 23:49:44 -07:00
Gleb Mazovetskiy
e7de0d4c4c fix doc typo 2013-08-10 04:43:25 +02:00
José Valim
2a8d0f9bee Update CHANGELOG 2013-08-09 10:30:29 +02:00
chris
a1d83d5d4e passes headers through test helpers' response 2013-08-09 09:51:05 +02:00
José Valim
4681f81ce6 Document the :store option for sign in 2013-08-09 08:37:27 +02:00
José Valim
86f2696b84 Merge pull request #2529 from papercavalier/lang-edit
Grammar
2013-08-08 13:39:50 -07:00
José Valim
20cf73facf Merge pull request #2549 from joaomilho/master
Using urlsafe_base64 cause it already handle url sensitive chars, keepin...
2013-08-08 13:38:05 -07:00
José Valim
d0219d914f Merge pull request #2560 from aarvay/patch-1
Added an extra validation to shared links
2013-08-08 13:37:45 -07:00
José Valim
50d17bbb8e Update CHANGELOG 2013-08-08 22:37:15 +02:00
José Valim
3dccf3c6ff Do not sign in after confirmation 2013-08-08 22:33:58 +02:00
Vignesh Rajagopalan
acd33174fc Added an extra validation to shared links 2013-08-08 18:05:19 +05:30
José Valim
d56641f514 Move to SHA256 2013-08-06 12:14:51 +02:00
José Valim
354e5022bf Only allow insecure token lookup if a flag is given 2013-08-06 11:55:13 +02:00
José Valim
3cdbf15fe9 Update OTHER lock 2013-08-05 19:24:04 +02:00
José Valim
143794d701 Use HMAC on tokens stored in the DB 2013-08-05 18:56:07 +02:00
Juan Lulkin
4048545151 Using urlsafe_base64 cause it already handle url sensitive chars, keeping the replacement of the confusing chars, though 2013-08-05 14:54:56 +03:00
José Valim
32648027e2 Add Devise::KeyGenerator 2013-08-05 11:47:36 +02:00
José Valim
7e96bac6a4 Get rid of deprecated code 2013-08-05 11:24:04 +02:00
José Valim
f5a77ac598 Skip storage for cookies on unverified requests 2013-08-05 10:24:11 +02:00
José Valim
591f4a97f7 Update the OTHER gemfile 2013-08-02 23:57:43 +02:00
José Valim
cf1989e1da Update Gemfile.lock 2013-08-02 23:43:07 +02:00
José Valim
7c8c0f8dba Release 3.0.1 2013-08-02 23:25:11 +02:00
José Valim
66afa2a2bf Update CHANGELOG 2013-08-02 23:14:54 +02:00
José Valim
747751a20f Protect against CSRF token fixation attacks 2013-08-02 23:13:15 +02:00
José Valim
8e0327e203 Merge pull request #2530 from barodeur/patch-1
Remove trailing whitespaces
2013-07-28 14:25:39 -07:00
Paul Chobert
d88b3cedfb Remove trailing whitespaces 2013-07-28 23:15:42 +02:00
hakanensari
9a60415e2e Fix assertion 2013-07-26 19:31:49 +01:00
hakanensari
b861a65e72 Fix run-on sentence 2013-07-26 14:24:19 +01:00
hakanensari
1ab7792beb Fix grammar 2013-07-26 14:24:13 +01:00
José Valim
c4d5a3fdaa No need to assert for a message we won't receive 2013-07-26 10:00:09 +02:00
José Valim
11a77055f1 Merge pull request #2525 from jetthoughts/timeoutable-without-rememberable
Fixed checking for rememberable in timeoutable
2013-07-26 00:58:09 -07:00
José Valim
9bc8e1211b Update CHANGELOG 2013-07-26 09:22:59 +02:00
José Valim
cd1bc53947 Do not generate attr_accessible for any Rails 4 app 2013-07-26 09:22:03 +02:00
Michael Nikitochkin
fffbeb5cc7 Fixed bug when user has field remember_created_at but the module rememberable is not enabled for the user 2013-07-26 10:20:29 +03:00
José Valim
7539d31a05 Update 3.2 Gemfile 2013-07-26 09:17:35 +02:00
José Valim
78fedd6c10 Merge pull request #2523 from Neschur/add_method_after_confrimation
Added method after_confrimation
2013-07-25 23:59:50 -07:00
José Valim
14a0cfefaa Merge pull request #2522 from jcoyne/attr_accessible
When using rails 3.2, the generator adds 'attr_accessible' to the model....
2013-07-25 23:56:03 -07:00
Justin Coyne
b7e67115fc When using rails 3.2, the generator adds 'attr_accessible' to the model. Fixes #2515 2013-07-23 22:49:05 -05:00
Siarhei Hanchuk
b7bc8dec12 Added method after_confrimation 2013-07-23 14:19:58 +03:00
José Valim
b8ed2f3160 Clarify the roles of Devise models 2013-07-23 10:21:01 +02:00
José Valim
b46b7e3736 Release v3.0.0 2013-07-14 20:40:56 +02:00
José Valim
c5ef39f087 Bump to Warden 1.2.3 2013-07-14 20:40:09 +02:00
José Valim
cfb8228de9 Merge pull request #2506 from mxhold/master
Update README.md
2013-07-14 11:20:35 -07:00
Max Holder
4e0c598de1 Update README.md
Replace case statement with if statement since we're comparing two equivalent classes (which would never be case equivalent).
2013-07-14 10:35:11 -04:00
José Valim
fed6a92d55 Merge pull request #2504 from plataformatec/remember-me
Add remember_me to the permitted sign_in params
2013-07-12 12:19:35 -07:00
Vasiliy Ermolovich
2c1ca126f4 add remember_me to the permitted sign_in params 2013-07-12 22:14:32 +03:00
Vasiliy Ermolovich
36fb1ecf4d update Gemfile.lock 2013-07-12 22:13:52 +03:00
José Valim
08986dbd4b Merge pull request #2502 from slainer68/readme_strong_parameters
Update README.md [ci skip]
2013-07-12 04:26:59 -07:00
Nicolas Blanco
b69d2c412f Update README.md [ci skip]
Fix the example for Strong parameters multi roles as resource_class is actually a class not an instance.
2013-07-12 13:25:26 +02:00
José Valim
6f5d176e8e Bump warden dependency 2013-07-12 13:00:31 +02:00
José Valim
57515de5ad Update to Rails 4.0 2013-07-09 09:09:22 +02:00
José Valim
49aebde435 Update CHANGELOG 2013-07-09 09:05:19 +02:00
José Valim
bc598b9da3 Merge pull request #2452 from latortuga/bad-strong-params-on-failed-login
Add failing test case for bad parameter sanitizing when failing to login
2013-07-08 23:53:41 -07:00
José Valim
da0323e591 Merge pull request #2419 from plataformatec/issue-2418
set error to the field specified in unlock_keys config
2013-07-08 23:52:19 -07:00
José Valim
061e9d7404 Merge pull request #2475 from tkhr/enable_skipping_reconfirmation_notification_but_regenerate_confirmation_token_2
Enable to skip sending reconfirmation email when reconfirmable is on and skip_confirmation_notification! is invoked
2013-07-08 23:51:42 -07:00
José Valim
3c519b13ff Merge pull request #2485 from betelgeuse/changelog_fix
CHANGELOG fix about _links.erb partial revert
2013-07-03 03:58:13 -07:00
Petteri Räty
aeec6138c2 CHANGELOG fix about _links.erb partial revert
9bf718 got reverted by aa2d15 but the CHANGELOG was not reflected to
show this.
2013-07-03 13:34:25 +03:00
José Valim
75ad4ee87b Add thread-safety support note 2013-06-30 14:18:57 +02:00
Drew Ulmer
e029ad7b0c Fix improper login param sanitization permit
This includes a failing test case that hooks into ActiveSupport
Notifications to catch the param permit error.
2013-06-25 13:44:39 -05:00
José Valim
225afe6813 Merge pull request #2480 from robinroestenburg/patch-1
Updated section 'Configuring controllers'
2013-06-25 04:19:23 -07:00
Robin Roestenburg
8487637b2f Updated section 'Configuring controllers'
I added an extra note in the section on creating a custom (namespaced) controller. 

This controller needs to be created in a directory in order for it to work. Otherwise (for example when creating the controller in `app/controllers`) a `uninitialized constant Admins` error is thrown.

Also, fixed the Markdown formatting for the numbered lists in the README.
2013-06-25 14:01:11 +03:00
José Valim
8978bd4fe0 Merge pull request #2479 from djmaze/patch-1
Update code example for #update_without_password
2013-06-25 02:30:41 -07:00
Martin Honermeyer
5926898cf4 Update code example for #update_without_password 2013-06-25 11:27:35 +02:00
Takehiro Adachi
df2995ce19 Enable to skip sending reconfirmation email when skip_confirmation_notification! is invoked
We could always generate a confirmation token but not sending a
confirmation email by invoking the skip_confirmation_notification!
method when creating the account.
But there were no way to do that when we were turning on reconfirmable
and updating email.
2013-06-20 08:21:54 +09:00
José Valim
5717c6f082 Splat args to be sanitized 2013-06-19 10:37:37 +02:00
José Valim
72cf2481b5 Rename ParamFilter to ParameterFilter for consistency 2013-06-19 09:17:54 +02:00
José Valim
5c39a0c6d1 Merge pull request #2458 from t-kot/fix_access_locked_return_value
Fix access_locked? always return boolean
2013-06-12 20:45:25 -07:00
José Valim
56a26bd280 Merge pull request #2464 from sslotnick/expose_reset_confirm_tokens
Expose reset password and confirmation tokens
2013-06-12 20:44:45 -07:00
Steve Slotnick
b194882b23 Renaming get_or_create_*_token to ensure_*_token to match API in token authenticatable 2013-06-12 15:10:14 -07:00
Steve Slotnick
b5909f9b93 changing name from *_token! to get_or_create_*_token 2013-06-11 14:14:17 -07:00
Steve Slotnick
3c9cfa50c0 Adding publicly available methods on Recoverable and Confirmable to retrieve tokens 2013-06-10 19:17:19 -07:00
t-kot
e632240aee Fix access_locked? always return boolean 2013-06-07 12:11:00 +09:00
José Valim
176158a309 Just for Rails 3.2 2013-06-06 00:45:02 +08:00
Vasiliy Ermolovich
2503f2d0a8 Merge pull request #2453 from jroes/patch-1
Code formatting for class names and command [ci skip]
2013-06-05 06:32:02 -07:00
Jonathan Roes
85897b4fe2 Code formatting for class names and command 2013-06-05 09:22:55 -04:00
José Valim
fdd47d74db We are not duck typing here, so don't call the variable duck 2013-06-01 10:06:33 +09:00
Carlos Antonio da Silva
ae4448403c Change flash message to alert instead of error
Devise uses the defaults :notice and :alert everywhere, this one seems to
have been missed since it was introduced in
ff75341c75.
2013-05-29 21:34:28 -03:00
José Valim
2ead747be6 Merge pull request #2444 from julp/no_ghost_transactions
Fix empty transactions created by devise
2013-05-29 16:50:41 -07:00
julp
10aadee637 record is potentially unchanged here, if so, no needs to save it 2013-05-29 19:27:02 +02:00
julp
7670eb8e98 don't update failed_attempts attribute if already equal to 0 2013-05-29 19:24:51 +02:00
José Valim
486dc65884 Merge pull request #2430 from kramerc/blank-email
Avoid sending confirmations to blank emails.
2013-05-27 12:13:05 -07:00
Kramer Campbell
17e85aa79d Avoid sending confirmations to blank emails.
At times, validations may be skipped and no email address may be
provided. Such an instance comes when testing uniqueness validations of
specific attributes in a Devise model with confirmable, especially when
using Shoulda matchers.
2013-05-22 19:48:06 -07:00
José Valim
10c9a492ab Merge pull request #2427 from plataformatec/issue-2421
redirect user to the referrer if latest request was not GET after timeout
2013-05-19 08:07:43 -07:00
Vasiliy Ermolovich
b7079c7cf2 redirect user to the referrer if latest request was not GET after timeout
closes #2421
2013-05-19 17:11:34 +03:00
Vasiliy Ermolovich
55e69b18a4 Merge pull request #2424 from emilsoman/doc-fix
Update doc to mention http_authenticable is false by default [ci skip]
2013-05-17 14:29:31 -07:00
Emil Soman
020341176c Update doc to mention http_authenticable is false by default 2013-05-18 01:50:06 +05:30
Vasiliy Ermolovich
a79846730e Merge pull request #2422 from x3qt/patch-1
Fix typo in README.md [ci skip]
2013-05-17 04:19:16 -07:00
Yuri Pole
48eea9d325 Fix typo in README.md 2013-05-17 14:08:08 +03:00
Vasiliy Ermolovich
dd7c3ee91f set error to the field specified in unlock_keys config
closes #2418
2013-05-14 17:41:47 +03:00
José Valim
4e2cdc2d5b Merge pull request #2413 from jbhannah/master
Fix redundant assignment of self.resource in Devise::RegistrationsController
2013-05-09 21:40:11 -07:00
Jesse B. Hannah
545a5cec3b Fix redundant assignment of self.resource in Devise::RegistrationsController
Devise::RegistrationsController#create set self.resource to the return value of build_resource--which is nil, because build_resource sets self.resource to an actual resource object. This caused attempting to save the resource (two lines down) to fail with "undefined method `save' on nil:NilClass."
2013-05-09 18:33:30 -06:00
José Valim
ab77e08690 Update README.md 2013-05-07 16:18:48 -06:00
Carlos Antonio da Silva
39c1a2c7d0 Release 3.0.0.rc with Rails 4 support 2013-05-07 13:32:03 -03:00
Carlos Antonio da Silva
270e2ece19 Merge pull request #2376 from plataformatec/rails4
Support Rails 4

Keep compatibility with Rails 3.2. Drop support to Ruby 1.8.
2013-05-07 09:22:23 -07:00
Carlos Antonio da Silva
6b5988d756 Add changelog note about Rails 4 and Strong Params support
Plus dropping support for Rails < 3.2 and Ruby < 1.9.3
[ci skip]
2013-05-07 13:12:58 -03:00
Carlos Antonio da Silva
a4efbb9ad6 Update mongo revision 2013-05-07 13:05:02 -03:00
Carlos Antonio da Silva
eb0ad1c21a Merge branch 'master' into rails4 2013-05-07 13:01:34 -03:00
Carlos Antonio da Silva
f5e33089a0 Release 2.2.4 2013-05-07 12:51:46 -03:00
José Valim
e499fadf52 Use persisted? in order to check if the record was destoryed or not 2013-05-07 08:55:30 -06:00
Carlos Antonio da Silva
70199ed039 Bump webrat to 0.7.3 on 3.1 as well 2013-05-07 11:48:03 -03:00
Carlos Antonio da Silva
fb07558082 Update changelog with latest fixes [ci skip] 2013-05-07 11:48:03 -03:00
José Valim
5ad122b928 Fix build for mongoid 2013-05-07 08:47:18 -06:00
José Valim
c78b4b40c1 Remove warning since webrat is emitting tons of them 2013-05-07 08:22:06 -06:00
José Valim
ef2a2280a3 Update examples to be compatible with Rails 4 2013-05-07 08:18:12 -06:00
Carlos Antonio da Silva
42fca4dbe5 Update 3.1 lock file 2013-05-07 11:12:58 -03:00
José Valim
03f2a6a5e4 Merge pull request #2392 from michiel3/master
Add destroy_with_password method
2013-05-07 07:11:47 -07:00
José Valim
cc2fea8276 Merge pull request #2402 from xtream/master
Avoid duplication on param filter
2013-05-07 07:09:47 -07:00
José Valim
bb4cc2428f Merge pull request #2407 from sebastianwr/master
No redirect when accessing devise API via JSON
2013-05-07 07:08:53 -07:00
Sebastian Wramba
43f7cf0f12 No redirect when Devise API is accessed via JSON 2013-05-07 10:18:23 +02:00
Carlos Antonio da Silva
bb5d65209a Change rubygems source to use https [ci skip] 2013-05-06 23:04:49 -03:00
Carlos Antonio da Silva
69f79ad446 Let Devise play with both Rails 3.2 and Rails 4 for now 2013-05-05 19:55:06 -03:00
Victor Cruz Dueñas
75fdd2944d Avoid hash mutation 2013-05-05 10:12:57 +02:00
Victor Cruz Dueñas
ae48fc8419 Refactor to avoid duplication on param filter 2013-05-05 01:19:37 +02:00
Victor Cruz Dueñas
d6d61fc5be Adding tests for case_insensitive_keys and strip_whitespace_keys to param filter 2013-05-05 01:02:48 +02:00
Victor Cruz Dueñas
19c8f0c0ad Merge remote-tracking branch 'upstream/master'
Conflicts:
	app/controllers/devise/registrations_controller.rb
	test/integration/registerable_test.rb
2013-05-05 00:20:34 +02:00
Rafael Mendonça França
63627d1439 Refactoring the code a little bit
* Rename #get_constraints_given_method to #constraints_for to make the
  method clear.

* The method name now is required.

* Use symbols instead of strings.

* Make #constraints_for a protected method.
2013-05-04 14:33:55 -03:00
José Valim
662f0e76d8 Merge pull request #2401 from jd-erreape/master
Refactor to avoid repeated code
2013-05-04 09:06:16 -07:00
DI2uNk
eadce2fef6 Refactored rails/routes.rb to avoid repeated code 2013-05-04 11:56:56 +02:00
Carlos Antonio da Silva
0fe0373144 Fix location of parameter sanitizer in docs [ci skip] 2013-05-03 22:52:26 -03:00
Carlos Antonio da Silva
1f9ebbd9f4 Update gemspec dependency to Rails 4 rc1 as well 2013-05-03 22:04:27 -03:00
Carlos Antonio da Silva
a0058d5fbf Add some spaces, remove comment 2013-05-03 21:52:00 -03:00
Carlos Antonio da Silva
e8d1c9ca23 Bump rails version to 4.0.0.rc1, closes #2399 2013-05-03 10:00:39 -03:00
Carlos Antonio da Silva
d9d5ae3d58 Correct OrderedHash initialization to ensure keys order in 1.8.7
This should hopefully fix the build with 1.8.7 🙏
2013-05-01 21:35:03 -03:00
Rafael Mendonça França
b51c7fe59b Merge pull request #2396 from nickborromeo/show_license_in_gemspec
Fix gemspec so that MIT license will be visible when running the -d flag

Closes #2390
2013-04-30 10:34:54 -07:00
Nick Borromeo
a6b754b697 Fix gemspec so that MIT license will be visible when running the -d flag 2013-04-30 10:23:50 -07:00
Michiel Prins
92218e9ecc Remove unnecessary code 2013-04-29 15:21:31 +02:00
Michiel Prins
60e933df73 Add destroy_with_password method 2013-04-29 15:06:13 +02:00
José Valim
b451fc0aad Merge pull request #2391 from stereoscott/patch-1
Fix spelling error in doc block
2013-04-28 22:20:59 -07:00
Scott M
2f28e48f54 Fix spelling error in doc block 2013-04-29 01:52:37 -03:00
Carlos Antonio da Silva
76e4967ca1 Update travis-ci link in README [ci skip] 2013-04-28 13:06:08 -03:00
Vasiliy Ermolovich
dceb788c6b fix OrderedHash initialization 2013-04-23 10:37:10 +03:00
Vasiliy Ermolovich
fae8e977e8 use ordered hash to fix tests on ruby 1.8 2013-04-22 22:42:49 +03:00
Vasiliy Ermolovich
0a588fab3a update CHANGELOG [ci skip] 2013-04-22 17:51:54 +03:00
Vasiliy Ermolovich
bbf57214ac Merge pull request #2384 from worker8/after_reset_password_redirect_path
Add ability to override the redirect path after user has reset their password
2013-04-22 07:36:41 -07:00
Tan Jun Rong
804fbdf6d5 Fix spelling error, 'reseting' to 'resetting' 2013-04-22 22:25:40 +08:00
Tan Jun Rong
e4987e8bb7 Fix resource_name to resource 2013-04-22 21:40:52 +08:00
Tan Jun Rong
9d5a9c8a61 Add ability to override the redirect path after user has reset their password 2013-04-22 20:22:53 +08:00
Carlos Antonio da Silva
c8aa5f3e62 Bump webrat to 0.7.3 2013-04-19 20:38:39 -03:00
Carlos Antonio da Silva
df4b282566 Set variable to false instead of nil 2013-04-19 19:59:08 -03:00
Carlos Antonio da Silva
b8c5d76c5a Merge pull request #2380 from vipulnsward/fix_warnings
fix some warnings
2013-04-19 15:53:43 -07:00
Vipul A M
b871bd5036 fix some warning 2013-04-19 19:08:20 +05:30
José Valim
c439b80524 Merge pull request #2381 from vipulnsward/enable_warinings
enable warnings by default
2013-04-18 13:40:01 -07:00
Rafael Mendonça França
704221d48f Merge pull request #2379 from vipulnsward/remove_unused_vars
Remove unused variables and fix typos
2013-04-18 06:38:32 -07:00
Vipul A M
da70348662 enable warnings by default 2013-04-18 11:07:36 +05:30
Vipul A M
2e6457006e Remove unused variables and fix typos 2013-04-18 10:24:38 +05:30
Carlos Antonio da Silva
1f68309c47 ✂️ changelog [ci skip] 2013-04-15 15:50:06 -03:00
José Valim
c618969677 Update README.md 2013-04-14 08:49:30 -07:00
Lucas Mazza
93013c2e89 Merge pull request #2366 from hauleth/extract-lookup-for-i18n
Extract get_message
2013-04-14 08:21:19 -07:00
José Valim
8ec89bf659 Update README.md 2013-04-13 23:39:32 -07:00
José Valim
b3edfeab73 Update README.md 2013-04-13 23:35:58 -07:00
José Valim
c63483ae24 Merge branch 'latortuga-rails4-sp' into rails4 2013-04-13 23:34:25 -07:00
José Valim
3ed0dc5d9f Update README 2013-04-13 23:34:07 -07:00
José Valim
8a93c34080 Clean up Devise parameter sanitizer 2013-04-13 23:21:46 -07:00
José Valim
2dfa7e1761 Update CHANGELOG 2013-04-13 22:10:48 -07:00
José Valim
5bf4f57fcf Tidy up devise configuration 2013-04-13 22:07:54 -07:00
José Valim
1b8fd7c2ff Merge pull request #2271 from robhurring/master
Allowing http token auth to set the token_authentication_key if missing from params
2013-04-13 21:39:36 -07:00
Carlos Antonio da Silva
f75352a373 Merge branch 'master' into rails4 2013-04-13 11:37:48 -03:00
Carlos Antonio da Silva
fa5ae57ce4 Use instance_eval instead of Proc#bind
Keep the implementation more similar to how it works in Action Mailer,
and avoid deprecation warnings with Proc#bind being raised in rails4
branch.
2013-04-13 11:35:51 -03:00
Carlos Antonio da Silva
ac2ebdfb11 Fix session store changed in Rails master
There's no encrypted cookie store anymore, by default the cookie store
will be encrypted.
2013-04-13 11:16:11 -03:00
Carlos Antonio da Silva
ea94e199ce Bundle update 2013-04-13 11:14:13 -03:00
Carlos Antonio da Silva
d89dad5728 Bundle update for both Rails 3.1 and 3.2, update mocha, fix failing tests 2013-04-13 11:08:27 -03:00
Carlos Antonio da Silva
32a141d2a9 Fix typo in test descriptions 2013-04-13 10:54:52 -03:00
Carlos Antonio da Silva
36557ef641 ✂️ [ci skip] 2013-04-13 10:53:49 -03:00
José Valim
aa24335656 Merge pull request #2371 from tomasv/custom-devise-mailer-default-proc-fix
Fix devise sender bug with custom devise mailers.
2013-04-12 08:37:31 -07:00
Tomas Varneckas
1acd3d1790 Fix devise sender bug with custom devise mailers.
The devise sender detection must take into account that the default
sender set in the custom devise mailer can be a proc.
2013-04-12 16:48:48 +03:00
Drew Ulmer
d20fdf87b6 Introduce BaseSanitizer null sanitizer and controller-specific callbacks
This updates Devise's StrongParameter support to feature:

- A Null base sanitizer to support existing Rails 3.x installations that
  don't want to use StrongParameters yet
- A new, simpler API for ParameterSanitizer: #permit, #permit!, and #forbid
- Overrideable callbacks on a controller-basis, e.g. #create_sessions_params
  for passing the current scope's parameters through StrongParameters and
  a helper method, whitelisted_params, for rolling your own implementations
  of #create_x_params in your own controllers.
- Lots of tests!
2013-04-10 10:33:50 -05:00
Łukasz Niemier
95f56258d7 Rename get_message to find_message and fix set_flash_message 2013-04-07 08:52:11 +02:00
Łukasz Niemier
8e9ad4626e Extract get_message 2013-04-06 18:46:21 +02:00
José Valim
2de7cbae25 Merge pull request #2363 from eloyesp/documenting_protected_methods
Generate documentation for protected methods.
2013-04-04 06:52:08 -07:00
Eloy Espinaco
37473cdaf7 Add config to customize documentation. 2013-04-04 09:48:33 -03:00
Lucas Mazza
bf30d79aca Update rubygems url inside Gemfile.lock 2013-04-03 10:22:46 -03:00
José Valim
148fa99dce Merge pull request #2330 from pungoyal/master
Language copy changes
2013-04-01 12:20:02 -07:00
Drew Ulmer
77203e3d97 Change parameter sanitizer instance method to scope to devise
This way it's very explicit that this method is for devise and it won't
run into any naming collisions with user code.
2013-04-01 09:46:46 -05:00
Drew Ulmer
b151d2cfe2 Remove MassAssignment security from Mongoid test shim 2013-04-01 09:00:36 -05:00
Drew Ulmer
e0ffe8f85f Fix internal helper test referencing resource_params 2013-03-31 21:31:54 -05:00
Drew Ulmer
78f137368c Add support for Rails 4 strong_parameters
This brings support for Rails 4 StrongParameters changes.

- Parameter sanitizing is setup for Devise controllers via
  resource_params except Omniauth Callbacks which doesn't use
  resource_params.

- Change #build_resource to not call resource_params for get requests.
  Parameter sanitizing is only needed when params are posted to the
  server so there's no need to try to construct resource params on get
  requests (new, edit).
2013-03-31 21:31:48 -05:00
Drew Ulmer
af4a582300 Remove mass-assignment role-based tests, no longer supported in Rails 4
Mass-assignment security roles are removed in Rails 4 so there's no need
to test :as => :role behavior.
2013-03-31 15:21:49 -05:00
Drew Ulmer
2f88f7c0ed Remove protected_attributes gem and all whitelisting 2013-03-31 15:21:49 -05:00
Lucas Mazza
ce37c301ff Update Rails dependency 2013-03-31 17:19:10 -03:00
Lucas Mazza
bd14589fe4 Ensure that include_root_in_json is true since our test suite depends on that. 2013-03-31 17:18:41 -03:00
Lucas Mazza
c07bc69fad Install Mongoid in Ruby 2.0 2013-03-31 17:18:02 -03:00
Rafael Mendonça França
9a8cb011d7 Use the latests Rails version 2013-03-28 14:00:55 -03:00
Rafael Mendonça França
335a6af861 Merge branch 'master' into rails4 2013-03-28 13:51:12 -03:00
Vasiliy Ermolovich
72cbafa322 Merge pull request #2340 from scottjacobsen/master
s/reseting/resetting

[ci skip]
2013-03-22 00:17:20 -07:00
Scott Jacobsen
4549d8c65f Update recoverable.rb
Fix type-o.
2013-03-21 18:49:19 -06:00
Vasiliy Ermolovich
6c566c1ca4 Merge pull request #2331 from yxhuvud/master
License information to gemspec.
[ci skip]
2013-03-16 09:06:04 -07:00
linus
41aed807fc Add license to gemspec. 2013-03-16 09:29:46 +01:00
Puneet Goyal
ddea9359a6 Removing an extra full stop 2013-03-15 15:19:52 +05:30
Puneet Goyal
5d87e150f7 removing an extra full stop 2013-03-15 15:18:45 +05:30
José Valim
d90e365636 Merge pull request #2315 from neo/http_auth_key
Allow explicit configuration of http auth key
2013-03-07 09:43:08 -08:00
Lucas Mazza
22442907af Fix send_devise_notification arity in the documentation.
[ci skip]
2013-03-05 15:55:19 -03:00
robhurring
10f58b636f update devise config template with new allow_token_authenticatable_via_headers options 2013-03-04 17:38:36 -05:00
robhurring
2d14bd2826 removing params hash merging of token and mimicking http basic auth flow 2013-03-04 17:33:27 -05:00
Matt Jones + Tony Schneider
f4ceecece4 Allow explicit configuration of http auth key
- Fix basic auth case in which authorized_keys is configured as hash
- Duplicate existing functionality when http_auth_key is not explicitly
  set
2013-03-04 12:23:05 -05:00
José Valim
359fdd840c Merge pull request #2311 from pixeltrix/improve-delayed-email-documentation
Improve documentation on sending delayed emails
2013-03-01 06:49:39 -08:00
Andrew White
c6578250d2 Improve documentation on sending delayed emails
There are a couple of gotchas in the existing documentation
about the `send_devise_notification` hook.

1.  The `after_commit` callback can be called multiple times
    so you should clear the array otherwise any additional
    invocations will trigger extra copies of the email.

2.  The `after_commit` callback is only called when a record
    is created or updated so you need to check for `new_record?`
    or `changed?` before adding it to `pending_notifications`
    otherwise it's okay to send it immediately.

The `new_record? || changed?` condition is necessary because
the latter isn't always true for new records, e.g:

    >> User.new.changed?
    => false

[ci skip]
2013-03-01 14:32:15 +00:00
José Valim
dc14c76ff6 Merge pull request #2308 from vfrride/patch-1
updates source url to use https
2013-02-27 18:59:31 -08:00
vfrride
5e74fd406b updates source url to use https 2013-02-27 21:39:45 -05:00
José Valim
ebeee33429 Run image optimizer on the logo (i'm done) 2013-02-26 11:36:25 -07:00
José Valim
e449c3b6d2 Update badges 2013-02-26 11:27:58 -07:00
José Valim
58871172ab Crop the logo a bit more 💣 2013-02-26 11:25:26 -07:00
José Valim
41a2d65ade Reduce logo dimentions 2013-02-26 11:23:11 -07:00
José Valim
e6dc425abb Add Devise logo 2013-02-26 11:19:48 -07:00
Carlos Antonio da Silva
d29b744d92 Enable Ruby 2.0 in travis 2013-02-25 22:13:48 -03:00
Carlos Antonio da Silva
e79ebe8aec Fix last mongoid tests since it does not have the order method 2013-02-25 22:13:36 -03:00
Santiago Pastorino
10f93129c3 Rails 4 now raises ActionController::UrlGenerationError
This is the commit in Rails
https://github.com/rails/rails/commit/db06d128
2013-02-25 22:12:21 -03:00
Santiago Pastorino
04d9512f30 We need to do match via [get, post] 2013-02-25 22:12:20 -03:00
Santiago Pastorino
135c8da390 To be able to post to root via is now needed 2013-02-25 22:12:20 -03:00
Carlos Antonio da Silva
aca7e5d162 Run tests with mongoid 2013-02-25 22:12:20 -03:00
Carlos Antonio da Silva
02298117a0 Do not remove app/mailers from autoloaded paths 2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
7998d6f878 Match full template name 2013-02-25 22:12:06 -03:00
Vasiliy Ermolovich
ed6e232756 assert_recognizes rises Assertion instead of RoutingError 2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
567fabbbc6 Disable forcing whitelist attributes from protected attributes
This was the previous functionality since we didn't set anything in the
application configuration. Now when using protected attributes gem, it
sets whitelist to true, forcing us to always declare the accessible
attributes, and this is not the case for the Admin model.
2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
d77a956276 Remove AR deprecated finder warnings 2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
3c885e043d Fix changed error messages from confirmation validation 2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
9ae013ae3c Updating test app running rake rails:update, tests running with failures 2013-02-25 22:12:06 -03:00
Carlos Antonio da Silva
1bae64d8c4 Update dependencies for Rails 4 2013-02-25 22:11:49 -03:00
Carlos Antonio da Silva
f8792c8cf0 Update to Rails 3-2-stable and fix failing tests 2013-02-25 22:06:10 -03:00
Lucas Mazza
198bfff2de Merge pull request #2300 from fphilipe/scoped-serialization
Make use of warden's scoped serialization
2013-02-25 15:32:43 -08:00
Lucas Mazza
d3f0665105 Merge pull request #2305 from gregates/feature/skip_confirmation_notice!
Changelog for #2296
2013-02-25 15:31:56 -08:00
Greg Gates
77b960f14a Changelog for #2296 2013-02-25 18:23:43 -05:00
José Valim
b388aae473 Merge pull request #2302 from islandr/master
Mention devise-encryptable requirement in initializer template
2013-02-25 14:05:15 -08:00
José Valim
81c6d70b7c Merge pull request #2296 from gregates/feature/skip_confirmation_notice!
Add #skip_confirmation_notification! to Confirmable
2013-02-25 14:01:54 -08:00
Ryan Mohr
f3928d8462 Mention devise-encryptable requirement for anything but bcrypt. 2013-02-25 10:42:06 -10:00
Philipe Fatio
c22d755cf4 Make use of warden's scoped serialization 2013-02-25 07:38:42 +01:00
Greg Gates
72cfaad618 Add #skip_confirmation_notification to Confirmable 2013-02-22 12:43:01 -05:00
José Valim
22897150d8 Merge pull request #2278 from plataformatec/issue-2275
allow_unconfirmed_access_for set to nil means unconfirmed access for unlimited time
2013-02-14 11:30:51 -08:00
Vasiliy Ermolovich
395a69b4ef allow_unconfirmed_access_for set to nil means unconfirmed access for unlimited time
closes #2275
2013-02-13 21:17:38 +03:00
Rob
547439d94c renaming devise option "allow_authorization_to_set_auth_token" to "allow_token_authenticatable_via_headers" 2013-02-10 12:50:52 -05:00
Rob
84f743c4ef adding http token auth options to env[devise.token_options] 2013-02-10 12:48:02 -05:00
Rob
22a8cfe6d3 fix hanging line on method call 2013-02-09 15:19:42 -05:00
Rob
3025b7e2f7 Allow http token authorization to set token_authentication_key in place of passing it in via params
It will not override existing token_authentication_key params if they are present.
2013-02-09 15:12:36 -05:00
Vasiliy Ermolovich
1b2460171e Merge pull request #2261 from plataformatec/issue-2253
use scoped path to shared views if scope is present
2013-02-08 15:43:39 -08:00
Vasiliy Ermolovich
f822f92321 use scoped path to shared views if scope is present
closes #2253
2013-02-09 02:35:06 +03:00
Lucas Mazza
042ba76480 Merge pull request #2263 from sboesen/patch-1
Typo - Update lib/generators/templates/devise.rb
2013-02-06 17:08:36 -08:00
Stefan Boesen
3458e12274 Update lib/generators/templates/devise.rb
Typo in template comment.
2013-02-06 16:30:00 -08:00
José Valim
d9364f7a4a Update CHANGELOG.rdoc
Close #2254
2013-02-01 09:30:43 -07:00
José Valim
fd0db0b188 Merge pull request #2251 from latortuga/2190-test-case
Add test for Issue #2190
2013-02-01 07:58:00 -08:00
Drew Ulmer
c9c1e13743 Add test for Issue #2190
Seems to be passing for me.
2013-01-31 10:05:53 -06:00
José Valim
25296d8c6f Add tests for sign out with redirect, related to #2249 2013-01-30 08:28:51 -07:00
José Valim
34c7981f69 Merge pull request #2248 from bvsatyaram/patch-1
Update README.md
2013-01-30 07:11:43 -08:00
B V Satyaram
f7a658e13d Update README.md
Devise is composed of 11 modules instead of 12.
2013-01-30 15:17:36 +05:30
José Valim
1d639bd0c5 Merge pull request #2247 from waldyr/patch-1
correcting tiny typo
2013-01-29 17:01:04 -08:00
Waldyr Guimarães Araújo de Souza
5ee07390b7 correcting tiny typo 2013-01-29 22:45:23 -02:00
Carlos Antonio da Silva
83ad67bd51 Fix inheriting mailer templates from Devise::Mailer
Previously inheriting from Devise::Mailer would not render default views
from devise when the inheriting mailer didn't have the view. Now it'll
correctly pick the default one from Devise::Mailer.
2013-01-29 00:08:26 -02:00
Carlos Antonio da Silva
72be1f1289 Match against string value, no need to create regexps 2013-01-28 23:59:15 -02:00
Carlos Antonio da Silva
0285565322 Actually fix this test by forcing to_s on the id 2013-01-28 21:40:11 -02:00
Carlos Antonio da Silva
acc3adb2c1 Use #next instead of calculating id + 1
The id attribute is not Integer in Mongo, so it fails with something like:

    NoMethodError: undefined method `+' for "5106fc06ee6da1ee44000002":Moped::BSON::ObjectId'`

With #next, it will work with both Integer and String ids, for both AR
and Mongo, returning a different id to test for filtered conditions.
2013-01-28 20:46:21 -02:00
Carlos Antonio da Silva
af37800c1d Change match routes to get / post
match without a verb is deprecated in Rails master.
2013-01-28 20:23:13 -02:00
Carlos Antonio da Silva
86eecc6606 Change "ActionController::IntegrationTest" to "ActionDispatch::IntegrationTest" 2013-01-28 19:58:21 -02:00
Rafael Mendonça França
349aab72f0 No need to test against ree since we are testing with 1.8.7 2013-01-28 13:50:08 -02:00
Rafael Mendonça França
bfa65dde70 Use the Ruby 1.8 hash syntax.
Yes we still support Ruby 1.8 😢
2013-01-28 13:21:44 -02:00
José Valim
d099d8f0ac Release v2.2.3 2013-01-26 11:43:17 -07:00
José Valim
5190f52857 Require string conversion for all values 2013-01-26 11:42:42 -07:00
José Valim
5790107f49 Merge pull request #2235 from camelmasa/sorted_locale_file
sorted locale file
2013-01-22 19:11:38 -08:00
camelmasa
6fd21ae37e sorted locale file 2013-01-23 10:39:58 +09:00
Vasiliy Ermolovich
b95c321660 update Gemfile.lock 2013-01-21 20:14:59 +03:00
Alexander Zaytsev
01bb721c33 Use mapping.fullpath in omniauth callbacks 2013-01-21 19:51:06 +05:00
Carlos Antonio da Silva
0061f113db Fix indent [ci skip] 2013-01-20 21:49:45 -02:00
José Valim
1fb3fbbd88 Merge pull request #2230 from nashby/issue-2218
add key option to rememberable_options
2013-01-20 12:23:21 -08:00
Vasiliy Ermolovich
d3f8bd6cae add key option to rememberable_options
closes #2218
2013-01-20 23:16:25 +03:00
José Valim
0642e2fc9b Merge pull request #2223 from jayshepherd/master
Allow parent_mailer to be customizable via Devise.parent_mailer ... (#2219)
2013-01-18 05:35:55 -08:00
Jay Shepherd
cc017b1f0d Allow parent_mailer to be customizable via Devise.parent_mailer, useful for engines 2013-01-18 02:26:41 -06:00
Víctor Manuel Cruz Dueñas
3511f8ac00 Checking if unconfirmed_email has changed before to set update_needs_confirmation flash message. 2012-07-05 19:10:34 +02:00
146 changed files with 2756 additions and 1902 deletions

View File

@@ -1,35 +1,13 @@
language: ruby
script: "bundle exec rake test"
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- ree
- 2.0.0
env:
- DEVISE_ORM=mongoid
- DEVISE_ORM=active_record
matrix:
exclude:
- rvm: ree
env: DEVISE_ORM=mongoid
gemfile: Gemfile
- rvm: ree
env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile.rails-3.1.x
- rvm: 1.8.7
env: DEVISE_ORM=mongoid
gemfile: Gemfile
- rvm: 1.8.7
env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile.rails-3.1.x
- rvm: 1.9.2
env: DEVISE_ORM=mongoid
gemfile: Gemfile
- rvm: 1.9.2
env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile.rails-3.1.x
gemfile:
- gemfiles/Gemfile.rails-3.1.x
- gemfiles/Gemfile.rails-3.2.x
- Gemfile
services:
- mongodb

9
.yardopts Normal file
View File

@@ -0,0 +1,9 @@
--protected
--no-private
--embed-mixin ClassMethods
-
README.md
CHANGELOG.rdoc
CONTRIBUTING.md
MIT-LICENSE

View File

@@ -1,15 +1,134 @@
== 2.2.2
### 3.2.2
* bug fix
* Ensure timeoutable works when `sign_out_all_scopes` is false (by @louman)
* Keep the query string when storing location (by @csexton)
* Require rails generator base class in devise generators
### 3.2.1
Security announcement: http://blog.plataformatec.com.br/2013/11/e-mail-enumeration-in-devise-in-paranoid-mode
* enhancements
* Add `store_location_for` helper and ensure it is safe (by @matthewrudy and @homakov)
* Add `yield` around resource methods in Devise controllers (by @edelpero)
* bug fix
* Bring `password_digest` back to fix compatibility with `devise-encryptable`
* Avoid e-mail enumeration on sign in when in paranoid mode
### 3.2.0
* enhancements
* Previously deprecated token authenticatable and insecure lookups have been removed
* Add a class method so you can encrypt passwords from fixtures (by @tenderlove)
* Send custom message when user enters invalid password and it has only one attempt
to enter correct password before his account will be locked (by @Lightpower)
* Prevent mutation of values assigned to case and whitespace santitized members (by @iamvery)
* Separate redirects and flash messages in `navigational_formats` and `flashing_formats` (by @ssendev)
* bug fix
* A GET to sign_in page shouldn't extend the session (by @drewish)
* Splat the arguments to `strong_parameters#permit` to work around a limitation in the `strong_parameters` gem (by @memberful)
* Omniauth now uses `mapping.fullpath` when generating routes. This means if you call `devise_for :users` inside a scope, like `scope "/api"`, the scope will now apply to the omniauth route (by @AlexanderZaytsev)
* Ensure timeoutable hook respects `Devise.sign_out_all_scopes` configuration
* deprecations
* `expire_session_data_after_sign_in!` has been deprecated in favor of `expire_data_after_sign_in!`
### 3.1.1
* bug fix
* Improve default message which asked users to sign in even when they were already signed (by @gregates)
* Improve error message for when the config.secret_key is missing
### 3.1.0
Security announcement: http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/
* backwards incompatible changes
* Do not store confirmation, unlock and reset password tokens directly in the database. This means tokens previously stored in the database are no longer valid. You can reenable this temporarily by setting `config.allow_insecure_token_lookup = true` in your configuration file. It is recommended to keep this configuration set to true just temporarily in your production servers only to aid migration
* The Devise mailer and its views were changed to explicitly receive a token argument as `@token`. You will need to update your mailers and re-copy the views to your application with `rails g devise:views`
* Sanitization of parameters should be done by calling `devise_parameter_sanitizer.sanitize(:action)` instead of `devise_parameter_sanitizer.for(:action)`
* deprecations
* Token authentication is deprecated
* enhancements
* Better security defaults
* Allow easier customization of parameter sanitizer (by @alexpeattie)
* bug fix
* Do not confirm e-mail after password reset (by @moll)
* Do not sign in after confirmation
* Do not store confirmation, unlock and reset password tokens directly in the database
* Do not compare directly against confirmation, unlock and reset password tokens
* Skip storage for cookies on unverified requests
### 3.0.2
* bug fix
* Skip storage for cookies on unverified requests
### 3.0.1
Security announcement: http://blog.plataformatec.com.br/2013/08/csrf-token-fixation-attacks-in-devise/
* enhancements
* Add after_confirmation callback
* bug fix
* When using rails 3.2, the generator adds 'attr_accessible' to the model (by @jcoyne)
* Clean up CSRF token after authentication (by @homakov). Notice this change will clean up the CSRF Token after authentication (sign in, sign up, etc). So if you are using AJAX for such features, you will need to fetch a new CSRF token from the server.
### 3.0.0
* enhancements
* Rails 4 and Strong Parameters compatibility (by @carlosantoniodasilva, @josevalim, @latortuga, @lucasmazza, @nashby, @rafaelfranca, @spastorino)
* Drop support for Rails < 3.2 and Ruby < 1.9.3
* Enable to skip sending reconfirmation email when reconfirmable is on and `skip_confirmation_notification!` is invoked (by @tkhr)
* bug fix
* Errors on unlock are now properly reflected on the first `unlock_keys`
* backwards incompatible changes
* Changes on session storage will expire all existing sessions on upgrade. For those storing the session in the DB, they can be upgraded according to this gist: https://gist.github.com/moll/6417606
### 2.2.4
* enhancements
* Add `destroy_with_password` to `DatabaseAuthenticatable`. Allows destroying a record when `:current_password` matches, similarly to how `update_with_password` works. (by @michiel3)
* Allow to override path after password resetting (by @worker8)
* Add `#skip_confirmation_notification!` method to `Confirmable`. Allows skipping confirmation email without auto-confirming. (by @gregates)
* allow_unconfirmed_access_for config from `:confirmable` module can be set to `nil` that means unconfirmed access for unlimited time. (by @nashby)
* Support Rails' token strategy on authentication (by @robhurring)
* Support explicitly setting the http authentication key via `config.http_authentication_key` (by @neo)
* bug fix
* Do not redirect when accessing devise API via JSON. (by @sebastianwr)
* Generating scoped devise views now uses the correct scoped shared links partial instead of the default devise one (by @nashby)
* Fix inheriting mailer templates from `Devise::Mailer`
* Fix a bug when procs are used as default mailer in Devise (by @tomasv)
### 2.2.3
Security announcement: http://blog.plataformatec.com.br/2013/01/security-announcement-devise-v2-2-3-v2-1-3-v2-0-5-and-v1-5-3-released/
* bug fix
* Require string conversion for all values
### 2.2.2
* bug fix
* Fix bug when checking for reconfirmable in templates
== 2.2.1
### 2.2.1
* bug fix
* Fix regression with case_insensitive_keys
* Fix regression when password is blank when it is invalid
== 2.2.0
### 2.2.0
* backwards incompatible changes
* `headers_for` is deprecated, customize the mailer directly instead
@@ -40,7 +159,7 @@
* `update_with_password` doesn't change encrypted password when it is invalid (by @nashby)
* Properly handle namespaced models on Active Record generator (by @nashby)
== 2.1.2
### 2.1.2
* enhancements
* Handle backwards incompatibility between Rails 3.2.6 and Thor 0.15.x
@@ -48,7 +167,7 @@
* bug fix
* Fix regression on strategy validation on previous release
== 2.1.1 (yanked)
### 2.1.1 (yanked)
* enhancements
* `sign_out_all_scopes` now locks warden and does not allow new logins in the same action
@@ -65,7 +184,7 @@
* deprecations
* Strategy#validate() no longer validates nil resources
== 2.1.0
### 2.1.0
* enhancements
* Add `check_fields!(model_class)` method on Devise::Models to check if the model includes the fields that Devise uses
@@ -90,8 +209,9 @@
* Do not accidentally mark `_prefixes` as private
* Better support for custom strategies on test helpers (by @mattconnolly)
* Return `head :no_content` in SessionsController now that most JS libraries handle it (by @julianvargasalvarez)
* Reverted moving devise/shared/_links.erb to devise/_links.erb
== 2.0.4
### 2.0.4
Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
@@ -99,7 +219,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Fix when :host is used with devise_for (by @mreinsch)
* Fix a regression that caused Warden to be initialized too late
== 2.0.3 (yanked)
### 2.0.3 (yanked)
* bug fix
* Ensure warning is not shown by mistake on apps with mounted engines
@@ -107,7 +227,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Ensure serializable_hash does not depend on accessible attributes
* Ensure that timeout callback does not run on sign out action
== 2.0.2
### 2.0.2
* enhancements
* Add devise_i18n_options to customize I18n message
@@ -119,7 +239,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Show a warning in case someone gives a pluralized name to devise generator
* Fix test behavior for rspec subject requests (by @sj26)
== 2.0.1
### 2.0.1
* enhancements
* Improved error messages on deprecation warnings
@@ -128,7 +248,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Removed tmp and log files from gem
== 2.0.0
### 2.0.0
* enhancements
* Add support for e-mail reconfirmation on change (by @Mandaryn and @heimidal)
@@ -154,14 +274,14 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Deprecated support to devise.registrations.reasons and devise.registrations.inactive_signed_up in favor of devise.registrations.signed_up_but_*
* Protected method render_with_scope was removed.
== 1.5.3
### 1.5.3
* bug fix
* Ensure delegator converts scope to symbol (by @dmitriy-kiriyenko)
* Ensure passing :format => false to devise_for is not permanent
* Ensure path checker does not check invalid routes
== 1.5.2
### 1.5.2
* enhancements
* Add support for Rails 3.1 new mass assignment conventions (by @kirs)
@@ -170,12 +290,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* OmniAuth error message now shows the proper option (:strategy_class instead of :klass)
== 1.5.1
### 1.5.1
* bug fix
* Devise should not attempt to load OmniAuth strategies. Strategies should be loaded before hand by the developer or explicitly given to Devise.
== 1.5.0
### 1.5.0
* enhancements
* Timeoutable also skips tracking if skip_trackable is given
@@ -196,12 +316,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* redirect_location is deprecated, please use after_sign_in_path_for
* after_sign_in_path_for now redirects to session[scope_return_to] if any value is stored in it
== 1.4.9
### 1.4.9
* bug fix
* url helpers were not being set under some circumstances
== 1.4.8
### 1.4.8
* enhancements
* Add docs for assets pipeline and Heroku
@@ -209,12 +329,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* confirmation_url was not being set under some circumstances
== 1.4.7
### 1.4.7
* bug fix
* Fix backward incompatible change from 1.4.6 for those using custom controllers
== 1.4.6 (yanked)
### 1.4.6 (yanked)
* enhancements
* Allow devise_for :skip => :all
@@ -222,7 +342,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Allow --skip-routes to devise generator
* Add allow_params_authentication! to make it explicit when params authentication is allowed in a controller
== 1.4.5
### 1.4.5
* bug fix
* Failure app tries the root path if a session one does not exist
@@ -230,12 +350,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Reset password shows proper message if user is not active
* `clean_up_passwords` sets the accessors to nil to skip validations
== 1.4.4
### 1.4.4
* bug fix
* Do not always skip helpers, instead provide :skip_helpers as option to trigger it manually
== 1.4.3
### 1.4.3
* enhancements
* Improve Rails 3.1 compatibility
@@ -251,12 +371,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* deprecations
* Loosened the used email regexp to simply assert the existent of "@". If someone relies on a more strict regexp, they may use https://github.com/SixArm/sixarm_ruby_email_address_validation
== 1.4.2
### 1.4.2
* bug fix
* Provide a more robust behavior to serializers and add :force_except option
== 1.4.1
### 1.4.1
* enhancements
* Add :defaults and :format support on router
@@ -267,7 +387,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Ensure to_xml is properly white listened
* Ensure handle_unverified_request clean up any cached signed-in user
== 1.4.0
### 1.4.0
* enhancements
* Added authenticated and unauthenticated to the router to route the used based on his status (by @sj26)
@@ -285,22 +405,22 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Devise now honors routes constraints (by @macmartine)
* Do not return the user resource when requesting instructions (by @rodrigoflores)
== 1.3.4
### 1.3.4
* bug fix
* Do not add formats if html or "*/*"
== 1.3.3
### 1.3.3
* bug fix
* Explicitly mark the token as expired if so
== 1.3.2
### 1.3.2
* bug fix
* Fix another regression related to reset_password_sent_at (by @alexdreher)
== 1.3.1
### 1.3.1
* enhancements
* Improve failure_app responses (by @indirect)
@@ -309,7 +429,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Fix a regression that occurred if reset_password_sent_at is not present (by @stevehodgkiss)
== 1.3.0
### 1.3.0
* enhancements
* All controllers can now handle different mime types than html using Responders (by @sikachu)
@@ -329,19 +449,19 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* backward incompatible changes
* authentication_keys are no longer considered when creating the e-mail validations, the previous behavior was buggy. You must double check if you were relying on such behavior.
== 1.2.1
### 1.2.1
* enhancements
* Improve update path messages
== 1.2.0
### 1.2.0
* bug fix
* Properly ignore path prefix on omniauthable
* Faster uniqueness queries
* Rename active? to active_for_authentication? to avoid conflicts
== 1.2.rc2
### 1.2.rc2
* enhancements
* Make friendly_token 20 chars long
@@ -371,7 +491,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Removed --haml and --slim view templates
* Devise::OmniAuth helpers were deprecated and removed in favor of Omniauth.config.test_mode
== 1.2.rc
### 1.2.rc
* deprecations
* cookie_domain is deprecated in favor of cookie_options
@@ -409,13 +529,13 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Ensure namespaces has proper scoped views
* Ensure Devise does not set empty flash messages (by @sxross)
== 1.1.6
### 1.1.6
* Use a more secure e-mail regexp
* Implement Rails 3.0.4 handle unverified request
* Use secure_compare to compare passwords
== 1.1.5
### 1.1.5
* bugfix
* Ensure to convert keys on indifferent hash
@@ -423,12 +543,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* defaults
* Set config.http_authenticatable to false to avoid confusion
== 1.1.4
### 1.1.4
* bugfix
* Avoid session fixation attacks
== 1.1.3
### 1.1.3
* bugfix
* Add reply-to to e-mail headers by default
@@ -439,17 +559,17 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Fix for failed first-ever logins on PostgreSQL where column default is nil (by @bensie)
* :default options is now honored in migrations
== 1.1.2
### 1.1.2
* bugfix
* Compatibility with latest Rails routes schema
== 1.1.1
### 1.1.1
* bugfix
* Fix a small bug where generated locale file was empty on devise:install
== 1.1.0
### 1.1.0
* enhancements
* Rememberable module allows user to be remembered across browsers and is enabled by default (by @trevorturk)
@@ -469,7 +589,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* deprecations
* use_default_scope is deprecated and has no effect. Use :as or :devise_scope in the router instead
== 1.1.rc2
### 1.1.rc2
* enhancements
* Allow to set cookie domain for the remember token. (by @mantas)
@@ -487,7 +607,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* devise.mailer.user.confirmations_instructions now should be devise.mailer.confirmations_instructions.user_subject
* Generators now use Rails 3 syntax (devise:install) instead of devise_install
== 1.1.rc1
### 1.1.rc1
* enhancements
* Rails 3 compatibility
@@ -519,7 +639,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* All messages under devise.sessions, except :signed_in and :signed_out, should be moved to devise.failure
* :as and :scope in routes is deprecated. Use :path and :singular instead
== 1.0.8
### 1.0.8
* enhancements
* Support for latest MongoMapper
@@ -528,7 +648,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* confirmation_required? is properly honored on active? calls. (by @paulrosania)
== 1.0.7
### 1.0.7
* bug fix
* Ensure password confirmation is always required
@@ -537,14 +657,14 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* authenticatable was deprecated and renamed to database_authenticatable
* confirmable is not included by default on generation
== 1.0.6
### 1.0.6
* bug fix
* Do not allow unlockable strategies based on time to access a controller.
* Do not send unlockable email several times.
* Allow controller to upstram custom! failures to Warden.
== 1.0.5
### 1.0.5
* bug fix
* Use prepend_before_filter in require_no_authentication.
@@ -552,19 +672,19 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Fix a bug when giving an association proxy to devise.
* Do not use lock! on lockable since it's part of ActiveRecord API.
== 1.0.4
### 1.0.4
* bug fix
* Fixed a bug when deleting an account with rememberable
* Fixed a bug with custom controllers
== 1.0.3
### 1.0.3
* enhancements
* HTML e-mails now have proper formatting
* Do not remove MongoMapper options in find
== 1.0.2
### 1.0.2
* enhancements
* Allows you set mailer content type (by @glennr)
@@ -572,7 +692,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Uses the same content type as request on http authenticatable 401 responses
== 1.0.1
### 1.0.1
* enhancements
* HttpAuthenticatable is not added by default automatically.
@@ -581,7 +701,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Fixed encryptors autoload
== 1.0.0
### 1.0.0
* deprecation
* :old_password in update_with_password is deprecated, use :current_password instead
@@ -590,9 +710,9 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Added Registerable
* Added Http Basic Authentication support
* Allow scoped_views to be customized per controller/mailer class
* [#99] Allow authenticatable to used in change_table statements
* Allow authenticatable to used in change_table statements
== 0.9.2
### 0.9.2
* bug fix
* Ensure inactive user cannot sign in
@@ -602,13 +722,13 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Added gemspec to repo
* Added token authenticatable (by @grimen)
== 0.9.1
### 0.9.1
* bug fix
* Allow bigger salt size (by @jgeiger)
* Fix relative url root
== 0.9.0
### 0.9.0
* deprecation
* devise :all is deprecated
@@ -625,7 +745,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Accept path prefix not starting with slash
* url helpers should rely on find_scope!
== 0.8.2
### 0.8.2
* enhancements
* Allow Devise.mailer_sender to be a proc (by @grimen)
@@ -633,7 +753,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Fix bug with passenger, update is required to anyone deploying on passenger (by @dvdpalm)
== 0.8.1
### 0.8.1
* enhancements
* Move salt to encryptors
@@ -643,7 +763,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Bcrypt generator was not being loaded neither setting the proper salt
== 0.8.0
### 0.8.0
* enhancements
* Warden 0.8.0 compatibility
@@ -657,19 +777,19 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* deprecation
* Removed DeviseMailer.sender
== 0.7.5
### 0.7.5
* enhancements
* Set a default value for mailer to avoid find_template issues
* Add models configuration to MongoMapper::EmbeddedDocument as well
== 0.7.4
### 0.7.4
* enhancements
* Extract Activatable from Confirmable
* Decouple Serializers from Devise modules
== 0.7.3
### 0.7.3
* bug fix
* Give scope to the proper model validation
@@ -679,7 +799,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Added update_with_password for authenticatable
* Allow render_with_scope to accept :controller option
== 0.7.2
### 0.7.2
* deprecation
* Renamed reset_confirmation! to resend_confirmation!
@@ -689,12 +809,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Fixed render_with_scope to work with all controllers
* Allow sign in with two different users in Devise::TestHelpers
== 0.7.1
### 0.7.1
* enhancements
* Small enhancements for other plugins compatibility (by @grimen)
== 0.7.0
### 0.7.0
* deprecations
* :authenticatable is not included by default anymore
@@ -703,25 +823,25 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Improve loading process
* Extract SessionSerializer from Authenticatable
== 0.6.3
### 0.6.3
* bug fix
* Added trackable to migrations
* Allow inflections to work
== 0.6.2
### 0.6.2
* enhancements
* More DataMapper compatibility
* Devise::Trackable - track sign in count, timestamps and ips
== 0.6.1
### 0.6.1
* enhancements
* Devise::Timeoutable - timeout sessions without activity
* DataMapper now accepts conditions
== 0.6.0
### 0.6.0
* deprecations
* :authenticatable is still included by default, but yields a deprecation warning
@@ -730,57 +850,57 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Added DataMapper support
* Remove store_location from authenticatable strategy and add it to failure app
* Allow a strategy to be placed after authenticatable
* [#45] Do not rely attribute? methods, since they are not added on Datamapper
* Do not rely attribute? methods, since they are not added on Datamapper
== 0.5.6
### 0.5.6
* enhancements
* [#42] Do not send nil to build (DataMapper compatibility)
* [#44] Allow to have scoped views
* Do not send nil to build (DataMapper compatibility)
* Allow to have scoped views
== 0.5.5
### 0.5.5
* enhancements
* Allow overwriting find for authentication method
* [#38] Remove Ruby 1.8.7 dependency
* Remove Ruby 1.8.7 dependency
== 0.5.4
### 0.5.4
* deprecations
* Deprecate :singular in devise_for and use :scope instead
* enhancements
* [#37] Create after_sign_in_path_for and after_sign_out_path_for hooks to be
* Create after_sign_in_path_for and after_sign_out_path_for hooks to be
overwriten in ApplicationController
* Create sign_in_and_redirect and sign_out_and_redirect helpers
* Warden::Manager.default_scope is automatically configured to the first given scope
== 0.5.3
### 0.5.3
* bug fix
* MongoMapper now converts DateTime to Time
* Ensure all controllers are unloadable
* enhancements
* [#35] Moved friendly_token to Devise
* Moved friendly_token to Devise
* Added Devise.all, so you can freeze your app strategies
* Added Devise.apply_schema, so you can turn it to false in Datamapper or MongoMapper
in cases you don't want it be handlded automatically
== 0.5.2
### 0.5.2
* enhancements
* [#28] Improved sign_in and sign_out helpers to accepts resources
* [#28] Added stored_location_for as a helper
* [#20] Added test helpers
* Improved sign_in and sign_out helpers to accepts resources
* Added stored_location_for as a helper
* Added test helpers
== 0.5.1
### 0.5.1
* enhancements
* Added serializers based on Warden ones
* Allow authentication keys to be set
== 0.5.0
### 0.5.0
* bug fix
* Fixed a bug where remember me module was not working properly
@@ -790,13 +910,13 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Implemented encryptors for Clearance, Authlogic and Restful-Authentication (by @mhfs)
* Added support for MongoMapper (by @shingara)
== 0.4.3
### 0.4.3
* bug fix
* [#29] Authentication just fails if user cannot be serialized from session, without raising errors;
* Authentication just fails if user cannot be serialized from session, without raising errors;
* Default configuration values should not overwrite user values;
== 0.4.2
### 0.4.2
* deprecations
* Renamed mail_sender to mailer_sender
@@ -808,12 +928,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Allow :path_prefix to be given to devise_for
* Allow default_url_options to be configured through devise (:path_prefix => "/:locale" is now supported)
== 0.4.1
### 0.4.1
* bug fix
* [#21] Ensure options can be set even if models were not loaded
* Ensure options can be set even if models were not loaded
== 0.4.0
### 0.4.0
* deprecations
* Notifier is deprecated, use DeviseMailer instead. Remember to rename
@@ -822,52 +942,52 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* :authenticable calls are deprecated, use :authenticatable instead
* enhancements
* [#16] Allow devise to be more agnostic and do not require ActiveRecord to be loaded
* Allow devise to be more agnostic and do not require ActiveRecord to be loaded
* Allow Warden::Manager to be configured through Devise
* Created a generator which creates an initializer
== 0.3.0
### 0.3.0
* bug fix
* [#15] Allow yml messages to be configured by not using engine locales
* Allow yml messages to be configured by not using engine locales
* deprecations
* Renamed confirm_in to confirm_within
* [#14] Do not send confirmation messages when user changes his e-mail
* [#13] Renamed authenticable to authenticatable and added deprecation warnings
* Do not send confirmation messages when user changes his e-mail
* Renamed authenticable to authenticatable and added deprecation warnings
== 0.2.3
### 0.2.3
* enhancements
* Ensure fail! works inside strategies
* [#12] Make unauthenticated message (when you haven't signed in) different from invalid message
* Make unauthenticated message (when you haven't signed in) different from invalid message
* bug fix
* Do not redirect on invalid authenticate
* Allow model configuration to be set to nil
== 0.2.2
### 0.2.2
* bug fix
* [#9] Fix a bug when using customized resources
* Fix a bug when using customized resources
== 0.2.1
### 0.2.1
* refactor
* Clean devise_views generator to use devise existing views
* enhancements
* [#7] Create instance variables (like @user) for each devise controller
* Create instance variables (like @user) for each devise controller
* Use Devise::Controller::Helpers only internally
* bug fix
* [#6] Fix a bug with Mongrel and Ruby 1.8.6
* Fix a bug with Mongrel and Ruby 1.8.6
== 0.2.0
### 0.2.0
* enhancements
* [#4] Allow option :null => true in authenticable migration
* [#3] Remove attr_accessible calls from devise modules
* Allow option :null => true in authenticable migration
* Remove attr_accessible calls from devise modules
* Customizable time frame for rememberable with :remember_for config
* Customizable time frame for confirmable with :confirm_in config
* Generators for creating a resource and copy views
@@ -876,14 +996,14 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Do not load hooks or strategies if they are not used
* bug fixes
* [#2] Fixed requiring devise strategies
* Fixed requiring devise strategies
== 0.1.1
### 0.1.1
* bug fixes
* [#1] Fixed requiring devise mapping
* Fixed requiring devise mapping
== 0.1.0
### 0.1.0
* Devise::Authenticable
* Devise::Confirmable

15
Gemfile
View File

@@ -1,8 +1,8 @@
source "http://rubygems.org"
source "https://rubygems.org"
gemspec
gem "rails", "~> 3.2.6"
gem "rails", "~> 4.0.0"
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "rdoc"
@@ -10,8 +10,8 @@ gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.2", :require => false
gem "mocha", "0.10.0", :require => false
gem "webrat", "0.7.3", :require => false
gem "mocha", "~> 0.13.1", :require => false
end
platforms :jruby do
@@ -24,9 +24,8 @@ platforms :ruby do
gem "sqlite3"
end
platforms :mri_19 do
platforms :mri_19, :mri_20 do
group :mongoid do
gem "mongoid", "~> 3.0"
gem "mongoid", github: "mongoid/mongoid", branch: "master"
end
end
end

View File

@@ -1,74 +1,78 @@
GIT
remote: git://github.com/mongoid/mongoid.git
revision: 346a79a7d01aa194de80e649916239a18d38ce13
branch: master
specs:
mongoid (4.0.0)
activemodel (~> 4.0.0)
moped (~> 1.5)
origin (~> 1.0)
tzinfo (~> 0.3.22)
PATH
remote: .
specs:
devise (2.2.1)
devise (3.2.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
GEM
remote: http://rubygems.org/
remote: https://rubygems.org/
specs:
actionmailer (3.2.11)
actionpack (= 3.2.11)
mail (~> 2.4.4)
actionpack (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
actionmailer (4.0.0)
actionpack (= 4.0.0)
mail (~> 2.5.3)
actionpack (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
activerecord (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
activesupport (3.2.11)
i18n (~> 0.6)
multi_json (~> 1.0)
arel (3.0.2)
bcrypt-ruby (3.0.1)
builder (3.0.4)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
activemodel (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
activerecord (4.0.0)
activemodel (= 4.0.0)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.0)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activesupport (4.0.0)
i18n (~> 0.6, >= 0.6.4)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
arel (4.0.0)
atomic (1.1.12)
bcrypt-ruby (3.1.2)
builder (3.1.4)
erubis (2.7.0)
faraday (0.8.4)
multipart-post (~> 1.1)
faraday (0.8.8)
multipart-post (~> 1.2.0)
hashie (1.2.0)
hike (1.2.1)
hike (1.2.3)
httpauth (0.2.0)
i18n (0.6.1)
journey (1.0.4)
json (1.7.6)
jwt (0.1.5)
multi_json (>= 1.0)
mail (2.4.4)
i18n (>= 0.4.0)
i18n (0.6.5)
json (1.8.0)
jwt (0.1.8)
multi_json (>= 1.5)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
mime-types (1.19)
mocha (0.10.0)
mime-types (1.23)
minitest (4.7.5)
mocha (0.13.3)
metaclass (~> 0.0.1)
mongoid (3.0.16)
activemodel (~> 3.1)
moped (~> 1.1)
origin (~> 1.0)
tzinfo (~> 0.3.22)
moped (1.3.2)
multi_json (1.5.0)
multipart-post (1.1.5)
nokogiri (1.5.5)
oauth2 (0.8.0)
moped (1.5.1)
multi_json (1.7.9)
multipart-post (1.2.0)
nokogiri (1.5.9)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
@@ -85,53 +89,53 @@ GEM
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
origin (1.0.11)
origin (1.1.0)
orm_adapter (0.4.0)
polyglot (0.3.3)
rack (1.4.3)
rack-cache (1.2)
rack (>= 0.4)
rack (1.5.2)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-ssl (1.3.2)
rack
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.11)
actionmailer (= 3.2.11)
actionpack (= 3.2.11)
activerecord (= 3.2.11)
activeresource (= 3.2.11)
activesupport (= 3.2.11)
bundler (~> 1.0)
railties (= 3.2.11)
railties (3.2.11)
actionpack (= 3.2.11)
activesupport (= 3.2.11)
rack-ssl (~> 1.3.2)
rails (4.0.0)
actionmailer (= 4.0.0)
actionpack (= 4.0.0)
activerecord (= 4.0.0)
activesupport (= 4.0.0)
bundler (>= 1.3.0, < 2.0)
railties (= 4.0.0)
sprockets-rails (~> 2.0.0)
railties (4.0.0)
actionpack (= 4.0.0)
activesupport (= 4.0.0)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.0.3)
rdoc (3.12)
thor (>= 0.18.1, < 2.0)
rake (10.1.0)
rdoc (4.0.1)
json (~> 1.4)
ruby-openid (2.2.2)
sprockets (2.2.2)
ruby-openid (2.2.3)
sprockets (2.10.0)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.12)
sprockets-rails (2.0.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.7)
thor (0.18.1)
thread_safe (0.1.2)
atomic
tilt (1.4.1)
treetop (1.4.14)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.35)
warden (1.2.1)
tzinfo (0.3.37)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.2)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
@@ -144,13 +148,13 @@ DEPENDENCIES
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (= 0.10.0)
mongoid (~> 3.0)
mocha (~> 0.13.1)
mongoid!
omniauth (~> 1.0.0)
omniauth-facebook
omniauth-oauth2 (~> 1.0.0)
omniauth-openid (~> 1.0.1)
rails (~> 3.2.6)
rails (~> 4.0.0)
rdoc
sqlite3
webrat (= 0.7.2)
webrat (= 0.7.3)

182
README.md
View File

@@ -1,8 +1,9 @@
## Devise
![Devise Logo](https://raw.github.com/plataformatec/devise/master/devise.png)
[![Build Status](https://secure.travis-ci.org/plataformatec/devise.png?branch=master)](http://travis-ci.org/plataformatec/devise)
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/plataformatec/devise)
[![Gem Version](https://fury-badge.herokuapp.com/rb/devise.png)](http://badge.fury.io/rb/devise)
By [Plataformatec](http://plataformatec.com.br/).
[![Build Status](https://api.travis-ci.org/plataformatec/devise.png?branch=master)](http://travis-ci.org/plataformatec/devise)
[![Code Climate](https://codeclimate.com/github/plataformatec/devise.png)](https://codeclimate.com/github/plataformatec/devise)
This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).
@@ -10,13 +11,12 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
* Is Rack based;
* Is a complete MVC solution based on Rails engines;
* Allows you to have multiple roles (or models/scopes) signed in at the same time;
* Allows you to have multiple models signed in at the same time;
* Is based on a modularity concept: use just what you really need.
It's composed of 12 modules:
It's composed of 10 modules:
* [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
* [Token Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable): signs in a user based on an authentication token (also known as "single access token"). The token can be given both through query string or HTTP Basic Authentication.
* [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds Omniauth (https://github.com/intridea/omniauth) support;
* [Confirmable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
* [Recoverable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable): resets the user password and sends reset instructions.
@@ -27,13 +27,15 @@ It's composed of 12 modules:
* [Validatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Validatable): provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.
* [Lockable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Lockable): locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.
Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby is on progress.
## Information
### The Devise wiki
The Devise Wiki has lots of additional information about Devise including many "how-to" articles and answers to the most frequently asked questions. Please browse the Wiki after finishing this README:
https://wiki.github.com/plataformatec/devise
https://github.com/plataformatec/devise/wiki
### Bug reports
@@ -55,7 +57,7 @@ You can view the Devise documentation in RDoc format here:
http://rubydoc.info/github/plataformatec/devise/master/frames
If you need to use Devise with Rails 2.3, you can always run "gem server" from the command line after you install the gem to access the old documentation.
If you need to use Devise with previous versions of Rails, you can always run "gem server" from the command line after you install the gem to access the old documentation.
### Example applications
@@ -88,7 +90,7 @@ Once you have solidified your understanding of Rails and authentication mechanis
## Getting started
Devise 2.0 works with Rails 3.1 onwards. You can add it to your Gemfile with:
Devise 3.0 works with Rails 3.2 onwards. You can add it to your Gemfile with:
```ruby
gem 'devise'
@@ -108,7 +110,7 @@ The generator will install an initializer which describes ALL Devise's configura
rails generate devise MODEL
```
Replace MODEL by the class name used for the applications users, it's frequently 'User' but could also be 'Admin'. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run "rake db:migrate" as the generator will have created a migration file (if your ORM supports them). This generator also configures your config/routes.rb file to point to the Devise controller.
Replace MODEL by the class name used for the applications users, it's frequently `User` but could also be `Admin`. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run `rake db:migrate` as the generator will have created a migration file (if your ORM supports them). This generator also configures your config/routes.rb file to point to the Devise controller.
Note that you should re-start your app here if you've already started it. Otherwise you'll run into strange errors like users being unable to login and the route helpers being undefined.
@@ -141,7 +143,7 @@ user_session
After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect. Example: For a :user resource, it will use `user_root_path` if it exists, otherwise default `root_path` will be used. This means that you need to set the root inside your routes:
```ruby
root :to => "home#index"
root to: "home#index"
```
You can also overwrite `after_sign_in_path_for` and `after_sign_out_path_for` to customize your redirect hooks.
@@ -174,34 +176,65 @@ devise :database_authenticatable, :registerable, :confirmable, :recoverable, :st
Besides :stretches, you can define :pepper, :encryptor, :confirm_within, :remember_for, :timeout_in, :unlock_in and other values. For details, see the initializer file that was created when you invoked the "devise:install" generator described above.
### Configuring multiple models
### Strong Parameters
Devise allows you to set up as many roles as you want. For example, you may have a User model and also want an Admin model with just authentication and timeoutable features. If so, just follow these steps:
When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing Devise to handle this concern at the controller as well.
There are just three actions in Devise that allows any set of parameters to be passed down to the model, therefore requiring sanitization. Their names and the permitted parameters by default are:
* `sign_in` (`Devise::SessionsController#new`) - Permits only the authentication keys (like `email`)
* `sign_up` (`Devise::RegistrationsController#create`) - Permits authentication keys plus `password` and `password_confirmation`
* `account_update` (`Devise::RegistrationsController#update`) - Permits authentication keys plus `password`, `password_confirmation` and `current_password`
In case you want to permit additional parameters (the lazy way™) you can do with a simple before filter in your `ApplicationController`:
```ruby
# Create a migration with the required fields
create_table :admins do |t|
t.string :email
t.string :encrypted_password
t.timestamps
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end
# Inside your Admin model
devise :database_authenticatable, :timeoutable
# Inside your routes
devise_for :admins
# Inside your protected controller
before_filter :authenticate_admin!
# Inside your controllers and views
admin_signed_in?
current_admin
admin_session
```
On the other hand, you can simply run the generator!
To completely change Devise defaults or invoke custom behaviour, you can also pass a block:
```ruby
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email) }
end
```
If you have multiple Devise models, you may want to set up different parameter sanitizer per model. In this case, we recommend inheriting from `Devise::ParameterSanitizer` and add your own logic:
```ruby
class User::ParameterSanitizer < Devise::ParameterSanitizer
def sign_in
default_params.permit(:username, :email)
end
end
```
And then configure your controllers to use it:
```ruby
class ApplicationController < ActionController::Base
protected
def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super # Use the default one
end
end
end
```
The example above overrides the permitted parameters for the user to be both `:username` and `:email`. The non-lazy way to configure parameters would be by defining the before filter above in a custom controller. We detail how to configure and customize controllers in some sections below.
### Configuring views
@@ -213,7 +246,7 @@ Since Devise is an engine, all its views are packaged inside the gem. These view
rails generate devise:views
```
If you have more than one role in your application (such as "User" and "Admin"), you will notice that Devise uses the same views for all roles. Fortunately, Devise offers an easy way to customize views. All you need to do is set "config.scoped_views = true" inside "config/initializers/devise.rb".
If you have more than one Devise model in your application (such as "User" and "Admin"), you will notice that Devise uses the same views for all models. Fortunately, Devise offers an easy way to customize views. All you need to do is set "config.scoped_views = true" inside "config/initializers/devise.rb".
After doing so, you will be able to have views based on the role like "users/sessions/new" and "admins/sessions/new". If no view is found within the scope, Devise will use the default view at "devise/sessions/new". You can also use the generator to generate scoped views:
@@ -225,22 +258,24 @@ rails generate devise:views users
If the customization at the views level is not enough, you can customize each controller by following these steps:
1) Create your custom controller, for example a Admins::SessionsController:
1. Create your custom controller, for example a `Admins::SessionsController`:
```ruby
class Admins::SessionsController < Devise::SessionsController
end
```
```ruby
class Admins::SessionsController < Devise::SessionsController
end
```
2) Tell the router to use this controller:
Note that in the above example, the controller needs to be created in the `app/controller/admins/` directory.
```ruby
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
```
2. Tell the router to use this controller:
3) And since we changed the controller, it won't use the "devise/sessions" views, so remember to copy "devise/sessions" to "admin/sessions".
```ruby
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
```
Remember that Devise uses flash messages to let users know if sign in was successful or failed. Devise expects your application to call "flash[:notice]" and "flash[:alert]" as appropriate. Do not print the entire flash hash, print specific keys or at least remove the `:timedout` key from the hash as Devise adds this key in some circumstances, this key is not meant for display.
3. And since we changed the controller, it won't use the `"devise/sessions"` views, so remember to copy `"devise/sessions"` to `"admin/sessions"`.
Remember that Devise uses flash messages to let users know if sign in was successful or failed. Devise expects your application to call `"flash[:notice]"` and `"flash[:alert]"` as appropriate. Do not print the entire flash hash, print specific keys or at least remove the `:timedout` key from the hash as Devise adds this key in some circumstances, this key is not meant for display.
### Configuring routes
@@ -332,12 +367,14 @@ sign_out @user # sign_out(resource)
There are two things that is important to keep in mind:
1) These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;
1. These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;
2) If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
2. If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
```ruby
@request.env["devise.mapping"] = Devise.mappings[:user]
get :new
```
### Omniauth
@@ -351,15 +388,42 @@ You can read more about Omniauth support in the wiki:
* https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
### Configuring multiple models
Devise allows you to set up as many Devise models as you want. If you want to have an Admin model with just authentication and timeout features, in addition to the User model above, just run:
```ruby
# Create a migration with the required fields
create_table :admins do |t|
t.string :email
t.string :encrypted_password
t.timestamps
end
# Inside your Admin model
devise :database_authenticatable, :timeoutable
# Inside your routes
devise_for :admins
# Inside your protected controller
before_filter :authenticate_admin!
# Inside your controllers and views
admin_signed_in?
current_admin
admin_session
```
Alternatively, you can simply run the Devise generator.
Keep in mind that those models will have completely different routes. They **do not** and **cannot** share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend you to use a role-based approach, by either providing a role column or using [CanCan](https://github.com/ryanb/cancan).
### Other ORMs
Devise supports ActiveRecord (default) and Mongoid. To choose other ORM, you just need to require it in the initializer file.
### Migrating from other solutions
Devise implements encryption strategies for Clearance, Authlogic and Restful-Authentication. To make use of these strategies, you need set the desired encryptor in the encryptor initializer config option and add :encryptable to your model. You might also need to rename your encrypted password and salt columns to match Devise's fields (encrypted_password and password_salt).
## Troubleshooting
## Additional information
### Heroku
@@ -371,8 +435,6 @@ config.assets.initialize_on_precompile = false
Read more about the potential issues at http://guides.rubyonrails.org/asset_pipeline.html
## Additional information
### Warden
Devise is based on Warden, which is a general Rack authentication framework created by Daniel Neighman. We encourage you to read more about Warden here:
@@ -383,14 +445,10 @@ https://github.com/hassox/warden
We have a long list of valued contributors. Check them all at:
https://github.com/plataformatec/devise/contributors
### Maintainers
* José Valim (https://github.com/josevalim)
* Carlos Antônio da Silva (https://github.com/carlosantoniodasilva)
* Rodrigo Flores (https://github.com/rodrigoflores)
https://github.com/plataformatec/devise/graphs/contributors
## License
MIT License. Copyright 2009-2013 Plataformatec. http://plataformatec.com.br
You are not granted rights or licenses to the trademarks of the Plataformatec, including without limitation the Devise name or logo.

View File

@@ -22,6 +22,7 @@ Rake::TestTask.new(:test) do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = false
end
desc 'Generate documentation for Devise.'

View File

@@ -1,12 +1,13 @@
class Devise::ConfirmationsController < DeviseController
# GET /resource/confirmation/new
def new
build_resource({})
self.resource = resource_class.new
end
# POST /resource/confirmation
def create
self.resource = resource_class.send_confirmation_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
@@ -18,10 +19,10 @@ class Devise::ConfirmationsController < DeviseController
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
yield resource if block_given?
if resource.errors.empty?
set_flash_message(:notice, :confirmed) if is_navigational_format?
sign_in(resource_name, resource)
set_flash_message(:notice, :confirmed) if is_flashing_format?
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
@@ -32,12 +33,15 @@ class Devise::ConfirmationsController < DeviseController
# The path used after resending confirmation instructions.
def after_resending_confirmation_instructions_path_for(resource_name)
new_session_path(resource_name)
new_session_path(resource_name) if is_navigational_format?
end
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
after_sign_in_path_for(resource)
if signed_in?
signed_in_root_path(resource)
else
new_session_path(resource_name)
end
end
end

View File

@@ -5,12 +5,13 @@ class Devise::PasswordsController < DeviseController
# GET /resource/password/new
def new
build_resource({})
self.resource = resource_class.new
end
# POST /resource/password
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
@@ -28,29 +29,33 @@ class Devise::PasswordsController < DeviseController
# PUT /resource/password
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_navigational_format?
set_flash_message(:notice, flash_message) if is_flashing_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
respond_with resource, :location => after_resetting_password_path_for(resource)
else
respond_with resource
end
end
protected
def after_resetting_password_path_for(resource)
after_sign_in_path_for(resource)
end
# The path used after sending reset password instructions
def after_sending_reset_password_instructions_path_for(resource_name)
new_session_path(resource_name)
new_session_path(resource_name) if is_navigational_format?
end
# Check if a reset_password_token is provided in the request
def assert_reset_token_passed
if params[:reset_password_token].blank?
set_flash_message(:error, :no_token)
set_flash_message(:alert, :no_token)
redirect_to new_session_path(resource_name)
end
end

View File

@@ -4,22 +4,23 @@ class Devise::RegistrationsController < DeviseController
# GET /resource/sign_up
def new
resource = build_resource({})
respond_with resource
build_resource({})
respond_with self.resource
end
# POST /resource
def create
build_resource
build_resource(sign_up_params)
if resource.save
yield resource if block_given?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
@@ -40,8 +41,9 @@ class Devise::RegistrationsController < DeviseController
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
if resource.update_with_password(resource_params)
if is_navigational_format?
if update_resource(resource, account_update_params)
yield resource if block_given?
if is_flashing_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
@@ -58,7 +60,8 @@ class Devise::RegistrationsController < DeviseController
def destroy
resource.destroy
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message :notice, :destroyed if is_navigational_format?
set_flash_message :notice, :destroyed if is_flashing_format?
yield resource if block_given?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
@@ -68,7 +71,7 @@ class Devise::RegistrationsController < DeviseController
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
def cancel
expire_session_data_after_sign_in!
expire_data_after_sign_in!
redirect_to new_registration_path(resource_name)
end
@@ -80,11 +83,16 @@ class Devise::RegistrationsController < DeviseController
previous != resource.unconfirmed_email
end
# By default we want to require a password checks on update.
# You can overwrite this method in your own RegistrationsController.
def update_resource(resource, params)
resource.update_with_password(params)
end
# Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user.
def build_resource(hash=nil)
hash ||= resource_params || {}
self.resource = resource_class.new_with_session(hash, session)
self.resource = resource_class.new_with_session(hash || {}, session)
end
# Signs in a user on sign up. You can overwrite this method in your own
@@ -116,4 +124,12 @@ class Devise::RegistrationsController < DeviseController
send(:"authenticate_#{resource_name}!", :force => true)
self.resource = send(:"current_#{resource_name}")
end
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
end
def account_update_params
devise_parameter_sanitizer.sanitize(:account_update)
end
end

View File

@@ -1,11 +1,11 @@
class Devise::SessionsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
prepend_before_filter :allow_params_authentication!, :only => :create
prepend_before_filter { request.env["devise.skip_timeout"] = true }
prepend_before_filter :only => [ :create, :destroy ] { request.env["devise.skip_timeout"] = true }
# GET /resource/sign_in
def new
self.resource = build_resource(nil, :unsafe => true)
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
respond_with(resource, serialize_options(resource))
end
@@ -13,8 +13,9 @@ class Devise::SessionsController < DeviseController
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, :location => after_sign_in_path_for(resource)
end
@@ -22,7 +23,8 @@ class Devise::SessionsController < DeviseController
def destroy
redirect_path = after_sign_out_path_for(resource_name)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
yield resource if block_given?
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
@@ -34,6 +36,10 @@ class Devise::SessionsController < DeviseController
protected
def sign_in_params
devise_parameter_sanitizer.sanitize(:sign_in)
end
def serialize_options(resource)
methods = resource_class.authentication_keys.dup
methods = methods.keys if methods.is_a?(Hash)
@@ -45,4 +51,3 @@ class Devise::SessionsController < DeviseController
{ :scope => resource_name, :recall => "#{controller_path}#new" }
end
end

View File

@@ -3,12 +3,13 @@ class Devise::UnlocksController < DeviseController
# GET /resource/unlock/new
def new
build_resource({})
self.resource = resource_class.new
end
# POST /resource/unlock
def create
self.resource = resource_class.send_unlock_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, :location => after_sending_unlock_instructions_path_for(resource))
@@ -20,9 +21,10 @@ class Devise::UnlocksController < DeviseController
# GET /resource/unlock?unlock_token=abcdef
def show
self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
yield resource if block_given?
if resource.errors.empty?
set_flash_message :notice, :unlocked if is_navigational_format?
set_flash_message :notice, :unlocked if is_flashing_format?
respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
else
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
@@ -33,12 +35,12 @@ class Devise::UnlocksController < DeviseController
# The path used after sending unlock password instructions
def after_sending_unlock_instructions_path_for(resource)
new_session_path(resource)
new_session_path(resource) if is_navigational_format?
end
# The path used after unlocking the resource
def after_unlock_path_for(resource)
new_session_path(resource)
new_session_path(resource) if is_navigational_format?
end
end

View File

@@ -28,10 +28,6 @@ class DeviseController < Devise.parent_controller.constantize
devise_mapping.to
end
def resource_params
params[resource_name]
end
# Returns a signed in resource from session (if one exists)
def signed_in_resource
warden.authenticate(:scope => resource_name)
@@ -67,7 +63,7 @@ This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
match "/some/route" => "some_devise_controller"
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
@@ -93,23 +89,6 @@ MESSAGE
instance_variable_set(:"@#{resource_name}", new_resource)
end
# Build a devise resource.
# Assignment bypasses attribute protection when :unsafe option is passed
def build_resource(hash = nil, options = {})
hash ||= resource_params || {}
if options[:unsafe]
self.resource = resource_class.new.tap do |resource|
hash.each do |key, value|
setter = :"#{key}="
resource.send(setter, value) if resource.respond_to?(setter)
end
end
else
self.resource = resource_class.new(hash)
end
end
# Helper for use in before_filters where no authentication is required.
#
# Example:
@@ -144,7 +123,7 @@ MESSAGE
end
if notice
set_flash_message :notice, notice if is_navigational_format?
set_flash_message :notice, notice if is_flashing_format?
true
end
end
@@ -163,13 +142,22 @@ MESSAGE
#
# Please refer to README or en.yml locale file to check what messages are
# available.
def set_flash_message(key, kind, options={})
def set_flash_message(key, kind, options = {})
message = find_message(kind, options)
flash[key] = message if message.present?
end
def devise_i18n_options(options)
options
end
# Get message for given
def find_message(kind, options = {})
options[:scope] = "devise.#{controller_name}"
options[:default] = Array(options[:default]).unshift(kind.to_sym)
options[:resource_name] = resource_name
options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
message = I18n.t("#{options[:resource_name]}.#{kind}", options)
flash[key] = message if message.present?
options = devise_i18n_options(options)
I18n.t("#{options[:resource_name]}.#{kind}", options)
end
def clean_up_passwords(object)
@@ -181,4 +169,8 @@ MESSAGE
format.any(*navigational_formats, &block)
end
end
def resource_params
params.fetch(resource_name, {})
end
end

View File

@@ -1,15 +1,20 @@
class Devise::Mailer < ::ActionMailer::Base
include Devise::Mailers::Helpers
if defined?(ActionMailer)
class Devise::Mailer < Devise.parent_mailer.constantize
include Devise::Mailers::Helpers
def confirmation_instructions(record, opts={})
devise_mail(record, :confirmation_instructions, opts)
end
def confirmation_instructions(record, token, opts={})
@token = token
devise_mail(record, :confirmation_instructions, opts)
end
def reset_password_instructions(record, opts={})
devise_mail(record, :reset_password_instructions, opts)
end
def reset_password_instructions(record, token, opts={})
@token = token
devise_mail(record, :reset_password_instructions, opts)
end
def unlock_instructions(record, opts={})
devise_mail(record, :unlock_instructions, opts)
def unlock_instructions(record, token, opts={})
@token = token
devise_mail(record, :unlock_instructions, opts)
end
end
end

View File

@@ -1,3 +0,0 @@
<% ActiveSupport::Deprecation.warn "Rendering partials devise/_links.erb is deprecated" \
"please use devise/shared/_links.erb instead."%>
<%= render "shared/links" %>

View File

@@ -2,4 +2,4 @@
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %></p>

View File

@@ -2,7 +2,7 @@
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View File

@@ -4,4 +4,4 @@
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @token) %></p>

View File

@@ -24,6 +24,6 @@
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %></p>
<%= link_to "Back", :back %>

View File

@@ -6,7 +6,7 @@
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>
@@ -22,4 +22,4 @@
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
<% end -%>
<% end -%>
<% end -%>

View File

@@ -1,60 +1,59 @@
# Additional translations at https://github.com/plataformatec/devise/wiki/I18n
en:
devise:
confirmations:
confirmed: "Your account was successfully confirmed."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
failure:
already_authenticated: "You are already signed in."
inactive: "Your account is not activated yet."
invalid: "Invalid email or password."
locked: "Your account is locked."
last_attempt: "You have one more attempt before your account will be locked."
not_found_in_database: "Invalid email or password."
timeout: "Your session expired. Please sign in again to continue."
unauthenticated: "You need to sign in or sign up before continuing."
unconfirmed: "You have to confirm your account before continuing."
mailer:
confirmation_instructions:
subject: "Confirmation instructions"
reset_password_instructions:
subject: "Reset password instructions"
unlock_instructions:
subject: "Unlock Instructions"
omniauth_callbacks:
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
success: "Successfully authenticated from %{kind} account."
passwords:
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
send_instructions: "You will receive an email with instructions about how to reset your password in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
updated: "Your password was changed successfully. You are now signed in."
updated_not_active: "Your password was changed successfully."
registrations:
destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon."
signed_up: "Welcome! You have signed up successfully."
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
updated: "You updated your account successfully."
sessions:
signed_in: "Signed in successfully."
signed_out: "Signed out successfully."
unlocks:
send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes."
send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
errors:
messages:
already_confirmed: "was already confirmed, please try signing in"
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
expired: "has expired, please request a new one"
not_found: "not found"
already_confirmed: "was already confirmed, please try signing in"
not_locked: "was not locked"
not_saved:
one: "1 error prohibited this %{resource} from being saved:"
other: "%{count} errors prohibited this %{resource} from being saved:"
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
devise:
failure:
already_authenticated: 'You are already signed in.'
unauthenticated: 'You need to sign in or sign up before continuing.'
unconfirmed: 'You have to confirm your account before continuing.'
locked: 'Your account is locked.'
not_found_in_database: 'Invalid email or password.'
invalid: 'Invalid email or password.'
invalid_token: 'Invalid authentication token.'
timeout: 'Your session expired, please sign in again to continue.'
inactive: 'Your account was not activated yet.'
sessions:
signed_in: 'Signed in successfully.'
signed_out: 'Signed out successfully.'
passwords:
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
updated: 'Your password was changed successfully. You are now signed in.'
updated_not_active: 'Your password was changed successfully.'
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
confirmations:
send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
send_paranoid_instructions: 'If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.'
confirmed: 'Your account was successfully confirmed. You are now signed in.'
registrations:
signed_up: 'Welcome! You have signed up successfully.'
signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.'
signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.'
signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.'
updated: 'You updated your account successfully.'
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
unlocks:
send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
unlocked: 'Your account has been unlocked successfully. Please sign in to continue.'
send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.'
omniauth_callbacks:
success: 'Successfully authenticated from %{kind} account.'
failure: 'Could not authenticate you from %{kind} because "%{reason}".'
mailer:
confirmation_instructions:
subject: 'Confirmation instructions'
reset_password_instructions:
subject: 'Reset password instructions'
unlock_instructions:
subject: 'Unlock Instructions'

View File

@@ -6,6 +6,7 @@ Gem::Specification.new do |s|
s.name = "devise"
s.version = Devise::VERSION.dup
s.platform = Gem::Platform::RUBY
s.licenses = ["MIT"]
s.summary = "Flexible authentication solution for Rails with Warden"
s.email = "contact@plataformatec.com.br"
s.homepage = "http://github.com/plataformatec/devise"
@@ -18,8 +19,9 @@ Gem::Specification.new do |s|
s.test_files = `git ls-files -- test/*`.split("\n")
s.require_paths = ["lib"]
s.add_dependency("warden", "~> 1.2.1")
s.add_dependency("warden", "~> 1.2.3")
s.add_dependency("orm_adapter", "~> 0.1")
s.add_dependency("bcrypt-ruby", "~> 3.0")
s.add_dependency("railties", "~> 3.1")
s.add_dependency("thread_safe", "~> 0.1")
s.add_dependency("railties", ">= 3.2.6", "< 5")
end

BIN
devise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,167 +0,0 @@
PATH
remote: ..
specs:
devise (2.2.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.1.10)
actionpack (= 3.1.10)
mail (~> 2.3.3)
actionpack (3.1.10)
activemodel (= 3.1.10)
activesupport (= 3.1.10)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
rack (~> 1.3.6)
rack-cache (~> 1.2)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
sprockets (~> 2.0.4)
activemodel (3.1.10)
activesupport (= 3.1.10)
builder (~> 3.0.0)
i18n (~> 0.6)
activerecord (3.1.10)
activemodel (= 3.1.10)
activesupport (= 3.1.10)
arel (~> 2.2.3)
tzinfo (~> 0.3.29)
activeresource (3.1.10)
activemodel (= 3.1.10)
activesupport (= 3.1.10)
activesupport (3.1.10)
multi_json (>= 1.0, < 1.3)
arel (2.2.3)
bcrypt-ruby (3.0.1)
builder (3.0.4)
columnize (0.3.6)
erubis (2.7.0)
faraday (0.8.4)
multipart-post (~> 1.1)
hashie (1.2.0)
hike (1.2.1)
httpauth (0.2.0)
i18n (0.6.1)
json (1.7.6)
jwt (0.1.5)
multi_json (>= 1.0)
linecache (0.46)
rbx-require-relative (> 0.0.4)
mail (2.3.3)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
mime-types (1.19)
mocha (0.10.0)
metaclass (~> 0.0.1)
mongoid (3.0.16)
activemodel (~> 3.1)
moped (~> 1.1)
origin (~> 1.0)
tzinfo (~> 0.3.22)
moped (1.3.2)
multi_json (1.2.0)
multipart-post (1.1.5)
nokogiri (1.5.6)
oauth2 (0.8.0)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.0.3)
hashie (~> 1.2)
rack
omniauth-facebook (1.4.0)
omniauth-oauth2 (~> 1.0.2)
omniauth-oauth2 (1.0.3)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
origin (1.0.11)
orm_adapter (0.4.0)
polyglot (0.3.3)
rack (1.3.8)
rack-cache (1.2)
rack (>= 0.4)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-ssl (1.3.2)
rack
rack-test (0.6.2)
rack (>= 1.0)
rails (3.1.10)
actionmailer (= 3.1.10)
actionpack (= 3.1.10)
activerecord (= 3.1.10)
activeresource (= 3.1.10)
activesupport (= 3.1.10)
bundler (~> 1.0)
railties (= 3.1.10)
railties (3.1.10)
actionpack (= 3.1.10)
activesupport (= 3.1.10)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (10.0.3)
rbx-require-relative (0.0.9)
rdoc (3.12)
json (~> 1.4)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
ruby-openid (2.2.2)
sprockets (2.0.4)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.35)
warden (1.2.1)
rack (>= 1.0)
webrat (0.7.2)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbc-adapter
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (= 0.10.0)
mongoid (~> 3.0)
omniauth (~> 1.0.0)
omniauth-facebook
omniauth-oauth2 (~> 1.0.0)
omniauth-openid (~> 1.0.1)
rails (~> 3.1.0)
rdoc
ruby-debug (>= 0.10.3)
sqlite3
webrat (= 0.7.2)

View File

@@ -1,8 +1,8 @@
source "http://rubygems.org"
source "https://rubygems.org"
gem "devise", :path => ".."
gemspec :path => '..'
gem "rails", "~> 3.1.0"
gem "rails", "~> 3.2.6"
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "rdoc"
@@ -10,12 +10,8 @@ gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.2", :require => false
gem "mocha", "0.10.0", :require => false
platforms :mri_18 do
gem "ruby-debug", ">= 0.10.3"
end
gem "webrat", "0.7.3", :require => false
gem "mocha", "~> 0.13.1", :require => false
end
platforms :jruby do
@@ -28,8 +24,8 @@ platforms :ruby do
gem "sqlite3"
end
platforms :mri_19 do
platforms :mri_19, :mri_20 do
group :mongoid do
gem "mongoid", "~> 3.0"
end
end
end

View File

@@ -0,0 +1,159 @@
PATH
remote: ..
specs:
devise (3.2.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
GEM
remote: https://rubygems.org/
specs:
actionmailer (3.2.14)
actionpack (= 3.2.14)
mail (~> 2.5.4)
actionpack (3.2.14)
activemodel (= 3.2.14)
activesupport (= 3.2.14)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.14)
activesupport (= 3.2.14)
builder (~> 3.0.0)
activerecord (3.2.14)
activemodel (= 3.2.14)
activesupport (= 3.2.14)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.14)
activemodel (= 3.2.14)
activesupport (= 3.2.14)
activesupport (3.2.14)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.2)
atomic (1.1.14)
bcrypt-ruby (3.1.2)
builder (3.0.4)
erubis (2.7.0)
faraday (0.8.8)
multipart-post (~> 1.2.0)
hashie (1.2.0)
hike (1.2.3)
httpauth (0.2.0)
i18n (0.6.5)
journey (1.0.4)
json (1.8.0)
jwt (0.1.8)
multi_json (>= 1.5)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
mime-types (1.23)
mocha (0.13.3)
metaclass (~> 0.0.1)
mongoid (3.1.4)
activemodel (~> 3.2)
moped (~> 1.4)
origin (~> 1.0)
tzinfo (~> 0.3.22)
moped (1.5.1)
multi_json (1.7.9)
multipart-post (1.2.0)
nokogiri (1.5.9)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.0.3)
hashie (~> 1.2)
rack
omniauth-facebook (1.4.0)
omniauth-oauth2 (~> 1.0.2)
omniauth-oauth2 (1.0.3)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
origin (1.1.0)
orm_adapter (0.4.0)
polyglot (0.3.3)
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-ssl (1.3.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.14)
actionmailer (= 3.2.14)
actionpack (= 3.2.14)
activerecord (= 3.2.14)
activeresource (= 3.2.14)
activesupport (= 3.2.14)
bundler (~> 1.0)
railties (= 3.2.14)
railties (3.2.14)
actionpack (= 3.2.14)
activesupport (= 3.2.14)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.1.0)
rdoc (3.12.2)
json (~> 1.4)
ruby-openid (2.2.3)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.7)
thor (0.18.1)
thread_safe (0.1.3)
atomic
tilt (1.4.1)
treetop (1.4.14)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbc-adapter
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (~> 0.13.1)
mongoid (~> 3.0)
omniauth (~> 1.0.0)
omniauth-facebook
omniauth-oauth2 (~> 1.0.0)
omniauth-openid (~> 1.0.1)
rails (~> 3.2.6)
rdoc
sqlite3
webrat (= 0.7.3)

View File

@@ -6,20 +6,29 @@ require 'set'
require 'securerandom'
module Devise
autoload :Delegator, 'devise/delegator'
autoload :FailureApp, 'devise/failure_app'
autoload :OmniAuth, 'devise/omniauth'
autoload :ParamFilter, 'devise/param_filter'
autoload :TestHelpers, 'devise/test_helpers'
autoload :TimeInflector, 'devise/time_inflector'
autoload :Delegator, 'devise/delegator'
autoload :FailureApp, 'devise/failure_app'
autoload :OmniAuth, 'devise/omniauth'
autoload :ParameterFilter, 'devise/parameter_filter'
autoload :BaseSanitizer, 'devise/parameter_sanitizer'
autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
autoload :TestHelpers, 'devise/test_helpers'
autoload :TimeInflector, 'devise/time_inflector'
autoload :TokenGenerator, 'devise/token_generator'
module Controllers
autoload :Helpers, 'devise/controllers/helpers'
autoload :Rememberable, 'devise/controllers/rememberable'
autoload :ScopedViews, 'devise/controllers/scoped_views'
autoload :SignInOut, 'devise/controllers/sign_in_out'
autoload :StoreLocation, 'devise/controllers/store_location'
autoload :UrlHelpers, 'devise/controllers/url_helpers'
end
module Hooks
autoload :Proxy, 'devise/hooks/proxy'
end
module Mailers
autoload :Helpers, 'devise/mailers/helpers'
end
@@ -43,7 +52,27 @@ module Devise
# True values used to check params
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
# Custom domain for cookies. Not set by default
# Secret key used by the key generator
mattr_accessor :secret_key
@@secret_key = nil
[ :allow_insecure_token_lookup,
:allow_insecure_sign_in_after_confirmation,
:token_authentication_key ].each do |method|
class_eval <<-RUBY
def self.#{method}
ActiveSupport::Deprecation.warn "Devise.#{method} is deprecated " \
"and has no effect"
end
def self.#{method}=(val)
ActiveSupport::Deprecation.warn "Devise.#{method}= is deprecated " \
"and has no effect"
end
RUBY
end
# Custom domain or key for cookies. Not set by default
mattr_accessor :rememberable_options
@@rememberable_options = {}
@@ -51,6 +80,10 @@ module Devise
mattr_accessor :stretches
@@stretches = 10
# The default key used when authenticating over http auth.
mattr_accessor :http_authentication_key
@@http_authentication_key = nil
# Keys used when authenticating a user.
mattr_accessor :authentication_keys
@@authentication_keys = [ :email ]
@@ -102,6 +135,7 @@ module Devise
@@extend_remember_period = false
# Time interval you can access your account before confirming your account.
# nil - allows unconfirmed access for unlimited time
mattr_accessor :allow_unconfirmed_access_for
@@allow_unconfirmed_access_for = 0.days
@@ -173,10 +207,6 @@ module Devise
mattr_accessor :mailer_sender
@@mailer_sender = nil
# Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
mattr_accessor :token_authentication_key
@@token_authentication_key = :auth_token
# Skip session storage for the following strategies
mattr_accessor :skip_session_storage
@@skip_session_storage = []
@@ -199,6 +229,12 @@ module Devise
mattr_accessor :parent_controller
@@parent_controller = "ApplicationController"
# The parent mailer all Devise mailers inherit from.
# Defaults to ActionMailer::Base. This should be set early
# in the initialization process and should be set to a string.
mattr_accessor :parent_mailer
@@parent_mailer = "ActionMailer::Base"
# The router Devise should use to generate routes. Defaults
# to :main_app. Should be overriden by engines in order
# to provide custom routes.
@@ -210,17 +246,9 @@ module Devise
mattr_accessor :omniauth_path_prefix
@@omniauth_path_prefix = nil
def self.encryptor=(value)
warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
end
def self.use_salt_as_remember_token=(value)
warn "\n[DEVISE] Devise.use_salt_as_remember_token is deprecated and has no effect. Please remove it.\n"
end
def self.apply_schema=(value)
warn "\n[DEVISE] Devise.apply_schema is deprecated and has no effect. Please remove it.\n"
end
# Set if we should clean up the CSRF Token on authentication
mattr_accessor :clean_up_csrf_token_on_authentication
@@clean_up_csrf_token_on_authentication = true
# PRIVATE CONFIGURATION
@@ -246,6 +274,14 @@ module Devise
mattr_accessor :paranoid
@@paranoid = false
# When true, warn user if he just used next-to-last attempt of authentication
mattr_accessor :last_attempt_warning
@@last_attempt_warning = false
# Stores the token generator
mattr_accessor :token_generator
@@token_generator = nil
# Default way to setup Devise. Run rails generate devise_install to create
# a fresh initializer with all configuration values.
def self.setup
@@ -304,7 +340,7 @@ module Devise
# == Options:
#
# +model+ - String representing the load path to a custom *model* for this module (to autoload.)
# +controller+ - Symbol representing the name of an exisiting or custom *controller* for this module.
# +controller+ - Symbol representing the name of an existing or custom *controller* for this module.
# +route+ - Symbol representing the named *route* helper for this module.
# +strategy+ - Symbol representing if this module got a custom *strategy*.
#
@@ -414,6 +450,17 @@ module Devise
Devise.mappings.each_value do |mapping|
warden_config.scope_defaults mapping.name, :strategies => mapping.strategies
warden_config.serialize_into_session(mapping.name) do |record|
mapping.to.serialize_into_session(record)
end
warden_config.serialize_from_session(mapping.name) do |key|
# Previous versions contained an additional entry at the beginning of
# key with the record's class name.
args = key[-2, 2]
mapping.to.serialize_from_session(*args)
end
end
@@warden_config_block.try :call, Devise.warden_config
@@ -421,9 +468,9 @@ module Devise
end
end
# Generate a friendly string randomically to be used as token.
# Generate a friendly string randomly to be used as token.
def self.friendly_token
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz')
end
# constant-time comparison algorithm to prevent timing attacks

View File

@@ -3,6 +3,8 @@ module Devise
# Those helpers are convenience methods added to ApplicationController.
module Helpers
extend ActiveSupport::Concern
include Devise::Controllers::SignInOut
include Devise::Controllers::StoreLocation
included do
helper_method :warden, :signed_in?, :devise_controller?
@@ -80,105 +82,22 @@ module Devise
is_a?(DeviseController)
end
# Setup a param sanitizer to filter parameters using strong_parameters. See
# lib/devise/parameter_sanitizer.rb for more info. Override this
# method in your application controller to use your own parameter sanitizer.
def devise_parameter_sanitizer
@devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
Devise::ParameterSanitizer.new(resource_class, resource_name, params)
else
Devise::BaseSanitizer.new(resource_class, resource_name, params)
end
end
# Tell warden that params authentication is allowed for that specific page.
def allow_params_authentication!
request.env["devise.allow_params_authentication"] = true
end
# Return true if the given scope is signed in session. If no scope given, return
# true if any scope is signed in. Does not run authentication hooks.
def signed_in?(scope=nil)
[ scope || Devise.mappings.keys ].flatten.any? do |_scope|
warden.authenticate?(:scope => _scope)
end
end
# Sign in a user that already was authenticated. This helper is useful for logging
# users in after sign up.
#
# All options given to sign_in is passed forward to the set_user method in warden.
# The only exception is the :bypass option, which bypass warden callbacks and stores
# the user straight in session. This option is useful in cases the user is already
# signed in, but we want to refresh the credentials in session.
#
# Examples:
#
# sign_in :user, @user # sign_in(scope, resource)
# sign_in @user # sign_in(resource)
# sign_in @user, :event => :authentication # sign_in(resource, options)
# sign_in @user, :bypass => true # sign_in(resource, options)
#
def sign_in(resource_or_scope, *args)
options = args.extract_options!
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource = args.last || resource_or_scope
expire_session_data_after_sign_in!
if options[:bypass]
warden.session_serializer.store(resource, scope)
elsif warden.user(scope) == resource && !options.delete(:force)
# Do nothing. User already signed in and we are not forcing it.
true
else
warden.set_user(resource, options.merge!(:scope => scope))
end
end
# Sign out a given user or scope. This helper is useful for signing out a user
# after deleting accounts. Returns true if there was a logout and false if there
# is no user logged in on the referred scope
#
# Examples:
#
# sign_out :user # sign_out(scope)
# sign_out @user # sign_out(resource)
#
def sign_out(resource_or_scope=nil)
return sign_out_all_scopes unless resource_or_scope
scope = Devise::Mapping.find_scope!(resource_or_scope)
user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
warden.raw_session.inspect # Without this inspect here. The session does not clear.
warden.logout(scope)
warden.clear_strategies_cache!(:scope => scope)
instance_variable_set(:"@current_#{scope}", nil)
!!user
end
# Sign out all active users or scopes. This helper is useful for signing out all roles
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
# and false if there was no user logged in on all scopes.
def sign_out_all_scopes(lock=true)
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
warden.raw_session.inspect
warden.logout
expire_devise_cached_variables!
warden.clear_strategies_cache!
warden.lock! if lock
users.any?
end
# Returns and delete (if it's navigational format) the url stored in the session for
# the given scope. Useful for giving redirect backs after sign up:
#
# Example:
#
# redirect_to stored_location_for(:user) || root_path
#
def stored_location_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
if is_navigational_format?
session.delete("#{scope}_return_to")
else
session["#{scope}_return_to"]
end
end
# The scope root url to be used when he's signed in. By default, it first
# tries to find a resource_root_path, otherwise it uses the root_path.
def signed_in_root_path(resource_or_scope)
@@ -245,10 +164,6 @@ module Devise
redirect_to after_sign_in_path_for(resource)
end
def expire_session_data_after_sign_in!
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
end
# Sign out a user and tries to redirect to the url specified by
# after_sign_out_path_for.
def sign_out_and_redirect(resource_or_scope)
@@ -263,7 +178,7 @@ module Devise
def handle_unverified_request
sign_out_all_scopes(false)
request.env["devise.skip_storage"] = true
expire_devise_cached_variables!
expire_data_after_sign_out!
super # call the default behaviour which resets the session
end
@@ -275,10 +190,23 @@ module Devise
Devise.navigational_formats.include?(request_format)
end
# Check if flash messages should be emitted. Default is to do it on
# navigational formats
def is_flashing_format?
is_navigational_format?
end
private
def expire_devise_cached_variables!
def expire_session_data_after_sign_in!
ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
"in favor of expire_data_after_sign_in!"
expire_data_after_sign_in!
end
def expire_data_after_sign_out!
Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
super
end
end
end

View File

@@ -1,36 +1,27 @@
module Devise
module Controllers
# A module that may be optionally included in a controller in order
# to provide remember me behavior.
# to provide remember me behavior. Useful when signing in is done
# through a callback, like in Omniauth.
module Rememberable
# Return default cookie values retrieved from session options.
def self.cookie_values
Rails.configuration.session_options.slice(:path, :domain, :secure)
end
# A small warden proxy so we can remember and forget uses from hooks.
class Proxy #:nodoc:
include Devise::Controllers::Rememberable
delegate :cookies, :env, :to => :@warden
def initialize(warden)
@warden = warden
end
end
# Remembers the given resource by setting up a cookie
def remember_me(resource)
return if env["devise.skip_storage"]
scope = Devise::Mapping.find_scope!(resource)
resource.remember_me!(resource.extend_remember_period)
cookies.signed["remember_#{scope}_token"] = remember_cookie_values(resource)
cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)
end
# Forgets the given resource by deleting a cookie
def forget_me(resource)
scope = Devise::Mapping.find_scope!(resource)
resource.forget_me!
cookies.delete("remember_#{scope}_token", forget_cookie_values(resource))
cookies.delete(remember_key(resource, scope), forget_cookie_values(resource))
end
protected
@@ -47,6 +38,10 @@ module Devise
:expires => resource.remember_expires_at
)
end
def remember_key(resource, scope)
resource.rememberable_options.fetch(:key, "remember_#{scope}_token")
end
end
end
end
end

View File

@@ -0,0 +1,103 @@
module Devise
module Controllers
# Provide sign in and sign out functionality.
# Included by default in all controllers.
module SignInOut
# Return true if the given scope is signed in session. If no scope given, return
# true if any scope is signed in. Does not run authentication hooks.
def signed_in?(scope=nil)
[ scope || Devise.mappings.keys ].flatten.any? do |_scope|
warden.authenticate?(:scope => _scope)
end
end
# Sign in a user that already was authenticated. This helper is useful for logging
# users in after sign up.
#
# All options given to sign_in is passed forward to the set_user method in warden.
# The only exception is the :bypass option, which bypass warden callbacks and stores
# the user straight in session. This option is useful in cases the user is already
# signed in, but we want to refresh the credentials in session.
#
# Examples:
#
# sign_in :user, @user # sign_in(scope, resource)
# sign_in @user # sign_in(resource)
# sign_in @user, :event => :authentication # sign_in(resource, options)
# sign_in @user, :store => false # sign_in(resource, options)
# sign_in @user, :bypass => true # sign_in(resource, options)
#
def sign_in(resource_or_scope, *args)
options = args.extract_options!
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource = args.last || resource_or_scope
expire_data_after_sign_in!
if options[:bypass]
warden.session_serializer.store(resource, scope)
elsif warden.user(scope) == resource && !options.delete(:force)
# Do nothing. User already signed in and we are not forcing it.
true
else
warden.set_user(resource, options.merge!(:scope => scope))
end
end
# Sign out a given user or scope. This helper is useful for signing out a user
# after deleting accounts. Returns true if there was a logout and false if there
# is no user logged in on the referred scope
#
# Examples:
#
# sign_out :user # sign_out(scope)
# sign_out @user # sign_out(resource)
#
def sign_out(resource_or_scope=nil)
return sign_out_all_scopes unless resource_or_scope
scope = Devise::Mapping.find_scope!(resource_or_scope)
user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
warden.raw_session.inspect # Without this inspect here. The session does not clear.
warden.logout(scope)
warden.clear_strategies_cache!(:scope => scope)
instance_variable_set(:"@current_#{scope}", nil)
!!user
end
# Sign out all active users or scopes. This helper is useful for signing out all roles
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
# and false if there was no user logged in on all scopes.
def sign_out_all_scopes(lock=true)
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
warden.raw_session.inspect
warden.logout
expire_data_after_sign_out!
warden.clear_strategies_cache!
warden.lock! if lock
users.any?
end
private
def expire_data_after_sign_in!
# session.keys will return an empty array if the session is not yet loaded.
# This is a bug in both Rack and Rails.
# A call to #empty? forces the session to be loaded.
session.empty?
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
end
def expire_data_after_sign_out!
# session.keys will return an empty array if the session is not yet loaded.
# This is a bug in both Rack and Rails.
# A call to #empty? forces the session to be loaded.
session.empty?
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
end
end
end
end

View File

@@ -0,0 +1,50 @@
require "uri"
module Devise
module Controllers
# Provide the ability to store a location.
# Used to redirect back to a desired path after sign in.
# Included by default in all controllers.
module StoreLocation
# Returns and delete (if it's navigational format) the url stored in the session for
# the given scope. Useful for giving redirect backs after sign up:
#
# Example:
#
# redirect_to stored_location_for(:user) || root_path
#
def stored_location_for(resource_or_scope)
session_key = stored_location_key_for(resource_or_scope)
if is_navigational_format?
session.delete(session_key)
else
session[session_key]
end
end
# Stores the provided location to redirect the user after signing in.
# Useful in combination with the `stored_location_for` helper.
#
# Example:
#
# store_location_for(:user, dashboard_path)
# redirect_to user_omniauth_authorize_path(:facebook)
#
def store_location_for(resource_or_scope, location)
session_key = stored_location_key_for(resource_or_scope)
if location
uri = URI.parse(location)
session[session_key] = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
end
end
private
def stored_location_key_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
"#{scope}_return_to"
end
end
end
end

View File

@@ -13,6 +13,8 @@ module Devise
include Rails.application.routes.url_helpers
include Rails.application.routes.mounted_helpers
include Devise::Controllers::StoreLocation
delegate :flash, :to => :request
def self.call(env)
@@ -64,12 +66,21 @@ module Devise
protected
def i18n_options(options)
options
end
def i18n_message(default = nil)
message = warden_message || default || :unauthenticated
if message.is_a?(Symbol)
I18n.t(:"#{scope}.#{message}", :resource_name => scope,
:scope => "devise.failure", :default => [message])
options = {}
options[:resource_name] = scope
options[:scope] = "devise.failure"
options[:default] = [message]
options = i18n_options(options)
I18n.t(:"#{scope}.#{message}", options)
else
message.to_s
end
@@ -78,7 +89,14 @@ module Devise
def redirect_url
if warden_message == :timeout
flash[:timedout] = true
attempted_path || scope_path
path = if request.get?
attempted_path
else
request.referrer
end
path || scope_path
else
scope_path
end
@@ -173,7 +191,7 @@ module Devise
# yet, but we still need to store the uri based on scope, so different scopes
# would never use the same uri to redirect.
def store_location!
session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
store_location_for(scope, attempted_path) if request.get? && !http_auth?
end
def is_navigational_format?

View File

@@ -0,0 +1,5 @@
Warden::Manager.after_authentication do |record, warden, options|
if Devise.clean_up_csrf_token_on_authentication
warden.request.session.try(:delete, :_csrf_token)
end
end

View File

@@ -4,6 +4,6 @@
# This avoids forgetting deleted users.
Warden::Manager.before_logout do |record, warden, options|
if record.respond_to?(:forget_me!)
Devise::Controllers::Rememberable::Proxy.new(warden).forget_me(record)
Devise::Hooks::Proxy.new(warden).forget_me(record)
end
end

View File

@@ -2,6 +2,6 @@
# This is only triggered when the user is explicitly set (with set_user)
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
record.update_attribute(:failed_attempts, 0)
record.update_attribute(:failed_attempts, 0) unless record.failed_attempts.to_i.zero?
end
end

21
lib/devise/hooks/proxy.rb Normal file
View File

@@ -0,0 +1,21 @@
module Devise
module Hooks
# A small warden proxy so we can remember, forget and
# sign out users from hooks.
class Proxy #:nodoc:
include Devise::Controllers::Rememberable
include Devise::Controllers::SignInOut
attr_reader :warden
delegate :cookies, :env, :to => :warden
def initialize(warden)
@warden = warden
end
def session
warden.request.session
end
end
end
end

View File

@@ -1,6 +1,7 @@
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
scope = options[:scope]
if record.respond_to?(:remember_me) && record.remember_me && warden.authenticated?(scope)
Devise::Controllers::Rememberable::Proxy.new(warden).remember_me(record)
if record.respond_to?(:remember_me) && options[:store] != false &&
record.remember_me && warden.authenticated?(scope)
Devise::Hooks::Proxy.new(warden).remember_me(record)
end
end

View File

@@ -9,12 +9,15 @@ Warden::Manager.after_set_user do |record, warden, options|
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
last_request_at = warden.session(scope)['last_request_at']
proxy = Devise::Hooks::Proxy.new(warden)
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
warden.logout(scope)
Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
record.reset_authentication_token!
end
throw :warden, :scope => scope, :message => :timeout
end

View File

@@ -35,12 +35,6 @@ module Devise
:template_name => action
}.merge(opts)
if resource.respond_to?(:headers_for)
ActiveSupport::Deprecation.warn "Calling headers_for in the model is no longer supported. " <<
"Please customize your mailer instead."
headers.merge!(resource.headers_for(action))
end
@email = headers[:to]
headers
end
@@ -54,8 +48,9 @@ module Devise
end
def mailer_sender(mapping, sender = :from)
if default_params[sender].present?
default_params[sender]
default_sender = default_params[sender]
if default_sender.present?
default_sender.respond_to?(:to_proc) ? instance_eval(&default_sender) : default_sender
elsif Devise.mailer_sender.is_a?(Proc)
Devise.mailer_sender.call(mapping.name)
else
@@ -64,12 +59,12 @@ module Devise
end
def template_paths
template_path = [self.class.mailer_name]
template_path = _prefixes.dup
template_path.unshift "#{@devise_mapping.scoped_path}/mailer" if self.class.scoped_views?
template_path
end
# Setup a subject doing an I18n lookup. At first, it attemps to set a subject
# Setup a subject doing an I18n lookup. At first, it attempts to set a subject
# based on the current mapping:
#
# en:

View File

@@ -29,17 +29,17 @@ module Devise
# Receives an object and find a scope for it. If a scope cannot be found,
# raises an error. If a symbol is given, it's considered to be the scope.
def self.find_scope!(duck)
case duck
def self.find_scope!(obj)
case obj
when String, Symbol
return duck
return obj
when Class
Devise.mappings.each_value { |m| return m.name if duck <= m.to }
Devise.mappings.each_value { |m| return m.name if obj <= m.to }
else
Devise.mappings.each_value { |m| return m.name if duck.is_a?(m.to) }
Devise.mappings.each_value { |m| return m.name if obj.is_a?(m.to) }
end
raise "Could not find a valid mapping for #{duck.inspect}"
raise "Could not find a valid mapping for #{obj.inspect}"
end
def self.find_by_path!(path, path_type=:fullpath)

View File

@@ -56,14 +56,8 @@ module Devise
klass.devise_modules.each do |mod|
constant = const_get(mod.to_s.classify)
if constant.respond_to?(:required_fields)
constant.required_fields(klass).each do |field|
failed_attributes << field unless instance.respond_to?(field)
end
else
ActiveSupport::Deprecation.warn "The module #{mod} doesn't implement self.required_fields(klass). " \
"Devise uses required_fields to warn developers of any missing fields in their models. " \
"Please implement #{mod}.required_fields(klass) that returns an array of symbols with the required fields."
constant.required_fields(klass).each do |field|
failed_attributes << field unless instance.respond_to?(field)
end
end
@@ -89,11 +83,8 @@ module Devise
devise_modules_hook! do
include Devise::Models::Authenticatable
selected_modules.each do |m|
if m == :encryptable && !(defined?(Devise::Models::Encryptable))
warn "[DEVISE] You're trying to include :encryptable in your model but it is not bundled with the Devise gem anymore. Please add `devise-encryptable` to your Gemfile to proceed.\n"
end
selected_modules.each do |m|
mod = Devise::Models.const_get(m.to_s.classify)
if mod.const_defined?("ClassMethods")

View File

@@ -1,4 +1,5 @@
require 'devise/hooks/activatable'
require 'devise/hooks/csrf_cleaner'
module Devise
module Models
@@ -10,29 +11,30 @@ module Devise
#
# * +authentication_keys+: parameters used for authentication. By default [:email].
#
# * +http_authentication_key+: map the username passed via HTTP Auth to this parameter. Defaults to
# the first element in +authentication_keys+.
#
# * +request_keys+: parameters from the request object used for authentication.
# By specifying a symbol (which should be a request method), it will automatically be
# passed to find_for_authentication method and considered in your model lookup.
#
# For instance, if you set :request_keys to [:subdomain], :subdomain will be considered
# as key on authentication. This can also be a hash where the value is a boolean expliciting
# as key on authentication. This can also be a hash where the value is a boolean specifying
# if the value is required or not.
#
# * +http_authenticatable+: if this model allows http authentication. By default true.
# * +http_authenticatable+: if this model allows http authentication. By default false.
# It also accepts an array specifying the strategies that should allow http.
#
# * +params_authenticatable+: if this model allows authentication through request params. By default true.
# It also accepts an array specifying the strategies that should allow params authentication.
#
# * +skip_session_storage+: By default Devise will store the user in session.
# You can skip storage for http and token auth by appending values to array:
# :skip_session_storage => [:token_auth] or :skip_session_storage => [:http_auth, :token_auth],
# by default is set to :skip_session_storage => [:http_auth].
# By default is set to :skip_session_storage => [:http_auth].
#
# == active_for_authentication?
#
# After authenticating a user and in each request, Devise checks if your model is active by
# calling model.active_for_authentication?. This method is overwriten by other devise modules. For instance,
# calling model.active_for_authentication?. This method is overwritten by other devise modules. For instance,
# :confirmable overwrites .active_for_authentication? to only return true if your model was confirmed.
#
# You overwrite this method yourself, but if you do, don't forget to call super:
@@ -140,14 +142,26 @@ module Devise
#
# protected
#
# def send_devise_notification(notification)
# pending_notifications << notification
# def send_devise_notification(notification, *args)
# # If the record is new or changed then delay the
# # delivery until the after_commit callback otherwise
# # send now because after_commit will not be called.
# if new_record? || changed?
# pending_notifications << [notification, args]
# else
# devise_mailer.send(notification, self, *args).deliver
# end
# end
#
# def send_pending_notifications
# pending_notifications.each do |n|
# devise_mailer.send(n, self).deliver
# pending_notifications.each do |notification, args|
# devise_mailer.send(notification, self, *args).deliver
# end
#
# # Empty the pending notifications array because the
# # after_commit hook can be called multiple times which
# # could cause multiple emails to be sent.
# pending_notifications.clear
# end
#
# def pending_notifications
@@ -155,34 +169,36 @@ module Devise
# end
# end
#
def send_devise_notification(notification, opts={})
devise_mailer.send(notification, self, opts).deliver
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver
end
def downcase_keys
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase!) }
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
end
def strip_whitespace
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip!) }
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip) }
end
def apply_to_attribute_or_variable(attr, method)
if self[attr]
self[attr].try(method)
self[attr] = self[attr].try(method)
# Use respond_to? here to avoid a regression where globally
# configured strip_whitespace_keys or case_insensitive_keys were
# attempting to strip! or downcase! when a model didn't have the
# attempting to strip or downcase when a model didn't have the
# globally configured key.
elsif respond_to?(attr)
send(attr).try(method)
elsif respond_to?(attr) && respond_to?("#{attr}=")
new_value = send(attr).try(method)
send("#{attr}=", new_value)
end
end
module ClassMethods
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage)
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage,
:http_authentication_key)
def serialize_into_session(record)
[record.to_key, record.authenticatable_salt]
@@ -214,21 +230,20 @@ module Devise
# namedscope to filter records while authenticating.
# Example:
#
# def self.find_for_authentication(conditions={})
# conditions[:active] = true
# super
# def self.find_for_authentication(tainted_conditions)
# find_first_by_auth_conditions(tainted_conditions, :active => true)
# end
#
# Finally, notice that Devise also queries for users in other scenarios
# besides authentication, for example when retrieving an user to send
# an e-mail for password reset. In such cases, find_for_authentication
# is not called.
def find_for_authentication(conditions)
find_first_by_auth_conditions(conditions)
def find_for_authentication(tainted_conditions)
find_first_by_auth_conditions(tainted_conditions)
end
def find_first_by_auth_conditions(conditions)
to_adapter.find_first devise_param_filter.filter(conditions)
def find_first_by_auth_conditions(tainted_conditions, opts={})
to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
end
# Find an initialize a record setting an error if it can't be found.
@@ -260,16 +275,8 @@ module Devise
protected
def devise_param_filter
@devise_param_filter ||= Devise::ParamFilter.new(case_insensitive_keys, strip_whitespace_keys)
end
# Generate a token by looping and ensuring does not already exist.
def generate_token(column)
loop do
token = Devise.friendly_token
break token unless to_adapter.find_first({ column => token })
end
def devise_parameter_filter
@devise_parameter_filter ||= Devise::ParameterFilter.new(case_insensitive_keys, strip_whitespace_keys)
end
end
end

View File

@@ -7,7 +7,7 @@ module Devise
#
# == Options
#
# Confirmable adds the following options to devise_for:
# Confirmable adds the following options to +devise+:
#
# * +allow_unconfirmed_access_for+: the time you want to allow the user to access his account
# before confirming it. After this period, the user access is denied. You can
@@ -34,9 +34,17 @@ module Devise
included do
before_create :generate_confirmation_token, :if => :confirmation_required?
after_create :send_on_create_confirmation_instructions, :if => :confirmation_required?
before_update :postpone_email_change_until_confirmation, :if => :postpone_email_change?
after_update :send_confirmation_instructions, :if => :reconfirmation_required?
after_create :send_on_create_confirmation_instructions, :if => :send_confirmation_notification?
before_update :postpone_email_change_until_confirmation_and_regenerate_confirmation_token, :if => :postpone_email_change?
after_update :send_reconfirmation_instructions, :if => :reconfirmation_required?
end
def initialize(*args, &block)
@bypass_confirmation_postpone = false
@reconfirmation_required = false
@skip_confirmation_notification = false
@raw_confirmation_token = nil
super
end
def self.required_fields(klass)
@@ -59,7 +67,7 @@ module Devise
self.confirmation_token = nil
self.confirmed_at = Time.now.utc
if self.class.reconfirmable && unconfirmed_email.present?
saved = if self.class.reconfirmable && unconfirmed_email.present?
skip_reconfirmation!
self.email = unconfirmed_email
self.unconfirmed_email = nil
@@ -69,6 +77,9 @@ module Devise
else
save(:validate => false)
end
after_confirmation if saved
saved
end
end
@@ -83,19 +94,26 @@ module Devise
# Send confirmation instructions by email
def send_confirmation_instructions
self.confirmation_token = nil if reconfirmation_required?
@reconfirmation_required = false
generate_confirmation_token! if self.confirmation_token.blank?
unless @raw_confirmation_token
generate_confirmation_token!
end
opts = pending_reconfirmation? ? { :to => unconfirmed_email } : { }
send_devise_notification(:confirmation_instructions, opts)
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
end
# Resend confirmation token. This method does not need to generate a new token.
def resend_confirmation_token
def send_reconfirmation_instructions
@reconfirmation_required = false
unless @skip_confirmation_notification
send_confirmation_instructions
end
end
# Resend confirmation token.
# Regenerates the token if the period is expired.
def resend_confirmation_instructions
pending_any_confirmation do
self.confirmation_token = nil if confirmation_period_expired?
send_confirmation_instructions
end
end
@@ -119,10 +137,16 @@ module Devise
self.confirmed_at = Time.now.utc
end
# Skips sending the confirmation/reconfirmation notification email after_create/after_update. Unlike
# #skip_confirmation!, record still requires confirmation.
def skip_confirmation_notification!
@skip_confirmation_notification = true
end
# If you don't want reconfirmation to be sent, neither a code
# to be generated, call skip_reconfirmation!
def skip_reconfirmation!
@bypass_postpone = true
@bypass_confirmation_postpone = true
end
protected
@@ -131,7 +155,7 @@ module Devise
# instructions on creation. This can be overriden
# in models to map to a nice sign up e-mail.
def send_on_create_confirmation_instructions
send_devise_notification(:confirmation_instructions)
send_confirmation_instructions
end
# Callback to overwrite if confirmation is required or not.
@@ -158,8 +182,11 @@ module Devise
# # allow_unconfirmed_access_for = 0.days
# confirmation_period_valid? # will always return false
#
# # allow_unconfirmed_access_for = nil
# confirmation_period_valid? # will always return true
#
def confirmation_period_valid?
confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago
self.class.allow_unconfirmed_access_for.nil? || (confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago)
end
# Checks if the user confirmation happens before the token becomes invalid
@@ -188,10 +215,12 @@ module Devise
end
end
# Generates a new random token for confirmation, and stores the time
# this token is being generated
# Generates a new random token for confirmation, and stores
# the time this token is being generated
def generate_confirmation_token
self.confirmation_token = self.class.confirmation_token
raw, enc = Devise.token_generator.generate(self.class, :confirmation_token)
@raw_confirmation_token = raw
self.confirmation_token = enc
self.confirmation_sent_at = Time.now.utc
end
@@ -199,25 +228,28 @@ module Devise
generate_confirmation_token && save(:validate => false)
end
def after_password_reset
super
confirm! unless confirmed?
end
def postpone_email_change_until_confirmation
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.email_was
generate_confirmation_token
end
def postpone_email_change?
postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone
@bypass_postpone = nil
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && !self.email.blank?
@bypass_confirmation_postpone = false
postpone
end
def reconfirmation_required?
self.class.reconfirmable && @reconfirmation_required
self.class.reconfirmable && @reconfirmation_required && !self.email.blank?
end
def send_confirmation_notification?
confirmation_required? && !@skip_confirmation_notification && !self.email.blank?
end
def after_confirmation
end
module ClassMethods
@@ -230,7 +262,7 @@ module Devise
unless confirmable.try(:persisted?)
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
end
confirmable.resend_confirmation_token if confirmable.persisted?
confirmable.resend_confirmation_instructions if confirmable.persisted?
confirmable
end
@@ -239,16 +271,15 @@ module Devise
# If the user is already confirmed, create an error for the user
# Options must have the confirmation_token
def confirm_by_token(confirmation_token)
original_token = confirmation_token
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
confirmable.confirm! if confirmable.persisted?
confirmable.confirmation_token = original_token
confirmable
end
# Generate a token checking if one does not already exist in the database.
def confirmation_token
generate_token(:confirmation_token)
end
# Find a record for confirmation by unconfirmed email field
def find_by_unconfirmed_email_with_errors(attributes = {})
unconfirmed_required_attributes = confirmation_keys.map { |k| k == :email ? :unconfirmed_email : k }

View File

@@ -2,6 +2,11 @@ require 'devise/strategies/database_authenticatable'
require 'bcrypt'
module Devise
# Digests the password using bcrypt.
def self.bcrypt(klass, password)
::BCrypt::Password.create("#{password}#{klass.pepper}", :cost => klass.stretches).to_s
end
module Models
# Authenticatable Module, responsible for encrypting password and validating
# authenticity of a user while signing in.
@@ -81,7 +86,7 @@ module Devise
#
# Example:
#
# def update_without_password(params={})
# def update_without_password(params, *options)
# params.delete(:email)
# super(params)
# end
@@ -95,6 +100,31 @@ module Devise
result
end
# Destroy record when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects
# :current_password if it is blank.
def destroy_with_password(current_password)
result = if valid_password?(current_password)
destroy
else
self.valid?
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
false
end
result
end
# A callback initiated after successfully authenticating. This can be
# used to insert your own logic that is only run after the user successfully
# authenticates.
#
# Example:
#
# def after_database_authentication
# self.update_attribute(:invite_code, nil)
# end
#
def after_database_authentication
end
@@ -105,9 +135,13 @@ module Devise
protected
# Digests the password using bcrypt.
# Digests the password using bcrypt. Custom encryption should override
# this method to apply their own algorithm.
#
# See https://github.com/plataformatec/devise-encryptable for examples
# of other encryption engines.
def password_digest(password)
::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
Devise.bcrypt(self.class, password)
end
module ClassMethods

View File

@@ -38,7 +38,6 @@ module Devise
self.locked_at = Time.now.utc
if unlock_strategy_enabled?(:email)
generate_unlock_token!
send_unlock_instructions
else
save(:validate => false)
@@ -55,16 +54,20 @@ module Devise
# Verifies whether a user is locked or not.
def access_locked?
locked_at && !lock_expired?
!!locked_at && !lock_expired?
end
# Send unlock instructions by email
def send_unlock_instructions
send_devise_notification(:unlock_instructions)
raw, enc = Devise.token_generator.generate(self.class, :unlock_token)
self.unlock_token = enc
self.save(:validate => false)
send_devise_notification(:unlock_instructions, raw, {})
raw
end
# Resend the unlock instructions if the user is locked.
def resend_unlock_token
def resend_unlock_instructions
if_access_locked { send_unlock_instructions }
end
@@ -109,6 +112,8 @@ module Devise
# leaks the existence of an account.
if Devise.paranoid
super
elsif lock_strategy_enabled?(:failed_attempts) && last_attempt?
:last_attempt
elsif lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?
:locked
else
@@ -122,13 +127,8 @@ module Devise
self.failed_attempts > self.class.maximum_attempts
end
# Generates unlock token
def generate_unlock_token
self.unlock_token = self.class.unlock_token
end
def generate_unlock_token!
generate_unlock_token && save(:validate => false)
def last_attempt?
self.failed_attempts == self.class.maximum_attempts
end
# Tells if the lock is expired if :time unlock strategy is active
@@ -146,19 +146,19 @@ module Devise
if access_locked?
yield
else
self.errors.add(:email, :not_locked)
self.errors.add(Devise.unlock_keys.first, :not_locked)
false
end
end
module ClassMethods
# Attempt to find a user by its email. If a record is found, send new
# Attempt to find a user by its unlock keys. If a record is found, send new
# unlock instructions to it. If not user is found, returns a new user
# with an email not found error.
# Options must contain the user email
# Options must contain the user's unlock keys
def send_unlock_instructions(attributes={})
lockable = find_or_initialize_with_errors(unlock_keys, attributes, :not_found)
lockable.resend_unlock_token if lockable.persisted?
lockable.resend_unlock_instructions if lockable.persisted?
lockable
end
@@ -167,8 +167,12 @@ module Devise
# If the user is not locked, creates an error for the user
# Options must have the unlock_token
def unlock_access_by_token(unlock_token)
original_token = unlock_token
unlock_token = Devise.token_generator.digest(self, :unlock_token, unlock_token)
lockable = find_or_initialize_with_error_by(:unlock_token, unlock_token)
lockable.unlock_access! if lockable.persisted?
lockable.unlock_token = original_token
lockable
end
@@ -182,10 +186,6 @@ module Devise
self.lock_strategy == strategy
end
def unlock_token
Devise.friendly_token
end
Devise::Models.config(self, :maximum_attempts, :lock_strategy, :unlock_strategy, :unlock_in, :unlock_keys)
end
end

View File

@@ -8,7 +8,7 @@ module Devise
#
# Oauthable adds the following options to devise_for:
#
# * +omniauth_providers+: Which providers are avaialble to this model. It expects an array:
# * +omniauth_providers+: Which providers are available to this model. It expects an array:
#
# devise_for :database_authenticatable, :omniauthable, :omniauth_providers => [:twitter]
#
@@ -24,4 +24,4 @@ module Devise
end
end
end
end
end

View File

@@ -1,7 +1,7 @@
module Devise
module Models
# Recoverable takes care of reseting the user password and send reset instructions.
# Recoverable takes care of resetting the user password and send reset instructions.
#
# ==Options
#
@@ -42,10 +42,17 @@ module Devise
save
end
# Resets reset password token and send reset password instructions by email
# Resets reset password token and send reset password instructions by email.
# Returns the token sent in the e-mail.
def send_reset_password_instructions
generate_reset_password_token! if should_generate_reset_token?
send_devise_notification(:reset_password_instructions)
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
self.reset_password_token = enc
self.reset_password_sent_at = Time.now.utc
self.save(:validate => false)
send_devise_notification(:reset_password_instructions, raw, {})
raw
end
# Checks if the reset password token sent is within the limit time.
@@ -74,23 +81,6 @@ module Devise
protected
def should_generate_reset_token?
reset_password_token.nil? || !reset_password_period_valid?
end
# Generates a new random token for reset password
def generate_reset_password_token
self.reset_password_token = self.class.reset_password_token
self.reset_password_sent_at = Time.now.utc
self.reset_password_token
end
# Resets the reset password token with and save the record without
# validating
def generate_reset_password_token!
generate_reset_password_token && save(:validate => false)
end
# Removes reset_password token
def clear_reset_password_token
self.reset_password_token = nil
@@ -111,18 +101,17 @@ module Devise
recoverable
end
# Generate a token checking if one does not already exist in the database.
def reset_password_token
generate_token(:reset_password_token)
end
# Attempt to find a user by its reset_password_token to reset its
# password. If a user is found and token is still valid, reset its password and automatically
# try saving the record. If not user is found, returns a new user
# containing an error in reset_password_token attribute.
# Attributes must contain reset_password_token, password and confirmation
def reset_password_by_token(attributes={})
recoverable = find_or_initialize_with_error_by(:reset_password_token, attributes[:reset_password_token])
original_token = attributes[:reset_password_token]
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
recoverable = find_or_initialize_with_error_by(:reset_password_token, reset_password_token)
if recoverable.persisted?
if recoverable.reset_password_period_valid?
recoverable.reset_password!(attributes[:password], attributes[:password_confirmation])
@@ -130,6 +119,8 @@ module Devise
recoverable.errors.add(:reset_password_token, :expired)
end
end
recoverable.reset_password_token = original_token
recoverable
end

View File

@@ -50,7 +50,7 @@ module Devise
def remember_me!(extend_period=false)
self.remember_token = self.class.remember_token if generate_remember_token?
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
save(:validate => false)
save(:validate => false) if self.changed?
end
# If the record is persisted, remove the remember token (but only if
@@ -110,12 +110,16 @@ module Devise
# Recreate the user based on the stored cookie
def serialize_from_cookie(id, remember_token)
record = to_adapter.get(id)
record if record && record.rememberable_value == remember_token && !record.remember_expired?
record if record && !record.remember_expired? &&
Devise.secure_compare(record.rememberable_value, remember_token)
end
# Generate a token checking if one does not already exist in the database.
def remember_token #:nodoc:
generate_token(:remember_token)
loop do
token = Devise.friendly_token
break token unless to_adapter.find_first({ :remember_token => token })
end
end
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options)

View File

@@ -2,7 +2,7 @@ require 'devise/hooks/timeoutable'
module Devise
module Models
# Timeoutable takes care of veryfing whether a user session has already
# Timeoutable takes care of verifyng whether a user session has already
# expired or not. When a session expires after the configured time, the user
# will be asked for credentials again, it means, he/she will be redirected
# to the sign in page.
@@ -37,7 +37,7 @@ module Devise
private
def remember_exists_and_not_expired?
return false unless respond_to?(:remember_created_at)
return false unless respond_to?(:remember_created_at) && respond_to?(:remember_expired?)
remember_created_at && !remember_expired?
end

View File

@@ -1,89 +0,0 @@
require 'devise/strategies/token_authenticatable'
module Devise
module Models
# The TokenAuthenticatable module is responsible for generating an authentication token and
# validating the authenticity of the same while signing in.
#
# This module only provides a few helpers to help you manage the token, but it is up to you
# to choose how to use it. For example, if you want to have a new token every time the user
# saves his account, you can do the following:
#
# before_save :reset_authentication_token
#
# On the other hand, if you want to generate token unless one exists, you should use instead:
#
# before_save :ensure_authentication_token
#
# If you want to delete the token after it is used, you can do so in the
# after_token_authentication callback.
#
# == APIs
#
# If you are using token authentication with APIs and using trackable. Every
# request will be considered as a new sign in (since there is no session in
# APIs). You can disable this by creating a before filter as follow:
#
# before_filter :skip_trackable
#
# def skip_trackable
# request.env['devise.skip_trackable'] = true
# end
#
# == Options
#
# TokenAuthenticatable adds the following options to devise_for:
#
# * +token_authentication_key+: Defines name of the authentication token params key. E.g. /users/sign_in?some_key=...
#
module TokenAuthenticatable
extend ActiveSupport::Concern
def self.required_fields(klass)
[:authentication_token]
end
# Generate new authentication token (a.k.a. "single access token").
def reset_authentication_token
self.authentication_token = self.class.authentication_token
end
# Generate new authentication token and save the record.
def reset_authentication_token!
reset_authentication_token
save(:validate => false)
end
# Generate authentication token unless already exists.
def ensure_authentication_token
reset_authentication_token if authentication_token.blank?
end
# Generate authentication token unless already exists and save the record.
def ensure_authentication_token!
reset_authentication_token! if authentication_token.blank?
end
# Hook called after token authentication.
def after_token_authentication
end
def expire_auth_token_on_timeout
self.class.expire_auth_token_on_timeout
end
module ClassMethods
def find_for_token_authentication(conditions)
find_for_authentication(:authentication_token => conditions[token_authentication_key])
end
# Generate a token checking if one does not already exist in the database.
def authentication_token
generate_token(:authentication_token)
end
Devise::Models.config(self, :token_authentication_key, :expire_auth_token_on_timeout)
end
end
end
end

View File

@@ -5,7 +5,6 @@ Devise.with_options :model => true do |d|
d.with_options :strategy => true do |s|
routes = [nil, :new, :destroy]
s.add_module :database_authenticatable, :controller => :sessions, :route => { :session => routes }
s.add_module :token_authenticatable, :controller => :sessions, :route => { :session => routes }, :no_input => true
s.add_module :rememberable, :no_input => true
end

View File

@@ -1,5 +1,5 @@
module Devise
class ParamFilter
class ParameterFilter
def initialize(case_insensitive_keys, strip_whitespace_keys)
@case_insensitive_keys = case_insensitive_keys || []
@strip_whitespace_keys = strip_whitespace_keys || []
@@ -8,16 +8,16 @@ module Devise
def filter(conditions)
conditions = stringify_params(conditions.dup)
@case_insensitive_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:downcase)
conditions[k] = value.downcase
end
conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :downcase, @case_insensitive_keys))
conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :strip, @strip_whitespace_keys))
@strip_whitespace_keys.each do |k|
conditions
end
def filtered_hash_by_method_for_given_keys(conditions, method, condition_keys)
condition_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:strip)
conditions[k] = value.strip
conditions[k] = value.send(method) if value.respond_to?(method)
end
conditions
@@ -33,9 +33,8 @@ module Devise
private
# Determine which values should be transformed to string or passed as-is to the query builder underneath
def param_requires_string_conversion?(value)
[Fixnum, TrueClass, FalseClass, Regexp].none? {|clz| value.is_a? clz }
true
end
end
end

View File

@@ -0,0 +1,99 @@
module Devise
class BaseSanitizer
attr_reader :params, :resource_name, :resource_class
def initialize(resource_class, resource_name, params)
@resource_class = resource_class
@resource_name = resource_name
@params = params
@blocks = Hash.new
end
def for(kind, &block)
if block_given?
@blocks[kind] = block
else
default_for(kind)
end
end
def sanitize(kind)
if block = @blocks[kind]
block.call(default_params)
else
default_sanitize(kind)
end
end
private
def default_for(kind)
raise ArgumentError, "a block is expected in Devise base sanitizer"
end
def default_sanitize(kind)
default_params
end
def default_params
params.fetch(resource_name, {})
end
end
class ParameterSanitizer < BaseSanitizer
def initialize(*)
super
@permitted = Hash.new { |h,k| h[k] = attributes_for(k) }
end
def sign_in
permit self.for(:sign_in)
end
def sign_up
permit self.for(:sign_up)
end
def account_update
permit self.for(:account_update)
end
private
# TODO: We do need to flatten so it works with strong_parameters
# gem. We should drop it once we move to Rails 4 only support.
def permit(keys)
default_params.permit(*Array(keys))
end
# Change for(kind) to return the values in the @permitted
# hash, allowing the developer to customize at runtime.
def default_for(kind)
@permitted[kind] || raise("No sanitizer provided for #{kind}")
end
def default_sanitize(kind)
if respond_to?(kind, true)
send(kind)
else
raise NotImplementedError, "Devise doesn't know how to sanitize parameters for #{kind}"
end
end
def attributes_for(kind)
case kind
when :sign_in
auth_keys + [:password, :remember_me]
when :sign_up
auth_keys + [:password, :password_confirmation]
when :account_update
auth_keys + [:password, :password_confirmation, :current_password]
end
end
def auth_keys
@auth_keys ||= @resource_class.authentication_keys.respond_to?(:keys) ?
@resource_class.authentication_keys.keys : @resource_class.authentication_keys
end
end
end

View File

@@ -29,21 +29,17 @@ module Devise
end
end
initializer "devise.mongoid_version_warning" do
if defined?(Mongoid)
require 'mongoid/version'
if Mongoid::VERSION.to_f < 2.1
puts "\n[DEVISE] Please note that Mongoid versions prior to 2.1 handle dirty model " \
"object attributes in such a way that the Devise `validatable` module will not apply " \
"its usual uniqueness and format validations for the email field. It is recommended " \
"that you upgrade to Mongoid 2.1+ for this and other fixes, but if for some reason you " \
"are unable to do so, you should add these validations manually.\n"
initializer "devise.secret_key" do
Devise.token_generator ||=
if secret_key = Devise.secret_key
Devise::TokenGenerator.new(
Devise::CachingKeyGenerator.new(Devise::KeyGenerator.new(secret_key))
)
end
end
end
initializer "devise.fix_routes_proxy_missing_respond_to_bug" do
# We can get rid of this once we support only Rails > 3.2
# Deprecate: Remove once we move to Rails 4 only.
ActionDispatch::Routing::RoutesProxy.class_eval do
def respond_to?(method, include_private = false)
super || routes.url_helpers.respond_to?(method)

View File

@@ -58,6 +58,28 @@ module ActionDispatch::Routing
# user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
# POST /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
#
# ==== Routes integration
#
# +devise_for+ is meant to play nicely with other routes methods. For example,
# by calling +devise_for+ inside a namespace, it automatically nests your devise
# controllers:
#
# namespace :publisher do
# devise_for :account
# end
#
# The snippet above will use publisher/sessions controller instead of devise/sessions
# controller. You can revert this change or configure it directly by passing the :module
# option described below to +devise_for+.
#
# Also note that when you use a namespace it will affect all the helpers and methods
# for controllers and views. For example, using the above setup you'll end with
# following methods: current_publisher_account, authenticate_publisher_account!,
# publisher_account_signed_in, etc.
#
# The only aspect not affect by the router configuration is the model name. The
# model name can be explicitly set via the :class_name option.
#
# ==== Options
#
# You can configure your routes with some options:
@@ -80,7 +102,8 @@ module ActionDispatch::Routing
# * :path_names => configure different path names to overwrite defaults :sign_in, :sign_out, :sign_up,
# :password, :confirmation, :unlock.
#
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout',
# :password => 'secret', :confirmation => 'verification', registration: 'register }
#
# * :controllers => the controller which should be used. All routes by default points to Devise controllers.
# However, if you want them to point to custom controller, you should do:
@@ -103,20 +126,6 @@ module ActionDispatch::Routing
#
# devise_for :users, :module => "users"
#
# Notice that whenever you use namespace in the router DSL, it automatically sets the module.
# So the following setup:
#
# namespace :publisher do
# devise_for :account
# end
#
# Will use publisher/sessions controller instead of devise/sessions controller. You can revert
# this by providing the :module option to devise_for.
#
# Also pay attention that when you use a namespace it will affect all the helpers and methods for controllers
# and views. For example, using the above setup you'll end with following methods:
# current_publisher_account, authenticate_publisher_account!, publisher_account_signed_in, etc.
#
# * :skip => tell which controller you want to skip routes from being created:
#
# devise_for :users, :skip => :sessions
@@ -191,6 +200,7 @@ module ActionDispatch::Routing
#
def devise_for(*resources)
@devise_finalized = false
raise_no_secret_key unless Devise.secret_key
options = resources.extract_options!
options[:as] ||= @scope[:as] if @scope[:as].present?
@@ -222,14 +232,6 @@ module ActionDispatch::Routing
routes = mapping.used_routes
devise_scope mapping.name do
if block_given?
ActiveSupport::Deprecation.warn "Passing a block to devise_for is deprecated. " \
"Please remove the block from devise_for (only the block, the call to " \
"devise_for must still exist) and call devise_scope :#{mapping.name} do ... end " \
"with the block instead", caller
yield
end
with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
end
@@ -250,15 +252,11 @@ module ActionDispatch::Routing
# end
#
# authenticate :user, lambda {|u| u.role == "admin"} do
# root :to => "admin/dashboard#show"
# root :to => "admin/dashboard#show", :as => :user_root
# end
#
def authenticate(scope=nil, block=nil)
constraint = lambda do |request|
request.env["warden"].authenticate!(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
constraints_for(:authenticate!, scope, block) do
yield
end
end
@@ -268,25 +266,21 @@ module ActionDispatch::Routing
# a model and allows extra constraints to be done on the instance.
#
# authenticated :admin do
# root :to => 'admin/dashboard#show'
# root :to => 'admin/dashboard#show', :as => :admin_root
# end
#
# authenticated do
# root :to => 'dashboard#show'
# root :to => 'dashboard#show', :as => :authenticated_root
# end
#
# authenticated :user, lambda {|u| u.role == "admin"} do
# root :to => "admin/dashboard#show"
# root :to => "admin/dashboard#show", :as => :user_root
# end
#
# root :to => 'landing#show'
#
def authenticated(scope=nil, block=nil)
constraint = lambda do |request|
request.env["warden"].authenticate?(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
constraints_for(:authenticate?, scope, block) do
yield
end
end
@@ -329,7 +323,7 @@ module ActionDispatch::Routing
# good and working example.
#
# devise_scope :user do
# match "/some/route" => "some_devise_controller"
# get "/some/route" => "some_devise_controller"
# end
# devise_for :users
#
@@ -392,8 +386,29 @@ module ActionDispatch::Routing
end
def devise_omniauth_callback(mapping, controllers) #:nodoc:
if mapping.fullpath =~ /:[a-zA-Z_]/
raise <<-ERROR
Devise does not support scoping omniauth callbacks under a dynamic segment
and you have set #{mapping.fullpath.inspect}. You can work around by passing
`skip: :omniauth_callbacks` and manually defining the routes. Here is an example:
match "/users/auth/:provider",
:constraints => { :provider => /\A(google|facebook)\z/ },
:to => "devise/omniauth_callbacks#passthru",
:as => :omniauth_authorize,
:via => [:get, :post]
match "/users/auth/:action/callback",
:constraints => { :action => /\A(google|facebook)\z/ },
:to => "devise/omniauth_callbacks",
:as => :omniauth_callback,
:via => [:get, :post]
ERROR
end
path, @scope[:path] = @scope[:path], nil
path_prefix = Devise.omniauth_path_prefix || "/#{mapping.path}/auth".squeeze("/")
path_prefix = Devise.omniauth_path_prefix || "/#{mapping.fullpath}/auth".squeeze("/")
set_omniauth_path_prefix!(path_prefix)
providers = Regexp.union(mapping.to.omniauth_providers.map(&:to_s))
@@ -401,12 +416,14 @@ module ActionDispatch::Routing
match "#{path_prefix}/:provider",
:constraints => { :provider => providers },
:to => "#{controllers[:omniauth_callbacks]}#passthru",
:as => :omniauth_authorize
:as => :omniauth_authorize,
:via => [:get, :post]
match "#{path_prefix}/:action/callback",
:constraints => { :action => providers },
:to => controllers[:omniauth_callbacks],
:as => :omniauth_callback
:as => :omniauth_callback,
:via => [:get, :post]
ensure
@scope[:path] = path
end
@@ -426,6 +443,17 @@ module ActionDispatch::Routing
@scope.merge!(old)
end
def constraints_for(method_to_apply, scope=nil, block=nil)
constraint = lambda do |request|
request.env['warden'].send(method_to_apply, :scope => scope) &&
(block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
yield
end
end
def set_omniauth_path_prefix!(path_prefix) #:nodoc:
if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \
@@ -437,6 +465,16 @@ module ActionDispatch::Routing
end
end
def raise_no_secret_key #:nodoc:
raise <<-ERROR
Devise.secret_key was not set. Please add the following to your Devise initializer:
config.secret_key = '#{SecureRandom.hex(64)}'
Please ensure you restarted your application after installing Devise or setting the key.
ERROR
end
def raise_no_devise_method_error!(klass) #:nodoc:
raise "#{klass} does not respond to 'devise' method. This usually means you haven't " \
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " \

View File

@@ -3,41 +3,20 @@ module Warden::Mixins::Common
@request ||= ActionDispatch::Request.new(env)
end
# This is called internally by Warden on logout
# Deprecate: Remove this check once we move to Rails 4 only.
NULL_STORE =
defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
def reset_session!
request.reset_session
# Calling reset_session on NULL_STORE causes it fail.
# This is a bug that needs to be fixed in Rails.
unless NULL_STORE && request.session.is_a?(NULL_STORE)
request.reset_session
end
end
def cookies
request.cookie_jar
end
end
class Warden::SessionSerializer
def serialize(record)
klass = record.class
array = klass.serialize_into_session(record)
array.unshift(klass.name)
end
def deserialize(keys)
klass_name, *args = keys
begin
klass = ActiveSupport::Inflector.constantize(klass_name)
if klass.respond_to? :serialize_from_session
klass.serialize_from_session(*args)
else
Rails.logger.warn "[Devise] Stored serialized class #{klass_name} seems not to be Devise enabled anymore. Did you do that on purpose?"
nil
end
rescue NameError => e
if e.message =~ /uninitialized constant/
Rails.logger.debug "[Devise] Trying to deserialize invalid class #{klass_name}"
nil
else
raise
end
end
end
end

View File

@@ -26,20 +26,8 @@ module Devise
# In case the resource can't be validated, it will fail with the given
# unauthenticated_message.
def validate(resource, &block)
unless resource
ActiveSupport::Deprecation.warn "an empty resource was given to #{self.class.name}#validate. " \
"Please ensure the resource is not nil", caller
end
result = resource && resource.valid_for_authentication?(&block)
case result
when Symbol, String
ActiveSupport::Deprecation.warn "valid_for_authentication? should return a boolean value"
fail!(result)
return false
end
if result
decorate(resource)
true
@@ -100,7 +88,7 @@ module Devise
# Extract a hash with attributes:values from the http params.
def http_auth_hash
keys = [authentication_keys.first, :password]
keys = [http_authentication_key, :password]
Hash[*keys.zip(decode_credentials).flatten]
end
@@ -134,24 +122,27 @@ module Devise
parse_authentication_key_values(request_values, request_keys)
end
# Holds the authentication keys.
def authentication_keys
@authentication_keys ||= mapping.to.authentication_keys
end
# Holds request keys.
def http_authentication_key
@http_authentication_key ||= mapping.to.http_authentication_key || case authentication_keys
when Array then authentication_keys.first
when Hash then authentication_keys.keys.first
end
end
def request_keys
@request_keys ||= mapping.to.request_keys
end
# Returns values from the request object.
def request_values
keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
values = keys.map { |k| self.request.send(k) }
Hash[keys.zip(values)]
end
# Parse authentication keys considering if they should be enforced or not.
def parse_authentication_key_values(hash, keys)
keys.each do |key, enforce|
value = hash[key].presence

View File

@@ -5,13 +5,16 @@ module Devise
# Default strategy for signing in a user, based on his email and password in the database.
class DatabaseAuthenticatable < Authenticatable
def authenticate!
resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
return fail(:not_found_in_database) unless resource
resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
encrypted = false
if validate(resource){ resource.valid_password?(password) }
if validate(resource){ encrypted = true; resource.valid_password?(password) }
resource.after_database_authentication
success!(resource)
end
mapping.to.new.password = password if !encrypted && Devise.paranoid
fail(:not_found_in_database) unless resource
end
end
end

View File

@@ -41,7 +41,7 @@ module Devise
end
def remember_key
"remember_#{scope}_token"
mapping.to.rememberable_options.fetch(:key, "remember_#{scope}_token")
end
def remember_cookie
@@ -52,4 +52,4 @@ module Devise
end
end
Warden::Strategies.add(:rememberable, Devise::Strategies::Rememberable)
Warden::Strategies.add(:rememberable, Devise::Strategies::Rememberable)

View File

@@ -1,56 +0,0 @@
require 'devise/strategies/base'
module Devise
module Strategies
# Strategy for signing in a user, based on a authenticatable token. This works for both params
# and http. For the former, all you need to do is to pass the params in the URL:
#
# http://myapp.example.com/?user_token=SECRET
#
# For HTTP, you can pass the token as username and blank password. Since some clients may require
# a password, you can pass "X" as password and it will simply be ignored.
class TokenAuthenticatable < Authenticatable
def store?
super && !mapping.to.skip_session_storage.include?(:token_auth)
end
def authenticate!
resource = mapping.to.find_for_token_authentication(authentication_hash)
return fail(:invalid_token) unless resource
if validate(resource)
resource.after_token_authentication
success!(resource)
end
end
private
# Token Authenticatable can be authenticated with params in any controller and any verb.
def valid_params_request?
true
end
# Do not use remember_me behavior with token.
def remember_me?
false
end
# Try both scoped and non scoped keys.
def params_auth_hash
if params[scope].kind_of?(Hash) && params[scope].has_key?(authentication_keys.first)
params[scope]
else
params
end
end
# Overwrite authentication keys to use token_authentication_key.
def authentication_keys
@authentication_keys ||= [mapping.to.token_authentication_key]
end
end
end
end
Warden::Strategies.add(:token_authenticatable, Devise::Strategies::TokenAuthenticatable)

View File

@@ -108,6 +108,7 @@ module Devise
Warden::Manager._run_callbacks(:before_failure, env, options)
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
@controller.response.headers.merge!(headers)
@controller.send :render, :status => status, :text => response.body,
:content_type => headers["Content-Type"], :location => headers["Location"]
nil # causes process return @response

View File

@@ -0,0 +1,70 @@
# Deprecate: Copied verbatim from Rails source, remove once we move to Rails 4 only.
require 'thread_safe'
require 'openssl'
require 'securerandom'
module Devise
class TokenGenerator
def initialize(key_generator, digest="SHA256")
@key_generator = key_generator
@digest = digest
end
def digest(klass, column, value)
value.present? && OpenSSL::HMAC.hexdigest(@digest, key_for(column), value.to_s)
end
def generate(klass, column)
key = key_for(column)
loop do
raw = Devise.friendly_token
enc = OpenSSL::HMAC.hexdigest(@digest, key, raw)
break [raw, enc] unless klass.to_adapter.find_first({ column => enc })
end
end
private
def key_for(column)
@key_generator.generate_key("Devise #{column}")
end
end
# KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
# It can be used to derive a number of keys for various purposes from a given secret.
# This lets Rails applications have a single secure secret, but avoid reusing that
# key in multiple incompatible contexts.
class KeyGenerator
def initialize(secret, options = {})
@secret = secret
# The default iterations are higher than required for our key derivation uses
# on the off chance someone uses this for password storage
@iterations = options[:iterations] || 2**16
end
# Returns a derived key suitable for use. The default key_size is chosen
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
# i.e. OpenSSL::Digest::SHA1#block_length
def generate_key(salt, key_size=64)
OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
end
end
# CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
# re-executing the key generation process when it's called using the same salt and
# key_size
class CachingKeyGenerator
def initialize(key_generator)
@key_generator = key_generator
@cache_keys = ThreadSafe::Cache.new
end
# Returns a derived key suitable for use. The default key_size is chosen
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
# i.e. OpenSSL::Digest::SHA1#block_length
def generate_key(salt, key_size=64)
@cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
end
end
end

View File

@@ -1,3 +1,3 @@
module Devise
VERSION = "2.2.2".freeze
VERSION = "3.2.2".freeze
end

View File

@@ -22,10 +22,7 @@ module ActiveRecord
end
def inject_devise_content
content = model_contents + <<CONTENT
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
CONTENT
content = model_contents
class_path = if namespaced?
class_name.to_s.split("::")
@@ -53,7 +50,7 @@ CONTENT
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.integer :sign_in_count, :default => 0, :null => false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
@@ -66,12 +63,9 @@ CONTENT
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
RUBY
end
end

View File

@@ -14,6 +14,5 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
add_index :<%= table_name %>, :reset_password_token, :unique => true
# add_index :<%= table_name %>, :confirmation_token, :unique => true
# add_index :<%= table_name %>, :unlock_token, :unique => true
# add_index :<%= table_name %>, :authentication_token, :unique => true
end
end

View File

@@ -15,7 +15,6 @@ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
add_index :<%= table_name %>, :reset_password_token, :unique => true
# add_index :<%= table_name %>, :confirmation_token, :unique => true
# add_index :<%= table_name %>, :unlock_token, :unique => true
# add_index :<%= table_name %>, :authentication_token, :unique => true
end
def self.down

View File

@@ -1,3 +1,5 @@
require 'rails/generators/named_base'
module Devise
module Generators
class DeviseGenerator < Rails::Generators::NamedBase

View File

@@ -1,3 +1,4 @@
require 'rails/generators/base'
require 'securerandom'
module Devise

View File

@@ -2,24 +2,43 @@ module Devise
module Generators
module OrmHelpers
def model_contents
<<-CONTENT
buffer = <<-CONTENT
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
CONTENT
buffer += <<-CONTENT if needs_attr_accessible?
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
CONTENT
buffer
end
def needs_attr_accessible?
rails_3? && !strong_parameters_enabled?
end
def rails_3?
Rails::VERSION::MAJOR == 3
end
def strong_parameters_enabled?
defined?(ActionController::StrongParameters)
end
private
def model_exists?
File.exists?(File.join(destination_root, model_path))
end
def migration_exists?(table_name)
Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_devise_to_#{table_name}.rb$/).first
end
def migration_path
@migration_path ||= File.join("db", "migrate")
end
@@ -29,4 +48,4 @@ CONTENT
end
end
end
end
end

View File

@@ -1,3 +1,5 @@
require 'rails/generators/base'
module Devise
module Generators
# Include this module in your generator to generate Devise views.
@@ -18,7 +20,7 @@ module Devise
public_task :copy_views
end
# TODO: Add this to Rails itslef
# TODO: Add this to Rails itself
module ClassMethods
def hide!
Rails::Generators.hide_namespace self.namespace
@@ -36,7 +38,13 @@ module Devise
protected
def view_directory(name, _target_path = nil)
directory name.to_s, _target_path || "#{target_path}/#{name}"
directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
if scope
content.gsub "devise/shared/links", "#{scope}/shared/links"
else
content
end
end
end
def target_path

View File

@@ -1,3 +1,4 @@
require 'rails/generators/named_base'
require 'generators/devise/orm_helpers'
module Mongoid
@@ -22,7 +23,7 @@ module Mongoid
## Database authenticatable
field :email, :type => String, :default => ""
field :encrypted_password, :type => String, :default => ""
## Recoverable
field :reset_password_token, :type => String
field :reset_password_sent_at, :type => Time
@@ -47,11 +48,8 @@ module Mongoid
# field :failed_attempts, :type => Integer, :default => 0 # Only if lock strategy is :failed_attempts
# field :unlock_token, :type => String # Only if unlock strategy is :email or :both
# field :locked_at, :type => Time
## Token authenticatable
# field :authentication_token, :type => String
RUBY
end
end
end
end
end

View File

@@ -21,7 +21,7 @@ Some setup you must do manually if you haven't yet:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. If you are deploying Rails 3.1+ on Heroku, you may want to set:
4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:
config.assets.initialize_on_precompile = false

View File

@@ -1,13 +1,19 @@
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
# The secret key used by Devise. Devise uses this key to generate
# random tokens. Changing this key will render invalid all existing
# confirmation, reset password and unlock tokens in the database.
config.secret_key = '<%= SecureRandom.hex(64) %>'
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
# Configure the class responsible to send e-mails.
# config.mailer = "Devise::Mailer"
# config.mailer = 'Devise::Mailer'
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default) and
@@ -48,17 +54,18 @@ Devise.setup do |config|
# enable it only for database (email + password) authentication.
# config.params_authenticatable = true
# Tell if authentication through HTTP Basic Auth is enabled. False by default.
# Tell if authentication through HTTP Auth is enabled. False by default.
# It can be set to an array that will enable http authentication only for the
# given strategies, for example, `config.http_authenticatable = [:token]` will
# enable it only for token authentication.
# given strategies, for example, `config.http_authenticatable = [:database]` will
# enable it only for database authentication. The supported strategies are:
# :database = Support basic authentication with authentication key + password
# config.http_authenticatable = false
# If http headers should be returned for AJAX requests. True by default.
# config.http_authenticatable_on_xhr = true
# The realm used in Http Basic Authentication. "Application" by default.
# config.http_authentication_realm = "Application"
# The realm used in Http Basic Authentication. 'Application' by default.
# config.http_authentication_realm = 'Application'
# It will change confirmation, password recovery and other workflows
# to behave the same regardless if the e-mail provided was right or wrong.
@@ -66,12 +73,18 @@ Devise.setup do |config|
# config.paranoid = true
# By default Devise will store the user in session. You can skip storage for
# :http_auth and :token_auth by adding those symbols to the array below.
# particular strategies by setting this option.
# Notice that if you are skipping storage for all authentication paths, you
# may want to disable generating routes to Devise's sessions controller by
# passing :skip => :sessions to `devise_for` in your config/routes.rb
config.skip_session_storage = [:http_auth]
# By default, Devise cleans up the CSRF token on authentication to
# avoid CSRF token fixation attacks. This means that, when using AJAX
# requests for sign in and sign up, you need to get a new CSRF token
# from the server. You can disable this option at your own risk.
# config.clean_up_csrf_token_on_authentication = true
# ==> Configuration for :database_authenticatable
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
# using other encryptors, it sets how many times you want the password re-encrypted.
@@ -82,7 +95,7 @@ Devise.setup do |config|
config.stretches = Rails.env.test? ? 1 : 10
# Setup a pepper to generate the encrypted password.
# config.pepper = <%= SecureRandom.hex(64).inspect %>
# config.pepper = '<%= SecureRandom.hex(64) %>'
# ==> Configuration for :confirmable
# A period that the user is allowed to access the website even without
@@ -125,7 +138,7 @@ Devise.setup do |config|
config.password_length = 8..128
# Email regex used to validate email formats. It simply asserts that
# an one (and only one) @ exists in the given string. This is mainly
# one (and only one) @ exists in the given string. This is mainly
# to give user feedback and not to assert the e-mail validity.
# config.email_regexp = /\A[^@]+@[^@]+\z/
@@ -160,6 +173,9 @@ Devise.setup do |config|
# Time interval to unlock the account if :time is enabled as unlock_strategy.
# config.unlock_in = 1.hour
# Warn on the last attempt before the account is locked.
# config.last_attempt_warning = false
# ==> Configuration for :recoverable
#
# Defines which key will be used when recovering the password for an account
@@ -175,13 +191,11 @@ Devise.setup do |config|
# :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
# :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
# and :restful_authentication_sha1 (then you should set stretches to 10, and copy
# REST_AUTH_SITE_KEY to pepper)
# REST_AUTH_SITE_KEY to pepper).
#
# Require the `devise-encryptable` gem when using anything other than bcrypt
# config.encryptor = :sha512
# ==> Configuration for :token_authenticatable
# Defines name of the authentication token params key
# config.token_authentication_key = :auth_token
# ==> Scopes configuration
# Turn scoped views on. Before rendering "sessions/new", it will first check for
# "users/sessions/new". It's turned off by default because it's slower if you
@@ -205,7 +219,7 @@ Devise.setup do |config|
# should add them to the navigational formats lists.
#
# The "*/*" below is required to match Internet Explorer requests.
# config.navigational_formats = ["*/*", :html]
# config.navigational_formats = ['*/*', :html]
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :delete
@@ -229,12 +243,12 @@ Devise.setup do |config|
# is mountable, there are some extra configurations to be taken into account.
# The following options are available, assuming the engine is mounted as:
#
# mount MyEngine, at: "/my_engine"
# mount MyEngine, at: '/my_engine'
#
# The router that invoked `devise_for`, in the example above, would be:
# config.router_name = :my_engine
#
# When using omniauth, Devise cannot automatically set Omniauth path,
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = "/my_engine/users/auth"
# config.omniauth_path_prefix = '/my_engine/users/auth'
end

View File

@@ -2,4 +2,4 @@ Welcome <%= @email %>!
You can confirm your account through the link below:
<%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %>
<%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %>

View File

@@ -2,7 +2,7 @@ Hello <%= @resource.email %>!
Someone has requested a link to change your password, and you can do this through the link below.
<%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %>
<%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %>
If you didn't request this, please ignore this email.
Your password won't change until you access the link above and create a new one.

View File

@@ -4,4 +4,4 @@ Your account has been locked due to an excessive number of unsuccessful sign in
Click the link below to unlock your account:
<%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %>
<%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @token) %>

View File

@@ -22,6 +22,6 @@
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %></p>
<%= link_to "Back", :back %>

View File

@@ -187,6 +187,29 @@ class ControllerAuthenticatableTest < ActionController::TestCase
assert_nil @controller.session[:"user_return_to"]
end
test 'store location for stores a location to redirect back to' do
assert_nil @controller.stored_location_for(:user)
@controller.store_location_for(:user, "/foo.bar")
assert_equal "/foo.bar", @controller.stored_location_for(:user)
end
test 'store location for accepts a resource as argument' do
@controller.store_location_for(User.new, "/foo.bar")
assert_equal "/foo.bar", @controller.stored_location_for(User.new)
end
test 'store location for stores paths' do
@controller.store_location_for(:user, "//host/foo.bar")
assert_equal "/foo.bar", @controller.stored_location_for(:user)
@controller.store_location_for(:user, "///foo.bar")
assert_equal "/foo.bar", @controller.stored_location_for(:user)
end
test 'store location for stores query string' do
@controller.store_location_for(:user, "/foo?bar=baz")
assert_equal "/foo?bar=baz", @controller.stored_location_for(:user)
end
test 'after sign in path defaults to root path if none by was specified for the given scope' do
assert_equal root_path, @controller.after_sign_in_path_for(:user)
end
@@ -202,7 +225,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
test 'sign in and redirect uses the stored location' do
user = User.new
@controller.session[:"user_return_to"] = "/foo.bar"
@controller.session[:user_return_to] = "/foo.bar"
@mock_warden.expects(:user).with(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
@controller.expects(:redirect_to).with("/foo.bar")

View File

@@ -34,10 +34,20 @@ class HelpersTest < ActionController::TestCase
end
test 'get resource params from request params using resource name as key' do
user_params = {'name' => 'Shirley Templar'}
@controller.stubs(:params).returns(HashWithIndifferentAccess.new({'user' => user_params}))
user_params = {'email' => 'shirley@templar.com'}
assert_equal user_params, @controller.resource_params
params = if Devise.rails4?
# Stub controller name so strong parameters can filter properly.
# DeviseController does not allow any parameters by default.
@controller.stubs(:controller_name).returns(:sessions_controller)
ActionController::Parameters.new({'user' => user_params})
else
HashWithIndifferentAccess.new({'user' => user_params})
end
@controller.stubs(:params).returns(params)
assert_equal user_params, @controller.send(:resource_params)
end
test 'resources methods are not controller actions' do
@@ -45,7 +55,7 @@ class HelpersTest < ActionController::TestCase
end
test 'require no authentication tests current mapping' do
@mock_warden.expects(:authenticate?).with(:rememberable, :token_authenticatable, :scope => :user).returns(true)
@mock_warden.expects(:authenticate?).with(:rememberable, :scope => :user).returns(true)
@mock_warden.expects(:user).with(:user).returns(User.new)
@controller.expects(:redirect_to).with(root_path)
@controller.send :require_no_authentication
@@ -61,7 +71,7 @@ class HelpersTest < ActionController::TestCase
end
test 'require no authentication sets a flash message' do
@mock_warden.expects(:authenticate?).with(:rememberable, :token_authenticatable, :scope => :user).returns(true)
@mock_warden.expects(:authenticate?).with(:rememberable, :scope => :user).returns(true)
@mock_warden.expects(:user).with(:user).returns(User.new)
@controller.expects(:redirect_to).with(root_path)
@controller.send :require_no_authentication

View File

@@ -0,0 +1,31 @@
require 'test_helper'
class PasswordsControllerTest < ActionController::TestCase
tests Devise::PasswordsController
include Devise::TestHelpers
setup do
request.env["devise.mapping"] = Devise.mappings[:user]
@user = create_user.tap(&:confirm!)
@raw = @user.send_reset_password_instructions
end
def put_update_with_params
put :update, "user" => {
"reset_password_token" => @raw, "password" => "123456", "password_confirmation" => "123456"
}
end
test 'redirect to after_sign_in_path_for if after_resetting_password_path_for is not overridden' do
put_update_with_params
assert_redirected_to "http://test.host/"
end
test 'redirect accordingly if after_resetting_password_path_for is overridden' do
custom_path = "http://custom.path/"
Devise::PasswordsController.any_instance.stubs(:after_resetting_password_path_for).with(@user).returns(custom_path)
put_update_with_params
assert_redirected_to custom_path
end
end

View File

@@ -4,6 +4,20 @@ class SessionsControllerTest < ActionController::TestCase
tests Devise::SessionsController
include Devise::TestHelpers
test "#create doesn't raise unpermitted params when sign in fails" do
ActiveSupport::Notifications.subscribe /unpermitted_parameters/ do |name, start, finish, id, payload|
flunk "Unpermitted params: #{payload}"
end
request.env["devise.mapping"] = Devise.mappings[:user]
request.session["user_return_to"] = 'foo.bar'
create_user
post :create, :user => {
:email => "wrong@email.com",
:password => "wrongpassword"
}
assert_equal 200, @response.status
end
test "#create works even with scoped views" do
swap Devise, :scoped_views => true do
request.env["devise.mapping"] = Devise.mappings[:user]

View File

@@ -11,6 +11,17 @@ module Devise
end
class DeviseTest < ActiveSupport::TestCase
test 'bcrypt on the class' do
password = "super secret"
klass = Struct.new(:pepper, :stretches).new("blahblah", 2)
hash = Devise.bcrypt(klass, password)
assert_equal ::BCrypt::Password.create(hash), hash
klass = Struct.new(:pepper, :stretches).new("bla", 2)
hash = Devise.bcrypt(klass, password)
assert_not_equal ::BCrypt::Password.new(hash), hash
end
test 'model options can be configured through Devise' do
swap Devise, :allow_unconfirmed_access_for => 113, :pepper => "foo" do
assert_equal 113, Devise.allow_unconfirmed_access_for
@@ -59,7 +70,7 @@ class DeviseTest < ActiveSupport::TestCase
Devise::ALL.delete(:kivi)
Devise::CONTROLLERS.delete(:kivi)
end
test 'should complain when comparing empty or different sized passes' do
[nil, ""].each do |empty|
assert_not Devise.secure_compare(empty, "something")

View File

@@ -8,6 +8,12 @@ class FailureTest < ActiveSupport::TestCase
end
end
class FailureWithI18nOptions < Devise::FailureApp
def i18n_options(options)
options.merge(:name => 'Steve')
end
end
def self.context(name, &block)
instance_eval(&block)
end
@@ -67,6 +73,11 @@ class FailureTest < ActiveSupport::TestCase
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
test 'uses custom i18n options' do
call_failure('warden' => OpenStruct.new(:message => :does_not_exist), :app => FailureWithI18nOptions)
assert_equal 'User Steve does not exist', @request.flash[:alert]
end
test 'uses the proxy failure message as string' do
call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
assert_equal 'Hello world', @request.flash[:alert]
@@ -80,9 +91,9 @@ class FailureTest < ActiveSupport::TestCase
test 'setup a default message' do
call_failure
assert_match /You are being/, @response.last.body
assert_match /redirected/, @response.last.body
assert_match /users\/sign_in/, @response.last.body
assert_match(/You are being/, @response.last.body)
assert_match(/redirected/, @response.last.body)
assert_match(/users\/sign_in/, @response.last.body)
end
test 'works for any navigational format' do
@@ -215,7 +226,7 @@ class FailureTest < ActiveSupport::TestCase
}
call_failure(env)
assert @response.third.body.include?('<h2>Sign in</h2>')
assert @response.third.body.include?('Your account was not activated yet.')
assert @response.third.body.include?('Your account is not activated yet.')
end
end
end

View File

@@ -10,13 +10,11 @@ if DEVISE_ORM == :active_record
test "all files are properly created with rails31 migration syntax" do
run_generator %w(monster)
assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
assert_migration "db/migrate/devise_create_monsters.rb", /def change/
end
test "all files for namespaced model are properly created" do
run_generator %w(admin/monster)
assert_file "app/models/admin/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
assert_migration "db/migrate/devise_create_admin_monsters.rb", /def change/
end
@@ -64,11 +62,41 @@ if DEVISE_ORM == :active_record
destination File.expand_path("../../tmp", __FILE__)
setup :prepare_destination
test "all files are properly created" do
test "all files are properly created in rails 4.0" do
ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(false)
simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
run_generator ["monster"]
assert_file "app/models/rails_engine/monster.rb", /devise/,/attr_accessible (:[a-z_]+(, )?)+/
assert_file "app/models/rails_engine/monster.rb", /devise/
assert_file "app/models/rails_engine/monster.rb" do |content|
assert_no_match /attr_accessible :email/, content
end
end
end
test "all files are properly created in rails 3.2 when strong_parameters gem is not installed" do
ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(false)
simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
run_generator ["monster"]
assert_file "app/models/rails_engine/monster.rb", /devise/
assert_file "app/models/rails_engine/monster.rb" do |content|
assert_match /attr_accessible :email/, content
end
end
end
test "all files are properly created in rails 3.2 when strong_parameters gem is installed" do
ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(true)
simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
run_generator ["monster"]
assert_file "app/models/rails_engine/monster.rb", /devise/
assert_file "app/models/rails_engine/monster.rb" do |content|
assert_no_match /attr_accessible :email/, content
end
end
end
end

View File

@@ -8,14 +8,17 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
test "Assert all views are properly created with no params" do
run_generator
assert_files
assert_shared_links
end
test "Assert all views are properly created with scope param param" do
test "Assert all views are properly created with scope param" do
run_generator %w(users)
assert_files "users"
assert_shared_links "users"
run_generator %w(admins)
assert_files "admins"
assert_shared_links "admins"
end
test "Assert views with simple form" do
@@ -49,4 +52,16 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
assert_file "app/views/#{scope}/shared/_links.erb"
assert_file "app/views/#{scope}/unlocks/new.html.erb"
end
def assert_shared_links(scope = nil)
scope = "devise" if scope.nil?
link = /<%= render \"#{scope}\/shared\/links\" %>/
assert_file "app/views/#{scope}/passwords/edit.html.erb", link
assert_file "app/views/#{scope}/passwords/new.html.erb", link
assert_file "app/views/#{scope}/confirmations/new.html.erb", link
assert_file "app/views/#{scope}/registrations/new.html.erb", link
assert_file "app/views/#{scope}/sessions/new.html.erb", link
assert_file "app/views/#{scope}/unlocks/new.html.erb", link
end
end

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class DeviseHelperTest < ActionController::IntegrationTest
class DeviseHelperTest < ActionDispatch::IntegrationTest
setup do
model_labels = { :models => { :user => "utilisateur" } }

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class AuthenticationSanityTest < ActionController::IntegrationTest
class AuthenticationSanityTest < ActionDispatch::IntegrationTest
test 'home should be accessible without sign in' do
visit '/'
assert_response :success
@@ -134,7 +134,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
end
end
class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
class AuthenticationRoutesRestrictions < ActionDispatch::IntegrationTest
test 'not signed in should not be able to access private route (authenticate denied)' do
get private_path
assert_redirected_to new_admin_session_path
@@ -191,7 +191,7 @@ class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
get dashboard_path
assert_response :success
assert_template 'home/admin'
assert_template 'home/admin_dashboard'
assert_contain 'Admin dashboard'
end
@@ -203,7 +203,7 @@ class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
get dashboard_path
assert_response :success
assert_template 'home/user'
assert_template 'home/user_dashboard'
assert_contain 'User dashboard'
end
@@ -254,7 +254,7 @@ class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
end
end
class AuthenticationRedirectTest < ActionController::IntegrationTest
class AuthenticationRedirectTest < ActionDispatch::IntegrationTest
test 'redirect from warden shows sign in or sign up message' do
get admins_path
@@ -317,7 +317,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
end
end
class AuthenticationSessionTest < ActionController::IntegrationTest
class AuthenticationSessionTest < ActionDispatch::IntegrationTest
test 'destroyed account is signed out' do
sign_in_as_user
get '/users'
@@ -327,28 +327,54 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
assert_redirected_to new_user_session_path
end
test 'refreshes _csrf_token' do
ApplicationController.allow_forgery_protection = true
begin
get new_user_session_path
token = request.session[:_csrf_token]
sign_in_as_user
assert_not_equal request.session[:_csrf_token], token
ensure
ApplicationController.allow_forgery_protection = false
end
end
test 'allows session to be set for a given scope' do
sign_in_as_user
get '/users'
assert_equal "Cart", @controller.user_session[:cart]
end
test 'does not explode when invalid user class is stored in session' do
klass = User
paths = ActiveSupport::Dependencies.autoload_paths.dup
test 'does not explode when class name is still stored in session' do
# In order to test that old sessions do not break with the new scoped
# deserialization, we need to serialize the session the old way. This is
# done by removing the newly used scoped serialization method
# (#user_serialize) and bringing back the old uncsoped #serialize method
# that includes the record's class name in the serialization.
begin
Warden::SessionSerializer.class_eval do
alias_method :original_serialize, :serialize
alias_method :original_user_serialize, :user_serialize
remove_method :user_serialize
def serialize(record)
klass = record.class
array = klass.serialize_into_session(record)
array.unshift(klass.name)
end
end
sign_in_as_user
assert warden.authenticated?(:user)
Object.send :remove_const, :User
ActiveSupport::Dependencies.autoload_paths.clear
visit "/users"
assert_not warden.authenticated?(:user)
ensure
Object.const_set(:User, klass)
ActiveSupport::Dependencies.autoload_paths.replace(paths)
Warden::SessionSerializer.class_eval do
alias_method :serialize, :original_serialize
remove_method :original_serialize
alias_method :user_serialize, :original_user_serialize
remove_method :original_user_serialize
end
end
end
@@ -364,7 +390,7 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
end
end
class AuthenticationWithScopedViewsTest < ActionController::IntegrationTest
class AuthenticationWithScopedViewsTest < ActionDispatch::IntegrationTest
test 'renders the scoped view if turned on and view is available' do
swap Devise, :scoped_views => true do
assert_raise Webrat::NotFoundError do
@@ -405,9 +431,9 @@ class AuthenticationWithScopedViewsTest < ActionController::IntegrationTest
end
end
class AuthenticationOthersTest < ActionController::IntegrationTest
class AuthenticationOthersTest < ActionDispatch::IntegrationTest
test 'handles unverified requests gets rid of caches' do
swap UsersController, :allow_forgery_protection => true do
swap ApplicationController, :allow_forgery_protection => true do
post exhibit_user_url(1)
assert_not warden.authenticated?(:user)
@@ -504,14 +530,26 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
end
test 'sign out with xml format returns ok response' do
test 'sign out with html redirects' do
sign_in_as_user
get destroy_user_session_path
assert_response :redirect
assert_current_url '/'
sign_in_as_user
get destroy_user_session_path(:format => 'html')
assert_response :redirect
assert_current_url '/'
end
test 'sign out with xml format returns no content' do
sign_in_as_user
get destroy_user_session_path(:format => 'xml')
assert_response :no_content
assert_not warden.authenticated?(:user)
end
test 'sign out with json format returns empty json response' do
test 'sign out with json format returns no content' do
sign_in_as_user
get destroy_user_session_path(:format => 'json')
assert_response :no_content
@@ -519,7 +557,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
end
test 'sign out with non-navigational format via XHR does not redirect' do
swap Devise, :navigational_formats => ['*/*', :html] do
swap Devise, :navigational_formats => ['*/*', :html] do
sign_in_as_user
xml_http_request :get, destroy_user_session_path, {}, { "HTTP_ACCEPT" => "application/json,text/javascript,*/*" } # NOTE: Bug is triggered by combination of XHR and */*.
assert_response :no_content
@@ -529,7 +567,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
# Belt and braces ... Perhaps this test is not necessary?
test 'sign out with navigational format via XHR does redirect' do
swap Devise, :navigational_formats => ['*/*', :html] do
swap Devise, :navigational_formats => ['*/*', :html] do
sign_in_as_user
xml_http_request :get, destroy_user_session_path, {}, { "HTTP_ACCEPT" => "text/html,*/*" }
assert_response :redirect
@@ -538,7 +576,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
end
end
class AuthenticationKeysTest < ActionController::IntegrationTest
class AuthenticationKeysTest < ActionDispatch::IntegrationTest
test 'missing authentication keys cause authentication to abort' do
swap Devise, :authentication_keys => [:subdomain] do
sign_in_as_user
@@ -555,7 +593,7 @@ class AuthenticationKeysTest < ActionController::IntegrationTest
end
end
class AuthenticationRequestKeysTest < ActionController::IntegrationTest
class AuthenticationRequestKeysTest < ActionDispatch::IntegrationTest
test 'request keys are used on authentication' do
host! 'foo.bar.baz'
@@ -596,7 +634,7 @@ class AuthenticationRequestKeysTest < ActionController::IntegrationTest
end
end
class AuthenticationSignOutViaTest < ActionController::IntegrationTest
class AuthenticationSignOutViaTest < ActionDispatch::IntegrationTest
def sign_in!(scope)
sign_in_as_admin(:visit => send("new_#{scope}_session_path"))
assert warden.authenticated?(scope)
@@ -650,3 +688,26 @@ class AuthenticationSignOutViaTest < ActionController::IntegrationTest
assert warden.authenticated?(:sign_out_via_delete_or_post)
end
end
class DoubleAuthenticationRedirectTest < ActionDispatch::IntegrationTest
test 'signed in as user redirects when visiting user sign in page' do
sign_in_as_user
get new_user_session_path(:format => :html)
assert_redirected_to '/'
end
test 'signed in as admin redirects when visiting admin sign in page' do
sign_in_as_admin
get new_admin_session_path(:format => :html)
assert_redirected_to '/admin_area/home'
end
test 'signed in as both user and admin redirects when visiting admin sign in page' do
sign_in_as_user
sign_in_as_admin
get new_user_session_path(:format => :html)
assert_redirected_to '/'
get new_admin_session_path(:format => :html)
assert_redirected_to '/admin_area/home'
end
end

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class ConfirmationTest < ActionController::IntegrationTest
class ConfirmationTest < ActionDispatch::IntegrationTest
def visit_user_confirmation_with_token(confirmation_token)
visit user_confirmation_path(:confirmation_token => confirmation_token)
@@ -28,9 +28,7 @@ class ConfirmationTest < ActionController::IntegrationTest
test 'user should receive a confirmation from a custom mailer' do
User.any_instance.stubs(:devise_mailer).returns(Users::Mailer)
resend_confirmation
assert_equal ['custom@example.com'], ActionMailer::Base.deliveries.first.from
end
@@ -40,21 +38,11 @@ class ConfirmationTest < ActionController::IntegrationTest
assert_contain /Confirmation token(.*)invalid/
end
test 'user with valid confirmation token should be able to confirm an account' do
user = create_user(:confirm => false)
assert_not user.confirmed?
visit_user_confirmation_with_token(user.confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_current_url '/'
assert user.reload.confirmed?
end
test 'user with valid confirmation token should not be able to confirm an account after the token has expired' do
swap Devise, :confirm_within => 3.days do
user = create_user(:confirm => false, :confirmation_sent_at => 4.days.ago)
assert_not user.confirmed?
visit_user_confirmation_with_token(user.confirmation_token)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_have_selector '#error_explanation'
assert_contain /needs to be confirmed within 3 days/
@@ -66,10 +54,10 @@ class ConfirmationTest < ActionController::IntegrationTest
swap Devise, :confirm_within => 3.days do
user = create_user(:confirm => false, :confirmation_sent_at => 2.days.ago)
assert_not user.confirmed?
visit_user_confirmation_with_token(user.confirmation_token)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_current_url '/'
assert_current_url '/users/sign_in'
assert user.reload.confirmed?
end
end
@@ -78,7 +66,7 @@ class ConfirmationTest < ActionController::IntegrationTest
Devise::ConfirmationsController.any_instance.stubs(:after_confirmation_path_for).returns("/?custom=1")
user = create_user(:confirm => false)
visit_user_confirmation_with_token(user.confirmation_token)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_current_url "/?custom=1"
end
@@ -87,7 +75,7 @@ class ConfirmationTest < ActionController::IntegrationTest
user = create_user(:confirm => false)
user.confirmed_at = Time.now
user.save
visit_user_confirmation_with_token(user.confirmation_token)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_have_selector '#error_explanation'
assert_contain 'already confirmed'
@@ -98,7 +86,7 @@ class ConfirmationTest < ActionController::IntegrationTest
user.confirmed_at = Time.now
user.save
visit_user_confirmation_with_token(user.confirmation_token)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'already confirmed'
fill_in 'email', :with => user.email
@@ -106,21 +94,6 @@ class ConfirmationTest < ActionController::IntegrationTest
assert_contain 'already confirmed'
end
test 'sign in user automatically after confirming its email' do
user = create_user(:confirm => false)
visit_user_confirmation_with_token(user.confirmation_token)
assert warden.authenticated?(:user)
end
test 'increases sign count when signed in through confirmation' do
user = create_user(:confirm => false)
visit_user_confirmation_with_token(user.confirmation_token)
user.reload
assert_equal 1, user.sign_in_count
end
test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
swap Devise, :allow_unconfirmed_access_for => 0.days do
sign_in_as_user(:confirm => false)
@@ -150,6 +123,16 @@ class ConfirmationTest < ActionController::IntegrationTest
end
end
test 'unconfirmed but signed in user should be redirected to their root path' do
swap Devise, :allow_unconfirmed_access_for => 1.day do
user = sign_in_as_user(:confirm => false)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_current_url '/'
end
end
test 'error message is configurable by resource name' do
store_translations :en, :devise => {
:failure => { :user => { :unconfirmed => "Not confirmed user" } }
@@ -167,7 +150,7 @@ class ConfirmationTest < ActionController::IntegrationTest
end
test 'resent confirmation token with invalid E-Mail in XML format should return invalid response' do
user = create_user(:confirm => false)
create_user(:confirm => false)
post user_confirmation_path(:format => 'xml'), :user => { :email => 'invalid.test@test.com' }
assert_response :unprocessable_entity
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
@@ -175,13 +158,13 @@ class ConfirmationTest < ActionController::IntegrationTest
test 'confirm account with valid confirmation token in XML format should return valid response' do
user = create_user(:confirm => false)
get user_confirmation_path(:confirmation_token => user.confirmation_token, :format => 'xml')
get user_confirmation_path(:confirmation_token => user.raw_confirmation_token, :format => 'xml')
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
end
test 'confirm account with invalid confirmation token in XML format should return invalid response' do
user = create_user(:confirm => false)
create_user(:confirm => false)
get user_confirmation_path(:confirmation_token => 'invalid_confirmation', :format => 'xml')
assert_response :unprocessable_entity
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
@@ -226,7 +209,7 @@ class ConfirmationTest < ActionController::IntegrationTest
end
end
class ConfirmationOnChangeTest < ActionController::IntegrationTest
class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
def create_second_admin(options={})
@admin = nil
create_admin(options)
@@ -256,10 +239,10 @@ class ConfirmationOnChangeTest < ActionController::IntegrationTest
admin = create_admin
admin.update_attributes(:email => 'new_test@example.com')
assert_equal 'new_test@example.com', admin.unconfirmed_email
visit_admin_confirmation_with_token(admin.confirmation_token)
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_current_url '/admin_area/home'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
assert_not admin.reload.pending_reconfirmation?
end
@@ -269,17 +252,19 @@ class ConfirmationOnChangeTest < ActionController::IntegrationTest
admin.update_attributes(:email => 'first_test@example.com')
assert_equal 'first_test@example.com', admin.unconfirmed_email
confirmation_token = admin.confirmation_token
raw_confirmation_token = admin.raw_confirmation_token
admin = Admin.find(admin.id)
admin.update_attributes(:email => 'second_test@example.com')
assert_equal 'second_test@example.com', admin.unconfirmed_email
visit_admin_confirmation_with_token(confirmation_token)
visit_admin_confirmation_with_token(raw_confirmation_token)
assert_have_selector '#error_explanation'
assert_contain /Confirmation token(.*)invalid/
assert_contain(/Confirmation token(.*)invalid/)
visit_admin_confirmation_with_token(admin.confirmation_token)
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_current_url '/admin_area/home'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
assert_not admin.reload.pending_reconfirmation?
end
@@ -291,9 +276,9 @@ class ConfirmationOnChangeTest < ActionController::IntegrationTest
create_second_admin(:email => "new_admin_test@example.com")
visit_admin_confirmation_with_token(admin.confirmation_token)
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
assert_have_selector '#error_explanation'
assert_contain /Email.*already.*taken/
assert_contain(/Email.*already.*taken/)
assert admin.reload.pending_reconfirmation?
end
end

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class DatabaseAuthenticationTest < ActionController::IntegrationTest
class DatabaseAuthenticationTest < ActionDispatch::IntegrationTest
test 'sign in with email of different case should succeed when email is in the list of case insensitive keys' do
create_user(:email => 'Foo@Bar.com')

View File

@@ -1,8 +1,8 @@
require 'test_helper'
class HttpAuthenticationTest < ActionController::IntegrationTest
class HttpAuthenticationTest < ActionDispatch::IntegrationTest
test 'handles unverified requests gets rid of caches but continues signed in' do
swap UsersController, :allow_forgery_protection => true do
swap ApplicationController, :allow_forgery_protection => true do
create_user
post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:12345678")}"
assert warden.authenticated?(:user)
@@ -62,6 +62,24 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
end
end
test 'it uses appropriate authentication_keys when configured with hash' do
swap Devise, :authentication_keys => ActiveSupport::OrderedHash[:username, false, :email, false] do
sign_in_as_new_user_with_http("usertest")
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert warden.authenticated?(:user)
end
end
test 'it uses the appropriate key when configured explicitly' do
swap Devise, :authentication_keys => ActiveSupport::OrderedHash[:email, false, :username, false], :http_authentication_key => :username do
sign_in_as_new_user_with_http("usertest")
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert warden.authenticated?(:user)
end
end
test 'test request with oauth2 header doesnt get mistaken for basic authentication' do
swap Devise, :http_authenticatable => true do
add_oauth2_header
@@ -70,16 +88,6 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
end
end
test 'sign in should authenticate with really long token' do
token = "token_containing_so_many_characters_that_the_base64_encoding_will_wrap"
user = create_user
user.update_attribute :authentication_token, token
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("#{token}:x")}"
assert_response :success
assert_match "<email>user@test.com</email>", response.body
assert warden.authenticated?(:user)
end
private
def sign_in_as_new_user_with_http(username="user@test.com", password="12345678")

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class LockTest < ActionController::IntegrationTest
class LockTest < ActionDispatch::IntegrationTest
def visit_user_unlock_with_token(unlock_token)
visit user_unlock_path(:unlock_token => unlock_token)
@@ -13,6 +13,7 @@ class LockTest < ActionController::IntegrationTest
visit new_user_session_path
click_link "Didn't receive unlock instructions?"
Devise.stubs(:friendly_token).returns("abcdef")
fill_in 'email', :with => user.email
click_button 'Resend unlock instructions'
end
@@ -22,8 +23,11 @@ class LockTest < ActionController::IntegrationTest
assert_template 'sessions/new'
assert_contain 'You will receive an email with instructions about how to unlock your account in a few minutes'
mail = ActionMailer::Base.deliveries.last
assert_equal 1, ActionMailer::Base.deliveries.size
assert_equal ['please-change-me@config-initializers-devise.com'], ActionMailer::Base.deliveries.first.from
assert_equal ['please-change-me@config-initializers-devise.com'], mail.from
assert_match user_unlock_path(unlock_token: 'abcdef'), mail.body.encoded
end
test 'user should receive the instructions from a custom mailer' do
@@ -75,23 +79,15 @@ class LockTest < ActionController::IntegrationTest
end
test "locked user should be able to unlock account" do
user = create_user(:locked => true)
assert user.access_locked?
visit_user_unlock_with_token(user.unlock_token)
user = create_user
raw = user.lock_access!
visit_user_unlock_with_token(raw)
assert_current_url "/users/sign_in"
assert_contain 'Your account has been unlocked successfully. Please sign in to continue.'
assert_not user.reload.access_locked?
end
test "redirect user to sign in page after unlocking its account" do
user = create_user(:locked => true)
visit_user_unlock_with_token(user.unlock_token)
assert_not warden.authenticated?(:user)
end
test "user should not send a new e-mail if already locked" do
user = create_user(:locked => true)
user.failed_attempts = User.maximum_attempts + 1
@@ -153,9 +149,10 @@ class LockTest < ActionController::IntegrationTest
end
test 'user with valid unlock token should be able to unlock account via XML request' do
user = create_user(:locked => true)
user = create_user()
raw = user.lock_access!
assert user.access_locked?
get user_unlock_path(:format => 'xml', :unlock_token => user.unlock_token)
get user_unlock_path(:format => 'xml', :unlock_token => raw)
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
end

View File

@@ -1,7 +1,7 @@
require 'test_helper'
class OmniauthableIntegrationTest < ActionController::IntegrationTest
class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
FACEBOOK_INFO = {
"id" => '12345',
"link" => 'http://facebook.com/josevalim',
@@ -90,7 +90,7 @@ class OmniauthableIntegrationTest < ActionController::IntegrationTest
end
assert session["devise.facebook_data"]
user = sign_in_as_user
sign_in_as_user
assert !session["devise.facebook_data"]
end

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class PasswordTest < ActionController::IntegrationTest
class PasswordTest < ActionDispatch::IntegrationTest
def visit_new_password_path
visit new_user_session_path
@@ -14,12 +14,16 @@ class PasswordTest < ActionController::IntegrationTest
fill_in 'email', :with => 'user@test.com'
yield if block_given?
Devise.stubs(:friendly_token).returns("abcdef")
click_button 'Send me reset password instructions'
end
def reset_password(options={}, &block)
visit edit_user_password_path(:reset_password_token => options[:reset_password_token]) unless options[:visit] == false
assert_response :success
unless options[:visit] == false
visit edit_user_password_path(:reset_password_token => options[:reset_password_token] || "abcdef")
assert_response :success
end
fill_in 'New password', :with => '987654321'
fill_in 'Confirm new password', :with => '987654321'
@@ -45,7 +49,10 @@ class PasswordTest < ActionController::IntegrationTest
request_forgot_password do
fill_in 'email', :with => 'foo@bar.com'
end
assert_equal ['custom@example.com'], ActionMailer::Base.deliveries.last.from
mail = ActionMailer::Base.deliveries.last
assert_equal ['custom@example.com'], mail.from
assert_match edit_user_password_path(reset_password_token: 'abcdef'), mail.body.encoded
end
test 'reset password with email of different case should fail when email is NOT the list of case insensitive keys' do
@@ -146,21 +153,22 @@ class PasswordTest < ActionController::IntegrationTest
test 'not authenticated user with valid reset password token but invalid password should not be able to change his password' do
user = create_user
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token do
reset_password do
fill_in 'Confirm new password', :with => 'other_password'
end
assert_response :success
assert_current_url '/users/password'
assert_have_selector '#error_explanation'
assert_contain 'Password doesn\'t match confirmation'
assert_contain Devise.rails4? ?
"Password confirmation doesn't match Password" : "Password doesn't match confirmation"
assert_not user.reload.valid_password?('987654321')
end
test 'not authenticated user with valid data should be able to change his password' do
user = create_user
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert_current_url '/'
assert_contain 'Your password was changed successfully. You are now signed in.'
@@ -170,22 +178,21 @@ class PasswordTest < ActionController::IntegrationTest
test 'after entering invalid data user should still be able to change his password' do
user = create_user
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token do
fill_in 'Confirm new password', :with => 'other_password'
end
reset_password { fill_in 'Confirm new password', :with => 'other_password' }
assert_response :success
assert_have_selector '#error_explanation'
assert_not user.reload.valid_password?('987654321')
reset_password :reset_password_token => user.reload.reset_password_token, :visit => false
reset_password :visit => false
assert_contain 'Your password was changed successfully.'
assert user.reload.valid_password?('987654321')
end
test 'sign in user automatically after changing its password' do
user = create_user
create_user
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert warden.authenticated?(:user)
end
@@ -195,7 +202,7 @@ class PasswordTest < ActionController::IntegrationTest
swap Devise, :unlock_strategy => strategy do
user = create_user(:locked => true)
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert_contain 'Your password was changed successfully.'
assert_not_contain 'You are now signed in.'
@@ -209,7 +216,7 @@ class PasswordTest < ActionController::IntegrationTest
swap Devise, :unlock_strategy => :email do
user = create_user(:locked => true)
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert_contain 'Your password was changed successfully.'
assert !user.reload.access_locked?
@@ -221,7 +228,7 @@ class PasswordTest < ActionController::IntegrationTest
swap Devise, :unlock_strategy => :both do
user = create_user(:locked => true)
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert_contain 'Your password was changed successfully.'
assert !user.reload.access_locked?
@@ -229,15 +236,6 @@ class PasswordTest < ActionController::IntegrationTest
end
end
test 'sign in user automatically and confirm after changing its password if it\'s not confirmed' do
user = create_user(:confirm => false)
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
assert warden.authenticated?(:user)
assert user.reload.confirmed?
end
test 'reset password request with valid E-Mail in XML format should return valid response' do
create_user
post user_password_path(:format => 'xml'), :user => {:email => "user@test.com"}
@@ -262,15 +260,17 @@ class PasswordTest < ActionController::IntegrationTest
end
test 'change password with valid parameters in XML format should return valid response' do
user = create_user
create_user
request_forgot_password
put user_password_path(:format => 'xml'), :user => {:reset_password_token => user.reload.reset_password_token, :password => '987654321', :password_confirmation => '987654321'}
put user_password_path(:format => 'xml'), :user => {
:reset_password_token => 'abcdef', :password => '987654321', :password_confirmation => '987654321'
}
assert_response :success
assert warden.authenticated?(:user)
end
test 'change password with invalid token in XML format should return invalid response' do
user = create_user
create_user
request_forgot_password
put user_password_path(:format => 'xml'), :user => {:reset_password_token => 'invalid.token', :password => '987654321', :password_confirmation => '987654321'}
assert_response :unprocessable_entity
@@ -325,7 +325,7 @@ class PasswordTest < ActionController::IntegrationTest
assert_equal 10, user.failed_attempts
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
reset_password
assert warden.authenticated?(:user)
user.reload

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class RegistrationTest < ActionController::IntegrationTest
class RegistrationTest < ActionDispatch::IntegrationTest
test 'a guest admin should be able to sign in successfully' do
get new_admin_session_path
@@ -17,7 +17,7 @@ class RegistrationTest < ActionController::IntegrationTest
assert warden.authenticated?(:admin)
assert_current_url "/admin_area/home"
admin = Admin.last :order => "id"
admin = Admin.order(:id).last
assert_equal admin.email, 'new_user@test.com'
end
@@ -56,7 +56,7 @@ class RegistrationTest < ActionController::IntegrationTest
assert_not warden.authenticated?(:user)
user = User.last :order => "id"
user = User.order(:id).last
assert_equal user.email, 'new_user@test.com'
assert_not user.confirmed?
end
@@ -100,7 +100,8 @@ class RegistrationTest < ActionController::IntegrationTest
assert_template 'registrations/new'
assert_have_selector '#error_explanation'
assert_contain "Email is invalid"
assert_contain "Password doesn't match confirmation"
assert_contain Devise.rails4? ?
"Password confirmation doesn't match Password" : "Password doesn't match confirmation"
assert_contain "2 errors prohibited"
assert_nil User.first
@@ -112,7 +113,7 @@ class RegistrationTest < ActionController::IntegrationTest
# https://github.com/mongoid/mongoid/issues/756
(pending "Fails on Mongoid < 2.1"; break) if defined?(Mongoid) && Mongoid::VERSION.to_f < 2.1
user = create_user
create_user
get new_user_registration_path
fill_in 'email', :with => 'user@test.com'
@@ -206,7 +207,8 @@ class RegistrationTest < ActionController::IntegrationTest
fill_in 'current password', :with => '12345678'
click_button 'Update'
assert_contain "Password doesn't match confirmation"
assert_contain Devise.rails4? ?
"Password confirmation doesn't match Password" : "Password doesn't match confirmation"
assert_not User.first.valid_password?('pas123')
end
@@ -251,7 +253,7 @@ class RegistrationTest < ActionController::IntegrationTest
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<admin>)
admin = Admin.last :order => "id"
admin = Admin.order(:id).last
assert_equal admin.email, 'new_user@test.com'
end
@@ -260,7 +262,7 @@ class RegistrationTest < ActionController::IntegrationTest
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
user = User.last :order => "id"
user = User.order(:id).last
assert_equal user.email, 'new_user@test.com'
end
@@ -285,14 +287,14 @@ class RegistrationTest < ActionController::IntegrationTest
end
test 'a user cancel his account in XML format should return valid response' do
user = sign_in_as_user
sign_in_as_user
delete user_registration_path(:format => 'xml')
assert_response :success
assert_equal User.count, 0
end
end
class ReconfirmableRegistrationTest < ActionController::IntegrationTest
class ReconfirmableRegistrationTest < ActionDispatch::IntegrationTest
test 'a signed in admin should see a more appropriate flash message when editing his account if reconfirmable is enabled' do
sign_in_as_admin
get edit_admin_registration_path

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class RememberMeTest < ActionController::IntegrationTest
class RememberMeTest < ActionDispatch::IntegrationTest
def create_user_and_remember(add_to_token='')
user = create_user
user.remember_me!
@@ -26,12 +26,12 @@ class RememberMeTest < ActionController::IntegrationTest
end
test 'do not remember the user if he has not checked remember me option' do
user = sign_in_as_user
sign_in_as_user
assert_nil request.cookies["remember_user_cookie"]
end
test 'handles unverified requests gets rid of caches' do
swap UsersController, :allow_forgery_protection => true do
test 'handle unverified requests gets rid of caches' do
swap ApplicationController, :allow_forgery_protection => true do
post exhibit_user_url(1)
assert_not warden.authenticated?(:user)
@@ -42,9 +42,21 @@ class RememberMeTest < ActionController::IntegrationTest
end
end
test 'handle unverified requests does not create cookies on sign in' do
swap ApplicationController, :allow_forgery_protection => true do
get new_user_session_path
assert request.session[:_csrf_token]
post user_session_path, :authenticity_token => "oops", :user =>
{ email: "jose.valim@gmail.com", password: "123456", :remember_me => "1" }
assert_not warden.authenticated?(:user)
assert_not request.cookies['remember_user_token']
end
end
test 'generate remember token after sign in' do
user = sign_in_as_user :remember_me => true
assert request.cookies["remember_user_token"]
sign_in_as_user :remember_me => true
assert request.cookies['remember_user_token']
end
test 'generate remember token after sign in setting cookie options' do
@@ -52,15 +64,22 @@ class RememberMeTest < ActionController::IntegrationTest
# since we changed the domain. This is the only difference with the
# previous test.
swap Devise, :rememberable_options => { :domain => "omg.somewhere.com" } do
user = sign_in_as_user :remember_me => true
sign_in_as_user :remember_me => true
assert_nil request.cookies["remember_user_token"]
end
end
test 'generate remember token with a custom key' do
swap Devise, :rememberable_options => { :key => "v1lat_token" } do
sign_in_as_user :remember_me => true
assert request.cookies["v1lat_token"]
end
end
test 'generate remember token after sign in setting session options' do
begin
Rails.configuration.session_options[:domain] = "omg.somewhere.com"
user = sign_in_as_user :remember_me => true
sign_in_as_user :remember_me => true
assert_nil request.cookies["remember_user_token"]
ensure
Rails.configuration.session_options.delete(:domain)
@@ -77,22 +96,12 @@ class RememberMeTest < ActionController::IntegrationTest
end
test 'remember the user before sign up and redirect him to his home' do
user = create_user_and_remember
create_user_and_remember
get new_user_registration_path
assert warden.authenticated?(:user)
assert_redirected_to root_path
end
test 'cookies are destroyed on unverified requests' do
swap ApplicationController, :allow_forgery_protection => true do
user = create_user_and_remember
get users_path
assert warden.authenticated?(:user)
post root_path, :authenticity_token => 'INVALID'
assert_not warden.authenticated?(:user)
end
end
test 'does not extend remember period through sign in' do
swap Devise, :extend_remember_period => true, :remember_for => 1.year do
user = create_user
@@ -110,7 +119,7 @@ class RememberMeTest < ActionController::IntegrationTest
end
test 'do not remember other scopes' do
user = create_user_and_remember
create_user_and_remember
get root_path
assert_response :success
assert warden.authenticated?(:user)
@@ -118,14 +127,14 @@ class RememberMeTest < ActionController::IntegrationTest
end
test 'do not remember with invalid token' do
user = create_user_and_remember('add')
create_user_and_remember('add')
get users_path
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path
end
test 'do not remember with expired token' do
user = create_user_and_remember
create_user_and_remember
swap Devise, :remember_for => 0 do
get users_path
assert_not warden.authenticated?(:user)
@@ -134,7 +143,7 @@ class RememberMeTest < ActionController::IntegrationTest
end
test 'do not remember the user anymore after forget' do
user = create_user_and_remember
create_user_and_remember
get users_path
assert warden.authenticated?(:user)

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class SessionTimeoutTest < ActionController::IntegrationTest
class SessionTimeoutTest < ActionDispatch::IntegrationTest
def last_request_at
@controller.user_session['last_request_at']
@@ -35,14 +35,43 @@ class SessionTimeoutTest < ActionController::IntegrationTest
assert warden.authenticated?(:user)
end
test 'time out user session after default limit time' do
user = sign_in_as_user
get expire_user_path(user)
assert_not_nil last_request_at
test 'time out user session after default limit time when sign_out_all_scopes is false' do
swap Devise, sign_out_all_scopes: false do
sign_in_as_admin
get users_path
assert_redirected_to users_path
assert_not warden.authenticated?(:user)
user = sign_in_as_user
get expire_user_path(user)
assert_not_nil last_request_at
get users_path
assert_redirected_to users_path
assert_not warden.authenticated?(:user)
assert warden.authenticated?(:admin)
end
end
test 'time out all sessions after default limit time when sign_out_all_scopes is true' do
swap Devise, sign_out_all_scopes: true do
sign_in_as_admin
user = sign_in_as_user
get expire_user_path(user)
assert_not_nil last_request_at
get root_path
assert_not warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
end
end
test 'time out user session after deault limit time and redirect to latest get request' do
user = sign_in_as_user
visit edit_form_user_path(user)
click_button 'Update'
sign_in_as_user
assert_equal edit_form_user_url(user), current_url
end
test 'time out is not triggered on sign out' do
@@ -57,6 +86,20 @@ class SessionTimeoutTest < ActionController::IntegrationTest
assert_contain 'Signed out successfully'
end
test 'expired session is not extended by sign in page' do
user = sign_in_as_user
get expire_user_path(user)
assert warden.authenticated?(:user)
get "/users/sign_in"
assert_redirected_to "/users/sign_in"
follow_redirect!
assert_response :success
assert_contain 'Sign in'
assert_not warden.authenticated?(:user)
end
test 'time out is not triggered on sign in' do
user = sign_in_as_user
get expire_user_path(user)

View File

@@ -1,161 +0,0 @@
require 'test_helper'
class TokenAuthenticationTest < ActionController::IntegrationTest
test 'authenticate with valid authentication token key and value through params' do
swap Devise, :token_authentication_key => :secret_token do
sign_in_as_new_user_with_token
assert_response :success
assert_current_url "/users?secret_token=#{VALID_AUTHENTICATION_TOKEN}"
assert_contain 'Welcome'
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through params, when params with the same key as scope exist' do
swap Devise, :token_authentication_key => :secret_token do
user = create_user_with_authentication_token
post exhibit_user_path(user), Devise.token_authentication_key => user.authentication_token, :user => { :some => "data" }
assert_response :success
assert_contain 'User is authenticated'
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key but does not store if stateless' do
swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth] do
sign_in_as_new_user_with_token
assert warden.authenticated?(:user)
get users_path
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through http' do
swap Devise, :token_authentication_key => :secret_token do
sign_in_as_new_user_with_token(:http_auth => true)
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert warden.authenticated?(:user)
end
end
test 'does authenticate with valid authentication token key and value through params if not configured' do
swap Devise, :token_authentication_key => :secret_token, :params_authenticatable => [:database] do
sign_in_as_new_user_with_token
assert_contain 'You need to sign in or sign up before continuing'
assert_contain 'Sign in'
assert_not warden.authenticated?(:user)
end
end
test 'does authenticate with valid authentication token key and value through http if not configured' do
swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => [:database] do
sign_in_as_new_user_with_token(:http_auth => true)
assert_response 401
assert_contain 'Invalid email or password.'
assert_not warden.authenticated?(:user)
end
end
test 'does not authenticate with improper authentication token key' do
swap Devise, :token_authentication_key => :donald_duck_token do
sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
assert_equal new_user_session_path, @request.path
assert_contain 'You need to sign in or sign up before continuing'
assert_contain 'Sign in'
assert_not warden.authenticated?(:user)
end
end
test 'does not authenticate with improper authentication token value' do
store_translations :en, :devise => {:failure => {:invalid_token => 'LOL, that was not a single character correct.'}} do
sign_in_as_new_user_with_token(:auth_token => '*** INVALID TOKEN ***')
assert_equal new_user_session_path, @request.path
assert_contain 'LOL, that was not a single character correct.'
assert_contain 'Sign in'
assert_not warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth], :timeout_in => (0.1).second do
user = sign_in_as_new_user_with_token
assert warden.authenticated?(:user)
# Expiring does not work because we are setting the session value when accessing it
sleep 0.3
get_users_path_as_existing_user(user)
assert warden.authenticated?(:user)
end
end
test 'should reset token and not authenticate when expire_auth_token_on_timeout is set to true, timeoutable is enabled and we have a timed out session' do
swap Devise, :token_authentication_key => :secret_token, :expire_auth_token_on_timeout => true, :timeout_in => (-1).minute do
user = sign_in_as_new_user_with_token
assert warden.authenticated?(:user)
token = user.authentication_token
get_users_path_as_existing_user(user)
assert_not warden.authenticated?(:user)
user.reload
assert_not_equal token, user.authentication_token
end
end
test 'should not be subject to injection' do
swap Devise, :token_authentication_key => :secret_token do
user1 = create_user_with_authentication_token()
# Clean up user cache
@user = nil
user2 = create_user_with_authentication_token(:email => "another@test.com")
user2.update_attribute(:authentication_token, "ANOTHERTOKEN")
assert_not_equal user1, user2
visit users_path(Devise.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
assert_nil warden.user(:user)
end
end
private
def sign_in_as_new_user_with_token(options = {})
user = options.delete(:user) || create_user_with_authentication_token(options)
options[:auth_token_key] ||= Devise.token_authentication_key
options[:auth_token] ||= user.authentication_token
if options[:http_auth]
header = "Basic #{Base64.encode64("#{VALID_AUTHENTICATION_TOKEN}:X")}"
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => header
else
visit users_path(options[:auth_token_key].to_sym => options[:auth_token])
end
user
end
def create_user_with_authentication_token(options={})
user = create_user(options)
user.authentication_token = VALID_AUTHENTICATION_TOKEN
user.save
user
end
def get_users_path_as_existing_user(user)
sign_in_as_new_user_with_token(:user => user)
end
end

View File

@@ -1,6 +1,6 @@
require 'test_helper'
class TrackableHooksTest < ActionController::IntegrationTest
class TrackableHooksTest < ActionDispatch::IntegrationTest
test "current and last sign in timestamps are updated on each sign in" do
user = create_user

View File

@@ -46,6 +46,16 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
assert_equal ['custom@example.com'], mail.from
end
test 'setup sender from custom mailer defaults with proc' do
Devise.mailer = 'Users::FromProcMailer'
assert_equal ['custom@example.com'], mail.from
end
test 'custom mailer renders parent mailer template' do
Devise.mailer = 'Users::Mailer'
assert_not_blank mail.body.encoded
end
test 'setup reply to as copy from sender' do
assert_equal ['test@example.com'], mail.reply_to
end
@@ -56,7 +66,6 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
assert_equal ['custom_reply_to@example.com'], mail.reply_to
end
test 'setup subject from I18n' do
store_translations :en, :devise => { :mailer => { :confirmation_instructions => { :subject => 'Account Confirmation' } } } do
assert_equal 'Account Confirmation', mail.subject
@@ -70,13 +79,17 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
end
test 'body should have user info' do
assert_match /#{user.email}/, mail.body.encoded
assert_match user.email, mail.body.encoded
end
test 'body should have link to confirm the account' do
host = ActionMailer::Base.default_url_options[:host]
confirmation_url_regexp = %r{<a href=\"http://#{host}/users/confirmation\?confirmation_token=#{user.confirmation_token}">}
assert_match confirmation_url_regexp, mail.body.encoded
if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/confirmation\?confirmation_token=([^"]+)">}
assert_equal Devise.token_generator.digest(user.class, :confirmation_token, $1), user.confirmation_token
else
flunk "expected confirmation url regex to match"
end
end
test 'renders a scoped if scoped_views is set to true' do

View File

@@ -1,7 +1,6 @@
require 'test_helper'
class ResetPasswordInstructionsTest < ActionMailer::TestCase
def setup
setup_mailer
Devise.mailer = 'Devise::Mailer'
@@ -49,6 +48,16 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
assert_equal ['custom@example.com'], mail.from
end
test 'setup sender from custom mailer defaults with proc' do
Devise.mailer = 'Users::FromProcMailer'
assert_equal ['custom@example.com'], mail.from
end
test 'custom mailer renders parent mailer template' do
Devise.mailer = 'Users::Mailer'
assert_not_blank mail.body.encoded
end
test 'setup reply to as copy from sender' do
assert_equal ['test@example.com'], mail.reply_to
end
@@ -66,13 +75,17 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
end
test 'body should have user info' do
assert_match(/#{user.email}/, mail.body.encoded)
assert_match user.email, mail.body.encoded
end
test 'body should have link to confirm the account' do
host = ActionMailer::Base.default_url_options[:host]
reset_url_regexp = %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=#{user.reset_password_token}">}
assert_match reset_url_regexp, mail.body.encoded
if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=([^"]+)">}
assert_equal Devise.token_generator.digest(user.class, :reset_password_token, $1), user.reset_password_token
else
flunk "expected reset password url regex to match"
end
end
test 'mailer sender accepts a proc' do

Some files were not shown because too many files have changed in this diff Show More