devise 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (52) hide show
  1. data/CHANGELOG.rdoc +4 -0
  2. data/README.rdoc +1 -0
  3. data/Rakefile +11 -3
  4. data/TODO +6 -3
  5. data/generators/devise_install/templates/devise.rb +7 -3
  6. data/lib/devise.rb +12 -7
  7. data/lib/devise/controllers/helpers.rb +1 -1
  8. data/lib/devise/hooks/{confirmable.rb → activatable.rb} +5 -4
  9. data/lib/devise/locales/en.yml +2 -0
  10. data/lib/devise/models.rb +20 -7
  11. data/lib/devise/models/activatable.rb +16 -0
  12. data/lib/devise/models/authenticatable.rb +14 -22
  13. data/lib/devise/models/confirmable.rb +12 -6
  14. data/lib/devise/models/cookie_serializer.rb +21 -0
  15. data/lib/devise/models/rememberable.rb +2 -20
  16. data/lib/devise/models/session_serializer.rb +19 -0
  17. data/lib/devise/models/validatable.rb +0 -4
  18. data/lib/devise/serializers/base.rb +2 -9
  19. data/lib/devise/serializers/cookie.rb +43 -0
  20. data/lib/devise/serializers/session.rb +22 -0
  21. data/lib/devise/version.rb +1 -1
  22. data/test/integration/confirmable_test.rb +3 -2
  23. data/test/integration/recoverable_test.rb +1 -1
  24. data/test/mapping_test.rb +9 -9
  25. data/test/models/authenticatable_test.rb +1 -1
  26. data/test/models/confirmable_test.rb +7 -5
  27. data/test/models/recoverable_test.rb +3 -3
  28. data/test/models/rememberable_test.rb +11 -5
  29. data/test/models/validatable_test.rb +1 -0
  30. data/test/models_test.rb +10 -10
  31. data/test/orm/active_record.rb +29 -0
  32. data/test/orm/mongo_mapper.rb +21 -0
  33. data/test/rails_app/app/{models → active_record}/account.rb +0 -0
  34. data/test/rails_app/app/{models → active_record}/admin.rb +1 -1
  35. data/test/rails_app/app/{models → active_record}/user.rb +1 -1
  36. data/test/rails_app/app/mongo_mapper/account.rb +9 -0
  37. data/test/rails_app/app/mongo_mapper/admin.rb +9 -0
  38. data/test/rails_app/app/mongo_mapper/user.rb +6 -0
  39. data/test/rails_app/config/environment.rb +3 -3
  40. data/test/rails_app/config/initializers/devise.rb +76 -0
  41. data/test/rails_app/config/routes.rb +2 -5
  42. data/test/routes_test.rb +4 -16
  43. data/test/support/assertions_helper.rb +15 -0
  44. data/test/support/integration_tests_helper.rb +1 -1
  45. data/test/support/model_tests_helper.rb +0 -15
  46. data/test/support/test_silencer.rb +5 -0
  47. data/test/test_helper.rb +7 -30
  48. data/test/test_helpers_test.rb +2 -6
  49. metadata +18 -9
  50. data/lib/devise/serializers/authenticatable.rb +0 -11
  51. data/lib/devise/serializers/rememberable.rb +0 -30
  52. data/test/rails_app/app/models/organizer.rb +0 -3
@@ -7,24 +7,17 @@ module Devise
7
7
  attr_reader :scope
8
8
 
9
9
  def serialize(record)
10
- record.class.send(:"serialize_into_#{serialization_type}", record)
10
+ record.class.send(:"serialize_into_#{klass_type}", record)
11
11
  end
12
12
 
13
13
  def deserialize(keys)
14
- mapping.to.send(:"serialize_from_#{serialization_type}", keys)
14
+ mapping.to.send(:"serialize_from_#{klass_type}", keys)
15
15
  end
16
16
 
17
17
  def fetch(scope)
18
18
  @scope = scope
19
19
  super
20
20
  end
21
-
22
- def serialization_type
23
- @serialization_type ||= begin
24
- warden = self.class.ancestors.find{ |k| k < Warden::Serializers::Base && k != self.class }
25
- warden.name.split("::").last.underscore
26
- end
27
- end
28
21
  end
29
22
  end
30
23
  end
@@ -0,0 +1,43 @@
1
+ require 'devise/serializers/base'
2
+
3
+ module Devise
4
+ module Serializers
5
+ # This is a cookie serializer which stores the information if a :remember_me
6
+ # is sent in the params and if the model responds to remember_me! as well.
7
+ # As in Session serializer, the invoked methods are:
8
+ #
9
+ # User.serialize_into_cookie(@user)
10
+ # User.serialize_from_cookie(*args)
11
+ #
12
+ # An implementation for such methods can be found at Devise::Models::Rememberable.
13
+ #
14
+ # Differently from session, this approach is based in a token which is stored in
15
+ # the database. So if you want to sign out all clients at once, you just need to
16
+ # clean up the token column.
17
+ #
18
+ class Cookie < Warden::Serializers::Cookie
19
+ include Devise::Serializers::Base
20
+
21
+ def store(record, scope)
22
+ remember_me = params[scope].try(:fetch, :remember_me, nil)
23
+ if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
24
+ record.remember_me!
25
+ super
26
+ end
27
+ end
28
+
29
+ def default_options(record)
30
+ super.merge!(:expires => record.remember_expires_at)
31
+ end
32
+
33
+ def delete(scope, record=nil)
34
+ if record && record.respond_to?(:forget_me!)
35
+ record.forget_me!
36
+ super
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ Warden::Serializers.add(:cookie, Devise::Serializers::Cookie)
@@ -0,0 +1,22 @@
1
+ require 'devise/serializers/base'
2
+
3
+ module Devise
4
+ module Serializers
5
+ # This serializer stores sign in information in th client session. It just
6
+ # extends Warden own serializer to move all the serialization logic to a
7
+ # class. For example, if a @user resource is given, it will call the following
8
+ # two methods to serialize and deserialize a record:
9
+ #
10
+ # User.serialize_into_session(@user)
11
+ # User.serialize_from_session(*args)
12
+ #
13
+ # This can be used any strategy and the default implementation is available
14
+ # at Devise::Models::SessionSerializer.
15
+ #
16
+ class Session < Warden::Serializers::Session
17
+ include Devise::Serializers::Base
18
+ end
19
+ end
20
+ end
21
+
22
+ Warden::Serializers.add(:session, Devise::Serializers::Session)
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "0.7.3".freeze
2
+ VERSION = "0.7.4".freeze
3
3
  end
@@ -27,7 +27,7 @@ class ConfirmationTest < ActionController::IntegrationTest
27
27
  assert_response :success
28
28
  assert_template 'confirmations/new'
29
29
  assert_have_selector '#errorExplanation'
30
- assert_contain 'Confirmation token is invalid'
30
+ assert_contain /Confirmation token(.*)invalid/
31
31
  end
32
32
 
33
33
  test 'user with valid confirmation token should be able to confirm an account' do
@@ -44,7 +44,8 @@ class ConfirmationTest < ActionController::IntegrationTest
44
44
 
45
45
  test 'user already confirmed user should not be able to confirm the account again' do
46
46
  user = create_user(:confirm => false)
47
- user.update_attribute(:confirmed_at, Time.now)
47
+ user.confirmed_at = Time.now
48
+ user.save
48
49
  visit_user_confirmation_with_token(user.confirmation_token)
49
50
 
50
51
  assert_template 'confirmations/new'
@@ -78,7 +78,7 @@ class PasswordTest < ActionController::IntegrationTest
78
78
  assert_response :success
79
79
  assert_template 'passwords/edit'
80
80
  assert_have_selector '#errorExplanation'
81
- assert_contain 'Reset password token is invalid'
81
+ assert_contain /Reset password token(.*)invalid/
82
82
  assert_not user.reload.valid_password?('987654321')
83
83
  end
84
84
 
@@ -14,8 +14,8 @@ class MappingTest < ActiveSupport::TestCase
14
14
  assert_equal :admin_area, Devise.mappings[:admin].as
15
15
  end
16
16
 
17
- test 'allow custom singular to be given' do
18
- assert_equal :organizers, Devise.mappings[:manager].as
17
+ test 'allow custom scope to be given' do
18
+ assert_equal :accounts, Devise.mappings[:manager].as
19
19
  end
20
20
 
21
21
  test 'allows a controller depending on the mapping' do
@@ -70,7 +70,7 @@ class MappingTest < ActiveSupport::TestCase
70
70
  end
71
71
 
72
72
  test 'allow custom path names to be given' do
73
- mapping = Devise.mappings[:account]
73
+ mapping = Devise.mappings[:manager]
74
74
  assert_equal 'login', mapping.path_names[:sign_in]
75
75
  assert_equal 'logout', mapping.path_names[:sign_out]
76
76
  assert_equal 'secret', mapping.path_names[:password]
@@ -78,7 +78,7 @@ class MappingTest < ActiveSupport::TestCase
78
78
  end
79
79
 
80
80
  test 'has an empty path as default path prefix' do
81
- mapping = Devise.mappings[:account]
81
+ mapping = Devise.mappings[:user]
82
82
  assert_equal '/', mapping.path_prefix
83
83
  end
84
84
 
@@ -88,20 +88,20 @@ class MappingTest < ActiveSupport::TestCase
88
88
  end
89
89
 
90
90
  test 'retrieve as from the proper position' do
91
- assert_equal 1, Devise.mappings[:account].as_position
91
+ assert_equal 1, Devise.mappings[:user].as_position
92
92
  assert_equal 2, Devise.mappings[:manager].as_position
93
93
  end
94
94
 
95
95
  test 'raw path is returned' do
96
- assert_equal '/account', Devise.mappings[:account].raw_path
97
- assert_equal '/:locale/organizers', Devise.mappings[:manager].raw_path
96
+ assert_equal '/users', Devise.mappings[:user].raw_path
97
+ assert_equal '/:locale/accounts', Devise.mappings[:manager].raw_path
98
98
  end
99
99
 
100
100
  test 'parsed path is returned' do
101
101
  begin
102
102
  Devise.default_url_options {{ :locale => I18n.locale }}
103
- assert_equal '/account', Devise.mappings[:account].parsed_path
104
- assert_equal '/en/organizers', Devise.mappings[:manager].parsed_path
103
+ assert_equal '/users', Devise.mappings[:user].parsed_path
104
+ assert_equal '/en/accounts', Devise.mappings[:manager].parsed_path
105
105
  ensure
106
106
  Devise.default_url_options {{ }}
107
107
  end
@@ -168,8 +168,8 @@ class AuthenticatableTest < ActiveSupport::TestCase
168
168
  user = create_user
169
169
  assert_not user.update_with_password(:old_password => 'other',
170
170
  :password => 'pass321', :password_confirmation => 'pass321')
171
- assert_equal 'is invalid', user.errors[:old_password]
172
171
  assert user.reload.valid_password?('123456')
172
+ assert_match /invalid/, user.errors[:old_password]
173
173
  end
174
174
 
175
175
  test 'should not update password with invalid confirmation' do
@@ -57,7 +57,7 @@ class ConfirmableTest < ActiveSupport::TestCase
57
57
  assert_nil user.errors[:email]
58
58
 
59
59
  assert_not user.confirm!
60
- assert_equal 'already confirmed', user.errors[:email]
60
+ assert_match /already confirmed/, user.errors[:email]
61
61
  end
62
62
 
63
63
  test 'should find and confirm an user automatically' do
@@ -70,18 +70,19 @@ class ConfirmableTest < ActiveSupport::TestCase
70
70
  test 'should return a new record with errors when a invalid token is given' do
71
71
  confirmed_user = User.confirm!(:confirmation_token => 'invalid_confirmation_token')
72
72
  assert confirmed_user.new_record?
73
- assert_equal "is invalid", confirmed_user.errors[:confirmation_token]
73
+ assert_match /invalid/, confirmed_user.errors[:confirmation_token]
74
74
  end
75
75
 
76
76
  test 'should return a new record with errors when a blank token is given' do
77
77
  confirmed_user = User.confirm!(:confirmation_token => '')
78
78
  assert confirmed_user.new_record?
79
- assert_equal "can't be blank", confirmed_user.errors[:confirmation_token]
79
+ assert_match /blank/, confirmed_user.errors[:confirmation_token]
80
80
  end
81
81
 
82
82
  test 'should generate errors for a user email if user is already confirmed' do
83
83
  user = create_user
84
- user.update_attribute(:confirmed_at, Time.now)
84
+ user.confirmed_at = Time.now
85
+ user.save
85
86
  confirmed_user = User.confirm!(:confirmation_token => user.confirmation_token)
86
87
  assert confirmed_user.confirmed?
87
88
  assert confirmed_user.errors[:email]
@@ -220,7 +221,8 @@ class ConfirmableTest < ActiveSupport::TestCase
220
221
 
221
222
  test 'should not be active without confirmation' do
222
223
  user = create_user
223
- user.update_attribute(:confirmation_sent_at, nil)
224
+ user.confirmation_sent_at = nil
225
+ user.save
224
226
  assert_not user.reload.active?
225
227
  end
226
228
  end
@@ -83,7 +83,7 @@ class RecoverableTest < ActiveSupport::TestCase
83
83
  test 'should return a new record with errors if user was not found by e-mail' do
84
84
  reset_password_user = User.send_reset_password_instructions(:email => "invalid@email.com")
85
85
  assert reset_password_user.new_record?
86
- assert_equal 'not found', reset_password_user.errors[:email]
86
+ assert_match /not found/, reset_password_user.errors[:email]
87
87
  end
88
88
 
89
89
  test 'should reset reset_password_token before send the reset instructions email' do
@@ -111,13 +111,13 @@ class RecoverableTest < ActiveSupport::TestCase
111
111
  test 'should a new record with errors if no reset_password_token is found' do
112
112
  reset_password_user = User.reset_password!(:reset_password_token => 'invalid_token')
113
113
  assert reset_password_user.new_record?
114
- assert_equal 'is invalid', reset_password_user.errors[:reset_password_token]
114
+ assert_match /invalid/, reset_password_user.errors[:reset_password_token]
115
115
  end
116
116
 
117
117
  test 'should a new record with errors if reset_password_token is blank' do
118
118
  reset_password_user = User.reset_password!(:reset_password_token => '')
119
119
  assert reset_password_user.new_record?
120
- assert_equal "can't be blank", reset_password_user.errors[:reset_password_token]
120
+ assert_match /blank/, reset_password_user.errors[:reset_password_token]
121
121
  end
122
122
 
123
123
  test 'should reset successfully user password given the new password and confirmation' do
@@ -56,7 +56,8 @@ class RememberableTest < ActiveSupport::TestCase
56
56
  test 'valid remember token should also verify if remember is not expired' do
57
57
  user = create_user
58
58
  user.remember_me!
59
- user.update_attribute(:remember_created_at, 3.days.ago)
59
+ user.remember_created_at = 3.days.ago
60
+ user.save
60
61
  assert_not user.valid_remember_token?(user.remember_token)
61
62
  end
62
63
 
@@ -72,8 +73,11 @@ class RememberableTest < ActiveSupport::TestCase
72
73
  assert_equal user, User.serialize_from_cookie("#{user.id}::#{user.remember_token}")
73
74
  end
74
75
 
75
- test 'serialize should return nil if no user is found' do
76
- assert_nil User.serialize_from_cookie('0::123')
76
+ # MongoMapper cries if an invalid ID is given, so this does not need to be tested
77
+ unless DEVISE_ORM == :mongo_mapper
78
+ test 'serialize should return nil if no user is found' do
79
+ assert_nil User.serialize_from_cookie('0::123')
80
+ end
77
81
  end
78
82
 
79
83
  test 'remember me return nil if is a valid user with invalid token' do
@@ -113,7 +117,8 @@ class RememberableTest < ActiveSupport::TestCase
113
117
  swap Devise, :remember_for => 1.day do
114
118
  user = create_user
115
119
  user.remember_me!
116
- user.update_attribute(:remember_created_at, 2.days.ago)
120
+ user.remember_created_at = 2.days.ago
121
+ user.save
117
122
  assert user.remember_expired?
118
123
  end
119
124
  end
@@ -122,7 +127,8 @@ class RememberableTest < ActiveSupport::TestCase
122
127
  swap Devise, :remember_for => 30.days do
123
128
  user = create_user
124
129
  user.remember_me!
125
- user.update_attribute(:remember_created_at, 30.days.ago + 2.minutes)
130
+ user.remember_created_at = (30.days.ago + 2.minutes)
131
+ user.save
126
132
  assert_not user.remember_expired?
127
133
  end
128
134
  end
@@ -1,6 +1,7 @@
1
1
  require 'test/test_helper'
2
2
 
3
3
  class ValidatableTest < ActiveSupport::TestCase
4
+ extend Devise::TestSilencer if [:mongo_mapper, :data_mapper].include?(DEVISE_ORM)
4
5
 
5
6
  test 'should require email to be set' do
6
7
  user = new_user(:email => nil)
@@ -24,7 +24,7 @@ class Timeoutable < User
24
24
  devise :authenticatable, :timeoutable
25
25
  end
26
26
 
27
- class Validatable < User
27
+ class IsValidatable < User
28
28
  devise :authenticatable, :validatable
29
29
  end
30
30
 
@@ -37,11 +37,11 @@ class Exceptable < User
37
37
  end
38
38
 
39
39
  class Configurable < User
40
- devise :all, :stretches => 15,
41
- :pepper => 'abcdef',
42
- :confirm_within => 5.days,
43
- :remember_for => 7.days,
44
- :timeout_in => 15.minutes
40
+ devise :all, :timeoutable, :stretches => 15,
41
+ :pepper => 'abcdef',
42
+ :confirm_within => 5.days,
43
+ :remember_for => 7.days,
44
+ :timeout_in => 15.minutes
45
45
  end
46
46
 
47
47
  class ActiveRecordTest < ActiveSupport::TestCase
@@ -60,7 +60,7 @@ class ActiveRecordTest < ActiveSupport::TestCase
60
60
  end
61
61
  end
62
62
 
63
- test 'include by default authenticatable only' do
63
+ test 'add authenticatable module only' do
64
64
  assert_include_modules Authenticatable, :authenticatable
65
65
  end
66
66
 
@@ -85,16 +85,16 @@ class ActiveRecordTest < ActiveSupport::TestCase
85
85
  end
86
86
 
87
87
  test 'add validatable module only' do
88
- assert_include_modules Validatable, :authenticatable, :validatable
88
+ assert_include_modules IsValidatable, :authenticatable, :validatable
89
89
  end
90
90
 
91
91
  test 'add all modules' do
92
92
  assert_include_modules Devisable,
93
- :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :timeoutable, :validatable
93
+ :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
94
94
  end
95
95
 
96
96
  test 'configure modules with except option' do
97
- assert_include_modules Exceptable, :authenticatable, :confirmable, :trackable, :timeoutable
97
+ assert_include_modules Exceptable, :authenticatable, :confirmable, :trackable
98
98
  end
99
99
 
100
100
  test 'set a default value for stretches' do
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'rails_app', 'config', 'environment')
2
+ require 'test_help'
3
+
4
+ ActiveRecord::Migration.verbose = false
5
+ ActiveRecord::Base.logger = Logger.new(nil)
6
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
7
+
8
+ ActiveRecord::Schema.define(:version => 1) do
9
+ [:users, :admins, :accounts].each do |table|
10
+ create_table table do |t|
11
+ t.authenticatable :null => table == :admins
12
+
13
+ if table != :admin
14
+ t.string :username
15
+ t.confirmable
16
+ t.recoverable
17
+ t.rememberable
18
+ t.trackable
19
+ end
20
+
21
+ t.timestamps
22
+ end
23
+ end
24
+ end
25
+
26
+ class ActiveSupport::TestCase
27
+ self.use_transactional_fixtures = true
28
+ self.use_instantiated_fixtures = false
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'mongo_mapper'
2
+ MongoMapper.database = "devise-test-suite"
3
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
4
+
5
+ require File.join(File.dirname(__FILE__), '..', 'rails_app', 'config', 'environment')
6
+ require 'test_help'
7
+
8
+ module MongoMapper::Document
9
+ # TODO This should not be required
10
+ def invalid?
11
+ !valid?
12
+ end
13
+ end
14
+
15
+ class ActiveSupport::TestCase
16
+ setup do
17
+ User.delete_all
18
+ Admin.delete_all
19
+ Account.delete_all
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  class Admin < ActiveRecord::Base
2
- devise :all, :except => [:recoverable, :confirmable, :rememberable, :validatable, :trackable]
2
+ devise :all, :timeoutable, :except => [:recoverable, :confirmable, :rememberable, :validatable, :trackable]
3
3
 
4
4
  def self.find_for_authentication(conditions)
5
5
  last(:conditions => conditions)
@@ -1,4 +1,4 @@
1
1
  class User < ActiveRecord::Base
2
- devise :all
2
+ devise :all, :timeoutable
3
3
  attr_accessible :username, :email, :password, :password_confirmation
4
4
  end
@@ -0,0 +1,9 @@
1
+ class Account
2
+ include MongoMapper::Document
3
+
4
+ devise :all
5
+
6
+ def self.find_for_authentication(conditions)
7
+ nil
8
+ end
9
+ end