sorcery 0.5.21 → 0.5.30

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.

Files changed (54) hide show
  1. data/README.rdoc +1 -1
  2. data/VERSION +1 -1
  3. data/lib/sorcery/controller.rb +5 -3
  4. data/lib/sorcery/controller/submodules/activity_logging.rb +10 -6
  5. data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -3
  6. data/lib/sorcery/controller/submodules/http_basic_auth.rb +10 -5
  7. data/lib/sorcery/controller/submodules/remember_me.rb +13 -4
  8. data/lib/sorcery/controller/submodules/session_timeout.rb +3 -1
  9. data/lib/sorcery/crypto_providers/aes256.rb +8 -5
  10. data/lib/sorcery/crypto_providers/bcrypt.rb +12 -6
  11. data/lib/sorcery/crypto_providers/sha256.rb +2 -1
  12. data/lib/sorcery/crypto_providers/sha512.rb +2 -1
  13. data/lib/sorcery/initializers/initializer.rb +125 -36
  14. data/lib/sorcery/model.rb +28 -15
  15. data/lib/sorcery/model/adapters/active_record.rb +2 -2
  16. data/lib/sorcery/model/adapters/mongoid.rb +2 -2
  17. data/lib/sorcery/model/submodules/activity_logging.rb +7 -6
  18. data/lib/sorcery/model/submodules/brute_force_protection.rb +10 -6
  19. data/lib/sorcery/model/submodules/external.rb +4 -2
  20. data/lib/sorcery/model/submodules/remember_me.rb +4 -3
  21. data/lib/sorcery/model/submodules/reset_password.rb +16 -8
  22. data/lib/sorcery/model/submodules/user_activation.rb +23 -10
  23. data/lib/sorcery/model/temporary_token.rb +3 -2
  24. data/lib/sorcery/test_helpers/internal.rb +2 -1
  25. data/lib/sorcery/test_helpers/internal/rails.rb +5 -1
  26. data/sorcery.gemspec +16 -2
  27. data/spec/Gemfile.lock +1 -1
  28. data/spec/rails3/Gemfile.lock +1 -1
  29. data/spec/rails3/spec/user_activation_spec.rb +2 -168
  30. data/spec/rails3/spec/user_activity_logging_spec.rb +2 -30
  31. data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -35
  32. data/spec/rails3/spec/user_oauth_spec.rb +2 -26
  33. data/spec/rails3/spec/user_remember_me_spec.rb +2 -45
  34. data/spec/rails3/spec/user_reset_password_spec.rb +3 -168
  35. data/spec/rails3/spec/user_spec.rb +3 -283
  36. data/spec/rails3_mongoid/Gemfile.lock +1 -1
  37. data/spec/rails3_mongoid/app/models/authentication.rb +3 -3
  38. data/spec/rails3_mongoid/spec/user_activation_spec.rb +2 -171
  39. data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +2 -25
  40. data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +2 -35
  41. data/spec/rails3_mongoid/spec/user_oauth_spec.rb +2 -28
  42. data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +2 -45
  43. data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +2 -176
  44. data/spec/rails3_mongoid/spec/user_spec.rb +3 -285
  45. data/spec/shared_examples/user_activation_shared_examples.rb +173 -0
  46. data/spec/shared_examples/user_activity_logging_shared_examples.rb +27 -0
  47. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +37 -0
  48. data/spec/shared_examples/user_oauth_shared_examples.rb +30 -0
  49. data/spec/shared_examples/user_remember_me_shared_examples.rb +47 -0
  50. data/spec/shared_examples/user_reset_password_shared_examples.rb +177 -0
  51. data/spec/shared_examples/user_shared_examples.rb +292 -0
  52. data/spec/sinatra/Gemfile.lock +1 -1
  53. data/spec/sinatra_modular/Gemfile.lock +1 -1
  54. metadata +16 -2
@@ -0,0 +1,27 @@
1
+ shared_examples_for "rails_3_activity_logging_model" do
2
+ # ----------------- PLUGIN CONFIGURATION -----------------------
3
+ describe User, "loaded plugin configuration" do
4
+ before(:all) do
5
+ sorcery_reload!([:activity_logging])
6
+ end
7
+
8
+ after(:each) do
9
+ User.sorcery_config.reset!
10
+ end
11
+
12
+ it "should allow configuration option 'last_login_at_attribute_name'" do
13
+ sorcery_model_property_set(:last_login_at_attribute_name, :login_time)
14
+ User.sorcery_config.last_login_at_attribute_name.should equal(:login_time)
15
+ end
16
+
17
+ it "should allow configuration option 'last_logout_at_attribute_name'" do
18
+ sorcery_model_property_set(:last_logout_at_attribute_name, :logout_time)
19
+ User.sorcery_config.last_logout_at_attribute_name.should equal(:logout_time)
20
+ end
21
+
22
+ it "should allow configuration option 'last_activity_at_attribute_name'" do
23
+ sorcery_model_property_set(:last_activity_at_attribute_name, :activity_time)
24
+ User.sorcery_config.last_activity_at_attribute_name.should equal(:activity_time)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ shared_examples_for "rails_3_brute_force_protection_model" do
2
+ # ----------------- PLUGIN CONFIGURATION -----------------------
3
+ describe User, "loaded plugin configuration" do
4
+
5
+ before(:all) do
6
+ sorcery_reload!([:brute_force_protection])
7
+ create_new_user
8
+ end
9
+
10
+ after(:each) do
11
+ User.sorcery_config.reset!
12
+ end
13
+
14
+ specify { @user.should respond_to(:failed_logins_count) }
15
+ specify { @user.should respond_to(:lock_expires_at) }
16
+
17
+ it "should enable configuration option 'failed_logins_count_attribute_name'" do
18
+ sorcery_model_property_set(:failed_logins_count_attribute_name, :my_count)
19
+ User.sorcery_config.failed_logins_count_attribute_name.should equal(:my_count)
20
+ end
21
+
22
+ it "should enable configuration option 'lock_expires_at_attribute_name'" do
23
+ sorcery_model_property_set(:lock_expires_at_attribute_name, :expires)
24
+ User.sorcery_config.lock_expires_at_attribute_name.should equal(:expires)
25
+ end
26
+
27
+ it "should enable configuration option 'consecutive_login_retries_amount_allowed'" do
28
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 34)
29
+ User.sorcery_config.consecutive_login_retries_amount_limit.should equal(34)
30
+ end
31
+
32
+ it "should enable configuration option 'login_lock_time_period'" do
33
+ sorcery_model_property_set(:login_lock_time_period, 2.hours)
34
+ User.sorcery_config.login_lock_time_period.should == 2.hours
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ shared_examples_for "rails_3_oauth_model" do
2
+ # ----------------- PLUGIN CONFIGURATION -----------------------
3
+ describe User, "loaded plugin configuration" do
4
+
5
+ before(:all) do
6
+ User.delete_all
7
+ Authentication.delete_all
8
+ sorcery_reload!([:external])
9
+ sorcery_controller_property_set(:external_providers, [:twitter])
10
+ sorcery_model_property_set(:authentications_class, Authentication)
11
+ sorcery_controller_external_property_set(:twitter, :key, "eYVNBjBDi33aa9GkA3w")
12
+ sorcery_controller_external_property_set(:twitter, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
13
+ sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com")
14
+ create_new_external_user(:twitter)
15
+ end
16
+
17
+ it "should respond to 'load_from_provider'" do
18
+ User.should respond_to(:load_from_provider)
19
+ end
20
+
21
+ it "'load_from_provider' should load user if exists" do
22
+ User.load_from_provider(:twitter,123).should == @user
23
+ end
24
+
25
+ it "'load_from_provider' should return nil if user doesn't exist" do
26
+ User.load_from_provider(:twitter,980342).should be_nil
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ shared_examples_for "rails_3_remember_me_model" do
2
+ # ----------------- PLUGIN CONFIGURATION -----------------------
3
+ describe User, "loaded plugin configuration" do
4
+ before(:all) do
5
+ sorcery_reload!([:remember_me])
6
+ create_new_user
7
+ end
8
+
9
+ after(:each) do
10
+ User.sorcery_config.reset!
11
+ end
12
+
13
+ it "should allow configuration option 'remember_me_token_attribute_name'" do
14
+ sorcery_model_property_set(:remember_me_token_attribute_name, :my_token)
15
+ User.sorcery_config.remember_me_token_attribute_name.should equal(:my_token)
16
+ end
17
+
18
+ it "should allow configuration option 'remember_me_token_expires_at_attribute_name'" do
19
+ sorcery_model_property_set(:remember_me_token_expires_at_attribute_name, :my_expires)
20
+ User.sorcery_config.remember_me_token_expires_at_attribute_name.should equal(:my_expires)
21
+ end
22
+
23
+ specify { @user.should respond_to(:remember_me!) }
24
+
25
+ specify { @user.should respond_to(:forget_me!) }
26
+
27
+ it "should generate a new token on 'remember_me!'" do
28
+ @user.remember_me_token.should be_nil
29
+ @user.remember_me!
30
+ @user.remember_me_token.should_not be_nil
31
+ end
32
+
33
+ it "should set an expiration based on 'remember_me_for' attribute" do
34
+ sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24)
35
+ @user.remember_me!
36
+ @user.remember_me_token_expires_at.utc.to_s.should == (Time.now + 2 * 60 * 60 * 24).utc.to_s
37
+ end
38
+
39
+ it "should delete the token and expiration on 'forget_me!'" do
40
+ @user.remember_me!
41
+ @user.remember_me_token.should_not be_nil
42
+ @user.forget_me!
43
+ @user.remember_me_token.should be_nil
44
+ @user.remember_me_token_expires_at.should be_nil
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,177 @@
1
+ shared_examples_for "rails_3_reset_password_model" do
2
+ # ----------------- PLUGIN CONFIGURATION -----------------------
3
+ describe User, "loaded plugin configuration" do
4
+
5
+ before(:all) do
6
+ sorcery_reload!([:reset_password], :reset_password_mailer => ::SorceryMailer)
7
+ end
8
+
9
+ after(:each) do
10
+ User.sorcery_config.reset!
11
+ end
12
+
13
+ context "API" do
14
+ before(:all) do
15
+ create_new_user
16
+ end
17
+
18
+ specify { @user.should respond_to(:deliver_reset_password_instructions!) }
19
+
20
+ specify { @user.should respond_to(:change_password!) }
21
+
22
+ it "should respond to .load_from_reset_password_token" do
23
+ User.should respond_to(:load_from_reset_password_token)
24
+ end
25
+ end
26
+
27
+ it "should allow configuration option 'reset_password_token_attribute_name'" do
28
+ sorcery_model_property_set(:reset_password_token_attribute_name, :my_code)
29
+ User.sorcery_config.reset_password_token_attribute_name.should equal(:my_code)
30
+ end
31
+
32
+ it "should allow configuration option 'reset_password_mailer'" do
33
+ sorcery_model_property_set(:reset_password_mailer, TestUser)
34
+ User.sorcery_config.reset_password_mailer.should equal(TestUser)
35
+ end
36
+
37
+ it "should allow configuration option 'reset_password_email_method_name'" do
38
+ sorcery_model_property_set(:reset_password_email_method_name, :my_mailer_method)
39
+ User.sorcery_config.reset_password_email_method_name.should equal(:my_mailer_method)
40
+ end
41
+
42
+ it "should allow configuration option 'reset_password_expiration_period'" do
43
+ sorcery_model_property_set(:reset_password_expiration_period, 16)
44
+ User.sorcery_config.reset_password_expiration_period.should equal(16)
45
+ end
46
+
47
+ it "should allow configuration option 'reset_password_email_sent_at_attribute_name'" do
48
+ sorcery_model_property_set(:reset_password_email_sent_at_attribute_name, :blabla)
49
+ User.sorcery_config.reset_password_email_sent_at_attribute_name.should equal(:blabla)
50
+ end
51
+
52
+ it "should allow configuration option 'reset_password_time_between_emails'" do
53
+ sorcery_model_property_set(:reset_password_time_between_emails, 16)
54
+ User.sorcery_config.reset_password_time_between_emails.should equal(16)
55
+ end
56
+ end
57
+
58
+ # ----------------- PLUGIN ACTIVATED -----------------------
59
+ describe User, "when activated with sorcery" do
60
+
61
+ before(:all) do
62
+ sorcery_reload!([:reset_password], :reset_password_mailer => ::SorceryMailer)
63
+ end
64
+
65
+ before(:each) do
66
+ User.delete_all
67
+ end
68
+
69
+ after(:each) do
70
+ Timecop.return
71
+ end
72
+
73
+ it "load_from_reset_password_token should return user when token is found" do
74
+ create_new_user
75
+ @user.deliver_reset_password_instructions!
76
+ User.load_from_reset_password_token(@user.reset_password_token).should == @user
77
+ end
78
+
79
+ it "load_from_reset_password_token should NOT return user when token is NOT found" do
80
+ create_new_user
81
+ @user.deliver_reset_password_instructions!
82
+ User.load_from_reset_password_token("a").should == nil
83
+ end
84
+
85
+ it "load_from_reset_password_token should return user when token is found and not expired" do
86
+ create_new_user
87
+ sorcery_model_property_set(:reset_password_expiration_period, 500)
88
+ @user.deliver_reset_password_instructions!
89
+ User.load_from_reset_password_token(@user.reset_password_token).should == @user
90
+ end
91
+
92
+ it "load_from_reset_password_token should NOT return user when token is found and expired" do
93
+ create_new_user
94
+ sorcery_model_property_set(:reset_password_expiration_period, 0.1)
95
+ @user.deliver_reset_password_instructions!
96
+ Timecop.travel(Time.now+0.5)
97
+ User.load_from_reset_password_token(@user.reset_password_token).should == nil
98
+ end
99
+
100
+ it "load_from_reset_password_token should always be valid if expiration period is nil" do
101
+ create_new_user
102
+ sorcery_model_property_set(:reset_password_expiration_period, nil)
103
+ @user.deliver_reset_password_instructions!
104
+ User.load_from_reset_password_token(@user.reset_password_token).should == @user
105
+ end
106
+
107
+ it "load_from_reset_password_token should return nil if token is blank" do
108
+ User.load_from_reset_password_token(nil).should == nil
109
+ User.load_from_reset_password_token("").should == nil
110
+ end
111
+
112
+ it "'deliver_reset_password_instructions!' should generate a reset_password_token" do
113
+ create_new_user
114
+ @user.reset_password_token.should be_nil
115
+ @user.deliver_reset_password_instructions!
116
+ @user.reset_password_token.should_not be_nil
117
+ end
118
+
119
+ it "the reset_password_token should be random" do
120
+ create_new_user
121
+ sorcery_model_property_set(:reset_password_time_between_emails, 0)
122
+ @user.deliver_reset_password_instructions!
123
+ old_password_code = @user.reset_password_token
124
+ @user.deliver_reset_password_instructions!
125
+ @user.reset_password_token.should_not == old_password_code
126
+ end
127
+
128
+ it "should send an email on reset" do
129
+ create_new_user
130
+ old_size = ActionMailer::Base.deliveries.size
131
+ @user.deliver_reset_password_instructions!
132
+ ActionMailer::Base.deliveries.size.should == old_size + 1
133
+ end
134
+
135
+ it "when change_password! is called, should delete reset_password_token" do
136
+ create_new_user
137
+ @user.deliver_reset_password_instructions!
138
+ @user.reset_password_token.should_not be_nil
139
+ @user.change_password!("blabulsdf")
140
+ @user.save!
141
+ @user.reset_password_token.should be_nil
142
+ end
143
+
144
+ it "should not send an email if time between emails has not passed since last email" do
145
+ create_new_user
146
+ sorcery_model_property_set(:reset_password_time_between_emails, 10000)
147
+ old_size = ActionMailer::Base.deliveries.size
148
+ @user.deliver_reset_password_instructions!
149
+ ActionMailer::Base.deliveries.size.should == old_size + 1
150
+ @user.deliver_reset_password_instructions!
151
+ ActionMailer::Base.deliveries.size.should == old_size + 1
152
+ end
153
+
154
+ it "should send an email if time between emails has passed since last email" do
155
+ create_new_user
156
+ sorcery_model_property_set(:reset_password_time_between_emails, 0.5)
157
+ old_size = ActionMailer::Base.deliveries.size
158
+ @user.deliver_reset_password_instructions!
159
+ ActionMailer::Base.deliveries.size.should == old_size + 1
160
+ Timecop.travel(Time.now+0.5)
161
+ @user.deliver_reset_password_instructions!
162
+ ActionMailer::Base.deliveries.size.should == old_size + 2
163
+ end
164
+
165
+ it "should encrypt properly on reset" do
166
+ create_new_user
167
+ @user.deliver_reset_password_instructions!
168
+ @user.change_password!("blagu")
169
+ Sorcery::CryptoProviders::BCrypt.matches?(@user.crypted_password,"blagu",@user.salt).should be_true
170
+ end
171
+
172
+ it "if mailer is nil on activation, throw exception!" do
173
+ expect{sorcery_reload!([:reset_password])}.to raise_error(ArgumentError)
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,292 @@
1
+ shared_examples_for "rails_3_core_model" do
2
+ describe User, "loaded plugin configuration" do
3
+ after(:each) do
4
+ User.sorcery_config.reset!
5
+ end
6
+
7
+ it "should enable configuration option 'username_attribute_name'" do
8
+ sorcery_model_property_set(:username_attribute_name, :email)
9
+ User.sorcery_config.username_attribute_name.should equal(:email)
10
+ end
11
+
12
+ it "should enable configuration option 'password_attribute_name'" do
13
+ sorcery_model_property_set(:password_attribute_name, :mypassword)
14
+ User.sorcery_config.password_attribute_name.should equal(:mypassword)
15
+ end
16
+
17
+ it "should enable configuration option 'email_attribute_name'" do
18
+ sorcery_model_property_set(:email_attribute_name, :my_email)
19
+ User.sorcery_config.email_attribute_name.should equal(:my_email)
20
+ end
21
+
22
+ it "should enable configuration option 'crypted_password_attribute_name'" do
23
+ sorcery_model_property_set(:crypted_password_attribute_name, :password)
24
+ User.sorcery_config.crypted_password_attribute_name.should equal(:password)
25
+ end
26
+
27
+ it "should enable configuration option 'salt_attribute_name'" do
28
+ sorcery_model_property_set(:salt_attribute_name, :my_salt)
29
+ User.sorcery_config.salt_attribute_name.should equal(:my_salt)
30
+ end
31
+
32
+ it "should enable configuration option 'encryption_algorithm'" do
33
+ sorcery_model_property_set(:encryption_algorithm, :none)
34
+ User.sorcery_config.encryption_algorithm.should equal(:none)
35
+ end
36
+
37
+ it "should enable configuration option 'encryption_key'" do
38
+ sorcery_model_property_set(:encryption_key, 'asdadas424234242')
39
+ User.sorcery_config.encryption_key.should == 'asdadas424234242'
40
+ end
41
+
42
+ it "should enable configuration option 'custom_encryption_provider'" do
43
+ sorcery_model_property_set(:encryption_algorithm, :custom)
44
+ sorcery_model_property_set(:custom_encryption_provider, Array)
45
+ User.sorcery_config.custom_encryption_provider.should equal(Array)
46
+ end
47
+
48
+ it "should enable configuration option 'salt_join_token'" do
49
+ salt_join_token = "--%%*&-"
50
+ sorcery_model_property_set(:salt_join_token, salt_join_token)
51
+ User.sorcery_config.salt_join_token.should equal(salt_join_token)
52
+ end
53
+
54
+ it "should enable configuration option 'stretches'" do
55
+ stretches = 15
56
+ sorcery_model_property_set(:stretches, stretches)
57
+ User.sorcery_config.stretches.should equal(stretches)
58
+ end
59
+
60
+ end
61
+
62
+ # ----------------- PLUGIN ACTIVATED -----------------------
63
+ describe User, "when activated with sorcery" do
64
+ before(:all) do
65
+ sorcery_reload!()
66
+ end
67
+
68
+ before(:each) do
69
+ User.delete_all
70
+ end
71
+
72
+ it "should respond to class method authenticate" do
73
+ ActiveRecord::Base.should_not respond_to(:authenticate) if defined?(ActiveRecord)
74
+ User.should respond_to(:authenticate)
75
+ end
76
+
77
+ it "authenticate should return true if credentials are good" do
78
+ create_new_user
79
+ User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
80
+ end
81
+
82
+ it "authenticate should return false if credentials are bad" do
83
+ create_new_user
84
+ User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'wrong!').should be_false
85
+ end
86
+
87
+ specify { User.should respond_to(:encrypt) }
88
+
89
+ it "subclass should inherit config if defined so" do
90
+ sorcery_reload!([],{:subclasses_inherit_config => true})
91
+ class Admin < User
92
+ end
93
+ Admin.sorcery_config.should_not be_nil
94
+ Admin.sorcery_config.should == User.sorcery_config
95
+ end
96
+
97
+ it "subclass should not inherit config if not defined so" do
98
+ sorcery_reload!([],{:subclasses_inherit_config => false})
99
+ class Admin2 < User
100
+ end
101
+ Admin2.sorcery_config.should be_nil
102
+ end
103
+ end
104
+
105
+ # ----------------- REGISTRATION -----------------------
106
+ describe User, "registration" do
107
+
108
+ before(:all) do
109
+ sorcery_reload!()
110
+ end
111
+
112
+ before(:each) do
113
+ User.delete_all
114
+ end
115
+
116
+ it "by default, encryption_provider should not be nil" do
117
+ User.sorcery_config.encryption_provider.should_not be_nil
118
+ end
119
+
120
+ it "should encrypt password when a new user is saved" do
121
+ create_new_user
122
+ User.sorcery_config.encryption_provider.matches?(@user.send(User.sorcery_config.crypted_password_attribute_name),'secret',@user.salt).should be_true
123
+ end
124
+
125
+ it "should clear the virtual password field if the encryption process worked" do
126
+ create_new_user
127
+ @user.password.should be_nil
128
+ end
129
+
130
+ it "should not clear the virtual password field if save failed due to validity" do
131
+ create_new_user
132
+ User.class_eval do
133
+ validates_format_of :email, :with => /^(.)+@(.)+$/, :if => Proc.new {|r| r.email}, :message => "is invalid"
134
+ end
135
+ @user.password = 'blupush'
136
+ @user.email = 'asd'
137
+ @user.save
138
+ @user.password.should_not be_nil
139
+ end
140
+
141
+ it "should not clear the virtual password field if save failed due to exception" do
142
+ create_new_user
143
+ @user.password = '4blupush'
144
+ @user.username = nil
145
+ User.class_eval do
146
+ validates_presence_of :username
147
+ end
148
+ begin
149
+ @user.save! # triggers validation exception since username field is required.
150
+ rescue
151
+ end
152
+ @user.password.should_not be_nil
153
+ end
154
+
155
+ it "should not encrypt the password twice when a user is updated" do
156
+ create_new_user
157
+ @user.email = "blup@bla.com"
158
+ @user.save!
159
+ User.sorcery_config.encryption_provider.matches?(@user.send(User.sorcery_config.crypted_password_attribute_name),'secret',@user.salt).should be_true
160
+ end
161
+
162
+ it "should replace the crypted_password in case a new password is set" do
163
+ create_new_user
164
+ @user.password = 'new_secret'
165
+ @user.save!
166
+ User.sorcery_config.encryption_provider.matches?(@user.send(User.sorcery_config.crypted_password_attribute_name),'secret',@user.salt).should be_false
167
+ end
168
+
169
+ end
170
+
171
+ # ----------------- PASSWORD ENCRYPTION -----------------------
172
+ describe User, "special encryption cases" do
173
+ before(:all) do
174
+ sorcery_reload!()
175
+ @text = "Some Text!"
176
+ end
177
+
178
+ before(:each) do
179
+ User.delete_all
180
+ end
181
+
182
+ after(:each) do
183
+ User.sorcery_config.reset!
184
+ end
185
+
186
+ it "should work with no password encryption" do
187
+ sorcery_model_property_set(:encryption_algorithm, :none)
188
+ create_new_user
189
+ User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
190
+ end
191
+
192
+ it "should work with custom password encryption" do
193
+ class MyCrypto
194
+ def self.encrypt(*tokens)
195
+ tokens.flatten.join('').gsub(/e/,'A')
196
+ end
197
+
198
+ def self.matches?(crypted,*tokens)
199
+ crypted == encrypt(*tokens)
200
+ end
201
+ end
202
+ sorcery_model_property_set(:encryption_algorithm, :custom)
203
+ sorcery_model_property_set(:custom_encryption_provider, MyCrypto)
204
+ create_new_user
205
+ User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
206
+ end
207
+
208
+ it "if encryption algo is aes256, it should set key to crypto provider" do
209
+ sorcery_model_property_set(:encryption_algorithm, :aes256)
210
+ sorcery_model_property_set(:encryption_key, nil)
211
+ expect{User.encrypt(@text)}.to raise_error(ArgumentError)
212
+ sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
213
+ expect{User.encrypt(@text)}.to_not raise_error(ArgumentError)
214
+ end
215
+
216
+ it "if encryption algo is aes256, it should set key to crypto provider, even if attributes are set in reverse" do
217
+ sorcery_model_property_set(:encryption_key, nil)
218
+ sorcery_model_property_set(:encryption_algorithm, :none)
219
+ sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
220
+ sorcery_model_property_set(:encryption_algorithm, :aes256)
221
+ expect{User.encrypt(@text)}.to_not raise_error(ArgumentError)
222
+ end
223
+
224
+ it "if encryption algo is md5 it should work" do
225
+ sorcery_model_property_set(:encryption_algorithm, :md5)
226
+ User.encrypt(@text).should == Sorcery::CryptoProviders::MD5.encrypt(@text)
227
+ end
228
+
229
+ it "if encryption algo is sha1 it should work" do
230
+ sorcery_model_property_set(:encryption_algorithm, :sha1)
231
+ User.encrypt(@text).should == Sorcery::CryptoProviders::SHA1.encrypt(@text)
232
+ end
233
+
234
+ it "if encryption algo is sha256 it should work" do
235
+ sorcery_model_property_set(:encryption_algorithm, :sha256)
236
+ User.encrypt(@text).should == Sorcery::CryptoProviders::SHA256.encrypt(@text)
237
+ end
238
+
239
+ it "if encryption algo is sha512 it should work" do
240
+ sorcery_model_property_set(:encryption_algorithm, :sha512)
241
+ User.encrypt(@text).should == Sorcery::CryptoProviders::SHA512.encrypt(@text)
242
+ end
243
+
244
+ it "salt should be random for each user and saved in db" do
245
+ sorcery_model_property_set(:salt_attribute_name, :salt)
246
+ create_new_user
247
+ @user.salt.should_not be_nil
248
+ end
249
+
250
+ it "if salt is set should use it to encrypt" do
251
+ sorcery_model_property_set(:salt_attribute_name, :salt)
252
+ sorcery_model_property_set(:encryption_algorithm, :sha512)
253
+ create_new_user
254
+ @user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret')
255
+ @user.crypted_password.should == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
256
+ end
257
+
258
+ it "if salt_join_token is set should use it to encrypt" do
259
+ sorcery_model_property_set(:salt_attribute_name, :salt)
260
+ sorcery_model_property_set(:salt_join_token, "-@=>")
261
+ sorcery_model_property_set(:encryption_algorithm, :sha512)
262
+ create_new_user
263
+ @user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret')
264
+ Sorcery::CryptoProviders::SHA512.join_token = ""
265
+ @user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
266
+ Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token
267
+ @user.crypted_password.should == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
268
+ end
269
+
270
+ end
271
+ end
272
+
273
+ shared_examples_for "external_user" do
274
+ before(:each) do
275
+ User.delete_all
276
+ end
277
+
278
+ it "should respond to 'external?'" do
279
+ create_new_user
280
+ @user.should respond_to(:external?)
281
+ end
282
+
283
+ it "external? should be false for regular users" do
284
+ create_new_user
285
+ @user.external?.should be_false
286
+ end
287
+
288
+ it "external? should be true for external users" do
289
+ create_new_external_user(:twitter)
290
+ @user.external?.should be_true
291
+ end
292
+ end