sorcery 0.8.6 → 0.9.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/.gitignore +2 -1
- data/.travis.yml +75 -14
- data/CHANGELOG.md +23 -1
- data/Gemfile +1 -0
- data/README.md +137 -86
- data/gemfiles/active_record-rails40.gemfile +7 -0
- data/gemfiles/active_record-rails41.gemfile +3 -2
- data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
- data/gemfiles/mongo_mapper-rails41.gemfile +2 -1
- data/gemfiles/mongoid-rails40.gemfile +9 -0
- data/gemfiles/mongoid-rails41.gemfile +3 -5
- data/gemfiles/mongoid3-rails32.gemfile +9 -0
- data/lib/generators/sorcery/USAGE +1 -1
- data/lib/generators/sorcery/install_generator.rb +19 -5
- data/lib/generators/sorcery/templates/initializer.rb +34 -9
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +3 -1
- data/lib/generators/sorcery/templates/migration/core.rb +2 -2
- data/lib/generators/sorcery/templates/migration/external.rb +3 -1
- data/lib/sorcery.rb +75 -43
- data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
- data/lib/sorcery/adapters/base_adapter.rb +30 -0
- data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
- data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
- data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
- data/lib/sorcery/controller.rb +5 -64
- data/lib/sorcery/controller/config.rb +65 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
- data/lib/sorcery/controller/submodules/external.rb +8 -28
- data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
- data/lib/sorcery/model.rb +43 -175
- data/lib/sorcery/model/config.rb +96 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +29 -36
- data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -37
- data/lib/sorcery/model/submodules/external.rb +53 -9
- data/lib/sorcery/model/submodules/remember_me.rb +12 -31
- data/lib/sorcery/model/submodules/reset_password.rb +21 -39
- data/lib/sorcery/model/submodules/user_activation.rb +21 -63
- data/lib/sorcery/model/temporary_token.rb +4 -4
- data/lib/sorcery/providers/base.rb +11 -0
- data/lib/sorcery/providers/facebook.rb +1 -1
- data/lib/sorcery/providers/github.rb +1 -1
- data/lib/sorcery/providers/google.rb +1 -1
- data/lib/sorcery/providers/heroku.rb +57 -0
- data/lib/sorcery/providers/jira.rb +77 -0
- data/lib/sorcery/providers/linkedin.rb +1 -1
- data/lib/sorcery/providers/liveid.rb +1 -1
- data/lib/sorcery/providers/salesforce.rb +50 -0
- data/lib/sorcery/providers/twitter.rb +1 -1
- data/lib/sorcery/providers/vk.rb +6 -4
- data/lib/sorcery/providers/xing.rb +1 -1
- data/lib/sorcery/test_helpers/internal.rb +7 -3
- data/lib/sorcery/test_helpers/rails/controller.rb +5 -1
- data/lib/sorcery/version.rb +3 -0
- data/sorcery.gemspec +6 -2
- data/spec/active_record/user_activity_logging_spec.rb +9 -0
- data/spec/controllers/controller_activity_logging_spec.rb +124 -0
- data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
- data/spec/{active_record → controllers}/controller_http_basic_auth_spec.rb +14 -11
- data/spec/{active_record → controllers}/controller_oauth2_spec.rb +128 -56
- data/spec/{active_record → controllers}/controller_oauth_spec.rb +94 -70
- data/spec/{active_record → controllers}/controller_remember_me_spec.rb +32 -12
- data/spec/{active_record → controllers}/controller_session_timeout_spec.rb +15 -5
- data/spec/{shared_examples/controller_shared_examples.rb → controllers/controller_spec.rb} +34 -19
- data/spec/{datamapper → data_mapper}/user_activation_spec.rb +1 -1
- data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
- data/spec/{datamapper → data_mapper}/user_brute_force_protection_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_oauth_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_remember_me_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_reset_password_spec.rb +1 -1
- data/spec/{datamapper → data_mapper}/user_spec.rb +1 -1
- data/spec/mongoid/user_spec.rb +13 -0
- data/spec/orm/active_record.rb +12 -0
- data/spec/orm/{datamapper.rb → data_mapper.rb} +16 -2
- data/spec/orm/mongo_mapper.rb +0 -1
- data/spec/orm/mongoid.rb +4 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +62 -1
- data/spec/rails_app/app/{datamapper → data_mapper}/authentication.rb +0 -0
- data/spec/rails_app/app/{datamapper → data_mapper}/user.rb +0 -0
- data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
- data/spec/rails_app/config/routes.rb +9 -0
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
- data/spec/shared_examples/user_activation_shared_examples.rb +7 -7
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +73 -5
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +127 -9
- data/spec/shared_examples/user_oauth_shared_examples.rb +3 -6
- data/spec/shared_examples/user_remember_me_shared_examples.rb +6 -3
- data/spec/shared_examples/user_reset_password_shared_examples.rb +10 -10
- data/spec/shared_examples/user_shared_examples.rb +117 -30
- data/spec/spec_helper.rb +7 -22
- metadata +36 -58
- data/Gemfile.rails4 +0 -22
- data/VERSION +0 -1
- data/lib/sorcery/model/adapters/active_record.rb +0 -54
- data/lib/sorcery/model/adapters/datamapper.rb +0 -123
- data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -60
- data/lib/sorcery/model/adapters/mongoid.rb +0 -88
- data/lib/sorcery/test_helpers/rails.rb +0 -7
- data/spec/active_record/controller_activity_logging_spec.rb +0 -29
- data/spec/active_record/controller_brute_force_protection_spec.rb +0 -158
- data/spec/active_record/controller_spec.rb +0 -8
- data/spec/active_record/integration_spec.rb +0 -23
- data/spec/datamapper/controller_activity_logging_spec.rb +0 -17
- data/spec/datamapper/controller_spec.rb +0 -8
- data/spec/datamapper/user_activity_logging_spec.rb +0 -9
- data/spec/mongo_mapper/controller_spec.rb +0 -8
- data/spec/mongoid/controller_activity_logging_spec.rb +0 -16
- data/spec/mongoid/controller_spec.rb +0 -8
- data/spec/rails_app/public/404.html +0 -26
- data/spec/rails_app/public/422.html +0 -26
- data/spec/rails_app/public/500.html +0 -26
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/javascripts/application.js +0 -2
- data/spec/rails_app/public/javascripts/controls.js +0 -965
- data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
- data/spec/rails_app/public/javascripts/effects.js +0 -1123
- data/spec/rails_app/public/javascripts/prototype.js +0 -6001
- data/spec/rails_app/public/javascripts/rails.js +0 -175
- data/spec/rails_app/public/robots.txt +0 -5
- data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
- data/spec/shared_examples/controller_activity_logging_shared_examples.rb +0 -125
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -52
- data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -62
@@ -1,38 +1,156 @@
|
|
1
1
|
shared_examples_for "rails_3_brute_force_protection_model" do
|
2
|
+
let(:user) { create_new_user }
|
3
|
+
before(:each) do
|
4
|
+
User.sorcery_adapter.delete_all
|
5
|
+
end
|
6
|
+
|
7
|
+
|
2
8
|
context "loaded plugin configuration" do
|
3
9
|
|
4
10
|
let(:config) { User.sorcery_config }
|
5
|
-
|
6
|
-
|
11
|
+
|
7
12
|
before(:all) do
|
8
13
|
sorcery_reload!([:brute_force_protection])
|
9
14
|
end
|
10
|
-
|
15
|
+
|
11
16
|
after(:each) do
|
12
17
|
User.sorcery_config.reset!
|
13
18
|
end
|
14
|
-
|
19
|
+
|
15
20
|
specify { expect(user).to respond_to(:failed_logins_count) }
|
16
21
|
specify { expect(user).to respond_to(:lock_expires_at) }
|
17
|
-
|
22
|
+
|
18
23
|
it "enables configuration option 'failed_logins_count_attribute_name'" do
|
19
24
|
sorcery_model_property_set(:failed_logins_count_attribute_name, :my_count)
|
20
25
|
expect(config.failed_logins_count_attribute_name).to eq :my_count
|
21
26
|
end
|
22
|
-
|
27
|
+
|
23
28
|
it "enables configuration option 'lock_expires_at_attribute_name'" do
|
24
29
|
sorcery_model_property_set(:lock_expires_at_attribute_name, :expires)
|
25
30
|
expect(config.lock_expires_at_attribute_name).to eq :expires
|
26
31
|
end
|
27
|
-
|
32
|
+
|
28
33
|
it "enables configuration option 'consecutive_login_retries_amount_allowed'" do
|
29
34
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 34)
|
30
35
|
expect(config.consecutive_login_retries_amount_limit).to eq 34
|
31
36
|
end
|
32
|
-
|
37
|
+
|
33
38
|
it "enables configuration option 'login_lock_time_period'" do
|
34
39
|
sorcery_model_property_set(:login_lock_time_period, 2.hours)
|
35
40
|
expect(config.login_lock_time_period).to eq 2.hours
|
36
41
|
end
|
42
|
+
|
43
|
+
describe "#locked?" do
|
44
|
+
it "is locked" do
|
45
|
+
user.send("#{config.lock_expires_at_attribute_name}=", Time.now + 5.days)
|
46
|
+
expect(user).to be_locked
|
47
|
+
end
|
48
|
+
|
49
|
+
it "isn't locked" do
|
50
|
+
user.send("#{config.lock_expires_at_attribute_name}=", nil)
|
51
|
+
expect(user).not_to be_locked
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#register_failed_login!" do
|
57
|
+
it "locks user when number of retries reached the limit" do
|
58
|
+
expect(user.lock_expires_at).to be_nil
|
59
|
+
|
60
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
|
61
|
+
user.register_failed_login!
|
62
|
+
lock_expires_at = User.sorcery_adapter.find_by_id(user.id).lock_expires_at
|
63
|
+
|
64
|
+
expect(lock_expires_at).not_to be_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
context "unlock_token_mailer_disabled is true" do
|
68
|
+
it "does not automatically send unlock email" do
|
69
|
+
sorcery_model_property_set(:unlock_token_mailer_disabled, true)
|
70
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
71
|
+
sorcery_model_property_set(:login_lock_time_period, 0)
|
72
|
+
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
73
|
+
|
74
|
+
3.times { user.register_failed_login! }
|
75
|
+
|
76
|
+
expect(ActionMailer::Base.deliveries.size).to eq 0
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "unlock_token_mailer_disabled is false" do
|
82
|
+
before do
|
83
|
+
sorcery_model_property_set(:unlock_token_mailer_disabled, false)
|
84
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
85
|
+
sorcery_model_property_set(:login_lock_time_period, 0)
|
86
|
+
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "does not automatically send unlock email" do
|
90
|
+
3.times { user.register_failed_login! }
|
91
|
+
|
92
|
+
expect(ActionMailer::Base.deliveries.size).to eq 1
|
93
|
+
end
|
94
|
+
|
95
|
+
it "generates unlock token before mail is sent" do
|
96
|
+
3.times { user.register_failed_login! }
|
97
|
+
|
98
|
+
expect(ActionMailer::Base.deliveries.last.body.to_s.match(user.unlock_token)).not_to be_nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context ".authenticate" do
|
104
|
+
|
105
|
+
it "unlocks after lock time period passes" do
|
106
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
107
|
+
sorcery_model_property_set(:login_lock_time_period, 0.2)
|
108
|
+
2.times { user.register_failed_login! }
|
109
|
+
|
110
|
+
lock_expires_at = User.sorcery_adapter.find_by_id(user.id).lock_expires_at
|
111
|
+
expect(lock_expires_at).not_to be_nil
|
112
|
+
|
113
|
+
Timecop.travel(Time.now.in_time_zone + 0.3)
|
114
|
+
User.authenticate('bla@bla.com', 'secret')
|
115
|
+
|
116
|
+
lock_expires_at = User.sorcery_adapter.find_by_id(user.id).lock_expires_at
|
117
|
+
expect(lock_expires_at).to be_nil
|
118
|
+
Timecop.return
|
119
|
+
end
|
120
|
+
|
121
|
+
it "doest not unlock if time period is 0 (permanent lock)" do
|
122
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
123
|
+
sorcery_model_property_set(:login_lock_time_period, 0)
|
124
|
+
|
125
|
+
2.times { user.register_failed_login! }
|
126
|
+
|
127
|
+
unlock_date = user.lock_expires_at
|
128
|
+
Timecop.travel(Time.now.in_time_zone + 1)
|
129
|
+
|
130
|
+
user.register_failed_login!
|
131
|
+
|
132
|
+
expect(user.lock_expires_at.to_s).to eq unlock_date.to_s
|
133
|
+
Timecop.return
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#unlock!" do
|
139
|
+
it "unlocks after entering unlock token" do
|
140
|
+
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
141
|
+
sorcery_model_property_set(:login_lock_time_period, 0)
|
142
|
+
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
143
|
+
3.times { user.register_failed_login! }
|
144
|
+
|
145
|
+
expect(user.unlock_token).not_to be_nil
|
146
|
+
|
147
|
+
token = user.unlock_token
|
148
|
+
user = User.load_from_unlock_token(token)
|
149
|
+
|
150
|
+
expect(user).not_to be_nil
|
151
|
+
|
152
|
+
user.unlock!
|
153
|
+
expect(User.load_from_unlock_token(user.unlock_token)).to be_nil
|
154
|
+
end
|
37
155
|
end
|
38
|
-
end
|
156
|
+
end
|
@@ -6,12 +6,9 @@ shared_examples_for "rails_3_oauth_model" do
|
|
6
6
|
describe "loaded plugin configuration" do
|
7
7
|
|
8
8
|
before(:all) do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Authentication.delete_all
|
13
|
-
end
|
14
|
-
User.delete_all
|
9
|
+
Authentication.sorcery_adapter.delete_all
|
10
|
+
User.sorcery_adapter.delete_all
|
11
|
+
|
15
12
|
sorcery_reload!([:external])
|
16
13
|
sorcery_controller_property_set(:external_providers, [:twitter])
|
17
14
|
sorcery_model_property_set(:authentications_class, Authentication)
|
@@ -35,12 +35,15 @@ shared_examples_for "rails_3_remember_me_model" do
|
|
35
35
|
expect(user.remember_me_token).not_to be_nil
|
36
36
|
end
|
37
37
|
|
38
|
-
# FIXME: assert on line 37 sometimes fails by a second
|
39
38
|
it "sets an expiration based on 'remember_me_for' attribute" do
|
40
39
|
sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24)
|
41
|
-
user.remember_me!
|
42
40
|
|
43
|
-
|
41
|
+
ts = Time.now.in_time_zone
|
42
|
+
Timecop.freeze(ts) do
|
43
|
+
user.remember_me!
|
44
|
+
end
|
45
|
+
|
46
|
+
expect(user.remember_me_token_expires_at.utc.to_s).to eq (ts + 2 * 60 * 60 * 24).utc.to_s
|
44
47
|
end
|
45
48
|
|
46
49
|
it "deletes the token and expiration on 'forget_me!'" do
|
@@ -82,7 +82,7 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
before(:each) do
|
85
|
-
User.delete_all
|
85
|
+
User.sorcery_adapter.delete_all
|
86
86
|
user
|
87
87
|
end
|
88
88
|
|
@@ -91,29 +91,29 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "load_from_reset_password_token returns user when token is found" do
|
94
|
-
user.
|
95
|
-
updated_user =
|
94
|
+
user.generate_reset_password_token!
|
95
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
96
96
|
|
97
97
|
expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user
|
98
98
|
end
|
99
99
|
|
100
100
|
it "load_from_reset_password_token does NOT return user when token is NOT found" do
|
101
|
-
user.
|
101
|
+
user.generate_reset_password_token!
|
102
102
|
|
103
103
|
expect(User.load_from_reset_password_token "a").to be_nil
|
104
104
|
end
|
105
105
|
|
106
106
|
it "load_from_reset_password_token returns user when token is found and not expired" do
|
107
107
|
sorcery_model_property_set(:reset_password_expiration_period, 500)
|
108
|
-
user.
|
109
|
-
updated_user =
|
108
|
+
user.generate_reset_password_token!
|
109
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
110
110
|
|
111
111
|
expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user
|
112
112
|
end
|
113
113
|
|
114
114
|
it "load_from_reset_password_token does NOT return user when token is found and expired" do
|
115
115
|
sorcery_model_property_set(:reset_password_expiration_period, 0.1)
|
116
|
-
user.
|
116
|
+
user.generate_reset_password_token!
|
117
117
|
Timecop.travel(Time.now.in_time_zone+0.5)
|
118
118
|
|
119
119
|
expect(User.load_from_reset_password_token user.reset_password_token).to be_nil
|
@@ -121,8 +121,8 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
121
121
|
|
122
122
|
it "load_from_reset_password_token is always valid if expiration period is nil" do
|
123
123
|
sorcery_model_property_set(:reset_password_expiration_period, nil)
|
124
|
-
user.
|
125
|
-
updated_user =
|
124
|
+
user.generate_reset_password_token!
|
125
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
126
126
|
|
127
127
|
expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user
|
128
128
|
end
|
@@ -156,7 +156,7 @@ shared_examples_for "rails_3_reset_password_model" do
|
|
156
156
|
|
157
157
|
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
it "calls send_reset_password_email! on reset" do
|
161
161
|
expect(user).to receive(:send_reset_password_email!).once
|
162
162
|
|
@@ -69,12 +69,16 @@ shared_examples_for "rails_3_core_model" do
|
|
69
69
|
|
70
70
|
expect(User.sorcery_config.stretches).to eq stretches
|
71
71
|
end
|
72
|
+
|
73
|
+
it 'respond to username=' do
|
74
|
+
expect(User.new).to respond_to(:username=)
|
75
|
+
end
|
72
76
|
end
|
73
77
|
|
74
78
|
describe "when activated with sorcery" do
|
75
79
|
before(:all) { sorcery_reload! }
|
76
|
-
before(:each) { User.delete_all }
|
77
|
-
|
80
|
+
before(:each) { User.sorcery_adapter.delete_all }
|
81
|
+
|
78
82
|
it "does not add authenticate method to base class", active_record: true do
|
79
83
|
expect(ActiveRecord::Base).not_to respond_to(:authenticate) if defined?(ActiveRecord)
|
80
84
|
end
|
@@ -131,7 +135,7 @@ shared_examples_for "rails_3_core_model" do
|
|
131
135
|
describe "registration" do
|
132
136
|
|
133
137
|
before(:all) { sorcery_reload! }
|
134
|
-
before(:each) { User.delete_all }
|
138
|
+
before(:each) { User.sorcery_adapter.delete_all }
|
135
139
|
|
136
140
|
it "by default, encryption_provider is not nil" do
|
137
141
|
expect(User.sorcery_config.encryption_provider).not_to be_nil
|
@@ -161,13 +165,10 @@ shared_examples_for "rails_3_core_model" do
|
|
161
165
|
user.password = '4blupush'
|
162
166
|
user.username = nil
|
163
167
|
|
164
|
-
|
168
|
+
expect(user).to receive(:save) { raise RuntimeError }
|
169
|
+
|
165
170
|
begin
|
166
|
-
|
167
|
-
user.save
|
168
|
-
else
|
169
|
-
user.save! # triggers validation exception since username field is required.
|
170
|
-
end
|
171
|
+
user.save
|
171
172
|
rescue
|
172
173
|
end
|
173
174
|
|
@@ -176,32 +177,21 @@ shared_examples_for "rails_3_core_model" do
|
|
176
177
|
|
177
178
|
it "does not encrypt the password twice when a user is updated" do
|
178
179
|
user.email = "blup@bla.com"
|
179
|
-
|
180
|
-
user.save
|
181
|
-
else
|
182
|
-
user.save!
|
183
|
-
end
|
180
|
+
user.save
|
184
181
|
|
185
182
|
expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be true
|
186
183
|
end
|
187
184
|
|
188
185
|
it "replaces the crypted_password in case a new password is set" do
|
189
186
|
user.password = 'new_secret'
|
190
|
-
|
191
|
-
user.save
|
192
|
-
else
|
193
|
-
user.save!
|
194
|
-
end
|
187
|
+
user.save
|
195
188
|
|
196
189
|
expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be false
|
197
190
|
end
|
198
191
|
|
199
192
|
describe "when user has password_confirmation_defined" do
|
200
193
|
before(:all) do
|
201
|
-
|
202
|
-
if defined?(DataMapper)
|
203
|
-
DataMapper.finalize
|
204
|
-
end
|
194
|
+
update_model { attr_accessor :password_confirmation }
|
205
195
|
end
|
206
196
|
|
207
197
|
after(:all) do
|
@@ -227,6 +217,21 @@ shared_examples_for "rails_3_core_model" do
|
|
227
217
|
end
|
228
218
|
end
|
229
219
|
|
220
|
+
describe "password validation" do
|
221
|
+
|
222
|
+
let(:user_with_pass) { create_new_user({:username => 'foo_bar', :email => "foo@bar.com", :password => 'foobar'})}
|
223
|
+
|
224
|
+
specify { expect(user_with_pass).to respond_to :valid_password? }
|
225
|
+
|
226
|
+
it "returns true if password is correct" do
|
227
|
+
expect(user_with_pass.valid_password?("foobar")).to be true
|
228
|
+
end
|
229
|
+
|
230
|
+
it "returns false if password is incorrect" do
|
231
|
+
expect(user_with_pass.valid_password?("foobug")).to be false
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
230
235
|
describe "special encryption cases" do
|
231
236
|
before(:all) do
|
232
237
|
sorcery_reload!()
|
@@ -234,7 +239,7 @@ shared_examples_for "rails_3_core_model" do
|
|
234
239
|
end
|
235
240
|
|
236
241
|
before(:each) do
|
237
|
-
User.delete_all
|
242
|
+
User.sorcery_adapter.delete_all
|
238
243
|
end
|
239
244
|
|
240
245
|
after(:each) do
|
@@ -344,13 +349,13 @@ shared_examples_for "rails_3_core_model" do
|
|
344
349
|
describe "ORM adapter" do
|
345
350
|
before(:all) do
|
346
351
|
sorcery_reload!()
|
347
|
-
User.delete_all
|
352
|
+
User.sorcery_adapter.delete_all
|
348
353
|
end
|
349
354
|
|
350
355
|
before(:each) { user }
|
351
356
|
|
352
357
|
after(:each) do
|
353
|
-
User.delete_all
|
358
|
+
User.sorcery_adapter.delete_all
|
354
359
|
User.sorcery_config.reset!
|
355
360
|
end
|
356
361
|
|
@@ -358,17 +363,17 @@ shared_examples_for "rails_3_core_model" do
|
|
358
363
|
it "find_by_username works as expected" do
|
359
364
|
sorcery_model_property_set(:username_attribute_names, [:username])
|
360
365
|
|
361
|
-
expect(User.find_by_username "gizmo").to eq user
|
366
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
362
367
|
end
|
363
368
|
|
364
369
|
it "find_by_username works as expected with multiple username attributes" do
|
365
370
|
sorcery_model_property_set(:username_attribute_names, [:username, :email])
|
366
371
|
|
367
|
-
expect(User.find_by_username "gizmo").to eq user
|
372
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
368
373
|
end
|
369
374
|
|
370
375
|
it "find_by_email works as expected" do
|
371
|
-
expect(User.find_by_email "bla@bla.com").to eq user
|
376
|
+
expect(User.sorcery_adapter.find_by_email "bla@bla.com").to eq user
|
372
377
|
end
|
373
378
|
end
|
374
379
|
end
|
@@ -378,7 +383,7 @@ shared_examples_for "external_user" do
|
|
378
383
|
let(:external_user) { create_new_external_user :twitter }
|
379
384
|
|
380
385
|
before(:each) do
|
381
|
-
User.delete_all
|
386
|
+
User.sorcery_adapter.delete_all
|
382
387
|
end
|
383
388
|
|
384
389
|
it "responds to 'external?'" do
|
@@ -392,4 +397,86 @@ shared_examples_for "external_user" do
|
|
392
397
|
it "external? is true for external users" do
|
393
398
|
expect(external_user.external?).to be true
|
394
399
|
end
|
400
|
+
|
401
|
+
describe ".create_from_provider" do
|
402
|
+
|
403
|
+
before(:all) do
|
404
|
+
if SORCERY_ORM == :active_record
|
405
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
|
406
|
+
User.reset_column_information
|
407
|
+
end
|
408
|
+
|
409
|
+
sorcery_reload!([:external])
|
410
|
+
end
|
411
|
+
|
412
|
+
after(:all) do
|
413
|
+
if SORCERY_ORM == :active_record
|
414
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
it 'supports nested attributes' do
|
419
|
+
sorcery_model_property_set(:authentications_class, Authentication)
|
420
|
+
|
421
|
+
expect { User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) }.to change { User.count }.by(1)
|
422
|
+
expect(User.first.username).to eq 'Noam Ben Ari'
|
423
|
+
end
|
424
|
+
|
425
|
+
context 'with block' do
|
426
|
+
it 'create user when block return true' do
|
427
|
+
expect {
|
428
|
+
User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { true }
|
429
|
+
}.to change { User.count }.by(1)
|
430
|
+
end
|
431
|
+
|
432
|
+
it 'does not create user when block return false' do
|
433
|
+
expect {
|
434
|
+
User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { false }
|
435
|
+
}.not_to change { User.count }
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
describe 'activation' do
|
442
|
+
before(:all) do
|
443
|
+
if SORCERY_ORM == :active_record
|
444
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
|
445
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
|
446
|
+
end
|
447
|
+
|
448
|
+
sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
|
449
|
+
end
|
450
|
+
|
451
|
+
after(:all) do
|
452
|
+
if SORCERY_ORM == :active_record
|
453
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
454
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
after(:each) do
|
459
|
+
User.sorcery_adapter.delete_all
|
460
|
+
end
|
461
|
+
|
462
|
+
[:facebook, :github, :google, :liveid].each do |provider|
|
463
|
+
|
464
|
+
it "does not send activation email to external users" do
|
465
|
+
old_size = ActionMailer::Base.deliveries.size
|
466
|
+
create_new_external_user(provider)
|
467
|
+
|
468
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
469
|
+
end
|
470
|
+
|
471
|
+
it "does not send external users an activation success email" do
|
472
|
+
sorcery_model_property_set(:activation_success_email_method_name, nil)
|
473
|
+
create_new_external_user(provider)
|
474
|
+
old_size = ActionMailer::Base.deliveries.size
|
475
|
+
@user.activate!
|
476
|
+
|
477
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
end
|
395
482
|
end
|