cbsorcery 0.8.6
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.
- data/.document +5 -0
- data/.gitignore +56 -0
- data/.rspec +1 -0
- data/.travis.yml +40 -0
- data/CHANGELOG.md +263 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +20 -0
- data/README.md +360 -0
- data/Rakefile +6 -0
- data/gemfiles/active_record-rails40.gemfile +7 -0
- data/gemfiles/active_record-rails41.gemfile +7 -0
- data/lib/generators/sorcery/USAGE +22 -0
- data/lib/generators/sorcery/helpers.rb +40 -0
- data/lib/generators/sorcery/install_generator.rb +95 -0
- data/lib/generators/sorcery/templates/initializer.rb +451 -0
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +10 -0
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +9 -0
- data/lib/generators/sorcery/templates/migration/core.rb +13 -0
- data/lib/generators/sorcery/templates/migration/external.rb +12 -0
- data/lib/generators/sorcery/templates/migration/remember_me.rb +8 -0
- data/lib/generators/sorcery/templates/migration/reset_password.rb +9 -0
- data/lib/generators/sorcery/templates/migration/user_activation.rb +9 -0
- data/lib/sorcery.rb +85 -0
- data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
- data/lib/sorcery/adapters/base_adapter.rb +30 -0
- data/lib/sorcery/controller.rb +157 -0
- data/lib/sorcery/controller/config.rb +65 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +82 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +38 -0
- data/lib/sorcery/controller/submodules/external.rb +199 -0
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +74 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +81 -0
- data/lib/sorcery/controller/submodules/session_timeout.rb +56 -0
- data/lib/sorcery/crypto_providers/aes256.rb +51 -0
- data/lib/sorcery/crypto_providers/bcrypt.rb +97 -0
- data/lib/sorcery/crypto_providers/common.rb +35 -0
- data/lib/sorcery/crypto_providers/md5.rb +19 -0
- data/lib/sorcery/crypto_providers/sha1.rb +28 -0
- data/lib/sorcery/crypto_providers/sha256.rb +36 -0
- data/lib/sorcery/crypto_providers/sha512.rb +36 -0
- data/lib/sorcery/engine.rb +21 -0
- data/lib/sorcery/model.rb +183 -0
- data/lib/sorcery/model/config.rb +96 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +70 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +125 -0
- data/lib/sorcery/model/submodules/external.rb +100 -0
- data/lib/sorcery/model/submodules/remember_me.rb +62 -0
- data/lib/sorcery/model/submodules/reset_password.rb +131 -0
- data/lib/sorcery/model/submodules/user_activation.rb +149 -0
- data/lib/sorcery/model/temporary_token.rb +30 -0
- data/lib/sorcery/protocols/certs/ca-bundle.crt +5182 -0
- data/lib/sorcery/protocols/oauth.rb +42 -0
- data/lib/sorcery/protocols/oauth2.rb +47 -0
- data/lib/sorcery/providers/base.rb +27 -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/jira.rb +77 -0
- data/lib/sorcery/providers/linkedin.rb +66 -0
- data/lib/sorcery/providers/liveid.rb +53 -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/railties/tasks.rake +6 -0
- data/lib/sorcery/test_helpers/internal.rb +78 -0
- data/lib/sorcery/test_helpers/internal/rails.rb +68 -0
- 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/sorcery.gemspec +34 -0
- data/spec/active_record/user_activation_spec.rb +18 -0
- data/spec/active_record/user_activity_logging_spec.rb +17 -0
- data/spec/active_record/user_brute_force_protection_spec.rb +16 -0
- data/spec/active_record/user_oauth_spec.rb +16 -0
- data/spec/active_record/user_remember_me_spec.rb +16 -0
- data/spec/active_record/user_reset_password_spec.rb +16 -0
- data/spec/active_record/user_spec.rb +37 -0
- 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 +407 -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 +215 -0
- data/spec/orm/active_record.rb +21 -0
- data/spec/rails_app/app/active_record/authentication.rb +3 -0
- data/spec/rails_app/app/active_record/user.rb +5 -0
- data/spec/rails_app/app/active_record/user_provider.rb +3 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +265 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/app/mailers/sorcery_mailer.rb +32 -0
- data/spec/rails_app/app/views/application/index.html.erb +17 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +56 -0
- data/spec/rails_app/config/boot.rb +4 -0
- data/spec/rails_app/config/database.yml +22 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/test.rb +37 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_app/config/initializers/session_store.rb +12 -0
- data/spec/rails_app/config/locales/en.yml +5 -0
- data/spec/rails_app/config/routes.rb +48 -0
- data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
- data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +19 -0
- data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +13 -0
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +22 -0
- data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/rails_app/db/schema.rb +23 -0
- data/spec/rails_app/db/seeds.rb +7 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +242 -0
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +97 -0
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +156 -0
- data/spec/shared_examples/user_oauth_shared_examples.rb +36 -0
- data/spec/shared_examples/user_remember_me_shared_examples.rb +57 -0
- data/spec/shared_examples/user_reset_password_shared_examples.rb +263 -0
- data/spec/shared_examples/user_shared_examples.rb +467 -0
- data/spec/sorcery_crypto_providers_spec.rb +198 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +41 -0
- metadata +350 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
shared_examples_for "rails_3_core_model" do
|
|
2
|
+
|
|
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
|
|
11
|
+
sorcery_model_property_set(:username_attribute_names, :email)
|
|
12
|
+
|
|
13
|
+
expect(User.sorcery_config.username_attribute_names).to eq [:email]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "enables configuration option 'password_attribute_name'" do
|
|
17
|
+
sorcery_model_property_set(:password_attribute_name, :mypassword)
|
|
18
|
+
|
|
19
|
+
expect(User.sorcery_config.password_attribute_name).to eq :mypassword
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "enables configuration option 'email_attribute_name'" do
|
|
23
|
+
sorcery_model_property_set(:email_attribute_name, :my_email)
|
|
24
|
+
|
|
25
|
+
expect(User.sorcery_config.email_attribute_name).to eq :my_email
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "enables configuration option 'crypted_password_attribute_name'" do
|
|
29
|
+
sorcery_model_property_set(:crypted_password_attribute_name, :password)
|
|
30
|
+
|
|
31
|
+
expect(User.sorcery_config.crypted_password_attribute_name).to eq :password
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "enables configuration option 'salt_attribute_name'" do
|
|
35
|
+
sorcery_model_property_set(:salt_attribute_name, :my_salt)
|
|
36
|
+
|
|
37
|
+
expect(User.sorcery_config.salt_attribute_name).to eq :my_salt
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "enables configuration option 'encryption_algorithm'" do
|
|
41
|
+
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
42
|
+
|
|
43
|
+
expect(User.sorcery_config.encryption_algorithm).to eq :none
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "enables configuration option 'encryption_key'" do
|
|
47
|
+
sorcery_model_property_set(:encryption_key, 'asdadas424234242')
|
|
48
|
+
|
|
49
|
+
expect(User.sorcery_config.encryption_key).to eq 'asdadas424234242'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "enables configuration option 'custom_encryption_provider'" do
|
|
53
|
+
sorcery_model_property_set(:encryption_algorithm, :custom)
|
|
54
|
+
sorcery_model_property_set(:custom_encryption_provider, Array)
|
|
55
|
+
|
|
56
|
+
expect(User.sorcery_config.custom_encryption_provider).to eq Array
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "enables configuration option 'salt_join_token'" do
|
|
60
|
+
salt_join_token = "--%%*&-"
|
|
61
|
+
sorcery_model_property_set(:salt_join_token, salt_join_token)
|
|
62
|
+
|
|
63
|
+
expect(User.sorcery_config.salt_join_token).to eq salt_join_token
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "enables configuration option 'stretches'" do
|
|
67
|
+
stretches = 15
|
|
68
|
+
sorcery_model_property_set(:stretches, stretches)
|
|
69
|
+
|
|
70
|
+
expect(User.sorcery_config.stretches).to eq stretches
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'respond to username=' do
|
|
74
|
+
expect(User.new).to respond_to(:username=)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
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)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "responds to class method authenticate" do
|
|
87
|
+
expect(User).to respond_to :authenticate
|
|
88
|
+
end
|
|
89
|
+
|
|
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
|
|
94
|
+
end
|
|
95
|
+
|
|
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
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "with empty credentials" do
|
|
103
|
+
before do
|
|
104
|
+
sorcery_model_property_set(:downcase_username_before_authenticating, true)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
after do
|
|
108
|
+
sorcery_reload!
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "don't downcase empty credentials" do
|
|
112
|
+
expect(User.authenticate(nil, 'wrong!')).to be_falsy
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
specify { expect(User).to respond_to(:encrypt) }
|
|
117
|
+
|
|
118
|
+
it "subclass inherits config if defined so" do
|
|
119
|
+
sorcery_reload!([],{:subclasses_inherit_config => true})
|
|
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
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "subclass does not inherit config if not defined so" do
|
|
127
|
+
sorcery_reload!([],{:subclasses_inherit_config => false})
|
|
128
|
+
class Admin2 < User; end
|
|
129
|
+
|
|
130
|
+
expect(Admin2.sorcery_config).to be_nil
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
describe "registration" do
|
|
136
|
+
|
|
137
|
+
before(:all) { sorcery_reload! }
|
|
138
|
+
before(:each) { User.sorcery_adapter.delete_all }
|
|
139
|
+
|
|
140
|
+
it "by default, encryption_provider is not nil" do
|
|
141
|
+
expect(User.sorcery_config.encryption_provider).not_to be_nil
|
|
142
|
+
end
|
|
143
|
+
|
|
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
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "clears the virtual password field if the encryption process worked" do
|
|
149
|
+
expect(user.password).to be_nil
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "does not clear the virtual password field if save failed due to validity" do
|
|
153
|
+
User.class_eval do
|
|
154
|
+
validates_format_of :email, :with => /\A(.)+@(.)+\Z/, :if => Proc.new {|r| r.email}, :message => "is invalid"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
user.password = 'blupush'
|
|
158
|
+
user.email = 'asd'
|
|
159
|
+
user.save
|
|
160
|
+
|
|
161
|
+
expect(user.password).not_to be_nil
|
|
162
|
+
end
|
|
163
|
+
|
|
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
|
+
|
|
170
|
+
begin
|
|
171
|
+
user.save
|
|
172
|
+
rescue
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
expect(user.password).not_to be_nil
|
|
176
|
+
end
|
|
177
|
+
|
|
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
|
|
183
|
+
end
|
|
184
|
+
|
|
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
|
|
190
|
+
end
|
|
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
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "special encryption cases" do
|
|
221
|
+
before(:all) do
|
|
222
|
+
sorcery_reload!()
|
|
223
|
+
@text = "Some Text!"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
before(:each) do
|
|
227
|
+
User.sorcery_adapter.delete_all
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
after(:each) do
|
|
231
|
+
User.sorcery_config.reset!
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "works with no password encryption" do
|
|
235
|
+
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
236
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
237
|
+
|
|
238
|
+
expect(User.authenticate username, 'secret').to be_truthy
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it "works with custom password encryption" do
|
|
242
|
+
class MyCrypto
|
|
243
|
+
def self.encrypt(*tokens)
|
|
244
|
+
tokens.flatten.join('').gsub(/e/,'A')
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def self.matches?(crypted,*tokens)
|
|
248
|
+
crypted == encrypt(*tokens)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
sorcery_model_property_set(:encryption_algorithm, :custom)
|
|
252
|
+
sorcery_model_property_set(:custom_encryption_provider, MyCrypto)
|
|
253
|
+
|
|
254
|
+
username = user.send(User.sorcery_config.username_attribute_names.first)
|
|
255
|
+
|
|
256
|
+
expect(User.authenticate username, 'secret').to be_truthy
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "if encryption algo is aes256, it sets key to crypto provider" do
|
|
260
|
+
sorcery_model_property_set(:encryption_algorithm, :aes256)
|
|
261
|
+
sorcery_model_property_set(:encryption_key, nil)
|
|
262
|
+
|
|
263
|
+
expect { User.encrypt @text }.to raise_error(ArgumentError)
|
|
264
|
+
|
|
265
|
+
sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
|
266
|
+
|
|
267
|
+
expect { User.encrypt @text }.not_to raise_error
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "if encryption algo is aes256, it sets key to crypto provider, even if attributes are set in reverse" do
|
|
271
|
+
sorcery_model_property_set(:encryption_key, nil)
|
|
272
|
+
sorcery_model_property_set(:encryption_algorithm, :none)
|
|
273
|
+
sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
|
274
|
+
sorcery_model_property_set(:encryption_algorithm, :aes256)
|
|
275
|
+
|
|
276
|
+
expect { User.encrypt @text }.not_to raise_error
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it "if encryption algo is md5 it works" do
|
|
280
|
+
sorcery_model_property_set(:encryption_algorithm, :md5)
|
|
281
|
+
|
|
282
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::MD5.encrypt(@text)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "if encryption algo is sha1 it works" do
|
|
286
|
+
sorcery_model_property_set(:encryption_algorithm, :sha1)
|
|
287
|
+
|
|
288
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA1.encrypt(@text)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "if encryption algo is sha256 it works" do
|
|
292
|
+
sorcery_model_property_set(:encryption_algorithm, :sha256)
|
|
293
|
+
|
|
294
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA256.encrypt(@text)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "if encryption algo is sha512 it works" do
|
|
298
|
+
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
299
|
+
|
|
300
|
+
expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA512.encrypt(@text)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "salt is random for each user and saved in db" do
|
|
304
|
+
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
305
|
+
|
|
306
|
+
expect(user.salt).not_to be_nil
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it "if salt is set uses it to encrypt" do
|
|
310
|
+
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
311
|
+
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
312
|
+
|
|
313
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
|
314
|
+
expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "if salt_join_token is set uses it to encrypt" do
|
|
318
|
+
sorcery_model_property_set(:salt_attribute_name, :salt)
|
|
319
|
+
sorcery_model_property_set(:salt_join_token, "-@=>")
|
|
320
|
+
sorcery_model_property_set(:encryption_algorithm, :sha512)
|
|
321
|
+
|
|
322
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
|
323
|
+
|
|
324
|
+
Sorcery::CryptoProviders::SHA512.join_token = ""
|
|
325
|
+
|
|
326
|
+
expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
327
|
+
|
|
328
|
+
Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token
|
|
329
|
+
|
|
330
|
+
expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
describe "ORM adapter" do
|
|
335
|
+
before(:all) do
|
|
336
|
+
sorcery_reload!()
|
|
337
|
+
User.sorcery_adapter.delete_all
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
before(:each) { user }
|
|
341
|
+
|
|
342
|
+
after(:each) do
|
|
343
|
+
User.sorcery_adapter.delete_all
|
|
344
|
+
User.sorcery_config.reset!
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
it "find_by_username works as expected" do
|
|
349
|
+
sorcery_model_property_set(:username_attribute_names, [:username])
|
|
350
|
+
|
|
351
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it "find_by_username works as expected with multiple username attributes" do
|
|
355
|
+
sorcery_model_property_set(:username_attribute_names, [:username, :email])
|
|
356
|
+
|
|
357
|
+
expect(User.sorcery_adapter.find_by_username "gizmo").to eq user
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "find_by_email works as expected" do
|
|
361
|
+
expect(User.sorcery_adapter.find_by_email "bla@bla.com").to eq user
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
shared_examples_for "external_user" do
|
|
367
|
+
let(:user) { create_new_user }
|
|
368
|
+
let(:external_user) { create_new_external_user :twitter }
|
|
369
|
+
|
|
370
|
+
before(:each) do
|
|
371
|
+
User.sorcery_adapter.delete_all
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "responds to 'external?'" do
|
|
375
|
+
expect(user).to respond_to(:external?)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "external? is false for regular users" do
|
|
379
|
+
expect(user.external?).to be false
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it "external? is true for external users" do
|
|
383
|
+
expect(external_user.external?).to be true
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
describe ".create_from_provider" do
|
|
387
|
+
|
|
388
|
+
before(:all) do
|
|
389
|
+
if SORCERY_ORM == :active_record
|
|
390
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
|
|
391
|
+
User.reset_column_information
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
sorcery_reload!([:external])
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
after(:all) do
|
|
398
|
+
if SORCERY_ORM == :active_record
|
|
399
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
it 'supports nested attributes' do
|
|
404
|
+
sorcery_model_property_set(:authentications_class, Authentication)
|
|
405
|
+
|
|
406
|
+
expect { User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) }.to change { User.count }.by(1)
|
|
407
|
+
expect(User.first.username).to eq 'Noam Ben Ari'
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context 'with block' do
|
|
411
|
+
it 'create user when block return true' do
|
|
412
|
+
expect {
|
|
413
|
+
User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { true }
|
|
414
|
+
}.to change { User.count }.by(1)
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
it 'does not create user when block return false' do
|
|
418
|
+
expect {
|
|
419
|
+
User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { false }
|
|
420
|
+
}.not_to change { User.count }
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
describe 'activation' do
|
|
427
|
+
before(:all) do
|
|
428
|
+
if SORCERY_ORM == :active_record
|
|
429
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
|
|
430
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
after(:all) do
|
|
437
|
+
if SORCERY_ORM == :active_record
|
|
438
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
|
439
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
after(:each) do
|
|
444
|
+
User.sorcery_adapter.delete_all
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
[:facebook, :github, :google, :liveid].each do |provider|
|
|
448
|
+
|
|
449
|
+
it "does not send activation email to external users" do
|
|
450
|
+
old_size = ActionMailer::Base.deliveries.size
|
|
451
|
+
create_new_external_user(provider)
|
|
452
|
+
|
|
453
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
it "does not send external users an activation success email" do
|
|
457
|
+
sorcery_model_property_set(:activation_success_email_method_name, nil)
|
|
458
|
+
create_new_external_user(provider)
|
|
459
|
+
old_size = ActionMailer::Base.deliveries.size
|
|
460
|
+
@user.activate!
|
|
461
|
+
|
|
462
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
end
|
|
467
|
+
end
|