Compare commits

...

166 Commits
v3.2 ... v3.3.0

Author SHA1 Message Date
Lucas Mazza
6e95b66b54 Release v3.3.0 2014-08-13 13:41:14 -03:00
Lucas Mazza
c37552f552 Update CHANGELOG 2014-08-11 17:36:57 -03:00
Lucas Mazza
5d43d5f3bc ✂️ 2014-08-11 17:35:28 -03:00
Lucas Mazza
6207e03070 Merge pull request #3135 from alexsoble/master
UX feature: heads-up for new users about minimum password length
2014-08-11 17:34:41 -03:00
alexsoble
c3fa8fabcf Restore password length message in case of error 2014-08-10 12:17:54 -04:00
alexsoble
fe015f5a54 Revert "Update routes to match 'sign up'/'log in', incorporate feedback from @carlosantoniodasilva"
This reverts commit de2a24b3d3.
2014-08-10 12:13:35 -04:00
alexsoble
de2a24b3d3 Update routes to match 'sign up'/'log in', incorporate feedback from @carlosantoniodasilva 2014-08-07 11:33:03 -04:00
alexsoble
67d8dd1e94 Replace 'Sign in' with 'Log in' in views, update tests 2014-08-06 13:32:02 -04:00
Lucas Mazza
42c3523632 Update Rails git dependencies 2014-08-06 13:40:26 -03:00
Lucas Mazza
6f75fc7a14 Do not mutate the receiving arguments 2014-08-06 13:28:17 -03:00
Lucas Mazza
876644168b remove intermediate Array manipulation 2014-08-06 13:24:29 -03:00
Lucas Mazza
880146668b Update devise_group documentation 2014-08-06 13:24:10 -03:00
Lucas Mazza
086b77ae6d Update CHANGELOG 2014-08-06 13:23:52 -03:00
alexsoble
039b75ba83 Incorporated edits from @lucasmazza, wrote integration tests for password reminder feature 2014-08-06 11:04:46 -04:00
Lucas Mazza
eb9db7ba3a Coerce time objects serialized as Strings before doing the timeoutable comparisons.
The comparison only fails on Ruby 1.9.3, when we need to parse it properly back
to a Time instance.

Related to #2930.
2014-08-05 14:58:27 -03:00
alexsoble
e65c26e1e7 Only display password length warning if validatable module is included 2014-08-05 10:22:47 -04:00
alexsoble
c38accd648 Tell new signups about minimum password length in registrations/new.html.erb 2014-08-04 15:53:40 -04:00
Lucas Mazza
447b7030f8 Work around I18n recent failures. 2014-07-29 18:27:34 -03:00
Lucas Mazza
3cd6e650ef 'eval_block' shouldn't be used since it is a private API.
This method was made private on Rails master @ d2d3376903
2014-07-29 18:22:42 -03:00
Lucas Mazza
8a4fd04436 Update dependencies 2014-07-29 15:58:15 -03:00
José Valim
66db52ce31 Merge pull request #3113 from jherdman/patch-1
Silence Warning Regarding Use of Splat
2014-07-11 21:09:36 +02:00
James Herdman
b64f165154 Silence Warning Regarding Use of Splat
I was seeing the following in my console:

```
/home/vagrant/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/devise-3.2.4/app/controllers/devise_controller.rb:9: warning: `*' interpreted as argument prefix
/home/vagrant/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/devise-3.2.4/app/controllers/devise_controller.rb:10: warning: `*' interpreted as argument prefix
```

This change silences this warning.
2014-07-11 15:06:56 -04:00
Carlos Antonio da Silva
1d803dd23b Get rid of extra module for group helpers
Just use the existing ClassMethods module which is properly extended
with AS::Concern.
2014-07-10 17:01:26 -03:00
Carlos Antonio da Silva
f1d57d7791 Use a different mapping name for testing the omniauth callback failure
This leaks into Devise mappings overriding the existing :admin one, so
depending on the test seed it fails like this:

    $ TESTOPTS="--seed=9972" rake

    ==> Devise.orm = :active_record
    Run options: --seed=9972

    ...

      1) Failure:
      MappingTest#test_allows_path_to_be_given [./test/mapping_test.rb:31]:
      Expected: "admin_area"
        Actual: "admin"

Using a different name should avoid any test randomization issues.
2014-07-10 08:58:21 -03:00
Carlos Antonio da Silva
da01235a20 Fix test that checks for proper configuration of omniauth callback
Previously the test was raising an ArgumentError by mistake:

    ArgumentError: wrong number of arguments (0 for 1)
        actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:328:in `eval_block'`

The #eval_block method expects a proc/lambda argument that can be
instance_exec'ed, not a real block. In the Rails implementation the block
is passed to #draw, which calls #eval_block internally passing the block
along, but as a Proc argument and not as a block.

Also the error we were raising from #devise_for was a RuntimeError,
changed to the expected ArgumentError. Adding an assertion on top of the
expected message should ensure we won't have this issue again.

This was introduced in 29da146c07, related
to #2802.
2014-07-10 08:53:18 -03:00
Carlos Antonio da Silva
57d7a75b65 Use Devise's swap mechanism in failure app test
Also refactor tests to remove the custom failure app class only used
once in favor of an inline class for the specific test, makes it easier
to follow what's going on.
2014-07-10 08:53:18 -03:00
Carlos Antonio da Silva
2e8aecdac2 Create an anonymous class to test the failure app
No need to have a named class inside the test.
2014-07-10 08:13:06 -03:00
Vasiliy Ermolovich
9938a5e933 add documentation about skip: :all option to devise_for method 2014-07-06 16:35:51 +03:00
Lucas Mazza
9a5783ade3 Update Rails dependency across all lockfiles 2014-07-03 11:50:46 -03:00
Lucas Mazza
50679e1d93 Update Rails version across all the Gemfiles 2014-06-26 20:17:16 -03:00
Lucas Mazza
b6af1675d5 Merge pull request #3082 from greysteil/update-travis
Update Travis config to test on ruby 2.1.2 instead of 2.1.1
2014-06-24 10:23:48 -03:00
Lucas Mazza
520dfe2eb4 Update the overall dependencies and test with mongoid 4.0.0 for now on. 2014-06-24 10:22:26 -03:00
Lucas Mazza
8df6980c9e Update _prefixes override to work with Rails 4.2 2014-06-24 10:06:45 -03:00
José Valim
6f7cd1332b Merge pull request #3083 from jjb/patch-1
changelog detail for expire_all_remember_me_on_sign_out
2014-06-21 10:21:38 +02:00
John Bachir
8c7f6bd2aa changelog detail for expire_all_remember_me_on_sign_out
explain that it's the configurability and not the functionality which is new
2014-06-20 18:01:35 -04:00
Grey Baker
89629e68c9 Update Travis config to test on ruby 2.1.2 instead of 2.1.1 2014-06-20 14:31:15 +01:00
José Valim
f0738098f0 Merge pull request #3079 from Yenwod/add-setup-detail
Add migration setup detail to README
2014-06-19 21:21:17 +02:00
Chris Downey
9abee354f7 Add migration setup detail to README 2014-06-19 15:03:19 -04:00
José Valim
382492ce40 Merge pull request #3077 from ShepBook/minor-readme-grammar
Make minor changes to readme grammar.
2014-06-19 10:49:31 +02:00
Jared Koumentis
d0cb629f81 Make minor changes to readme grammar. 2014-06-19 00:31:37 -04:00
Rafael Mendonça França
a11f54151b Merge pull request #3074 from adamniedzielski/remove-cancan-from-readme
Outdated reference to CanCan in README
2014-06-18 11:11:10 -03:00
Adam Niedzielski
a0b97f5b5d Update README.md
Remove reference to CanCan - it is no longer maintained
2014-06-18 16:03:39 +02:00
José Valim
83c01142a7 Merge pull request #3072 from roryokane/patch-1
Fix grammar and capitalization errors in README
2014-06-16 20:55:49 +02:00
Rory O’Kane
47ba796c26 Fix grammar and capitalization errors in README 2014-06-16 13:43:55 -04:00
José Valim
eeb6060d9d Merge pull request #3054 from cheerfulstoic/devise-neo4j
Changes to support devise-neo4j
2014-06-06 21:08:28 +02:00
José Valim
301539378e Merge pull request #3060 from thomasdarde/patch-1
Update README.md
2014-06-06 21:00:22 +02:00
Thomas Darde
cb48c9c408 Update README.md
Add more description on the way I18n.locale has to be set in case of multi-locale app.
2014-06-06 18:39:06 +02:00
Brian Underwood
74f4442319 User Model.to_adapter directly as suggested by @josevalim 2014-06-06 08:35:42 -07:00
José Valim
2bde395840 Update activatable.rb 2014-06-06 13:03:53 +02:00
José Valim
8b3b3d7955 Merge pull request #3042 from dropletzz/group_helpers
Helper methods for groups of mappings
2014-06-06 12:58:44 +02:00
Brian Underwood
2174e4675e Use User and Admin orm_adapter adapter in tests to support other ORMs (neo4j, in this case) 2014-06-04 21:59:30 -07:00
Lucas Mazza
40068c4cba Merge pull request #3048 from shanab/master
Update README.md
2014-05-29 10:13:10 -03:00
Ahmed Mostafa
37e05380d1 Update README.md
Fixed incorrect method definition.
2014-05-29 16:08:29 +03:00
Brian Underwood
65d7d1ba55 Change test to use acts_like? so that we can have DateTime fields 2014-05-28 22:17:07 -07:00
Giovanni Caniato
dfcb342a8f group methods defined in the current scope 2014-05-28 19:30:03 +02:00
Lucas Mazza
88efa6545f Swap the failure app during the test case properly. 2014-05-28 12:07:25 -03:00
Giovanni Caniato
cb1d6c4684 moved helpers definition from routes to controllers 2014-05-27 11:58:55 +02:00
Giovanni Caniato
8df6a2f38b added groups with their helper methods 2014-05-26 16:45:18 +02:00
José Valim
395b5c4237 Merge pull request #3011 from dwhenry/make-devise-more-engine-friendly
Make devise more engine friendly
2014-05-24 20:20:03 +09:00
Lucas Mazza
08d8591dfd Merge pull request #3038 from kushkella/non-bang-method-trackable
added non-bang version of update_tracked_fields
2014-05-24 00:58:06 -03:00
Lucas Mazza
09db3c65ec Merge pull request #3041 from brentkearney/master
Getting Started instructions: clarification on dynamic method names
2014-05-24 00:40:01 -03:00
Brent Kearney
82b60fce15 Changed MODEL to model, as per request. 2014-05-23 15:15:41 -06:00
Brent Kearney
0e14ac3aa7 Updated Getting Started instructions to help avoid confusion around alternate devise MODEL names 2014-05-23 12:26:19 -06:00
Kush Kella
dd56dc7da6 added test for update_tracked_fields method 2014-05-22 11:11:13 -07:00
José Valim
9818038a72 Merge pull request #3029 from randoum/master
lock_access! better failure message
2014-05-22 10:20:41 +02:00
José Valim
6a783c9ec7 Merge pull request #3023 from jphenow/omniauth-cant-cleanup-csrf
Omniauth can't cleanup CSRF
2014-05-22 10:17:48 +02:00
Kush Kella
451be888cb added non-bang version of update_tracked_fields 2014-05-21 16:18:35 -07:00
Jimmy Chen
72f5eae391 Document that we can configure Devise test helpers in spec_helper.rb
Closes #3006 [ci skip]
2014-05-21 20:07:07 -03:00
randoum
4ee2402cd7 lock_access! better failure message 2014-05-16 06:02:11 +08:00
randoum
d8ee3e49cb lock_access! better failure message 2014-05-16 05:57:18 +08:00
David Henry
6a628724ea Ensure I don't leave public methods around that break the test suit.. 2014-05-15 19:42:08 +01:00
David Henry
c5c360cdd9 Add classes for mongoid based tests 2014-05-15 18:59:51 +01:00
Jon Phenow
d47c370916 * Allows CSRF cleanup to be turned off for certain strategy types
* Defaults Authenticatable CSRF cleanup
2014-05-15 09:16:31 -05:00
Lucas Mazza
2f6edfd0c5 Update dependencies. 2014-05-14 23:41:29 -03:00
Lucas Mazza
fa36464268 Silence the OmniAuth logger during tests. 2014-05-14 23:25:29 -03:00
Lauro Caetano
b51c3c1911 Merge pull request #3024 from diegosouzapb/master
Update README.md
2014-05-11 01:30:19 -03:00
Diego Souza Rodrigues
d1a9f220a1 Update README.md
The old Michael Hartl's online book link was broken. I guess this link is its substitute.
2014-05-11 01:11:48 -03:00
David Henry
426560a4db Attempt without adding engine to application 2014-05-08 00:46:19 +01:00
Carlos Antonio da Silva
6129215afe Simplify test that verifies multiple warden blocks 2014-05-07 18:53:09 -03:00
Carlos Antonio da Silva
916e1d8da9 No need for instance vars on these tests 2014-05-07 18:50:50 -03:00
Carlos Antonio da Silva
1e8a387f34 Merge pull request #3020 from adrpac/master
Fix Rails 4 detection
2014-05-07 17:22:33 -03:00
Adrian Pacała
a2376d6ca1 Fix Rails 4 detection 2014-05-07 22:17:40 +02:00
José Valim
f611b63069 Merge pull request #3017 from adrpac/master
Use inet column type when generating migrations under PostgreSQL
2014-05-07 10:08:39 +02:00
Adrian Pacała
fa1a864731 Generate inet columns for Rails 4 only 2014-05-07 09:18:10 +02:00
Adrian Pacała
53504f7e28 Generate inet columns for postgresql 2014-05-07 08:50:21 +02:00
David Henry
c7099ac5b0 Merge branch 'master' of github.com:plataformatec/devise into make-devise-more-engine-friendly
Conflicts:
	.travis.yml
	Gemfile.lock
2014-05-07 00:22:16 +01:00
David Henry
bec913fc07 Clean up the code. 2014-05-06 23:31:59 +01:00
David Henry
b5da4e82d0 Add full tests around confirmation when using devise_for with router_name 2014-05-06 23:07:24 +01:00
David Henry
ceafc710ef Start adding tests to the engine routing tests. 2014-05-06 00:56:58 +01:00
David Henry
2d3ca4dc31 get everything working with the engine included and devise routes declared within it. 2014-05-05 23:50:26 +01:00
David Henry
18da4b1eff Stash as test have broken 2014-05-05 23:23:55 +01:00
David Henry
1e8e8516f0 Simplify access to router_name using the existing scope lookup. 2014-05-05 23:19:03 +01:00
Lucas Mazza
a51036196a Merge pull request #3013 from aditya-kapoor/split-send_reset_password_instructions
Split send_reset_password_instructions for better hooking
2014-05-05 17:45:09 -03:00
aditya-kapoor
2fc25a8c68 rename method + remove extra db call 2014-05-06 01:23:55 +05:30
aditya-kapoor
c8fcbde2af split send_reset_password_instructions into two parts for better hooking 2014-05-05 13:41:08 +05:30
Lucas Mazza
a3fc587c24 Update Travis config to test on ruby 2.1.1 instead of 2.1.0 2014-05-04 22:45:07 -03:00
Lucas Mazza
3014bcbc45 Update Rails HEAD Gemfile dependencies. 2014-05-04 21:36:38 -03:00
Lucas Mazza
4110ab3228 Update 4-0-stable Gemfile dependencies. 2014-05-04 21:30:06 -03:00
Lucas Mazza
303145c8b7 Update 3-2-stable Gemfile dependencies. 2014-05-04 21:28:01 -03:00
Lucas Mazza
7bab20e55e Update main Gemfile dependencies. 2014-05-04 21:21:45 -03:00
David Henry
33873426ad Use 2.1 instead of 2.1.0
travis-ci/travis-ci#2220
2014-05-04 22:59:29 +01:00
David Henry
3e8fce5081 Make sure I include the new class into the gem 2014-05-04 12:53:25 +01:00
David Henry
d875c01bc2 Extract routing context to its own file. 2014-05-03 23:22:00 +01:00
David Henry
feff27aaee Add description around the new method. 2014-05-03 22:47:27 +01:00
David Henry
1dd84a8244 Don't couple the routing object to the whole system.. pass around the RoutingDetails object instead.
NOTE: RoutingDetails is supposed to be a simple data transfer object.
2014-05-03 22:46:04 +01:00
David Henry
2dee54bc86 make the find_mapping! method return a mapping object 2014-05-03 22:41:32 +01:00
David Henry
23761aded2 Add find_mapping! method to return the router_name instead of overloading find_scope! 2014-05-03 22:37:21 +01:00
David Henry
e085526b6e Get the logic in the right order and fix variable naming (and run the tests) 2014-05-02 00:22:20 +01:00
David Henry
38b347ac00 Fix bug in the tests 2014-05-02 00:17:17 +01:00
David Henry
9e8371c293 Make after_sign_out_path_for and after_inactive_sign_up_path_for aware of router name if declared in devise_for declaration. 2014-05-01 23:49:46 +01:00
David Henry
da49ed23f9 Start adding code to allow devise_for to specify the engine context (router_name) to be used. 2014-05-01 23:39:05 +01:00
José Valim
873e57e97d Merge pull request #3008 from weih/update-legacy-comment
Update legacy comment [ci skip]
2014-05-01 14:19:08 +02:00
Hao Wei
11c8875479 Update legacy comment 2014-05-01 19:49:37 +08:00
Lucas Mazza
1ad09f9cfc Improve CHANGELOG and move assignment to outside the if statement. 2014-04-28 11:28:48 -03:00
Lucas Mazza
13a8ad81ee Merge pull request #2997 from parallel588/master
fixed store location with bad URL
2014-04-28 11:26:56 -03:00
Lucas Mazza
b4c06d1ded Merge pull request #3004 from kento1218/topic/confirmation-success-redirect
Fix Devise::ConfirmationsController#after_confirmation_path_for
2014-04-28 10:56:31 -03:00
kento1218
d63b6b7b9d Fix Devise::ConfirmationsController#after_confirmation_path_for
after_confirmation_path_for checks whether the user already signed in
by calling signed_in? after confirmation succeeded.
Since it was called without scope specification, the user treated as
signed in inappropriately when the user signed in as another resource
(such as 'admin').
2014-04-28 20:44:00 +09:00
Lauro Caetano
1fbc165b98 Merge pull request #3001 from daniely/patch-1
Update README.md
2014-04-27 01:17:55 -03:00
daniely
9cafe0dff6 Update README.md
Correct grammar from "on progress" to "in progress"
2014-04-27 10:25:16 +08:00
Maxim Pechnikov
a841e6c4f0 fixed storing location with bad URL 2014-04-25 19:14:32 +04:00
José Valim
24327c7310 Merge pull request #2990 from westonplatter/master
remove new line to keep convention with other methods
2014-04-20 22:55:48 +02:00
Weston Platter
0b096c961a remove new line to keep convention with other methods 2014-04-20 13:57:31 -06:00
José Valim
0a27a0da3b Merge pull request #2985 from crismali/present-over-not-blank
Switched all instances of 'not blank?' to 'present?'
2014-04-18 08:41:02 +02:00
Michael Crismali
f37b10ef87 Switched all instances of 'not blank?' to 'present?' 2014-04-17 20:34:28 -05:00
Rafael Mendonça França
081ea9e0ba Add CHANGELOG entry for #2978 [ci skip] 2014-04-15 18:47:16 -03:00
Rafael Mendonça França
f60892be23 Merge pull request #2978 from rossta/support_for_multiple_warden_config_blocks
Support multiple warden configuration blocks
2014-04-15 18:46:28 -03:00
Ross Kaffenberger
5f32cd25fd support multiple warden configuration blocks
Changes the behavior of `Devise.warden` such that calling it multiple
times with different blocks will result in a call to each block on
`Devise.configure_warden!` rather than "last block wins". This is
especially used for plugins that wish to extend warden functionality
without clobbering base app configuration or vice versa.
2014-04-15 17:20:21 -04:00
Lucas Mazza
38e868dc79 Update Travis encrypted keys 2014-04-09 19:24:25 -03:00
Lucas Mazza
67613117aa Merge pull request #2955 from lucasmazza/lm-cached-bundle
Cache bundle results on Travis to S3
2014-04-09 19:21:29 -03:00
José Valim
61c497d173 Merge pull request #2968 from plataformatec/sign_out_not_logged_in_user
Check if there is a logged user before logout.
2014-04-09 18:17:06 +02:00
Lauro Caetano
571dead19b Check if there is a signed in user before sign out.
Only execute the `SessionsController#destroy` if there is a signed in
user, otherwise it will raise
`ActionController::InvalidAuthenticityToken`.

Fixes #2934.
2014-04-09 10:25:44 -03:00
Lucas Mazza
b0b18fb805 Merge pull request #2965 from sadjow/use-port-option-on-default-url-options
Use port option in default url options for ActionMailer
2014-04-04 21:14:04 -03:00
Lucas Mazza
5c57d88505 Cache bundle results on Travis to S3 2014-04-04 20:22:39 -03:00
Sadjow Leão
a2bd5631da Use port option in default url options for ActionMailer 2014-04-04 19:01:12 -03:00
José Valim
6466d5c517 Merge pull request #2964 from plataformatec/invalidate_all_sessions_on_logout
Add configuration to invalidate all the remember me tokens when the user signs out.
2014-04-04 21:28:22 +02:00
Lauro Caetano
f7fdde1ab0 Add the invalidate_all_sessions_on_logout configuration to invalidate
all the remember me tokens when the user signs out.
2014-04-04 16:17:26 -03:00
José Valim
947169e4f5 Merge pull request #2960 from kgiszczak/redirect-url-tweaks
Use full urls instead of just paths when redirecting in failure app.
2014-04-04 17:41:41 +02:00
Kamil Giszczak
9cada8d2d4 Use scope instead of constraints to define routes.
It works the same with rails 3 and rails 4.
2014-04-04 16:07:37 +02:00
José Valim
314f731a66 Update CHANGELOG 2014-04-04 09:50:13 +02:00
José Valim
b786c384d5 Remove need for raw session inspect 2014-04-03 21:00:12 +02:00
Lucas Mazza
6027787930 Merge pull request #2954 from plataformatec/lm-last-request-at-json-serialization
Serialize the `last_request_at` entry as an Integer
2014-04-02 22:58:14 -03:00
Kamil Giszczak
a38f2f96b5 Use _url routes instead of _path 2014-04-02 15:42:41 +02:00
José Valim
d019e1ed1a Merge pull request #2958 from karlentwistle/master
Find a resource based off its encrypted reset_password_token
2014-03-31 19:16:20 +02:00
Karl Entwistle
58b311a93f Use the ORM Adapter API 2014-03-31 15:24:55 +01:00
Karl Entwistle
de57ef83fb Find a resource based off its encrypted reset_password_token 2014-03-31 14:58:52 +01:00
Lucas Mazza
145ce9e1de Merge pull request #2956 from Yasserius/patch-1
before_filter turned into before_action
2014-03-29 16:01:54 -03:00
Yasserius
7adf95b945 before_filter turned into before_action 2014-03-30 00:52:00 +06:00
Lucas Mazza
71d8dd37bb Update mongoid dependency. 2014-03-28 23:11:53 -03:00
Lucas Mazza
da0c27393f Serialize the last_request_at entry as an Integer
Pushing the `Time` object inside the session has inconsistencies
across different serializers and we should use a more primitive type
so we don't need any specific parsing logic for the JSON serializer.
2014-03-28 22:51:56 -03:00
Lucas Mazza
f19e82021f Add some spaces around the curly brackets. 2014-03-28 20:53:50 -03:00
Lucas Mazza
3d0559bc4d Merge pull request #2953 from jbnunn/README_ConfiguredParams
Fixed documentation for configured_permitted_parameters
2014-03-28 20:51:36 -03:00
J. Nunn
739c187e81 Fixed documentation for configured_permitted_parameters 2014-03-28 17:21:50 -05:00
Vasiliy Ermolovich
937ed6291c Merge pull request #2946 from naveda89/patch-1
Fixed path syntax error on README.md
2014-03-25 16:46:06 +02:00
Alvaro Naveda
aa456c9d07 Fixed path syntax error on README.md
Minor fix on the configuring controllers section.
2014-03-25 15:43:46 +01:00
José Valim
5b49bd3450 Improve docs for update_with_password
Closes #2942
2014-03-24 21:49:48 +01:00
José Valim
da34c54093 Merge pull request #2937 from dpehrson/registrations-controller-failure-yield
Ensure registration controller block yields happen on failure in addition to success
2014-03-24 18:58:29 +09:00
Daniel Pehrson
90e55409e1 Upgrade stray legacy hash syntax to 1.9 syntax. 2014-03-21 15:24:25 -04:00
Daniel Pehrson
ce3ead6b5f Ensure registration controller block yields happen on failure in addition to success and closes #2936.
Now with 100% more unit tests.
2014-03-21 10:29:14 -04:00
Lucas Mazza
d439bc409c Fix typo on CHANGELOG 2014-03-17 12:11:01 -03:00
Lucas Mazza
8d7a72326a Add a note about #2906 to the CHANGELOG. 2014-03-17 12:10:44 -03:00
Lucas Mazza
59cd0cc240 Merge pull request #2906 from p-originate/master
Grammar/content fixes for email confirmation language
2014-03-17 12:08:07 -03:00
Lucas Mazza
1eab594895 SessionsController#destroy no longer yields the resource object.
If you need access to the current resource when overring the action
use the scope helper (like `current_user`) before calling `super`.

Closes #2926.
2014-03-17 11:52:20 -03:00
Oleg Pudeyev
47845e44a2 Chase language changes in tests 2014-03-03 10:15:33 -05:00
Oleg Pudeyev
dbddce6acd Missed some "instructions about" -> for 2014-02-28 15:12:07 -05:00
Oleg Pudeyev
1a87fd6477 All other text does not use camel case 2014-02-28 02:04:35 -05:00
Oleg Pudeyev
00af1481f8 Grammar/content fixes for email confirmation language
- account -> email address
- was -> has been
2014-02-28 02:04:23 -05:00
88 changed files with 1646 additions and 348 deletions

1
.gitignore vendored
View File

@@ -8,4 +8,3 @@ rdoc/*
pkg
log
test/tmp/*
gemfiles/*.lock

View File

@@ -1,14 +1,21 @@
language: ruby
script: "bundle exec rake test"
before_install:
- gem install bundler -v '>= 1.5.1'
install: script/cached-bundle install --deployment --path vendor/bundle
rvm:
- 1.9.3
- 2.0.0
- 2.1.0
- 2.1.2
env:
- DEVISE_ORM=mongoid
- DEVISE_ORM=active_record
matrix:
- DEVISE_ORM=mongoid
- DEVISE_ORM=active_record
global:
# AMAZON_S3_BUCKET
- secure: "qkeYGn2mpgsgU5tKS9GWvFp/utUF/9O8++Shch24DMnq8OB01TrV5QQ2Elj7sSjMWqw2Pbe56nUCA9eOWXhPglGyIq2AI9E0umsEGZxdRlqqobpiMWs5wl8KZ0cFD1rZm6CwfL8atmcNfTt5TnvsaQ2l/k3TerOT2e66R/Mibk8="
# AMAZON_ACCESS_KEY_ID
- secure: "rTYGUFH9SPN0L7QtdE6Liyy/1z7nGKxqDF9LMRsmNsIfsqxoTPKZ8bCctQ4ksuk9svynGQsLfsda5pA+YvuALzjdWmGcID6ENgOGvoFnhZO5LuJ5f6t0k8gFpV9oBquQgDWzhzrcPYvCUrUYg3GSlHjFSXdPdht3SoYn7PiDaNs="
# AMAZON_SECRET_ACCESS_KEY
- secure: "VJ4qiWMzoleLojCcluX+w0RtaFVc9ybRNo6NODkGhHSaao8+4EX4rETBQG67tNSInk1iuNqCcZAGwC8V/12RXdao3PguRSLD5IiKeT+D78dqFEoP0+yHg4PbmZ6TJXADW3gUv/IOqkW7f/UYGinRaPu7hloyiC498FpQdmMWSNI="
gemfile:
- gemfiles/Gemfile.rails-head
- gemfiles/Gemfile.rails-4.0-stable

View File

@@ -1,8 +1,35 @@
### Unreleased
* enhancements
* bug fixes
### 3.3.0
* enhancements
* Support multiple warden configuration blocks on devise configuration. (by @rossta)
* Previously, when a user signed out, all remember me tokens for all sessions/browsers would be
invalidated, and this behavior could not be changed. This behavior is now configurable via
`expire_all_remember_me_on_sign_out`. The default continues to be true. (by @laurocaetano)
* Default email messages was updated with grammar fixes, check the diff on
#2906 for the updated copy (by @p-originate)
* Allow a resource to be found based on its encrypted password token (by @karlentwistle)
* Adds `devise_group`, a macro to define controller helpers for multiple mappings at once. (by @dropletzz)
* The default views now use `Log in` instead of `Sign in` and have a hint about the minimum password length if
the current scope is using the `validatable` module (by @alexsoble)
* bug fix
* Check if there is a signed in user before executing the `SessionsController#destroy`.
* `SessionsController#destroy` no longer yields the `resource` to receiving block,
since the resource isn't loaded in the action. If you need access to the current
resource when overring the action use the scope helper (like `current_user`) before
calling `super`
* Serialize the `last_request_at` entry as an Integer
* Ensure registration controller block yields happen on failure in addition to success (by @dpehrson)
* Only valid paths will be stored for redirections (by @parallel588)
### 3.2.4
* enchancements
* enhancements
* `bcrypt` dependency updated due https://github.com/codahale/bcrypt-ruby/pull/86.
* View generator now can generate specific views with the `-v` flag, like `rails g devise:views -v sessions` (by @kayline)

10
Gemfile
View File

@@ -2,16 +2,16 @@ source "https://rubygems.org"
gemspec
gem "rails", "~> 4.0.0"
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "rails", "~> 4.1.0"
gem "omniauth", "~> 1.2.0"
gem "omniauth-oauth2", "~> 1.1.0"
gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.0.0", require: false
gem "mocha", "~> 1.1", require: false
end
platforms :jruby do
@@ -25,5 +25,5 @@ platforms :ruby do
end
group :mongoid do
gem "mongoid", github: "mongoid/mongoid", branch: "master"
gem "mongoid", "~> 4.0.0"
end

View File

@@ -1,18 +1,7 @@
GIT
remote: git://github.com/mongoid/mongoid.git
revision: 346a79a7d01aa194de80e649916239a18d38ce13
branch: master
specs:
mongoid (4.0.0)
activemodel (~> 4.0.0)
moped (~> 1.5)
origin (~> 1.0)
tzinfo (~> 0.3.22)
PATH
remote: .
specs:
devise (3.2.4)
devise (3.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@@ -22,117 +11,134 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actionmailer (4.0.0)
actionpack (= 4.0.0)
mail (~> 2.5.3)
actionpack (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
erubis (~> 2.7.0)
actionmailer (4.1.4)
actionpack (= 4.1.4)
actionview (= 4.1.4)
mail (~> 2.5.4)
actionpack (4.1.4)
actionview (= 4.1.4)
activesupport (= 4.1.4)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
activemodel (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
activerecord (4.0.0)
activemodel (= 4.0.0)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.0)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activesupport (4.0.0)
i18n (~> 0.6, >= 0.6.4)
minitest (~> 4.2)
multi_json (~> 1.3)
actionview (4.1.4)
activesupport (= 4.1.4)
builder (~> 3.1)
erubis (~> 2.7.0)
activemodel (4.1.4)
activesupport (= 4.1.4)
builder (~> 3.1)
activerecord (4.1.4)
activemodel (= 4.1.4)
activesupport (= 4.1.4)
arel (~> 5.0.0)
activesupport (4.1.4)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
arel (4.0.0)
atomic (1.1.12)
tzinfo (~> 1.1)
arel (5.0.1.20140414130214)
bcrypt (3.1.7)
builder (3.1.4)
bson (2.3.0)
builder (3.2.2)
connection_pool (2.0.0)
erubis (2.7.0)
faraday (0.8.8)
multipart-post (~> 1.2.0)
hashie (1.2.0)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
hashie (3.2.0)
hike (1.2.3)
httpauth (0.2.0)
i18n (0.6.5)
json (1.8.0)
jwt (0.1.8)
multi_json (>= 1.5)
i18n (0.6.11)
json (1.8.1)
jwt (1.0.0)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.4)
mime-types (1.23)
minitest (4.7.5)
mocha (1.0.0)
mime-types (1.25.1)
mini_portile (0.6.0)
minitest (5.4.0)
mocha (1.1.0)
metaclass (~> 0.0.1)
moped (1.5.1)
multi_json (1.7.9)
multipart-post (1.2.0)
nokogiri (1.5.9)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
mongoid (4.0.0)
activemodel (~> 4.0)
moped (~> 2.0.0)
origin (~> 2.1)
tzinfo (>= 0.3.37)
moped (2.0.0)
bson (~> 2.2)
connection_pool (~> 2.0)
optionable (~> 0.2.0)
multi_json (1.10.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
oauth2 (0.9.4)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (~> 1.2)
omniauth (1.0.3)
hashie (~> 1.2)
rack
omniauth-facebook (1.4.0)
omniauth-oauth2 (~> 1.0.2)
omniauth-oauth2 (1.0.3)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
omniauth (1.2.2)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1)
omniauth-oauth2 (1.1.2)
faraday (>= 0.8, < 0.10)
multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
origin (1.1.0)
optionable (0.2.0)
origin (2.1.1)
orm_adapter (0.5.0)
polyglot (0.3.3)
polyglot (0.3.5)
rack (1.5.2)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-test (0.6.2)
rack (>= 1.0)
rails (4.0.0)
actionmailer (= 4.0.0)
actionpack (= 4.0.0)
activerecord (= 4.0.0)
activesupport (= 4.0.0)
rails (4.1.4)
actionmailer (= 4.1.4)
actionpack (= 4.1.4)
actionview (= 4.1.4)
activemodel (= 4.1.4)
activerecord (= 4.1.4)
activesupport (= 4.1.4)
bundler (>= 1.3.0, < 2.0)
railties (= 4.0.0)
sprockets-rails (~> 2.0.0)
railties (4.0.0)
actionpack (= 4.0.0)
activesupport (= 4.0.0)
railties (= 4.1.4)
sprockets-rails (~> 2.0)
railties (4.1.4)
actionpack (= 4.1.4)
activesupport (= 4.1.4)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (10.1.0)
rdoc (4.0.1)
rake (10.3.2)
rdoc (4.1.1)
json (~> 1.4)
ruby-openid (2.2.3)
sprockets (2.10.0)
ruby-openid (2.5.0)
sprockets (2.12.1)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.0.0)
sprockets-rails (2.1.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.7)
thor (0.18.1)
thread_safe (0.1.2)
atomic
sqlite3 (1.3.9)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
treetop (1.4.14)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
tzinfo (1.2.1)
thread_safe (~> 0.1)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
@@ -148,13 +154,13 @@ DEPENDENCIES
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (~> 1.0.0)
mongoid!
omniauth (~> 1.0.0)
mocha (~> 1.1)
mongoid (~> 4.0.0)
omniauth (~> 1.2.0)
omniauth-facebook
omniauth-oauth2 (~> 1.0.0)
omniauth-oauth2 (~> 1.1.0)
omniauth-openid (~> 1.0.1)
rails (~> 4.0.0)
rails (~> 4.1.0)
rdoc
sqlite3
webrat (= 0.7.3)

View File

@@ -27,7 +27,7 @@ It's composed of 10 modules:
* [Validatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Validatable): provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.
* [Lockable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Lockable): locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.
Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby is on progress.
Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby is in progress.
## Information
@@ -83,7 +83,7 @@ You will usually want to write tests for your changes. To run the test suite, g
If you are building your first Rails application, we recommend you to *not* use Devise. Devise requires a good understanding of the Rails Framework. In such cases, we advise you to start a simple authentication system from scratch, today we have two resources:
* Michael Hartl's online book: http://railstutorial.org/chapters/modeling-and-viewing-users-two#top
* Michael Hartl's online book: http://www.railstutorial.org/book/demo_app#sec-modeling_demo_users
* Ryan Bates' Railscast: http://railscasts.com/episodes/250-authentication-from-scratch
Once you have solidified your understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :)
@@ -110,24 +110,28 @@ The generator will install an initializer which describes ALL Devise's configura
rails generate devise MODEL
```
Replace MODEL by the class name used for the applications users, it's frequently `User` but could also be `Admin`. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run `rake db:migrate` as the generator will have created a migration file (if your ORM supports them). This generator also configures your `config/routes.rb` file to point to the Devise controller.
Replace MODEL with the class name used for the applications users (its frequently `User` but could also be `Admin`). This will create a model (if one does not exist) and configure it with default Devise modules. The generator also configures your `config/routes.rb` file to point to the Devise controller.
Next, you need to set up the default url options for the Devise mailer in each environment. Here is a possible configuration for `config/environments/development.rb`:
Next, check the MODEL for any additional configuration options you might want to add, such as confirmable or lockable. If you add an option, be sure to inspect the migration file (created by the generator if your ORM supports them) and uncomment the appropriate section. For example, if you add the confirmable option in the model, you'll need to uncomment the Confirmable section in the migration. Then run `rake db:migrate`
Next, you need to set up the default URL options for the Devise mailer in each environment. Here is a possible configuration for `config/environments/development.rb`:
```ruby
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```
You should restart your application after changing Devise's configuration options. Otherwise you'll run into strange errors like users being unable to login and route helpers being undefined.
### Controller filters and helpers
Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_filter:
Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_action (assuming your devise model is 'User'):
```ruby
before_filter :authenticate_user!
before_action :authenticate_user!
```
If your devise model is something other than User, replace "_user" with "_yourmodel". The same logic applies to the instructions below.
To verify if a user is signed in, use the following helper:
```ruby
@@ -157,7 +161,7 @@ You can also override `after_sign_in_path_for` and `after_sign_out_path_for` to
Notice that if your Devise model is called `Member` instead of `User`, for example, then the helpers available are:
```ruby
before_filter :authenticate_member!
before_action :authenticate_member!
member_signed_in?
@@ -190,7 +194,7 @@ In case you want to permit additional parameters (the lazy way™) you can do wi
```ruby
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
before_action :configure_permitted_parameters, if: :devise_controller?
protected
@@ -200,7 +204,7 @@ class ApplicationController < ActionController::Base
end
```
The above works for any additional fields where the parameters are simple scalar types. If you have nested attributes (say you're using `accepts_nested_parameters_for`), then you will need to tell devise about those nestings and types. Devise allows you to completely change Devise defaults or invoke custom behaviour by passing a block:
The above works for any additional fields where the parameters are simple scalar types. If you have nested attributes (say you're using `accepts_nested_attributes_for`), then you will need to tell devise about those nestings and types. Devise allows you to completely change Devise defaults or invoke custom behaviour by passing a block:
To permit simple scalar values for username and email, use this
@@ -214,7 +218,7 @@ If you have some checkboxes that express the roles a user may take on registrati
```ruby
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(roles: [], :email, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit({ roles: [] }, :email, :password, :password_confirmation) }
end
```
For the list of permitted scalars, and how to declare permitted keys in nested hashes and arrays, see
@@ -285,7 +289,7 @@ If the customization at the views level is not enough, you can customize each co
end
```
Note that in the above example, the controller needs to be created in the `app/controller/admins/` directory.
Note that in the above example, the controller needs to be created in the `app/controllers/admins/` directory.
2. Tell the router to use this controller:
@@ -383,6 +387,8 @@ Take a look at our locale file to check all available messages. You may also be
https://github.com/plataformatec/devise/wiki/I18n
Caution: Devise Controllers inherit from ApplicationController. If your app uses multiple locales, you should be sure to set I18n.locale in ApplicationController
### Test helpers
Devise includes some test 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:
@@ -393,7 +399,7 @@ class ActionController::TestCase
end
```
If you're using RSpec, you can put the following inside a file named `spec/support/devise.rb`:
If you're using RSpec, you can put the following inside a file named `spec/support/devise.rb` or in your `spec/spec_helper.rb`:
```ruby
RSpec.configure do |config|
@@ -411,11 +417,11 @@ sign_out :user # sign_out(scope)
sign_out @user # sign_out(resource)
```
There are two things that is important to keep in mind:
There are two things that are important to keep in mind:
1. These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;
2. If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
2. If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from the router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
```ruby
@request.env["devise.mapping"] = Devise.mappings[:user]
@@ -463,7 +469,7 @@ admin_session
Alternatively, you can simply run the Devise generator.
Keep in mind that those models will have completely different routes. They **do not** and **cannot** share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend you to use a role-based approach, by either providing a role column or using [CanCan](https://github.com/ryanb/cancan).
Keep in mind that those models will have completely different routes. They **do not** and **cannot** share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend you to use a role-based approach, by either providing a role column or using a dedicated gem for authorization.
### Other ORMs

View File

@@ -38,7 +38,7 @@ class Devise::ConfirmationsController < DeviseController
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
if signed_in?
if signed_in?(resource_name)
signed_in_root_path(resource)
else
new_session_path(resource_name)

View File

@@ -5,6 +5,10 @@ class Devise::RegistrationsController < DeviseController
# GET /resource/sign_up
def new
build_resource({})
@validatable = devise_mapping.validatable?
if @validatable
@minimum_password_length = resource_class.password_length.min
end
respond_with self.resource
end
@@ -12,8 +16,9 @@ class Devise::RegistrationsController < DeviseController
def create
build_resource(sign_up_params)
if resource.save
yield resource if block_given?
resource_saved = resource.save
yield resource if block_given?
if resource_saved
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
@@ -25,6 +30,10 @@ class Devise::RegistrationsController < DeviseController
end
else
clean_up_passwords resource
@validatable = devise_mapping.validatable?
if @validatable
@minimum_password_length = resource_class.password_length.min
end
respond_with resource
end
end
@@ -41,8 +50,9 @@ class Devise::RegistrationsController < DeviseController
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
if update_resource(resource, account_update_params)
yield resource if block_given?
resource_updated = update_resource(resource, account_update_params)
yield resource if block_given?
if resource_updated
if is_flashing_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
@@ -110,7 +120,10 @@ class Devise::RegistrationsController < DeviseController
# The path used after sign up for inactive accounts. You need to overwrite
# this method in your own RegistrationsController.
def after_inactive_sign_up_path_for(resource)
respond_to?(:root_path) ? root_path : "/"
scope = Devise::Mapping.find_scope!(resource)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : self
context.respond_to?(:root_path) ? context.root_path : "/"
end
# The default url to be used after updating a resource. You need to overwrite

View File

@@ -1,6 +1,7 @@
class Devise::SessionsController < DeviseController
prepend_before_filter :require_no_authentication, only: [ :new, :create ]
prepend_before_filter :allow_params_authentication!, only: :create
prepend_before_filter :verify_signed_out_user, only: :destroy
prepend_before_filter only: [ :create, :destroy ] { request.env["devise.skip_timeout"] = true }
# GET /resource/sign_in
@@ -21,17 +22,10 @@ class Devise::SessionsController < DeviseController
# DELETE /resource/sign_out
def destroy
redirect_path = after_sign_out_path_for(resource_name)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
yield resource if block_given?
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to redirect_path }
end
yield if block_given?
respond_to_on_destroy
end
protected
@@ -50,4 +44,33 @@ class Devise::SessionsController < DeviseController
def auth_options
{ scope: resource_name, recall: "#{controller_path}#new" }
end
private
# Check if there is no signed in user before doing the sign out.
#
# If there is no signed in user, it will set the flash message and redirect
# to the after_sign_out path.
def verify_signed_out_user
if all_signed_out?
set_flash_message :notice, :already_signed_out if is_flashing_format?
respond_to_on_destroy
end
end
def all_signed_out?
users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
users.all?(&:blank?)
end
def respond_to_on_destroy
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
end
end
end

View File

@@ -6,8 +6,8 @@ class DeviseController < Devise.parent_controller.constantize
helpers = %w(resource scope_name resource_name signed_in_resource
resource_class resource_params devise_mapping)
hide_action *helpers
helper_method *helpers
hide_action(*helpers)
helper_method(*helpers)
prepend_before_filter :assert_is_devise_resource!
respond_to :html if mimes_for_respond_to.empty?
@@ -44,7 +44,7 @@ class DeviseController < Devise.parent_controller.constantize
# loaded before even having a request object.
def _prefixes #:nodoc:
@_prefixes ||= if self.class.scoped_views? && request && devise_mapping
super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
["#{devise_mapping.scoped_path}/#{controller_name}"] + super
else
super
end

View File

@@ -6,7 +6,7 @@
<div><%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %></div>
<div><%= f.label :password %><br />
<div><%= f.label :password %> <% if @validatable %><i>(<%= @minimum_password_length %> characters minimum)</i><% end %><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation %><br />

View File

@@ -1,4 +1,4 @@
<h2>Sign in</h2>
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div><%= f.label :email %><br />
@@ -11,7 +11,7 @@
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= f.submit "Sign in" %></div>
<div><%= f.submit "Log in" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -1,5 +1,5 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Sign in", new_session_path(resource_name) %><br />
<%= link_to "Log in", new_session_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>

View File

@@ -3,26 +3,26 @@
en:
devise:
confirmations:
confirmed: "Your account was successfully confirmed."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
confirmed: "Your email address has been successfully confirmed."
send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
failure:
already_authenticated: "You are already signed in."
inactive: "Your account is not activated yet."
invalid: "Invalid email or password."
locked: "Your account is locked."
last_attempt: "You have one more attempt before your account will be locked."
not_found_in_database: "Invalid email or password."
last_attempt: "You have one more attempt before your account is locked."
not_found_in_database: "Invalid email address or password."
timeout: "Your session expired. Please sign in again to continue."
unauthenticated: "You need to sign in or sign up before continuing."
unconfirmed: "You have to confirm your account before continuing."
unconfirmed: "You have to confirm your email address before continuing."
mailer:
confirmation_instructions:
subject: "Confirmation instructions"
reset_password_instructions:
subject: "Reset password instructions"
unlock_instructions:
subject: "Unlock Instructions"
subject: "Unlock instructions"
omniauth_callbacks:
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
success: "Successfully authenticated from %{kind} account."
@@ -30,22 +30,23 @@ en:
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
updated: "Your password was changed successfully. You are now signed in."
updated_not_active: "Your password was changed successfully."
updated: "Your password has been changed successfully. You are now signed in."
updated_not_active: "Your password has been changed successfully."
registrations:
destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon."
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
signed_up: "Welcome! You have signed up successfully."
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
updated: "You updated your account successfully."
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
updated: "Your account has been updated successfully."
sessions:
signed_in: "Signed in successfully."
signed_out: "Signed out successfully."
already_signed_out: "Signed out successfully."
unlocks:
send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes."
send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
errors:
messages:

View File

@@ -3,15 +3,15 @@ source "https://rubygems.org"
gemspec path: '..'
gem "rails", github: 'rails/rails', branch: '3-2-stable'
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "omniauth", "~> 1.2.0"
gem "omniauth-oauth2", "~> 1.1.0"
gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.0.0", require: false
gem "mocha", "~> 1.1", require: false
end
platforms :jruby do

View File

@@ -0,0 +1,166 @@
GIT
remote: git://github.com/rails/rails.git
revision: 11fd052aa815ae0255ea5b2463e88138fb3fec61
branch: 3-2-stable
specs:
actionmailer (3.2.19)
actionpack (= 3.2.19)
mail (~> 2.5.4)
actionpack (3.2.19)
activemodel (= 3.2.19)
activesupport (= 3.2.19)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.19)
activesupport (= 3.2.19)
builder (~> 3.0.0)
activerecord (3.2.19)
activemodel (= 3.2.19)
activesupport (= 3.2.19)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.19)
activemodel (= 3.2.19)
activesupport (= 3.2.19)
activesupport (3.2.19)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
rails (3.2.19)
actionmailer (= 3.2.19)
actionpack (= 3.2.19)
activerecord (= 3.2.19)
activeresource (= 3.2.19)
activesupport (= 3.2.19)
bundler (~> 1.0)
railties (= 3.2.19)
railties (3.2.19)
actionpack (= 3.2.19)
activesupport (= 3.2.19)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
PATH
remote: ..
specs:
devise (3.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
GEM
remote: https://rubygems.org/
specs:
arel (3.0.3)
bcrypt (3.1.7)
builder (3.0.4)
erubis (2.7.0)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
hashie (3.2.0)
hike (1.2.3)
i18n (0.6.11)
journey (1.0.4)
json (1.8.1)
jwt (1.0.0)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.4)
mime-types (1.25.1)
mini_portile (0.6.0)
mocha (1.1.0)
metaclass (~> 0.0.1)
mongoid (3.1.6)
activemodel (~> 3.2)
moped (~> 1.4)
origin (~> 1.0)
tzinfo (~> 0.3.29)
moped (1.5.2)
multi_json (1.10.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
oauth2 (0.9.4)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (~> 1.2)
omniauth (1.2.2)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1)
omniauth-oauth2 (1.1.2)
faraday (>= 0.8, < 0.10)
multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
origin (1.1.0)
orm_adapter (0.5.0)
polyglot (0.3.5)
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-ssl (1.3.4)
rack
rack-test (0.6.2)
rack (>= 1.0)
rake (10.3.2)
rdoc (3.12.2)
json (~> 1.4)
ruby-openid (2.5.0)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.9)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.40)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbc-adapter
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (~> 1.1)
mongoid (~> 3.0)
omniauth (~> 1.2.0)
omniauth-facebook
omniauth-oauth2 (~> 1.1.0)
omniauth-openid (~> 1.0.1)
rails!
rdoc
sqlite3
webrat (= 0.7.3)

View File

@@ -3,15 +3,15 @@ source "https://rubygems.org"
gemspec path: '..'
gem "rails", github: 'rails/rails', branch: '4-0-stable'
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "omniauth", "~> 1.2.0"
gem "omniauth-oauth2", "~> 1.1.0"
gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.0.0", require: false
gem "mocha", "~> 1.1", require: false
end
platforms :jruby do
@@ -25,5 +25,5 @@ platforms :ruby do
end
group :mongoid do
gem "mongoid", github: "mongoid/mongoid", branch: "master"
gem "mongoid", "~> 4.0.0"
end

View File

@@ -0,0 +1,162 @@
GIT
remote: git://github.com/rails/rails.git
revision: 6d95e04c6968fb7597ea5dbd08b31f271fb87c9c
branch: 4-0-stable
specs:
actionmailer (4.0.8)
actionpack (= 4.0.8)
mail (~> 2.5, >= 2.5.4)
actionpack (4.0.8)
activesupport (= 4.0.8)
builder (~> 3.1.0)
erubis (~> 2.7.0)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
activemodel (4.0.8)
activesupport (= 4.0.8)
builder (~> 3.1.0)
activerecord (4.0.8)
activemodel (= 4.0.8)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.8)
arel (~> 4.0.0)
activesupport (4.0.8)
i18n (~> 0.6, >= 0.6.9)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
rails (4.0.8)
actionmailer (= 4.0.8)
actionpack (= 4.0.8)
activerecord (= 4.0.8)
activesupport (= 4.0.8)
bundler (>= 1.3.0, < 2.0)
railties (= 4.0.8)
sprockets-rails (~> 2.0)
railties (4.0.8)
actionpack (= 4.0.8)
activesupport (= 4.0.8)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
PATH
remote: ..
specs:
devise (3.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
GEM
remote: https://rubygems.org/
specs:
activerecord-deprecated_finders (1.0.3)
arel (4.0.2)
bcrypt (3.1.7)
bson (2.3.0)
builder (3.1.4)
connection_pool (2.0.0)
erubis (2.7.0)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
hashie (3.2.0)
hike (1.2.3)
i18n (0.6.11)
json (1.8.1)
jwt (1.0.0)
mail (2.6.1)
mime-types (>= 1.16, < 3)
metaclass (0.0.4)
mime-types (2.3)
mini_portile (0.6.0)
minitest (4.7.5)
mocha (1.1.0)
metaclass (~> 0.0.1)
mongoid (4.0.0)
activemodel (~> 4.0)
moped (~> 2.0.0)
origin (~> 2.1)
tzinfo (>= 0.3.37)
moped (2.0.0)
bson (~> 2.2)
connection_pool (~> 2.0)
optionable (~> 0.2.0)
multi_json (1.10.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
oauth2 (0.9.4)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (~> 1.2)
omniauth (1.2.2)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1)
omniauth-oauth2 (1.1.2)
faraday (>= 0.8, < 0.10)
multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
optionable (0.2.0)
origin (2.1.1)
orm_adapter (0.5.0)
rack (1.5.2)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-test (0.6.2)
rack (>= 1.0)
rake (10.3.2)
rdoc (4.1.1)
json (~> 1.4)
ruby-openid (2.5.0)
sprockets (2.12.1)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.1.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.9)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
tzinfo (0.3.40)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbc-adapter
activerecord-jdbcsqlite3-adapter
devise!
jruby-openssl
mocha (~> 1.1)
mongoid (~> 4.0.0)
omniauth (~> 1.2.0)
omniauth-facebook
omniauth-oauth2 (~> 1.1.0)
omniauth-openid (~> 1.0.1)
rails!
rdoc
sqlite3
webrat (= 0.7.3)

View File

@@ -2,16 +2,19 @@ source "https://rubygems.org"
gemspec path: '..'
gem "rails", github: 'rails/rails'
gem "omniauth", "~> 1.0.0"
gem "omniauth-oauth2", "~> 1.0.0"
gem "rails", github: "rails/rails"
gem "arel", github: "rails/arel"
gem "rack", github: "rack/rack"
gem "i18n", github: "svenfuchs/i18n"
gem "omniauth", "~> 1.2.0"
gem "omniauth-oauth2", "~> 1.1.0"
gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.0.0", require: false
gem "mocha", "~> 1.1", require: false
end
platforms :jruby do

View File

@@ -0,0 +1,190 @@
GIT
remote: git://github.com/mongoid/mongoid.git
revision: 8cb17e9839973b76295cf87189e91a5ffcc03ab0
branch: master
specs:
mongoid (4.0.0)
activemodel (~> 4.0)
moped (~> 2.0.0)
origin (~> 2.1)
tzinfo (>= 0.3.37)
GIT
remote: git://github.com/rack/rack.git
revision: 92811eec6e86cb4dba52b3969c4dd66e639df158
specs:
rack (1.6.0.alpha)
GIT
remote: git://github.com/rails/arel.git
revision: 66cee768bc163537087037a583f60639eae49fc3
specs:
arel (6.0.0.20140505020427)
GIT
remote: git://github.com/rails/rails.git
revision: d5be08347fb7ff758572775ec93247a3ca886004
specs:
actionmailer (4.2.0.alpha)
actionpack (= 4.2.0.alpha)
actionview (= 4.2.0.alpha)
mail (~> 2.5, >= 2.5.4)
actionpack (4.2.0.alpha)
actionview (= 4.2.0.alpha)
activesupport (= 4.2.0.alpha)
rack (~> 1.6.0.alpha)
rack-test (~> 0.6.2)
actionview (4.2.0.alpha)
activesupport (= 4.2.0.alpha)
builder (~> 3.1)
erubis (~> 2.7.0)
activemodel (4.2.0.alpha)
activesupport (= 4.2.0.alpha)
builder (~> 3.1)
activerecord (4.2.0.alpha)
activemodel (= 4.2.0.alpha)
activesupport (= 4.2.0.alpha)
arel (~> 6.0.0)
activesupport (4.2.0.alpha)
i18n (>= 0.7.0.dev, < 0.8)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
rails (4.2.0.alpha)
actionmailer (= 4.2.0.alpha)
actionpack (= 4.2.0.alpha)
actionview (= 4.2.0.alpha)
activemodel (= 4.2.0.alpha)
activerecord (= 4.2.0.alpha)
activesupport (= 4.2.0.alpha)
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.0.alpha)
sprockets-rails (~> 2.1)
railties (4.2.0.alpha)
actionpack (= 4.2.0.alpha)
activesupport (= 4.2.0.alpha)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
GIT
remote: git://github.com/svenfuchs/i18n.git
revision: cb679b8cdbab675703a3f88de4d48a48f7b50e06
specs:
i18n (0.7.0.dev)
PATH
remote: ..
specs:
devise (3.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
GEM
remote: https://rubygems.org/
specs:
bcrypt (3.1.7)
bson (2.3.0)
builder (3.2.2)
connection_pool (2.0.0)
erubis (2.7.0)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
hashie (3.2.0)
hike (1.2.3)
json (1.8.1)
jwt (1.0.0)
mail (2.6.1)
mime-types (>= 1.16, < 3)
metaclass (0.0.4)
mime-types (2.3)
mini_portile (0.6.0)
minitest (5.4.0)
mocha (1.1.0)
metaclass (~> 0.0.1)
moped (2.0.0)
bson (~> 2.2)
connection_pool (~> 2.0)
optionable (~> 0.2.0)
multi_json (1.10.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
oauth2 (0.9.4)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (~> 1.2)
omniauth (1.2.2)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1)
omniauth-oauth2 (1.1.2)
faraday (>= 0.8, < 0.10)
multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2)
omniauth-openid (1.0.1)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
optionable (0.2.0)
origin (2.1.1)
orm_adapter (0.5.0)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-test (0.6.2)
rack (>= 1.0)
rake (10.3.2)
rdoc (4.1.1)
json (~> 1.4)
ruby-openid (2.5.0)
sprockets (2.12.1)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.1.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.9)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
tzinfo (1.2.1)
thread_safe (~> 0.1)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbc-adapter
activerecord-jdbcsqlite3-adapter
arel!
devise!
i18n!
jruby-openssl
mocha (~> 1.1)
mongoid!
omniauth (~> 1.2.0)
omniauth-facebook
omniauth-oauth2 (~> 1.1.0)
omniauth-openid (~> 1.0.1)
rack!
rails!
rdoc
sqlite3
webrat (= 0.7.3)

View File

@@ -134,6 +134,10 @@ module Devise
mattr_accessor :extend_remember_period
@@extend_remember_period = false
# If true, all the remember me tokens are going to be invalidated when the user signs out.
mattr_accessor :expire_all_remember_me_on_sign_out
@@expire_all_remember_me_on_sign_out = true
# Time interval you can access your account before confirming your account.
# nil - allows unconfirmed access for unlimited time
mattr_accessor :allow_unconfirmed_access_for
@@ -268,7 +272,7 @@ module Devise
# Private methods to interface with Warden.
mattr_accessor :warden_config
@@warden_config = nil
@@warden_config_block = nil
@@warden_config_blocks = []
# When true, enter in paranoid mode to avoid user enumeration.
mattr_accessor :paranoid
@@ -400,7 +404,7 @@ module Devise
# Sets warden configuration using a block that will be invoked on warden
# initialization.
#
# Devise.initialize do |config|
# Devise.setup do |config|
# config.allow_unconfirmed_access_for = 2.days
#
# config.warden do |manager|
@@ -409,7 +413,7 @@ module Devise
# end
# end
def self.warden(&block)
@@warden_config_block = block
@@warden_config_blocks << block
end
# Specify an omniauth provider.
@@ -463,7 +467,7 @@ module Devise
end
end
@@warden_config_block.try :call, Devise.warden_config
@@warden_config_blocks.map { |block| block.call Devise.warden_config }
true
end
end

View File

@@ -11,6 +11,68 @@ module Devise
end
module ClassMethods
# Define authentication filters and accessor helpers for a group of mappings.
# These methods are useful when you are working with multiple mappings that
# share some functionality. They are pretty much the same as the ones
# defined for normal mappings.
#
# Example:
#
# inside BlogsController (or any other controller, it doesn't matter which):
# devise_group :blogger, contains: [:user, :admin]
#
# Generated methods:
# authenticate_blogger! # Redirects unless user or admin are signed in
# blogger_signed_in? # Checks whether there is either a user or an admin signed in
# current_blogger # Currently signed in user or admin
# current_bloggers # Currently signed in user and admin
#
# Use:
# before_filter :authenticate_blogger! # Redirects unless either a user or an admin are authenticated
# before_filter ->{ authenticate_blogger! :admin } # Redirects to the admin login page
# current_blogger :user # Preferably returns a User if one is signed in
#
def devise_group(group_name, opts={})
mappings = "[#{ opts[:contains].map { |m| ":#{m}" }.join(',') }]"
class_eval <<-METHODS, __FILE__, __LINE__ + 1
def authenticate_#{group_name}!(favourite=nil, opts={})
unless #{group_name}_signed_in?
mappings = #{mappings}
mappings.unshift mappings.delete(favourite.to_sym) if favourite
mappings.each do |mapping|
opts[:scope] = mapping
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
end
end
end
def #{group_name}_signed_in?
#{mappings}.any? do |mapping|
warden.authenticate?(scope: mapping)
end
end
def current_#{group_name}(favourite=nil)
mappings = #{mappings}
mappings.unshift mappings.delete(favourite.to_sym) if favourite
mappings.each do |mapping|
current = warden.authenticate(scope: mapping)
return current if current
end
nil
end
def current_#{group_name.to_s.pluralize}
#{mappings}.map do |mapping|
warden.authenticate(scope: mapping)
end.compact
end
helper_method "current_#{group_name}", "current_#{group_name.to_s.pluralize}", "#{group_name}_signed_in?"
METHODS
end
def log_process_action(payload)
payload[:status] ||= 401 unless payload[:exception]
super
@@ -102,9 +164,16 @@ module Devise
# tries to find a resource_root_path, otherwise it uses the root_path.
def signed_in_root_path(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
router_name = Devise.mappings[scope].router_name
home_path = "#{scope}_root_path"
if respond_to?(home_path, true)
send(home_path)
context = router_name ? send(router_name) : self
if context.respond_to?(home_path, true)
context.send(home_path)
elsif context.respond_to?(:root_path)
context.root_path
elsif respond_to?(:root_path)
root_path
else
@@ -150,7 +219,10 @@ module Devise
#
# By default it is the root_path.
def after_sign_out_path_for(resource_or_scope)
respond_to?(:root_path) ? root_path : "/"
scope = Devise::Mapping.find_scope!(resource_or_scope)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : self
context.respond_to?(:root_path) ? context.root_path : "/"
end
# Sign in a user and tries to redirect first to the stored location and
@@ -176,10 +248,9 @@ module Devise
# Overwrite Rails' handle unverified request to sign out all scopes,
# clear run strategies and remove cached variables.
def handle_unverified_request
sign_out_all_scopes(false)
super # call the default behaviour which resets/nullifies/raises
request.env["devise.skip_storage"] = true
expire_data_after_sign_out!
super # call the default behaviour which resets the session
sign_out_all_scopes(false)
end
def request_format

View File

@@ -72,7 +72,6 @@ module Devise
def sign_out_all_scopes(lock=true)
users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
warden.raw_session.inspect
warden.logout
expire_data_after_sign_out!
warden.clear_strategies_cache!

View File

@@ -33,14 +33,20 @@ module Devise
#
def store_location_for(resource_or_scope, location)
session_key = stored_location_key_for(resource_or_scope)
if location
uri = URI.parse(location)
uri = parse_uri(location)
if uri
session[session_key] = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
end
end
private
def parse_uri(location)
location && URI.parse(location)
rescue URI::InvalidURIError
nil
end
def stored_location_key_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
"#{scope}_return_to"

View File

@@ -47,7 +47,9 @@ module Devise
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
def #{method}(resource_or_scope, *args)
scope = Devise::Mapping.find_scope!(resource_or_scope)
_devise_route_context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : _devise_route_context
context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
end
URL_HELPERS
end

View File

@@ -96,15 +96,15 @@ module Devise
request.referrer
end
path || scope_path
path || scope_url
else
scope_path
scope_url
end
end
def scope_path
def scope_url
opts = {}
route = :"new_#{scope}_session_path"
route = :"new_#{scope}_session_url"
opts[:format] = request_format unless skip_format?
config = Rails.application.config
@@ -114,8 +114,8 @@ module Devise
if context.respond_to?(route)
context.send(route, opts)
elsif respond_to?(:root_path)
root_path(opts)
elsif respond_to?(:root_url)
root_url(opts)
else
"/"
end

View File

@@ -1,7 +1,6 @@
# Deny user access whenever their account is not active yet. All strategies that inherits from
# Devise::Strategies::Authenticatable and uses the validate already check if the user is active_for_authentication?
# before actively signing them in. However, we need this as hook to validate the user activity
# in each request and in case the user is using other strategies beside Devise ones.
# Deny user access whenever their account is not active yet.
# We need this as hook to validate the user activity on each request
# and in case the user is using other strategies beside Devise ones.
Warden::Manager.after_set_user do |record, warden, options|
if record && record.respond_to?(:active_for_authentication?) && !record.active_for_authentication?
scope = options[:scope]

View File

@@ -1,5 +1,7 @@
Warden::Manager.after_authentication do |record, warden, options|
if Devise.clean_up_csrf_token_on_authentication
clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) ||
warden.winning_strategy.clean_up_csrf?
if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy
warden.request.session.try(:delete, :_csrf_token)
end
end

View File

@@ -9,6 +9,13 @@ Warden::Manager.after_set_user do |record, warden, options|
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
last_request_at = warden.session(scope)['last_request_at']
if last_request_at.is_a? Integer
last_request_at = Time.at(last_request_at).utc
elsif last_request_at.is_a? String
last_request_at = Time.parse(last_request_at)
end
proxy = Devise::Hooks::Proxy.new(warden)
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
@@ -22,7 +29,7 @@ Warden::Manager.after_set_user do |record, warden, options|
end
unless env['devise.skip_trackable']
warden.session(scope)['last_request_at'] = Time.now.utc
warden.session(scope)['last_request_at'] = Time.now.utc.to_i
end
end
end

View File

@@ -23,7 +23,8 @@ module Devise
#
class Mapping #:nodoc:
attr_reader :singular, :scoped_path, :path, :controllers, :path_names,
:class_name, :sign_out_via, :format, :used_routes, :used_helpers, :failure_app
:class_name, :sign_out_via, :format, :used_routes, :used_helpers,
:failure_app, :router_name
alias :name :singular
@@ -60,6 +61,8 @@ module Devise
@sign_out_via = options[:sign_out_via] || Devise.sign_out_via
@format = options[:format]
@router_name = options[:router_name]
default_failure_app(options)
default_controllers(options)
default_path_names(options)

View File

@@ -236,17 +236,17 @@ module Devise
end
def postpone_email_change?
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && !self.email.blank?
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && self.email.present?
@bypass_confirmation_postpone = false
postpone
end
def reconfirmation_required?
self.class.reconfirmable && @reconfirmation_required && !self.email.blank?
self.class.reconfirmable && @reconfirmation_required && self.email.present?
end
def send_confirmation_notification?
confirmation_required? && !@skip_confirmation_notification && !self.email.blank?
confirmation_required? && !@skip_confirmation_notification && self.email.present?
end
def after_confirmation

View File

@@ -55,9 +55,13 @@ module Devise
self.password = self.password_confirmation = nil
end
# Update record attributes when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects :password and
# :password_confirmation if they are blank.
# Update record attributes when :current_password matches, otherwise
# returns error on :current_password.
#
# This method also rejects the password field if it is blank (allowing
# users to change relevant information like the e-mail without changing
# their password). In case the password field is rejected, the confirmation
# is also rejected as long as it is also blank.
def update_with_password(params, *options)
current_password = params.delete(:current_password)

View File

@@ -115,10 +115,10 @@ module Devise
# leaks the existence of an account.
if Devise.paranoid
super
elsif access_locked? || (lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?)
:locked
elsif lock_strategy_enabled?(:failed_attempts) && last_attempt?
:last_attempt
elsif lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?
:locked
else
super
end

View File

@@ -45,14 +45,10 @@ module Devise
# Resets reset password token and send reset password instructions by email.
# Returns the token sent in the e-mail.
def send_reset_password_instructions
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
token = set_reset_password_token
send_reset_password_instructions_notification(token)
self.reset_password_token = enc
self.reset_password_sent_at = Time.now.utc
self.save(validate: false)
send_devise_notification(:reset_password_instructions, raw, {})
raw
token
end
# Checks if the reset password token sent is within the limit time.
@@ -90,7 +86,27 @@ module Devise
def after_password_reset
end
def set_reset_password_token
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
self.reset_password_token = enc
self.reset_password_sent_at = Time.now.utc
self.save(validate: false)
raw
end
def send_reset_password_instructions_notification(token)
send_devise_notification(:reset_password_instructions, token, {})
end
module ClassMethods
# Attempt to find a user by password reset token. If a user is found, return it
# If a user is not found, return nil
def with_reset_password_token(token)
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, token)
to_adapter.find_first(reset_password_token: reset_password_token)
end
# Attempt to find a user by its email. If a record is found, send new
# password instructions to it. If user is not found, returns a new user
# with an email not found error.

View File

@@ -58,7 +58,7 @@ module Devise
def forget_me!
return unless persisted?
self.remember_token = nil if respond_to?(:remember_token=)
self.remember_created_at = nil
self.remember_created_at = nil if self.class.expire_all_remember_me_on_sign_out
save(validate: false)
end
@@ -122,7 +122,7 @@ module Devise
end
end
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options)
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options, :expire_all_remember_me_on_sign_out)
end
end
end

View File

@@ -15,7 +15,7 @@ module Devise
[:current_sign_in_at, :current_sign_in_ip, :last_sign_in_at, :last_sign_in_ip, :sign_in_count]
end
def update_tracked_fields!(request)
def update_tracked_fields(request)
old_current, new_current = self.current_sign_in_at, Time.now.utc
self.last_sign_in_at = old_current || new_current
self.current_sign_in_at = new_current
@@ -26,7 +26,10 @@ module Devise
self.sign_in_count ||= 0
self.sign_in_count += 1
end
def update_tracked_fields!(request)
update_tracked_fields(request)
save(validate: false) or raise "Devise trackable could not save #{inspect}." \
"Please make sure a model using trackable can be saved at sign in."
end

View File

@@ -129,7 +129,8 @@ module ActionDispatch::Routing
#
# devise_for :users, module: "users"
#
# * skip: tell which controller you want to skip routes from being created:
# * skip: tell which controller you want to skip routes from being created.
# It accepts :all as an option, meaning it will not generate any route at all:
#
# devise_for :users, skip: :sessions
#
@@ -153,6 +154,8 @@ module ActionDispatch::Routing
#
# * defaults: works the same as Rails' defaults
#
# * router_name: allows application level router name to be overwritten for the current scope
#
# ==== Scoping
#
# Following Rails 3 routes DSL, you can nest devise_for calls inside a scope:
@@ -224,7 +227,7 @@ module ActionDispatch::Routing
raise_no_devise_method_error!(mapping.class_name) unless mapping.to.respond_to?(:devise)
rescue NameError => e
raise unless mapping.class_name == resource.to_s.classify
warn "[WARNING] You provided devise_for #{resource.inspect} but there is " <<
warn "[WARNING] You provided devise_for #{resource.inspect} but there is " \
"no model #{mapping.class_name} defined in your application"
next
rescue NoMethodError => e
@@ -234,13 +237,12 @@ module ActionDispatch::Routing
if options[:controllers] && options[:controllers][:omniauth_callbacks]
unless mapping.omniauthable?
msg = "Mapping omniauth_callbacks on a resource that is not omniauthable\n"
msg << "Please add `devise :omniauthable` to the `#{mapping.class_name}` model"
raise msg
raise ArgumentError, "Mapping omniauth_callbacks on a resource that is not omniauthable\n" \
"Please add `devise :omniauthable` to the `#{mapping.class_name}` model"
end
end
routes = mapping.used_routes
routes = mapping.used_routes
devise_scope mapping.name do
with_devise_exclusive_scope mapping.fullpath, mapping.name, options do

View File

@@ -16,6 +16,13 @@ module Devise
valid_for_params_auth? || valid_for_http_auth?
end
# Override and set to false for things like OmniAuth that technically
# run through Authentication (user_set) very often, which would normally
# reset CSRF data in the session
def clean_up_csrf?
true
end
private
# Receives a resource and check if it is valid by calling valid_for_authentication?

View File

@@ -1,3 +1,3 @@
module Devise
VERSION = "3.2.4".freeze
VERSION = "3.3.0".freeze
end

View File

@@ -53,8 +53,8 @@ module ActiveRecord
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.#{ip_column} :current_sign_in_ip
t.#{ip_column} :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
@@ -68,6 +68,23 @@ module ActiveRecord
# t.datetime :locked_at
RUBY
end
def ip_column
# Padded with spaces so it aligns nicely with the rest of the columns.
"%-8s" % (inet? ? "inet" : "string")
end
def inet?
rails4? && postgresql?
end
def rails4?
Rails.version.start_with? '4'
end
def postgresql?
ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
end
end
end
end

View File

@@ -6,7 +6,7 @@ Some setup you must do manually if you haven't yet:
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.

View File

@@ -132,6 +132,9 @@ Devise.setup do |config|
# The time the user will be remembered without asking for credentials again.
# config.remember_for = 2.weeks
# Invalidates all the remember me tokens when the user signs out.
config.expire_all_remember_me_on_sign_out = true
# If true, extends the user's remember period when remembered via cookie.
# config.extend_remember_period = false

49
script/cached-bundle Executable file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Usage: cached-bundle install --deployment
#
# After running `bundle`, caches the `vendor/bundle` directory to S3.
# On the next run, restores the cached directory before running `bundle`.
# When `Gemfile.lock` changes, the cache gets rebuilt.
#
# Requirements:
# - Gemfile.lock
# - TRAVIS_REPO_SLUG
# - TRAVIS_RUBY_VERSION
# - AMAZON_S3_BUCKET
# - script/s3-put
# - bundle
# - curl
#
# Author: Mislav Marohnić
set -e
compute_md5() {
local output="$(openssl md5)"
echo "${output##* }"
}
download() {
curl --tcp-nodelay -qsfL "$1" -o "$2"
}
gemfile="${BUNDLE_GEMFILE:-Gemfile}"
bundle_fullpath="$(dirname $gemfile)/vendor/bundle"
bundle_path=${bundle_fullpath#$PWD/}
gemfile_hash="$(compute_md5 <"${gemfile}.lock")"
cache_name="${TRAVIS_RUBY_VERSION}-${gemfile_hash}.tgz"
fetch_url="http://${AMAZON_S3_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
if download "$fetch_url" "$cache_name"; then
echo "Reusing cached bundle ${cache_name}"
tar xzf "$cache_name"
fi
bundle "$@"
if [ ! -f "$cache_name" ] && [ -n "$AMAZON_SECRET_ACCESS_KEY" ]; then
echo "Caching \`${bundle_path}' to S3"
tar czf "$cache_name" "$bundle_path"
script/s3-put "$cache_name" "${AMAZON_S3_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
fi

71
script/s3-put Executable file
View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bash
# Usage: s3-put <FILE> <S3_BUCKET>[:<PATH>] [<CONTENT_TYPE>]
#
# Uploads a file to the Amazon S3 service.
# Outputs the URL for the newly uploaded file.
#
# Requirements:
# - AMAZON_ACCESS_KEY_ID
# - AMAZON_SECRET_ACCESS_KEY
# - openssl
# - curl
#
# Author: Mislav Marohnić
set -e
authorization() {
local signature="$(string_to_sign | hmac_sha1 | base64)"
echo "AWS ${AMAZON_ACCESS_KEY_ID?}:${signature}"
}
hmac_sha1() {
openssl dgst -binary -sha1 -hmac "${AMAZON_SECRET_ACCESS_KEY?}"
}
base64() {
openssl enc -base64
}
bin_md5() {
openssl dgst -binary -md5
}
string_to_sign() {
echo "$http_method"
echo "$content_md5"
echo "$content_type"
echo "$date"
echo "x-amz-acl:$acl"
printf "/$bucket/$remote_path"
}
date_string() {
LC_TIME=C date "+%a, %d %h %Y %T %z"
}
file="$1"
bucket="${2%%:*}"
remote_path="${2#*:}"
content_type="$3"
if [ -z "$remote_path" ] || [ "$remote_path" = "$bucket" ]; then
remote_path="${file##*/}"
fi
http_method=PUT
acl="public-read"
content_md5="$(bin_md5 < "$file" | base64)"
date="$(date_string)"
url="https://$bucket.s3.amazonaws.com/$remote_path"
curl -qsSf -T "$file" \
-H "Authorization: $(authorization)" \
-H "x-amz-acl: $acl" \
-H "Date: $date" \
-H "Content-MD5: $content_md5" \
-H "Content-Type: $content_type" \
"$url"
echo "$url"

View File

@@ -0,0 +1,35 @@
require 'test_helper'
class CustomRegistrationsControllerTest < ActionController::TestCase
tests Custom::RegistrationsController
include Devise::TestHelpers
setup do
request.env["devise.mapping"] = Devise.mappings[:user]
@password = 'password'
@user = create_user(password: @password, password_confirmation: @password).tap(&:confirm!)
end
test "yield resource to block on create success" do
post :create, { user: { email: "user@example.org", password: "password", password_confirmation: "password" } }
assert @controller.create_block_called?, "create failed to yield resource to provided block"
end
test "yield resource to block on create failure" do
post :create, { user: { } }
assert @controller.create_block_called?, "create failed to yield resource to provided block"
end
test "yield resource to block on update success" do
sign_in @user
put :update, { user: { current_password: @password } }
assert @controller.update_block_called?, "update failed to yield resource to provided block"
end
test "yield resource to block on update failure" do
sign_in @user
put :update, { user: { } }
assert @controller.update_block_called?, "update failed to yield resource to provided block"
end
end

View File

@@ -25,6 +25,13 @@ class ControllerAuthenticatableTest < ActionController::TestCase
@controller.signed_in?
end
test 'proxy [group]_signed_in? to authenticate? with each scope' do
[:user, :admin].each do |scope|
@mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
end
@controller.commenter_signed_in?
end
test 'proxy current_user to authenticate with user scope' do
@mock_warden.expects(:authenticate).with(scope: :user)
@controller.current_user
@@ -35,6 +42,20 @@ class ControllerAuthenticatableTest < ActionController::TestCase
@controller.current_admin
end
test 'proxy current_[group] to authenticate with each scope' do
[:user, :admin].each do |scope|
@mock_warden.expects(:authenticate).with(scope: scope).returns(nil)
end
@controller.current_commenter
end
test 'proxy current_[plural_group] to authenticate with each scope' do
[:user, :admin].each do |scope|
@mock_warden.expects(:authenticate).with(scope: scope)
end
@controller.current_commenters
end
test 'proxy current_publisher_account to authenticate with namespaced publisher account scope' do
@mock_warden.expects(:authenticate).with(scope: :publisher_account)
@controller.current_publisher_account
@@ -55,6 +76,14 @@ class ControllerAuthenticatableTest < ActionController::TestCase
@controller.authenticate_admin!
end
test 'proxy authenticate_[group]! to authenticate!? with each scope' do
[:user, :admin].each do |scope|
@mock_warden.expects(:authenticate!).with(scope: scope)
@mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
end
@controller.authenticate_commenter!
end
test 'proxy authenticate_publisher_account! to authenticate with namespaced publisher account scope' do
@mock_warden.expects(:authenticate!).with(scope: :publisher_account)
@controller.authenticate_publisher_account!
@@ -193,6 +222,12 @@ class ControllerAuthenticatableTest < ActionController::TestCase
assert_equal "/foo.bar", @controller.stored_location_for(:user)
end
test 'store bad location for stores a location to redirect back to' do
assert_nil @controller.stored_location_for(:user)
@controller.store_location_for(:user, "/foo.bar\">Carry")
assert_nil @controller.stored_location_for(:user)
end
test 'store location for accepts a resource as argument' do
@controller.store_location_for(User.new, "/foo.bar")
assert_equal "/foo.bar", @controller.stored_location_for(User.new)

View File

@@ -51,7 +51,7 @@ class HelpersTest < ActionController::TestCase
end
test 'resources methods are not controller actions' do
assert @controller.class.action_methods.empty?
assert @controller.class.action_methods.delete_if { |m| m.include? 'commenter' }.empty?
end
test 'require no authentication tests current mapping' do

View File

@@ -12,7 +12,7 @@ class PasswordsControllerTest < ActionController::TestCase
def put_update_with_params
put :update, "user" => {
"reset_password_token" => @raw, "password" => "123456", "password_confirmation" => "123456"
"reset_password_token" => @raw, "password" => "1234567", "password_confirmation" => "1234567"
}
end

View File

@@ -3,10 +3,10 @@ require 'test_helper'
module Devise
def self.yield_and_restore
@@warden_configured = nil
c, b = @@warden_config, @@warden_config_block
c, b = @@warden_config, @@warden_config_blocks
yield
ensure
@@warden_config, @@warden_config_block = c, b
@@warden_config, @@warden_config_blocks = c, b
end
end
@@ -42,14 +42,27 @@ class DeviseTest < ActiveSupport::TestCase
test 'warden manager user configuration through a block' do
Devise.yield_and_restore do
@executed = false
executed = false
Devise.warden do |config|
@executed = true
executed = true
assert_kind_of Warden::Config, config
end
Devise.configure_warden!
assert @executed
assert executed
end
end
test 'warden manager user configuration through multiple blocks' do
Devise.yield_and_restore do
executed = 0
3.times do
Devise.warden { |config| executed += 1 }
end
Devise.configure_warden!
assert_equal 3, executed
end
end

View File

@@ -8,6 +8,18 @@ class FailureTest < ActiveSupport::TestCase
end
end
class FailureWithSubdomain < RootFailureApp
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
scope subdomain: 'sub' do
root to: 'foo#bar'
end
end
include routes.url_helpers
end
class FailureWithI18nOptions < Devise::FailureApp
def i18n_options(options)
options.merge(name: 'Steve')
@@ -42,6 +54,13 @@ class FailureTest < ActiveSupport::TestCase
assert_equal 'http://test.host/users/sign_in', @response.second['Location']
end
test 'returns to the default redirect location considering subdomain' do
call_failure('warden.options' => { scope: :subdomain_user })
assert_equal 302, @response.first
assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
assert_equal 'http://sub.test.host/subdomain_users/sign_in', @response.second['Location']
end
test 'returns to the default redirect location for wildcard requests' do
call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
assert_equal 302, @response.first
@@ -57,6 +76,15 @@ class FailureTest < ActiveSupport::TestCase
end
end
test 'returns to the root path considering subdomain if no session path is available' do
swap Devise, router_name: :fake_app do
call_failure app: FailureWithSubdomain
assert_equal 302, @response.first
assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
assert_equal 'http://sub.test.host/', @response.second['Location']
end
end
if Rails.application.config.respond_to?(:relative_url_root)
test 'returns to the default redirect location considering the relative url root' do
swap Rails.application.config, relative_url_root: "/sample" do
@@ -65,6 +93,14 @@ class FailureTest < ActiveSupport::TestCase
assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
end
end
test 'returns to the default redirect location considering the relative url root and subdomain' do
swap Rails.application.config, relative_url_root: "/sample" do
call_failure('warden.options' => { scope: :subdomain_user })
assert_equal 302, @response.first
assert_equal 'http://sub.test.host/sample/subdomain_users/sign_in', @response.second['Location']
end
end
end
test 'uses the proxy failure message as symbol' do
@@ -203,7 +239,7 @@ class FailureTest < ActiveSupport::TestCase
"warden" => stub_everything
}
call_failure(env)
assert @response.third.body.include?('<h2>Sign in</h2>')
assert @response.third.body.include?('<h2>Log in</h2>')
assert @response.third.body.include?('Invalid email or password.')
end
@@ -214,8 +250,8 @@ class FailureTest < ActiveSupport::TestCase
"warden" => stub_everything
}
call_failure(env)
assert @response.third.body.include?('<h2>Sign in</h2>')
assert @response.third.body.include?('You have to confirm your account before continuing.')
assert @response.third.body.include?('<h2>Log in</h2>')
assert @response.third.body.include?('You have to confirm your email address before continuing.')
end
test 'calls the original controller if inactive account' do
@@ -225,7 +261,7 @@ class FailureTest < ActiveSupport::TestCase
"warden" => stub_everything
}
call_failure(env)
assert @response.third.body.include?('<h2>Sign in</h2>')
assert @response.third.body.include?('<h2>Log in</h2>')
assert @response.third.body.include?('Your account is not activated yet.')
end
end

View File

@@ -37,6 +37,12 @@ if DEVISE_ORM == :active_record
assert_no_file "app/models/monster.rb"
assert_no_migration "db/migrate/devise_create_monsters.rb"
end
test "use string column type for ip addresses" do
run_generator %w(monster)
assert_migration "db/migrate/devise_create_monsters.rb", /t.string :current_sign_in_ip/
assert_migration "db/migrate/devise_create_monsters.rb", /t.string :last_sign_in_ip/
end
end
module RailsEngine

View File

@@ -3,7 +3,9 @@ require 'test_helper'
class DeviseHelperTest < ActionDispatch::IntegrationTest
setup do
model_labels = { models: { user: "utilisateur" } }
# TODO: Remove this hack that fixes the I18n performance safeguards that
# breaks the custom locale.
I18n.available_locales += [:fr]
I18n.backend.store_translations :fr,
{
errors: { messages: { not_saved: {
@@ -48,4 +50,3 @@ class DeviseHelperTest < ActionDispatch::IntegrationTest
assert_contain "Erreur lors de l'enregistrement de 'utilisateur': 2 erreurs"
end
end

View File

@@ -118,13 +118,13 @@ class AuthenticationSanityTest < ActionDispatch::IntegrationTest
assert_not warden.authenticated?(:admin)
end
test 'unauthenticated admin does not set message on sign out' do
test 'unauthenticated admin set message on sign out' do
get destroy_admin_session_path
assert_response :redirect
assert_redirected_to root_path
get root_path
assert_not_contain 'Signed out successfully'
assert_contain 'Signed out successfully'
end
test 'scope uses custom failure app' do
@@ -448,7 +448,7 @@ class AuthenticationOthersTest < ActionDispatch::IntegrationTest
test 'uses the custom controller with the custom controller view' do
get '/admin_area/sign_in'
assert_contain 'Sign in'
assert_contain 'Log in'
assert_contain 'Welcome to "admins/sessions" controller!'
assert_contain 'Welcome to "sessions/new" view!'
end
@@ -711,3 +711,19 @@ class DoubleAuthenticationRedirectTest < ActionDispatch::IntegrationTest
assert_redirected_to '/admin_area/home'
end
end
class DoubleSignOutRedirectTest < ActionDispatch::IntegrationTest
test 'sign out after already having signed out redirects to sign in' do
sign_in_as_user
post destroy_sign_out_via_delete_or_post_session_path
get root_path
assert_contain 'Signed out successfully.'
post destroy_sign_out_via_delete_or_post_session_path
get root_path
assert_contain 'Signed out successfully.'
end
end

View File

@@ -21,7 +21,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
resend_confirmation
assert_current_url '/users/sign_in'
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
assert_contain 'You will receive an email with instructions for how to confirm your email address in a few minutes'
assert_equal 1, ActionMailer::Base.deliveries.size
assert_equal ['please-change-me@config-initializers-devise.com'], ActionMailer::Base.deliveries.first.from
end
@@ -47,6 +47,37 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
assert_have_selector '#error_explanation'
assert_contain /needs to be confirmed within 3 days/
assert_not user.reload.confirmed?
assert_current_url "/users/confirmation?confirmation_token=#{user.raw_confirmation_token}"
end
end
test 'user with valid confirmation token where the token has expired and with application router_name set to a different engine it should raise an error' do
user = create_user(confirm: false, confirmation_sent_at: 4.days.ago)
swap Devise, confirm_within: 3.days, router_name: :fake_engine do
assert_raise ActionView::Template::Error do
visit_user_confirmation_with_token(user.raw_confirmation_token)
end
end
end
test 'user with valid confirmation token where the token has expired and with application router_name set to a different engine and route overrides back to main it shows the path' do
user = create_user(confirm: false, confirmation_sent_at: 4.days.ago)
swap Devise, confirm_within: 3.days, router_name: :fake_engine do
visit user_on_main_app_confirmation_path(confirmation_token: user.raw_confirmation_token)
assert_current_url "/user_on_main_apps/confirmation?confirmation_token=#{user.raw_confirmation_token}"
end
end
test 'user with valid confirmation token where the token has expired with router overrides different engine it shows the path' do
user = create_user(confirm: false, confirmation_sent_at: 4.days.ago)
swap Devise, confirm_within: 3.days do
visit user_on_engine_confirmation_path(confirmation_token: user.raw_confirmation_token)
assert_current_url "/user_on_engines/confirmation?confirmation_token=#{user.raw_confirmation_token}"
end
end
@@ -56,7 +87,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
assert_not user.confirmed?
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/users/sign_in'
assert user.reload.confirmed?
end
@@ -98,7 +129,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
swap Devise, allow_unconfirmed_access_for: 0.days do
sign_in_as_user(confirm: false)
assert_contain 'You have to confirm your account before continuing'
assert_contain 'You have to confirm your email address before continuing'
assert_not warden.authenticated?(:user)
end
end
@@ -128,11 +159,20 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
user = sign_in_as_user(confirm: false)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/'
end
end
test 'user should be redirected to sign in page whenever signed in as another resource at same session already' do
sign_in_as_admin
user = create_user(confirm: false)
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_current_url '/users/sign_in'
end
test 'error message is configurable by resource name' do
store_translations :en, devise: {
failure: { user: { unconfirmed: "Not confirmed user" } }
@@ -187,7 +227,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
fill_in 'email', with: user.email
click_button 'Resend confirmation instructions'
assert_contain "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
assert_contain "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
assert_current_url "/users/sign_in"
end
end
@@ -203,7 +243,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
assert_not_contain "1 error prohibited this user from being saved:"
assert_not_contain "Email not found"
assert_contain "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
assert_contain "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
assert_current_url "/users/sign_in"
end
end
@@ -232,7 +272,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
end
assert_current_url '/admin_area/sign_in'
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
assert_contain 'You will receive an email with instructions for how to confirm your email address in a few minutes'
end
test 'admin with valid confirmation token should be able to confirm email after email changed' do
@@ -241,7 +281,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
assert_equal 'new_test@example.com', admin.unconfirmed_email
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
assert_not admin.reload.pending_reconfirmation?
@@ -263,7 +303,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
assert_contain(/Confirmation token(.*)invalid/)
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
assert_contain 'Your account was successfully confirmed.'
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
assert_not admin.reload.pending_reconfirmation?

View File

@@ -42,7 +42,7 @@ class HttpAuthenticationTest < ActionDispatch::IntegrationTest
sign_in_as_new_user_with_http("unknown")
assert_equal 401, status
assert_equal "application/xml; charset=utf-8", headers["Content-Type"]
assert_match "<error>Invalid email or password.</error>", response.body
assert_match "<error>Invalid email address or password.</error>", response.body
end
test 'returns a custom response with www-authenticate and chosen realm' do

View File

@@ -22,7 +22,7 @@ class LockTest < ActionDispatch::IntegrationTest
send_unlock_request
assert_template 'sessions/new'
assert_contain 'You will receive an email with instructions about how to unlock your account in a few minutes'
assert_contain 'You will receive an email with instructions for how to unlock your account in a few minutes'
mail = ActionMailer::Base.deliveries.last
assert_equal 1, ActionMailer::Base.deliveries.size
@@ -182,7 +182,7 @@ class LockTest < ActionDispatch::IntegrationTest
click_button 'Resend unlock instructions'
assert_current_url "/users/sign_in"
assert_contain "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
end
end
@@ -197,7 +197,7 @@ class LockTest < ActionDispatch::IntegrationTest
click_button 'Resend unlock instructions'
assert_current_url "/users/sign_in"
assert_contain "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
end
end
@@ -213,7 +213,7 @@ class LockTest < ActionDispatch::IntegrationTest
assert_not_contain "Email not found"
assert_current_url "/users/sign_in"
assert_contain "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
assert_contain "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
end
end
@@ -225,11 +225,11 @@ class LockTest < ActionDispatch::IntegrationTest
visit new_user_session_path
fill_in 'email', with: user.email
fill_in 'password', with: "abadpassword"
click_button 'Sign in'
click_button 'Log in'
fill_in 'email', with: user.email
fill_in 'password', with: "abadpassword"
click_button 'Sign in'
click_button 'Log in'
assert_current_url "/users/sign_in"
assert_not_contain "locked"

View File

@@ -171,7 +171,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
reset_password
assert_current_url '/'
assert_contain 'Your password was changed successfully. You are now signed in.'
assert_contain 'Your password has been changed successfully. You are now signed in.'
assert user.reload.valid_password?('987654321')
end
@@ -185,7 +185,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
assert_not user.reload.valid_password?('987654321')
reset_password visit: false
assert_contain 'Your password was changed successfully.'
assert_contain 'Your password has been changed successfully.'
assert user.reload.valid_password?('987654321')
end
@@ -204,7 +204,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
request_forgot_password
reset_password
assert_contain 'Your password was changed successfully.'
assert_contain 'Your password has been changed successfully.'
assert_not_contain 'You are now signed in.'
assert_equal new_user_session_path, @request.path
assert !warden.authenticated?(:user)
@@ -218,7 +218,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
request_forgot_password
reset_password
assert_contain 'Your password was changed successfully.'
assert_contain 'Your password has been changed successfully.'
assert !user.reload.access_locked?
assert warden.authenticated?(:user)
end
@@ -230,7 +230,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
request_forgot_password
reset_password
assert_contain 'Your password was changed successfully.'
assert_contain 'Your password has been changed successfully.'
assert !user.reload.access_locked?
assert warden.authenticated?(:user)
end

View File

@@ -17,7 +17,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert warden.authenticated?(:admin)
assert_current_url "/admin_area/home"
admin = Admin.order(:id).last
admin = Admin.to_adapter.find_first(order: [:id, :desc])
assert_equal admin.email, 'new_user@test.com'
end
@@ -36,6 +36,11 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_current_url "/?custom=1"
end
test 'a guest admin should not see a warning about minimum password length' do
get new_admin_session_path
assert_not_contain 'characters minimum'
end
def user_sign_up
ActionMailer::Base.deliveries.clear
@@ -47,16 +52,21 @@ class RegistrationTest < ActionDispatch::IntegrationTest
click_button 'Sign up'
end
test 'a guest user should see a warning about minimum password length' do
get new_user_registration_path
assert_contain '7 characters minimum'
end
test 'a guest user should be able to sign up successfully and be blocked by confirmation' do
user_sign_up
assert_contain 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.'
assert_contain 'A message with a confirmation link has been sent to your email address. Please follow the link to activate your account.'
assert_not_contain 'You have to confirm your account before continuing'
assert_current_url "/"
assert_not warden.authenticated?(:user)
user = User.order(:id).last
user = User.to_adapter.find_first(order: [:id, :desc])
assert_equal user.email, 'new_user@test.com'
assert_not user.confirmed?
end
@@ -103,7 +113,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_contain Devise.rails4? ?
"Password confirmation doesn't match Password" : "Password doesn't match confirmation"
assert_contain "2 errors prohibited"
assert_nil User.first
assert_nil User.to_adapter.find_first
assert_not warden.authenticated?(:user)
end
@@ -149,9 +159,9 @@ class RegistrationTest < ActionDispatch::IntegrationTest
click_button 'Update'
assert_current_url '/'
assert_contain 'You updated your account successfully.'
assert_contain 'Your account has been updated successfully.'
assert_equal "user.new@example.com", User.first.email
assert_equal "user.new@example.com", User.to_adapter.find_first.email
end
test 'a signed in user should still be able to use the website after changing their password' do
@@ -163,7 +173,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
fill_in 'current password', with: '12345678'
click_button 'Update'
assert_contain 'You updated your account successfully.'
assert_contain 'Your account has been updated successfully.'
get users_path
assert warden.authenticated?(:user)
end
@@ -180,7 +190,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_contain 'user@test.com'
assert_have_selector 'form input[value="user.new@example.com"]'
assert_equal "user@test.com", User.first.email
assert_equal "user@test.com", User.to_adapter.find_first.email
end
test 'a signed in user should be able to edit their password' do
@@ -193,9 +203,9 @@ class RegistrationTest < ActionDispatch::IntegrationTest
click_button 'Update'
assert_current_url '/'
assert_contain 'You updated your account successfully.'
assert_contain 'Your account has been updated successfully.'
assert User.first.valid_password?('pass1234')
assert User.to_adapter.find_first.valid_password?('pass1234')
end
test 'a signed in user should not be able to edit their password with invalid confirmation' do
@@ -209,7 +219,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_contain Devise.rails4? ?
"Password confirmation doesn't match Password" : "Password doesn't match confirmation"
assert_not User.first.valid_password?('pas123')
assert_not User.to_adapter.find_first.valid_password?('pas123')
end
test 'a signed in user should be able to cancel their account' do
@@ -217,9 +227,9 @@ class RegistrationTest < ActionDispatch::IntegrationTest
get edit_user_registration_path
click_button "Cancel my account"
assert_contain "Bye! Your account was successfully cancelled. We hope to see you again soon."
assert_contain "Bye! Your account has been successfully cancelled. We hope to see you again soon."
assert User.all.empty?
assert User.to_adapter.find_all.empty?
end
test 'a user should be able to cancel sign up by deleting data in the session' do
@@ -253,7 +263,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<admin>)
admin = Admin.order(:id).last
admin = Admin.to_adapter.find_first(order: [:id, :desc])
assert_equal admin.email, 'new_user@test.com'
end
@@ -262,7 +272,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
user = User.order(:id).last
user = User.to_adapter.find_first(order: [:id, :desc])
assert_equal user.email, 'new_user@test.com'
end
@@ -290,7 +300,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
sign_in_as_user
delete user_registration_path(format: 'xml')
assert_response :success
assert_equal User.count, 0
assert_equal User.to_adapter.find_all.size, 0
end
end
@@ -305,7 +315,7 @@ class ReconfirmableRegistrationTest < ActionDispatch::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.to_adapter.find_first.unconfirmed_email
get edit_admin_registration_path
assert_contain 'Currently waiting confirmation for: admin.new@example.com'
@@ -321,9 +331,9 @@ class ReconfirmableRegistrationTest < ActionDispatch::IntegrationTest
click_button 'Update'
assert_current_url '/admin_area/home'
assert_contain 'You updated your account successfully.'
assert_contain 'Your account has been updated successfully.'
assert Admin.first.valid_password?('pas123')
assert Admin.to_adapter.find_first.valid_password?('pas123')
end
test 'a signed in admin should not see a reconfirmation message if they did not change their email, despite having an unconfirmed email' do
@@ -341,9 +351,9 @@ class ReconfirmableRegistrationTest < ActionDispatch::IntegrationTest
click_button 'Update'
assert_current_url '/admin_area/home'
assert_contain 'You updated your account successfully.'
assert_contain 'Your account has been updated successfully.'
assert_equal "admin.new@example.com", Admin.first.unconfirmed_email
assert Admin.first.valid_password?('pas123')
assert_equal "admin.new@example.com", Admin.to_adapter.find_first.unconfirmed_email
assert Admin.to_adapter.find_first.valid_password?('pas123')
end
end

View File

@@ -8,12 +8,11 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
test 'set last request at in user session after each request' do
sign_in_as_user
old_last_request = last_request_at
assert_not_nil last_request_at
@controller.user_session.delete('last_request_at')
get users_path
assert_not_nil last_request_at
assert_not_equal old_last_request, last_request_at
end
test 'set last request at in user session after each request is skipped if tracking is disabled' do
@@ -180,4 +179,11 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
assert_response :success
assert warden.authenticated?(:user)
end
test 'does not crashes when the last_request_at is a String' do
user = sign_in_as_user
get edit_form_user_path(user, last_request_at: Time.now.utc.to_s)
get users_path
end
end

View File

@@ -10,8 +10,8 @@ class TrackableHooksTest < ActionDispatch::IntegrationTest
sign_in_as_user
user.reload
assert_kind_of Time, user.current_sign_in_at
assert_kind_of Time, user.last_sign_in_at
assert user.current_sign_in_at.acts_like?(:time)
assert user.last_sign_in_at.acts_like?(:time)
assert_equal user.current_sign_in_at, user.last_sign_in_at
assert user.current_sign_in_at >= user.created_at

View File

@@ -53,7 +53,7 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
test 'custom mailer renders parent mailer template' do
Devise.mailer = 'Users::Mailer'
assert_not_blank mail.body.encoded
assert_present mail.body.encoded
end
test 'setup reply to as copy from sender' do
@@ -83,9 +83,9 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
end
test 'body should have link to confirm the account' do
host = ActionMailer::Base.default_url_options[:host]
host, port = ActionMailer::Base.default_url_options.values_at :host, :port
if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/confirmation\?confirmation_token=([^"]+)">}
if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/confirmation\?confirmation_token=([^"]+)">}
assert_equal Devise.token_generator.digest(user.class, :confirmation_token, $1), user.confirmation_token
else
flunk "expected confirmation url regex to match"

View File

@@ -55,7 +55,7 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
test 'custom mailer renders parent mailer template' do
Devise.mailer = 'Users::Mailer'
assert_not_blank mail.body.encoded
assert_present mail.body.encoded
end
test 'setup reply to as copy from sender' do
@@ -79,9 +79,9 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
end
test 'body should have link to confirm the account' do
host = ActionMailer::Base.default_url_options[:host]
host, port = ActionMailer::Base.default_url_options.values_at :host, :port
if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=([^"]+)">}
if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/password/edit\?reset_password_token=([^"]+)">}
assert_equal Devise.token_generator.digest(user.class, :reset_password_token, $1), user.reset_password_token
else
flunk "expected reset password url regex to match"

View File

@@ -56,7 +56,7 @@ class UnlockInstructionsTest < ActionMailer::TestCase
test 'custom mailer renders parent mailer template' do
Devise.mailer = 'Users::Mailer'
assert_not_blank mail.body.encoded
assert_present mail.body.encoded
end
test 'setup reply to as copy from sender' do
@@ -80,9 +80,9 @@ class UnlockInstructionsTest < ActionMailer::TestCase
end
test 'body should have link to unlock the account' do
host = ActionMailer::Base.default_url_options[:host]
host, port = ActionMailer::Base.default_url_options.values_at :host, :port
if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/unlock\?unlock_token=([^"]+)">}
if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/unlock\?unlock_token=([^"]+)">}
assert_equal Devise.token_generator.digest(user.class, :unlock_token, $1), user.unlock_token
else
flunk "expected unlock url regex to match"

View File

@@ -6,7 +6,7 @@ class AuthenticatableTest < ActiveSupport::TestCase
end
test 'find_first_by_auth_conditions allows custom filtering parameters' do
user = User.create!(email: "example@example.com", password: "123456")
user = User.create!(email: "example@example.com", password: "1234567")
assert_equal User.find_first_by_auth_conditions({ email: "example@example.com" }), user
assert_nil User.find_first_by_auth_conditions({ email: "example@example.com" }, id: user.id.to_s.next)
end

View File

@@ -313,4 +313,10 @@ class LockableTest < ActiveSupport::TestCase
end
end
end
test 'should return locked message if user was programatically locked' do
user = create_user
user.lock_access!
assert_equal :locked, user.unauthenticated_message
end
end

View File

@@ -181,4 +181,16 @@ class RecoverableTest < ActiveSupport::TestCase
:reset_password_token
]
end
test 'should return a user based on the raw token' do
user = create_user
raw = user.send_reset_password_instructions
assert_equal User.with_reset_password_token(raw), user
end
test 'should return nil if a user based on the raw token is not found' do
assert_equal User.with_reset_password_token('random-token'), nil
end
end

View File

@@ -55,12 +55,27 @@ class RememberableTest < ActiveSupport::TestCase
assert resource_class.new.respond_to?(:remember_me=)
end
test 'forget_me should clear remember_created_at' do
resource = create_resource
resource.remember_me!
assert_not resource.remember_created_at.nil?
resource.forget_me!
assert resource.remember_created_at.nil?
test 'forget_me should clear remember_created_at if expire_all_remember_me_on_sign_out is true' do
swap Devise, expire_all_remember_me_on_sign_out: true do
resource = create_resource
resource.remember_me!
assert_not_nil resource.remember_created_at
resource.forget_me!
assert_nil resource.remember_created_at
end
end
test 'forget_me should not clear remember_created_at if expire_all_remember_me_on_sign_out is false' do
swap Devise, expire_all_remember_me_on_sign_out: false do
resource = create_resource
resource.remember_me!
assert_not_nil resource.remember_created_at
resource.forget_me!
assert_not_nil resource.remember_created_at
end
end
test 'forget_me should not try to update resource if it has been destroyed' do

View File

@@ -10,4 +10,32 @@ class TrackableTest < ActiveSupport::TestCase
:sign_in_count
]
end
test 'update_tracked_fields should only set attributes but not save the record' do
user = create_user
request = mock
request.stubs(:remote_ip).returns("127.0.0.1")
assert_nil user.current_sign_in_ip
assert_nil user.last_sign_in_ip
assert_nil user.current_sign_in_at
assert_nil user.last_sign_in_at
assert_equal 0, user.sign_in_count
user.update_tracked_fields(request)
assert_equal "127.0.0.1", user.current_sign_in_ip
assert_equal "127.0.0.1", user.last_sign_in_ip
assert_not_nil user.current_sign_in_at
assert_not_nil user.last_sign_in_at
assert_equal 1, user.sign_in_count
user.reload
assert_nil user.current_sign_in_ip
assert_nil user.last_sign_in_ip
assert_nil user.current_sign_in_at
assert_nil user.last_sign_in_at
assert_equal 0, user.sign_in_count
end
end

View File

@@ -86,10 +86,10 @@ class ValidatableTest < ActiveSupport::TestCase
end
end
test 'should require a password with minimum of 6 characters' do
test 'should require a password with minimum of 7 characters' do
user = new_user(password: '12345', password_confirmation: '12345')
assert user.invalid?
assert_equal 'is too short (minimum is 6 characters)', user.errors[:password].join
assert_equal 'is too short (minimum is 7 characters)', user.errors[:password].join
end
test 'should require a password with maximum of 128 characters long' do

View File

@@ -0,0 +1,7 @@
require 'shared_user_without_omniauth'
class UserOnEngine < ActiveRecord::Base
self.table_name = 'users'
include Shim
include SharedUserWithoutOmniauth
end

View File

@@ -0,0 +1,7 @@
require 'shared_user_without_omniauth'
class UserOnMainApp < ActiveRecord::Base
self.table_name = 'users'
include Shim
include SharedUserWithoutOmniauth
end

View File

@@ -6,4 +6,7 @@ class ApplicationController < ActionController::Base
before_filter :current_user, unless: :devise_controller?
before_filter :authenticate_user!, if: :devise_controller?
respond_to *Mime::SET.map(&:to_sym)
devise_group :commenter, contains: [:user, :admin]
end

View File

@@ -0,0 +1,30 @@
class ApplicationWithFakeEngine < ApplicationController
private
helper_method :fake_engine
def fake_engine
@fake_engine ||= FakeEngine.new
end
end
class FakeEngine
def user_on_engine_confirmation_path
'/user_on_engine/confirmation'
end
def new_user_on_engine_session_path
'/user_on_engine/confirmation/new'
end
def new_user_on_engine_registration_path
'/user_on_engine/registration/new'
end
def new_user_on_engine_password_path
'/user_on_engine/password/new'
end
def new_user_on_engine_unlock_path
'/user_on_engine/unlock/new'
end
end

View File

@@ -0,0 +1,21 @@
class Custom::RegistrationsController < Devise::RegistrationsController
def create
super do |resource|
@create_block_called = true
end
end
def update
super do |resource|
@update_block_called = true
end
end
def create_block_called?
@create_block_called == true
end
def update_block_called?
@update_block_called == true
end
end

View File

@@ -6,7 +6,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def sign_in_facebook
user = User.find_by_email('user@test.com')
user = User.to_adapter.find_first(email: 'user@test.com')
user.remember_me = true
sign_in user
render text: ""

View File

@@ -9,7 +9,7 @@ class UsersController < ApplicationController
end
def edit_form
user_session['last_request_at'] = 31.minutes.ago.utc
user_session['last_request_at'] = params.fetch(:last_request_at, 31.minutes.ago.utc)
end
def update_form

View File

@@ -0,0 +1,39 @@
require 'shared_user_without_omniauth'
class UserOnEngine
include Mongoid::Document
include Shim
include SharedUserWithoutOmniauth
field :username, type: String
field :facebook_token, type: String
## Database authenticatable
field :email, type: String, default: ""
field :encrypted_password, type: String, default: ""
## Recoverable
field :reset_password_token, type: String
field :reset_password_sent_at, type: Time
## Rememberable
field :remember_created_at, type: Time
## Trackable
field :sign_in_count, type: Integer, default: 0
field :current_sign_in_at, type: Time
field :last_sign_in_at, type: Time
field :current_sign_in_ip, type: String
field :last_sign_in_ip, type: String
## Confirmable
field :confirmation_token, type: String
field :confirmed_at, type: Time
field :confirmation_sent_at, type: Time
# field :unconfirmed_email, type: String # Only if using reconfirmable
## Lockable
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
field :unlock_token, type: String # Only if unlock strategy is :email or :both
field :locked_at, type: Time
end

View File

@@ -0,0 +1,39 @@
require 'shared_user_without_omniauth'
class UserOnMainApp
include Mongoid::Document
include Shim
include SharedUserWithoutOmniauth
field :username, type: String
field :facebook_token, type: String
## Database authenticatable
field :email, type: String, default: ""
field :encrypted_password, type: String, default: ""
## Recoverable
field :reset_password_token, type: String
field :reset_password_sent_at, type: Time
## Rememberable
field :remember_created_at, type: Time
## Trackable
field :sign_in_count, type: Integer, default: 0
field :current_sign_in_at, type: Time
field :last_sign_in_at, type: Time
field :current_sign_in_ip, type: String
field :last_sign_in_ip, type: String
## Confirmable
field :confirmation_token, type: String
field :confirmed_at, type: Time
field :confirmation_sent_at, type: Time
# field :unconfirmed_email, type: String # Only if using reconfirmable
## Lockable
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
field :unlock_token, type: String # Only if unlock strategy is :email or :both
field :locked_at, type: Time
end

View File

@@ -30,7 +30,7 @@ module RailsApp
config.filter_parameters << :password
config.assets.enabled = false
config.action_mailer.default_url_options = { host: "localhost:3000" }
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
# This was used to break devise in some situations
config.to_prepare do

View File

@@ -12,6 +12,8 @@ Devise.setup do |config|
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
config.mailer_sender = "please-change-me@config-initializers-devise.com"
config.parent_controller = "ApplicationWithFakeEngine"
# Configure the class responsible to send e-mails.
# config.mailer = "Devise::Mailer"

View File

@@ -20,12 +20,25 @@ Rails.application.routes.draw do
# Users scope
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
devise_for :user_on_main_apps,
class_name: 'UserOnMainApp',
router_name: :main_app,
module: :devise
devise_for :user_on_engines,
class_name: 'UserOnEngine',
router_name: :fake_engine,
module: :devise
as :user do
get "/as/sign_in", to: "devise/sessions#new"
end
get "/sign_in", to: "devise/sessions#new"
# Routes for custom controller testing
devise_for :user, only: [:registrations], controllers: { registrations: "custom/registrations" }, as: :custom, path: :custom
# Admin scope
devise_for :admin, path: "admin_area", controllers: { sessions: :"admins/sessions" }, skip: :passwords
@@ -63,6 +76,10 @@ Rails.application.routes.draw do
devise_for :homebase_admin, class_name: "Admin", path: "homebase"
end
scope(subdomain: 'sub') do
devise_for :subdomain_users, class_name: "User", only: [:sessions]
end
devise_for :skip_admin, class_name: "Admin", skip: :all
# Routes for format=false testing

View File

@@ -4,7 +4,7 @@ module SharedUser
included do
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
:registerable, :rememberable, :timeoutable,
:trackable, :validatable, :omniauthable
:trackable, :validatable, :omniauthable, password_length: 7..128
attr_accessor :other_key

View File

@@ -0,0 +1,13 @@
module SharedUserWithoutOmniauth
extend ActiveSupport::Concern
included do
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
:registerable, :rememberable, :timeoutable,
:trackable, :validatable
end
def raw_confirmation_token
@raw_confirmation_token
end
end

View File

@@ -241,11 +241,13 @@ class CustomizedRoutingTest < ActionController::TestCase
end
test 'checks if mapping has proper configuration for omniauth callback' do
assert_raise ArgumentError do
@routes.dup.eval_block do
devise_for :admin, controllers: {omniauth_callbacks: "users/omniauth_callbacks"}
e = assert_raise ArgumentError do
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
devise_for :not_omniauthable, class_name: 'Admin', controllers: {omniauth_callbacks: "users/omniauth_callbacks"}
end
end
assert_match "Mapping omniauth_callbacks on a resource that is not omniauthable", e.message
end
end

View File

@@ -9,10 +9,9 @@ class ActiveSupport::TestCase
assert assertion.blank?
end
def assert_not_blank(assertion)
assert !assertion.blank?
def assert_present(assertion)
assert assertion.present?
end
alias :assert_present :assert_not_blank
def assert_email_sent(address = nil, &block)
assert_difference('ActionMailer::Base.deliveries.size', &block)

View File

@@ -40,7 +40,7 @@ class ActionDispatch::IntegrationTest
fill_in 'password', with: options[:password] || '12345678'
check 'remember me' if options[:remember_me] == true
yield if block_given?
click_button 'Sign In'
click_button 'Log In'
user
end
@@ -50,7 +50,7 @@ class ActionDispatch::IntegrationTest
fill_in 'email', with: 'admin@test.com'
fill_in 'password', with: '123456'
yield if block_given?
click_button 'Sign In'
click_button 'Log In'
admin
end

View File

@@ -17,6 +17,8 @@ Webrat.configure do |config|
config.open_error_files = false
end
OmniAuth.config.logger = Logger.new('/dev/null')
# Add support to load paths so we can overwrite broken webrat setup
$:.unshift File.expand_path('../support', __FILE__)
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }

View File

@@ -4,12 +4,6 @@ class TestHelpersTest < ActionController::TestCase
tests UsersController
include Devise::TestHelpers
class CustomFailureApp < Devise::FailureApp
def redirect
self.status = 306
end
end
test "redirects if attempting to access a page unauthenticated" do
get :index
assert_redirected_to new_user_session_path
@@ -72,12 +66,30 @@ class TestHelpersTest < ActionController::TestCase
end
test "respects custom failure app" do
begin
Devise.warden_config.failure_app = CustomFailureApp
custom_failure_app = Class.new(Devise::FailureApp) do
def redirect
self.status = 306
end
end
swap Devise.warden_config, failure_app: custom_failure_app do
get :index
assert_response 306
ensure
Devise.warden_config.failure_app = Devise::FailureApp
end
end
test "passes given headers from the failure app to the response" do
custom_failure_app = Class.new(Devise::FailureApp) do
def respond
self.status = 401
self.response.headers["CUSTOMHEADER"] = 1
end
end
swap Devise.warden_config, failure_app: custom_failure_app do
sign_in create_user
get :index
assert_equal 1, @response.headers["CUSTOMHEADER"]
end
end
@@ -148,26 +160,4 @@ class TestHelpersTest < ActionController::TestCase
get :index
assert_match /User ##{second_user.id}/, @response.body
end
test "passes given headers from the failure app to the response" do
begin
old_failure_app = Devise.warden_config[:failure_app]
class CustomTestFailureApp < Devise::FailureApp
def respond
self.status = 401
self.response.headers["CUSTOMHEADER"] = 1
end
end
Devise.warden_config[:failure_app] = CustomTestFailureApp
user = create_user
sign_in user
get :index
assert_equal 1, @response.headers["CUSTOMHEADER"]
ensure
Devise.warden_config[:failure_app] = old_failure_app
end
end
end