Compare commits

..

86 Commits

Author SHA1 Message Date
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
chris
a1d83d5d4e passes headers through test helpers' response 2013-08-09 09:51:05 +02:00
Alexander Zaytsev
01bb721c33 Use mapping.fullpath in omniauth callbacks 2013-01-21 19:51:06 +05:00
71 changed files with 616 additions and 862 deletions

View File

@@ -1,9 +1,36 @@
== 3.1.0.rc
### 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_tokens_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 as argument. 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_sanitizier.sanitize(:action)` instead of `devise_parameter_sanitizier.for(:action)`
* 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
@@ -13,17 +40,18 @@
* 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
### 3.0.2
* bug fix
* Skip storage for cookies on unverified requests
== 3.0.1
### 3.0.1
Security announcement: http://blog.plataformatec.com.br/2013/08/csrf-token-fixation-attacks-in-devise/
@@ -34,17 +62,20 @@ Security announcement: http://blog.plataformatec.com.br/2013/08/csrf-token-fixat
* 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
### 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)
* 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`
== 2.2.4
* 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)
@@ -60,25 +91,25 @@ Security announcement: http://blog.plataformatec.com.br/2013/08/csrf-token-fixat
* Fix inheriting mailer templates from `Devise::Mailer`
* Fix a bug when procs are used as default mailer in Devise (by @tomasv)
== 2.2.3
### 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
### 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
@@ -109,7 +140,7 @@ Security announcement: http://blog.plataformatec.com.br/2013/01/security-announc
* `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
@@ -117,7 +148,7 @@ Security announcement: http://blog.plataformatec.com.br/2013/01/security-announc
* 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
@@ -134,7 +165,7 @@ Security announcement: http://blog.plataformatec.com.br/2013/01/security-announc
* 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
@@ -161,7 +192,7 @@ Security announcement: http://blog.plataformatec.com.br/2013/01/security-announc
* 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
@@ -169,7 +200,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
@@ -177,7 +208,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
@@ -189,7 +220,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
@@ -198,7 +229,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)
@@ -224,14 +255,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)
@@ -240,12 +271,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
@@ -266,12 +297,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
@@ -279,12 +310,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
@@ -292,7 +323,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
@@ -300,12 +331,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
@@ -321,12 +352,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
@@ -337,7 +368,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)
@@ -355,22 +386,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)
@@ -379,7 +410,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)
@@ -399,19 +430,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
@@ -441,7 +472,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
@@ -479,13 +510,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
@@ -493,12 +524,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
@@ -509,17 +540,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)
@@ -539,7 +570,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)
@@ -557,7 +588,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
@@ -589,7 +620,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
@@ -598,7 +629,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
@@ -607,14 +638,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.
@@ -622,19 +653,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)
@@ -642,7 +673,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.
@@ -651,7 +682,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
@@ -662,7 +693,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Allow scoped_views to be customized per controller/mailer class
* Allow authenticatable to used in change_table statements
== 0.9.2
### 0.9.2
* bug fix
* Ensure inactive user cannot sign in
@@ -672,13 +703,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
@@ -695,7 +726,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)
@@ -703,7 +734,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
@@ -713,7 +744,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
@@ -727,19 +758,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
@@ -749,7 +780,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!
@@ -759,12 +790,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
@@ -773,25 +804,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
@@ -802,19 +833,19 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Allow a strategy to be placed after authenticatable
* Do not rely attribute? methods, since they are not added on Datamapper
== 0.5.6
### 0.5.6
* enhancements
* 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
* Remove Ruby 1.8.7 dependency
== 0.5.4
### 0.5.4
* deprecations
* Deprecate :singular in devise_for and use :scope instead
@@ -825,7 +856,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* 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
@@ -837,20 +868,20 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* 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
* 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
@@ -860,13 +891,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
* 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
@@ -878,12 +909,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
* 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
@@ -896,7 +927,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Allow Warden::Manager to be configured through Devise
* Created a generator which creates an initializer
== 0.3.0
### 0.3.0
* bug fix
* Allow yml messages to be configured by not using engine locales
@@ -906,7 +937,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* 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
@@ -916,12 +947,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* Do not redirect on invalid authenticate
* Allow model configuration to be set to nil
== 0.2.2
### 0.2.2
* bug fix
* Fix a bug when using customized resources
== 0.2.1
### 0.2.1
* refactor
* Clean devise_views generator to use devise existing views
@@ -933,7 +964,7 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fix
* Fix a bug with Mongrel and Ruby 1.8.6
== 0.2.0
### 0.2.0
* enhancements
* Allow option :null => true in authenticable migration
@@ -948,12 +979,12 @@ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.
* bug fixes
* Fixed requiring devise strategies
== 0.1.1
### 0.1.1
* bug fixes
* Fixed requiring devise mapping
== 0.1.0
### 0.1.0
* Devise::Authenticable
* Devise::Confirmable

View File

@@ -12,7 +12,7 @@ GIT
PATH
remote: .
specs:
devise (3.1.0.rc)
devise (3.2.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@@ -48,7 +48,7 @@ GEM
tzinfo (~> 0.3.37)
arel (4.0.0)
atomic (1.1.12)
bcrypt-ruby (3.1.1)
bcrypt-ruby (3.1.2)
builder (3.1.4)
erubis (2.7.0)
faraday (0.8.8)

View File

@@ -2,7 +2,6 @@
By [Plataformatec](http://plataformatec.com.br/).
[![Gem Version](https://fury-badge.herokuapp.com/rb/devise.png)](http://badge.fury.io/rb/devise)
[![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)
@@ -36,7 +35,7 @@ Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby i
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
@@ -446,7 +445,7 @@ https://github.com/hassox/warden
We have a long list of valued contributors. Check them all at:
https://github.com/plataformatec/devise/contributors
https://github.com/plataformatec/devise/graphs/contributors
## License

View File

@@ -20,8 +20,7 @@ class Devise::ConfirmationsController < DeviseController
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if resource.errors.empty?
set_flash_message(:notice, :confirmed) if is_navigational_format?
sign_in(resource_name, resource) if Devise.allow_insecure_sign_in_after_confirmation
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 }
@@ -37,8 +36,8 @@ class Devise::ConfirmationsController < DeviseController
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
if Devise.allow_insecure_sign_in_after_confirmation
after_sign_in_path_for(resource)
if signed_in?
signed_in_root_path(resource)
else
new_session_path(resource_name)
end

View File

@@ -32,7 +32,7 @@ class Devise::PasswordsController < DeviseController
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_resetting_password_path_for(resource)
else

View File

@@ -14,12 +14,12 @@ class Devise::RegistrationsController < DeviseController
if resource.save
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 +40,8 @@ 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(account_update_params)
if is_navigational_format?
if update_resource(resource, account_update_params)
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 +58,7 @@ 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?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
@@ -68,7 +68,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,6 +80,12 @@ 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)

View File

@@ -1,7 +1,7 @@
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
@@ -13,7 +13,7 @@ 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)
respond_with resource, :location => after_sign_in_path_for(resource)
end
@@ -22,7 +22,7 @@ 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?
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request

View File

@@ -22,7 +22,7 @@ class Devise::UnlocksController < DeviseController
self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
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 }

View File

@@ -123,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
@@ -147,12 +147,16 @@ MESSAGE
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)
options = devise_i18n_options(options)
I18n.t("#{options[:resource_name]}.#{kind}", options)
end

View File

@@ -1,18 +1,20 @@
class Devise::Mailer < Devise.parent_mailer.constantize
include Devise::Mailers::Helpers
if defined?(ActionMailer)
class Devise::Mailer < Devise.parent_mailer.constantize
include Devise::Mailers::Helpers
def confirmation_instructions(record, token, opts={})
@token = token
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, token, opts={})
@token = token
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, token, opts={})
@token = token
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

@@ -3,15 +3,15 @@
en:
devise:
confirmations:
confirmed: "Your account was successfully confirmed. You are now signed in."
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."
invalid_token: "Invalid authentication token."
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."

View File

@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
devise (3.1.0.rc)
devise (3.2.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@@ -39,8 +39,8 @@ GEM
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.2)
atomic (1.1.12)
bcrypt-ruby (3.1.1)
atomic (1.1.14)
bcrypt-ruby (3.1.2)
builder (3.0.4)
erubis (2.7.0)
faraday (0.8.8)
@@ -125,7 +125,7 @@ GEM
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.7)
thor (0.18.1)
thread_safe (0.1.2)
thread_safe (0.1.3)
atomic
tilt (1.4.1)
treetop (1.4.14)

View File

@@ -20,9 +20,14 @@ module Devise
autoload :Helpers, 'devise/controllers/helpers'
autoload :Rememberable, 'devise/controllers/rememberable'
autoload :ScopedViews, 'devise/controllers/scoped_views'
autoload :SignInOut, 'devise/controllers/sign_in_out'
autoload :UrlHelpers, 'devise/controllers/url_helpers'
end
module Hooks
autoload :Proxy, 'devise/hooks/proxy'
end
module Mailers
autoload :Helpers, 'devise/mailers/helpers'
end
@@ -50,15 +55,21 @@ module Devise
mattr_accessor :secret_key
@@secret_key = nil
# Allow insecure token lookup. Must be used
# temporarily just for migration.
mattr_accessor :allow_insecure_token_lookup
@@allow_insecure_tokens_lookup = false
[ :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
# Allow insecure sign in after confirmation. Must be used
# temporarily just for migration.
mattr_accessor :allow_insecure_sign_in_after_confirmation
@@allow_insecure_sign_in_after_confirmation = false
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
@@ -195,10 +206,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 = []
@@ -266,6 +273,10 @@ 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

View File

@@ -3,6 +3,7 @@ module Devise
# Those helpers are convenience methods added to ApplicationController.
module Helpers
extend ActiveSupport::Concern
include Devise::Controllers::SignInOut
included do
helper_method :warden, :signed_in?, :devise_controller?
@@ -96,84 +97,6 @@ module Devise
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, :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_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:
#
@@ -257,10 +180,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)
@@ -275,7 +194,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
@@ -287,10 +206,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,24 +1,14 @@
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"]

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

@@ -64,12 +64,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

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) unless record.failed_attempts.zero?
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

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

@@ -84,11 +84,6 @@ module Devise
devise_modules_hook! do
include Devise::Models::Authenticatable
if selected_modules.include?(:token_authenticatable)
ActiveSupport::Deprecation.warn "devise :token_authenticatable is deprecated. " \
"Please check Devise 3.1 release notes for more information on how to upgrade."
end
selected_modules.each do |m|
mod = Devise::Models.const_get(m.to_s.classify)

View File

@@ -29,9 +29,7 @@ module Devise
# 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?
#
@@ -176,23 +174,24 @@ module Devise
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

View File

@@ -228,11 +228,6 @@ module Devise
generate_confirmation_token && save(:validate => false)
end
def after_password_reset
super
confirm! unless confirmed?
end
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
@@ -280,10 +275,6 @@ module Devise
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
if !confirmable.persisted? && Devise.allow_insecure_token_lookup
confirmable = find_or_initialize_with_error_by(:confirmation_token, original_token)
end
confirmable.confirm! if confirmable.persisted?
confirmable.confirmation_token = original_token
confirmable

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.
@@ -34,7 +39,7 @@ module Devise
# Generates password encryption based on the given value.
def password=(new_password)
@password = new_password
self.encrypted_password = password_digest(@password) if @password.present?
self.encrypted_password = Devise.bcrypt(self.class, @password) if @password.present?
end
# Verifies whether an password (ie from sign in) is the user password.
@@ -96,7 +101,7 @@ module Devise
end
# Destroy record when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects
# 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)
@@ -110,6 +115,16 @@ module Devise
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
@@ -120,11 +135,6 @@ module Devise
protected
# Digests the password using bcrypt.
def password_digest(password)
::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
end
module ClassMethods
Devise::Models.config(self, :pepper, :stretches)

View File

@@ -112,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
@@ -125,6 +127,10 @@ module Devise
self.failed_attempts > self.class.maximum_attempts
end
def last_attempt?
self.failed_attempts == self.class.maximum_attempts
end
# Tells if the lock is expired if :time unlock strategy is active
def lock_expired?
if unlock_strategy_enabled?(:time)
@@ -165,10 +171,6 @@ module Devise
unlock_token = Devise.token_generator.digest(self, :unlock_token, unlock_token)
lockable = find_or_initialize_with_error_by(:unlock_token, unlock_token)
if !lockable.persisted? && Devise.allow_insecure_token_lookup
lockable = find_or_initialize_with_error_by(:unlock_token, original_token)
end
lockable.unlock_access! if lockable.persisted?
lockable.unlock_token = original_token
lockable

View File

@@ -101,11 +101,6 @@ 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
@@ -116,9 +111,6 @@ module Devise
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? && Devise.allow_insecure_token_lookup
recoverable = find_or_initialize_with_error_by(:reset_password_token, original_token)
end
if recoverable.persisted?
if recoverable.reset_password_period_valid?

View File

@@ -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

@@ -1,92 +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
loop do
token = Devise.friendly_token
break token unless to_adapter.find_first({ :authentication_token => token })
end
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

@@ -47,19 +47,25 @@ module Devise
end
def sign_in
default_params.permit self.for(:sign_in)
permit self.for(:sign_in)
end
def sign_up
default_params.permit self.for(:sign_up)
permit self.for(:sign_up)
end
def account_update
default_params.permit self.for(: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)

View File

@@ -35,13 +35,6 @@ module Devise
Devise::TokenGenerator.new(
Devise::CachingKeyGenerator.new(Devise::KeyGenerator.new(secret_key))
)
else
raise <<-ERROR
Devise.secret_key was not set. Please add the following to your Devise initializer:
config.secret_key = '#{SecureRandom.hex(64)}'
ERROR
end
end

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?
@@ -376,8 +386,14 @@ module ActionDispatch::Routing
end
def devise_omniauth_callback(mapping, controllers) #:nodoc:
if mapping.fullpath =~ /:[a-zA-Z_]/
raise "[DEVISE] Nesting omniauth callbacks under scopes with dynamic segments " \
"is not supported. Please, use Devise.omniauth_path_prefix instead."
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))
@@ -434,6 +450,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

@@ -1,91 +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 headers, you can use basic authentication passing 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.
#
# You may also pass the token using the Token authentication mechanism provided
# by Rails: http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
# The token options are stored in request.env['devise.token_options']
class TokenAuthenticatable < Authenticatable
def store?
super && !mapping.to.skip_session_storage.include?(:token_auth)
end
def valid?
super || valid_for_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
# Check if the model accepts this strategy as token authenticatable.
def token_authenticatable?
mapping.to.http_authenticatable?(:token_options)
end
# Check if this is strategy is valid for token authentication by:
#
# * Validating if the model allows http token authentication;
# * If the http auth token exists;
# * If all authentication keys are present;
#
def valid_for_token_auth?
token_authenticatable? && auth_token.present? && with_authentication_hash(:token_auth, token_auth_hash)
end
# Extract the auth token from the request
def auth_token
@auth_token ||= ActionController::HttpAuthentication::Token.token_and_options(request)
end
# Extract a hash with attributes:values from the auth_token
def token_auth_hash
request.env['devise.token_options'] = auth_token.last
{ authentication_keys.first => auth_token.first }
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

@@ -1,3 +1,3 @@
module Devise
VERSION = "3.1.0.rc".freeze
VERSION = "3.2.0".freeze
end

View File

@@ -50,7 +50,7 @@ module ActiveRecord
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
@@ -63,12 +63,9 @@ module ActiveRecord
# 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

@@ -4,8 +4,7 @@ module Devise
def model_contents
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

View File

@@ -47,9 +47,6 @@ 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

View File

@@ -56,12 +56,9 @@ Devise.setup do |config|
# 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. The supported strategies are:
# 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
# :token = Support basic authentication with token authentication key
# :token_options = Support token authentication with options as defined in
# http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
# config.http_authenticatable = false
# If http headers should be returned for AJAX requests. True by default.
@@ -76,7 +73,7 @@ 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
@@ -98,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
@@ -176,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
@@ -196,10 +196,6 @@ Devise.setup do |config|
# 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

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

@@ -55,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
@@ -71,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

@@ -6,7 +6,7 @@ class PasswordsControllerTest < ActionController::TestCase
setup do
request.env["devise.mapping"] = Devise.mappings[:user]
@user = create_user
@user = create_user.tap(&:confirm!)
@raw = @user.send_reset_password_instructions
end

View File

@@ -10,7 +10,7 @@ class SessionsControllerTest < ActionController::TestCase
end
request.env["devise.mapping"] = Devise.mappings[:user]
request.session["user_return_to"] = 'foo.bar'
user = create_user
create_user
post :create, :user => {
:email => "wrong@email.com",
:password => "wrongpassword"

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]

View File

@@ -123,6 +123,16 @@ class ConfirmationTest < ActionDispatch::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" } }

View File

@@ -88,16 +88,6 @@ class HttpAuthenticationTest < ActionDispatch::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

@@ -190,7 +190,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
end
test 'sign in user automatically after changing its password' do
user = create_user
create_user
request_forgot_password
reset_password
@@ -236,15 +236,6 @@ class PasswordTest < ActionDispatch::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
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"}
@@ -269,7 +260,7 @@ class PasswordTest < ActionDispatch::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 => 'abcdef', :password => '987654321', :password_confirmation => '987654321'

View File

@@ -64,14 +64,14 @@ class RememberMeTest < ActionDispatch::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
user = sign_in_as_user :remember_me => true
sign_in_as_user :remember_me => true
assert request.cookies["v1lat_token"]
end
end
@@ -79,7 +79,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
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)

View File

@@ -45,6 +45,20 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
assert_not warden.authenticated?(:user)
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)
@@ -67,6 +81,20 @@ class SessionTimeoutTest < ActionDispatch::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,205 +0,0 @@
require 'test_helper'
class TokenAuthenticationTest < ActionDispatch::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
test 'authenticate with valid authentication token key and value through http header' do
swap Devise, :token_authentication_key => :secret_token do
sign_in_as_new_user_with_token(:token_auth => true)
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert_equal request.env['devise.token_options'], {}
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through http header, with options' do
swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => [:token_options] do
signature = "**TESTSIGNATURE**"
sign_in_as_new_user_with_token(:token_auth => true, :token_options => {:signature => signature, :nonce => 'def'})
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert_equal request.env['devise.token_options'][:signature], signature
assert_equal request.env['devise.token_options'][:nonce], 'def'
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through http header without allowing token authorization setting is denied' do
swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => false do
sign_in_as_new_user_with_token(:token_auth => true)
assert_response :unauthorized
assert_nil warden.user(:user)
end
end
test 'does not authenticate with improper authentication token value in header' do
sign_in_as_new_user_with_token(:token_auth => true, :auth_token => '*** INVALID TOKEN ***')
assert_response :unauthorized
assert_nil warden.user(:user)
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
elsif options[:token_auth]
token_options = options[:token_options] || {}
header = ActionController::HttpAuthentication::Token.encode_credentials(options[:auth_token], token_options)
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

@@ -50,12 +50,12 @@ class MappingTest < ActiveSupport::TestCase
end
test 'has strategies depending on the model declaration' do
assert_equal [:rememberable, :token_authenticatable, :database_authenticatable], Devise.mappings[:user].strategies
assert_equal [:rememberable, :database_authenticatable], Devise.mappings[:user].strategies
assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
end
test 'has no input strategies depending on the model declaration' do
assert_equal [:rememberable, :token_authenticatable], Devise.mappings[:user].no_input_strategies
assert_equal [:rememberable], Devise.mappings[:user].no_input_strategies
assert_equal [], Devise.mappings[:admin].no_input_strategies
end

View File

@@ -51,15 +51,6 @@ class ConfirmableTest < ActiveSupport::TestCase
assert_equal "was already confirmed, please try signing in", user.errors[:email].join
end
test 'DEPRECATED: should find and confirm a user automatically' do
swap Devise, allow_insecure_token_lookup: true do
user = create_user
confirmed_user = User.confirm_by_token(user.confirmation_token)
assert_equal confirmed_user, user
assert user.reload.confirmed?
end
end
test 'should find and confirm a user automatically based on the raw token' do
user = create_user
raw = user.raw_confirmation_token

View File

@@ -24,6 +24,15 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
assert_equal confirmation.downcase, user.email_confirmation
end
test 'should not mutate value assigned to case insensitive key' do
email = 'Foo@Bar.com'
original_email = email.dup
user = new_user(:email => email)
user.save!
assert_equal original_email, email
end
test 'should remove whitespace from strip whitespace keys when saving' do
# strip_whitespace_keys is set to :email by default.
email = ' foo@bar.com '
@@ -34,6 +43,15 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
assert_equal email.strip, user.email
end
test 'should not mutate value assigned to string whitespace key' do
email = ' foo@bar.com '
original_email = email.dup
user = new_user(:email => email)
user.save!
assert_equal original_email, email
end
test "doesn't throw exception when globally configured strip_whitespace_keys are not present on a model" do
swap Devise, :strip_whitespace_keys => [:fake_key] do
assert_nothing_raised { create_user }
@@ -203,7 +221,7 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
end
test 'downcase_keys with validation' do
user = User.create(:email => "HEllO@example.com", :password => "123456")
User.create(:email => "HEllO@example.com", :password => "123456")
user = User.create(:email => "HEllO@example.com", :password => "123456")
assert !user.valid?
end

View File

@@ -139,16 +139,6 @@ class LockableTest < ActiveSupport::TestCase
end
end
test 'DEPRECATED: should find and unlock a user automatically' do
swap Devise, allow_insecure_token_lookup: true do
user = create_user
user.lock_access!
locked_user = User.unlock_access_by_token(user.unlock_token)
assert_equal locked_user, user
assert_not user.reload.access_locked?
end
end
test 'should find and unlock a user automatically based on raw token' do
user = create_user
raw = user.send_unlock_instructions
@@ -289,4 +279,20 @@ class LockableTest < ActiveSupport::TestCase
assert_equal :invalid, user.unauthenticated_message
end
end
test 'should return last attempt message if user made next-to-last attempt of password entering' do
swap Devise, :last_attempt_warning => :true do
swap Devise, :lock_strategy => :failed_attempts do
user = create_user
user.failed_attempts = Devise.maximum_attempts - 1
assert_equal :invalid, user.unauthenticated_message
user.failed_attempts = Devise.maximum_attempts
assert_equal :last_attempt, user.unauthenticated_message
user.failed_attempts = Devise.maximum_attempts + 1
assert_equal :locked, user.unauthenticated_message
end
end
end
end

View File

@@ -108,16 +108,6 @@ class RecoverableTest < ActiveSupport::TestCase
end
end
test 'DEPRECATED: should find a user to reset his password based on reset_password_token' do
swap Devise, allow_insecure_token_lookup: true do
user = create_user
user.send_reset_password_instructions
reset_password_user = User.reset_password_by_token(:reset_password_token => user.reset_password_token)
assert_equal reset_password_user, user
end
end
test 'should find a user to reset his password based on the raw token' do
user = create_user
raw = user.send_reset_password_instructions

View File

@@ -22,6 +22,14 @@ class RememberableTest < ActiveSupport::TestCase
user.forget_me!
end
test 'can generate remember token' do
user = create_user
user.singleton_class.send(:attr_accessor, :remember_token)
User.to_adapter.expects(:find_first).returns(nil)
user.remember_me!
assert user.remember_token
end
test 'serialize into cookie' do
user = create_user
user.remember_me!

View File

@@ -1,55 +0,0 @@
require 'test_helper'
class TokenAuthenticatableTest < ActiveSupport::TestCase
test 'should reset authentication token' do
user = new_user
user.reset_authentication_token
previous_token = user.authentication_token
user.reset_authentication_token
assert_not_equal previous_token, user.authentication_token
end
test 'should ensure authentication token' do
user = new_user
user.ensure_authentication_token
previous_token = user.authentication_token
user.ensure_authentication_token
assert_equal previous_token, user.authentication_token
end
test 'should authenticate a valid user with authentication token and return it' do
user = create_user
user.ensure_authentication_token!
user.confirm!
authenticated_user = User.find_for_token_authentication(:auth_token => user.authentication_token)
assert_equal authenticated_user, user
end
test 'should return nil when authenticating an invalid user by authentication token' do
user = create_user
user.ensure_authentication_token!
user.confirm!
authenticated_user = User.find_for_token_authentication(:auth_token => user.authentication_token.reverse)
assert_nil authenticated_user
end
test 'should not be subject to injection' do
user1 = create_user
user1.ensure_authentication_token!
user1.confirm!
user2 = create_user
user2.ensure_authentication_token!
user2.confirm!
user = User.find_for_token_authentication(:auth_token => {'$ne' => user1.authentication_token})
assert_nil user
end
test 'required_fields should contain the fields that Devise uses' do
assert_same_content Devise::Models::TokenAuthenticatable.required_fields(User), [
:authentication_token
]
end
end

View File

@@ -68,5 +68,14 @@ if defined?(ActionController::StrongParameters)
sanitizer.sanitize(:unknown)
end
end
test 'passes parameters to filter as arguments to sanitizer' do
params = {user: stub}
sanitizer = Devise::ParameterSanitizer.new(User, :user, params)
params[:user].expects(:permit).with(kind_of(Symbol), kind_of(Symbol), kind_of(Symbol))
sanitizer.sanitize(:sign_in)
end
end
end

View File

@@ -36,7 +36,4 @@ class User
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
end

View File

@@ -33,9 +33,6 @@ class CreateTables < ActiveRecord::Migration
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
## Token authenticatable
t.string :authentication_token
t.timestamps
end

View File

@@ -44,7 +44,6 @@ ActiveRecord::Schema.define(:version => 20100401102949) do
t.integer "failed_attempts", :default => 0
t.string "unlock_token"
t.datetime "locked_at"
t.string "authentication_token"
t.datetime "created_at"
t.datetime "updated_at"
end

View File

@@ -3,7 +3,7 @@ module SharedUser
included do
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
:registerable, :rememberable, :timeoutable, :token_authenticatable,
:registerable, :rememberable, :timeoutable,
:trackable, :validatable, :omniauthable
attr_accessor :other_key

View File

@@ -1,4 +1,8 @@
en:
devise:
failure:
user:
does_not_exist: "User %{name} does not exist"
errors:
messages:
taken: "has already been taken"

View File

@@ -148,4 +148,26 @@ class TestHelpersTest < ActionController::TestCase
get :index
assert_match /User ##{second_user.id}/, @response.body
end
test "passes given headers from the failure app to the response" do
begin
old_failure_app = Devise.warden_config[:failure_app]
class CustomTestFailureApp < Devise::FailureApp
def respond
self.status = 401
self.response.headers["CUSTOMHEADER"] = 1
end
end
Devise.warden_config[:failure_app] = CustomTestFailureApp
user = create_user
sign_in user
get :index
assert_equal 1, @response.headers["CUSTOMHEADER"]
ensure
Devise.warden_config[:failure_app] = old_failure_app
end
end
end