1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Merge branch 'master' into rails4

This commit is contained in:
Carlos Antonio da Silva 2013-05-07 13:01:34 -03:00
commit eb0ad1c21a
38 changed files with 284 additions and 100 deletions

View file

@ -1,12 +1,18 @@
== master
== 2.2.4
* enhancements
* Add `destroy_with_password` to `DatabaseAuthenticatable`. Allows destroying a record when `:current_password` matches, similarly to how `update_with_password` works. (by @michiel3)
* Allow to override path after password resetting (by @worker8)
* Add `#skip_confirmation_notification!` method to `Confirmable`. Allows skipping confirmation email without auto-confirming. (by @gregates)
* allow_unconfirmed_access_for config from `:confirmable` module can be set to `nil` that means unconfirmed access for unlimited time. (by @nashby)
* Support Rails' token strategy on authentication (by @robhurring)
* Support explicitly setting the http authentication key via `config.http_authentication_key` (by @neo)
* bug fix
* Do not redirect when accessing devise API via JSON. (by @sebastianwr)
* Generating scoped devise views now uses the correct scoped shared links partial instead of the default devise one (by @nashby)
* Fix inheriting mailer templates from `Devise::Mailer`
* Fix a bug when procs are used as default mailer in Devise (by @tomasv)
== 2.2.3

View file

@ -10,7 +10,7 @@ gem "rdoc"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid", "~> 1.0.1"
gem "webrat", "0.7.2", :require => false
gem "webrat", "0.7.3", :require => false
gem "mocha", "~> 0.13.1", :require => false
end

View file

@ -12,7 +12,7 @@ GIT
PATH
remote: .
specs:
devise (2.2.3)
devise (2.2.4)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@ -135,7 +135,7 @@ GEM
tzinfo (0.3.37)
warden (1.2.1)
rack (>= 1.0)
webrat (0.7.2)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
@ -157,4 +157,4 @@ DEPENDENCIES
rails (~> 4.0.0.rc1)
rdoc
sqlite3
webrat (= 0.7.2)
webrat (= 0.7.3)

View file

@ -1,7 +1,9 @@
![Devise Logo](https://raw.github.com/plataformatec/devise/master/devise.png)
By [Plataformatec](http://plataformatec.com.br/).
[![Gem Version](https://fury-badge.herokuapp.com/rb/devise.png)](http://badge.fury.io/rb/devise)
[![Build Status](https://secure.travis-ci.org/plataformatec/devise.png?branch=master)](http://travis-ci.org/plataformatec/devise)
[![Build Status](https://api.travis-ci.org/plataformatec/devise.png?branch=master)](http://travis-ci.org/plataformatec/devise)
[![Code Climate](https://codeclimate.com/github/plataformatec/devise.png)](https://codeclimate.com/github/plataformatec/devise)
This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).

View file

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

View file

@ -32,7 +32,7 @@ class Devise::ConfirmationsController < DeviseController
# The path used after resending confirmation instructions.
def after_resending_confirmation_instructions_path_for(resource_name)
new_session_path(resource_name)
new_session_path(resource_name) if is_navigational_format?
end
# The path used after confirmation.

View file

@ -34,17 +34,20 @@ class Devise::PasswordsController < DeviseController
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
respond_with resource, :location => after_resetting_password_path_for(resource)
else
respond_with resource
end
end
protected
def after_resetting_password_path_for(resource)
after_sign_in_path_for(resource)
end
# The path used after sending reset password instructions
def after_sending_reset_password_instructions_path_for(resource_name)
new_session_path(resource_name)
new_session_path(resource_name) if is_navigational_format?
end
# Check if a reset_password_token is provided in the request

View file

@ -33,12 +33,12 @@ class Devise::UnlocksController < DeviseController
# The path used after sending unlock password instructions
def after_sending_unlock_instructions_path_for(resource)
new_session_path(resource)
new_session_path(resource) if is_navigational_format?
end
# The path used after unlocking the resource
def after_unlock_path_for(resource)
new_session_path(resource)
new_session_path(resource) if is_navigational_format?
end
end

View file

@ -142,13 +142,18 @@ MESSAGE
#
# Please refer to README or en.yml locale file to check what messages are
# available.
def set_flash_message(key, kind, options={})
def set_flash_message(key, kind, options = {})
message = find_message(kind, options)
flash[key] = message if message.present?
end
# Get message for given
def find_message(kind, options = {})
options[:scope] = "devise.#{controller_name}"
options[:default] = Array(options[:default]).unshift(kind.to_sym)
options[:resource_name] = resource_name
options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
message = I18n.t("#{options[:resource_name]}.#{kind}", options)
flash[key] = message if message.present?
I18n.t("#{options[:resource_name]}.#{kind}", options)
end
def clean_up_passwords(object)

View file

@ -6,7 +6,7 @@ Gem::Specification.new do |s|
s.name = "devise"
s.version = Devise::VERSION.dup
s.platform = Gem::Platform::RUBY
s.license = "MIT"
s.licenses = ["MIT"]
s.summary = "Flexible authentication solution for Rails with Warden"
s.email = "contact@plataformatec.com.br"
s.homepage = "http://github.com/plataformatec/devise"

View file

@ -1,7 +1,7 @@
PATH
remote: /Users/carlos/Projects/oss/devise
remote: ..
specs:
devise (2.2.3)
devise (2.2.4)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@ -65,7 +65,7 @@ GEM
origin (~> 1.0)
tzinfo (~> 0.3.22)
moped (1.4.5)
multi_json (1.7.2)
multi_json (1.7.3)
multipart-post (1.2.0)
nokogiri (1.5.9)
oauth2 (0.8.1)

View file

@ -54,8 +54,8 @@ module Devise
@@stretches = 10
# The default key used when authenticating over http auth.
mattr_accessor :http_auth_key
@@http_auth_key = nil
mattr_accessor :http_authentication_key
@@http_authentication_key = nil
# Keys used when authenticating a user.
mattr_accessor :authentication_keys
@ -317,7 +317,7 @@ module Devise
# == Options:
#
# +model+ - String representing the load path to a custom *model* for this module (to autoload.)
# +controller+ - Symbol representing the name of an exisiting or custom *controller* for this module.
# +controller+ - Symbol representing the name of an existing or custom *controller* for this module.
# +route+ - Symbol representing the named *route* helper for this module.
# +strategy+ - Symbol representing if this module got a custom *strategy*.
#
@ -445,7 +445,7 @@ module Devise
end
end
# Generate a friendly string randomically to be used as token.
# Generate a friendly string randomly to be used as token.
def self.friendly_token
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
end

View file

@ -70,7 +70,7 @@ module Devise
template_path
end
# Setup a subject doing an I18n lookup. At first, it attemps to set a subject
# Setup a subject doing an I18n lookup. At first, it attempts to set a subject
# based on the current mapping:
#
# en:

View file

@ -10,7 +10,7 @@ module Devise
#
# * +authentication_keys+: parameters used for authentication. By default [:email].
#
# * +http_auth_key+: map the username passed via HTTP Auth to this parameter. Defaults to
# * +http_authentication_key+: map the username passed via HTTP Auth to this parameter. Defaults to
# the first element in +authentication_keys+.
#
# * +request_keys+: parameters from the request object used for authentication.
@ -18,7 +18,7 @@ module Devise
# passed to find_for_authentication method and considered in your model lookup.
#
# For instance, if you set :request_keys to [:subdomain], :subdomain will be considered
# as key on authentication. This can also be a hash where the value is a boolean expliciting
# as key on authentication. This can also be a hash where the value is a boolean specifying
# if the value is required or not.
#
# * +http_authenticatable+: if this model allows http authentication. By default true.
@ -35,7 +35,7 @@ module Devise
# == active_for_authentication?
#
# After authenticating a user and in each request, Devise checks if your model is active by
# calling model.active_for_authentication?. This method is overwriten by other devise modules. For instance,
# calling model.active_for_authentication?. This method is overwritten by other devise modules. For instance,
# :confirmable overwrites .active_for_authentication? to only return true if your model was confirmed.
#
# You overwrite this method yourself, but if you do, don't forget to call super:
@ -198,7 +198,7 @@ module Devise
module ClassMethods
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage,
:http_auth_key)
:http_authentication_key)
def serialize_into_session(record)
[record.to_key, record.authenticatable_salt]

View file

@ -39,6 +39,13 @@ module Devise
after_update :send_confirmation_instructions, :if => :reconfirmation_required?
end
def initialize(*args, &block)
@bypass_postpone = false
@reconfirmation_required = false
@skip_confirmation_notification = false
super
end
def self.required_fields(klass)
required_methods = [:confirmation_token, :confirmed_at, :confirmation_sent_at]
required_methods << :unconfirmed_email if klass.reconfirmable
@ -221,7 +228,7 @@ module Devise
def postpone_email_change?
postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone
@bypass_postpone = nil
@bypass_postpone = false
postpone
end

View file

@ -95,6 +95,21 @@ module Devise
result
end
# Destroy record when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects
# :current_password if it is blank.
def destroy_with_password(current_password)
result = if valid_password?(current_password)
destroy
else
self.valid?
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
false
end
result
end
def after_database_authentication
end

View file

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

View file

@ -2,7 +2,7 @@ require 'devise/hooks/timeoutable'
module Devise
module Models
# Timeoutable takes care of veryfing whether a user session has already
# Timeoutable takes care of verifyng whether a user session has already
# expired or not. When a session expires after the configured time, the user
# will be asked for credentials again, it means, he/she will be redirected
# to the sign in page.

View file

@ -8,16 +8,16 @@ module Devise
def filter(conditions)
conditions = stringify_params(conditions.dup)
@case_insensitive_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:downcase)
conditions[k] = value.downcase
end
conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :downcase, @case_insensitive_keys))
conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :strip, @strip_whitespace_keys))
@strip_whitespace_keys.each do |k|
conditions
end
def filtered_hash_by_method_for_given_keys(conditions, method, condition_keys)
condition_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:strip)
conditions[k] = value.strip
conditions[k] = value.send(method) if value.respond_to?(method)
end
conditions

View file

@ -250,15 +250,11 @@ module ActionDispatch::Routing
# end
#
# authenticate :user, lambda {|u| u.role == "admin"} do
# root :to => "admin/dashboard#show"
# root :to => "admin/dashboard#show", :as => :user_root
# end
#
def authenticate(scope=nil, block=nil)
constraint = lambda do |request|
request.env["warden"].authenticate!(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
constraints_for(:authenticate!, scope, block) do
yield
end
end
@ -268,25 +264,21 @@ module ActionDispatch::Routing
# a model and allows extra constraints to be done on the instance.
#
# authenticated :admin do
# root :to => 'admin/dashboard#show'
# root :to => 'admin/dashboard#show', :as => :admin_root
# end
#
# authenticated do
# root :to => 'dashboard#show'
# root :to => 'dashboard#show', :as => :authenticated_root
# end
#
# authenticated :user, lambda {|u| u.role == "admin"} do
# root :to => "admin/dashboard#show"
# root :to => "admin/dashboard#show", :as => :user_root
# end
#
# root :to => 'landing#show'
#
def authenticated(scope=nil, block=nil)
constraint = lambda do |request|
request.env["warden"].authenticate?(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
constraints_for(:authenticate?, scope, block) do
yield
end
end
@ -428,6 +420,17 @@ module ActionDispatch::Routing
@scope.merge!(old)
end
def constraints_for(method_to_apply, scope=nil, block=nil)
constraint = lambda do |request|
request.env['warden'].send(method_to_apply, :scope => scope) &&
(block.nil? || block.call(request.env["warden"].user(scope)))
end
constraints(constraint) do
yield
end
end
def set_omniauth_path_prefix!(path_prefix) #:nodoc:
if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \

View file

@ -100,7 +100,7 @@ module Devise
# Extract a hash with attributes:values from the http params.
def http_auth_hash
keys = [http_auth_key, :password]
keys = [http_authentication_key, :password]
Hash[*keys.zip(decode_credentials).flatten]
end
@ -134,32 +134,27 @@ module Devise
parse_authentication_key_values(request_values, request_keys)
end
# Holds the authentication keys.
def authentication_keys
@authentication_keys ||= mapping.to.authentication_keys
end
def http_auth_key
@http_auth_key ||= mapping.to.http_auth_key
@http_auth_key ||= case authentication_keys
def http_authentication_key
@http_authentication_key ||= mapping.to.http_authentication_key || case authentication_keys
when Array then authentication_keys.first
when Hash then authentication_keys.keys.first
end
end
# Holds request keys.
def request_keys
@request_keys ||= mapping.to.request_keys
end
# Returns values from the request object.
def request_values
keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
values = keys.map { |k| self.request.send(k) }
Hash[keys.zip(values)]
end
# Parse authentication keys considering if they should be enforced or not.
def parse_authentication_key_values(hash, keys)
keys.each do |key, enforce|
value = hash[key].presence

View file

@ -7,13 +7,22 @@ module Devise
#
# http://myapp.example.com/?user_token=SECRET
#
# For HTTP, you can pass the token as username and blank password. Since some clients may require
# a password, you can pass "X" as password and it will simply be ignored.
# For headers, you can use basic authentication passing the token as username and
# blank password. Since some clients may require a password, you can pass "X" as
# password and it will simply be ignored.
#
# You may also pass the token using the Token authentication mechanism provided
# by Rails: http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
# The token options are stored in request.env['devise.token_options']
class TokenAuthenticatable < Authenticatable
def store?
super && !mapping.to.skip_session_storage.include?(:token_auth)
end
def valid?
super || valid_for_token_auth?
end
def authenticate!
resource = mapping.to.find_for_token_authentication(authentication_hash)
return fail(:invalid_token) unless resource
@ -36,7 +45,33 @@ module Devise
false
end
# Try both scoped and non scoped keys.
# Check if the model accepts this strategy as token authenticatable.
def token_authenticatable?
mapping.to.http_authenticatable?(:token_options)
end
# Check if this is strategy is valid for token authentication by:
#
# * Validating if the model allows http token authentication;
# * If the http auth token exists;
# * If all authentication keys are present;
#
def valid_for_token_auth?
token_authenticatable? && auth_token.present? && with_authentication_hash(:token_auth, token_auth_hash)
end
# Extract the auth token from the request
def auth_token
@auth_token ||= ActionController::HttpAuthentication::Token.token_and_options(request)
end
# Extract a hash with attributes:values from the auth_token
def token_auth_hash
request.env['devise.token_options'] = auth_token.last
{ authentication_keys.first => auth_token.first }
end
# Try both scoped and non scoped keys
def params_auth_hash
if params[scope].kind_of?(Hash) && params[scope].has_key?(authentication_keys.first)
params[scope]

View file

@ -1,3 +1,3 @@
module Devise
VERSION = "2.2.3".freeze
VERSION = "2.2.4".freeze
end

View file

@ -48,10 +48,14 @@ Devise.setup do |config|
# enable it only for database (email + password) authentication.
# config.params_authenticatable = true
# Tell if authentication through HTTP Basic Auth is enabled. False by default.
# Tell if authentication through HTTP Auth is enabled. False by default.
# It can be set to an array that will enable http authentication only for the
# given strategies, for example, `config.http_authenticatable = [:token]` will
# enable it only for token authentication.
# enable it only for token authentication. The supported strategies are:
# :database = Support basic authentication with authentication key + password
# :token = Support basic authentication with token authentication key
# :token_options = Support token authentication with options as defined in
# http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
# config.http_authenticatable = false
# If http headers should be returned for AJAX requests. True by default.

View file

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

View file

@ -80,9 +80,9 @@ class FailureTest < ActiveSupport::TestCase
test 'setup a default message' do
call_failure
assert_match /You are being/, @response.last.body
assert_match /redirected/, @response.last.body
assert_match /users\/sign_in/, @response.last.body
assert_match(/You are being/, @response.last.body)
assert_match(/redirected/, @response.last.body)
assert_match(/users\/sign_in/, @response.last.body)
end
test 'works for any navigational format' do

View file

@ -167,7 +167,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
end
test 'resent confirmation token with invalid E-Mail in XML format should return invalid response' do
user = create_user(:confirm => false)
create_user(:confirm => false)
post user_confirmation_path(:format => 'xml'), :user => { :email => 'invalid.test@test.com' }
assert_response :unprocessable_entity
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
@ -181,7 +181,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
end
test 'confirm account with invalid confirmation token in XML format should return invalid response' do
user = create_user(:confirm => false)
create_user(:confirm => false)
get user_confirmation_path(:confirmation_token => 'invalid_confirmation', :format => 'xml')
assert_response :unprocessable_entity
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>)
@ -275,7 +275,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
visit_admin_confirmation_with_token(confirmation_token)
assert_have_selector '#error_explanation'
assert_contain /Confirmation token(.*)invalid/
assert_contain(/Confirmation token(.*)invalid/)
visit_admin_confirmation_with_token(admin.confirmation_token)
assert_contain 'Your account was successfully confirmed.'
@ -293,7 +293,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
visit_admin_confirmation_with_token(admin.confirmation_token)
assert_have_selector '#error_explanation'
assert_contain /Email.*already.*taken/
assert_contain(/Email.*already.*taken/)
assert admin.reload.pending_reconfirmation?
end
end

View file

@ -63,7 +63,7 @@ class HttpAuthenticationTest < ActionDispatch::IntegrationTest
end
test 'it uses appropriate authentication_keys when configured with hash' do
swap Devise, :authentication_keys => { :username => false, :email => false } do
swap Devise, :authentication_keys => ActiveSupport::OrderedHash[:username, false, :email, false] do
sign_in_as_new_user_with_http("usertest")
assert_response :success
assert_match '<email>user@test.com</email>', response.body
@ -72,7 +72,7 @@ class HttpAuthenticationTest < ActionDispatch::IntegrationTest
end
test 'it uses the appropriate key when configured explicitly' do
swap Devise, :authentication_keys => { :email => false, :username => false }, :http_auth_key => :username do
swap Devise, :authentication_keys => ActiveSupport::OrderedHash[:email, false, :username, false], :http_authentication_key => :username do
sign_in_as_new_user_with_http("usertest")
assert_response :success
assert_match '<email>user@test.com</email>', response.body

View file

@ -90,7 +90,7 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
end
assert session["devise.facebook_data"]
user = sign_in_as_user
sign_in_as_user
assert !session["devise.facebook_data"]
end

View file

@ -271,7 +271,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
end
test 'change password with invalid token in XML format should return invalid response' do
user = create_user
create_user
request_forgot_password
put user_password_path(:format => 'xml'), :user => {:reset_password_token => 'invalid.token', :password => '987654321', :password_confirmation => '987654321'}
assert_response :unprocessable_entity

View file

@ -113,7 +113,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
# https://github.com/mongoid/mongoid/issues/756
(pending "Fails on Mongoid < 2.1"; break) if defined?(Mongoid) && Mongoid::VERSION.to_f < 2.1
user = create_user
create_user
get new_user_registration_path
fill_in 'email', :with => 'user@test.com'
@ -287,7 +287,7 @@ class RegistrationTest < ActionDispatch::IntegrationTest
end
test 'a user cancel his account in XML format should return valid response' do
user = sign_in_as_user
sign_in_as_user
delete user_registration_path(:format => 'xml')
assert_response :success
assert_equal User.count, 0

View file

@ -26,7 +26,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'do not remember the user if he has not checked remember me option' do
user = sign_in_as_user
sign_in_as_user
assert_nil request.cookies["remember_user_cookie"]
end
@ -43,7 +43,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'generate remember token after sign in' do
user = sign_in_as_user :remember_me => true
sign_in_as_user :remember_me => true
assert request.cookies["remember_user_token"]
end
@ -84,7 +84,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'remember the user before sign up and redirect him to his home' do
user = create_user_and_remember
create_user_and_remember
get new_user_registration_path
assert warden.authenticated?(:user)
assert_redirected_to root_path
@ -92,7 +92,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
test 'cookies are destroyed on unverified requests' do
swap ApplicationController, :allow_forgery_protection => true do
user = create_user_and_remember
create_user_and_remember
get users_path
assert warden.authenticated?(:user)
post root_path, :authenticity_token => 'INVALID'
@ -117,7 +117,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'do not remember other scopes' do
user = create_user_and_remember
create_user_and_remember
get root_path
assert_response :success
assert warden.authenticated?(:user)
@ -125,14 +125,14 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'do not remember with invalid token' do
user = create_user_and_remember('add')
create_user_and_remember('add')
get users_path
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path
end
test 'do not remember with expired token' do
user = create_user_and_remember
create_user_and_remember
swap Devise, :remember_for => 0 do
get users_path
assert_not warden.authenticated?(:user)
@ -141,7 +141,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
test 'do not remember the user anymore after forget' do
user = create_user_and_remember
create_user_and_remember
get users_path
assert warden.authenticated?(:user)

View file

@ -129,6 +129,46 @@ class TokenAuthenticationTest < ActionDispatch::IntegrationTest
end
end
test 'authenticate with valid authentication token key and value through http header' do
swap Devise, :token_authentication_key => :secret_token do
sign_in_as_new_user_with_token(:token_auth => true)
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert_equal request.env['devise.token_options'], {}
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through http header, with options' do
swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => [:token_options] do
signature = "**TESTSIGNATURE**"
sign_in_as_new_user_with_token(:token_auth => true, :token_options => {:signature => signature, :nonce => 'def'})
assert_response :success
assert_match '<email>user@test.com</email>', response.body
assert_equal request.env['devise.token_options'][:signature], signature
assert_equal request.env['devise.token_options'][:nonce], 'def'
assert warden.authenticated?(:user)
end
end
test 'authenticate with valid authentication token key and value through http header without allowing token authorization setting is denied' do
swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => false do
sign_in_as_new_user_with_token(:token_auth => true)
assert_response :unauthorized
assert_nil warden.user(:user)
end
end
test 'does not authenticate with improper authentication token value in header' do
sign_in_as_new_user_with_token(:token_auth => true, :auth_token => '*** INVALID TOKEN ***')
assert_response :unauthorized
assert_nil warden.user(:user)
end
private
def sign_in_as_new_user_with_token(options = {})
@ -140,6 +180,10 @@ class TokenAuthenticationTest < ActionDispatch::IntegrationTest
if options[:http_auth]
header = "Basic #{Base64.encode64("#{VALID_AUTHENTICATION_TOKEN}:X")}"
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => header
elsif options[:token_auth]
token_options = options[:token_options] || {}
header = ActionController::HttpAuthentication::Token.encode_credentials(options[:auth_token], token_options)
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => header
else
visit users_path(options[:auth_token_key].to_sym => options[:auth_token])
end

View file

@ -52,6 +52,18 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
assert_equal( { "login" => "foo@bar.com", "bool1" => "true", "bool2" => "false", "fixnum" => "123", "will_be_converted" => "1..10" }, conditions)
end
test 'param filter should filter case_insensitive_keys as insensitive' do
conditions = {'insensitive' => 'insensitive_VAL', 'sensitive' => 'sensitive_VAL'}
conditions = Devise::ParamFilter.new(['insensitive'], []).filter(conditions)
assert_equal( {'insensitive' => 'insensitive_val', 'sensitive' => 'sensitive_VAL'}, conditions )
end
test 'param filter should filter strip_whitespace_keys stripping whitespaces' do
conditions = {'strip_whitespace' => ' strip_whitespace_val ', 'do_not_strip_whitespace' => ' do_not_strip_whitespace_val '}
conditions = Devise::ParamFilter.new([], ['strip_whitespace']).filter(conditions)
assert_equal( {'strip_whitespace' => 'strip_whitespace_val', 'do_not_strip_whitespace' => ' do_not_strip_whitespace_val '}, conditions )
end
test 'should respond to password and password confirmation' do
user = new_user
assert user.respond_to?(:password)
@ -170,6 +182,26 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
assert user.valid_password?('12345678')
end
test 'should destroy user if current password is valid' do
user = create_user
assert user.destroy_with_password('12345678')
assert !user.persisted?
end
test 'should not destroy user with invalid password' do
user = create_user
assert_not user.destroy_with_password('other')
assert user.persisted?
assert_match "is invalid", user.errors[:current_password].join
end
test 'should not destroy user with blank password' do
user = create_user
assert_not user.destroy_with_password(nil)
assert user.persisted?
assert_match "can't be blank", user.errors[:current_password].join
end
test 'downcase_keys with validation' do
user = User.create(:email => "HEllO@example.com", :password => "123456")
user = User.create(:email => "HEllO@example.com", :password => "123456")

View file

@ -59,7 +59,7 @@ class LockableTest < ActiveSupport::TestCase
assert_not user.active_for_authentication?
end
test "should unlock a user by cleaning locked_at, falied_attempts and unlock_token" do
test "should unlock a user by cleaning locked_at, failed_attempts and unlock_token" do
user = create_user
user.lock_access!
assert_not_nil user.reload.locked_at

View file

@ -115,7 +115,7 @@ class RememberableTest < ActiveSupport::TestCase
end
end
test 'remember should not be expired if it was created whitin the limit time' do
test 'remember should not be expired if it was created within the limit time' do
swap Devise, :remember_for => 30.days do
resource = create_resource
resource.remember_me!
@ -167,7 +167,7 @@ class RememberableTest < ActiveSupport::TestCase
end
end
test 'should have the required_fiels array' do
test 'should have the required_fields array' do
assert_same_content Devise::Models::Rememberable.required_fields(User), [
:remember_created_at
]

View file

@ -6,18 +6,18 @@ class SerializableTest < ActiveSupport::TestCase
end
test 'should not include unsafe keys on XML' do
assert_match /email/, @user.to_xml
assert_no_match /confirmation-token/, @user.to_xml
assert_match(/email/, @user.to_xml)
assert_no_match(/confirmation-token/, @user.to_xml)
end
test 'should not include unsafe keys on XML even if a new except is provided' do
assert_no_match /email/, @user.to_xml(:except => :email)
assert_no_match /confirmation-token/, @user.to_xml(:except => :email)
assert_no_match(/email/, @user.to_xml(:except => :email))
assert_no_match(/confirmation-token/, @user.to_xml(:except => :email))
end
test 'should include unsafe keys on XML if a force_except is provided' do
assert_no_match /<email/, @user.to_xml(:force_except => :email)
assert_match /confirmation-token/, @user.to_xml(:force_except => :email)
assert_no_match(/<email/, @user.to_xml(:force_except => :email))
assert_match(/confirmation-token/, @user.to_xml(:force_except => :email))
end
test 'should not include unsafe keys on JSON' do

View file

@ -64,7 +64,7 @@ class ValidatableTest < ActiveSupport::TestCase
end
end
test 'should require password when updating/reseting password' do
test 'should require password when updating/resetting password' do
user = create_user
user.password = ''
@ -74,7 +74,7 @@ class ValidatableTest < ActiveSupport::TestCase
assert_equal 'can\'t be blank', user.errors[:password].join
end
test 'should require confirmation when updating/reseting password' do
test 'should require confirmation when updating/resetting password' do
user = create_user
user.password_confirmation = 'another_password'
assert user.invalid?
@ -108,7 +108,7 @@ class ValidatableTest < ActiveSupport::TestCase
assert_not (user.errors[:password].join =~ /is too long/)
end
test 'should complain about length even if possword is not required' do
test 'should complain about length even if password is not required' do
user = new_user(:password => 'x'*129, :password_confirmation => 'x'*129)
user.stubs(:password_required?).returns(false)
assert user.invalid?