cb-sorcery 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
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