mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 23:58:06 -05:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba2e44c6a4 | ||
|
|
4f07ed42e3 | ||
|
|
66716023e4 | ||
|
|
4bc2ff997a | ||
|
|
b1633f2454 | ||
|
|
41a91188f5 | ||
|
|
4def600076 | ||
|
|
18a18e4c72 | ||
|
|
85c90671bc | ||
|
|
16b688eced | ||
|
|
37c55eb192 | ||
|
|
2d7dc3e82d | ||
|
|
e7a8a7247c | ||
|
|
c4818a9fb2 | ||
|
|
8c2a7146df | ||
|
|
311e3206c9 | ||
|
|
6ad6b3d2a6 | ||
|
|
471a05fd59 | ||
|
|
7a12655111 | ||
|
|
1b26869b74 | ||
|
|
13f35d80a9 | ||
|
|
1c4faa7d8a | ||
|
|
c26ed53927 | ||
|
|
fe0f6e96b3 | ||
|
|
6dd7ccee68 | ||
|
|
9327cf8af5 | ||
|
|
512b52e23a | ||
|
|
5df7105301 | ||
|
|
a84fdb771f | ||
|
|
ff75341c75 | ||
|
|
f0d48a96ca | ||
|
|
215fdf119e | ||
|
|
985b646ee1 | ||
|
|
622e480c4b | ||
|
|
2e78a46c52 | ||
|
|
b1b6e53d6f | ||
|
|
65325f7f81 | ||
|
|
9bd82e5a24 | ||
|
|
0689b4558e | ||
|
|
dbea934701 | ||
|
|
8e4d5fb38f | ||
|
|
e324ee9823 | ||
|
|
54e9cabf5d | ||
|
|
7a3f6fb53d | ||
|
|
59a9576498 | ||
|
|
57eb3886ba | ||
|
|
fe9e6db0e2 | ||
|
|
db8eeb6c6e | ||
|
|
2b7328535d | ||
|
|
d4e5424360 | ||
|
|
d67d992749 | ||
|
|
b6c7aafe55 | ||
|
|
9829384829 | ||
|
|
1d79c1982a | ||
|
|
f6259531c3 | ||
|
|
ed03039d19 | ||
|
|
b6abc4623b | ||
|
|
d1949b7b42 | ||
|
|
b6e30427a3 | ||
|
|
96e0dcf5d5 | ||
|
|
ab48435211 | ||
|
|
8bcb05d6c0 | ||
|
|
6b363d6af9 | ||
|
|
2fd2a8662d |
@@ -1,15 +1,40 @@
|
||||
== trunk (2.1.0.rc2)
|
||||
== 2.1.1
|
||||
|
||||
Notes: https://github.com/plataformatec/devise/wiki/How-to:-upgrade-to-devise-2.1
|
||||
|
||||
* enhancements
|
||||
* `sign_out_all_scopes` now locks warden and does not allow new logins in the same action
|
||||
* `Devise.omniauth_path_prefix` is available to configure omniauth path prefix
|
||||
* Redirect to sign in page when trying to access password#edit without a token (by @gbataille)
|
||||
* Allow a lambda in authenticate(d) routes helpers to further select the scope
|
||||
* Removed warnings on Rails 3.2.6 (by @nashby)
|
||||
|
||||
* bug fix
|
||||
* `update_with_password` now relies on assign_attributes and forwards the :as option (by @wtn)
|
||||
* Do not trigger timeout on sign in related actions
|
||||
* Timeout does not explode when reset_authentication_token! is accidentally defined by Active Model (by @remomueller)
|
||||
|
||||
* deprecations
|
||||
* Strategy#validate() no longer validates nil resources
|
||||
|
||||
== 2.1.0
|
||||
|
||||
* enhancements
|
||||
* Add `check_fields!(model_class)` method on Devise::Models to check if the model includes the fields that Devise uses
|
||||
* Add `skip_reconfirmation!` to skip reconfirmation
|
||||
* Devise model generator now works with engines
|
||||
* Devise encryptable was moved to its new gem (http://github.com/plataformatec/devise-encryptable)
|
||||
|
||||
* deprecations
|
||||
* Deprecations warnings added on Devise 2.0 are now removed with their features
|
||||
* use_salt_as_remember_token and apply_schema does not have any effect since 2.0 and are now deprecated
|
||||
* valid_for_authentication? must now return a boolean
|
||||
* All devise modules should now have a `required_fields(klass)` module method to help gathering missing attributes
|
||||
* `use_salt_as_remember_token` and `apply_schema` does not have any effect since 2.0 and are now deprecated
|
||||
* `valid_for_authentication?` must now return a boolean
|
||||
|
||||
* bug fix
|
||||
* Ensure after sign in hook is not called without a resource
|
||||
* Fix a term: now on Omniauth related flash messages, we say that we're authenticating from an omniauth provider instead of authorizing
|
||||
* Fixed redirect when authenticated mounted apps (by @hakanensari)
|
||||
* Ensure the failure app still respects config.relative_url_root
|
||||
* `/users/sign_in` doesn't choke on protected attributes used to select sign in scope (by @Paymium)
|
||||
* `failed_attempts` is set to zero after any sign in (including via reset password) (by @rodrigoflores)
|
||||
@@ -18,20 +43,6 @@
|
||||
* Better support for custom strategies on test helpers (by @mattconnolly)
|
||||
* Return `head :no_content` in SessionsController now that most JS libraries handle it (by @julianvargasalvarez)
|
||||
|
||||
== 2.1.0.rc
|
||||
|
||||
* enhancements
|
||||
* Add check_fields! method on Devise::Models to check if the model includes the fields that Devise uses
|
||||
* Add `skip_reconfirmation!` to skip reconfirmation
|
||||
|
||||
* bug fix
|
||||
* Ensure after sign in hook is not called without a resource
|
||||
* Fix a term: now on Omniauth related flash messages, we say that we're authenticating from an omniauth provider instead of authorizing
|
||||
* Fixed redirect when authenticated mounted apps (by @hakanensari)
|
||||
|
||||
* deprecation
|
||||
* All devise modules should have a required_fields(klass) module method to help gathering missing attributes
|
||||
|
||||
== 2.0.4
|
||||
|
||||
Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -2,7 +2,7 @@ source "http://rubygems.org"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "rails", "~> 3.2.0"
|
||||
gem "rails", "~> 3.2.3"
|
||||
gem "omniauth", "~> 1.0.0"
|
||||
gem "omniauth-oauth2", "~> 1.0.0"
|
||||
gem "rdoc"
|
||||
|
||||
82
Gemfile.lock
82
Gemfile.lock
@@ -3,42 +3,42 @@ PATH
|
||||
specs:
|
||||
devise (2.1.0)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.7)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.1.1)
|
||||
warden (~> 1.2.1)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.0)
|
||||
actionpack (= 3.2.0)
|
||||
mail (~> 2.4.0)
|
||||
actionpack (3.2.0)
|
||||
activemodel (= 3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
actionmailer (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.0)
|
||||
journey (~> 1.0.1)
|
||||
rack (~> 1.4.0)
|
||||
rack-cache (~> 1.1)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.1.2)
|
||||
activemodel (3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
activemodel (3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.0)
|
||||
activemodel (= 3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
arel (~> 3.0.0)
|
||||
activerecord (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.0)
|
||||
activemodel (= 3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
activesupport (3.2.0)
|
||||
activeresource (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
activesupport (3.2.3)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
addressable (2.2.6)
|
||||
arel (3.0.0)
|
||||
arel (3.0.2)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bson (1.5.1)
|
||||
bson_ext (1.3.1)
|
||||
@@ -52,16 +52,16 @@ GEM
|
||||
hashie (1.2.0)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.0)
|
||||
journey (1.0.0)
|
||||
json (1.6.5)
|
||||
journey (1.0.3)
|
||||
json (1.7.3)
|
||||
linecache (0.46)
|
||||
rbx-require-relative (> 0.0.4)
|
||||
mail (2.4.1)
|
||||
mail (2.4.4)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.1)
|
||||
mime-types (1.17.2)
|
||||
mime-types (1.18)
|
||||
mocha (0.10.0)
|
||||
metaclass (~> 0.0.1)
|
||||
mongo (1.3.1)
|
||||
@@ -87,10 +87,10 @@ GEM
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
orm_adapter (0.0.7)
|
||||
orm_adapter (0.1.0)
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.1)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
@@ -99,17 +99,17 @@ GEM
|
||||
rack
|
||||
rack-test (0.6.1)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.0)
|
||||
actionmailer (= 3.2.0)
|
||||
actionpack (= 3.2.0)
|
||||
activerecord (= 3.2.0)
|
||||
activeresource (= 3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
rails (3.2.3)
|
||||
actionmailer (= 3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activerecord (= 3.2.3)
|
||||
activeresource (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.0)
|
||||
railties (3.2.0)
|
||||
actionpack (= 3.2.0)
|
||||
activesupport (= 3.2.0)
|
||||
railties (= 3.2.3)
|
||||
railties (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
@@ -124,7 +124,7 @@ GEM
|
||||
ruby-debug-base (0.10.4)
|
||||
linecache (>= 0.3)
|
||||
ruby-openid (2.1.8)
|
||||
sprockets (2.1.2)
|
||||
sprockets (2.1.3)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
@@ -134,8 +134,8 @@ GEM
|
||||
treetop (1.4.10)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.31)
|
||||
warden (1.1.1)
|
||||
tzinfo (0.3.33)
|
||||
warden (1.2.1)
|
||||
rack (>= 1.0)
|
||||
webrat (0.7.2)
|
||||
nokogiri (>= 1.2.0)
|
||||
@@ -158,7 +158,7 @@ DEPENDENCIES
|
||||
omniauth-facebook
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
omniauth-openid (~> 1.0.1)
|
||||
rails (~> 3.2.0)
|
||||
rails (~> 3.2.3)
|
||||
rdoc
|
||||
ruby-debug (>= 0.10.3)
|
||||
sqlite3
|
||||
|
||||
45
README.md
45
README.md
@@ -1,12 +1,10 @@
|
||||
*IMPORTANT:* Devise 2.1 is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.1
|
||||
|
||||
*IMPORTANT:* Devise 2.0 is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
|
||||
|
||||
## Devise
|
||||
|
||||
INFO: This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).
|
||||
|
||||
[](http://travis-ci.org/plataformatec/devise)
|
||||
[](http://travis-ci.org/plataformatec/devise) [](https://codeclimate.com/github/plataformatec/devise)
|
||||
|
||||
Devise is a flexible authentication solution for Rails based on Warden. It:
|
||||
|
||||
@@ -15,11 +13,11 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
|
||||
* Allows you to have multiple roles (or models/scopes) signed in at the same time;
|
||||
* Is based on a modularity concept: use just what you really need.
|
||||
|
||||
It's comprised of 12 modules:
|
||||
It's composed of 12 modules:
|
||||
|
||||
* [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
|
||||
* [Token Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable): signs in a user based on an authentication token (also known as "single access token"). The token can be given both through query string or HTTP Basic Authentication.
|
||||
* [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds Omniauth (github.com/intridea/omniauth) support;
|
||||
* [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds Omniauth (https://github.com/intridea/omniauth) support;
|
||||
* [Confirmable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
|
||||
* [Recoverable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable): resets the user password and sends reset instructions.
|
||||
* [Registerable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Registerable): handles signing up users through a registration process, also allowing them to edit and destroy their account.
|
||||
@@ -306,7 +304,23 @@ https://github.com/plataformatec/devise/wiki/I18n
|
||||
|
||||
### Test helpers
|
||||
|
||||
Devise includes some tests helpers for functional specs. To use them, you just need to include Devise::TestHelpers in your test class and use the sign_in and sign_out method. Such methods have the same signature as in controllers:
|
||||
Devise includes some tests helpers for functional specs. In other to use them, you need to include Devise in your functional tests by adding the following to the bottom of your `test/test_helper.rb` file:
|
||||
|
||||
```ruby
|
||||
class ActionController::TestCase
|
||||
include Devise::TestHelpers
|
||||
end
|
||||
```
|
||||
|
||||
If you're using RSpec, you can put the following inside a file named `spec/support/devise.rb`:
|
||||
|
||||
```ruby
|
||||
RSpec.configure do |config|
|
||||
config.include Devise::TestHelpers, :type => :controller
|
||||
end
|
||||
```
|
||||
|
||||
Now you are ready to use the `sign_in` and `sign_out` methods. Such methods have the same signature as in controllers:
|
||||
|
||||
```ruby
|
||||
sign_in :user, @user # sign_in(scope, resource)
|
||||
@@ -316,23 +330,14 @@ sign_out :user # sign_out(scope)
|
||||
sign_out @user # sign_out(resource)
|
||||
```
|
||||
|
||||
You can include the Devise Test Helpers in all of your tests by adding the following to the bottom of your test/test_helper.rb file:
|
||||
There are two things that is important to keep in mind:
|
||||
|
||||
```ruby
|
||||
class ActionController::TestCase
|
||||
include Devise::TestHelpers
|
||||
end
|
||||
```
|
||||
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;
|
||||
|
||||
If you're using RSpec and want the helpers automatically included within all `describe` blocks, add a file called spec/support/devise.rb with the following contents:
|
||||
2) If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
|
||||
|
||||
```ruby
|
||||
RSpec.configure do |config|
|
||||
config.include Devise::TestHelpers, :type => :controller
|
||||
end
|
||||
```
|
||||
|
||||
Do not use such helpers for integration tests such as Cucumber or Webrat. Instead, fill in the form or explicitly set the user in session. For more tips, check the wiki (https://wiki.github.com/plataformatec/devise).
|
||||
@request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
get :new
|
||||
|
||||
### Omniauth
|
||||
|
||||
|
||||
2
Rakefile
2
Rakefile
@@ -29,6 +29,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'Devise'
|
||||
rdoc.options << '--line-numbers' << '--inline-source'
|
||||
rdoc.rdoc_files.include('README.rdoc')
|
||||
rdoc.rdoc_files.include('README.md')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
class Devise::OmniauthCallbacksController < DeviseController
|
||||
prepend_before_filter { request.env["devise.skip_timeout"] = true }
|
||||
|
||||
def passthru
|
||||
render :status => 404, :text => "Not found. Authentication passthru."
|
||||
end
|
||||
|
||||
def failure
|
||||
set_flash_message :alert, :failure, :kind => failed_strategy.name.to_s.humanize, :reason => failure_message
|
||||
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class Devise::PasswordsController < DeviseController
|
||||
prepend_before_filter :require_no_authentication
|
||||
# Render the #edit only if coming from a reset password email link
|
||||
append_before_filter :assert_reset_token_passed, :only => :edit
|
||||
|
||||
# GET /resource/password/new
|
||||
def new
|
||||
@@ -44,4 +46,11 @@ class Devise::PasswordsController < DeviseController
|
||||
new_session_path(resource_name)
|
||||
end
|
||||
|
||||
# Check if a reset_password_token is provided in the request
|
||||
def assert_reset_token_passed
|
||||
if params[:reset_password_token].blank?
|
||||
set_flash_message(:error, :no_token)
|
||||
redirect_to new_session_path(resource_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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 { request.env["devise.skip_timeout"] = true }
|
||||
|
||||
# GET /resource/sign_in
|
||||
def new
|
||||
|
||||
@@ -43,8 +43,11 @@ class DeviseController < Devise.parent_controller.constantize
|
||||
end
|
||||
|
||||
# Override prefixes to consider the scoped view.
|
||||
# Notice we need to check for the request due to a bug in
|
||||
# Action Controller tests that forces _prefixes to be
|
||||
# loaded before even having a request object.
|
||||
def _prefixes #:nodoc:
|
||||
@_prefixes ||= if self.class.scoped_views? && devise_mapping
|
||||
@_prefixes ||= if self.class.scoped_views? && request && devise_mapping
|
||||
super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
|
||||
else
|
||||
super
|
||||
@@ -59,11 +62,19 @@ class DeviseController < Devise.parent_controller.constantize
|
||||
def assert_is_devise_resource! #:nodoc:
|
||||
unknown_action! <<-MESSAGE unless devise_mapping
|
||||
Could not find devise mapping for path #{request.fullpath.inspect}.
|
||||
Maybe you forgot to wrap your route inside the scope block? For example:
|
||||
This may happen for two reasons:
|
||||
|
||||
1) You forgot to wrap your route inside the scope block. For example:
|
||||
|
||||
devise_scope :user do
|
||||
match "/some/route" => "some_devise_controller"
|
||||
end
|
||||
|
||||
2) You are testing a Devise controller bypassing the router.
|
||||
If so, you can explicitly tell Devise which mapping to use:
|
||||
|
||||
@request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
|
||||
devise_scope :user do
|
||||
match "/some/route" => "some_devise_controller"
|
||||
end
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
<div><%= f.submit "Resend confirmation instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -13,4 +13,4 @@
|
||||
<div><%= f.submit "Change my password" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
<div><%= f.submit "Send me reset password instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
|
||||
<h3>Cancel my account</h3>
|
||||
|
||||
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
|
||||
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
|
||||
|
||||
<%= link_to "Back", :back %>
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
<div><%= f.submit "Sign up" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
<div><%= f.submit "Sign in" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
<div><%= f.submit "Resend unlock instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -29,6 +29,7 @@ en:
|
||||
updated: 'Your password was changed successfully. You are now signed in.'
|
||||
updated_not_active: 'Your password was changed successfully.'
|
||||
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
||||
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
||||
confirmations:
|
||||
send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
|
||||
send_paranoid_instructions: 'If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.'
|
||||
|
||||
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
|
||||
s.test_files = `git ls-files -- test/*`.split("\n")
|
||||
s.require_paths = ["lib"]
|
||||
|
||||
s.add_dependency("warden", "~> 1.1.1")
|
||||
s.add_dependency("orm_adapter", "~> 0.0.7")
|
||||
s.add_dependency("warden", "~> 1.2.1")
|
||||
s.add_dependency("orm_adapter", "~> 0.1")
|
||||
s.add_dependency("bcrypt-ruby", "~> 3.0")
|
||||
s.add_dependency("railties", "~> 3.1")
|
||||
end
|
||||
|
||||
@@ -10,7 +10,6 @@ module Devise
|
||||
autoload :FailureApp, 'devise/failure_app'
|
||||
autoload :OmniAuth, 'devise/omniauth'
|
||||
autoload :ParamFilter, 'devise/param_filter'
|
||||
autoload :Schema, 'devise/schema'
|
||||
autoload :TestHelpers, 'devise/test_helpers'
|
||||
|
||||
module Controllers
|
||||
@@ -200,6 +199,11 @@ module Devise
|
||||
# to provide custom routes.
|
||||
mattr_accessor :router_name
|
||||
@@router_name = nil
|
||||
|
||||
# Set the omniauth path prefix so it can be overriden when
|
||||
# Devise is used in a mountable engine
|
||||
mattr_accessor :omniauth_path_prefix
|
||||
@@omniauth_path_prefix = nil
|
||||
|
||||
def self.encryptor=(value)
|
||||
warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
|
||||
|
||||
@@ -88,8 +88,8 @@ module Devise
|
||||
# Return true if the given scope is signed in session. If no scope given, return
|
||||
# true if any scope is signed in. Does not run authentication hooks.
|
||||
def signed_in?(scope=nil)
|
||||
[ scope || Devise.mappings.keys ].flatten.any? do |scope|
|
||||
warden.authenticate?(:scope => scope)
|
||||
[ scope || Devise.mappings.keys ].flatten.any? do |_scope|
|
||||
warden.authenticate?(:scope => _scope)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -126,8 +126,8 @@ module Devise
|
||||
end
|
||||
|
||||
# Sign out a given user or scope. This helper is useful for signing out a user
|
||||
# after deleting accounts. Returns true if there was a logout and false if there is no user logged in
|
||||
# on the referred scope
|
||||
# after deleting accounts. Returns true if there was a logout and false if there
|
||||
# is no user logged in on the referred scope
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
@@ -141,6 +141,7 @@ module Devise
|
||||
|
||||
warden.raw_session.inspect # Without this inspect here. The session does not clear.
|
||||
warden.logout(scope)
|
||||
warden.clear_strategies_cache!(:scope => scope)
|
||||
instance_variable_set(:"@current_#{scope}", nil)
|
||||
|
||||
!!user
|
||||
@@ -149,13 +150,15 @@ module Devise
|
||||
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
||||
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
|
||||
# and false if there was no user logged in on all scopes.
|
||||
def sign_out_all_scopes
|
||||
def sign_out_all_scopes(lock=true)
|
||||
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
|
||||
|
||||
warden.raw_session.inspect
|
||||
warden.logout
|
||||
expire_devise_cached_variables!
|
||||
|
||||
warden.clear_strategies_cache!
|
||||
warden.lock! if lock
|
||||
|
||||
users.any?
|
||||
end
|
||||
|
||||
@@ -253,8 +256,8 @@ 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
|
||||
warden.clear_strategies_cache!
|
||||
sign_out_all_scopes(false)
|
||||
request.env["devise.skip_storage"] = true
|
||||
expire_devise_cached_variables!
|
||||
super # call the default behaviour which resets the session
|
||||
end
|
||||
|
||||
@@ -5,17 +5,20 @@
|
||||
# verify timeout in the following request.
|
||||
Warden::Manager.after_set_user do |record, warden, options|
|
||||
scope = options[:scope]
|
||||
env = warden.request.env
|
||||
|
||||
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
|
||||
last_request_at = warden.session(scope)['last_request_at']
|
||||
|
||||
if record.timedout?(last_request_at)
|
||||
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
|
||||
warden.logout(scope)
|
||||
record.reset_authentication_token! if record.respond_to?(:reset_authentication_token!) && record.expire_auth_token_on_timeout
|
||||
if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
|
||||
record.reset_authentication_token!
|
||||
end
|
||||
throw :warden, :scope => scope, :message => :timeout
|
||||
end
|
||||
|
||||
unless warden.request.env['devise.skip_trackable']
|
||||
unless env['devise.skip_trackable']
|
||||
warden.session(scope)['last_request_at'] = Time.now.utc
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ module Devise
|
||||
# inside the given class.
|
||||
#
|
||||
def self.config(mod, *accessors) #:nodoc:
|
||||
(class << mod; self; end).send :attr_accessor, :available_configs
|
||||
class << mod; attr_accessor :available_configs; end
|
||||
mod.available_configs = accessors
|
||||
|
||||
accessors.each do |accessor|
|
||||
@@ -51,12 +51,13 @@ module Devise
|
||||
|
||||
def self.check_fields!(klass)
|
||||
failed_attributes = []
|
||||
instance = klass.new
|
||||
|
||||
klass.devise_modules.each do |mod|
|
||||
instance = klass.new
|
||||
constant = const_get(mod.to_s.classify)
|
||||
|
||||
if const_get(mod.to_s.classify).respond_to?(:required_fields)
|
||||
const_get(mod.to_s.classify).required_fields(klass).each do |field|
|
||||
if constant.respond_to?(:required_fields)
|
||||
constant.required_fields(klass).each do |field|
|
||||
failed_attributes << field unless instance.respond_to?(field)
|
||||
end
|
||||
else
|
||||
|
||||
@@ -93,22 +93,10 @@ module Devise
|
||||
def authenticatable_salt
|
||||
end
|
||||
|
||||
def devise_mailer
|
||||
Devise.mailer
|
||||
end
|
||||
|
||||
def headers_for(name)
|
||||
{}
|
||||
end
|
||||
|
||||
def downcase_keys
|
||||
self.class.case_insensitive_keys.each { |k| self[k].try(:downcase!) }
|
||||
end
|
||||
|
||||
def strip_whitespace
|
||||
self.class.strip_whitespace_keys.each { |k| self[k].try(:strip!) }
|
||||
end
|
||||
|
||||
array = %w(serializable_hash)
|
||||
# to_xml does not call serializable_hash on 3.1
|
||||
array << "to_xml" if Rails::VERSION::STRING[0,3] == "3.1"
|
||||
@@ -134,6 +122,55 @@ module Devise
|
||||
RUBY
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def devise_mailer
|
||||
Devise.mailer
|
||||
end
|
||||
|
||||
# This is an internal method called every time Devise needs
|
||||
# to send a notification/mail. This can be overriden if you
|
||||
# need to customize the e-mail delivery logic. For instance,
|
||||
# if you are using a queue to deliver e-mails (delayed job,
|
||||
# sidekiq, resque, etc), you must add the delivery to the queue
|
||||
# just after the transaction was committed. To achieve this,
|
||||
# you can override send_devise_notification to store the
|
||||
# deliveries until the after_commit callback is triggered:
|
||||
#
|
||||
# class User
|
||||
# devise :database_authenticatable, :confirmable
|
||||
#
|
||||
# after_commit :send_pending_notifications
|
||||
#
|
||||
# protected
|
||||
#
|
||||
# def send_devise_notification(notification)
|
||||
# pending_notifications << notification
|
||||
# end
|
||||
#
|
||||
# def send_pending_notifications
|
||||
# pending_notifications.each do |n|
|
||||
# devise_mailer.send(n, self).deliver
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def pending_notifications
|
||||
# @pending_notifications ||= []
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def send_devise_notification(notification)
|
||||
devise_mailer.send(notification, self).deliver
|
||||
end
|
||||
|
||||
def downcase_keys
|
||||
self.class.case_insensitive_keys.each { |k| self[k].try(:downcase!) }
|
||||
end
|
||||
|
||||
def strip_whitespace
|
||||
self.class.strip_whitespace_keys.each { |k| self[k].try(:strip!) }
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
|
||||
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage)
|
||||
|
||||
@@ -78,7 +78,7 @@ module Devise
|
||||
@reconfirmation_required = false
|
||||
|
||||
generate_confirmation_token! if self.confirmation_token.blank?
|
||||
self.devise_mailer.confirmation_instructions(self).deliver
|
||||
send_devise_notification(:confirmation_instructions)
|
||||
end
|
||||
|
||||
# Resend confirmation token. This method does not need to generate a new token.
|
||||
@@ -125,7 +125,7 @@ module Devise
|
||||
# instructions on creation. This can be overriden
|
||||
# in models to map to a nice sign up e-mail.
|
||||
def send_on_create_confirmation_instructions
|
||||
self.devise_mailer.confirmation_instructions(self).deliver
|
||||
send_devise_notification(:confirmation_instructions)
|
||||
end
|
||||
|
||||
# Callback to overwrite if confirmation is required or not.
|
||||
|
||||
@@ -64,7 +64,7 @@ module Devise
|
||||
result = if valid_password?(current_password)
|
||||
update_attributes(params, *options)
|
||||
else
|
||||
self.attributes = params
|
||||
self.assign_attributes(params, *options)
|
||||
self.valid?
|
||||
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
|
||||
false
|
||||
|
||||
@@ -38,11 +38,11 @@ module Devise
|
||||
self.locked_at = Time.now.utc
|
||||
|
||||
if unlock_strategy_enabled?(:email)
|
||||
generate_unlock_token
|
||||
generate_unlock_token!
|
||||
send_unlock_instructions
|
||||
else
|
||||
save(:validate => false)
|
||||
end
|
||||
|
||||
save(:validate => false)
|
||||
end
|
||||
|
||||
# Unlock a user by cleaning locked_at and failed_attempts.
|
||||
@@ -60,7 +60,7 @@ module Devise
|
||||
|
||||
# Send unlock instructions by email
|
||||
def send_unlock_instructions
|
||||
self.devise_mailer.unlock_instructions(self).deliver
|
||||
send_devise_notification(:unlock_instructions)
|
||||
end
|
||||
|
||||
# Resend the unlock instructions if the user is locked.
|
||||
@@ -123,6 +123,10 @@ module Devise
|
||||
self.unlock_token = self.class.unlock_token
|
||||
end
|
||||
|
||||
def generate_unlock_token!
|
||||
generate_unlock_token && save(:validate => false)
|
||||
end
|
||||
|
||||
# Tells if the lock is expired if :time unlock strategy is active
|
||||
def lock_expired?
|
||||
if unlock_strategy_enabled?(:time)
|
||||
|
||||
@@ -45,7 +45,7 @@ module Devise
|
||||
# Resets reset password token and send reset password instructions by email
|
||||
def send_reset_password_instructions
|
||||
generate_reset_password_token! if should_generate_reset_token?
|
||||
self.devise_mailer.reset_password_instructions(self).deliver
|
||||
send_devise_notification(:reset_password_instructions)
|
||||
end
|
||||
|
||||
# Checks if the reset password token sent is within the limit time.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
begin
|
||||
require "omniauth"
|
||||
require "omniauth/version"
|
||||
rescue LoadError => e
|
||||
rescue LoadError
|
||||
warn "Could not load 'omniauth'. Please ensure you have the omniauth gem >= 1.0.0 installed and listed in your Gemfile."
|
||||
raise
|
||||
end
|
||||
|
||||
@@ -2,21 +2,6 @@ module Devise
|
||||
module OmniAuth
|
||||
module UrlHelpers
|
||||
def self.define_helpers(mapping)
|
||||
return unless mapping.omniauthable?
|
||||
|
||||
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
|
||||
def #{mapping.name}_omniauth_authorize_path(provider, params = {})
|
||||
if Devise.omniauth_configs[provider.to_sym]
|
||||
script_name = request.env["SCRIPT_NAME"]
|
||||
|
||||
path = "\#{script_name}/#{mapping.path}/auth/\#{provider}\".squeeze("/")
|
||||
path << '?' + params.to_param if params.present?
|
||||
path
|
||||
else
|
||||
raise ArgumentError, "Could not find omniauth provider \#{provider.inspect}"
|
||||
end
|
||||
end
|
||||
URL_HELPERS
|
||||
end
|
||||
|
||||
def omniauth_authorize_path(resource_or_scope, *args)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require "active_support/core_ext/object/try"
|
||||
require "active_support/core_ext/hash/slice"
|
||||
|
||||
module ActionDispatch::Routing
|
||||
class RouteSet #:nodoc:
|
||||
@@ -236,7 +237,9 @@ module ActionDispatch::Routing
|
||||
end
|
||||
end
|
||||
|
||||
# Allow you to add authentication request from the router:
|
||||
# Allow you to add authentication request from the router.
|
||||
# Takes an optional scope and block to provide constraints
|
||||
# on the model instance itself.
|
||||
#
|
||||
# authenticate do
|
||||
# resources :post
|
||||
@@ -246,9 +249,13 @@ module ActionDispatch::Routing
|
||||
# resources :users
|
||||
# end
|
||||
#
|
||||
def authenticate(scope=nil)
|
||||
# authenticate :user, lambda {|u| u.role == "admin"} do
|
||||
# root :to => "admin/dashboard#show"
|
||||
# end
|
||||
#
|
||||
def authenticate(scope=nil, block=nil)
|
||||
constraint = lambda do |request|
|
||||
request.env["warden"].authenticate!(:scope => scope)
|
||||
request.env["warden"].authenticate!(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
|
||||
end
|
||||
|
||||
constraints(constraint) do
|
||||
@@ -257,7 +264,8 @@ module ActionDispatch::Routing
|
||||
end
|
||||
|
||||
# Allow you to route based on whether a scope is authenticated. You
|
||||
# can optionally specify which scope.
|
||||
# can optionally specify which scope and a block. The block accepts
|
||||
# a model and allows extra constraints to be done on the instance.
|
||||
#
|
||||
# authenticated :admin do
|
||||
# root :to => 'admin/dashboard#show'
|
||||
@@ -267,11 +275,15 @@ module ActionDispatch::Routing
|
||||
# root :to => 'dashboard#show'
|
||||
# end
|
||||
#
|
||||
# authenticated :user, lambda {|u| u.role == "admin"} do
|
||||
# root :to => "admin/dashboard#show"
|
||||
# end
|
||||
#
|
||||
# root :to => 'landing#show'
|
||||
#
|
||||
def authenticated(scope=nil)
|
||||
def authenticated(scope=nil, block=nil)
|
||||
constraint = lambda do |request|
|
||||
request.env["warden"].authenticate? :scope => scope
|
||||
request.env["warden"].authenticate?(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
|
||||
end
|
||||
|
||||
constraints(constraint) do
|
||||
@@ -367,16 +379,54 @@ module ActionDispatch::Routing
|
||||
:cancel => mapping.path_names[:cancel]
|
||||
}
|
||||
|
||||
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
|
||||
:path_names => path_names, :controller => controllers[:registrations] do
|
||||
options = {
|
||||
:only => [:new, :create, :edit, :update, :destroy],
|
||||
:path => mapping.path_names[:registration],
|
||||
:path_names => path_names,
|
||||
:controller => controllers[:registrations]
|
||||
}
|
||||
|
||||
resource :registration, options do
|
||||
get :cancel
|
||||
end
|
||||
end
|
||||
|
||||
def devise_omniauth_callback(mapping, controllers) #:nodoc:
|
||||
path, @scope[:path] = @scope[:path], nil
|
||||
path_prefix = "/#{mapping.path}/auth".squeeze("/")
|
||||
path_prefix = Devise.omniauth_path_prefix || "/#{mapping.path}/auth".squeeze("/")
|
||||
set_omniauth_path_prefix!(path_prefix)
|
||||
|
||||
providers = Regexp.union(mapping.to.omniauth_providers.map(&:to_s))
|
||||
|
||||
match "#{path_prefix}/:provider",
|
||||
:constraints => { :provider => providers },
|
||||
:to => "#{controllers[:omniauth_callbacks]}#passthru",
|
||||
:as => :omniauth_authorize
|
||||
|
||||
match "#{path_prefix}/:action/callback",
|
||||
:constraints => { :action => providers },
|
||||
:to => controllers[:omniauth_callbacks],
|
||||
:as => :omniauth_callback
|
||||
ensure
|
||||
@scope[:path] = path
|
||||
end
|
||||
|
||||
DEVISE_SCOPE_KEYS = [:as, :path, :module, :constraints, :defaults, :options]
|
||||
|
||||
def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
|
||||
old = {}
|
||||
DEVISE_SCOPE_KEYS.each { |k| old[k] = @scope[k] }
|
||||
|
||||
new = { :as => new_as, :path => new_path, :module => nil }
|
||||
new.merge!(options.slice(:constraints, :defaults, :options))
|
||||
|
||||
@scope.merge!(new)
|
||||
yield
|
||||
ensure
|
||||
@scope.merge!(old)
|
||||
end
|
||||
|
||||
def set_omniauth_path_prefix!(path_prefix) #:nodoc:
|
||||
if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
|
||||
raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \
|
||||
"1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one\n" \
|
||||
@@ -385,22 +435,6 @@ module ActionDispatch::Routing
|
||||
else
|
||||
::OmniAuth.config.path_prefix = path_prefix
|
||||
end
|
||||
|
||||
match "#{path_prefix}/:action/callback", :constraints => { :action => Regexp.union(mapping.to.omniauth_providers.map(&:to_s)) },
|
||||
:to => controllers[:omniauth_callbacks], :as => :omniauth_callback
|
||||
ensure
|
||||
@scope[:path] = path
|
||||
end
|
||||
|
||||
def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
|
||||
old_as, old_path, old_module, old_constraints, old_defaults, old_options =
|
||||
*@scope.values_at(:as, :path, :module, :constraints, :defaults, :options)
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
|
||||
new_as, new_path, nil, *options.values_at(:constraints, :defaults, :options)
|
||||
yield
|
||||
ensure
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
|
||||
old_as, old_path, old_module, old_constraints, old_defaults, old_options
|
||||
end
|
||||
|
||||
def raise_no_devise_method_error!(klass) #:nodoc:
|
||||
|
||||
@@ -9,7 +9,7 @@ module Devise
|
||||
attr_accessor :authentication_hash, :authentication_type, :password
|
||||
|
||||
def store?
|
||||
!mapping.to.skip_session_storage.include?(authentication_type)
|
||||
super && !mapping.to.skip_session_storage.include?(authentication_type)
|
||||
end
|
||||
|
||||
def valid?
|
||||
@@ -18,13 +18,24 @@ module Devise
|
||||
|
||||
private
|
||||
|
||||
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
||||
# Receives a resource and check if it is valid by calling valid_for_authentication?
|
||||
# An optional block that will be triggered while validating can be optionally
|
||||
# given as parameter. Check Devise::Models::Authenticable.valid_for_authentication?
|
||||
# for more information.
|
||||
#
|
||||
# In case the resource can't be validated, it will fail with the given
|
||||
# unauthenticated_message.
|
||||
def validate(resource, &block)
|
||||
unless resource
|
||||
ActiveSupport::Depreation.warn "an empty resource was given to #{self.class.name}#validate. " \
|
||||
"Please ensure the resource is not nil", caller
|
||||
end
|
||||
|
||||
result = resource && resource.valid_for_authentication?(&block)
|
||||
|
||||
case result
|
||||
when Symbol, String
|
||||
ActiveSupport::Deprecation.warn "valid_for_authentication should return a boolean value"
|
||||
ActiveSupport::Deprecation.warn "valid_for_authentication? should return a boolean value"
|
||||
fail!(result)
|
||||
return false
|
||||
end
|
||||
@@ -84,8 +95,8 @@ module Devise
|
||||
|
||||
# Extract the appropriate subhash for authentication from params.
|
||||
def params_auth_hash
|
||||
params[scope]
|
||||
end
|
||||
params[scope]
|
||||
end
|
||||
|
||||
# Extract a hash with attributes:values from the http params.
|
||||
def http_auth_hash
|
||||
|
||||
@@ -2,6 +2,11 @@ module Devise
|
||||
module Strategies
|
||||
# Base strategy for Devise. Responsible for verifying correct scope and mapping.
|
||||
class Base < ::Warden::Strategies::Base
|
||||
# Whenever CSRF cannot be verified, we turn off any kind of storage
|
||||
def store?
|
||||
!env["devise.skip_storage"]
|
||||
end
|
||||
|
||||
# Checks if a valid scope was given for devise and find mapping based on this scope.
|
||||
def mapping
|
||||
@mapping ||= begin
|
||||
|
||||
@@ -6,12 +6,11 @@ module Devise
|
||||
class DatabaseAuthenticatable < Authenticatable
|
||||
def authenticate!
|
||||
resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
|
||||
return fail(:invalid) unless resource
|
||||
|
||||
if validate(resource){ resource.valid_password?(password) }
|
||||
resource.after_database_authentication
|
||||
success!(resource)
|
||||
elsif !halted?
|
||||
fail(:invalid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,11 +19,13 @@ module Devise
|
||||
def authenticate!
|
||||
resource = mapping.to.serialize_from_cookie(*remember_cookie)
|
||||
|
||||
unless resource
|
||||
cookies.delete(remember_key)
|
||||
return pass
|
||||
end
|
||||
|
||||
if validate(resource)
|
||||
success!(resource)
|
||||
elsif !halted?
|
||||
cookies.delete(remember_key)
|
||||
pass
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -16,12 +16,11 @@ module Devise
|
||||
|
||||
def authenticate!
|
||||
resource = mapping.to.find_for_token_authentication(authentication_hash)
|
||||
return fail(:invalid_token) unless resource
|
||||
|
||||
if validate(resource)
|
||||
resource.after_token_authentication
|
||||
success!(resource)
|
||||
elsif !halted?
|
||||
fail(:invalid_token)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Devise
|
||||
VERSION = "2.1.0".freeze
|
||||
VERSION = "2.1.1".freeze
|
||||
end
|
||||
|
||||
@@ -20,9 +20,12 @@ module Mongoid
|
||||
def migration_data
|
||||
<<RUBY
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => false, :default => ""
|
||||
field :encrypted_password, :type => String, :null => false, :default => ""
|
||||
field :email, :type => String, :default => ""
|
||||
field :encrypted_password, :type => String, :default => ""
|
||||
|
||||
validates_presence_of :email
|
||||
validates_presence_of :encrypted_password
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
field :reset_password_sent_at, :type => Time
|
||||
|
||||
@@ -125,6 +125,9 @@ Devise.setup do |config|
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again. Default is 30 minutes.
|
||||
# config.timeout_in = 30.minutes
|
||||
|
||||
# If true, expires auth token on session timeout.
|
||||
# config.expire_auth_token_on_timeout = false
|
||||
|
||||
# ==> Configuration for :lockable
|
||||
# Defines which strategy will be used to lock an account.
|
||||
@@ -181,9 +184,8 @@ Devise.setup do |config|
|
||||
# devise role declared in your routes (usually :user).
|
||||
# config.default_scope = :user
|
||||
|
||||
# Configure sign_out behavior.
|
||||
# Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
|
||||
# The default is true, which means any logout action will sign out all active scopes.
|
||||
# Set this configuration to false if you want /users/sign_out to sign out
|
||||
# only the current scope. By default, Devise signs out all scopes.
|
||||
# config.sign_out_all_scopes = true
|
||||
|
||||
# ==> Navigation configuration
|
||||
@@ -213,4 +215,18 @@ Devise.setup do |config|
|
||||
# manager.intercept_401 = false
|
||||
# manager.default_strategies(:scope => :user).unshift :some_external_strategy
|
||||
# end
|
||||
end
|
||||
|
||||
# ==> Mountable engine configurations
|
||||
# When using Devise inside an engine, let's call it `MyEngine`, and this engine
|
||||
# is mountable, there are some extra configurations to be taken into account.
|
||||
# The following options are available, assuming the engine is mounted as:
|
||||
#
|
||||
# mount MyEngine, at: "/my_engine"
|
||||
#
|
||||
# The router that invoked `devise_for`, in the example above, would be:
|
||||
# config.router_name = :my_engine
|
||||
#
|
||||
# When using omniauth, Devise cannot automatically set Omniauth path,
|
||||
# so you need to do it manually. For the users scope, it would be:
|
||||
# config.omniauth_path_prefix = "/my_engine/users/auth"
|
||||
end
|
||||
@@ -3,13 +3,13 @@
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Resend confirmation instructions" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
<%= f.input :reset_password_token, :as => :hidden %>
|
||||
<%= f.full_error :reset_password_token %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :password, :label => "New password", :required => true %>
|
||||
<%= f.input :password_confirmation, :label => "Confirm your new password", :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Change my password" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Send me reset password instructions" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
<%= f.input :password, :autocomplete => "off", :hint => "leave it blank if you don't want to change it", :required => false %>
|
||||
<%= f.input :password_confirmation, :required => false %>
|
||||
<%= f.input :current_password, :hint => "we need your current password to confirm your changes", :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Update" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<h3>Cancel my account</h3>
|
||||
|
||||
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
|
||||
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
|
||||
|
||||
<%= link_to "Back", :back %>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true, :autofocus => true %>
|
||||
<%= f.input :password, :required => true %>
|
||||
<%= f.input :password_confirmation, :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Sign up" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<h2>Sign in</h2>
|
||||
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => false, :autofocus => true %>
|
||||
<%= f.input :password, :required => false %>
|
||||
<%= f.input :remember_me, :as => :boolean if devise_mapping.rememberable? %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Sign in" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<%= simple_form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="form-inputs">
|
||||
<%= f.input :email, :required => true %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit, "Resend unlock instructions" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "devise/shared/links" %>
|
||||
<%= render "devise/shared/links" %>
|
||||
|
||||
@@ -139,30 +139,27 @@ class ControllerAuthenticatableTest < ActionController::TestCase
|
||||
assert_equal nil, @controller.instance_variable_get(:@current_admin)
|
||||
end
|
||||
|
||||
test 'sign out clears up any signed in user by scope' do
|
||||
test 'sign out logs out and clears up any signed in user by scope' do
|
||||
user = User.new
|
||||
@mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(user)
|
||||
@mock_warden.expects(:logout).with(:user).returns(true)
|
||||
@mock_warden.expects(:clear_strategies_cache!).with(:scope => :user).returns(true)
|
||||
@controller.instance_variable_set(:@current_user, user)
|
||||
@controller.sign_out(:user)
|
||||
assert_equal nil, @controller.instance_variable_get(:@current_user)
|
||||
end
|
||||
|
||||
test 'sign out proxy to logout on warden' do
|
||||
@mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(true)
|
||||
@mock_warden.expects(:logout).with(:user).returns(true)
|
||||
@controller.sign_out(:user)
|
||||
end
|
||||
|
||||
test 'sign out accepts a resource as argument' do
|
||||
@mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(true)
|
||||
@mock_warden.expects(:logout).with(:user).returns(true)
|
||||
@mock_warden.expects(:clear_strategies_cache!).with(:scope => :user).returns(true)
|
||||
@controller.sign_out(User.new)
|
||||
end
|
||||
|
||||
test 'sign out without args proxy to sign out all scopes' do
|
||||
@mock_warden.expects(:user).times(Devise.mappings.size)
|
||||
@mock_warden.expects(:logout).with().returns(true)
|
||||
@mock_warden.expects(:clear_strategies_cache!).with().returns(true)
|
||||
@controller.sign_out
|
||||
end
|
||||
|
||||
@@ -232,6 +229,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
|
||||
swap Devise, :sign_out_all_scopes => false do
|
||||
@mock_warden.expects(:user).with(:scope => :admin, :run_callbacks => false).returns(true)
|
||||
@mock_warden.expects(:logout).with(:admin).returns(true)
|
||||
@mock_warden.expects(:clear_strategies_cache!).with(:scope => :admin).returns(true)
|
||||
@controller.expects(:redirect_to).with(admin_root_path)
|
||||
@controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end"
|
||||
@controller.sign_out_and_redirect(:admin)
|
||||
@@ -242,6 +240,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
|
||||
swap Devise, :sign_out_all_scopes => true do
|
||||
@mock_warden.expects(:user).times(Devise.mappings.size)
|
||||
@mock_warden.expects(:logout).with().returns(true)
|
||||
@mock_warden.expects(:clear_strategies_cache!).with().returns(true)
|
||||
@controller.expects(:redirect_to).with(admin_root_path)
|
||||
@controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end"
|
||||
@controller.sign_out_and_redirect(:admin)
|
||||
|
||||
@@ -4,6 +4,15 @@ class SessionsControllerTest < ActionController::TestCase
|
||||
tests Devise::SessionsController
|
||||
include Devise::TestHelpers
|
||||
|
||||
test "#create works even with scoped views" do
|
||||
swap Devise, :scoped_views => true do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
post :create
|
||||
assert_equal 200, @response.status
|
||||
assert_template "users/sessions/new"
|
||||
end
|
||||
end
|
||||
|
||||
test "#create doesn't raise exception after Warden authentication fails when TestHelpers included" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
post :create, :user => {
|
||||
@@ -13,23 +22,21 @@ class SessionsControllerTest < ActionController::TestCase
|
||||
assert_equal 200, @response.status
|
||||
assert_template "devise/sessions/new"
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord)
|
||||
if ActiveRecord::Base.respond_to?(:mass_assignment_sanitizer)
|
||||
test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
|
||||
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
||||
User.class_eval { attr_protected :email }
|
||||
|
||||
begin
|
||||
assert_nothing_raised ActiveModel::MassAssignmentSecurity::Error do
|
||||
get :new, :user => { :email => "allez viens!" }
|
||||
end
|
||||
ensure
|
||||
ActiveRecord::Base.mass_assignment_sanitizer = :logger
|
||||
User.class_eval { attr_accessible :email }
|
||||
if defined?(ActiveRecord) && ActiveRecord::Base.respond_to?(:mass_assignment_sanitizer)
|
||||
test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
|
||||
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
||||
User.class_eval { attr_protected :email }
|
||||
|
||||
begin
|
||||
assert_nothing_raised ActiveModel::MassAssignmentSecurity::Error do
|
||||
get :new, :user => { :email => "allez viens!" }
|
||||
end
|
||||
ensure
|
||||
ActiveRecord::Base.mass_assignment_sanitizer = :logger
|
||||
User.class_eval { attr_accessible :email }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,80 +75,6 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'not signed in as admin should not be able to access private route restricted to admins' do
|
||||
get private_path
|
||||
assert_redirected_to new_admin_session_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'signed in as user should not be able to access private route restricted to admins' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
get private_path
|
||||
assert_redirected_to new_admin_session_path
|
||||
end
|
||||
|
||||
test 'signed in as admin should be able to access private route restricted to admins' do
|
||||
sign_in_as_admin
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get private_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/private'
|
||||
assert_contain 'Private!'
|
||||
end
|
||||
|
||||
test 'signed in as admin should get admin dashboard' do
|
||||
sign_in_as_admin
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get dashboard_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/admin'
|
||||
assert_contain 'Admin dashboard'
|
||||
end
|
||||
|
||||
test 'signed in as user should get user dashboard' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
|
||||
get dashboard_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/user'
|
||||
assert_contain 'User dashboard'
|
||||
end
|
||||
|
||||
test 'not signed in should get no dashboard' do
|
||||
assert_raises ActionController::RoutingError do
|
||||
get dashboard_path
|
||||
end
|
||||
end
|
||||
|
||||
test 'signed in user should not see unauthenticated page' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
|
||||
assert_raises ActionController::RoutingError do
|
||||
get join_path
|
||||
end
|
||||
end
|
||||
|
||||
test 'not signed in users should see unautheticated page' do
|
||||
get join_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/join'
|
||||
assert_contain 'Join'
|
||||
end
|
||||
|
||||
test 'signed in as user should not be able to access admins actions' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
@@ -208,6 +134,126 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
|
||||
test 'not signed in should not be able to access private route (authenticate denied)' do
|
||||
get private_path
|
||||
assert_redirected_to new_admin_session_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'signed in as user should not be able to access private route restricted to admins (authenticate denied)' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
get private_path
|
||||
assert_redirected_to new_admin_session_path
|
||||
end
|
||||
|
||||
test 'signed in as admin should be able to access private route restricted to admins (authenticate accepted)' do
|
||||
sign_in_as_admin
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get private_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/private'
|
||||
assert_contain 'Private!'
|
||||
end
|
||||
|
||||
test 'signed in as inactive admin should not be able to access private/active route restricted to active admins (authenticate denied)' do
|
||||
sign_in_as_admin(:active => false)
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
assert_raises ActionController::RoutingError do
|
||||
get "/private/active"
|
||||
end
|
||||
end
|
||||
|
||||
test 'signed in as active admin should be able to access private/active route restricted to active admins (authenticate accepted)' do
|
||||
sign_in_as_admin(:active => true)
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get private_active_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/private'
|
||||
assert_contain 'Private!'
|
||||
end
|
||||
|
||||
test 'signed in as admin should get admin dashboard (authenticated accepted)' do
|
||||
sign_in_as_admin
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get dashboard_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/admin'
|
||||
assert_contain 'Admin dashboard'
|
||||
end
|
||||
|
||||
test 'signed in as user should get user dashboard (authenticated accepted)' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
|
||||
get dashboard_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/user'
|
||||
assert_contain 'User dashboard'
|
||||
end
|
||||
|
||||
test 'not signed in should get no dashboard (authenticated denied)' do
|
||||
assert_raises ActionController::RoutingError do
|
||||
get dashboard_path
|
||||
end
|
||||
end
|
||||
|
||||
test 'signed in as inactive admin should not be able to access dashboard/active route restricted to active admins (authenticated denied)' do
|
||||
sign_in_as_admin(:active => false)
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
assert_raises ActionController::RoutingError do
|
||||
get "/dashboard/active"
|
||||
end
|
||||
end
|
||||
|
||||
test 'signed in as active admin should be able to access dashboard/active route restricted to active admins (authenticated accepted)' do
|
||||
sign_in_as_admin(:active => true)
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
get dashboard_active_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/admin_dashboard'
|
||||
assert_contain 'Admin dashboard'
|
||||
end
|
||||
|
||||
test 'signed in user should not see unauthenticated page (unauthenticated denied)' do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
|
||||
assert_raises ActionController::RoutingError do
|
||||
get join_path
|
||||
end
|
||||
end
|
||||
|
||||
test 'not signed in users should see unautheticated page (unauthenticated accepted)' do
|
||||
get join_path
|
||||
|
||||
assert_response :success
|
||||
assert_template 'home/join'
|
||||
assert_contain 'Join'
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationRedirectTest < ActionController::IntegrationTest
|
||||
test 'redirect from warden shows sign in or sign up message' do
|
||||
get admins_path
|
||||
|
||||
@@ -126,6 +126,12 @@ class PasswordTest < ActionController::IntegrationTest
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'not authenticated user without a reset password token should not be able to visit the page' do
|
||||
get edit_user_password_path
|
||||
assert_response :redirect
|
||||
assert_redirected_to "/users/sign_in"
|
||||
end
|
||||
|
||||
test 'not authenticated user with invalid reset password token should not be able to change his password' do
|
||||
user = create_user
|
||||
reset_password :reset_password_token => 'invalid_reset_password'
|
||||
|
||||
@@ -25,7 +25,7 @@ class SessionTimeoutTest < ActionController::IntegrationTest
|
||||
assert_equal old_last_request, last_request_at
|
||||
end
|
||||
|
||||
test 'not time out user session before default limit time' do
|
||||
test 'does not time out user session before default limit time' do
|
||||
sign_in_as_user
|
||||
assert_response :success
|
||||
assert warden.authenticated?(:user)
|
||||
@@ -53,12 +53,38 @@ class SessionTimeoutTest < ActionController::IntegrationTest
|
||||
|
||||
assert_response :redirect
|
||||
assert_redirected_to root_path
|
||||
|
||||
follow_redirect!
|
||||
|
||||
assert_contain 'Signed out successfully'
|
||||
end
|
||||
|
||||
test 'time out is not triggered on sign in' do
|
||||
user = sign_in_as_user
|
||||
get expire_user_path(user)
|
||||
|
||||
post "/users/sign_in", :email => user.email, :password => "123456"
|
||||
|
||||
assert_response :redirect
|
||||
follow_redirect!
|
||||
assert_contain 'You are signed in'
|
||||
end
|
||||
|
||||
test 'admin does not explode on time out' do
|
||||
admin = sign_in_as_admin
|
||||
get expire_admin_path(admin)
|
||||
|
||||
Admin.send :define_method, :reset_authentication_token! do
|
||||
nil
|
||||
end
|
||||
|
||||
begin
|
||||
get admins_path
|
||||
assert_redirected_to admins_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
ensure
|
||||
Admin.send(:remove_method, :reset_authentication_token!)
|
||||
end
|
||||
end
|
||||
|
||||
test 'user configured timeout limit' do
|
||||
swap Devise, :timeout_in => 8.minutes do
|
||||
user = sign_in_as_user
|
||||
|
||||
@@ -97,7 +97,7 @@ class RecoverableTest < ActiveSupport::TestCase
|
||||
test 'should reset reset_password_token before send the reset instructions email' do
|
||||
user = create_user
|
||||
token = user.reset_password_token
|
||||
reset_password_user = User.send_reset_password_instructions(:email => user.email)
|
||||
User.send_reset_password_instructions(:email => user.email)
|
||||
assert_not_equal token, user.reload.reset_password_token
|
||||
end
|
||||
|
||||
@@ -142,7 +142,7 @@ class RecoverableTest < ActiveSupport::TestCase
|
||||
old_password = user.password
|
||||
user.send :generate_reset_password_token!
|
||||
|
||||
reset_password_user = User.reset_password_by_token(
|
||||
User.reset_password_by_token(
|
||||
:reset_password_token => user.reset_password_token,
|
||||
:password => 'new_password',
|
||||
:password_confirmation => 'new_password'
|
||||
@@ -202,4 +202,4 @@ class RecoverableTest < ActiveSupport::TestCase
|
||||
:reset_password_token
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ end
|
||||
class ActiveRecordTest < ActiveSupport::TestCase
|
||||
def include_module?(klass, mod)
|
||||
klass.devise_modules.include?(mod) &&
|
||||
klass.included_modules.include?(Devise::Models::const_get(mod.to_s.classify))
|
||||
klass.included_modules.include?(Devise::Models::const_get(mod.to_s.classify))
|
||||
end
|
||||
|
||||
def assert_include_modules(klass, *modules)
|
||||
@@ -153,13 +153,13 @@ class CheckFieldsTest < ActiveSupport::TestCase
|
||||
devise :database_authenticatable
|
||||
end
|
||||
|
||||
exception = assert_raise_with_message Devise::Models::MissingAttribute, "The following attribute(s) is (are) missing on your model: encrypted_password, email" do
|
||||
assert_raise_with_message Devise::Models::MissingAttribute, "The following attribute(s) is (are) missing on your model: encrypted_password, email" do
|
||||
Devise::Models.check_fields!(Magician)
|
||||
end
|
||||
end
|
||||
|
||||
test "doesn't raise a NoMethodError exception when the module doesn't have a required_field(klass) class method" do
|
||||
driver = Class.new do
|
||||
driver = Class.new do
|
||||
extend Devise::Models
|
||||
|
||||
def self.before_validation(instance)
|
||||
|
||||
@@ -30,7 +30,7 @@ class OmniAuthRoutesTest < ActionController::TestCase
|
||||
test 'should generate authorization path' do
|
||||
assert_match "/users/auth/facebook", @controller.omniauth_authorize_path(:user, :facebook)
|
||||
|
||||
assert_raise ArgumentError do
|
||||
assert_raise ActionController::RoutingError do
|
||||
@controller.omniauth_authorize_path(:user, :github)
|
||||
end
|
||||
end
|
||||
@@ -48,11 +48,4 @@ class OmniAuthRoutesTest < ActionController::TestCase
|
||||
assert_equal "/users/auth/openid",
|
||||
@controller.omniauth_authorize_path(:user, :openid)
|
||||
end
|
||||
|
||||
test 'should set script name in the path if present' do
|
||||
@request.env['SCRIPT_NAME'] = '/q'
|
||||
|
||||
assert_equal "/q/users/auth/facebook",
|
||||
@controller.omniauth_authorize_path(:user, :facebook)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,4 +3,9 @@ class AdminsController < ApplicationController
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def expire
|
||||
admin_session['last_request_at'] = 31.minutes.ago.utc
|
||||
render :text => 'Admin will be expired on next request'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,9 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :admins, :only => [:index]
|
||||
resources :admins, :only => [:index] do
|
||||
get :expire, :on => :member
|
||||
end
|
||||
|
||||
# Users scope
|
||||
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
|
||||
@@ -30,10 +32,18 @@ Rails.application.routes.draw do
|
||||
match "/private", :to => "home#private", :as => :private
|
||||
end
|
||||
|
||||
authenticate(:admin, lambda { |admin| admin.active? }) do
|
||||
match "/private/active", :to => "home#private", :as => :private_active
|
||||
end
|
||||
|
||||
authenticated :admin do
|
||||
match "/dashboard", :to => "home#admin_dashboard"
|
||||
end
|
||||
|
||||
authenticated :admin, lambda { |admin| admin.active? } do
|
||||
match "/dashboard/active", :to => "home#admin_dashboard"
|
||||
end
|
||||
|
||||
authenticated do
|
||||
match "/dashboard", :to => "home#user_dashboard"
|
||||
end
|
||||
|
||||
@@ -60,6 +60,9 @@ class CreateTables < ActiveRecord::Migration
|
||||
## Lockable
|
||||
t.datetime :locked_at
|
||||
|
||||
## Attribute for testing route blocks
|
||||
t.boolean :active, :default => false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,14 +15,14 @@ class ActiveSupport::TestCase
|
||||
alias :assert_present :assert_not_blank
|
||||
|
||||
def assert_email_sent(address = nil, &block)
|
||||
assert_difference('ActionMailer::Base.deliveries.size') { yield }
|
||||
assert_difference('ActionMailer::Base.deliveries.size', &block)
|
||||
if address.present?
|
||||
assert_equal address, ActionMailer::Base.deliveries.last['to'].to_s
|
||||
end
|
||||
end
|
||||
|
||||
def assert_email_not_sent(&block)
|
||||
assert_no_difference('ActionMailer::Base.deliveries.size') { yield }
|
||||
assert_no_difference('ActionMailer::Base.deliveries.size', &block)
|
||||
end
|
||||
|
||||
def assert_same_content(result, expected)
|
||||
@@ -32,11 +32,9 @@ class ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def assert_raise_with_message(exception_klass, message)
|
||||
exception = assert_raise exception_klass do
|
||||
yield
|
||||
end
|
||||
|
||||
assert_equal exception.message, message, "The expected message was #{message} but your exception throwed #{exception.message}"
|
||||
def assert_raise_with_message(exception_klass, message, &block)
|
||||
exception = assert_raise exception_klass, &block
|
||||
assert_equal exception.message, message,
|
||||
"The expected message was #{message} but your exception throwed #{exception.message}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +24,8 @@ class ActionDispatch::IntegrationTest
|
||||
@admin ||= begin
|
||||
admin = Admin.create!(
|
||||
:email => options[:email] || 'admin@test.com',
|
||||
:password => '123456', :password_confirmation => '123456'
|
||||
:password => '123456', :password_confirmation => '123456',
|
||||
:active => options[:active]
|
||||
)
|
||||
admin.confirm! unless options[:confirm] == false
|
||||
admin
|
||||
|
||||
Reference in New Issue
Block a user