sorcery 0.17.0 → 0.18.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.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -1
  3. data/README.md +8 -5
  4. data/lib/generators/sorcery/helpers.rb +1 -1
  5. data/lib/generators/sorcery/install_generator.rb +9 -18
  6. data/lib/generators/sorcery/templates/initializer.rb +24 -10
  7. data/lib/sorcery/adapters/active_record_adapter.rb +12 -14
  8. data/lib/sorcery/adapters/mongoid_adapter.rb +6 -8
  9. data/lib/sorcery/controller/config.rb +27 -29
  10. data/lib/sorcery/controller/submodules/activity_logging.rb +4 -7
  11. data/lib/sorcery/controller/submodules/brute_force_protection.rb +4 -1
  12. data/lib/sorcery/controller/submodules/external.rb +11 -11
  13. data/lib/sorcery/controller/submodules/http_basic_auth.rb +7 -2
  14. data/lib/sorcery/controller/submodules/remember_me.rb +2 -1
  15. data/lib/sorcery/controller/submodules/session_timeout.rb +2 -2
  16. data/lib/sorcery/controller.rb +36 -18
  17. data/lib/sorcery/crypto_providers/aes256.rb +4 -2
  18. data/lib/sorcery/crypto_providers/bcrypt.rb +2 -1
  19. data/lib/sorcery/crypto_providers/md5.rb +1 -0
  20. data/lib/sorcery/crypto_providers/sha1.rb +1 -0
  21. data/lib/sorcery/crypto_providers/sha256.rb +1 -0
  22. data/lib/sorcery/crypto_providers/sha512.rb +1 -0
  23. data/lib/sorcery/engine.rb +6 -4
  24. data/lib/sorcery/errors.rb +10 -0
  25. data/lib/sorcery/model/config.rb +20 -31
  26. data/lib/sorcery/model/submodules/activity_logging.rb +8 -6
  27. data/lib/sorcery/model/submodules/brute_force_protection.rb +16 -14
  28. data/lib/sorcery/model/submodules/external.rb +8 -10
  29. data/lib/sorcery/model/submodules/magic_login.rb +8 -4
  30. data/lib/sorcery/model/submodules/remember_me.rb +3 -3
  31. data/lib/sorcery/model/submodules/reset_password.rb +21 -13
  32. data/lib/sorcery/model/submodules/user_activation.rb +19 -17
  33. data/lib/sorcery/model/temporary_token.rb +5 -5
  34. data/lib/sorcery/model.rb +21 -25
  35. data/lib/sorcery/providers/base.rb +1 -1
  36. data/lib/sorcery/providers/facebook.rb +2 -2
  37. data/lib/sorcery/providers/github.rb +3 -3
  38. data/lib/sorcery/providers/heroku.rb +1 -2
  39. data/lib/sorcery/providers/jira.rb +3 -2
  40. data/lib/sorcery/providers/line.rb +2 -4
  41. data/lib/sorcery/providers/microsoft.rb +1 -1
  42. data/lib/sorcery/providers/twitter.rb +2 -2
  43. data/lib/sorcery/providers/vk.rb +4 -4
  44. data/lib/sorcery/providers/xing.rb +3 -2
  45. data/lib/sorcery/test_helpers/internal/rails.rb +5 -22
  46. data/lib/sorcery/test_helpers/internal.rb +4 -6
  47. data/lib/sorcery/test_helpers/rails/integration.rb +1 -1
  48. data/lib/sorcery/test_helpers/rails/request.rb +1 -1
  49. data/lib/sorcery/version.rb +1 -1
  50. data/lib/sorcery.rb +6 -1
  51. metadata +21 -150
  52. data/.devcontainer/Dockerfile +0 -10
  53. data/.devcontainer/devcontainer.json +0 -29
  54. data/.devcontainer/postcreate.sh +0 -4
  55. data/.document +0 -5
  56. data/.github/FUNDING.yml +0 -1
  57. data/.github/ISSUE_TEMPLATE.md +0 -24
  58. data/.github/PULL_REQUEST_TEMPLATE.md +0 -7
  59. data/.github/workflows/ruby.yml +0 -54
  60. data/.gitignore +0 -60
  61. data/.rspec +0 -1
  62. data/.rubocop.yml +0 -55
  63. data/.rubocop_todo.yml +0 -163
  64. data/CODE_OF_CONDUCT.md +0 -14
  65. data/Gemfile +0 -8
  66. data/MAINTAINING.md +0 -64
  67. data/Rakefile +0 -8
  68. data/SECURITY.md +0 -19
  69. data/gemfiles/rails_61.gemfile +0 -7
  70. data/gemfiles/rails_70.gemfile +0 -7
  71. data/gemfiles/rails_71.gemfile +0 -7
  72. data/sorcery.gemspec +0 -49
  73. data/spec/active_record/user_activation_spec.rb +0 -17
  74. data/spec/active_record/user_activity_logging_spec.rb +0 -15
  75. data/spec/active_record/user_brute_force_protection_spec.rb +0 -15
  76. data/spec/active_record/user_magic_login_spec.rb +0 -15
  77. data/spec/active_record/user_oauth_spec.rb +0 -15
  78. data/spec/active_record/user_remember_me_spec.rb +0 -15
  79. data/spec/active_record/user_reset_password_spec.rb +0 -15
  80. data/spec/active_record/user_spec.rb +0 -27
  81. data/spec/controllers/controller_activity_logging_spec.rb +0 -113
  82. data/spec/controllers/controller_brute_force_protection_spec.rb +0 -41
  83. data/spec/controllers/controller_http_basic_auth_spec.rb +0 -67
  84. data/spec/controllers/controller_oauth2_spec.rb +0 -568
  85. data/spec/controllers/controller_oauth_spec.rb +0 -266
  86. data/spec/controllers/controller_remember_me_spec.rb +0 -130
  87. data/spec/controllers/controller_session_timeout_spec.rb +0 -168
  88. data/spec/controllers/controller_spec.rb +0 -200
  89. data/spec/orm/active_record.rb +0 -21
  90. data/spec/providers/example_provider_spec.rb +0 -17
  91. data/spec/providers/example_spec.rb +0 -17
  92. data/spec/providers/examples_spec.rb +0 -17
  93. data/spec/providers/vk_spec.rb +0 -42
  94. data/spec/rails_app/app/active_record/authentication.rb +0 -3
  95. data/spec/rails_app/app/active_record/user.rb +0 -5
  96. data/spec/rails_app/app/active_record/user_provider.rb +0 -3
  97. data/spec/rails_app/app/assets/config/manifest.js +0 -1
  98. data/spec/rails_app/app/controllers/application_controller.rb +0 -2
  99. data/spec/rails_app/app/controllers/sorcery_controller.rb +0 -489
  100. data/spec/rails_app/app/helpers/application_helper.rb +0 -2
  101. data/spec/rails_app/app/mailers/sorcery_mailer.rb +0 -38
  102. data/spec/rails_app/app/views/application/index.html.erb +0 -17
  103. data/spec/rails_app/app/views/layouts/application.html.erb +0 -14
  104. data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +0 -17
  105. data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +0 -9
  106. data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +0 -17
  107. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +0 -17
  108. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +0 -9
  109. data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.html.erb +0 -13
  110. data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.text.erb +0 -6
  111. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +0 -16
  112. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +0 -8
  113. data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +0 -1
  114. data/spec/rails_app/config/application.rb +0 -61
  115. data/spec/rails_app/config/boot.rb +0 -4
  116. data/spec/rails_app/config/database.yml +0 -22
  117. data/spec/rails_app/config/environment.rb +0 -5
  118. data/spec/rails_app/config/environments/test.rb +0 -37
  119. data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  120. data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +0 -11
  121. data/spec/rails_app/config/initializers/inflections.rb +0 -10
  122. data/spec/rails_app/config/initializers/mime_types.rb +0 -5
  123. data/spec/rails_app/config/initializers/session_store.rb +0 -12
  124. data/spec/rails_app/config/locales/en.yml +0 -5
  125. data/spec/rails_app/config/routes.rb +0 -81
  126. data/spec/rails_app/config/secrets.yml +0 -4
  127. data/spec/rails_app/config.ru +0 -4
  128. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
  129. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -19
  130. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -13
  131. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +0 -16
  132. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +0 -22
  133. data/spec/rails_app/db/migrate/invalidate_active_sessions/20180221093235_add_invalidate_active_sessions_before_to_users.rb +0 -9
  134. data/spec/rails_app/db/migrate/magic_login/20170924151831_add_magic_login_to_users.rb +0 -17
  135. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
  136. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -15
  137. data/spec/rails_app/db/schema.rb +0 -21
  138. data/spec/rails_app/db/seeds.rb +0 -7
  139. data/spec/shared_examples/user_activation_shared_examples.rb +0 -361
  140. data/spec/shared_examples/user_activity_logging_shared_examples.rb +0 -106
  141. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +0 -151
  142. data/spec/shared_examples/user_magic_login_shared_examples.rb +0 -150
  143. data/spec/shared_examples/user_oauth_shared_examples.rb +0 -33
  144. data/spec/shared_examples/user_remember_me_shared_examples.rb +0 -129
  145. data/spec/shared_examples/user_reset_password_shared_examples.rb +0 -370
  146. data/spec/shared_examples/user_shared_examples.rb +0 -678
  147. data/spec/sorcery_crypto_providers_spec.rb +0 -245
  148. data/spec/sorcery_temporary_token_spec.rb +0 -27
  149. data/spec/spec.opts +0 -2
  150. data/spec/spec_helper.rb +0 -50
  151. data/spec/support/migration_helper.rb +0 -29
  152. data/spec/support/providers/example.rb +0 -11
  153. data/spec/support/providers/example_provider.rb +0 -11
  154. data/spec/support/providers/examples.rb +0 -11
@@ -1,678 +0,0 @@
1
- shared_examples_for 'rails_3_core_model' do
2
- let(:user) { create_new_user }
3
- let(:crypted_password) { user.send User.sorcery_config.crypted_password_attribute_name }
4
-
5
- describe 'loaded plugin configuration' do
6
- after(:each) { User.sorcery_config.reset! }
7
-
8
- it "enables configuration option 'username_attribute_names'" do
9
- sorcery_model_property_set(:username_attribute_names, :email)
10
-
11
- expect(User.sorcery_config.username_attribute_names).to eq [:email]
12
- end
13
-
14
- it "enables configuration option 'password_attribute_name'" do
15
- sorcery_model_property_set(:password_attribute_name, :mypassword)
16
-
17
- expect(User.sorcery_config.password_attribute_name).to eq :mypassword
18
- end
19
-
20
- it "enables configuration option 'email_attribute_name'" do
21
- sorcery_model_property_set(:email_attribute_name, :my_email)
22
-
23
- expect(User.sorcery_config.email_attribute_name).to eq :my_email
24
- end
25
-
26
- it "enables configuration option 'crypted_password_attribute_name'" do
27
- sorcery_model_property_set(:crypted_password_attribute_name, :password)
28
-
29
- expect(User.sorcery_config.crypted_password_attribute_name).to eq :password
30
- end
31
-
32
- it "enables configuration option 'salt_attribute_name'" do
33
- sorcery_model_property_set(:salt_attribute_name, :my_salt)
34
-
35
- expect(User.sorcery_config.salt_attribute_name).to eq :my_salt
36
- end
37
-
38
- it "enables configuration option 'encryption_algorithm'" do
39
- sorcery_model_property_set(:encryption_algorithm, :none)
40
-
41
- expect(User.sorcery_config.encryption_algorithm).to eq :none
42
- end
43
-
44
- it "enables configuration option 'encryption_key'" do
45
- sorcery_model_property_set(:encryption_key, 'asdadas424234242')
46
-
47
- expect(User.sorcery_config.encryption_key).to eq 'asdadas424234242'
48
- end
49
-
50
- it "enables configuration option 'custom_encryption_provider'" do
51
- sorcery_model_property_set(:encryption_algorithm, :custom)
52
- sorcery_model_property_set(:custom_encryption_provider, Array)
53
-
54
- expect(User.sorcery_config.custom_encryption_provider).to eq Array
55
- end
56
-
57
- it "enables configuration option 'pepper'" do
58
- pepper = '*$%&%*++'
59
- sorcery_model_property_set(:pepper, pepper)
60
-
61
- expect(User.sorcery_config.pepper).to eq pepper
62
- end
63
-
64
- it "enables configuration option 'salt_join_token'" do
65
- salt_join_token = '--%%*&-'
66
- sorcery_model_property_set(:salt_join_token, salt_join_token)
67
-
68
- expect(User.sorcery_config.salt_join_token).to eq salt_join_token
69
- end
70
-
71
- it "enables configuration option 'stretches'" do
72
- stretches = 15
73
- sorcery_model_property_set(:stretches, stretches)
74
-
75
- expect(User.sorcery_config.stretches).to eq stretches
76
- end
77
-
78
- it "enables configuration option 'deliver_later_enabled" do
79
- sorcery_model_property_set(:email_delivery_method, :deliver_later)
80
- expect(User.sorcery_config.email_delivery_method).to eq :deliver_later
81
- end
82
-
83
- it 'respond to username=' do
84
- expect(User.new).to respond_to(:username=)
85
- end
86
- end
87
-
88
- describe 'when activated with sorcery' do
89
- before(:all) { sorcery_reload! }
90
- before(:each) { User.sorcery_adapter.delete_all }
91
-
92
- it 'does not add authenticate method to base class', active_record: true do
93
- expect(ActiveRecord::Base).not_to respond_to(:authenticate) if defined?(ActiveRecord)
94
- end
95
-
96
- it 'responds to class method authenticate' do
97
- expect(User).to respond_to :authenticate
98
- end
99
-
100
- describe '#authenticate' do
101
- it 'returns user if credentials are good' do
102
- expect(User.authenticate(user.email, 'secret')).to eq user
103
- end
104
-
105
- it 'returns nil if credentials are bad' do
106
- expect(User.authenticate(user.email, 'wrong!')).to be nil
107
- end
108
-
109
- context 'downcasing username' do
110
- after do
111
- sorcery_reload!
112
- end
113
-
114
- context 'when downcasing set to false' do
115
- before do
116
- sorcery_model_property_set(:downcase_username_before_authenticating, false)
117
- end
118
-
119
- it 'does not find user with wrongly capitalized username' do
120
- expect(User.authenticate(user.email.capitalize, 'secret')).to be_nil
121
- end
122
-
123
- it 'finds user with correctly capitalized username' do
124
- expect(User.authenticate(user.email, 'secret')).to eq user
125
- end
126
- end
127
-
128
- context 'when downcasing set to true' do
129
- before do
130
- sorcery_model_property_set(:downcase_username_before_authenticating, true)
131
- end
132
-
133
- it 'does not find user with wrongly capitalized username' do
134
- expect(User.authenticate(user.email.capitalize, 'secret')).to eq user
135
- end
136
-
137
- it 'finds user with correctly capitalized username' do
138
- expect(User.authenticate(user.email, 'secret')).to eq user
139
- end
140
- end
141
- end
142
-
143
- context 'and model implements active_for_authentication?' do
144
- it 'authenticates returns user if active_for_authentication? returns true' do
145
- allow_any_instance_of(User).to receive(:active_for_authentication?) { true }
146
-
147
- expect(User.authenticate(user.email, 'secret')).to eq user
148
- end
149
-
150
- it 'authenticate returns nil if active_for_authentication? returns false' do
151
- allow_any_instance_of(User).to receive(:active_for_authentication?) { false }
152
-
153
- expect(User.authenticate(user.email, 'secret')).to be_nil
154
- end
155
- end
156
-
157
- context 'in block mode' do
158
- it 'yields the user if credentials are good' do
159
- User.authenticate(user.email, 'secret') do |user2, failure|
160
- expect(user2).to eq user
161
- expect(failure).to be_nil
162
- end
163
- end
164
-
165
- it 'yields the user and proper error if credentials are bad' do
166
- User.authenticate(user.email, 'wrong!') do |user2, failure|
167
- expect(user2).to eq user
168
- expect(failure).to eq :invalid_password
169
- end
170
- end
171
-
172
- it 'yields the proper error if no user exists' do
173
- [nil, '', 'not@a.user'].each do |email|
174
- User.authenticate(email, 'wrong!') do |user2, failure|
175
- expect(user2).to be_nil
176
- expect(failure).to eq :invalid_login
177
- end
178
- end
179
- end
180
- end
181
- end
182
-
183
- specify { expect(User).to respond_to(:encrypt) }
184
-
185
- it 'subclass inherits config if defined so' do
186
- sorcery_reload!([], subclasses_inherit_config: true)
187
- class Admin < User; end
188
-
189
- expect(Admin.sorcery_config).not_to be_nil
190
- expect(Admin.sorcery_config).to eq User.sorcery_config
191
- end
192
-
193
- it 'subclass does not inherit config if not defined so' do
194
- sorcery_reload!([], subclasses_inherit_config: false)
195
- class Admin2 < User; end
196
-
197
- expect(Admin2.sorcery_config).to be_nil
198
- end
199
- end
200
-
201
- describe 'registration' do
202
- before(:all) { sorcery_reload! }
203
- before(:each) { User.sorcery_adapter.delete_all }
204
-
205
- it 'by default, encryption_provider is not nil' do
206
- expect(User.sorcery_config.encryption_provider).not_to be_nil
207
- end
208
-
209
- it 'encrypts password when a new user is saved' do
210
- expect(
211
- User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)
212
- ).to be true
213
- end
214
-
215
- it 'clears the virtual password field if the encryption process worked' do
216
- expect(user.password).to be_nil
217
- end
218
-
219
- it 'does not clear the virtual password field if save failed due to validity' do
220
- User.class_eval do
221
- validates_format_of :email, with: /\A(.)+@(.)+\Z/,
222
- if: proc { |r| r.email }, message: 'is invalid'
223
- end
224
-
225
- user.password = 'blupush'
226
- user.email = 'asd'
227
- user.save
228
-
229
- expect(user.password).not_to be_nil
230
- end
231
-
232
- it 'does not clear the virtual password field if save failed due to exception' do
233
- user.password = '4blupush'
234
- user.username = nil
235
-
236
- expect(user).to receive(:save) { raise RuntimeError }
237
-
238
- # rubocop:disable Lint/HandleExceptions
239
- begin
240
- user.save
241
- rescue RuntimeError
242
- # Intentionally force exception during save
243
- end
244
- # rubocop:enable Lint/HandleExceptions
245
-
246
- expect(user.password).not_to be_nil
247
- end
248
-
249
- it 'does not encrypt the password twice when a user is updated' do
250
- user.email = 'blup@bla.com'
251
- user.save
252
-
253
- expect(
254
- User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)
255
- ).to be true
256
- end
257
-
258
- it 'replaces the crypted_password in case a new password is set' do
259
- user.password = 'new_secret'
260
- user.save
261
-
262
- expect(
263
- User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)
264
- ).to be false
265
- end
266
-
267
- describe 'when user has password_confirmation_defined' do
268
- before(:all) do
269
- update_model { attr_accessor :password_confirmation }
270
- end
271
-
272
- after(:all) do
273
- User.send(:remove_method, :password_confirmation)
274
- User.send(:remove_method, :password_confirmation=)
275
- end
276
-
277
- it 'clears the virtual password field if the encryption process worked' do
278
- user = create_new_user(
279
- username: 'u',
280
- password: 'secret', password_confirmation: 'secret',
281
- email: 'email@example.com'
282
- )
283
-
284
- expect(user.password_confirmation).to be_nil
285
- end
286
-
287
- it 'does not clear the virtual password field if save failed due to validity' do
288
- User.class_eval do
289
- validates_format_of :email, with: /\A(.)+@(.)+\Z/
290
- end
291
- user = build_new_user(
292
- username: 'u',
293
- password: 'secret', password_confirmation: 'secret',
294
- email: 'asd'
295
- )
296
- user.save
297
-
298
- expect(user.password_confirmation).not_to be_nil
299
- end
300
- end
301
- end
302
-
303
- describe 'password validation' do
304
- let(:user_with_pass) do
305
- create_new_user(username: 'foo_bar', email: 'foo@bar.com', password: 'foobar')
306
- end
307
-
308
- specify { expect(user_with_pass).to respond_to :valid_password? }
309
-
310
- it 'returns true if password is correct' do
311
- expect(user_with_pass.valid_password?('foobar')).to be true
312
- end
313
-
314
- it 'returns false if password is incorrect' do
315
- expect(user_with_pass.valid_password?('foobug')).to be false
316
- end
317
- end
318
-
319
- describe 'generic send email' do
320
- before(:all) do
321
- MigrationHelper.migrate("#{Rails.root}/db/migrate/activation")
322
- User.reset_column_information
323
- end
324
-
325
- after(:all) do
326
- MigrationHelper.rollback("#{Rails.root}/db/migrate/activation")
327
- end
328
-
329
- before do
330
- @mail = double('mail')
331
- allow(::SorceryMailer).to receive(:activation_success_email).and_return(@mail)
332
- end
333
-
334
- it 'use deliver_later' do
335
- sorcery_reload!(
336
- %i[
337
- user_activation
338
- user_activation_mailer
339
- activation_needed_email_method_name
340
- email_delivery_method
341
- ],
342
- user_activation_mailer: SorceryMailer,
343
- activation_needed_email_method_name: nil,
344
- email_delivery_method: :deliver_later
345
- )
346
-
347
- expect(@mail).to receive(:deliver_later).once
348
- user.activate!
349
- end
350
-
351
- describe 'email_delivery_method is default' do
352
- it 'use deliver_now if rails version 4.2+' do
353
- allow(Rails).to receive(:version).and_return('4.2.0')
354
- sorcery_reload!(
355
- %i[
356
- user_activation
357
- user_activation_mailer
358
- activation_needed_email_method_name
359
- ],
360
- user_activation_mailer: SorceryMailer,
361
- activation_needed_email_method_name: nil
362
- )
363
-
364
- expect(@mail).to receive(:deliver_now).once
365
- user.activate!
366
- end
367
-
368
- it 'use deliver if rails version < 4.2' do
369
- allow(Rails).to receive(:version).and_return('4.1.0')
370
- sorcery_reload!(
371
- %i[
372
- user_activation
373
- user_activation_mailer
374
- activation_needed_email_method_name
375
- ],
376
- user_activation_mailer: SorceryMailer,
377
- activation_needed_email_method_name: nil
378
- )
379
-
380
- expect(@mail).to receive(:deliver).once
381
- user.activate!
382
- end
383
- end
384
- end
385
-
386
- describe 'special encryption cases' do
387
- before(:all) do
388
- sorcery_reload!
389
- @text = 'Some Text!'
390
- end
391
-
392
- before(:each) do
393
- User.sorcery_adapter.delete_all
394
- end
395
-
396
- after(:each) do
397
- User.sorcery_config.reset!
398
- end
399
-
400
- it 'works with no password encryption' do
401
- sorcery_model_property_set(:encryption_algorithm, :none)
402
- username = user.send(User.sorcery_config.username_attribute_names.first)
403
-
404
- expect(User.authenticate(username, 'secret')).to be_truthy
405
- end
406
-
407
- it 'works with custom password encryption' do
408
- class MyCrypto
409
- def self.encrypt(*tokens)
410
- tokens.flatten.join('').tr('e', 'A')
411
- end
412
-
413
- def self.matches?(crypted, *tokens)
414
- crypted == encrypt(*tokens)
415
- end
416
- end
417
- sorcery_model_property_set(:encryption_algorithm, :custom)
418
- sorcery_model_property_set(:custom_encryption_provider, MyCrypto)
419
-
420
- username = user.send(User.sorcery_config.username_attribute_names.first)
421
-
422
- expect(User.authenticate(username, 'secret')).to be_truthy
423
- end
424
-
425
- it 'if encryption algo is aes256, it sets key to crypto provider' do
426
- sorcery_model_property_set(:encryption_algorithm, :aes256)
427
- sorcery_model_property_set(:encryption_key, nil)
428
-
429
- expect { User.encrypt @text }.to raise_error(ArgumentError)
430
-
431
- sorcery_model_property_set(:encryption_key, 'asd234dfs423fddsmndsflktsdf32343')
432
-
433
- expect { User.encrypt @text }.not_to raise_error
434
- end
435
-
436
- it 'if encryption algo is aes256, it sets key to crypto provider, even if attributes are set in reverse' do
437
- sorcery_model_property_set(:encryption_key, nil)
438
- sorcery_model_property_set(:encryption_algorithm, :none)
439
- sorcery_model_property_set(:encryption_key, 'asd234dfs423fddsmndsflktsdf32343')
440
- sorcery_model_property_set(:encryption_algorithm, :aes256)
441
-
442
- expect { User.encrypt @text }.not_to raise_error
443
- end
444
-
445
- it 'if encryption algo is md5 it works' do
446
- sorcery_model_property_set(:encryption_algorithm, :md5)
447
-
448
- expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::MD5.encrypt(@text)
449
- end
450
-
451
- it 'if encryption algo is sha1 it works' do
452
- sorcery_model_property_set(:encryption_algorithm, :sha1)
453
-
454
- expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA1.encrypt(@text)
455
- end
456
-
457
- it 'if encryption algo is sha256 it works' do
458
- sorcery_model_property_set(:encryption_algorithm, :sha256)
459
-
460
- expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA256.encrypt(@text)
461
- end
462
-
463
- it 'if encryption algo is sha512 it works' do
464
- sorcery_model_property_set(:encryption_algorithm, :sha512)
465
-
466
- expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA512.encrypt(@text)
467
- end
468
-
469
- it 'if encryption algo is bcrypt it works' do
470
- sorcery_model_property_set(:encryption_algorithm, :bcrypt)
471
-
472
- # comparison is done using BCrypt::Password#==(raw_token), not by String#==
473
- expect(User.encrypt(@text)).to be_an_instance_of BCrypt::Password
474
- expect(User.encrypt(@text)).to eq @text
475
- end
476
-
477
- it 'salt is random for each user and saved in db' do
478
- sorcery_model_property_set(:salt_attribute_name, :salt)
479
-
480
- expect(user.salt).not_to be_nil
481
- end
482
-
483
- it 'if salt is set uses it to encrypt' do
484
- sorcery_model_property_set(:salt_attribute_name, :salt)
485
- sorcery_model_property_set(:encryption_algorithm, :sha512)
486
-
487
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
488
- expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt)
489
- end
490
-
491
- it 'if salt_join_token is set uses it to encrypt' do
492
- sorcery_model_property_set(:salt_attribute_name, :salt)
493
- sorcery_model_property_set(:salt_join_token, '-@=>')
494
- sorcery_model_property_set(:encryption_algorithm, :sha512)
495
-
496
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret')
497
-
498
- Sorcery::CryptoProviders::SHA512.join_token = ''
499
-
500
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt)
501
-
502
- Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token
503
-
504
- expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt)
505
- end
506
-
507
- it 'if pepper is set uses it to encrypt' do
508
- sorcery_model_property_set(:salt_attribute_name, :salt)
509
- sorcery_model_property_set(:pepper, '++@^$')
510
- sorcery_model_property_set(:encryption_algorithm, :bcrypt)
511
-
512
- # password comparison is done using BCrypt::Password#==(raw_token), not String#==
513
- bcrypt_password = BCrypt::Password.new(user.crypted_password)
514
- allow(::BCrypt::Password).to receive(:create) do |token, options = {}|
515
- # need to use common BCrypt's salt when genarating BCrypt::Password objects
516
- # so that any generated password hashes can be compared each other
517
- ::BCrypt::Engine.hash_secret(token, bcrypt_password.salt)
518
- end
519
-
520
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret')
521
-
522
- Sorcery::CryptoProviders::BCrypt.pepper = ''
523
-
524
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret', user.salt)
525
-
526
- Sorcery::CryptoProviders::BCrypt.pepper = User.sorcery_config.pepper
527
-
528
- expect(user.crypted_password).to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret', user.salt)
529
- end
530
-
531
- it 'if pepper is empty string (default) does not use pepper to encrypt' do
532
- sorcery_model_property_set(:salt_attribute_name, :salt)
533
- sorcery_model_property_set(:pepper, '')
534
- sorcery_model_property_set(:encryption_algorithm, :bcrypt)
535
-
536
- # password comparison is done using BCrypt::Password#==(raw_token), not String#==
537
- bcrypt_password = BCrypt::Password.new(user.crypted_password)
538
- allow(::BCrypt::Password).to receive(:create) do |token, options = {}|
539
- # need to use common BCrypt's salt when genarating BCrypt::Password objects
540
- # so that any generated password hashes can be compared each other
541
- ::BCrypt::Engine.hash_secret(token, bcrypt_password.salt)
542
- end
543
-
544
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret')
545
-
546
- Sorcery::CryptoProviders::BCrypt.pepper = 'some_pepper'
547
-
548
- expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret', user.salt)
549
-
550
- Sorcery::CryptoProviders::BCrypt.pepper = User.sorcery_config.pepper
551
-
552
- expect(user.crypted_password).to eq Sorcery::CryptoProviders::BCrypt.encrypt('secret', user.salt)
553
- end
554
- end
555
-
556
- describe 'ORM adapter' do
557
- before(:all) do
558
- sorcery_reload!
559
- User.sorcery_adapter.delete_all
560
- end
561
-
562
- before(:each) { user }
563
-
564
- after(:each) do
565
- User.sorcery_adapter.delete_all
566
- User.sorcery_config.reset!
567
- end
568
-
569
- it 'find_by_username works as expected' do
570
- sorcery_model_property_set(:username_attribute_names, [:username])
571
-
572
- expect(User.sorcery_adapter.find_by_username('gizmo')).to eq user
573
- end
574
-
575
- it 'find_by_username works as expected with multiple username attributes' do
576
- sorcery_model_property_set(:username_attribute_names, %i[username email])
577
-
578
- expect(User.sorcery_adapter.find_by_username('gizmo')).to eq user
579
- end
580
-
581
- it 'find_by_email works as expected' do
582
- expect(User.sorcery_adapter.find_by_email('bla@bla.com')).to eq user
583
- end
584
- end
585
- end
586
-
587
- shared_examples_for 'external_user' do
588
- let(:user) { create_new_user }
589
- let(:external_user) { create_new_external_user :twitter }
590
-
591
- before(:all) do
592
- if SORCERY_ORM == :active_record
593
- MigrationHelper.migrate("#{Rails.root}/db/migrate/external")
594
- MigrationHelper.migrate("#{Rails.root}/db/migrate/activation")
595
- end
596
- sorcery_reload!
597
- end
598
-
599
- after(:all) do
600
- if SORCERY_ORM == :active_record
601
- MigrationHelper.rollback("#{Rails.root}/db/migrate/external")
602
- MigrationHelper.rollback("#{Rails.root}/db/migrate/activation")
603
- end
604
- end
605
-
606
- before(:each) do
607
- User.sorcery_adapter.delete_all
608
- end
609
-
610
- it "responds to 'external?'" do
611
- expect(user).to respond_to(:external?)
612
- end
613
-
614
- it 'external? is false for regular users' do
615
- expect(user.external?).to be false
616
- end
617
-
618
- it 'external? is true for external users' do
619
- expect(external_user.external?).to be true
620
- end
621
-
622
- describe '.create_from_provider' do
623
- before(:each) do
624
- sorcery_reload!([:external])
625
- sorcery_model_property_set(:authentications_class, Authentication)
626
- end
627
-
628
- it 'supports nested attributes' do
629
- expect do
630
- User.create_from_provider('facebook', '123', username: 'Noam Ben Ari')
631
- end.to change { User.count }.by(1)
632
-
633
- expect(User.first.username).to eq 'Noam Ben Ari'
634
- end
635
-
636
- context 'with block' do
637
- it 'create user when block return true' do
638
- expect do
639
- User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') { true }
640
- end.to change { User.count }.by(1)
641
- end
642
-
643
- it 'does not create user when block return false' do
644
- expect do
645
- User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') { false }
646
- end.not_to(change { User.count })
647
- end
648
- end
649
- end
650
-
651
- describe 'activation' do
652
- before(:each) do
653
- sorcery_reload!(%i[user_activation external], user_activation_mailer: ::SorceryMailer)
654
- end
655
-
656
- after(:each) do
657
- User.sorcery_adapter.delete_all
658
- end
659
-
660
- %i[facebook github google liveid slack].each do |provider|
661
- it 'does not send activation email to external users' do
662
- old_size = ActionMailer::Base.deliveries.size
663
- create_new_external_user(provider)
664
-
665
- expect(ActionMailer::Base.deliveries.size).to eq old_size
666
- end
667
-
668
- it 'does not send external users an activation success email' do
669
- sorcery_model_property_set(:activation_success_email_method_name, nil)
670
- create_new_external_user(provider)
671
- old_size = ActionMailer::Base.deliveries.size
672
- @user.activate!
673
-
674
- expect(ActionMailer::Base.deliveries.size).to eq old_size
675
- end
676
- end
677
- end
678
- end