mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 23:58:06 -05:00
Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86f0bff332 | ||
|
|
30ab6f923d | ||
|
|
839e8fc8ac | ||
|
|
4c83743263 | ||
|
|
e1fde192f2 | ||
|
|
73389ea491 | ||
|
|
eeb6a30752 | ||
|
|
01669c7374 | ||
|
|
ac3a25bf2e | ||
|
|
0652117c79 | ||
|
|
2261005ed5 | ||
|
|
e80e0c9a89 | ||
|
|
79e9d6e564 | ||
|
|
0c6f2adf14 | ||
|
|
77ec1b08cd | ||
|
|
2be9fb292e | ||
|
|
88dba417ef | ||
|
|
b98f021d0f | ||
|
|
c026b5a3f6 | ||
|
|
3696cbf33e | ||
|
|
cbfdcbeaed | ||
|
|
130d684198 | ||
|
|
f0f3e15c08 | ||
|
|
19a1ea5211 | ||
|
|
6c2c808478 | ||
|
|
adc9a45f05 | ||
|
|
50186474d4 | ||
|
|
ffab77c35e | ||
|
|
cde2229e59 | ||
|
|
397fce1f9d | ||
|
|
f044916f94 | ||
|
|
0415564a7d | ||
|
|
ed6f2abc23 | ||
|
|
96a0477555 | ||
|
|
da5464acf6 | ||
|
|
1c8fc18fad | ||
|
|
fbf667e009 | ||
|
|
071ba358a9 | ||
|
|
ef4db2e93d | ||
|
|
6a2ef52aa0 | ||
|
|
d821275588 | ||
|
|
59966e817c | ||
|
|
b1df686a2e | ||
|
|
ae426dcc1c | ||
|
|
1646684af9 | ||
|
|
ac58c28617 | ||
|
|
7d72121bd7 | ||
|
|
10235f9d72 | ||
|
|
5d311e7557 | ||
|
|
5d86327e4d | ||
|
|
61903b534a | ||
|
|
ee61d86546 | ||
|
|
06a2cff140 | ||
|
|
2f36d0dd32 | ||
|
|
d5a2a9b2da | ||
|
|
8ee1591868 | ||
|
|
18c377e0d7 | ||
|
|
00a01c2bc4 | ||
|
|
00e8841e93 | ||
|
|
f79bb31ee6 | ||
|
|
d6449d014e | ||
|
|
b853871667 | ||
|
|
f796439cf2 | ||
|
|
692175b897 | ||
|
|
68dc20cba2 | ||
|
|
90dbae4c7a | ||
|
|
564e588f5e | ||
|
|
8f4b06542e | ||
|
|
7513512000 | ||
|
|
7b04ecdddb | ||
|
|
50338b34f9 | ||
|
|
75268bed5c | ||
|
|
e873e2aeed | ||
|
|
b27491061e | ||
|
|
9e096a4113 | ||
|
|
8c7bf7dd15 | ||
|
|
f7dd59839c | ||
|
|
84c4759f58 | ||
|
|
e345d3940c | ||
|
|
d59301ed2a | ||
|
|
48751783a7 | ||
|
|
691172d01f | ||
|
|
eb51d0365f | ||
|
|
422bf89182 | ||
|
|
4962fbcb51 | ||
|
|
be2b481385 | ||
|
|
d169ef3641 | ||
|
|
2a64972321 | ||
|
|
33fac7f765 | ||
|
|
5c2e3e1a12 | ||
|
|
4a24667e80 | ||
|
|
c3d9dc3007 | ||
|
|
df0a9401b1 | ||
|
|
f7f086faae | ||
|
|
6ae64b1723 | ||
|
|
7d41072c0e | ||
|
|
2f75b12add | ||
|
|
352dd1f2fc | ||
|
|
bdf0bc7b1e | ||
|
|
b1f490a2f8 | ||
|
|
73f617db7b | ||
|
|
1da8490dbc | ||
|
|
6e79c5c242 | ||
|
|
f4db03d31c | ||
|
|
8bc1096099 | ||
|
|
a23247d431 | ||
|
|
6a37945025 | ||
|
|
dcada8fe75 | ||
|
|
f80cecc864 | ||
|
|
1d6ee13aae | ||
|
|
01d3ed7172 | ||
|
|
a1411c885f | ||
|
|
6e48fcee76 | ||
|
|
42a0c30139 | ||
|
|
87f2fa9767 | ||
|
|
8463c6dce4 | ||
|
|
9b77ac0cab | ||
|
|
0afae74386 | ||
|
|
56c1ab0824 | ||
|
|
1ec23994f2 | ||
|
|
2950434ed3 | ||
|
|
1aca139c65 | ||
|
|
fa451306fc | ||
|
|
c179cef365 | ||
|
|
1579ec9a87 | ||
|
|
cbc6926e3d | ||
|
|
9678b422ff | ||
|
|
d1bf31729d | ||
|
|
a89a2052b8 | ||
|
|
6c80839e7b | ||
|
|
972ac3b5f0 | ||
|
|
caa8961938 | ||
|
|
619826fbc8 | ||
|
|
fe62d1bf6a | ||
|
|
95f20587ef | ||
|
|
8171ad39e0 | ||
|
|
0c9b79947d | ||
|
|
4c9680787d | ||
|
|
6eeb9e4b7d | ||
|
|
80b2240ef0 | ||
|
|
2f142724c5 |
26
.travis.yml
26
.travis.yml
@@ -1,12 +1,38 @@
|
||||
language: ruby
|
||||
script: "bundle exec rake test"
|
||||
rvm:
|
||||
- 1.8.7
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
- ree
|
||||
env:
|
||||
- DEVISE_ORM=mongoid
|
||||
- DEVISE_ORM=active_record
|
||||
matrix:
|
||||
exclude:
|
||||
- rvm: ree
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: Gemfile
|
||||
- rvm: ree
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: gemfiles/Gemfile.rails-3.1.x
|
||||
- rvm: 1.8.7
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: Gemfile
|
||||
- rvm: 1.8.7
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: gemfiles/Gemfile.rails-3.1.x
|
||||
- rvm: 1.9.2
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: Gemfile
|
||||
- rvm: 1.9.2
|
||||
env: DEVISE_ORM=mongoid
|
||||
gemfile: gemfiles/Gemfile.rails-3.1.x
|
||||
gemfile:
|
||||
- gemfiles/Gemfile.rails-3.1.x
|
||||
- Gemfile
|
||||
services:
|
||||
- mongodb
|
||||
notifications:
|
||||
recipients:
|
||||
- jose.valim@plataformatec.com.br
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
== 2.2.0.rc
|
||||
|
||||
* important changes
|
||||
* Default minimum password length is now 8 (by @carlosgaldino)
|
||||
* Support alternate sign in error message when email record does not exist (this adds a new I18n key to the locale file) (@gabetax)
|
||||
* DeviseController responds only to HTML requests by default (call `DeviseController.respond_to` or `ApplicationController.respond_to` to add new formats)
|
||||
* Support Mongoid 3 onwards (by @durran)
|
||||
* Fix unlockable which could leak account existence on paranoid mode (by @latortuga)
|
||||
|
||||
* enhancements
|
||||
* Confirmable now has a confirm_within option to set a period while the confirmation token is still valid (by @promisedlandt)
|
||||
* Flash messages in controller now respects `resource_name` (by @latortuga)
|
||||
* Separate `sign_in` and `sign_up` on RegistrationsController (by @rubynortheast)
|
||||
* Add autofocus to default views (by @Radagaisus)
|
||||
* Unlock user on password reset (by @marcinb)
|
||||
* Allow validation callbacks to apply to virtual attributes (by @latortuga)
|
||||
|
||||
* bug fix
|
||||
* unconfirmed_email now uses the proper e-mail on salutation
|
||||
* Fix default email_regexp config to not allow spaces (by @kukula)
|
||||
* Fix a regression introduced on warden 1.2.1 (by @ejfinneran)
|
||||
* Properly camelize omniauth strategies (by @saizai)
|
||||
* Do not set flash messages for non navigational requests on session sign out (by @mathieul)
|
||||
* Set the proper fields as required on the lockable module (by @nickhoffman)
|
||||
* Respects Devise mailer default's reply_to (by @mrchrisadams)
|
||||
* Properly assign resource on `sign_in` related action (by @adammcnamara)
|
||||
* `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
|
||||
|
||||
* Enhancements
|
||||
* enhancements
|
||||
* Handle backwards incompatibility between Rails 3.2.6 and Thor 0.15.x
|
||||
|
||||
* bug fix
|
||||
|
||||
14
CONTRIBUTING.md
Normal file
14
CONTRIBUTING.md
Normal file
@@ -0,0 +1,14 @@
|
||||
### Please read before contributing
|
||||
|
||||
1) Do not post questions in the issues tracker. If you have any questions about Devise, search the [Wiki](https://github.com/plataformatec/devise/wiki) or use the [Mailing List](https://groups.google.com/group/plataformatec-devise) or [Stack Overflow](http://stackoverflow.com/questions/tagged/devise).
|
||||
|
||||
2) If you find a security bug, **DO NOT** submit an issue here. Please send an e-mail to [developers@plataformatec.com.br](mailto:developers@plataformatec.com.br) instead.
|
||||
|
||||
3) Do a small search on the issues tracker before submitting your issue to see if it was already reported / fixed.
|
||||
|
||||
4) When reporting an issue, include Rails, Devise and Warden versions. If you are getting exceptions, please include the full backtrace.
|
||||
|
||||
That's it! The more information you give, the easier it becomes for us to track it down and fix it.
|
||||
Ideally, you should provide an application that reproduces the error or a test case to Devise's suite.
|
||||
|
||||
Thanks!
|
||||
10
Gemfile
10
Gemfile
@@ -11,11 +11,7 @@ group :test do
|
||||
gem "omniauth-facebook"
|
||||
gem "omniauth-openid", "~> 1.0.1"
|
||||
gem "webrat", "0.7.2", :require => false
|
||||
gem "mocha", :require => false
|
||||
|
||||
platforms :mri_18 do
|
||||
gem "ruby-debug", ">= 0.10.3"
|
||||
end
|
||||
gem "mocha", "0.10.0", :require => false
|
||||
end
|
||||
|
||||
platforms :jruby do
|
||||
@@ -28,8 +24,6 @@ platforms :ruby do
|
||||
gem "sqlite3"
|
||||
|
||||
group :mongoid do
|
||||
gem "mongo", "~> 1.3.0"
|
||||
gem "mongoid", "~> 2.0"
|
||||
gem "bson_ext", "~> 1.3.0"
|
||||
gem "mongoid", "~> 3.0"
|
||||
end
|
||||
end
|
||||
|
||||
143
Gemfile.lock
143
Gemfile.lock
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
devise (2.1.2)
|
||||
devise (2.2.0.rc)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
@@ -10,84 +10,83 @@ PATH
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.6)
|
||||
actionpack (= 3.2.6)
|
||||
actionmailer (3.2.9)
|
||||
actionpack (= 3.2.9)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.6)
|
||||
activemodel (= 3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
actionpack (3.2.9)
|
||||
activemodel (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.1)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.0)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.1.3)
|
||||
activemodel (3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.6)
|
||||
activemodel (= 3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
activerecord (3.2.9)
|
||||
activemodel (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.6)
|
||||
activemodel (= 3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
activesupport (3.2.6)
|
||||
activeresource (3.2.9)
|
||||
activemodel (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
activesupport (3.2.9)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
addressable (2.2.6)
|
||||
arel (3.0.2)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bson (1.5.1)
|
||||
bson_ext (1.3.1)
|
||||
builder (3.0.0)
|
||||
columnize (0.3.5)
|
||||
builder (3.0.4)
|
||||
erubis (2.7.0)
|
||||
faraday (0.7.5)
|
||||
addressable (~> 2.2.6)
|
||||
multipart-post (~> 1.1.3)
|
||||
rack (>= 1.1.0, < 2)
|
||||
faraday (0.8.4)
|
||||
multipart-post (~> 1.1)
|
||||
hashie (1.2.0)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.0)
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.1)
|
||||
journey (1.0.4)
|
||||
json (1.7.3)
|
||||
linecache (0.46)
|
||||
rbx-require-relative (> 0.0.4)
|
||||
json (1.7.5)
|
||||
jwt (0.1.5)
|
||||
multi_json (>= 1.0)
|
||||
mail (2.4.4)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.1)
|
||||
mime-types (1.18)
|
||||
mime-types (1.19)
|
||||
mocha (0.10.0)
|
||||
metaclass (~> 0.0.1)
|
||||
mongo (1.3.1)
|
||||
bson (>= 1.3.1)
|
||||
mongoid (2.3.4)
|
||||
mongoid (3.0.14)
|
||||
activemodel (~> 3.1)
|
||||
mongo (~> 1.3)
|
||||
moped (~> 1.1)
|
||||
origin (~> 1.0)
|
||||
tzinfo (~> 0.3.22)
|
||||
multi_json (1.0.4)
|
||||
multipart-post (1.1.4)
|
||||
nokogiri (1.5.0)
|
||||
oauth2 (0.5.1)
|
||||
faraday (~> 0.7.4)
|
||||
multi_json (~> 1.0.3)
|
||||
omniauth (1.0.1)
|
||||
moped (1.3.1)
|
||||
multi_json (1.4.0)
|
||||
multipart-post (1.1.5)
|
||||
nokogiri (1.5.5)
|
||||
oauth2 (0.8.0)
|
||||
faraday (~> 0.8)
|
||||
httpauth (~> 0.1)
|
||||
jwt (~> 0.1.4)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.2)
|
||||
omniauth (1.0.3)
|
||||
hashie (~> 1.2)
|
||||
rack
|
||||
omniauth-facebook (1.0.0)
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
omniauth-oauth2 (1.0.0)
|
||||
oauth2 (~> 0.5.0)
|
||||
omniauth-facebook (1.4.0)
|
||||
omniauth-oauth2 (~> 1.0.2)
|
||||
omniauth-oauth2 (1.0.3)
|
||||
oauth2 (~> 0.8.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
orm_adapter (0.1.0)
|
||||
origin (1.0.11)
|
||||
orm_adapter (0.4.0)
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.2)
|
||||
@@ -97,44 +96,39 @@ GEM
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-ssl (1.3.2)
|
||||
rack
|
||||
rack-test (0.6.1)
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.6)
|
||||
actionmailer (= 3.2.6)
|
||||
actionpack (= 3.2.6)
|
||||
activerecord (= 3.2.6)
|
||||
activeresource (= 3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
rails (3.2.9)
|
||||
actionmailer (= 3.2.9)
|
||||
actionpack (= 3.2.9)
|
||||
activerecord (= 3.2.9)
|
||||
activeresource (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.6)
|
||||
railties (3.2.6)
|
||||
actionpack (= 3.2.6)
|
||||
activesupport (= 3.2.6)
|
||||
railties (= 3.2.9)
|
||||
railties (3.2.9)
|
||||
actionpack (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (0.9.2.2)
|
||||
rbx-require-relative (0.0.5)
|
||||
rake (10.0.2)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
ruby-debug (0.10.4)
|
||||
columnize (>= 0.1)
|
||||
ruby-debug-base (~> 0.10.4.0)
|
||||
ruby-debug-base (0.10.4)
|
||||
linecache (>= 0.3)
|
||||
ruby-openid (2.1.8)
|
||||
sprockets (2.1.3)
|
||||
ruby-openid (2.2.2)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.5)
|
||||
thor (0.15.2)
|
||||
sqlite3 (1.3.6)
|
||||
thor (0.16.0)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.10)
|
||||
treetop (1.4.12)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.33)
|
||||
tzinfo (0.3.35)
|
||||
warden (1.2.1)
|
||||
rack (>= 1.0)
|
||||
webrat (0.7.2)
|
||||
@@ -148,18 +142,15 @@ PLATFORMS
|
||||
DEPENDENCIES
|
||||
activerecord-jdbc-adapter
|
||||
activerecord-jdbcsqlite3-adapter
|
||||
bson_ext (~> 1.3.0)
|
||||
devise!
|
||||
jruby-openssl
|
||||
mocha
|
||||
mongo (~> 1.3.0)
|
||||
mongoid (~> 2.0)
|
||||
mocha (= 0.10.0)
|
||||
mongoid (~> 3.0)
|
||||
omniauth (~> 1.0.0)
|
||||
omniauth-facebook
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
omniauth-openid (~> 1.0.1)
|
||||
rails (~> 3.2.6)
|
||||
rdoc
|
||||
ruby-debug (>= 0.10.3)
|
||||
sqlite3
|
||||
webrat (= 0.7.2)
|
||||
|
||||
24
README.md
24
README.md
@@ -1,10 +1,10 @@
|
||||
*IMPORTANT:* Devise 2.1 is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.1
|
||||
|
||||
## Devise
|
||||
|
||||
INFO: This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).
|
||||
[](http://travis-ci.org/plataformatec/devise)
|
||||
[](https://codeclimate.com/github/plataformatec/devise)
|
||||
[](http://badge.fury.io/rb/devise)
|
||||
|
||||
[](http://travis-ci.org/plataformatec/devise) [](https://codeclimate.com/github/plataformatec/devise)
|
||||
This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).
|
||||
|
||||
Devise is a flexible authentication solution for Rails based on Warden. It:
|
||||
|
||||
@@ -108,7 +108,7 @@ The generator will install an initializer which describes ALL Devise's configura
|
||||
rails generate devise MODEL
|
||||
```
|
||||
|
||||
Replace MODEL by the class name used for the applications users, it's frequently 'User' but could also be 'Admin'. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run "rake db:migrate" as the generator will have created a migration file (if your ORM supports them). This generator also configures your config/routes.rb file to point to Devise controller.
|
||||
Replace MODEL by the class name used for the applications users, it's frequently 'User' but could also be 'Admin'. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run "rake db:migrate" as the generator will have created a migration file (if your ORM supports them). This generator also configures your config/routes.rb file to point to the Devise controller.
|
||||
|
||||
Note that you should re-start your app here if you've already started it. Otherwise you'll run into strange errors like users being unable to login and the route helpers being undefined.
|
||||
|
||||
@@ -240,14 +240,14 @@ devise_for :admins, :controllers => { :sessions => "admins/sessions" }
|
||||
|
||||
3) And since we changed the controller, it won't use the "devise/sessions" views, so remember to copy "devise/sessions" to "admin/sessions".
|
||||
|
||||
Remember that Devise uses flash messages to let users know if sign in was successful or failed. Devise expects your application to call "flash[:notice]" and "flash[:alert]" as appropriate.
|
||||
Remember that Devise uses flash messages to let users know if sign in was successful or failed. Devise expects your application to call "flash[:notice]" and "flash[:alert]" as appropriate. Do not print the entire flash hash, print specific keys or at least remove the `:timedout` key from the hash as Devise adds this key in some circumstances, this key is not meant for display.
|
||||
|
||||
### Configuring routes
|
||||
|
||||
Devise also ships with default routes. If you need to customize them, you should probably be able to do it through the devise_for method. It accepts several options like :class_name, :path_prefix and so on, including the possibility to change path names for I18n:
|
||||
|
||||
```ruby
|
||||
devise_for :users, :path => "usuarios", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
|
||||
devise_for :users, :path => "auth", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
|
||||
```
|
||||
|
||||
Be sure to check `devise_for` documentation for details.
|
||||
@@ -304,7 +304,7 @@ https://github.com/plataformatec/devise/wiki/I18n
|
||||
|
||||
### Test helpers
|
||||
|
||||
Devise includes some tests helpers for functional specs. In other to use them, you need to include Devise in your functional tests by adding the following to the bottom of your `test/test_helper.rb` file:
|
||||
Devise includes some tests helpers for functional specs. In order to use them, you need to include Devise in your functional tests by adding the following to the bottom of your `test/test_helper.rb` file:
|
||||
|
||||
```ruby
|
||||
class ActionController::TestCase
|
||||
@@ -341,7 +341,13 @@ There are two things that is important to keep in mind:
|
||||
|
||||
### Omniauth
|
||||
|
||||
Devise comes with Omniauth support out of the box to authenticate from other providers. You can read more about Omniauth support in the wiki:
|
||||
Devise comes with Omniauth support out of the box to authenticate with other providers. To use it, just specify your omniauth configuration in `config/initializers/devise.rb`:
|
||||
|
||||
```ruby
|
||||
config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
|
||||
```
|
||||
|
||||
You can read more about Omniauth support in the wiki:
|
||||
|
||||
* https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class Devise::OmniauthCallbacksController < DeviseController
|
||||
end
|
||||
|
||||
def failure
|
||||
set_flash_message :alert, :failure, :kind => failed_strategy.name.to_s.humanize, :reason => failure_message
|
||||
set_flash_message :alert, :failure, :kind => OmniAuth::Utils.camelize(failed_strategy.name), :reason => failure_message
|
||||
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||
end
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class Devise::PasswordsController < DeviseController
|
||||
self.resource = resource_class.reset_password_by_token(resource_params)
|
||||
|
||||
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?
|
||||
sign_in(resource_name, resource)
|
||||
@@ -53,4 +54,12 @@ class Devise::PasswordsController < DeviseController
|
||||
redirect_to new_session_path(resource_name)
|
||||
end
|
||||
end
|
||||
|
||||
# Check if proper Lockable module methods are present & unlock strategy
|
||||
# allows to unlock resource on password reset
|
||||
def unlockable?(resource)
|
||||
resource.respond_to?(:unlock_access!) &&
|
||||
resource.respond_to?(:unlock_strategy_enabled?) &&
|
||||
resource.unlock_strategy_enabled?(:email)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ class Devise::RegistrationsController < DeviseController
|
||||
if resource.save
|
||||
if resource.active_for_authentication?
|
||||
set_flash_message :notice, :signed_up if is_navigational_format?
|
||||
sign_in(resource_name, resource)
|
||||
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?
|
||||
@@ -38,13 +38,13 @@ class Devise::RegistrationsController < DeviseController
|
||||
# the current user in place.
|
||||
def update
|
||||
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
|
||||
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
|
||||
|
||||
if resource.update_with_password(resource_params)
|
||||
if is_navigational_format?
|
||||
if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
|
||||
flash_key = :update_needs_confirmation
|
||||
end
|
||||
set_flash_message :notice, flash_key || :updated
|
||||
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
|
||||
:update_needs_confirmation : :updated
|
||||
set_flash_message :notice, flash_key
|
||||
end
|
||||
sign_in resource_name, resource, :bypass => true
|
||||
respond_with resource, :location => after_update_path_for(resource)
|
||||
@@ -74,6 +74,12 @@ class Devise::RegistrationsController < DeviseController
|
||||
|
||||
protected
|
||||
|
||||
def update_needs_confirmation?(resource, previous)
|
||||
resource.respond_to?(:pending_reconfirmation?) &&
|
||||
resource.pending_reconfirmation? &&
|
||||
previous != resource.unconfirmed_email
|
||||
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)
|
||||
@@ -81,6 +87,12 @@ class Devise::RegistrationsController < DeviseController
|
||||
self.resource = resource_class.new_with_session(hash, session)
|
||||
end
|
||||
|
||||
# Signs in a user on sign up. You can overwrite this method in your own
|
||||
# RegistrationsController.
|
||||
def sign_up(resource_name, resource)
|
||||
sign_in(resource_name, resource)
|
||||
end
|
||||
|
||||
# The path used after sign up. You need to overwrite this method
|
||||
# in your own RegistrationsController.
|
||||
def after_sign_up_path_for(resource)
|
||||
|
||||
@@ -5,14 +5,14 @@ class Devise::SessionsController < DeviseController
|
||||
|
||||
# GET /resource/sign_in
|
||||
def new
|
||||
resource = build_resource(nil, :unsafe => true)
|
||||
self.resource = build_resource(nil, :unsafe => true)
|
||||
clean_up_passwords(resource)
|
||||
respond_with(resource, serialize_options(resource))
|
||||
end
|
||||
|
||||
# POST /resource/sign_in
|
||||
def create
|
||||
resource = warden.authenticate!(auth_options)
|
||||
self.resource = warden.authenticate!(auth_options)
|
||||
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
||||
sign_in(resource_name, resource)
|
||||
respond_with resource, :location => after_sign_in_path_for(resource)
|
||||
@@ -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
|
||||
set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
|
||||
|
||||
# We actually need to hardcode this as Rails default responder doesn't
|
||||
# support returning empty response on GET request
|
||||
|
||||
@@ -10,7 +10,7 @@ class DeviseController < Devise.parent_controller.constantize
|
||||
helper_method *helpers
|
||||
|
||||
prepend_before_filter :assert_is_devise_resource!
|
||||
respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
|
||||
respond_to :html if mimes_for_respond_to.empty?
|
||||
|
||||
# Gets the actual resource stored in the instance variable
|
||||
def resource
|
||||
@@ -72,7 +72,7 @@ This may happen for two reasons:
|
||||
|
||||
2) You are testing a Devise controller bypassing the router.
|
||||
If so, you can explicitly tell Devise which mapping to use:
|
||||
|
||||
|
||||
@request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
|
||||
MESSAGE
|
||||
@@ -168,7 +168,7 @@ MESSAGE
|
||||
options[:default] = Array(options[:default]).unshift(kind.to_sym)
|
||||
options[:resource_name] = resource_name
|
||||
options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
|
||||
message = I18n.t("#{resource_name}.#{kind}", options)
|
||||
message = I18n.t("#{options[:resource_name]}.#{kind}", options)
|
||||
flash[key] = message if message.present?
|
||||
end
|
||||
|
||||
@@ -181,12 +181,4 @@ MESSAGE
|
||||
format.any(*navigational_formats, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def request_format
|
||||
@request_format ||= request.format.try(:ref)
|
||||
end
|
||||
|
||||
def is_navigational_format?
|
||||
Devise.navigational_formats.include?(request.format.try(:ref))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.submit "Resend confirmation instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<p>Welcome <%= @resource.email %>!</p>
|
||||
<p>Welcome <%= @email %>!</p>
|
||||
|
||||
<p>You can confirm your account email through the link below:</p>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<p>Hello <%= @resource.email %>!</p>
|
||||
|
||||
<p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
|
||||
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
|
||||
|
||||
<p>Click the link below to unlock your account:</p>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<%= f.hidden_field :reset_password_token %>
|
||||
|
||||
<div><%= f.label :password, "New password" %><br />
|
||||
<%= f.password_field :password %></div>
|
||||
<%= f.password_field :password, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
|
||||
<%= f.password_field :password_confirmation %></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.submit "Send me reset password instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<% if resource.class.reconfirmable && resource.unconfirmed_email.present? %>
|
||||
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
|
||||
<% end %>
|
||||
|
||||
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
|
||||
<%= f.password_field :password, :autocomplete => "off" %></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.label :password %><br />
|
||||
<%= f.password_field :password %></div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.label :password %><br />
|
||||
<%= f.password_field :password %></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email %></div>
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.submit "Resend unlock instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
@@ -10,6 +10,7 @@ en:
|
||||
not_saved:
|
||||
one: "1 error prohibited this %{resource} from being saved:"
|
||||
other: "%{count} errors prohibited this %{resource} from being saved:"
|
||||
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
|
||||
|
||||
devise:
|
||||
failure:
|
||||
@@ -17,6 +18,7 @@ en:
|
||||
unauthenticated: 'You need to sign in or sign up before continuing.'
|
||||
unconfirmed: 'You have to confirm your account before continuing.'
|
||||
locked: 'Your account is locked.'
|
||||
not_found_in_database: 'Invalid email or password.'
|
||||
invalid: 'Invalid email or password.'
|
||||
invalid_token: 'Invalid authentication token.'
|
||||
timeout: 'Your session expired, please sign in again to continue.'
|
||||
|
||||
@@ -28,8 +28,6 @@ platforms :ruby do
|
||||
gem "sqlite3"
|
||||
|
||||
group :mongoid do
|
||||
gem "mongo", "~> 1.3.0"
|
||||
gem "mongoid", "~> 2.0"
|
||||
gem "bson_ext", "~> 1.3.0"
|
||||
gem "mongoid", "~> 3.0"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (2.1.0.rc2)
|
||||
devise (2.1.2)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.7)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.1.1)
|
||||
warden (~> 1.2.1)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
@@ -41,8 +41,6 @@ GEM
|
||||
addressable (2.2.7)
|
||||
arel (2.2.3)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bson (1.5.2)
|
||||
bson_ext (1.3.1)
|
||||
builder (3.0.0)
|
||||
columnize (0.3.6)
|
||||
erubis (2.7.0)
|
||||
@@ -64,12 +62,12 @@ GEM
|
||||
mime-types (1.18)
|
||||
mocha (0.10.4)
|
||||
metaclass (~> 0.0.1)
|
||||
mongo (1.3.1)
|
||||
bson (>= 1.3.1)
|
||||
mongoid (2.4.4)
|
||||
mongoid (3.0.12)
|
||||
activemodel (~> 3.1)
|
||||
mongo (~> 1.3)
|
||||
moped (~> 1.1)
|
||||
origin (~> 1.0)
|
||||
tzinfo (~> 0.3.22)
|
||||
moped (1.2.9)
|
||||
multi_json (1.3.4)
|
||||
multipart-post (1.1.5)
|
||||
nokogiri (1.5.0)
|
||||
@@ -87,7 +85,8 @@ GEM
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
orm_adapter (0.0.7)
|
||||
origin (1.0.10)
|
||||
orm_adapter (0.4.0)
|
||||
polyglot (0.3.3)
|
||||
rack (1.3.6)
|
||||
rack-cache (1.2)
|
||||
@@ -137,7 +136,7 @@ GEM
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.33)
|
||||
warden (1.1.1)
|
||||
warden (1.2.1)
|
||||
rack (>= 1.0)
|
||||
webrat (0.7.2)
|
||||
nokogiri (>= 1.2.0)
|
||||
@@ -150,12 +149,10 @@ PLATFORMS
|
||||
DEPENDENCIES
|
||||
activerecord-jdbc-adapter
|
||||
activerecord-jdbcsqlite3-adapter
|
||||
bson_ext (~> 1.3.0)
|
||||
devise!
|
||||
jruby-openssl
|
||||
mocha
|
||||
mongo (~> 1.3.0)
|
||||
mongoid (~> 2.0)
|
||||
mongoid (~> 3.0)
|
||||
omniauth (~> 1.0.0)
|
||||
omniauth-facebook
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
|
||||
@@ -6,11 +6,12 @@ require 'set'
|
||||
require 'securerandom'
|
||||
|
||||
module Devise
|
||||
autoload :Delegator, 'devise/delegator'
|
||||
autoload :FailureApp, 'devise/failure_app'
|
||||
autoload :OmniAuth, 'devise/omniauth'
|
||||
autoload :ParamFilter, 'devise/param_filter'
|
||||
autoload :TestHelpers, 'devise/test_helpers'
|
||||
autoload :Delegator, 'devise/delegator'
|
||||
autoload :FailureApp, 'devise/failure_app'
|
||||
autoload :OmniAuth, 'devise/omniauth'
|
||||
autoload :ParamFilter, 'devise/param_filter'
|
||||
autoload :TestHelpers, 'devise/test_helpers'
|
||||
autoload :TimeInflector, 'devise/time_inflector'
|
||||
|
||||
module Controllers
|
||||
autoload :Helpers, 'devise/controllers/helpers'
|
||||
@@ -86,7 +87,7 @@ module Devise
|
||||
# an one (and only one) @ exists in the given string. This is mainly
|
||||
# to give user feedback and not to assert the e-mail validity.
|
||||
mattr_accessor :email_regexp
|
||||
@@email_regexp = /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
|
||||
@@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
|
||||
|
||||
# Range validation for password length
|
||||
mattr_accessor :password_length
|
||||
@@ -104,6 +105,10 @@ module Devise
|
||||
mattr_accessor :allow_unconfirmed_access_for
|
||||
@@allow_unconfirmed_access_for = 0.days
|
||||
|
||||
# Time interval the confirmation token is valid. nil = unlimited
|
||||
mattr_accessor :confirm_within
|
||||
@@confirm_within = nil
|
||||
|
||||
# Defines which key will be used when confirming an account.
|
||||
mattr_accessor :confirmation_keys
|
||||
@@confirmation_keys = [ :email ]
|
||||
@@ -199,7 +204,7 @@ module Devise
|
||||
# to provide custom routes.
|
||||
mattr_accessor :router_name
|
||||
@@router_name = nil
|
||||
|
||||
|
||||
# Set the omniauth path prefix so it can be overriden when
|
||||
# Devise is used in a mountable engine
|
||||
mattr_accessor :omniauth_path_prefix
|
||||
|
||||
@@ -162,8 +162,8 @@ module Devise
|
||||
users.any?
|
||||
end
|
||||
|
||||
# Returns and delete the url stored in the session for the given scope. Useful
|
||||
# for giving redirect backs after sign up:
|
||||
# Returns and delete (if it's navigational format) the url stored in the session for
|
||||
# the given scope. Useful for giving redirect backs after sign up:
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
@@ -171,7 +171,12 @@ module Devise
|
||||
#
|
||||
def stored_location_for(resource_or_scope)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
session.delete("#{scope}_return_to")
|
||||
|
||||
if is_navigational_format?
|
||||
session.delete("#{scope}_return_to")
|
||||
else
|
||||
session["#{scope}_return_to"]
|
||||
end
|
||||
end
|
||||
|
||||
# The scope root url to be used when he's signed in. By default, it first
|
||||
@@ -262,6 +267,14 @@ module Devise
|
||||
super # call the default behaviour which resets the session
|
||||
end
|
||||
|
||||
def request_format
|
||||
@request_format ||= request.format.try(:ref)
|
||||
end
|
||||
|
||||
def is_navigational_format?
|
||||
Devise.navigational_formats.include?(request_format)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expire_devise_cached_variables!
|
||||
|
||||
@@ -28,8 +28,9 @@ module Devise
|
||||
def headers_for(action)
|
||||
headers = {
|
||||
:subject => translate(devise_mapping, action),
|
||||
:from => mailer_sender(devise_mapping),
|
||||
:to => resource.email,
|
||||
:from => mailer_sender(devise_mapping),
|
||||
:reply_to => mailer_reply_to(devise_mapping),
|
||||
:template_path => template_paths
|
||||
}
|
||||
|
||||
@@ -37,16 +38,21 @@ module Devise
|
||||
headers.merge!(resource.headers_for(action))
|
||||
end
|
||||
|
||||
unless headers.key?(:reply_to)
|
||||
headers[:reply_to] = headers[:from]
|
||||
end
|
||||
|
||||
@email = headers[:to]
|
||||
headers
|
||||
end
|
||||
|
||||
def mailer_sender(mapping)
|
||||
if default_params[:from].present?
|
||||
default_params[:from]
|
||||
def mailer_reply_to(mapping)
|
||||
mailer_sender(mapping, :reply_to)
|
||||
end
|
||||
|
||||
def mailer_from(mapping)
|
||||
mailer_sender(mapping, :from)
|
||||
end
|
||||
|
||||
def mailer_sender(mapping, sender = :from)
|
||||
if default_params[sender].present?
|
||||
default_params[sender]
|
||||
elsif Devise.mailer_sender.is_a?(Proc)
|
||||
Devise.mailer_sender.call(mapping.name)
|
||||
else
|
||||
|
||||
@@ -164,11 +164,15 @@ module Devise
|
||||
end
|
||||
|
||||
def downcase_keys
|
||||
self.class.case_insensitive_keys.each { |k| self[k].try(: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| self[k].try(:strip!) }
|
||||
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip!) }
|
||||
end
|
||||
|
||||
def apply_to_attribute_or_variable(attr, method)
|
||||
(self[attr] || send(attr)).try(method)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
@@ -199,7 +203,7 @@ module Devise
|
||||
# it may be wrapped as well. For instance, database authenticatable
|
||||
# provides a `find_for_database_authentication` that wraps a call to
|
||||
# this method. This allows you to customize both database authenticatable
|
||||
# or the whole authenticate stack by customize `find_for_authentication.`
|
||||
# or the whole authenticate stack by customize `find_for_authentication.`
|
||||
#
|
||||
# Overwrite to add customized conditions, create a join, or maybe use a
|
||||
# namedscope to filter records while authenticating.
|
||||
|
||||
@@ -19,6 +19,8 @@ module Devise
|
||||
# db field to be setup (t.reconfirmable in migrations). Until confirmed new email is
|
||||
# stored in unconfirmed email column, and copied to email column on successful
|
||||
# confirmation.
|
||||
# * +confirm_within+: the time before a sent confirmation token becomes invalid.
|
||||
# You can use this to force the user to confirm within a set period of time.
|
||||
#
|
||||
# == Examples
|
||||
#
|
||||
@@ -28,6 +30,7 @@ module Devise
|
||||
#
|
||||
module Confirmable
|
||||
extend ActiveSupport::Concern
|
||||
include ActionView::Helpers::DateHelper
|
||||
|
||||
included do
|
||||
before_create :generate_confirmation_token, :if => :confirmation_required?
|
||||
@@ -47,6 +50,12 @@ module Devise
|
||||
# add errors
|
||||
def confirm!
|
||||
pending_any_confirmation do
|
||||
if confirmation_period_expired?
|
||||
self.errors.add(:email, :confirmation_period_expired,
|
||||
:period => Devise::TimeInflector.time_ago_in_words(self.class.confirm_within.ago))
|
||||
return false
|
||||
end
|
||||
|
||||
self.confirmation_token = nil
|
||||
self.confirmed_at = Time.now.utc
|
||||
|
||||
@@ -83,7 +92,10 @@ module Devise
|
||||
|
||||
# Resend confirmation token. This method does not need to generate a new token.
|
||||
def resend_confirmation_token
|
||||
pending_any_confirmation { send_confirmation_instructions }
|
||||
pending_any_confirmation do
|
||||
self.confirmation_token = nil if confirmation_period_expired?
|
||||
send_confirmation_instructions
|
||||
end
|
||||
end
|
||||
|
||||
# Overwrites active_for_authentication? for confirmation
|
||||
@@ -156,9 +168,25 @@ module Devise
|
||||
confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago
|
||||
end
|
||||
|
||||
# Checks if the user confirmation happens before the token becomes invalid
|
||||
# Examples:
|
||||
#
|
||||
# # confirm_within = 3.days and confirmation_sent_at = 2.days.ago
|
||||
# confirmation_period_expired? # returns false
|
||||
#
|
||||
# # confirm_within = 3.days and confirmation_sent_at = 4.days.ago
|
||||
# confirmation_period_expired? # returns true
|
||||
#
|
||||
# # confirm_within = nil
|
||||
# confirmation_period_expired? # will always return false
|
||||
#
|
||||
def confirmation_period_expired?
|
||||
self.class.confirm_within && (Time.now > self.confirmation_sent_at + self.class.confirm_within )
|
||||
end
|
||||
|
||||
# Checks whether the record requires any confirmation.
|
||||
def pending_any_confirmation
|
||||
if !confirmed? || pending_reconfirmation?
|
||||
if (!confirmed? || pending_reconfirmation?)
|
||||
yield
|
||||
else
|
||||
self.errors.add(:email, :already_confirmed)
|
||||
@@ -235,7 +263,7 @@ module Devise
|
||||
find_or_initialize_with_errors(unconfirmed_required_attributes, unconfirmed_attributes, :not_found)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :allow_unconfirmed_access_for, :confirmation_keys, :reconfirmable)
|
||||
Devise::Models.config(self, :allow_unconfirmed_access_for, :confirmation_keys, :reconfirmable, :confirm_within)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,6 +64,7 @@ module Devise
|
||||
result = if valid_password?(current_password)
|
||||
update_attributes(params, *options)
|
||||
else
|
||||
params.delete(:password)
|
||||
self.assign_attributes(params, *options)
|
||||
self.valid?
|
||||
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
|
||||
@@ -75,7 +76,7 @@ module Devise
|
||||
end
|
||||
|
||||
# Updates record attributes without asking for the current password.
|
||||
# Never allows to change the current password. If you are using this
|
||||
# Never allows a change to the current password. If you are using this
|
||||
# method, you should probably override this method to protect other
|
||||
# attributes you would not like to be updated without a password.
|
||||
#
|
||||
|
||||
@@ -27,7 +27,7 @@ module Devise
|
||||
def self.required_fields(klass)
|
||||
attributes = []
|
||||
attributes << :failed_attempts if klass.lock_strategy_enabled?(:failed_attempts)
|
||||
attributes << :unlock_at if klass.unlock_strategy_enabled?(:time)
|
||||
attributes << :locked_at if klass.unlock_strategy_enabled?(:time)
|
||||
attributes << :unlock_token if klass.unlock_strategy_enabled?(:email)
|
||||
|
||||
attributes
|
||||
@@ -105,7 +105,11 @@ module Devise
|
||||
end
|
||||
|
||||
def unauthenticated_message
|
||||
if lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?
|
||||
# If set to paranoid mode, do not show the locked message because it
|
||||
# leaks the existence of an account.
|
||||
if Devise.paranoid
|
||||
super
|
||||
elsif lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?
|
||||
:locked
|
||||
else
|
||||
super
|
||||
|
||||
@@ -102,9 +102,9 @@ module Devise
|
||||
|
||||
module ClassMethods
|
||||
# Attempt to find a user by its email. If a record is found, send new
|
||||
# password instructions to it. If not user is found, returns a new user
|
||||
# password instructions to it. If user is not found, returns a new user
|
||||
# with an email not found error.
|
||||
# Attributes must contain the user email
|
||||
# Attributes must contain the user's email
|
||||
def send_reset_password_instructions(attributes={})
|
||||
recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
|
||||
recoverable.send_reset_password_instructions if recoverable.persisted?
|
||||
|
||||
@@ -18,6 +18,18 @@ module Devise
|
||||
# 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:
|
||||
|
||||
@@ -20,7 +20,7 @@ module Devise
|
||||
self.last_sign_in_at = old_current || new_current
|
||||
self.current_sign_in_at = new_current
|
||||
|
||||
old_current, new_current = self.current_sign_in_ip, request.ip
|
||||
old_current, new_current = self.current_sign_in_ip, request.remote_ip
|
||||
self.last_sign_in_ip = old_current || new_current
|
||||
self.current_sign_in_ip = new_current
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module Devise
|
||||
# Validatable adds the following options to devise_for:
|
||||
#
|
||||
# * +email_regexp+: the regular expression used to validate e-mails;
|
||||
# * +password_length+: a range expressing password length. Defaults to 6..128.
|
||||
# * +password_length+: a range expressing password length. Defaults to 8..128.
|
||||
#
|
||||
module Validatable
|
||||
# All validations used by this module.
|
||||
|
||||
@@ -43,20 +43,20 @@ module ActionDispatch::Routing
|
||||
# needed routes:
|
||||
#
|
||||
# # Session routes for Authenticatable (default)
|
||||
# new_user_session GET /users/sign_in {:controller=>"devise/sessions", :action=>"new"}
|
||||
# user_session POST /users/sign_in {:controller=>"devise/sessions", :action=>"create"}
|
||||
# destroy_user_session GET /users/sign_out {:controller=>"devise/sessions", :action=>"destroy"}
|
||||
# new_user_session GET /users/sign_in {:controller=>"devise/sessions", :action=>"new"}
|
||||
# user_session POST /users/sign_in {:controller=>"devise/sessions", :action=>"create"}
|
||||
# destroy_user_session DELETE /users/sign_out {:controller=>"devise/sessions", :action=>"destroy"}
|
||||
#
|
||||
# # Password routes for Recoverable, if User model has :recoverable configured
|
||||
# new_user_password GET /users/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
|
||||
# edit_user_password GET /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
|
||||
# user_password PUT /users/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
|
||||
# POST /users/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
|
||||
# new_user_password GET /users/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
|
||||
# edit_user_password GET /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
|
||||
# user_password PUT /users/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
|
||||
# POST /users/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
|
||||
#
|
||||
# # Confirmation routes for Confirmable, if User model has :confirmable configured
|
||||
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
|
||||
# user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
|
||||
# POST /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
|
||||
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
|
||||
# user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
|
||||
# POST /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
|
||||
#
|
||||
# ==== Options
|
||||
#
|
||||
@@ -183,7 +183,7 @@ module ActionDispatch::Routing
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# In order to get Devise to recognize the deactivate action, your devise_for entry should look like this,
|
||||
# In order to get Devise to recognize the deactivate action, your devise_scope entry should look like this:
|
||||
#
|
||||
# devise_scope :owner do
|
||||
# post "deactivate", :to => "registrations#deactivate", :as => "deactivate_registration"
|
||||
|
||||
@@ -6,7 +6,7 @@ module Devise
|
||||
class DatabaseAuthenticatable < Authenticatable
|
||||
def authenticate!
|
||||
resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
|
||||
return fail(:invalid) unless resource
|
||||
return fail(:not_found_in_database) unless resource
|
||||
|
||||
if validate(resource){ resource.valid_password?(password) }
|
||||
resource.after_database_authentication
|
||||
|
||||
@@ -45,6 +45,7 @@ module Devise
|
||||
def sign_in(resource_or_scope, resource=nil)
|
||||
scope ||= Devise::Mapping.find_scope!(resource_or_scope)
|
||||
resource ||= resource_or_scope
|
||||
warden.instance_variable_get(:@users).delete(scope)
|
||||
warden.session_serializer.store(resource, scope)
|
||||
end
|
||||
|
||||
@@ -106,8 +107,8 @@ module Devise
|
||||
env["warden.options"] = options
|
||||
Warden::Manager._run_callbacks(:before_failure, env, options)
|
||||
|
||||
status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
|
||||
@controller.send :render, :status => status, :text => body,
|
||||
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
|
||||
@controller.send :render, :status => status, :text => response.body,
|
||||
:content_type => headers["Content-Type"], :location => headers["Location"]
|
||||
nil # causes process return @response
|
||||
end
|
||||
|
||||
14
lib/devise/time_inflector.rb
Normal file
14
lib/devise/time_inflector.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
require "active_support/core_ext/module/delegation"
|
||||
|
||||
module Devise
|
||||
class TimeInflector
|
||||
include ActionView::Helpers::DateHelper
|
||||
|
||||
class << self
|
||||
attr_reader :instance
|
||||
delegate :time_ago_in_words, :to => :instance
|
||||
end
|
||||
|
||||
@instance = new
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,3 @@
|
||||
module Devise
|
||||
VERSION = "2.1.2".freeze
|
||||
VERSION = "2.2.0.rc".freeze
|
||||
end
|
||||
|
||||
@@ -27,7 +27,11 @@ module ActiveRecord
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me
|
||||
CONTENT
|
||||
|
||||
class_path = class_name.to_s.split("::")
|
||||
class_path = if namespaced?
|
||||
class_name.to_s.split("::")
|
||||
else
|
||||
[class_name]
|
||||
end
|
||||
|
||||
indent_depth = class_path.size - 1
|
||||
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
||||
|
||||
@@ -22,9 +22,6 @@ module Mongoid
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :default => ""
|
||||
field :encrypted_password, :type => String, :default => ""
|
||||
|
||||
validates_presence_of :email
|
||||
validates_presence_of :encrypted_password
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
|
||||
@@ -21,11 +21,15 @@ Some setup you must do manually if you haven't yet:
|
||||
<p class="notice"><%= notice %></p>
|
||||
<p class="alert"><%= alert %></p>
|
||||
|
||||
4. If you are deploying Rails 3.1 on Heroku, you may want to set:
|
||||
4. If you are deploying Rails 3.1+ on Heroku, you may want to set:
|
||||
|
||||
config.assets.initialize_on_precompile = false
|
||||
|
||||
On config/application.rb forcing your application to not access the DB
|
||||
or load models when precompiling your assets.
|
||||
|
||||
5. You can copy Devise views (for customization) to your app by running:
|
||||
|
||||
rails g devise:views
|
||||
|
||||
===============================================================================
|
||||
|
||||
@@ -92,6 +92,14 @@ Devise.setup do |config|
|
||||
# the user cannot access the website without confirming his account.
|
||||
# config.allow_unconfirmed_access_for = 2.days
|
||||
|
||||
# A period that the user is allowed to confirm their account before their
|
||||
# token becomes invalid. For example, if set to 3.days, the user can confirm
|
||||
# their account within 3 days after the mail was sent, but on the fourth day
|
||||
# their account can't be confirmed with the token any more.
|
||||
# Default is nil, meaning there is no restriction on how long a user can take
|
||||
# before confirming their account.
|
||||
# config.confirm_within = 3.days
|
||||
|
||||
# If true, requires any email changes to be confirmed (exactly the same way as
|
||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||
# db field (see migrations). Until confirmed new email is stored in
|
||||
@@ -113,8 +121,8 @@ Devise.setup do |config|
|
||||
# config.rememberable_options = {}
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length. Default is 6..128.
|
||||
# config.password_length = 6..128
|
||||
# Range for password length. Default is 8..128.
|
||||
config.password_length = 8..128
|
||||
|
||||
# Email regex used to validate email formats. It simply asserts that
|
||||
# an one (and only one) @ exists in the given string. This is mainly
|
||||
@@ -125,7 +133,7 @@ Devise.setup do |config|
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again. Default is 30 minutes.
|
||||
# config.timeout_in = 30.minutes
|
||||
|
||||
|
||||
# If true, expires auth token on session timeout.
|
||||
# config.expire_auth_token_on_timeout = false
|
||||
|
||||
@@ -229,4 +237,4 @@ Devise.setup do |config|
|
||||
# When using omniauth, Devise cannot automatically set Omniauth path,
|
||||
# so you need to do it manually. For the users scope, it would be:
|
||||
# config.omniauth_path_prefix = "/my_engine/users/auth"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Welcome <%= @resource.email %>!
|
||||
Welcome <%= @email %>!
|
||||
|
||||
You can confirm your account through the link below:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Hello <%= @resource.email %>!
|
||||
|
||||
Your account has been locked due to an excessive amount of unsuccessful sign in attempts.
|
||||
Your account has been locked due to an excessive number of unsuccessful sign in attempts.
|
||||
|
||||
Click the link below to unlock your account:
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
<%= f.full_error :confirmation_token %>
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<%= f.full_error :reset_password_token %>
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :password, :label => "New password", :required => true %>
|
||||
<%= f.input :password, :label => "New password", :required => true, :autofocus => true %>
|
||||
<%= f.input :password_confirmation, :label => "Confirm your new password", :required => true %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
|
||||
<% if resource.class.reconfirmable && resource.unconfirmed_email.present? %>
|
||||
<p>Currently waiting confirmation for: <%= resource.unconfirmed_email %></p>
|
||||
<% end %>
|
||||
|
||||
<%= f.input :password, :autocomplete => "off", :hint => "leave it blank if you don't want to change it", :required => false %>
|
||||
<%= f.input :password_confirmation, :required => false %>
|
||||
<%= f.input :current_password, :hint => "we need your current password to confirm your changes", :required => true %>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
<%= f.full_error :unlock_token %>
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
|
||||
@@ -95,6 +95,12 @@ class HelpersTest < ActionController::TestCase
|
||||
assert_equal 'devise custom options', flash[:notice]
|
||||
end
|
||||
|
||||
test 'allows custom i18n options to override resource_name' do
|
||||
I18n.expects(:t).with("custom_resource_name.confirmed", anything)
|
||||
@controller.stubs(:devise_i18n_options).returns(:resource_name => "custom_resource_name")
|
||||
@controller.send :set_flash_message, :notice, :confirmed
|
||||
end
|
||||
|
||||
test 'navigational_formats not returning a wild card' do
|
||||
MyController.send(:public, :navigational_formats)
|
||||
Devise.navigational_formats = [:"*/*", :html]
|
||||
|
||||
@@ -13,6 +13,34 @@ class SessionsControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "#create delete the url stored in the session if the requested format is navigational" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
request.session["user_return_to"] = 'foo.bar'
|
||||
|
||||
user = create_user
|
||||
user.confirm!
|
||||
post :create, :user => {
|
||||
:email => user.email,
|
||||
:password => user.password
|
||||
}
|
||||
|
||||
assert_nil request.session["user_return_to"]
|
||||
end
|
||||
|
||||
test "#create doesn't delete the url stored in the session if the requested format is not navigational" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
request.session["user_return_to"] = 'foo.bar'
|
||||
|
||||
user = create_user
|
||||
user.confirm!
|
||||
post :create, :format => 'json', :user => {
|
||||
:email => user.email,
|
||||
:password => user.password
|
||||
}
|
||||
|
||||
assert_equal 'foo.bar', request.session["user_return_to"]
|
||||
end
|
||||
|
||||
test "#create doesn't raise exception after Warden authentication fails when TestHelpers included" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
post :create, :user => {
|
||||
@@ -23,6 +51,20 @@ class SessionsControllerTest < ActionController::TestCase
|
||||
assert_template "devise/sessions/new"
|
||||
end
|
||||
|
||||
test "#destroy doesn't set the flash if the requested format is not navigational" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
user = create_user
|
||||
user.confirm!
|
||||
post :create, :format => 'json', :user => {
|
||||
:email => user.email,
|
||||
:password => user.password
|
||||
}
|
||||
|
||||
delete :destroy, :format => 'json'
|
||||
assert flash[:notice].blank?, "flash[:notice] should be blank, not #{flash[:notice].inspect}"
|
||||
assert_equal 204, @response.status
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord) && ActiveRecord::Base.respond_to?(:mass_assignment_sanitizer)
|
||||
test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
@@ -40,4 +82,4 @@ class SessionsControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,5 +68,16 @@ class DeviseTest < ActiveSupport::TestCase
|
||||
end
|
||||
assert_not Devise.secure_compare("size_1", "size_four")
|
||||
end
|
||||
|
||||
|
||||
test 'Devise.email_regexp should match valid email addresses' do
|
||||
valid_emails = ["test@example.com", "jo@jo.co", "f4$_m@you.com", "testing.example@example.com.ua"]
|
||||
non_valid_emails = ["rex", "test@go,com", "test user@example.com", "test_user@example server.com"]
|
||||
|
||||
valid_emails.each do |email|
|
||||
assert_match Devise.email_regexp, email
|
||||
end
|
||||
non_valid_emails.each do |email|
|
||||
assert_no_match Devise.email_regexp, email
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,6 +14,12 @@ if DEVISE_ORM == :active_record
|
||||
assert_migration "db/migrate/devise_create_monsters.rb", /def change/
|
||||
end
|
||||
|
||||
test "all files for namespaced model are properly created" do
|
||||
run_generator %w(admin/monster)
|
||||
assert_file "app/models/admin/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
|
||||
assert_migration "db/migrate/devise_create_admin_monsters.rb", /def change/
|
||||
end
|
||||
|
||||
test "update model migration when model exists" do
|
||||
run_generator %w(monster)
|
||||
assert_file "app/models/monster.rb"
|
||||
@@ -66,4 +72,4 @@ if DEVISE_ORM == :active_record
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
class IndifferentHashTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@hash = Devise::IndifferentHash.new
|
||||
end
|
||||
|
||||
test "it overwrites getter and setter" do
|
||||
@hash[:foo] = "bar"
|
||||
assert_equal "bar", @hash["foo"]
|
||||
assert_equal "bar", @hash[:foo]
|
||||
|
||||
@hash["foo"] = "baz"
|
||||
assert_equal "baz", @hash["foo"]
|
||||
assert_equal "baz", @hash[:foo]
|
||||
end
|
||||
|
||||
test "it overwrites update" do
|
||||
@hash.update :foo => "bar"
|
||||
assert_equal "bar", @hash["foo"]
|
||||
assert_equal "bar", @hash[:foo]
|
||||
|
||||
@hash.update "foo" => "baz"
|
||||
assert_equal "baz", @hash["foo"]
|
||||
assert_equal "baz", @hash[:foo]
|
||||
end
|
||||
|
||||
test "it returns a Hash on to_hash" do
|
||||
@hash[:foo] = "bar"
|
||||
assert_equal Hash["foo", "bar"], @hash.to_hash
|
||||
assert_kind_of Hash, @hash.to_hash
|
||||
end
|
||||
end if defined?(Devise::IndifferentHash)
|
||||
@@ -456,7 +456,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
||||
assert_match '<?xml version="1.0" encoding="UTF-8"?>', response.body
|
||||
assert_match /<user>.*<\/user>/m, response.body
|
||||
assert_match '<email></email>', response.body
|
||||
assert_match '<password nil="true"></password>', response.body
|
||||
assert_match '<password nil="true"', response.body
|
||||
end
|
||||
|
||||
test 'sign in stub in json format' do
|
||||
@@ -483,7 +483,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
||||
|
||||
test 'sign in with xml format returns xml response' do
|
||||
create_user
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '123456'}
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '12345678'}
|
||||
assert_response :success
|
||||
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
|
||||
end
|
||||
@@ -493,13 +493,13 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
||||
assert_response :success
|
||||
|
||||
create_user
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '123456'}
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '12345678'}
|
||||
assert_response :success
|
||||
|
||||
get new_user_session_path(:format => 'xml')
|
||||
assert_response :success
|
||||
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '123456'}
|
||||
post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '12345678'}
|
||||
assert_response :success
|
||||
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
|
||||
end
|
||||
|
||||
@@ -50,6 +50,30 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
assert user.reload.confirmed?
|
||||
end
|
||||
|
||||
test 'user with valid confirmation token should not be able to confirm an account after the token has expired' do
|
||||
swap Devise, :confirm_within => 3.days do
|
||||
user = create_user(:confirm => false, :confirmation_sent_at => 4.days.ago)
|
||||
assert_not user.confirmed?
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain /needs to be confirmed within 3 days/
|
||||
assert_not user.reload.confirmed?
|
||||
end
|
||||
end
|
||||
|
||||
test 'user with valid confirmation token should be able to confirm an account before the token has expired' do
|
||||
swap Devise, :confirm_within => 3.days do
|
||||
user = create_user(:confirm => false, :confirmation_sent_at => 2.days.ago)
|
||||
assert_not user.confirmed?
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
assert_contain 'Your account was successfully confirmed.'
|
||||
assert_current_url '/'
|
||||
assert user.reload.confirmed?
|
||||
end
|
||||
end
|
||||
|
||||
test 'user should be redirected to a custom path after confirmation' do
|
||||
Devise::ConfirmationsController.any_instance.stubs(:after_confirmation_path_for).returns("/?custom=1")
|
||||
|
||||
@@ -240,6 +264,26 @@ class ConfirmationOnChangeTest < ActionController::IntegrationTest
|
||||
assert_not admin.reload.pending_reconfirmation?
|
||||
end
|
||||
|
||||
test 'admin with previously valid confirmation token should not be able to confirm email after email changed again' do
|
||||
admin = create_admin
|
||||
admin.update_attributes(:email => 'first_test@example.com')
|
||||
assert_equal 'first_test@example.com', admin.unconfirmed_email
|
||||
|
||||
confirmation_token = admin.confirmation_token
|
||||
admin.update_attributes(:email => 'second_test@example.com')
|
||||
assert_equal 'second_test@example.com', admin.unconfirmed_email
|
||||
|
||||
visit_admin_confirmation_with_token(confirmation_token)
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain /Confirmation token(.*)invalid/
|
||||
|
||||
visit_admin_confirmation_with_token(admin.confirmation_token)
|
||||
assert_contain 'Your account was successfully confirmed.'
|
||||
assert_current_url '/admin_area/home'
|
||||
assert admin.reload.confirmed?
|
||||
assert_not admin.reload.pending_reconfirmation?
|
||||
end
|
||||
|
||||
test 'admin email should be unique also within unconfirmed_email' do
|
||||
admin = create_admin
|
||||
admin.update_attributes(:email => 'new_admin_test@example.com')
|
||||
|
||||
@@ -3,44 +3,44 @@ require 'test_helper'
|
||||
class DatabaseAuthenticationTest < ActionController::IntegrationTest
|
||||
test 'sign in with email of different case should succeed when email is in the list of case insensitive keys' do
|
||||
create_user(:email => 'Foo@Bar.com')
|
||||
|
||||
|
||||
sign_in_as_user do
|
||||
fill_in 'email', :with => 'foo@bar.com'
|
||||
end
|
||||
|
||||
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'sign in with email of different case should fail when email is NOT the list of case insensitive keys' do
|
||||
swap Devise, :case_insensitive_keys => [] do
|
||||
create_user(:email => 'Foo@Bar.com')
|
||||
|
||||
|
||||
sign_in_as_user do
|
||||
fill_in 'email', :with => 'foo@bar.com'
|
||||
end
|
||||
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
test 'sign in with email including extra spaces should succeed when email is in the list of strip whitespace keys' do
|
||||
create_user(:email => ' foo@bar.com ')
|
||||
|
||||
|
||||
sign_in_as_user do
|
||||
fill_in 'email', :with => 'foo@bar.com'
|
||||
end
|
||||
|
||||
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'sign in with email including extra spaces should fail when email is NOT the list of strip whitespace keys' do
|
||||
swap Devise, :strip_whitespace_keys => [] do
|
||||
create_user(:email => 'foo@bar.com')
|
||||
|
||||
|
||||
sign_in_as_user do
|
||||
fill_in 'email', :with => ' foo@bar.com '
|
||||
end
|
||||
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
@@ -53,12 +53,14 @@ class DatabaseAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'sign in with invalid email should return to sign in form with error message' do
|
||||
sign_in_as_admin do
|
||||
fill_in 'email', :with => 'wrongemail@test.com'
|
||||
end
|
||||
store_translations :en, :devise => { :failure => { :admin => { :not_found_in_database => 'Invalid email address' } } } do
|
||||
sign_in_as_admin do
|
||||
fill_in 'email', :with => 'wrongemail@test.com'
|
||||
end
|
||||
|
||||
assert_contain 'Invalid email or password'
|
||||
assert_not warden.authenticated?(:admin)
|
||||
assert_contain 'Invalid email address'
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
end
|
||||
|
||||
test 'sign in with invalid pasword should return to sign in form with error message' do
|
||||
@@ -79,4 +81,4 @@ class DatabaseAuthenticationTest < ActionController::IntegrationTest
|
||||
assert_contain 'Invalid credentials'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
test 'handles unverified requests gets rid of caches but continues signed in' do
|
||||
swap UsersController, :allow_forgery_protection => true do
|
||||
create_user
|
||||
post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:123456")}"
|
||||
post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:12345678")}"
|
||||
assert warden.authenticated?(:user)
|
||||
assert_equal "User is authenticated", response.body
|
||||
end
|
||||
@@ -82,7 +82,7 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
|
||||
private
|
||||
|
||||
def sign_in_as_new_user_with_http(username="user@test.com", password="123456")
|
||||
def sign_in_as_new_user_with_http(username="user@test.com", password="12345678")
|
||||
user = create_user
|
||||
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("#{username}:#{password}")}"
|
||||
user
|
||||
@@ -91,7 +91,7 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
# Sign in with oauth2 token. This is just to test that it isn't misinterpreted as basic authentication
|
||||
def add_oauth2_header
|
||||
user = create_user
|
||||
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{Base64.encode64("#{user.email}:123456")}"
|
||||
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{Base64.encode64("#{user.email}:12345678")}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -221,4 +221,22 @@ class LockTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test "in paranoid mode, when locking a user that exists it should not say that the user was locked" do
|
||||
swap Devise, :paranoid => true, :maximum_attempts => 1 do
|
||||
user = create_user(:locked => false)
|
||||
|
||||
visit new_user_session_path
|
||||
fill_in 'email', :with => user.email
|
||||
fill_in 'password', :with => "abadpassword"
|
||||
click_button 'Sign in'
|
||||
|
||||
fill_in 'email', :with => user.email
|
||||
fill_in 'password', :with => "abadpassword"
|
||||
click_button 'Sign in'
|
||||
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_not_contain "locked"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -61,8 +61,8 @@ class OmniauthableIntegrationTest < ActionController::IntegrationTest
|
||||
|
||||
assert_difference "User.count" do
|
||||
visit "/users/sign_up"
|
||||
fill_in "Password", :with => "123456"
|
||||
fill_in "Password confirmation", :with => "123456"
|
||||
fill_in "Password", :with => "12345678"
|
||||
fill_in "Password confirmation", :with => "12345678"
|
||||
click_button "Sign up"
|
||||
end
|
||||
|
||||
|
||||
@@ -190,15 +190,43 @@ class PasswordTest < ActionController::IntegrationTest
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'does not sign in user automatically after changing its password if it\'s locked' do
|
||||
user = create_user(:locked => true)
|
||||
request_forgot_password
|
||||
reset_password :reset_password_token => user.reload.reset_password_token
|
||||
test 'does not sign in user automatically after changing its password if it\'s locked and unlock strategy is :none or :time' do
|
||||
[:none, :time].each do |strategy|
|
||||
swap Devise, :unlock_strategy => strategy do
|
||||
user = create_user(:locked => true)
|
||||
request_forgot_password
|
||||
reset_password :reset_password_token => user.reload.reset_password_token
|
||||
|
||||
assert_contain 'Your password was changed successfully.'
|
||||
assert_not_contain 'You are now signed in.'
|
||||
assert_equal new_user_session_path, @request.path
|
||||
assert !warden.authenticated?(:user)
|
||||
assert_contain 'Your password was changed successfully.'
|
||||
assert_not_contain 'You are now signed in.'
|
||||
assert_equal new_user_session_path, @request.path
|
||||
assert !warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'unlocks and signs in locked user automatically after changing it\'s password if unlock strategy is :email' do
|
||||
swap Devise, :unlock_strategy => :email do
|
||||
user = create_user(:locked => true)
|
||||
request_forgot_password
|
||||
reset_password :reset_password_token => user.reload.reset_password_token
|
||||
|
||||
assert_contain 'Your password was changed successfully.'
|
||||
assert !user.reload.access_locked?
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'unlocks and signs in locked user automatically after changing it\'s password if unlock strategy is :both' do
|
||||
swap Devise, :unlock_strategy => :both do
|
||||
user = create_user(:locked => true)
|
||||
request_forgot_password
|
||||
reset_password :reset_password_token => user.reload.reset_password_token
|
||||
|
||||
assert_contain 'Your password was changed successfully.'
|
||||
assert !user.reload.access_locked?
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'sign in user automatically and confirm after changing its password if it\'s not confirmed' do
|
||||
|
||||
@@ -144,7 +144,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
get edit_user_registration_path
|
||||
|
||||
fill_in 'email', :with => 'user.new@example.com'
|
||||
fill_in 'current password', :with => '123456'
|
||||
fill_in 'current password', :with => '12345678'
|
||||
click_button 'Update'
|
||||
|
||||
assert_current_url '/'
|
||||
@@ -157,9 +157,9 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
sign_in_as_user
|
||||
get edit_user_registration_path
|
||||
|
||||
fill_in 'password', :with => '12345678'
|
||||
fill_in 'password confirmation', :with => '12345678'
|
||||
fill_in 'current password', :with => '123456'
|
||||
fill_in 'password', :with => '1234567890'
|
||||
fill_in 'password confirmation', :with => '1234567890'
|
||||
fill_in 'current password', :with => '12345678'
|
||||
click_button 'Update'
|
||||
|
||||
assert_contain 'You updated your account successfully.'
|
||||
@@ -186,15 +186,15 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
sign_in_as_user
|
||||
get edit_user_registration_path
|
||||
|
||||
fill_in 'password', :with => 'pas123'
|
||||
fill_in 'password confirmation', :with => 'pas123'
|
||||
fill_in 'current password', :with => '123456'
|
||||
fill_in 'password', :with => 'pass1234'
|
||||
fill_in 'password confirmation', :with => 'pass1234'
|
||||
fill_in 'current password', :with => '12345678'
|
||||
click_button 'Update'
|
||||
|
||||
assert_current_url '/'
|
||||
assert_contain 'You updated your account successfully.'
|
||||
|
||||
assert User.first.valid_password?('pas123')
|
||||
assert User.first.valid_password?('pass1234')
|
||||
end
|
||||
|
||||
test 'a signed in user should not be able to edit his password with invalid confirmation' do
|
||||
@@ -203,7 +203,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
|
||||
fill_in 'password', :with => 'pas123'
|
||||
fill_in 'password confirmation', :with => ''
|
||||
fill_in 'current password', :with => '123456'
|
||||
fill_in 'current password', :with => '12345678'
|
||||
click_button 'Update'
|
||||
|
||||
assert_contain "Password doesn't match confirmation"
|
||||
@@ -272,7 +272,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
|
||||
test 'a user update information with valid data in XML format should return valid response' do
|
||||
user = sign_in_as_user
|
||||
put user_registration_path(:format => 'xml'), :user => { :current_password => '123456', :email => 'user.new@test.com' }
|
||||
put user_registration_path(:format => 'xml'), :user => { :current_password => '12345678', :email => 'user.new@test.com' }
|
||||
assert_response :success
|
||||
assert_equal user.reload.email, 'user.new@test.com'
|
||||
end
|
||||
@@ -303,8 +303,10 @@ class ReconfirmableRegistrationTest < ActionController::IntegrationTest
|
||||
|
||||
assert_current_url '/admin_area/home'
|
||||
assert_contain 'but we need to verify your new email address'
|
||||
assert_equal 'admin.new@example.com', Admin.first.unconfirmed_email
|
||||
|
||||
assert_equal "admin.new@example.com", Admin.first.unconfirmed_email
|
||||
get edit_admin_registration_path
|
||||
assert_contain 'Currently waiting confirmation for: admin.new@example.com'
|
||||
end
|
||||
|
||||
test 'a signed in admin should not see a reconfirmation message if they did not change their password' do
|
||||
@@ -321,4 +323,25 @@ class ReconfirmableRegistrationTest < ActionController::IntegrationTest
|
||||
|
||||
assert Admin.first.valid_password?('pas123')
|
||||
end
|
||||
|
||||
test 'a signed in admin should not see a reconfirmation message if he did not change his email, despite having an unconfirmed email' do
|
||||
sign_in_as_admin
|
||||
|
||||
get edit_admin_registration_path
|
||||
fill_in 'email', :with => 'admin.new@example.com'
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
get edit_admin_registration_path
|
||||
fill_in 'password', :with => 'pas123'
|
||||
fill_in 'password confirmation', :with => 'pas123'
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
assert_current_url '/admin_area/home'
|
||||
assert_contain 'You updated your account successfully.'
|
||||
|
||||
assert_equal "admin.new@example.com", Admin.first.unconfirmed_email
|
||||
assert Admin.first.valid_password?('pas123')
|
||||
end
|
||||
end
|
||||
@@ -50,6 +50,13 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
|
||||
assert_equal ['test@example.com'], mail.reply_to
|
||||
end
|
||||
|
||||
test 'setup reply to as different if set in defaults' do
|
||||
Devise.mailer = 'Users::ReplyToMailer'
|
||||
assert_equal ['custom@example.com'], mail.from
|
||||
assert_equal ['custom_reply_to@example.com'], mail.reply_to
|
||||
end
|
||||
|
||||
|
||||
test 'setup subject from I18n' do
|
||||
store_translations :en, :devise => { :mailer => { :confirmation_instructions => { :subject => 'Account Confirmation' } } } do
|
||||
assert_equal 'Account Confirmation', mail.subject
|
||||
|
||||
@@ -235,6 +235,40 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
assert_equal "can't be blank", confirm_user.errors[:username].join
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_user_by_token_with_confirmation_sent_at(confirmation_sent_at)
|
||||
user = create_user
|
||||
user.update_attribute(:confirmation_sent_at, confirmation_sent_at)
|
||||
confirmed_user = User.confirm_by_token(user.confirmation_token)
|
||||
assert_equal confirmed_user, user
|
||||
user.reload.confirmed?
|
||||
end
|
||||
|
||||
test 'should accept confirmation email token even after 5 years when no expiration is set' do
|
||||
assert confirm_user_by_token_with_confirmation_sent_at(5.years.ago)
|
||||
end
|
||||
|
||||
test 'should accept confirmation email token after 2 days when expiration is set to 3 days' do
|
||||
swap Devise, :confirm_within => 3.days do
|
||||
assert confirm_user_by_token_with_confirmation_sent_at(2.days.ago)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not accept confirmation email token after 4 days when expiration is set to 3 days' do
|
||||
swap Devise, :confirm_within => 3.days do
|
||||
assert_not confirm_user_by_token_with_confirmation_sent_at(4.days.ago)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should generate a new token if the previous one has expired' do
|
||||
swap Devise, :confirm_within => 3.days do
|
||||
user = create_user
|
||||
user.update_attribute(:confirmation_sent_at, 4.days.ago)
|
||||
old = user.confirmation_token
|
||||
user.resend_confirmation_token
|
||||
assert_not_equal user.confirmation_token, old
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ReconfirmableTest < ActiveSupport::TestCase
|
||||
@@ -260,7 +294,6 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
||||
assert_nil admin.confirmation_token
|
||||
end
|
||||
|
||||
|
||||
test 'should regenerate confirmation token after changing email' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
@@ -276,6 +309,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
||||
assert_email_sent "new_test@example.com" do
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
end
|
||||
assert_match "new_test@example.com", ActionMailer::Base.deliveries.last.body.encoded
|
||||
end
|
||||
|
||||
test 'should not send confirmation by email after changing password' do
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'test_helper'
|
||||
require 'test_models'
|
||||
require 'digest/sha1'
|
||||
|
||||
class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
@@ -12,6 +13,17 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
assert_equal email.downcase, user.email
|
||||
end
|
||||
|
||||
test 'should downcase case insensitive keys that refer to virtual attributes when saving' do
|
||||
email = 'Foo@Bar1.com'
|
||||
confirmation = 'Foo@Bar1.com'
|
||||
attributes = valid_attributes(:email => email, :email_confirmation => confirmation)
|
||||
user = UserWithVirtualAttributes.new(attributes)
|
||||
|
||||
assert_equal confirmation, user.email_confirmation
|
||||
user.save!
|
||||
assert_equal confirmation.downcase, user.email_confirmation
|
||||
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 '
|
||||
@@ -66,14 +78,14 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should test for a valid password' do
|
||||
user = create_user
|
||||
assert user.valid_password?('123456')
|
||||
assert user.valid_password?('12345678')
|
||||
assert_not user.valid_password?('654321')
|
||||
end
|
||||
|
||||
test 'should not raise error with an empty password' do
|
||||
user = create_user
|
||||
user.encrypted_password = ''
|
||||
assert_nothing_raised { user.valid_password?('123456') }
|
||||
assert_nothing_raised { user.valid_password?('12345678') }
|
||||
end
|
||||
|
||||
test 'should be an invalid password if the user has an empty password' do
|
||||
@@ -88,31 +100,38 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should update password with valid current password' do
|
||||
user = create_user
|
||||
assert user.update_with_password(:current_password => '123456',
|
||||
:password => 'pass321', :password_confirmation => 'pass321')
|
||||
assert user.reload.valid_password?('pass321')
|
||||
assert user.update_with_password(:current_password => '12345678',
|
||||
:password => 'pass4321', :password_confirmation => 'pass4321')
|
||||
assert user.reload.valid_password?('pass4321')
|
||||
end
|
||||
|
||||
test 'should update password with valid current password and :as option' do
|
||||
user = create_user
|
||||
assert user.update_with_password(:current_password => '123456',
|
||||
:password => 'pass321', :password_confirmation => 'pass321', :as => :admin)
|
||||
assert user.reload.valid_password?('pass321')
|
||||
assert user.update_with_password(:current_password => '12345678',
|
||||
:password => 'pass4321', :password_confirmation => 'pass4321', :as => :admin)
|
||||
assert user.reload.valid_password?('pass4321')
|
||||
end
|
||||
|
||||
test 'should add an error to current password when it is invalid' do
|
||||
user = create_user
|
||||
assert_not user.update_with_password(:current_password => 'other',
|
||||
:password => 'pass321', :password_confirmation => 'pass321')
|
||||
assert user.reload.valid_password?('123456')
|
||||
:password => 'pass4321', :password_confirmation => 'pass4321')
|
||||
assert user.reload.valid_password?('12345678')
|
||||
assert_match "is invalid", user.errors[:current_password].join
|
||||
end
|
||||
|
||||
test 'should not change encrypted password when it is invalid' do
|
||||
user = create_user
|
||||
assert_not user.update_with_password(:current_password => 'other',
|
||||
:password => 'pass4321', :password_confirmation => 'pass4321')
|
||||
assert_not user.encrypted_password_changed?
|
||||
end
|
||||
|
||||
test 'should add an error to current password when it is blank' do
|
||||
user = create_user
|
||||
assert_not user.update_with_password(:password => 'pass321',
|
||||
:password_confirmation => 'pass321')
|
||||
assert user.reload.valid_password?('123456')
|
||||
assert_not user.update_with_password(:password => 'pass4321',
|
||||
:password_confirmation => 'pass4321')
|
||||
assert user.reload.valid_password?('12345678')
|
||||
assert_match "can't be blank", user.errors[:current_password].join
|
||||
end
|
||||
|
||||
@@ -127,21 +146,21 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should ignore password and its confirmation if they are blank' do
|
||||
user = create_user
|
||||
assert user.update_with_password(:current_password => '123456', :email => "new@example.com")
|
||||
assert user.update_with_password(:current_password => '12345678', :email => "new@example.com")
|
||||
assert_equal "new@example.com", user.email
|
||||
end
|
||||
|
||||
test 'should not update password with invalid confirmation' do
|
||||
user = create_user
|
||||
assert_not user.update_with_password(:current_password => '123456',
|
||||
:password => 'pass321', :password_confirmation => 'other')
|
||||
assert user.reload.valid_password?('123456')
|
||||
assert_not user.update_with_password(:current_password => '12345678',
|
||||
:password => 'pass4321', :password_confirmation => 'other')
|
||||
assert user.reload.valid_password?('12345678')
|
||||
end
|
||||
|
||||
test 'should clean up password fields on failure' do
|
||||
user = create_user
|
||||
assert_not user.update_with_password(:current_password => '123456',
|
||||
:password => 'pass321', :password_confirmation => 'other')
|
||||
assert_not user.update_with_password(:current_password => '12345678',
|
||||
:password => 'pass4321', :password_confirmation => 'other')
|
||||
assert user.password.blank?
|
||||
assert user.password_confirmation.blank?
|
||||
end
|
||||
@@ -160,9 +179,9 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should not update password without password' do
|
||||
user = create_user
|
||||
user.update_without_password(:password => 'pass321', :password_confirmation => 'pass321')
|
||||
assert !user.reload.valid_password?('pass321')
|
||||
assert user.valid_password?('123456')
|
||||
user.update_without_password(:password => 'pass4321', :password_confirmation => 'pass4321')
|
||||
assert !user.reload.valid_password?('pass4321')
|
||||
assert user.valid_password?('12345678')
|
||||
end
|
||||
|
||||
test 'downcase_keys with validation' do
|
||||
@@ -186,4 +205,4 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -232,19 +232,19 @@ class LockableTest < ActiveSupport::TestCase
|
||||
swap Devise, :lock_strategy => :failed_attempts do
|
||||
assert_same_content Devise::Models::Lockable.required_fields(User), [
|
||||
:failed_attempts,
|
||||
:unlock_at,
|
||||
:locked_at,
|
||||
:unlock_token
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'required_fields should contain only failed_attempts and unlock_at when the strategies are time and failed_attempts are enabled' do
|
||||
test 'required_fields should contain only failed_attempts and locked_at when the strategies are time and failed_attempts are enabled' do
|
||||
swap Devise, :unlock_strategy => :time do
|
||||
swap Devise, :lock_strategy => :failed_attempts do
|
||||
assert_same_content Devise::Models::Lockable.required_fields(User), [
|
||||
:failed_attempts,
|
||||
:unlock_at
|
||||
:locked_at
|
||||
]
|
||||
end
|
||||
end
|
||||
@@ -260,4 +260,14 @@ class LockableTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not return a locked unauthenticated message if in paranoid mode' do
|
||||
swap Devise, :paranoid => :true do
|
||||
user = create_user
|
||||
user.failed_attempts = Devise.maximum_attempts + 1
|
||||
user.lock_access!
|
||||
|
||||
assert_equal :invalid, user.unauthenticated_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,7 +21,8 @@ class SerializableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on JSON' do
|
||||
assert_equal %w(created_at email facebook_token id updated_at username), from_json().keys.sort
|
||||
keys = from_json().keys.select{ |key| !key.include?("id") }
|
||||
assert_equal %w(created_at email facebook_token updated_at username), keys.sort
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on JSON even if a new except is provided' do
|
||||
|
||||
@@ -1,26 +1,5 @@
|
||||
require 'test_helper'
|
||||
|
||||
class Configurable < User
|
||||
devise :database_authenticatable, :confirmable, :rememberable, :timeoutable, :lockable,
|
||||
:stretches => 15, :pepper => 'abcdef', :allow_unconfirmed_access_for => 5.days,
|
||||
:remember_for => 7.days, :timeout_in => 15.minutes, :unlock_in => 10.days
|
||||
end
|
||||
|
||||
class WithValidation < Admin
|
||||
devise :database_authenticatable, :validatable, :password_length => 2..6
|
||||
end
|
||||
|
||||
class UserWithValidation < User
|
||||
validates_presence_of :username
|
||||
end
|
||||
|
||||
class Several < Admin
|
||||
devise :validatable
|
||||
devise :lockable
|
||||
end
|
||||
|
||||
class Inheritable < Admin
|
||||
end
|
||||
require 'test_models'
|
||||
|
||||
class ActiveRecordTest < ActiveSupport::TestCase
|
||||
def include_module?(klass, mod)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
require 'mongoid/version'
|
||||
|
||||
Mongoid.configure do |config|
|
||||
config.master = Mongo::Connection.new('127.0.0.1', 27017).db("devise-test-suite")
|
||||
config.connect_to("devise-test-suite")
|
||||
config.use_utc = true
|
||||
config.include_root_in_json = true
|
||||
end
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
setup do
|
||||
User.delete_all
|
||||
Admin.delete_all
|
||||
Mongoid.purge!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,4 +5,5 @@ class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
before_filter :current_user, :unless => :devise_controller?
|
||||
before_filter :authenticate_user!, :if => :devise_controller?
|
||||
respond_to *Mime::SET.map(&:to_sym)
|
||||
end
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
class Users::Mailer < Devise::Mailer
|
||||
default :from => 'custom@example.com'
|
||||
default :from => 'custom@example.com'
|
||||
end
|
||||
|
||||
class Users::ReplyToMailer < Devise::Mailer
|
||||
default :from => 'custom@example.com'
|
||||
default :reply_to => 'custom_reply_to@example.com'
|
||||
end
|
||||
@@ -6,8 +6,8 @@ class Admin
|
||||
include SharedAdmin
|
||||
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => true
|
||||
field :encrypted_password, :type => String, :null => true
|
||||
field :email, :type => String
|
||||
field :encrypted_password, :type => String
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
@@ -24,4 +24,6 @@ class Admin
|
||||
|
||||
## Lockable
|
||||
field :locked_at, :type => Time
|
||||
|
||||
field :active, :type => Boolean, :default => false
|
||||
end
|
||||
|
||||
@@ -7,13 +7,13 @@ module Shim
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def last(options={})
|
||||
def last(options = {})
|
||||
options.delete(:order) if options[:order] == "id"
|
||||
super(options)
|
||||
where(options).last
|
||||
end
|
||||
|
||||
def find_by_email(email)
|
||||
first(:conditions => { :email => email })
|
||||
find_by(:email => email)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ class User
|
||||
field :facebook_token, :type => String
|
||||
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => false, :default => ""
|
||||
field :encrypted_password, :type => String, :null => false, :default => ""
|
||||
field :email, :type => String, :default => ""
|
||||
field :encrypted_password, :type => String, :default => ""
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
|
||||
@@ -85,8 +85,8 @@ Devise.setup do |config|
|
||||
# config.extend_remember_period = false
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length. Default is 6..128.
|
||||
# config.password_length = 6..128
|
||||
# Range for password length. Default is 8..128.
|
||||
# config.password_length = 8..128
|
||||
|
||||
# Regex to use to validate the email address
|
||||
# config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
|
||||
|
||||
@@ -7,7 +7,7 @@ module SharedUser
|
||||
:trackable, :validatable, :omniauthable
|
||||
|
||||
attr_accessor :other_key
|
||||
attr_accessible :username, :email, :password, :password_confirmation, :remember_me
|
||||
attr_accessible :username, :email, :password, :password_confirmation, :remember_me, :confirmation_sent_at
|
||||
|
||||
# They need to be included after Devise is called.
|
||||
extend ExtendMethods
|
||||
|
||||
@@ -25,8 +25,8 @@ class ActiveSupport::TestCase
|
||||
def valid_attributes(attributes={})
|
||||
{ :username => "usertest",
|
||||
:email => generate_unique_email,
|
||||
:password => '123456',
|
||||
:password_confirmation => '123456' }.update(attributes)
|
||||
:password => '12345678',
|
||||
:password_confirmation => '12345678' }.update(attributes)
|
||||
end
|
||||
|
||||
def new_user(attributes={})
|
||||
|
||||
@@ -10,10 +10,11 @@ class ActionDispatch::IntegrationTest
|
||||
user = User.create!(
|
||||
:username => 'usertest',
|
||||
:email => options[:email] || 'user@test.com',
|
||||
:password => options[:password] || '123456',
|
||||
:password_confirmation => options[:password] || '123456',
|
||||
:password => options[:password] || '12345678',
|
||||
:password_confirmation => options[:password] || '12345678',
|
||||
:created_at => Time.now.utc
|
||||
)
|
||||
user.update_attribute(:confirmation_sent_at, options[:confirmation_sent_at]) if options[:confirmation_sent_at]
|
||||
user.confirm! unless options[:confirm] == false
|
||||
user.lock_access! if options[:locked] == true
|
||||
user
|
||||
@@ -36,7 +37,7 @@ class ActionDispatch::IntegrationTest
|
||||
user = create_user(options)
|
||||
visit_with_option options[:visit], new_user_session_path
|
||||
fill_in 'email', :with => options[:email] || 'user@test.com'
|
||||
fill_in 'password', :with => options[:password] || '123456'
|
||||
fill_in 'password', :with => options[:password] || '12345678'
|
||||
check 'remember me' if options[:remember_me] == true
|
||||
yield if block_given?
|
||||
click_button 'Sign In'
|
||||
|
||||
@@ -9,7 +9,7 @@ class TestHelpersTest < ActionController::TestCase
|
||||
self.status = 306
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
test "redirects if attempting to access a page unauthenticated" do
|
||||
get :index
|
||||
assert_redirected_to new_user_session_path
|
||||
@@ -47,6 +47,18 @@ class TestHelpersTest < ActionController::TestCase
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "does not redirect with valid user after failed first attempt" do
|
||||
get :index
|
||||
assert_response :redirect
|
||||
|
||||
user = create_user
|
||||
user.confirm!
|
||||
|
||||
sign_in user
|
||||
get :index
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "redirects if valid user signed out" do
|
||||
user = create_user
|
||||
user.confirm!
|
||||
@@ -58,7 +70,7 @@ class TestHelpersTest < ActionController::TestCase
|
||||
get :index
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
|
||||
test "respects custom failure app" do
|
||||
begin
|
||||
Devise.warden_config.failure_app = CustomFailureApp
|
||||
@@ -69,6 +81,11 @@ class TestHelpersTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "returns the body of a failure app" do
|
||||
get :index
|
||||
assert_equal response.body, "<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>"
|
||||
end
|
||||
|
||||
test "defined Warden after_authentication callback should not be called when sign_in is called" do
|
||||
begin
|
||||
Warden::Manager.after_authentication do |user, auth, opts|
|
||||
|
||||
27
test/test_models.rb
Normal file
27
test/test_models.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
class Configurable < User
|
||||
devise :database_authenticatable, :confirmable, :rememberable, :timeoutable, :lockable,
|
||||
:stretches => 15, :pepper => 'abcdef', :allow_unconfirmed_access_for => 5.days,
|
||||
:remember_for => 7.days, :timeout_in => 15.minutes, :unlock_in => 10.days
|
||||
end
|
||||
|
||||
class WithValidation < Admin
|
||||
devise :database_authenticatable, :validatable, :password_length => 2..6
|
||||
end
|
||||
|
||||
class UserWithValidation < User
|
||||
validates_presence_of :username
|
||||
end
|
||||
|
||||
class UserWithVirtualAttributes < User
|
||||
devise :case_insensitive_keys => [ :email, :email_confirmation ]
|
||||
validates :email, :presence => true, :confirmation => {:on => :create}
|
||||
attr_accessible :email, :email_confirmation
|
||||
end
|
||||
|
||||
class Several < Admin
|
||||
devise :validatable
|
||||
devise :lockable
|
||||
end
|
||||
|
||||
class Inheritable < Admin
|
||||
end
|
||||
Reference in New Issue
Block a user