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.
Files changed (135) hide show
  1. data/.document +5 -0
  2. data/.gitignore +56 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +40 -0
  5. data/CHANGELOG.md +263 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +360 -0
  9. data/Rakefile +6 -0
  10. data/gemfiles/active_record-rails40.gemfile +7 -0
  11. data/gemfiles/active_record-rails41.gemfile +7 -0
  12. data/lib/generators/sorcery/USAGE +22 -0
  13. data/lib/generators/sorcery/helpers.rb +40 -0
  14. data/lib/generators/sorcery/install_generator.rb +95 -0
  15. data/lib/generators/sorcery/templates/initializer.rb +451 -0
  16. data/lib/generators/sorcery/templates/migration/activity_logging.rb +10 -0
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +9 -0
  18. data/lib/generators/sorcery/templates/migration/core.rb +13 -0
  19. data/lib/generators/sorcery/templates/migration/external.rb +12 -0
  20. data/lib/generators/sorcery/templates/migration/remember_me.rb +8 -0
  21. data/lib/generators/sorcery/templates/migration/reset_password.rb +9 -0
  22. data/lib/generators/sorcery/templates/migration/user_activation.rb +9 -0
  23. data/lib/sorcery.rb +85 -0
  24. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  25. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  26. data/lib/sorcery/controller.rb +157 -0
  27. data/lib/sorcery/controller/config.rb +65 -0
  28. data/lib/sorcery/controller/submodules/activity_logging.rb +82 -0
  29. data/lib/sorcery/controller/submodules/brute_force_protection.rb +38 -0
  30. data/lib/sorcery/controller/submodules/external.rb +199 -0
  31. data/lib/sorcery/controller/submodules/http_basic_auth.rb +74 -0
  32. data/lib/sorcery/controller/submodules/remember_me.rb +81 -0
  33. data/lib/sorcery/controller/submodules/session_timeout.rb +56 -0
  34. data/lib/sorcery/crypto_providers/aes256.rb +51 -0
  35. data/lib/sorcery/crypto_providers/bcrypt.rb +97 -0
  36. data/lib/sorcery/crypto_providers/common.rb +35 -0
  37. data/lib/sorcery/crypto_providers/md5.rb +19 -0
  38. data/lib/sorcery/crypto_providers/sha1.rb +28 -0
  39. data/lib/sorcery/crypto_providers/sha256.rb +36 -0
  40. data/lib/sorcery/crypto_providers/sha512.rb +36 -0
  41. data/lib/sorcery/engine.rb +21 -0
  42. data/lib/sorcery/model.rb +183 -0
  43. data/lib/sorcery/model/config.rb +96 -0
  44. data/lib/sorcery/model/submodules/activity_logging.rb +70 -0
  45. data/lib/sorcery/model/submodules/brute_force_protection.rb +125 -0
  46. data/lib/sorcery/model/submodules/external.rb +100 -0
  47. data/lib/sorcery/model/submodules/remember_me.rb +62 -0
  48. data/lib/sorcery/model/submodules/reset_password.rb +131 -0
  49. data/lib/sorcery/model/submodules/user_activation.rb +149 -0
  50. data/lib/sorcery/model/temporary_token.rb +30 -0
  51. data/lib/sorcery/protocols/certs/ca-bundle.crt +5182 -0
  52. data/lib/sorcery/protocols/oauth.rb +42 -0
  53. data/lib/sorcery/protocols/oauth2.rb +47 -0
  54. data/lib/sorcery/providers/base.rb +27 -0
  55. data/lib/sorcery/providers/facebook.rb +63 -0
  56. data/lib/sorcery/providers/github.rb +51 -0
  57. data/lib/sorcery/providers/google.rb +51 -0
  58. data/lib/sorcery/providers/jira.rb +77 -0
  59. data/lib/sorcery/providers/linkedin.rb +66 -0
  60. data/lib/sorcery/providers/liveid.rb +53 -0
  61. data/lib/sorcery/providers/twitter.rb +59 -0
  62. data/lib/sorcery/providers/vk.rb +63 -0
  63. data/lib/sorcery/providers/xing.rb +64 -0
  64. data/lib/sorcery/railties/tasks.rake +6 -0
  65. data/lib/sorcery/test_helpers/internal.rb +78 -0
  66. data/lib/sorcery/test_helpers/internal/rails.rb +68 -0
  67. data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
  68. data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
  69. data/lib/sorcery/version.rb +3 -0
  70. data/sorcery.gemspec +34 -0
  71. data/spec/active_record/user_activation_spec.rb +18 -0
  72. data/spec/active_record/user_activity_logging_spec.rb +17 -0
  73. data/spec/active_record/user_brute_force_protection_spec.rb +16 -0
  74. data/spec/active_record/user_oauth_spec.rb +16 -0
  75. data/spec/active_record/user_remember_me_spec.rb +16 -0
  76. data/spec/active_record/user_reset_password_spec.rb +16 -0
  77. data/spec/active_record/user_spec.rb +37 -0
  78. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  79. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  80. data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
  81. data/spec/controllers/controller_oauth2_spec.rb +407 -0
  82. data/spec/controllers/controller_oauth_spec.rb +240 -0
  83. data/spec/controllers/controller_remember_me_spec.rb +117 -0
  84. data/spec/controllers/controller_session_timeout_spec.rb +80 -0
  85. data/spec/controllers/controller_spec.rb +215 -0
  86. data/spec/orm/active_record.rb +21 -0
  87. data/spec/rails_app/app/active_record/authentication.rb +3 -0
  88. data/spec/rails_app/app/active_record/user.rb +5 -0
  89. data/spec/rails_app/app/active_record/user_provider.rb +3 -0
  90. data/spec/rails_app/app/controllers/sorcery_controller.rb +265 -0
  91. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  92. data/spec/rails_app/app/mailers/sorcery_mailer.rb +32 -0
  93. data/spec/rails_app/app/views/application/index.html.erb +17 -0
  94. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  95. data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  96. data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  97. data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +17 -0
  98. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  99. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  100. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  101. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  102. data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
  103. data/spec/rails_app/config.ru +4 -0
  104. data/spec/rails_app/config/application.rb +56 -0
  105. data/spec/rails_app/config/boot.rb +4 -0
  106. data/spec/rails_app/config/database.yml +22 -0
  107. data/spec/rails_app/config/environment.rb +5 -0
  108. data/spec/rails_app/config/environments/test.rb +37 -0
  109. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  110. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  111. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  112. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  113. data/spec/rails_app/config/initializers/session_store.rb +12 -0
  114. data/spec/rails_app/config/locales/en.yml +5 -0
  115. data/spec/rails_app/config/routes.rb +48 -0
  116. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  117. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +19 -0
  118. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +13 -0
  119. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +16 -0
  120. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +22 -0
  121. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  122. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  123. data/spec/rails_app/db/schema.rb +23 -0
  124. data/spec/rails_app/db/seeds.rb +7 -0
  125. data/spec/shared_examples/user_activation_shared_examples.rb +242 -0
  126. data/spec/shared_examples/user_activity_logging_shared_examples.rb +97 -0
  127. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +156 -0
  128. data/spec/shared_examples/user_oauth_shared_examples.rb +36 -0
  129. data/spec/shared_examples/user_remember_me_shared_examples.rb +57 -0
  130. data/spec/shared_examples/user_reset_password_shared_examples.rb +263 -0
  131. data/spec/shared_examples/user_shared_examples.rb +467 -0
  132. data/spec/sorcery_crypto_providers_spec.rb +198 -0
  133. data/spec/spec.opts +2 -0
  134. data/spec/spec_helper.rb +41 -0
  135. 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