sorcery 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +29 -104
- data/CHANGELOG.md +13 -1
- data/Gemfile +2 -16
- data/README.md +124 -272
- data/Rakefile +2 -2
- data/gemfiles/{mongoid-rails40.gemfile → active_record-rails42.gemfile} +1 -3
- data/lib/generators/sorcery/helpers.rb +4 -4
- data/lib/generators/sorcery/install_generator.rb +25 -19
- data/lib/generators/sorcery/templates/initializer.rb +27 -52
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +2 -2
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +1 -1
- data/lib/generators/sorcery/templates/migration/core.rb +3 -3
- data/lib/generators/sorcery/templates/migration/external.rb +2 -2
- data/lib/generators/sorcery/templates/migration/remember_me.rb +2 -2
- data/lib/generators/sorcery/templates/migration/reset_password.rb +2 -2
- data/lib/generators/sorcery/templates/migration/user_activation.rb +2 -2
- data/lib/sorcery.rb +0 -28
- data/lib/sorcery/adapters/active_record_adapter.rb +7 -18
- data/lib/sorcery/controller.rb +19 -21
- data/lib/sorcery/controller/config.rb +20 -18
- data/lib/sorcery/controller/submodules/activity_logging.rb +7 -15
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
- data/lib/sorcery/controller/submodules/external.rb +22 -14
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +16 -19
- data/lib/sorcery/controller/submodules/remember_me.rb +15 -10
- data/lib/sorcery/controller/submodules/session_timeout.rb +7 -8
- data/lib/sorcery/crypto_providers/aes256.rb +15 -15
- data/lib/sorcery/crypto_providers/bcrypt.rb +19 -21
- data/lib/sorcery/crypto_providers/common.rb +1 -1
- data/lib/sorcery/crypto_providers/md5.rb +5 -5
- data/lib/sorcery/crypto_providers/sha1.rb +5 -5
- data/lib/sorcery/crypto_providers/sha256.rb +2 -2
- data/lib/sorcery/crypto_providers/sha512.rb +3 -3
- data/lib/sorcery/engine.rb +3 -8
- data/lib/sorcery/model.rb +24 -32
- data/lib/sorcery/model/config.rb +64 -49
- data/lib/sorcery/model/submodules/activity_logging.rb +31 -12
- data/lib/sorcery/model/submodules/brute_force_protection.rb +23 -23
- data/lib/sorcery/model/submodules/external.rb +3 -7
- data/lib/sorcery/model/submodules/remember_me.rb +19 -7
- data/lib/sorcery/model/submodules/reset_password.rb +32 -36
- data/lib/sorcery/model/submodules/user_activation.rb +38 -50
- data/lib/sorcery/model/temporary_token.rb +2 -2
- data/lib/sorcery/protocols/oauth.rb +3 -9
- data/lib/sorcery/protocols/oauth2.rb +0 -2
- data/lib/sorcery/providers/base.rb +4 -4
- data/lib/sorcery/providers/facebook.rb +5 -8
- data/lib/sorcery/providers/github.rb +5 -7
- data/lib/sorcery/providers/google.rb +3 -5
- data/lib/sorcery/providers/heroku.rb +6 -8
- data/lib/sorcery/providers/jira.rb +12 -17
- data/lib/sorcery/providers/linkedin.rb +6 -8
- data/lib/sorcery/providers/liveid.rb +4 -7
- data/lib/sorcery/providers/paypal.rb +60 -0
- data/lib/sorcery/providers/salesforce.rb +3 -5
- data/lib/sorcery/providers/slack.rb +45 -0
- data/lib/sorcery/providers/twitter.rb +4 -6
- data/lib/sorcery/providers/vk.rb +3 -5
- data/lib/sorcery/providers/wechat.rb +79 -0
- data/lib/sorcery/providers/xing.rb +7 -10
- data/lib/sorcery/test_helpers/internal.rb +10 -10
- data/lib/sorcery/test_helpers/internal/rails.rb +16 -8
- data/lib/sorcery/test_helpers/rails/controller.rb +1 -1
- data/lib/sorcery/test_helpers/rails/integration.rb +5 -6
- data/lib/sorcery/version.rb +1 -1
- data/sorcery.gemspec +25 -27
- data/spec/active_record/user_activation_spec.rb +2 -3
- data/spec/active_record/user_activity_logging_spec.rb +2 -4
- data/spec/active_record/user_brute_force_protection_spec.rb +3 -4
- data/spec/active_record/user_oauth_spec.rb +3 -4
- data/spec/active_record/user_remember_me_spec.rb +3 -4
- data/spec/active_record/user_reset_password_spec.rb +2 -3
- data/spec/active_record/user_spec.rb +7 -7
- data/spec/controllers/controller_activity_logging_spec.rb +13 -24
- data/spec/controllers/controller_brute_force_protection_spec.rb +6 -8
- data/spec/controllers/controller_http_basic_auth_spec.rb +19 -20
- data/spec/controllers/controller_oauth2_spec.rb +125 -100
- data/spec/controllers/controller_oauth_spec.rb +86 -66
- data/spec/controllers/controller_remember_me_spec.rb +35 -30
- data/spec/controllers/controller_session_timeout_spec.rb +14 -15
- data/spec/controllers/controller_spec.rb +77 -111
- data/spec/orm/active_record.rb +1 -1
- data/spec/rails_app/app/active_record/authentication.rb +1 -1
- data/spec/rails_app/app/active_record/user.rb +2 -2
- data/spec/rails_app/app/controllers/sorcery_controller.rb +89 -24
- data/spec/rails_app/app/mailers/sorcery_mailer.rb +16 -17
- data/spec/rails_app/config.ru +1 -1
- data/spec/rails_app/config/application.rb +7 -7
- data/spec/rails_app/config/boot.rb +1 -1
- data/spec/rails_app/config/environments/test.rb +1 -1
- data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +11 -0
- data/spec/rails_app/config/initializers/session_store.rb +3 -3
- data/spec/rails_app/config/routes.rb +11 -1
- data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +4 -4
- data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +8 -8
- data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +5 -5
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +5 -5
- data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +3 -3
- data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +6 -6
- data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +5 -5
- data/spec/shared_examples/user_activation_shared_examples.rb +99 -58
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +47 -41
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +19 -24
- data/spec/shared_examples/user_oauth_shared_examples.rb +7 -10
- data/spec/shared_examples/user_remember_me_shared_examples.rb +90 -21
- data/spec/shared_examples/user_reset_password_shared_examples.rb +52 -54
- data/spec/shared_examples/user_shared_examples.rb +215 -118
- data/spec/sorcery_crypto_providers_spec.rb +63 -76
- data/spec/spec_helper.rb +17 -13
- metadata +28 -83
- data/gemfiles/mongo_mapper-rails40.gemfile +0 -9
- data/gemfiles/mongo_mapper-rails41.gemfile +0 -9
- data/gemfiles/mongoid-rails41.gemfile +0 -9
- data/gemfiles/mongoid3-rails32.gemfile +0 -9
- data/lib/sorcery/adapters/data_mapper_adapter.rb +0 -176
- data/lib/sorcery/adapters/mongo_mapper_adapter.rb +0 -110
- data/lib/sorcery/adapters/mongoid_adapter.rb +0 -97
- data/lib/sorcery/railties/tasks.rake +0 -6
- data/spec/data_mapper/user_activation_spec.rb +0 -10
- data/spec/data_mapper/user_activity_logging_spec.rb +0 -14
- data/spec/data_mapper/user_brute_force_protection_spec.rb +0 -9
- data/spec/data_mapper/user_oauth_spec.rb +0 -9
- data/spec/data_mapper/user_remember_me_spec.rb +0 -8
- data/spec/data_mapper/user_reset_password_spec.rb +0 -8
- data/spec/data_mapper/user_spec.rb +0 -27
- data/spec/mongo_mapper/user_activation_spec.rb +0 -9
- data/spec/mongo_mapper/user_activity_logging_spec.rb +0 -8
- data/spec/mongo_mapper/user_brute_force_protection_spec.rb +0 -8
- data/spec/mongo_mapper/user_oauth_spec.rb +0 -8
- data/spec/mongo_mapper/user_remember_me_spec.rb +0 -8
- data/spec/mongo_mapper/user_reset_password_spec.rb +0 -8
- data/spec/mongo_mapper/user_spec.rb +0 -37
- data/spec/mongoid/user_activation_spec.rb +0 -9
- data/spec/mongoid/user_activity_logging_spec.rb +0 -8
- data/spec/mongoid/user_brute_force_protection_spec.rb +0 -8
- data/spec/mongoid/user_oauth_spec.rb +0 -8
- data/spec/mongoid/user_remember_me_spec.rb +0 -8
- data/spec/mongoid/user_reset_password_spec.rb +0 -8
- data/spec/mongoid/user_spec.rb +0 -51
- data/spec/orm/data_mapper.rb +0 -48
- data/spec/orm/mongo_mapper.rb +0 -10
- data/spec/orm/mongoid.rb +0 -22
- data/spec/rails_app/app/data_mapper/authentication.rb +0 -8
- data/spec/rails_app/app/data_mapper/user.rb +0 -7
- data/spec/rails_app/app/mongo_mapper/authentication.rb +0 -6
- data/spec/rails_app/app/mongo_mapper/user.rb +0 -7
- data/spec/rails_app/app/mongoid/authentication.rb +0 -7
- data/spec/rails_app/app/mongoid/user.rb +0 -7
@@ -1,5 +1,5 @@
|
|
1
|
-
shared_examples_for
|
2
|
-
context
|
1
|
+
shared_examples_for 'rails_3_activity_logging_model' do
|
2
|
+
context 'loaded plugin configuration' do
|
3
3
|
before(:all) do
|
4
4
|
sorcery_reload!([:activity_logging])
|
5
5
|
end
|
@@ -29,43 +29,6 @@ shared_examples_for "rails_3_activity_logging_model" do
|
|
29
29
|
expect(User.sorcery_config.last_login_from_ip_address_name).to eq :ip_address
|
30
30
|
end
|
31
31
|
|
32
|
-
describe ".current_users" do
|
33
|
-
let(:user) { create_new_user }
|
34
|
-
|
35
|
-
it "is empty when no users are logged in" do
|
36
|
-
skip('unavailable in MongoMapper') if SORCERY_ORM == :mongo_mapper
|
37
|
-
expect(User.current_users).to be_empty
|
38
|
-
end
|
39
|
-
|
40
|
-
it "holds the user object when 1 user is logged in" do
|
41
|
-
skip('unavailable in MongoMapper') if SORCERY_ORM == :mongo_mapper
|
42
|
-
user.set_last_activity_at(Time.now.in_time_zone)
|
43
|
-
|
44
|
-
expect(User.current_users).to match([User.sorcery_adapter.find(user.id)])
|
45
|
-
end
|
46
|
-
|
47
|
-
it "'current_users' shows all current_users, whether they have logged out before or not." do
|
48
|
-
skip('unavailable in MongoMapper') if SORCERY_ORM == :mongo_mapper
|
49
|
-
User.sorcery_adapter.delete_all
|
50
|
-
user1 = create_new_user({:username => 'gizmo1', :email => "bla1@bla.com", :password => 'secret1'})
|
51
|
-
user2 = create_new_user({:username => 'gizmo2', :email => "bla2@bla.com", :password => 'secret2'})
|
52
|
-
user3 = create_new_user({:username => 'gizmo3', :email => "bla3@bla.com", :password => 'secret3'})
|
53
|
-
|
54
|
-
now = Time.now.in_time_zone
|
55
|
-
[user1, user2, user3].each do |user|
|
56
|
-
user.set_last_login_at(now)
|
57
|
-
user.set_last_activity_at(now)
|
58
|
-
end
|
59
|
-
|
60
|
-
expect(User.current_users.map(&:id)).to match_array([user1, user2, user3].map(&:id))
|
61
|
-
Timecop.travel now + 5
|
62
|
-
user1.set_last_logout_at(Time.now.in_time_zone)
|
63
|
-
expect(User.current_users.map(&:id)).to match_array([user2, user3].map(&:id))
|
64
|
-
Timecop.return
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
32
|
it '.set_last_login_at update last_login_at' do
|
70
33
|
user = create_new_user
|
71
34
|
now = Time.now.in_time_zone
|
@@ -90,11 +53,54 @@ shared_examples_for "rails_3_activity_logging_model" do
|
|
90
53
|
user.set_last_activity_at(now)
|
91
54
|
end
|
92
55
|
|
93
|
-
it '.
|
56
|
+
it '.set_last_ip_address update last_login_from_ip_address' do
|
94
57
|
user = create_new_user
|
95
58
|
expect(user.sorcery_adapter).to receive(:update_attribute).with(:last_login_from_ip_address, '0.0.0.0')
|
96
59
|
|
97
|
-
user.
|
60
|
+
user.set_last_ip_address('0.0.0.0')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'show if user logged in' do
|
64
|
+
user = create_new_user
|
65
|
+
expect(user.logged_in?).to eq(false)
|
66
|
+
|
67
|
+
now = Time.now.in_time_zone
|
68
|
+
user.set_last_login_at(now)
|
69
|
+
expect(user.logged_in?).to eq(true)
|
70
|
+
|
71
|
+
now = Time.now.in_time_zone
|
72
|
+
user.set_last_logout_at(now)
|
73
|
+
expect(user.logged_in?).to eq(false)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'show if user logged out' do
|
77
|
+
user = create_new_user
|
78
|
+
expect(user.logged_out?).to eq(true)
|
79
|
+
|
80
|
+
now = Time.now.in_time_zone
|
81
|
+
user.set_last_login_at(now)
|
82
|
+
expect(user.logged_out?).to eq(false)
|
83
|
+
|
84
|
+
now = Time.now.in_time_zone
|
85
|
+
user.set_last_logout_at(now)
|
86
|
+
expect(user.logged_out?).to eq(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'show online status of user' do
|
90
|
+
user = create_new_user
|
91
|
+
expect(user.online?).to eq(false)
|
92
|
+
|
93
|
+
now = Time.now.in_time_zone
|
94
|
+
user.set_last_login_at(now)
|
95
|
+
user.set_last_activity_at(now)
|
96
|
+
expect(user.online?).to eq(true)
|
97
|
+
|
98
|
+
user.set_last_activity_at(now - 1.day)
|
99
|
+
expect(user.online?).to eq(false)
|
100
|
+
|
101
|
+
now = Time.now.in_time_zone
|
102
|
+
user.set_last_logout_at(now)
|
103
|
+
expect(user.online?).to eq(false)
|
98
104
|
end
|
99
105
|
end
|
100
106
|
end
|
@@ -1,12 +1,10 @@
|
|
1
|
-
shared_examples_for
|
1
|
+
shared_examples_for 'rails_3_brute_force_protection_model' do
|
2
2
|
let(:user) { create_new_user }
|
3
3
|
before(:each) do
|
4
4
|
User.sorcery_adapter.delete_all
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
context "loaded plugin configuration" do
|
9
|
-
|
7
|
+
context 'loaded plugin configuration' do
|
10
8
|
let(:config) { User.sorcery_config }
|
11
9
|
|
12
10
|
before(:all) do
|
@@ -40,21 +38,21 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
40
38
|
expect(config.login_lock_time_period).to eq 2.hours
|
41
39
|
end
|
42
40
|
|
43
|
-
describe
|
44
|
-
it
|
41
|
+
describe '#login_locked?' do
|
42
|
+
it 'is locked' do
|
45
43
|
user.send("#{config.lock_expires_at_attribute_name}=", Time.now + 5.days)
|
46
|
-
expect(user).to
|
44
|
+
expect(user).to be_login_locked
|
47
45
|
end
|
48
46
|
|
49
47
|
it "isn't locked" do
|
50
48
|
user.send("#{config.lock_expires_at_attribute_name}=", nil)
|
51
|
-
expect(user).not_to
|
49
|
+
expect(user).not_to be_login_locked
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
56
|
-
describe
|
57
|
-
it
|
54
|
+
describe '#register_failed_login!' do
|
55
|
+
it 'locks user when number of retries reached the limit' do
|
58
56
|
expect(user.lock_expires_at).to be_nil
|
59
57
|
|
60
58
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
|
@@ -64,8 +62,8 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
64
62
|
expect(lock_expires_at).not_to be_nil
|
65
63
|
end
|
66
64
|
|
67
|
-
context
|
68
|
-
it
|
65
|
+
context 'unlock_token_mailer_disabled is true' do
|
66
|
+
it 'does not automatically send unlock email' do
|
69
67
|
sorcery_model_property_set(:unlock_token_mailer_disabled, true)
|
70
68
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
71
69
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
@@ -74,11 +72,10 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
74
72
|
3.times { user.register_failed_login! }
|
75
73
|
|
76
74
|
expect(ActionMailer::Base.deliveries.size).to eq 0
|
77
|
-
|
78
75
|
end
|
79
76
|
end
|
80
77
|
|
81
|
-
context
|
78
|
+
context 'unlock_token_mailer_disabled is false' do
|
82
79
|
before do
|
83
80
|
sorcery_model_property_set(:unlock_token_mailer_disabled, false)
|
84
81
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
@@ -86,13 +83,13 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
86
83
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
87
84
|
end
|
88
85
|
|
89
|
-
it
|
86
|
+
it 'does not automatically send unlock email' do
|
90
87
|
3.times { user.register_failed_login! }
|
91
88
|
|
92
89
|
expect(ActionMailer::Base.deliveries.size).to eq 1
|
93
90
|
end
|
94
91
|
|
95
|
-
it
|
92
|
+
it 'generates unlock token before mail is sent' do
|
96
93
|
3.times { user.register_failed_login! }
|
97
94
|
|
98
95
|
expect(ActionMailer::Base.deliveries.last.body.to_s.match(user.unlock_token)).not_to be_nil
|
@@ -100,9 +97,8 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
100
97
|
end
|
101
98
|
end
|
102
99
|
|
103
|
-
context
|
104
|
-
|
105
|
-
it "unlocks after lock time period passes" do
|
100
|
+
context '.authenticate' do
|
101
|
+
it 'unlocks after lock time period passes' do
|
106
102
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
107
103
|
sorcery_model_property_set(:login_lock_time_period, 0.2)
|
108
104
|
2.times { user.register_failed_login! }
|
@@ -118,7 +114,7 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
118
114
|
Timecop.return
|
119
115
|
end
|
120
116
|
|
121
|
-
it
|
117
|
+
it 'doest not unlock if time period is 0 (permanent lock)' do
|
122
118
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
123
119
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
124
120
|
|
@@ -132,11 +128,10 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
132
128
|
expect(user.lock_expires_at.to_s).to eq unlock_date.to_s
|
133
129
|
Timecop.return
|
134
130
|
end
|
135
|
-
|
136
131
|
end
|
137
132
|
|
138
|
-
describe
|
139
|
-
it
|
133
|
+
describe '#login_unlock!' do
|
134
|
+
it 'unlocks after entering unlock token' do
|
140
135
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
141
136
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
142
137
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
@@ -149,7 +144,7 @@ shared_examples_for "rails_3_brute_force_protection_model" do
|
|
149
144
|
|
150
145
|
expect(user).not_to be_nil
|
151
146
|
|
152
|
-
user.
|
147
|
+
user.login_unlock!
|
153
148
|
expect(User.load_from_unlock_token(user.unlock_token)).to be_nil
|
154
149
|
end
|
155
150
|
end
|
@@ -1,10 +1,9 @@
|
|
1
|
-
shared_examples_for
|
1
|
+
shared_examples_for 'rails_3_oauth_model' do
|
2
2
|
# ----------------- PLUGIN CONFIGURATION -----------------------
|
3
3
|
|
4
4
|
let(:external_user) { create_new_external_user :twitter }
|
5
5
|
|
6
|
-
describe
|
7
|
-
|
6
|
+
describe 'loaded plugin configuration' do
|
8
7
|
before(:all) do
|
9
8
|
Authentication.sorcery_adapter.delete_all
|
10
9
|
User.sorcery_adapter.delete_all
|
@@ -12,9 +11,9 @@ shared_examples_for "rails_3_oauth_model" do
|
|
12
11
|
sorcery_reload!([:external])
|
13
12
|
sorcery_controller_property_set(:external_providers, [:twitter])
|
14
13
|
sorcery_model_property_set(:authentications_class, Authentication)
|
15
|
-
sorcery_controller_external_property_set(:twitter, :key,
|
16
|
-
sorcery_controller_external_property_set(:twitter, :secret,
|
17
|
-
sorcery_controller_external_property_set(:twitter, :callback_url,
|
14
|
+
sorcery_controller_external_property_set(:twitter, :key, 'eYVNBjBDi33aa9GkA3w')
|
15
|
+
sorcery_controller_external_property_set(:twitter, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8')
|
16
|
+
sorcery_controller_external_property_set(:twitter, :callback_url, 'http://blabla.com')
|
18
17
|
end
|
19
18
|
|
20
19
|
it "responds to 'load_from_provider'" do
|
@@ -23,14 +22,12 @@ shared_examples_for "rails_3_oauth_model" do
|
|
23
22
|
|
24
23
|
it "'load_from_provider' loads user if exists" do
|
25
24
|
external_user
|
26
|
-
expect(User.load_from_provider
|
25
|
+
expect(User.load_from_provider(:twitter, 123)).to eq external_user
|
27
26
|
end
|
28
27
|
|
29
28
|
it "'load_from_provider' returns nil if user doesn't exist" do
|
30
29
|
external_user
|
31
|
-
expect(User.load_from_provider
|
30
|
+
expect(User.load_from_provider(:twitter, 980342)).to be_nil
|
32
31
|
end
|
33
|
-
|
34
32
|
end
|
35
|
-
|
36
33
|
end
|
@@ -1,16 +1,15 @@
|
|
1
|
-
shared_examples_for
|
1
|
+
shared_examples_for 'rails_3_remember_me_model' do
|
2
2
|
let(:user) { create_new_user }
|
3
3
|
|
4
|
-
describe
|
5
|
-
|
4
|
+
describe 'loaded plugin configuration' do
|
6
5
|
before(:all) do
|
7
6
|
sorcery_reload!([:remember_me])
|
8
7
|
end
|
9
|
-
|
8
|
+
|
10
9
|
after(:each) do
|
11
10
|
User.sorcery_config.reset!
|
12
11
|
end
|
13
|
-
|
12
|
+
|
14
13
|
it "allows configuration option 'remember_me_token_attribute_name'" do
|
15
14
|
sorcery_model_property_set(:remember_me_token_attribute_name, :my_token)
|
16
15
|
|
@@ -22,19 +21,19 @@ shared_examples_for "rails_3_remember_me_model" do
|
|
22
21
|
|
23
22
|
expect(User.sorcery_config.remember_me_token_expires_at_attribute_name).to eq :my_expires
|
24
23
|
end
|
25
|
-
|
24
|
+
|
25
|
+
it "allows configuration option 'remember_me_token_persist_globally'" do
|
26
|
+
sorcery_model_property_set(:remember_me_token_persist_globally, true)
|
27
|
+
|
28
|
+
expect(User.sorcery_config.remember_me_token_persist_globally).to eq true
|
29
|
+
end
|
30
|
+
|
26
31
|
specify { expect(user).to respond_to :remember_me! }
|
27
32
|
|
28
33
|
specify { expect(user).to respond_to :forget_me! }
|
29
|
-
|
30
|
-
it "generates a new token on 'remember_me!'" do
|
31
|
-
expect(user.remember_me_token).to be_nil
|
32
34
|
|
33
|
-
|
35
|
+
specify { expect(user).to respond_to :force_forget_me! }
|
34
36
|
|
35
|
-
expect(user.remember_me_token).not_to be_nil
|
36
|
-
end
|
37
|
-
|
38
37
|
it "sets an expiration based on 'remember_me_for' attribute" do
|
39
38
|
sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24)
|
40
39
|
|
@@ -45,16 +44,86 @@ shared_examples_for "rails_3_remember_me_model" do
|
|
45
44
|
|
46
45
|
expect(user.remember_me_token_expires_at.utc.to_s).to eq (ts + 2 * 60 * 60 * 24).utc.to_s
|
47
46
|
end
|
48
|
-
|
49
|
-
it "deletes the token and expiration on 'forget_me!'" do
|
50
|
-
user.remember_me!
|
51
47
|
|
52
|
-
|
48
|
+
context 'when not persisting globally' do
|
49
|
+
before { sorcery_model_property_set(:remember_me_token_persist_globally, false) }
|
50
|
+
|
51
|
+
it "generates a new token on 'remember_me!' when a token doesn't exist" do
|
52
|
+
expect(user.remember_me_token).to be_nil
|
53
|
+
user.remember_me!
|
54
|
+
|
55
|
+
expect(user.remember_me_token).not_to be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "generates a new token on 'remember_me!' when a token exists" do
|
59
|
+
user.remember_me_token = 'abc123'
|
60
|
+
user.remember_me!
|
61
|
+
|
62
|
+
expect(user.remember_me_token).not_to be_nil
|
63
|
+
expect(user.remember_me_token).not_to eq('abc123')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "deletes the token and expiration on 'forget_me!'" do
|
67
|
+
user.remember_me!
|
68
|
+
|
69
|
+
expect(user.remember_me_token).not_to be_nil
|
70
|
+
|
71
|
+
user.forget_me!
|
72
|
+
|
73
|
+
expect(user.remember_me_token).to be_nil
|
74
|
+
expect(user.remember_me_token_expires_at).to be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "deletes the token and expiration on 'force_forget_me!'" do
|
78
|
+
user.remember_me!
|
79
|
+
|
80
|
+
expect(user.remember_me_token).not_to be_nil
|
81
|
+
|
82
|
+
user.force_forget_me!
|
83
|
+
|
84
|
+
expect(user.remember_me_token).to be_nil
|
85
|
+
expect(user.remember_me_token_expires_at).to be_nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when persisting globally' do
|
90
|
+
before { sorcery_model_property_set(:remember_me_token_persist_globally, true) }
|
91
|
+
|
92
|
+
it "generates a new token on 'remember_me!' when a token doesn't exist" do
|
93
|
+
expect(user.remember_me_token).to be_nil
|
94
|
+
user.remember_me!
|
95
|
+
|
96
|
+
expect(user.remember_me_token).not_to be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "keeps existing token on 'remember_me!' when a token exists" do
|
100
|
+
user.remember_me_token = 'abc123'
|
101
|
+
user.remember_me!
|
102
|
+
|
103
|
+
expect(user.remember_me_token).to eq('abc123')
|
104
|
+
end
|
105
|
+
|
106
|
+
it "keeps the token and expiration on 'forget_me!'" do
|
107
|
+
user.remember_me!
|
108
|
+
|
109
|
+
expect(user.remember_me_token).not_to be_nil
|
110
|
+
|
111
|
+
user.forget_me!
|
53
112
|
|
54
|
-
|
113
|
+
expect(user.remember_me_token).to_not be_nil
|
114
|
+
expect(user.remember_me_token_expires_at).to_not be_nil
|
115
|
+
end
|
116
|
+
|
117
|
+
it "deletes the token and expiration on 'force_forget_me!'" do
|
118
|
+
user.remember_me!
|
55
119
|
|
56
|
-
|
57
|
-
|
120
|
+
expect(user.remember_me_token).not_to be_nil
|
121
|
+
|
122
|
+
user.force_forget_me!
|
123
|
+
|
124
|
+
expect(user.remember_me_token).to be_nil
|
125
|
+
expect(user.remember_me_token_expires_at).to be_nil
|
126
|
+
end
|
58
127
|
end
|
59
128
|
end
|
60
|
-
end
|
129
|
+
end
|
@@ -1,24 +1,22 @@
|
|
1
|
-
shared_examples_for
|
1
|
+
shared_examples_for 'rails_3_reset_password_model' do
|
2
2
|
# ----------------- PLUGIN CONFIGURATION -----------------------
|
3
3
|
let(:user) { create_new_user }
|
4
4
|
|
5
|
-
describe
|
6
|
-
|
5
|
+
describe 'loaded plugin configuration' do
|
7
6
|
before(:all) do
|
8
|
-
sorcery_reload!([:reset_password], :
|
7
|
+
sorcery_reload!([:reset_password], reset_password_mailer: ::SorceryMailer)
|
9
8
|
end
|
10
9
|
|
11
10
|
after(:each) do
|
12
11
|
User.sorcery_config.reset!
|
13
12
|
end
|
14
13
|
|
15
|
-
context
|
16
|
-
|
14
|
+
context 'API' do
|
17
15
|
specify { expect(user).to respond_to :deliver_reset_password_instructions! }
|
18
16
|
|
19
17
|
specify { expect(user).to respond_to :change_password! }
|
20
18
|
|
21
|
-
it
|
19
|
+
it 'responds to .load_from_reset_password_token' do
|
22
20
|
expect(User).to respond_to :load_from_reset_password_token
|
23
21
|
end
|
24
22
|
end
|
@@ -41,12 +39,12 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
41
39
|
expect(User.sorcery_config.reset_password_mailer_disabled).to eq :my_reset_password_mailer_disabled
|
42
40
|
end
|
43
41
|
|
44
|
-
it
|
45
|
-
expect{sorcery_reload!([:reset_password], :
|
42
|
+
it 'if mailer is nil and mailer is enabled, throw exception!' do
|
43
|
+
expect { sorcery_reload!([:reset_password], reset_password_mailer_disabled: false) }.to raise_error(ArgumentError)
|
46
44
|
end
|
47
45
|
|
48
|
-
it
|
49
|
-
expect{sorcery_reload!([:reset_password], :
|
46
|
+
it 'if mailer is disabled and mailer is nil, do NOT throw exception' do
|
47
|
+
expect { sorcery_reload!([:reset_password], reset_password_mailer_disabled: true) }.to_not raise_error
|
50
48
|
end
|
51
49
|
|
52
50
|
it "allows configuration option 'reset_password_email_method_name'" do
|
@@ -74,11 +72,9 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
77
|
-
|
78
|
-
describe "when activated with sorcery" do
|
79
|
-
|
75
|
+
describe 'when activated with sorcery' do
|
80
76
|
before(:all) do
|
81
|
-
sorcery_reload!([:reset_password], :
|
77
|
+
sorcery_reload!([:reset_password], reset_password_mailer: ::SorceryMailer)
|
82
78
|
end
|
83
79
|
|
84
80
|
before(:each) do
|
@@ -90,46 +86,46 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
90
86
|
Timecop.return
|
91
87
|
end
|
92
88
|
|
93
|
-
it
|
89
|
+
it 'load_from_reset_password_token returns user when token is found' do
|
94
90
|
user.generate_reset_password_token!
|
95
|
-
updated_user
|
91
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
96
92
|
|
97
|
-
expect(User.load_from_reset_password_token
|
93
|
+
expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user
|
98
94
|
end
|
99
95
|
|
100
|
-
it
|
96
|
+
it 'load_from_reset_password_token does NOT return user when token is NOT found' do
|
101
97
|
user.generate_reset_password_token!
|
102
98
|
|
103
|
-
expect(User.load_from_reset_password_token
|
99
|
+
expect(User.load_from_reset_password_token('a')).to be_nil
|
104
100
|
end
|
105
101
|
|
106
|
-
it
|
102
|
+
it 'load_from_reset_password_token returns user when token is found and not expired' do
|
107
103
|
sorcery_model_property_set(:reset_password_expiration_period, 500)
|
108
104
|
user.generate_reset_password_token!
|
109
|
-
updated_user
|
105
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
110
106
|
|
111
|
-
expect(User.load_from_reset_password_token
|
107
|
+
expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user
|
112
108
|
end
|
113
109
|
|
114
|
-
it
|
110
|
+
it 'load_from_reset_password_token does NOT return user when token is found and expired' do
|
115
111
|
sorcery_model_property_set(:reset_password_expiration_period, 0.1)
|
116
112
|
user.generate_reset_password_token!
|
117
|
-
Timecop.travel(Time.now.in_time_zone+0.5)
|
113
|
+
Timecop.travel(Time.now.in_time_zone + 0.5)
|
118
114
|
|
119
|
-
expect(User.load_from_reset_password_token
|
115
|
+
expect(User.load_from_reset_password_token(user.reset_password_token)).to be_nil
|
120
116
|
end
|
121
117
|
|
122
|
-
it
|
118
|
+
it 'load_from_reset_password_token is always valid if expiration period is nil' do
|
123
119
|
sorcery_model_property_set(:reset_password_expiration_period, nil)
|
124
120
|
user.generate_reset_password_token!
|
125
|
-
updated_user
|
121
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
126
122
|
|
127
|
-
expect(User.load_from_reset_password_token
|
123
|
+
expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user
|
128
124
|
end
|
129
125
|
|
130
|
-
it
|
131
|
-
expect(User.load_from_reset_password_token
|
132
|
-
expect(User.load_from_reset_password_token
|
126
|
+
it 'load_from_reset_password_token returns nil if token is blank' do
|
127
|
+
expect(User.load_from_reset_password_token(nil)).to be_nil
|
128
|
+
expect(User.load_from_reset_password_token('')).to be_nil
|
133
129
|
end
|
134
130
|
|
135
131
|
it "'deliver_reset_password_instructions!' generates a reset_password_token" do
|
@@ -140,7 +136,11 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
140
136
|
expect(user.reset_password_token).not_to be_nil
|
141
137
|
end
|
142
138
|
|
143
|
-
it "
|
139
|
+
it "'deliver_reset_password_instructions! returns a Mail::Message object" do
|
140
|
+
expect(user.deliver_reset_password_instructions!).to be_an_instance_of Mail::Message
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'the reset_password_token is random' do
|
144
144
|
sorcery_model_property_set(:reset_password_time_between_emails, 0)
|
145
145
|
user.deliver_reset_password_instructions!
|
146
146
|
old_password_code = user.reset_password_token
|
@@ -149,21 +149,21 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
149
149
|
expect(user.reset_password_token).not_to eq old_password_code
|
150
150
|
end
|
151
151
|
|
152
|
-
context
|
153
|
-
it
|
152
|
+
context 'mailer is enabled' do
|
153
|
+
it 'sends an email on reset' do
|
154
154
|
old_size = ActionMailer::Base.deliveries.size
|
155
155
|
user.deliver_reset_password_instructions!
|
156
156
|
|
157
157
|
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
158
158
|
end
|
159
159
|
|
160
|
-
it
|
160
|
+
it 'calls send_reset_password_email! on reset' do
|
161
161
|
expect(user).to receive(:send_reset_password_email!).once
|
162
162
|
|
163
163
|
user.deliver_reset_password_instructions!
|
164
164
|
end
|
165
165
|
|
166
|
-
it
|
166
|
+
it 'does not send an email if time between emails has not passed since last email' do
|
167
167
|
sorcery_model_property_set(:reset_password_time_between_emails, 10000)
|
168
168
|
old_size = ActionMailer::Base.deliveries.size
|
169
169
|
user.deliver_reset_password_instructions!
|
@@ -175,40 +175,39 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
175
175
|
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
176
176
|
end
|
177
177
|
|
178
|
-
it
|
178
|
+
it 'sends an email if time between emails has passed since last email' do
|
179
179
|
sorcery_model_property_set(:reset_password_time_between_emails, 0.5)
|
180
180
|
old_size = ActionMailer::Base.deliveries.size
|
181
181
|
user.deliver_reset_password_instructions!
|
182
182
|
|
183
183
|
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
184
184
|
|
185
|
-
Timecop.travel(Time.now.in_time_zone+0.5)
|
185
|
+
Timecop.travel(Time.now.in_time_zone + 0.5)
|
186
186
|
user.deliver_reset_password_instructions!
|
187
187
|
|
188
188
|
expect(ActionMailer::Base.deliveries.size).to eq old_size + 2
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
context
|
193
|
-
|
192
|
+
context 'mailer is disabled' do
|
194
193
|
before(:all) do
|
195
|
-
sorcery_reload!([:reset_password], :
|
194
|
+
sorcery_reload!([:reset_password], reset_password_mailer_disabled: true, reset_password_mailer: ::SorceryMailer)
|
196
195
|
end
|
197
196
|
|
198
|
-
it
|
197
|
+
it 'sends an email on reset' do
|
199
198
|
old_size = ActionMailer::Base.deliveries.size
|
200
199
|
user.deliver_reset_password_instructions!
|
201
200
|
|
202
201
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
203
202
|
end
|
204
203
|
|
205
|
-
it
|
204
|
+
it 'does not call send_reset_password_email! on reset' do
|
206
205
|
expect(user).to receive(:send_reset_password_email!).never
|
207
206
|
|
208
207
|
user.deliver_reset_password_instructions!
|
209
208
|
end
|
210
209
|
|
211
|
-
it
|
210
|
+
it 'does not send an email if time between emails has not passed since last email' do
|
212
211
|
sorcery_model_property_set(:reset_password_time_between_emails, 10000)
|
213
212
|
old_size = ActionMailer::Base.deliveries.size
|
214
213
|
user.deliver_reset_password_instructions!
|
@@ -220,44 +219,43 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
220
219
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
221
220
|
end
|
222
221
|
|
223
|
-
it
|
222
|
+
it 'sends an email if time between emails has passed since last email' do
|
224
223
|
sorcery_model_property_set(:reset_password_time_between_emails, 0.5)
|
225
224
|
old_size = ActionMailer::Base.deliveries.size
|
226
225
|
user.deliver_reset_password_instructions!
|
227
226
|
|
228
227
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
229
228
|
|
230
|
-
Timecop.travel(Time.now.in_time_zone+0.5)
|
229
|
+
Timecop.travel(Time.now.in_time_zone + 0.5)
|
231
230
|
user.deliver_reset_password_instructions!
|
232
231
|
|
233
232
|
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
234
233
|
end
|
235
234
|
end
|
236
235
|
|
237
|
-
it
|
236
|
+
it 'when change_password! is called, deletes reset_password_token' do
|
238
237
|
user.deliver_reset_password_instructions!
|
239
238
|
|
240
239
|
expect(user.reset_password_token).not_to be_nil
|
241
240
|
|
242
|
-
user.change_password!(
|
241
|
+
user.change_password!('blabulsdf')
|
243
242
|
user.save!
|
244
243
|
|
245
244
|
expect(user.reset_password_token).to be_nil
|
246
245
|
end
|
247
246
|
|
248
|
-
it
|
247
|
+
it 'returns false if time between emails has not passed since last email' do
|
249
248
|
sorcery_model_property_set(:reset_password_time_between_emails, 10000)
|
250
249
|
user.deliver_reset_password_instructions!
|
251
250
|
|
252
251
|
expect(user.deliver_reset_password_instructions!).to be false
|
253
252
|
end
|
254
253
|
|
255
|
-
it
|
254
|
+
it 'encrypts properly on reset' do
|
256
255
|
user.deliver_reset_password_instructions!
|
257
|
-
user.change_password!(
|
256
|
+
user.change_password!('blagu')
|
258
257
|
|
259
|
-
expect(Sorcery::CryptoProviders::BCrypt.matches?
|
258
|
+
expect(Sorcery::CryptoProviders::BCrypt.matches?(user.crypted_password, 'blagu', user.salt)).to be true
|
260
259
|
end
|
261
|
-
|
262
260
|
end
|
263
261
|
end
|