sorcery 0.8.5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.travis.yml +122 -5
- data/CHANGELOG.md +37 -1
- data/Gemfile +10 -18
- data/README.md +159 -88
- data/gemfiles/active_record-rails40.gemfile +7 -0
- data/gemfiles/active_record-rails41.gemfile +7 -0
- data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
- data/gemfiles/mongo_mapper-rails41.gemfile +9 -0
- data/gemfiles/mongoid-rails40.gemfile +9 -0
- data/gemfiles/mongoid-rails41.gemfile +9 -0
- 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/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/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 +35 -40
- data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
- data/lib/sorcery/controller.rb +10 -74
- data/lib/sorcery/model/config.rb +96 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +30 -13
- data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -21
- data/lib/sorcery/model/submodules/external.rb +53 -9
- data/lib/sorcery/model/submodules/remember_me.rb +15 -19
- data/lib/sorcery/model/submodules/reset_password.rb +33 -34
- data/lib/sorcery/model/submodules/user_activation.rb +36 -47
- data/lib/sorcery/model/temporary_token.rb +4 -4
- data/lib/sorcery/model.rb +73 -173
- data/lib/sorcery/protocols/oauth.rb +42 -0
- data/lib/sorcery/protocols/oauth2.rb +47 -0
- data/lib/sorcery/providers/base.rb +38 -0
- data/lib/sorcery/providers/facebook.rb +63 -0
- data/lib/sorcery/providers/github.rb +51 -0
- data/lib/sorcery/providers/google.rb +51 -0
- data/lib/sorcery/providers/heroku.rb +57 -0
- data/lib/sorcery/providers/jira.rb +77 -0
- data/lib/sorcery/providers/linkedin.rb +66 -0
- data/lib/sorcery/providers/liveid.rb +53 -0
- data/lib/sorcery/providers/salesforce.rb +50 -0
- data/lib/sorcery/providers/twitter.rb +59 -0
- data/lib/sorcery/providers/vk.rb +63 -0
- data/lib/sorcery/providers/xing.rb +64 -0
- data/lib/sorcery/test_helpers/internal/rails.rb +14 -3
- data/lib/sorcery/test_helpers/internal.rb +7 -3
- data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
- data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
- data/lib/sorcery/version.rb +3 -0
- data/lib/sorcery.rb +82 -58
- data/sorcery.gemspec +19 -19
- data/spec/active_record/user_activation_spec.rb +1 -1
- data/spec/active_record/user_activity_logging_spec.rb +10 -1
- data/spec/active_record/user_brute_force_protection_spec.rb +1 -1
- data/spec/active_record/user_oauth_spec.rb +1 -1
- data/spec/active_record/user_remember_me_spec.rb +1 -1
- data/spec/active_record/user_reset_password_spec.rb +1 -1
- data/spec/active_record/user_spec.rb +7 -8
- data/spec/controllers/controller_activity_logging_spec.rb +124 -0
- data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
- data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
- data/spec/controllers/controller_oauth2_spec.rb +414 -0
- data/spec/controllers/controller_oauth_spec.rb +240 -0
- data/spec/controllers/controller_remember_me_spec.rb +117 -0
- data/spec/controllers/controller_session_timeout_spec.rb +80 -0
- data/spec/controllers/controller_spec.rb +218 -0
- data/spec/data_mapper/user_activation_spec.rb +10 -0
- data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
- data/spec/data_mapper/user_brute_force_protection_spec.rb +9 -0
- data/spec/data_mapper/user_oauth_spec.rb +9 -0
- data/spec/data_mapper/user_remember_me_spec.rb +8 -0
- data/spec/data_mapper/user_reset_password_spec.rb +8 -0
- data/spec/data_mapper/user_spec.rb +27 -0
- data/spec/mongo_mapper/user_activation_spec.rb +1 -2
- data/spec/mongo_mapper/user_activity_logging_spec.rb +1 -1
- data/spec/mongo_mapper/user_brute_force_protection_spec.rb +1 -1
- data/spec/mongo_mapper/user_oauth_spec.rb +1 -1
- data/spec/mongo_mapper/user_remember_me_spec.rb +1 -1
- data/spec/mongo_mapper/user_reset_password_spec.rb +1 -1
- data/spec/mongo_mapper/user_spec.rb +7 -8
- data/spec/mongoid/user_activation_spec.rb +1 -2
- data/spec/mongoid/user_activity_logging_spec.rb +1 -2
- data/spec/mongoid/user_brute_force_protection_spec.rb +1 -2
- data/spec/mongoid/user_oauth_spec.rb +1 -2
- data/spec/mongoid/user_remember_me_spec.rb +1 -2
- data/spec/mongoid/user_reset_password_spec.rb +1 -2
- data/spec/mongoid/user_spec.rb +21 -9
- data/spec/orm/active_record.rb +14 -0
- data/spec/orm/data_mapper.rb +48 -0
- data/spec/orm/mongo_mapper.rb +1 -1
- data/spec/orm/mongoid.rb +5 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +125 -59
- data/spec/rails_app/app/data_mapper/authentication.rb +8 -0
- data/spec/rails_app/app/data_mapper/user.rb +7 -0
- data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
- data/spec/rails_app/config/routes.rb +27 -13
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
- data/spec/shared_examples/user_activation_shared_examples.rb +108 -91
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +83 -15
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +140 -21
- data/spec/shared_examples/user_oauth_shared_examples.rb +21 -16
- data/spec/shared_examples/user_remember_me_shared_examples.rb +36 -24
- data/spec/shared_examples/user_reset_password_shared_examples.rb +138 -117
- data/spec/shared_examples/user_shared_examples.rb +297 -150
- data/spec/sorcery_crypto_providers_spec.rb +28 -28
- data/spec/spec_helper.rb +12 -18
- metadata +99 -165
- data/Gemfile.rails4 +0 -24
- data/VERSION +0 -1
- data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +0 -46
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +0 -50
- data/lib/sorcery/controller/submodules/external/providers/base.rb +0 -21
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +0 -99
- data/lib/sorcery/controller/submodules/external/providers/github.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/google.rb +0 -92
- data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +0 -103
- data/lib/sorcery/controller/submodules/external/providers/liveid.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/twitter.rb +0 -94
- data/lib/sorcery/controller/submodules/external/providers/vk.rb +0 -101
- data/lib/sorcery/controller/submodules/external/providers/xing.rb +0 -98
- data/lib/sorcery/model/adapters/active_record.rb +0 -49
- data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -56
- data/lib/sorcery/model/adapters/mongoid.rb +0 -88
- data/lib/sorcery/test_helpers/rails.rb +0 -16
- data/lib/sorcery/test_helpers.rb +0 -5
- data/spec/active_record/controller_activity_logging_spec.rb +0 -140
- data/spec/active_record/controller_brute_force_protection_spec.rb +0 -136
- data/spec/active_record/controller_http_basic_auth_spec.rb +0 -59
- data/spec/active_record/controller_oauth2_spec.rb +0 -417
- data/spec/active_record/controller_oauth_spec.rb +0 -212
- data/spec/active_record/controller_remember_me_spec.rb +0 -96
- data/spec/active_record/controller_session_timeout_spec.rb +0 -55
- data/spec/active_record/controller_spec.rb +0 -182
- data/spec/active_record/integration_spec.rb +0 -23
- data/spec/mongo_mapper/controller_spec.rb +0 -175
- data/spec/mongoid/controller_activity_logging_spec.rb +0 -111
- data/spec/mongoid/controller_spec.rb +0 -186
- 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_oauth2_shared_examples.rb +0 -56
- data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -69
- /data/lib/sorcery/{controller/submodules/external/protocols → protocols}/certs/ca-bundle.crt +0 -0
|
@@ -1,86 +1,102 @@
|
|
|
1
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
2
|
|
|
7
|
-
|
|
3
|
+
let(:user) { create_new_user }
|
|
4
|
+
let(:crypted_password) { user.send User.sorcery_config.crypted_password_attribute_name }
|
|
5
|
+
|
|
6
|
+
describe "loaded plugin configuration" do
|
|
7
|
+
|
|
8
|
+
after(:each) { User.sorcery_config.reset! }
|
|
9
|
+
|
|
10
|
+
it "enables configuration option 'username_attribute_names'" do
|
|
8
11
|
sorcery_model_property_set(:username_attribute_names, :email)
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
expect(User.sorcery_config.username_attribute_names).to eq [:email]
|
|
10
14
|
end
|
|
11
15
|
|
|
12
|
-
it "
|
|
16
|
+
it "enables configuration option 'password_attribute_name'" do
|
|
13
17
|
sorcery_model_property_set(:password_attribute_name, :mypassword)
|
|
14
|
-
|
|
18
|
+
|
|
19
|
+
expect(User.sorcery_config.password_attribute_name).to eq :mypassword
|
|
15
20
|
end
|
|
16
21
|
|
|
17
|
-
it "
|
|
22
|
+
it "enables configuration option 'email_attribute_name'" do
|
|
18
23
|
sorcery_model_property_set(:email_attribute_name, :my_email)
|
|
19
|
-
|
|
24
|
+
|
|
25
|
+
expect(User.sorcery_config.email_attribute_name).to eq :my_email
|
|
20
26
|
end
|
|
21
27
|
|
|
22
|
-
it "
|
|
28
|
+
it "enables configuration option 'crypted_password_attribute_name'" do
|
|
23
29
|
sorcery_model_property_set(:crypted_password_attribute_name, :password)
|
|
24
|
-
|
|
30
|
+
|
|
31
|
+
expect(User.sorcery_config.crypted_password_attribute_name).to eq :password
|
|
25
32
|
end
|
|
26
33
|
|
|
27
|
-
it "
|
|
34
|
+
it "enables configuration option 'salt_attribute_name'" do
|
|
28
35
|
sorcery_model_property_set(:salt_attribute_name, :my_salt)
|
|
29
|
-
|
|
36
|
+
|
|
37
|
+
expect(User.sorcery_config.salt_attribute_name).to eq :my_salt
|
|
30
38
|
end
|
|
31
39
|
|
|
32
|
-
it "
|
|
40
|
+
it "enables configuration option 'encryption_algorithm'" do
|
|
33
41
|
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
34
|
-
|
|
42
|
+
|
|
43
|
+
expect(User.sorcery_config.encryption_algorithm).to eq :none
|
|
35
44
|
end
|
|
36
45
|
|
|
37
|
-
it "
|
|
46
|
+
it "enables configuration option 'encryption_key'" do
|
|
38
47
|
sorcery_model_property_set(:encryption_key, 'asdadas424234242')
|
|
39
|
-
|
|
48
|
+
|
|
49
|
+
expect(User.sorcery_config.encryption_key).to eq 'asdadas424234242'
|
|
40
50
|
end
|
|
41
51
|
|
|
42
|
-
it "
|
|
52
|
+
it "enables configuration option 'custom_encryption_provider'" do
|
|
43
53
|
sorcery_model_property_set(:encryption_algorithm, :custom)
|
|
44
54
|
sorcery_model_property_set(:custom_encryption_provider, Array)
|
|
45
|
-
|
|
55
|
+
|
|
56
|
+
expect(User.sorcery_config.custom_encryption_provider).to eq Array
|
|
46
57
|
end
|
|
47
58
|
|
|
48
|
-
it "
|
|
59
|
+
it "enables configuration option 'salt_join_token'" do
|
|
49
60
|
salt_join_token = "--%%*&-"
|
|
50
61
|
sorcery_model_property_set(:salt_join_token, salt_join_token)
|
|
51
|
-
|
|
62
|
+
|
|
63
|
+
expect(User.sorcery_config.salt_join_token).to eq salt_join_token
|
|
52
64
|
end
|
|
53
65
|
|
|
54
|
-
it "
|
|
66
|
+
it "enables configuration option 'stretches'" do
|
|
55
67
|
stretches = 15
|
|
56
68
|
sorcery_model_property_set(:stretches, stretches)
|
|
57
|
-
|
|
69
|
+
|
|
70
|
+
expect(User.sorcery_config.stretches).to eq stretches
|
|
58
71
|
end
|
|
59
|
-
end
|
|
60
72
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
before(:all) do
|
|
64
|
-
sorcery_reload!
|
|
73
|
+
it 'respond to username=' do
|
|
74
|
+
expect(User.new).to respond_to(:username=)
|
|
65
75
|
end
|
|
76
|
+
end
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
describe "when activated with sorcery" do
|
|
79
|
+
before(:all) { sorcery_reload! }
|
|
80
|
+
before(:each) { User.sorcery_adapter.delete_all }
|
|
81
|
+
|
|
82
|
+
it "does not add authenticate method to base class", active_record: true do
|
|
83
|
+
expect(ActiveRecord::Base).not_to respond_to(:authenticate) if defined?(ActiveRecord)
|
|
69
84
|
end
|
|
70
85
|
|
|
71
|
-
it "
|
|
72
|
-
|
|
73
|
-
User.should respond_to(:authenticate)
|
|
86
|
+
it "responds to class method authenticate" do
|
|
87
|
+
expect(User).to respond_to :authenticate
|
|
74
88
|
end
|
|
75
89
|
|
|
76
|
-
it "authenticate
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
it "authenticate returns true if credentials are good" do
|
|
91
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
92
|
+
|
|
93
|
+
expect(User.authenticate username, 'secret').to be_truthy
|
|
79
94
|
end
|
|
80
95
|
|
|
81
|
-
it "authenticate
|
|
82
|
-
|
|
83
|
-
|
|
96
|
+
it "authenticate returns nil if credentials are bad" do
|
|
97
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
98
|
+
|
|
99
|
+
expect(User.authenticate username, 'wrong!').to be nil
|
|
84
100
|
end
|
|
85
101
|
|
|
86
102
|
context "with empty credentials" do
|
|
@@ -93,116 +109,151 @@ shared_examples_for "rails_3_core_model" do
|
|
|
93
109
|
end
|
|
94
110
|
|
|
95
111
|
it "don't downcase empty credentials" do
|
|
96
|
-
expect(User.authenticate(nil, 'wrong!')).to
|
|
112
|
+
expect(User.authenticate(nil, 'wrong!')).to be_falsy
|
|
97
113
|
end
|
|
98
114
|
end
|
|
99
115
|
|
|
100
|
-
specify { User.
|
|
116
|
+
specify { expect(User).to respond_to(:encrypt) }
|
|
101
117
|
|
|
102
|
-
it "subclass
|
|
118
|
+
it "subclass inherits config if defined so" do
|
|
103
119
|
sorcery_reload!([],{:subclasses_inherit_config => true})
|
|
104
|
-
class Admin < User
|
|
105
|
-
|
|
106
|
-
Admin.sorcery_config.
|
|
107
|
-
Admin.sorcery_config.
|
|
120
|
+
class Admin < User; end
|
|
121
|
+
|
|
122
|
+
expect(Admin.sorcery_config).not_to be_nil
|
|
123
|
+
expect(Admin.sorcery_config).to eq User.sorcery_config
|
|
108
124
|
end
|
|
109
125
|
|
|
110
|
-
it "subclass
|
|
126
|
+
it "subclass does not inherit config if not defined so" do
|
|
111
127
|
sorcery_reload!([],{:subclasses_inherit_config => false})
|
|
112
|
-
class Admin2 < User
|
|
113
|
-
|
|
114
|
-
Admin2.sorcery_config.
|
|
128
|
+
class Admin2 < User; end
|
|
129
|
+
|
|
130
|
+
expect(Admin2.sorcery_config).to be_nil
|
|
115
131
|
end
|
|
116
132
|
end
|
|
117
133
|
|
|
118
|
-
# ----------------- REGISTRATION -----------------------
|
|
119
|
-
describe User, "registration" do
|
|
120
134
|
|
|
121
|
-
|
|
122
|
-
sorcery_reload!()
|
|
123
|
-
end
|
|
135
|
+
describe "registration" do
|
|
124
136
|
|
|
125
|
-
before(:
|
|
126
|
-
|
|
127
|
-
end
|
|
137
|
+
before(:all) { sorcery_reload! }
|
|
138
|
+
before(:each) { User.sorcery_adapter.delete_all }
|
|
128
139
|
|
|
129
|
-
it "by default, encryption_provider
|
|
130
|
-
User.sorcery_config.encryption_provider.
|
|
140
|
+
it "by default, encryption_provider is not nil" do
|
|
141
|
+
expect(User.sorcery_config.encryption_provider).not_to be_nil
|
|
131
142
|
end
|
|
132
143
|
|
|
133
|
-
it "
|
|
134
|
-
|
|
135
|
-
User.sorcery_config.encryption_provider.matches?(@user.send(User.sorcery_config.crypted_password_attribute_name),'secret',@user.salt).should be_true
|
|
144
|
+
it "encrypts password when a new user is saved" do
|
|
145
|
+
expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be true
|
|
136
146
|
end
|
|
137
147
|
|
|
138
|
-
it "
|
|
139
|
-
|
|
140
|
-
@user.password.should be_nil
|
|
148
|
+
it "clears the virtual password field if the encryption process worked" do
|
|
149
|
+
expect(user.password).to be_nil
|
|
141
150
|
end
|
|
142
151
|
|
|
143
|
-
it "
|
|
144
|
-
create_new_user
|
|
152
|
+
it "does not clear the virtual password field if save failed due to validity" do
|
|
145
153
|
User.class_eval do
|
|
146
154
|
validates_format_of :email, :with => /\A(.)+@(.)+\Z/, :if => Proc.new {|r| r.email}, :message => "is invalid"
|
|
147
155
|
end
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
|
|
157
|
+
user.password = 'blupush'
|
|
158
|
+
user.email = 'asd'
|
|
159
|
+
user.save
|
|
160
|
+
|
|
161
|
+
expect(user.password).not_to be_nil
|
|
152
162
|
end
|
|
153
163
|
|
|
154
|
-
it "
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
end
|
|
164
|
+
it "does not clear the virtual password field if save failed due to exception" do
|
|
165
|
+
user.password = '4blupush'
|
|
166
|
+
user.username = nil
|
|
167
|
+
|
|
168
|
+
expect(user).to receive(:save) { raise RuntimeError }
|
|
169
|
+
|
|
161
170
|
begin
|
|
162
|
-
|
|
171
|
+
user.save
|
|
163
172
|
rescue
|
|
164
173
|
end
|
|
165
|
-
|
|
174
|
+
|
|
175
|
+
expect(user.password).not_to be_nil
|
|
166
176
|
end
|
|
167
177
|
|
|
168
|
-
it "
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
User.sorcery_config.encryption_provider.matches?
|
|
178
|
+
it "does not encrypt the password twice when a user is updated" do
|
|
179
|
+
user.email = "blup@bla.com"
|
|
180
|
+
user.save
|
|
181
|
+
|
|
182
|
+
expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be true
|
|
173
183
|
end
|
|
174
184
|
|
|
175
|
-
it "
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
User.sorcery_config.encryption_provider.matches?
|
|
185
|
+
it "replaces the crypted_password in case a new password is set" do
|
|
186
|
+
user.password = 'new_secret'
|
|
187
|
+
user.save
|
|
188
|
+
|
|
189
|
+
expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be false
|
|
180
190
|
end
|
|
181
191
|
|
|
192
|
+
describe "when user has password_confirmation_defined" do
|
|
193
|
+
before(:all) do
|
|
194
|
+
update_model { attr_accessor :password_confirmation }
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
after(:all) do
|
|
198
|
+
User.send(:remove_method, :password_confirmation)
|
|
199
|
+
User.send(:remove_method, :password_confirmation=)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "clears the virtual password field if the encryption process worked" do
|
|
203
|
+
user = create_new_user(username: "u", password: "secret", password_confirmation: "secret", email: "email@example.com")
|
|
204
|
+
|
|
205
|
+
expect(user.password_confirmation).to be_nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "does not clear the virtual password field if save failed due to validity" do
|
|
209
|
+
User.class_eval do
|
|
210
|
+
validates_format_of :email, :with => /\A(.)+@(.)+\Z/
|
|
211
|
+
end
|
|
212
|
+
user = build_new_user(username: "u", password: "secret", password_confirmation: "secret", email: "asd")
|
|
213
|
+
user.save
|
|
214
|
+
|
|
215
|
+
expect(user.password_confirmation).not_to be_nil
|
|
216
|
+
end
|
|
217
|
+
end
|
|
182
218
|
end
|
|
183
219
|
|
|
184
|
-
|
|
185
|
-
|
|
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
|
+
|
|
235
|
+
describe "special encryption cases" do
|
|
186
236
|
before(:all) do
|
|
187
237
|
sorcery_reload!()
|
|
188
238
|
@text = "Some Text!"
|
|
189
239
|
end
|
|
190
240
|
|
|
191
241
|
before(:each) do
|
|
192
|
-
User.delete_all
|
|
242
|
+
User.sorcery_adapter.delete_all
|
|
193
243
|
end
|
|
194
244
|
|
|
195
245
|
after(:each) do
|
|
196
246
|
User.sorcery_config.reset!
|
|
197
247
|
end
|
|
198
248
|
|
|
199
|
-
it "
|
|
249
|
+
it "works with no password encryption" do
|
|
200
250
|
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
201
|
-
|
|
202
|
-
|
|
251
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
252
|
+
|
|
253
|
+
expect(User.authenticate username, 'secret').to be_truthy
|
|
203
254
|
end
|
|
204
255
|
|
|
205
|
-
it "
|
|
256
|
+
it "works with custom password encryption" do
|
|
206
257
|
class MyCrypto
|
|
207
258
|
def self.encrypt(*tokens)
|
|
208
259
|
tokens.flatten.join('').gsub(/e/,'A')
|
|
@@ -214,122 +265,218 @@ shared_examples_for "rails_3_core_model" do
|
|
|
214
265
|
end
|
|
215
266
|
sorcery_model_property_set(:encryption_algorithm, :custom)
|
|
216
267
|
sorcery_model_property_set(:custom_encryption_provider, MyCrypto)
|
|
217
|
-
|
|
218
|
-
|
|
268
|
+
|
|
269
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
270
|
+
|
|
271
|
+
expect(User.authenticate username, 'secret').to be_truthy
|
|
219
272
|
end
|
|
220
273
|
|
|
221
|
-
it "if encryption algo is aes256, it
|
|
274
|
+
it "if encryption algo is aes256, it sets key to crypto provider" do
|
|
222
275
|
sorcery_model_property_set(:encryption_algorithm, :aes256)
|
|
223
276
|
sorcery_model_property_set(:encryption_key, nil)
|
|
224
|
-
|
|
277
|
+
|
|
278
|
+
expect { User.encrypt @text }.to raise_error(ArgumentError)
|
|
279
|
+
|
|
225
280
|
sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
|
226
|
-
|
|
281
|
+
|
|
282
|
+
expect { User.encrypt @text }.not_to raise_error
|
|
227
283
|
end
|
|
228
284
|
|
|
229
|
-
it "if encryption algo is aes256, it
|
|
285
|
+
it "if encryption algo is aes256, it sets key to crypto provider, even if attributes are set in reverse" do
|
|
230
286
|
sorcery_model_property_set(:encryption_key, nil)
|
|
231
287
|
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
232
288
|
sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
|
233
289
|
sorcery_model_property_set(:encryption_algorithm, :aes256)
|
|
234
|
-
|
|
290
|
+
|
|
291
|
+
expect { User.encrypt @text }.not_to raise_error
|
|
235
292
|
end
|
|
236
293
|
|
|
237
|
-
it "if encryption algo is md5 it
|
|
294
|
+
it "if encryption algo is md5 it works" do
|
|
238
295
|
sorcery_model_property_set(:encryption_algorithm, :md5)
|
|
239
|
-
|
|
296
|
+
|
|
297
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::MD5.encrypt(@text)
|
|
240
298
|
end
|
|
241
299
|
|
|
242
|
-
it "if encryption algo is sha1 it
|
|
300
|
+
it "if encryption algo is sha1 it works" do
|
|
243
301
|
sorcery_model_property_set(:encryption_algorithm, :sha1)
|
|
244
|
-
|
|
302
|
+
|
|
303
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA1.encrypt(@text)
|
|
245
304
|
end
|
|
246
305
|
|
|
247
|
-
it "if encryption algo is sha256 it
|
|
306
|
+
it "if encryption algo is sha256 it works" do
|
|
248
307
|
sorcery_model_property_set(:encryption_algorithm, :sha256)
|
|
249
|
-
|
|
308
|
+
|
|
309
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA256.encrypt(@text)
|
|
250
310
|
end
|
|
251
311
|
|
|
252
|
-
it "if encryption algo is sha512 it
|
|
312
|
+
it "if encryption algo is sha512 it works" do
|
|
253
313
|
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
254
|
-
|
|
314
|
+
|
|
315
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA512.encrypt(@text)
|
|
255
316
|
end
|
|
256
317
|
|
|
257
|
-
it "salt
|
|
318
|
+
it "salt is random for each user and saved in db" do
|
|
258
319
|
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
259
|
-
|
|
260
|
-
|
|
320
|
+
|
|
321
|
+
expect(user.salt).not_to be_nil
|
|
261
322
|
end
|
|
262
323
|
|
|
263
|
-
it "if salt is set
|
|
324
|
+
it "if salt is set uses it to encrypt" do
|
|
264
325
|
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
265
326
|
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
327
|
+
|
|
328
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
|
329
|
+
expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
269
330
|
end
|
|
270
331
|
|
|
271
|
-
it "if salt_join_token is set
|
|
332
|
+
it "if salt_join_token is set uses it to encrypt" do
|
|
272
333
|
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
273
334
|
sorcery_model_property_set(:salt_join_token, "-@=>")
|
|
274
335
|
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
275
|
-
|
|
276
|
-
|
|
336
|
+
|
|
337
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
|
338
|
+
|
|
277
339
|
Sorcery::CryptoProviders::SHA512.join_token = ""
|
|
278
|
-
|
|
340
|
+
|
|
341
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
342
|
+
|
|
279
343
|
Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token
|
|
280
|
-
@user.crypted_password.should == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
|
|
281
|
-
end
|
|
282
344
|
|
|
345
|
+
expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
346
|
+
end
|
|
283
347
|
end
|
|
284
348
|
|
|
285
|
-
describe
|
|
349
|
+
describe "ORM adapter" do
|
|
286
350
|
before(:all) do
|
|
287
351
|
sorcery_reload!()
|
|
288
|
-
User.delete_all
|
|
352
|
+
User.sorcery_adapter.delete_all
|
|
289
353
|
end
|
|
290
354
|
|
|
291
|
-
before(:each)
|
|
292
|
-
create_new_user
|
|
293
|
-
end
|
|
355
|
+
before(:each) { user }
|
|
294
356
|
|
|
295
357
|
after(:each) do
|
|
296
|
-
User.delete_all
|
|
358
|
+
User.sorcery_adapter.delete_all
|
|
297
359
|
User.sorcery_config.reset!
|
|
298
360
|
end
|
|
299
361
|
|
|
300
|
-
|
|
362
|
+
|
|
363
|
+
it "find_by_username works as expected" do
|
|
301
364
|
sorcery_model_property_set(:username_attribute_names, [:username])
|
|
302
|
-
|
|
365
|
+
|
|
366
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
|
303
367
|
end
|
|
304
368
|
|
|
305
|
-
it "find_by_username
|
|
369
|
+
it "find_by_username works as expected with multiple username attributes" do
|
|
306
370
|
sorcery_model_property_set(:username_attribute_names, [:username, :email])
|
|
307
|
-
|
|
371
|
+
|
|
372
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
|
308
373
|
end
|
|
309
374
|
|
|
310
|
-
it "find_by_email
|
|
311
|
-
User.find_by_email
|
|
375
|
+
it "find_by_email works as expected" do
|
|
376
|
+
expect(User.sorcery_adapter.find_by_email "bla@bla.com").to eq user
|
|
312
377
|
end
|
|
313
378
|
end
|
|
314
379
|
end
|
|
315
380
|
|
|
316
381
|
shared_examples_for "external_user" do
|
|
382
|
+
let(:user) { create_new_user }
|
|
383
|
+
let(:external_user) { create_new_external_user :twitter }
|
|
384
|
+
|
|
317
385
|
before(:each) do
|
|
318
|
-
User.delete_all
|
|
386
|
+
User.sorcery_adapter.delete_all
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it "responds to 'external?'" do
|
|
390
|
+
expect(user).to respond_to(:external?)
|
|
319
391
|
end
|
|
320
392
|
|
|
321
|
-
it "
|
|
322
|
-
|
|
323
|
-
@user.should respond_to(:external?)
|
|
393
|
+
it "external? is false for regular users" do
|
|
394
|
+
expect(user.external?).to be false
|
|
324
395
|
end
|
|
325
396
|
|
|
326
|
-
it "external?
|
|
327
|
-
|
|
328
|
-
|
|
397
|
+
it "external? is true for external users" do
|
|
398
|
+
expect(external_user.external?).to be true
|
|
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
|
+
|
|
329
439
|
end
|
|
330
440
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
+
|
|
334
481
|
end
|
|
335
|
-
end
|
|
482
|
+
end
|